mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-08 21:22:09 -04:00
Merge "input: touchscreen: Enable FTS Touch driver"
This commit is contained in:
commit
9cf1fba397
32 changed files with 17926 additions and 4 deletions
|
|
@ -278,7 +278,6 @@ config TOUCHSCREEN_CYTTSP4_SPI
|
|||
config TOUCHSCREEN_DA9034
|
||||
tristate "Touchscreen support for Dialog Semiconductor DA9034"
|
||||
depends on PMIC_DA903X
|
||||
default y
|
||||
help
|
||||
Say Y here to enable the support for the touchscreen found
|
||||
on Dialog Semiconductor DA9034 PMIC.
|
||||
|
|
@ -824,7 +823,6 @@ config TOUCHSCREEN_WM97XX
|
|||
config TOUCHSCREEN_WM9705
|
||||
bool "WM9705 Touchscreen interface support"
|
||||
depends on TOUCHSCREEN_WM97XX
|
||||
default y
|
||||
help
|
||||
Say Y here to enable support for the Wolfson Microelectronics
|
||||
WM9705 touchscreen controller.
|
||||
|
|
@ -832,7 +830,6 @@ config TOUCHSCREEN_WM9705
|
|||
config TOUCHSCREEN_WM9712
|
||||
bool "WM9712 Touchscreen interface support"
|
||||
depends on TOUCHSCREEN_WM97XX
|
||||
default y
|
||||
help
|
||||
Say Y here to enable support for the Wolfson Microelectronics
|
||||
WM9712 touchscreen controller.
|
||||
|
|
@ -840,7 +837,6 @@ config TOUCHSCREEN_WM9712
|
|||
config TOUCHSCREEN_WM9713
|
||||
bool "WM9713 Touchscreen interface support"
|
||||
depends on TOUCHSCREEN_WM97XX
|
||||
default y
|
||||
help
|
||||
Say Y here to enable support for the Wolfson Microelectronics
|
||||
WM9713 touchscreen controller.
|
||||
|
|
@ -1314,4 +1310,6 @@ config TOUCHSCREEN_IQS5XX
|
|||
To compile this driver as a module, choose M here: the
|
||||
module will be called iqs5xx.
|
||||
|
||||
source "drivers/input/touchscreen/st/Kconfig"
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -110,3 +110,4 @@ obj-$(CONFIG_TOUCHSCREEN_COLIBRI_VF50) += colibri-vf50-ts.o
|
|||
obj-$(CONFIG_TOUCHSCREEN_ROHM_BU21023) += rohm_bu21023.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_RASPBERRYPI_FW) += raspberrypi-ts.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_IQS5XX) += iqs5xx.o
|
||||
obj-$(CONFIG_TOUCHSCREEN_ST) += st/
|
||||
|
|
|
|||
22
drivers/input/touchscreen/st/Kconfig
Normal file
22
drivers/input/touchscreen/st/Kconfig
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# STMicroelectronics touchscreen driver configuration
|
||||
#
|
||||
|
||||
config TOUCHSCREEN_ST
|
||||
tristate "STMicroelectronics Touchscreen Driver"
|
||||
depends on I2C
|
||||
help
|
||||
Say Y here if you have a STMicroelectronics Touchscreen.
|
||||
|
||||
If unsure, say N.
|
||||
To compile this driver as a module, choose M here: the
|
||||
module will be called st.
|
||||
|
||||
config TOUCHSCREEN_ST_I2C
|
||||
#tristate "STMicroelectronics i2c touchscreen"
|
||||
string "STMicroelectronics ts directory name"
|
||||
default "st"
|
||||
depends on TOUCHSCREEN_ST
|
||||
help
|
||||
This enables support for ST touch panel over I2C based touchscreens.
|
||||
11
drivers/input/touchscreen/st/Makefile
Normal file
11
drivers/input/touchscreen/st/Makefile
Normal file
|
|
@ -0,0 +1,11 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
## Makefile for the STMicroelectronics touchscreen driver.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_TOUCHSCREEN_ST) += st_fts.o
|
||||
|
||||
st_fts-y := fts.o fts_gui.o fts_driver_test.o fts_aoi_event.o \
|
||||
fts_lib/ftsCompensation.o fts_lib/ftsCrossCompile.o fts_lib/ftsError.o \
|
||||
fts_lib/ftsFrame.o fts_lib/ftsIO.o fts_lib/ftsTest.o fts_lib/ftsTime.o \
|
||||
fts_lib/ftsTool.o fts_lib/ftsFlash.o fts_lib/ftsGesture.o
|
||||
5059
drivers/input/touchscreen/st/fts.c
Normal file
5059
drivers/input/touchscreen/st/fts.c
Normal file
File diff suppressed because it is too large
Load diff
350
drivers/input/touchscreen/st/fts.h
Normal file
350
drivers/input/touchscreen/st/fts.h
Normal file
|
|
@ -0,0 +1,350 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef _LINUX_FTS_I2C_H_
|
||||
#define _LINUX_FTS_I2C_H_
|
||||
|
||||
/*#include <linux/wakelock.h>*/
|
||||
#include <linux/pm_wakeup.h>
|
||||
#include <linux/timekeeping.h>
|
||||
|
||||
#include "fts_lib/ftsSoftware.h"
|
||||
#include "fts_lib/ftsHardware.h"
|
||||
#include "fts_lib/ftsGesture.h"
|
||||
|
||||
#define FTS_POWER_ON 1
|
||||
#define FTS_POWER_OFF 0
|
||||
|
||||
/****************** CONFIGURATION SECTION ******************/
|
||||
|
||||
/**** CODE CONFIGURATION ****/
|
||||
|
||||
#define FTS_TS_DRV_NAME "fts"
|
||||
#define FTS_TS_DRV_VERSION "4.2.14" /* version */
|
||||
|
||||
/*#define SCRIPTLESS*/ /*allow to work in scriptless mode with the GUI*/
|
||||
#ifdef SCRIPTLESS
|
||||
#define SCRIPTLESS_DEBUG
|
||||
/**
|
||||
* uncomment this macro definition to print debug
|
||||
* message for script less support
|
||||
*/
|
||||
#endif
|
||||
|
||||
#define DRIVER_TEST
|
||||
|
||||
/* #define FW_H_FILE */ /*include the FW as header file*/
|
||||
#ifdef FW_H_FILE
|
||||
#define FW_SIZE_NAME myArray_size
|
||||
#define FW_ARRAY_NAME myArray
|
||||
#endif
|
||||
|
||||
/*#define LIMITS_H_FILE*/ /*include the limits file as header file*/
|
||||
#ifdef LIMITS_H_FILE
|
||||
#define LIMITS_SIZE_NAME myArray2_size
|
||||
#define LIMITS_ARRAY_NAME myArray2
|
||||
#endif
|
||||
|
||||
/**** END ****/
|
||||
|
||||
|
||||
/**** FEATURES USED IN THE IC ***/
|
||||
/* #define PHONE_KEY enable the keys */
|
||||
|
||||
#define PHONE_GESTURE /*allow to use the gestures*/
|
||||
#ifdef PHONE_GESTURE
|
||||
#define USE_GESTURE_MASK
|
||||
#define USE_CUSTOM_GESTURES
|
||||
#endif
|
||||
|
||||
#define USE_ONE_FILE_NODE
|
||||
/*allow to enable/disable all the features just using one file node*/
|
||||
|
||||
#define EDGE_REJ
|
||||
/*allow edge rej feature (comment to disable)*/
|
||||
|
||||
#define CORNER_REJ
|
||||
/*allow corn rej feature (comment to disable)*/
|
||||
|
||||
#define EDGE_PALM_REJ
|
||||
/*allow edge palm rej feature (comment to disable)*/
|
||||
|
||||
#define CHARGER_MODE
|
||||
/*allow charger mode feature (comment to disable)*/
|
||||
|
||||
#define GLOVE_MODE
|
||||
/*allow glove mode feature (comment to disable)*/
|
||||
|
||||
#define VR_MODE
|
||||
/*allow vr mode feature (comment to disable)*/
|
||||
|
||||
#define COVER_MODE
|
||||
/*allow cover mode feature (comment to disable)*/
|
||||
|
||||
#define STYLUS_MODE
|
||||
/*allow stylus mode feature (comment to disable)*/
|
||||
|
||||
#define USE_NOISE_PARAM
|
||||
/*set noise params during resume (comment to disable)*/
|
||||
|
||||
/**** END ****/
|
||||
|
||||
|
||||
/**** PANEL SPECIFICATION ****/
|
||||
#define X_AXIS_MAX 1440
|
||||
#define X_AXIS_MIN 0
|
||||
#define Y_AXIS_MAX 2880
|
||||
#define Y_AXIS_MIN 0
|
||||
|
||||
#define PRESSURE_MIN 0
|
||||
#define PRESSURE_MAX 127
|
||||
|
||||
#define TOUCH_ID_MAX 10
|
||||
|
||||
#define AREA_MIN PRESSURE_MIN
|
||||
#define AREA_MAX PRESSURE_MAX
|
||||
/**** END ****/
|
||||
|
||||
/*********************************************************/
|
||||
|
||||
/* Flash programming */
|
||||
|
||||
#define INIT_FLAG_CNT 3
|
||||
|
||||
/* KEYS */
|
||||
#define KEY1 0x02
|
||||
#define KEY2 0x01
|
||||
#define KEY3 0x04
|
||||
|
||||
/*
|
||||
* Configuration mode
|
||||
*/
|
||||
/**
|
||||
* bitmask which can assume the value defined as
|
||||
* features in ftsSoftware.h or the following values
|
||||
*/
|
||||
|
||||
#define MODE_NOTHING 0x00000000
|
||||
#define MODE_SENSEON 0x10000000
|
||||
#define MODE_SENSEOFF 0x20000000
|
||||
#define FEAT_GESTURE 0x40000000
|
||||
|
||||
|
||||
/*
|
||||
* Status Event Field:
|
||||
* id of command that triggered the event
|
||||
*/
|
||||
|
||||
#define FTS_FLASH_WRITE_CONFIG 0x03
|
||||
#define FTS_FLASH_WRITE_COMP_MEMORY 0x04
|
||||
#define FTS_FORCE_CAL_SELF_MUTUAL 0x05
|
||||
#define FTS_FORCE_CAL_SELF 0x06
|
||||
#define FTS_WATER_MODE_ON 0x07
|
||||
#define FTS_WATER_MODE_OFF 0x08
|
||||
|
||||
|
||||
#define EXP_FN_WORK_DELAY_MS 1000
|
||||
|
||||
#define CMD_STR_LEN 32
|
||||
#define I2C_DATA_MAX_LEN 32
|
||||
|
||||
#ifdef SCRIPTLESS
|
||||
/*
|
||||
* I2C Command Read/Write Function
|
||||
*/
|
||||
|
||||
#define CMD_RESULT_STR_LEN 2048
|
||||
#endif
|
||||
|
||||
#define TSP_BUF_SIZE 4096
|
||||
|
||||
#define PINCTRL_STATE_ACTIVE "pmx_ts_active"
|
||||
#define PINCTRL_STATE_SUSPEND "pmx_ts_suspend"
|
||||
#define PINCTRL_STATE_RELEASE "pmx_ts_release"
|
||||
|
||||
/*add by guchong*/
|
||||
#ifdef PHONE_GESTURE
|
||||
extern u16 gesture_coordinates_x[GESTURE_COORDS_REPORT_MAX];
|
||||
extern u16 gesture_coordinates_y[GESTURE_COORDS_REPORT_MAX];
|
||||
extern int gesture_coords_reported;
|
||||
extern struct mutex gestureMask_mutex;
|
||||
#endif
|
||||
|
||||
struct fts_i2c_platform_data {
|
||||
bool x_flip;
|
||||
bool y_flip;
|
||||
int (*power)(bool on);
|
||||
int irq_gpio;
|
||||
int reset_gpio;
|
||||
const char *pwr_reg_name;
|
||||
const char *bus_reg_name;
|
||||
bool pwr_on_suspend;
|
||||
};
|
||||
|
||||
/*
|
||||
* Forward declaration
|
||||
*/
|
||||
struct fts_ts_info;
|
||||
|
||||
/*
|
||||
* Dispatch event handler
|
||||
*/
|
||||
struct event_dispatch_handler_t {
|
||||
void (*handler)(struct fts_ts_info *info, unsigned char *data);
|
||||
};
|
||||
|
||||
/*
|
||||
* struct fts_ts_info - FTS capacitive touch screen device information
|
||||
* @dev: Pointer to the structure device
|
||||
* @client: I2C client structure
|
||||
* @input_dev Input device structure
|
||||
* @work Work thread
|
||||
* @event_wq Event queue for work thread
|
||||
* @event_dispatch_table Event dispatch table handlers
|
||||
* @attrs SysFS attributes
|
||||
* @mode Device operating mode (bitmask)
|
||||
* @touch_id Bitmask for touch id (mapped to input slots)
|
||||
* @stylus_id Bitmask for tracking the stylus touches
|
||||
* (mapped using the touchId)
|
||||
* @timer Timer when operating in polling mode
|
||||
* @power Power on/off routine
|
||||
* @bdata HW info retrived from device tree
|
||||
* @pwr_reg DVDD power regulator
|
||||
* @bus_reg AVDD power regulator
|
||||
* @resume_bit Indicate if screen off/on
|
||||
* @fwupdate_stat Store the result of a fw update triggered by the host
|
||||
* @notifier Used for be notified from a suspend/resume event
|
||||
* @sensor_sleep true susped was called, false resume was called
|
||||
* @wakelock Wake Lock struct
|
||||
* @input_report_mutex mutex for handling the pressure of keys
|
||||
* @series of switches to store the enabling status of a particular
|
||||
* feature from the host
|
||||
*/
|
||||
struct fts_ts_info {
|
||||
struct device *dev;
|
||||
struct i2c_client *client;
|
||||
struct input_dev *input_dev;
|
||||
|
||||
struct work_struct work;
|
||||
struct work_struct suspend_work;
|
||||
struct work_struct resume_work;
|
||||
struct workqueue_struct *event_wq;
|
||||
|
||||
struct delayed_work fwu_work;
|
||||
struct workqueue_struct *fwu_workqueue;
|
||||
struct completion cmd_done;
|
||||
|
||||
struct pinctrl *ts_pinctrl;
|
||||
struct pinctrl_state *pinctrl_state_active;
|
||||
struct pinctrl_state *pinctrl_state_suspend;
|
||||
struct pinctrl_state *pinctrl_state_release;
|
||||
|
||||
struct event_dispatch_handler_t *event_dispatch_table;
|
||||
|
||||
struct attribute_group attrs;
|
||||
|
||||
unsigned int mode;
|
||||
unsigned long touch_id;
|
||||
#ifdef STYLUS_MODE
|
||||
unsigned long stylus_id;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef FTS_USE_POLLING_MODE
|
||||
struct hrtimer timer;
|
||||
#endif
|
||||
|
||||
|
||||
#ifdef SCRIPTLESS
|
||||
/*I2C cmd*/
|
||||
struct device *i2c_cmd_dev;
|
||||
char cmd_read_result[CMD_RESULT_STR_LEN];
|
||||
char cmd_wr_result[CMD_RESULT_STR_LEN];
|
||||
char cmd_write_result[20];
|
||||
#endif
|
||||
|
||||
#ifdef DRIVER_TEST
|
||||
struct device *test_cmd_dev;
|
||||
#endif
|
||||
int (*power)(bool on);
|
||||
|
||||
struct fts_i2c_platform_data *bdata;
|
||||
struct regulator *pwr_reg;
|
||||
struct regulator *bus_reg;
|
||||
|
||||
int resume_bit;
|
||||
int fwupdate_stat;
|
||||
|
||||
struct notifier_block notifier;
|
||||
bool sensor_sleep;
|
||||
struct wakeup_source *wakeup_source;
|
||||
|
||||
/* input lock */
|
||||
struct mutex input_report_mutex;
|
||||
|
||||
/*switches for features*/
|
||||
unsigned int gesture_enabled;
|
||||
unsigned int glove_enabled;
|
||||
unsigned int charger_enabled;
|
||||
unsigned int stylus_enabled;
|
||||
unsigned int vr_enabled;
|
||||
unsigned int cover_enabled;
|
||||
unsigned int edge_rej_enabled;
|
||||
unsigned int corner_rej_enabled;
|
||||
unsigned int edge_palm_rej_enabled;
|
||||
|
||||
uint8_t *i2c_data;
|
||||
uint8_t i2c_data_len;
|
||||
|
||||
struct device *aoi_cmd_dev;
|
||||
bool aoi_notify_enabled;
|
||||
bool aoi_wake_on_suspend;
|
||||
|
||||
/* aoi region */
|
||||
int aoi_left;
|
||||
int aoi_top;
|
||||
int aoi_bottom;
|
||||
int aoi_right;
|
||||
};
|
||||
|
||||
extern struct chipInfo ftsInfo;
|
||||
|
||||
int fts_chip_powercycle(struct fts_ts_info *info);
|
||||
int fts_chip_powercycle2(struct fts_ts_info *info, unsigned long sleep);
|
||||
/*int fts_get_fw_version(struct fts_ts_info *info);*/
|
||||
/*extern unsigned int le_to_uint(const unsigned char *ptr);*/
|
||||
/*extern unsigned int be_to_uint(const unsigned char *ptr);*/
|
||||
extern int input_register_notifier_client(struct notifier_block *nb);
|
||||
extern int input_unregister_notifier_client(struct notifier_block *nb);
|
||||
|
||||
extern struct attribute_group aoi_cmd_attr_group;
|
||||
|
||||
#ifdef SCRIPTLESS
|
||||
extern struct attribute_group i2c_cmd_attr_group;
|
||||
#endif
|
||||
|
||||
#ifdef DRIVER_TEST
|
||||
extern struct attribute_group test_cmd_attr_group;
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
102
drivers/input/touchscreen/st/fts_aoi_event.c
Normal file
102
drivers/input/touchscreen/st/fts_aoi_event.c
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* Copyright (c) 2019, The Linux Foundation. All rights reserved.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 and
|
||||
* only version 2 as published by the Free Software Foundation.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/i2c.h>
|
||||
#include "fts.h"
|
||||
|
||||
static ssize_t touch_event_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
ssize_t aoi_set_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int ret;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct fts_ts_info *info = i2c_get_clientdata(client);
|
||||
int left, top, right, bottom;
|
||||
|
||||
ret = sscanf(buf, "%d %d %d %d", &left, &top, &right, &bottom);
|
||||
if (ret != 4)
|
||||
return -EINVAL;
|
||||
|
||||
if (right > X_AXIS_MAX)
|
||||
right = X_AXIS_MAX;
|
||||
if (bottom > Y_AXIS_MAX)
|
||||
bottom = Y_AXIS_MAX;
|
||||
|
||||
if (left < 0 || left > X_AXIS_MAX || right < 0 ||
|
||||
top > Y_AXIS_MAX || bottom < 0)
|
||||
return -EINVAL;
|
||||
|
||||
if (left >= right || top >= bottom) {
|
||||
info->aoi_left = 0;
|
||||
info->aoi_top = 0;
|
||||
info->aoi_right = 0;
|
||||
info->aoi_bottom = 0;
|
||||
info->aoi_notify_enabled = false;
|
||||
return count;
|
||||
}
|
||||
|
||||
info->aoi_left = left;
|
||||
info->aoi_top = top;
|
||||
info->aoi_right = right;
|
||||
info->aoi_bottom = bottom;
|
||||
|
||||
info->aoi_notify_enabled = true;
|
||||
return count;
|
||||
}
|
||||
|
||||
static ssize_t aoi_set_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct fts_ts_info *info = i2c_get_clientdata(client);
|
||||
size_t len = 0;
|
||||
|
||||
len = scnprintf(buf + len, PAGE_SIZE,
|
||||
"%d %d %d %d",
|
||||
info->aoi_left,
|
||||
info->aoi_top,
|
||||
info->aoi_right,
|
||||
info->aoi_bottom);
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
static ssize_t power_set_store(struct device *dev,
|
||||
struct device_attribute *attr, const char *buf, size_t count)
|
||||
{
|
||||
int enable;
|
||||
|
||||
if (kstrtoint(buf, 10, &enable))
|
||||
return -EINVAL;
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RO(touch_event);
|
||||
static DEVICE_ATTR_RW(aoi_set);
|
||||
static DEVICE_ATTR_WO(power_set);
|
||||
|
||||
static struct attribute *aoi_cmd_attributes[] = {
|
||||
&dev_attr_touch_event.attr,
|
||||
&dev_attr_aoi_set.attr,
|
||||
&dev_attr_power_set.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct attribute_group aoi_cmd_attr_group = {
|
||||
.attrs = aoi_cmd_attributes,
|
||||
};
|
||||
1107
drivers/input/touchscreen/st/fts_driver_test.c
Normal file
1107
drivers/input/touchscreen/st/fts_driver_test.c
Normal file
File diff suppressed because it is too large
Load diff
412
drivers/input/touchscreen/st/fts_gui.c
Normal file
412
drivers/input/touchscreen/st/fts_gui.c
Normal file
|
|
@ -0,0 +1,412 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <linux/completion.h>
|
||||
//#include <linux/wakelock.h>
|
||||
#include <linux/pm_wakeup.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include "fts.h"
|
||||
#include "fts_lib/ftsIO.h"
|
||||
|
||||
#ifdef SCRIPTLESS
|
||||
|
||||
static unsigned int fts_data[CMD_RESULT_STR_LEN] = {0};
|
||||
static unsigned char fts_pAddress_i2c[CMD_RESULT_STR_LEN] = {0};
|
||||
static int byte_count_read;
|
||||
static char Out_buff[TSP_BUF_SIZE];
|
||||
|
||||
|
||||
/*I2C CMd functions: functions to interface with GUI without script */
|
||||
|
||||
ssize_t fts_i2c_wr_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct fts_ts_info *info = i2c_get_clientdata(client);
|
||||
int i;
|
||||
char buff[16];
|
||||
|
||||
memset(Out_buff, 0x00, sizeof(Out_buff));
|
||||
if (byte_count_read == 0) {
|
||||
snprintf(Out_buff, sizeof(Out_buff), "{FAILED}\n");
|
||||
return snprintf(buf, TSP_BUF_SIZE, "%s\n", Out_buff);
|
||||
}
|
||||
#ifdef SCRIPTLESS_DEBUG
|
||||
pr_err("%s:DATA READ {\n", __func__);
|
||||
for (i = 0; i < byte_count_read; i++) {
|
||||
pr_err(" %02X\n", (unsigned int)info->cmd_wr_result[i]);
|
||||
if (i < (byte_count_read - 1))
|
||||
pr_err("\n");
|
||||
}
|
||||
pr_err("}\n");
|
||||
#endif
|
||||
snprintf(buff, sizeof(buff), "{");
|
||||
strlcat(Out_buff, buff, sizeof(Out_buff));
|
||||
for (i = 0; i < (byte_count_read + 2); i++) {
|
||||
char temp_byte_count_read;
|
||||
|
||||
if (i == 0) {
|
||||
temp_byte_count_read = (byte_count_read >> 8) & 0xFF;
|
||||
|
||||
snprintf(buff, sizeof(buff), "%02X",
|
||||
temp_byte_count_read);
|
||||
} else if (i == 1) {
|
||||
temp_byte_count_read = (byte_count_read) & 0xFF;
|
||||
|
||||
snprintf(buff, sizeof(buff), "%02X",
|
||||
temp_byte_count_read);
|
||||
|
||||
} else {
|
||||
snprintf(buff, sizeof(buff), "%02X",
|
||||
info->cmd_wr_result[i-2]);
|
||||
}
|
||||
//snprintf(buff, sizeof(buff), "%02X", info->cmd_wr_result[i]);
|
||||
strlcat(Out_buff, buff, sizeof(Out_buff));
|
||||
if (i < (byte_count_read + 1)) {
|
||||
snprintf(buff, sizeof(buff), " ");
|
||||
strlcat(Out_buff, buff, sizeof(Out_buff));
|
||||
}
|
||||
}
|
||||
snprintf(buff, sizeof(buff), "}");
|
||||
strlcat(Out_buff, buff, sizeof(Out_buff));
|
||||
return snprintf(buf, TSP_BUF_SIZE, "%s\n", Out_buff);
|
||||
}
|
||||
|
||||
ssize_t fts_i2c_wr_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int ret;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct fts_ts_info *info = i2c_get_clientdata(client);
|
||||
unsigned char pAddress[9];
|
||||
unsigned int byte_count = 0;
|
||||
int i;
|
||||
unsigned int data[9];
|
||||
|
||||
memset(data, 0x00, sizeof(data));
|
||||
memset(pAddress, 0x00, sizeof(pAddress));
|
||||
memset(info->cmd_wr_result, 0x00, CMD_RESULT_STR_LEN);
|
||||
ret = sscanf(buf, "%x %x %x %x %x %x %x %x %x ",
|
||||
(data + 8), (data), (data + 1), (data + 2), (data + 3),
|
||||
(data + 4), (data + 5), (data + 6), (data + 7));
|
||||
|
||||
byte_count = data[8];
|
||||
|
||||
/**
|
||||
* if(sizeof(buf) != byte_count )
|
||||
* {
|
||||
* printk("%s : Byte count is wrong\n",__func__);
|
||||
* return count;
|
||||
* }
|
||||
*/
|
||||
|
||||
if (byte_count > sizeof(pAddress))
|
||||
return -EINVAL;
|
||||
#ifdef SCRIPTLESS_DEBUG
|
||||
|
||||
pr_err("%s: Input Data 1:\n", __func__);
|
||||
|
||||
for (i = 0 ; i < byte_count; i++) {
|
||||
pr_err(" %02X\n", data[i]);
|
||||
pAddress[i] = (unsigned char)data[i];
|
||||
}
|
||||
pr_err("\n");
|
||||
#else
|
||||
for (i = 0 ; i < byte_count; i++)
|
||||
pAddress[i] = (unsigned char)data[i];
|
||||
#endif
|
||||
byte_count_read = (((unsigned int)data[byte_count - 2]) << 8)
|
||||
| data[byte_count - 1];
|
||||
ret = fts_writeCmd(pAddress, 3);
|
||||
msleep(20);
|
||||
ret = fts_readCmd(&pAddress[3], (byte_count - 5),
|
||||
info->cmd_wr_result, byte_count_read);
|
||||
#ifdef SCRIPTLESS_DEBUG
|
||||
pr_err("%s:DATA READ {\n", __func__);
|
||||
for (i = 0; i < (2 + byte_count_read); i++) {
|
||||
char temp_byte_count_read;
|
||||
|
||||
if (i == 0) {
|
||||
temp_byte_count_read = (byte_count_read >> 8) & 0xFF;
|
||||
pr_err("%02X\n", (unsigned int)temp_byte_count_read);
|
||||
} else if (i == 1) {
|
||||
temp_byte_count_read = (byte_count_read) & 0xFF;
|
||||
pr_err("%02X\n", (unsigned int)temp_byte_count_read);
|
||||
|
||||
} else {
|
||||
pr_err("%02X\n",
|
||||
(unsigned int)info->cmd_read_result[i - 2]);
|
||||
}
|
||||
|
||||
if (i < (byte_count_read + 1))
|
||||
pr_err("\n");
|
||||
|
||||
}
|
||||
pr_err("}\n");
|
||||
#endif
|
||||
if (ret)
|
||||
dev_err(dev, "Unable to read register\n");
|
||||
return count;
|
||||
}
|
||||
|
||||
ssize_t fts_i2c_read_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct fts_ts_info *info = i2c_get_clientdata(client);
|
||||
int i;
|
||||
char buff[16];
|
||||
|
||||
memset(Out_buff, 0x00, sizeof(Out_buff));
|
||||
if (byte_count_read == 0) {
|
||||
snprintf(Out_buff, sizeof(Out_buff), "{FAILED}");
|
||||
return snprintf(buf, TSP_BUF_SIZE, "%s\n", Out_buff);
|
||||
}
|
||||
#ifdef SCRIPTLESS_DEBUG
|
||||
pr_err("%s:DATA READ {\n", __func__);
|
||||
for (i = 0; i < byte_count_read; i++) {
|
||||
pr_err("%02X\n", (unsigned int)info->cmd_read_result[i]);
|
||||
if (i < (byte_count_read - 1))
|
||||
pr_err("\n");
|
||||
}
|
||||
pr_err("}\n");
|
||||
#endif
|
||||
snprintf(buff, sizeof(buff), "{");
|
||||
strlcat(Out_buff, buff, sizeof(Out_buff));
|
||||
for (i = 0; i < (byte_count_read + 2); i++) {
|
||||
char temp_byte_count_read;
|
||||
|
||||
if (i == 0) {
|
||||
temp_byte_count_read = (byte_count_read >> 8) & 0xFF;
|
||||
snprintf(buff, sizeof(buff), "%02X",
|
||||
temp_byte_count_read);
|
||||
} else if (i == 1) {
|
||||
temp_byte_count_read = (byte_count_read) & 0xFF;
|
||||
snprintf(buff, sizeof(buff), "%02X",
|
||||
temp_byte_count_read);
|
||||
} else {
|
||||
snprintf(buff, sizeof(buff), "%02X",
|
||||
info->cmd_read_result[i - 2]);
|
||||
}
|
||||
strlcat(Out_buff, buff, sizeof(Out_buff));
|
||||
if (i < (byte_count_read + 1)) {
|
||||
snprintf(buff, sizeof(buff), " ");
|
||||
strlcat(Out_buff, buff, sizeof(Out_buff));
|
||||
}
|
||||
}
|
||||
snprintf(buff, sizeof(buff), "}");
|
||||
strlcat(Out_buff, buff, sizeof(Out_buff));
|
||||
|
||||
return snprintf(buf, TSP_BUF_SIZE, "%s\n", Out_buff);
|
||||
}
|
||||
|
||||
ssize_t fts_i2c_read_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int ret;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct fts_ts_info *info = i2c_get_clientdata(client);
|
||||
unsigned char pAddress[9];
|
||||
unsigned int byte_count = 0;
|
||||
int i;
|
||||
unsigned int data[9];
|
||||
|
||||
byte_count_read = 0;
|
||||
memset(data, 0x00, sizeof(data));
|
||||
memset(pAddress, 0x00, sizeof(pAddress));
|
||||
memset(info->cmd_read_result, 0x00, CMD_RESULT_STR_LEN);
|
||||
ret = sscanf(buf, "%x %x %x %x %x %x %x %x %x ",
|
||||
(data + 8), (data), (data + 1), (data + 2), (data + 3),
|
||||
(data + 4), (data + 5), (data + 6), (data + 7));
|
||||
|
||||
byte_count = data[8];
|
||||
|
||||
if (byte_count > 8) {
|
||||
#ifdef SCRIPTLESS_DEBUG
|
||||
pr_err("%s:Byte count is more than 8\n", __func__);
|
||||
#endif
|
||||
return count;
|
||||
}
|
||||
/*if(sizeof(buf) != byte_count )*/
|
||||
/*{*/
|
||||
/* printk("%s : Byte count is wrong\n",__func__);*/
|
||||
/* return count;*/
|
||||
/*}*/
|
||||
#ifdef SCRIPTLESS_DEBUG
|
||||
pr_err("%s: Input Data 1:\n", __func__);
|
||||
for (i = 0 ; i < byte_count; i++) {
|
||||
pr_err("%02X\n", data[i]);
|
||||
pAddress[i] = (unsigned char)data[i];
|
||||
}
|
||||
pr_err("\n");
|
||||
#else
|
||||
for (i = 0 ; i < byte_count; i++)
|
||||
pAddress[i] = (unsigned char)data[i];
|
||||
#endif
|
||||
byte_count_read = (((unsigned int)data[byte_count - 2]) << 8)
|
||||
| data[byte_count - 1];
|
||||
ret = fts_readCmd(pAddress, (byte_count - 2), info->cmd_read_result,
|
||||
byte_count_read);
|
||||
#ifdef SCRIPTLESS_DEBUG
|
||||
pr_err("%s:DATA READ\n{\n", __func__);
|
||||
for (i = 0; i < (byte_count_read + 2); i++) {
|
||||
char temp_byte_count_read;
|
||||
|
||||
if (i == 0) {
|
||||
temp_byte_count_read = (byte_count_read >> 8) & 0xFF;
|
||||
|
||||
pr_err("%02X\n", (unsigned int)temp_byte_count_read);
|
||||
} else if (i == 1) {
|
||||
temp_byte_count_read = (byte_count_read) & 0xFF;
|
||||
|
||||
pr_err("%02X\n", (unsigned int)temp_byte_count_read);
|
||||
|
||||
} else {
|
||||
pr_err("%02X\n",
|
||||
(unsigned int)info->cmd_read_result[i - 2]);
|
||||
}
|
||||
if (i < (byte_count_read + 1))
|
||||
pr_err("\n");
|
||||
}
|
||||
pr_err("}\n");
|
||||
#endif
|
||||
if (ret)
|
||||
dev_err(dev, "Unable to read register\n");
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
ssize_t fts_i2c_write_show(struct device *dev,
|
||||
struct device_attribute *attr, char *buf)
|
||||
{
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct fts_ts_info *info = i2c_get_clientdata(client);
|
||||
|
||||
return snprintf(buf, TSP_BUF_SIZE, "%s", info->cmd_write_result);
|
||||
|
||||
}
|
||||
|
||||
ssize_t fts_i2c_write_store(struct device *dev, struct device_attribute *attr,
|
||||
const char *buf, size_t count)
|
||||
{
|
||||
int ret;
|
||||
struct i2c_client *client = to_i2c_client(dev);
|
||||
struct fts_ts_info *info = i2c_get_clientdata(client);
|
||||
unsigned int byte_count = 0;
|
||||
int i;
|
||||
unsigned int *data = &fts_data[0];
|
||||
|
||||
memset(fts_data, 0x00, sizeof(fts_data));
|
||||
memset(fts_pAddress_i2c, 0x00, sizeof(fts_pAddress_i2c));
|
||||
memset(info->cmd_write_result, 0x00, sizeof(info->cmd_write_result));
|
||||
ret = sscanf(buf, "%x %x", data, (data + 1));
|
||||
if (ret != 2)
|
||||
return -EINVAL;
|
||||
byte_count = data[0] << 8 | data[1];
|
||||
|
||||
if (byte_count <= sizeof(fts_pAddress_i2c)) {
|
||||
for (i = 0; i < (byte_count); i++) {
|
||||
ret = sscanf(&buf[3 * (i + 2)], "%x ", (data + i));
|
||||
if (ret != 1)
|
||||
return -EINVAL;
|
||||
}
|
||||
} else {
|
||||
#ifdef SCRIPTLESS_DEBUG
|
||||
pr_err("%s:message size is > allowed limit of 512 bytes\n",
|
||||
__func__);
|
||||
#endif
|
||||
snprintf(info->cmd_write_result, sizeof(info->cmd_write_result),
|
||||
"{Write NOT OK}\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
#ifdef SCRIPTLESS_DEBUG
|
||||
pr_err("\n");
|
||||
pr_err("%s:Byte_count = %02d|Count = %02d |size of buf:%02d\n",
|
||||
__func__, byte_count, (int)count, (int)sizeof(buf));
|
||||
pr_err("%s: Input Data 1:\n", __func__);
|
||||
for (i = 0 ; i < byte_count; i++) {
|
||||
pr_err(" %02X\n", data[i]);
|
||||
fts_pAddress_i2c[i] = (unsigned char)data[i];
|
||||
}
|
||||
pr_err("\n");
|
||||
#else
|
||||
for (i = 0 ; i < byte_count; i++)
|
||||
fts_pAddress_i2c[i] = (unsigned char)data[i];
|
||||
#endif
|
||||
if ((fts_pAddress_i2c[0] == 0xb3) && (fts_pAddress_i2c[3] == 0xb1)) {
|
||||
ret = fts_writeCmd(fts_pAddress_i2c, 3);
|
||||
msleep(20);
|
||||
ret = fts_writeCmd(&fts_pAddress_i2c[3], byte_count-3);
|
||||
} else
|
||||
ret = fts_writeCmd(fts_pAddress_i2c, byte_count);
|
||||
|
||||
#ifdef SCRIPTLESS_DEBUG
|
||||
pr_err("%s:DATA :\n", __func__);
|
||||
for (i = 0; i < byte_count; i++)
|
||||
pr_err(" %02X\n", (unsigned int)fts_pAddress_i2c[i]);
|
||||
pr_err(" byte_count: %02X\n", byte_count);
|
||||
#endif
|
||||
if (ret < 0) {
|
||||
dev_err(dev, "{Write NOT OK}\n");
|
||||
snprintf(info->cmd_write_result, sizeof(info->cmd_write_result),
|
||||
"{Write NOT OK}\n");
|
||||
} else {
|
||||
snprintf(info->cmd_write_result, sizeof(info->cmd_write_result),
|
||||
"{Write OK}\n");
|
||||
#ifdef SCRIPTLESS_DEBUG
|
||||
pr_err("%s : {Write OK}\n", __func__);
|
||||
#endif
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
static DEVICE_ATTR_RW(fts_i2c_read);
|
||||
static DEVICE_ATTR_RW(fts_i2c_wr);
|
||||
static DEVICE_ATTR_RW(fts_i2c_write);
|
||||
|
||||
static struct attribute *i2c_cmd_attributes[] = {
|
||||
&dev_attr_fts_i2c_read.attr,
|
||||
&dev_attr_fts_i2c_wr.attr,
|
||||
&dev_attr_fts_i2c_write.attr,
|
||||
NULL,
|
||||
};
|
||||
|
||||
struct attribute_group i2c_cmd_attr_group = {
|
||||
.attrs = i2c_cmd_attributes,
|
||||
};
|
||||
|
||||
#endif
|
||||
9
drivers/input/touchscreen/st/fts_lib/Makefile
Normal file
9
drivers/input/touchscreen/st/fts_lib/Makefile
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
# SPDX-License-Identifier: GPL-2.0-only
|
||||
#
|
||||
# Makefile for the FTS touchscreen driver.
|
||||
#
|
||||
|
||||
obj-$(CONFIG_TOUCHSCREEN_ST) += ftsCompensation.o \
|
||||
ftsCrossCompile.o ftsError.o ftsFrame.o ftsIO.o ftsTest.o \
|
||||
ftsTime.o ftsTool.o ftsFlash.o ftsGesture.o
|
||||
|
||||
744
drivers/input/touchscreen/st/fts_lib/ftsCompensation.c
Normal file
744
drivers/input/touchscreen/st/fts_lib/ftsCompensation.c
Normal file
|
|
@ -0,0 +1,744 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS functions for getting Initialization Data *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <stdarg.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/of_gpio.h>
|
||||
//#include <linux/sec_sysfs.h>
|
||||
|
||||
#include "ftsCrossCompile.h"
|
||||
#include "ftsCompensation.h"
|
||||
#include "ftsError.h"
|
||||
#include "ftsFrame.h"
|
||||
#include "ftsHardware.h"
|
||||
#include "ftsIO.h"
|
||||
#include "ftsSoftware.h"
|
||||
#include "ftsTool.h"
|
||||
|
||||
|
||||
static char tag[8] = "[ FTS ]\0";
|
||||
struct chipInfo ftsInfo;
|
||||
|
||||
int requestCompensationData(u16 type)
|
||||
{
|
||||
int retry = 0;
|
||||
int ret;
|
||||
char *temp = NULL;
|
||||
u16 answer;
|
||||
|
||||
int event_to_search[3];
|
||||
u8 readEvent[FIFO_EVENT_SIZE];
|
||||
|
||||
u8 cmd[3] = { FTS_CMD_REQU_COMP_DATA, 0x00, 0x00};
|
||||
/* B8 is the command for asking compensation data*/
|
||||
u16ToU8(type, &cmd[1]);
|
||||
|
||||
event_to_search[0] = (int)EVENTID_COMP_DATA_READ;
|
||||
event_to_search[1] = cmd[1];
|
||||
event_to_search[2] = cmd[2];
|
||||
|
||||
while (retry < COMP_DATA_READ_RETRY) {
|
||||
temp = printHex("Command = ", cmd, 3);
|
||||
if (temp != NULL)
|
||||
logError(0, "%s %s", tag, temp);
|
||||
kfree(temp);
|
||||
ret = fts_writeFwCmd(cmd, 3);
|
||||
/*send the request to the chip to load*/
|
||||
/*in memory the Compensation Data*/
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s:ERROR %02X\n",
|
||||
tag, __func__, ERROR_I2C_W);
|
||||
return ERROR_I2C_W;
|
||||
}
|
||||
ret = pollForEvent(event_to_search, 3, readEvent,
|
||||
TIMEOUT_REQU_COMP_DATA);
|
||||
if (ret < OK) {
|
||||
logError(0, "%s Event did not Found at %d attemp!\n",
|
||||
tag, retry + 1);
|
||||
retry += 1;
|
||||
} else {
|
||||
retry = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (retry == COMP_DATA_READ_RETRY) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_TIMEOUT);
|
||||
return ERROR_TIMEOUT;
|
||||
}
|
||||
|
||||
u8ToU16_le(&readEvent[1], &answer);
|
||||
|
||||
if (answer == type)
|
||||
return OK;
|
||||
|
||||
logError(1, "%sThe event found has a different type of ", tag);
|
||||
logError(1, "Compensation data %02X\n", ERROR_DIFF_COMP_TYPE);
|
||||
return ERROR_DIFF_COMP_TYPE;
|
||||
|
||||
}
|
||||
|
||||
int readCompensationDataHeader(u16 type, struct DataHeader *header,
|
||||
u16 *address)
|
||||
{
|
||||
u16 offset = ADDR_FRAMEBUFFER_DATA;
|
||||
u16 answer;
|
||||
u8 data[COMP_DATA_HEADER];
|
||||
|
||||
if (readCmdU16(FTS_CMD_FRAMEBUFFER_R, offset, data, COMP_DATA_HEADER,
|
||||
DUMMY_FRAMEBUFFER) < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_I2C_R);
|
||||
return ERROR_I2C_R;
|
||||
}
|
||||
logError(0, "%s Read Data Header done!\n", tag);
|
||||
|
||||
if (data[0] != HEADER_SIGNATURE) {
|
||||
logError(1, "%s %s:%02X The Header Signature was wrong!",
|
||||
tag, __func__, ERROR_WRONG_COMP_SIGN);
|
||||
logError(1, "%02X != %02X\n", data[0], HEADER_SIGNATURE);
|
||||
|
||||
return ERROR_WRONG_COMP_SIGN;
|
||||
}
|
||||
|
||||
|
||||
u8ToU16_le(&data[1], &answer);
|
||||
|
||||
if (answer != type) {
|
||||
logError(1, "%s %s:ERROR %02X\n",
|
||||
tag, __func__, ERROR_DIFF_COMP_TYPE);
|
||||
|
||||
return ERROR_DIFF_COMP_TYPE;
|
||||
}
|
||||
|
||||
logError(0, "%s Type of Compensation data OK!\n", tag);
|
||||
|
||||
header->type = type;
|
||||
header->force_node = (int)data[4];
|
||||
header->sense_node = (int)data[5];
|
||||
|
||||
*address = offset + COMP_DATA_HEADER;
|
||||
|
||||
return OK;
|
||||
|
||||
}
|
||||
|
||||
int readMutualSenseGlobalData(u16 *address, struct MutualSenseData *global)
|
||||
{
|
||||
|
||||
u8 data[COMP_DATA_GLOBAL];
|
||||
|
||||
logError(0, "%s Address for Global data= %02X\n", tag, *address);
|
||||
|
||||
if (readCmdU16(FTS_CMD_FRAMEBUFFER_R, *address, data,
|
||||
COMP_DATA_GLOBAL, DUMMY_FRAMEBUFFER) < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_I2C_R);
|
||||
|
||||
return ERROR_I2C_R;
|
||||
}
|
||||
logError(0, "%s Global data Read!\n", tag);
|
||||
|
||||
global->tuning_ver = data[0];
|
||||
global->cx1 = data[1];
|
||||
|
||||
logError(0, "%s tuning_ver = %d CX1 = %d\n",
|
||||
tag, global->tuning_ver, global->cx1);
|
||||
|
||||
*address += COMP_DATA_GLOBAL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
|
||||
int readMutualSenseNodeData(u16 address, struct MutualSenseData *node)
|
||||
{
|
||||
int size = node->header.force_node*node->header.sense_node;
|
||||
|
||||
logError(0, "%s Address for Node data = %02X\n", tag, address);
|
||||
|
||||
node->node_data = (u8 *)kmalloc_array(size, (sizeof(u8)), GFP_KERNEL);
|
||||
|
||||
if (node->node_data == NULL) {
|
||||
logError(1, "%s %s: ERROR %02X", tag, __func__, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
logError(0, "%s Node Data to read %d bytes\n", tag, size);
|
||||
|
||||
if (readCmdU16(FTS_CMD_FRAMEBUFFER_R, address, node->node_data,
|
||||
size, DUMMY_FRAMEBUFFER) < 0) {
|
||||
logError(1, "%s %s:ERROR %02X\n", tag, __func__, ERROR_I2C_R);
|
||||
kfree(node->node_data);
|
||||
return ERROR_I2C_R;
|
||||
}
|
||||
node->node_data_size = size;
|
||||
|
||||
logError(0, "%s Read node data ok!\n", tag);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
int readMutualSenseCompensationData(u16 type, struct MutualSenseData *data)
|
||||
{
|
||||
int ret;
|
||||
u16 address;
|
||||
|
||||
data->node_data = NULL;
|
||||
|
||||
if (!(type == MS_TOUCH_ACTIVE || type == MS_TOUCH_LOW_POWER
|
||||
|| type == MS_TOUCH_ULTRA_LOW_POWER || type == MS_KEY)) {
|
||||
logError(1, "%s %s: Choose a MS type of compensation data ",
|
||||
tag, __func__);
|
||||
logError(1, "ERROR %02X\n", ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
ret = requestCompensationData(type);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_REQU_COMP_DATA);
|
||||
return (ret|ERROR_REQU_COMP_DATA);
|
||||
}
|
||||
|
||||
ret = readCompensationDataHeader(type, &(data->header), &address);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_COMP_DATA_HEADER);
|
||||
return (ret | ERROR_COMP_DATA_HEADER);
|
||||
}
|
||||
|
||||
ret = readMutualSenseGlobalData(&address, data);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_COMP_DATA_GLOBAL);
|
||||
return (ret|ERROR_COMP_DATA_GLOBAL);
|
||||
}
|
||||
|
||||
ret = readMutualSenseNodeData(address, data);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_COMP_DATA_NODE);
|
||||
return (ret | ERROR_COMP_DATA_NODE);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
int readSelfSenseGlobalData(u16 *address, struct SelfSenseData *global)
|
||||
{
|
||||
u8 data[COMP_DATA_GLOBAL];
|
||||
|
||||
logError(0, "%s Address for Global data= %02X\n", tag, *address);
|
||||
|
||||
if (readCmdU16(FTS_CMD_FRAMEBUFFER_R, *address, data,
|
||||
COMP_DATA_GLOBAL, DUMMY_FRAMEBUFFER) < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_I2C_R);
|
||||
return ERROR_I2C_R;
|
||||
}
|
||||
|
||||
logError(0, "%s Global data Read!\n", tag);
|
||||
|
||||
global->tuning_ver = data[0];
|
||||
global->f_ix1 = data[1];
|
||||
global->s_ix1 = data[2];
|
||||
global->f_cx1 = data[3];
|
||||
global->s_cx1 = data[4];
|
||||
global->f_max_n = data[5];
|
||||
global->s_max_n = data[6];
|
||||
|
||||
logError(0,
|
||||
"%stuning_ver = %df_ix1 = %ds_ix1 = %df_cx1 = %d s_cx1 = %d\n",
|
||||
tag, global->tuning_ver, global->f_ix1,
|
||||
global->s_ix1, global->f_cx1, global->s_cx1);
|
||||
logError(0, "%s max_n = %d s_max_n = %d\n",
|
||||
tag, global->f_max_n, global->s_max_n);
|
||||
|
||||
*address += COMP_DATA_GLOBAL;
|
||||
return OK;
|
||||
}
|
||||
|
||||
int readSelfSenseNodeData(u16 address, struct SelfSenseData *node)
|
||||
{
|
||||
int size = node->header.force_node * 2 + node->header.sense_node * 2;
|
||||
u8 *data;
|
||||
|
||||
node->ix2_fm = (u8 *)kmalloc_array(node->header.force_node,
|
||||
sizeof(u8), GFP_KERNEL);
|
||||
if (node->ix2_fm == NULL) {
|
||||
logError(1, "%s %s: ERROR %02X", tag, __func__, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
node->cx2_fm = (u8 *)kmalloc_array(node->header.force_node,
|
||||
sizeof(u8), GFP_KERNEL);
|
||||
if (node->cx2_fm == NULL) {
|
||||
logError(1, "%s %s: ERROR %02X", tag, __func__, ERROR_ALLOC);
|
||||
kfree(node->ix2_fm);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
node->ix2_sn = (u8 *)kmalloc_array(node->header.sense_node,
|
||||
sizeof(u8), GFP_KERNEL);
|
||||
if (node->ix2_sn == NULL) {
|
||||
logError(1, "%s %s: ERROR %02X", tag, __func__, ERROR_ALLOC);
|
||||
kfree(node->ix2_fm);
|
||||
kfree(node->cx2_fm);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
node->cx2_sn = (u8 *)kmalloc_array(node->header.sense_node,
|
||||
sizeof(u8), GFP_KERNEL);
|
||||
if (node->cx2_sn == NULL) {
|
||||
logError(1, "%s %s: ERROR %02X", tag, __func__, ERROR_ALLOC);
|
||||
kfree(node->ix2_fm);
|
||||
kfree(node->cx2_fm);
|
||||
kfree(node->ix2_sn);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
logError(0, "%s Address for Node data = %02X\n", tag, address);
|
||||
|
||||
logError(0, "%s Node Data to read %d bytes\n", tag, size);
|
||||
|
||||
data = (u8 *)kmalloc_array(size, sizeof(u8), GFP_KERNEL);
|
||||
if (data == NULL) {
|
||||
logError(1, "%s %s: ERROR %02X", tag, __func__, ERROR_ALLOC);
|
||||
kfree(node->ix2_fm);
|
||||
kfree(node->cx2_fm);
|
||||
kfree(node->ix2_sn);
|
||||
kfree(node->cx2_sn);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
if (readCmdU16(FTS_CMD_FRAMEBUFFER_R, address, data, size,
|
||||
DUMMY_FRAMEBUFFER) < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_I2C_R);
|
||||
kfree(node->ix2_fm);
|
||||
kfree(node->cx2_fm);
|
||||
kfree(node->ix2_sn);
|
||||
kfree(node->cx2_sn);
|
||||
kfree(data);
|
||||
return ERROR_I2C_R;
|
||||
}
|
||||
|
||||
logError(0, "%s Read node data ok!\n", tag);
|
||||
|
||||
memcpy(node->ix2_fm, data, node->header.force_node);
|
||||
memcpy(node->ix2_sn, &data[node->header.force_node],
|
||||
node->header.sense_node);
|
||||
memcpy(node->cx2_fm,
|
||||
&data[node->header.force_node + node->header.sense_node],
|
||||
node->header.force_node);
|
||||
memcpy(node->cx2_sn,
|
||||
&data[node->header.force_node * 2 + node->header.sense_node],
|
||||
node->header.sense_node);
|
||||
|
||||
kfree(data);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int readSelfSenseCompensationData(u16 type, struct SelfSenseData *data)
|
||||
{
|
||||
|
||||
int ret;
|
||||
u16 address;
|
||||
|
||||
data->ix2_fm = NULL;
|
||||
data->cx2_fm = NULL;
|
||||
data->ix2_sn = NULL;
|
||||
data->cx2_sn = NULL;
|
||||
|
||||
if (!(type == SS_TOUCH || type == SS_KEY || type == SS_HOVER
|
||||
|| type == SS_PROXIMITY)) {
|
||||
logError(1, "%s %s:Choose a SS type of compensation data ",
|
||||
tag, __func__);
|
||||
logError(1, "ERROR %02X\n", ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
ret = requestCompensationData(type);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_REQU_COMP_DATA);
|
||||
return (ret | ERROR_REQU_COMP_DATA);
|
||||
}
|
||||
|
||||
ret = readCompensationDataHeader(type, &(data->header), &address);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_COMP_DATA_HEADER);
|
||||
return (ret|ERROR_COMP_DATA_HEADER);
|
||||
}
|
||||
|
||||
ret = readSelfSenseGlobalData(&address, data);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_COMP_DATA_GLOBAL);
|
||||
return (ret | ERROR_COMP_DATA_GLOBAL);
|
||||
}
|
||||
|
||||
ret = readSelfSenseNodeData(address, data);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_COMP_DATA_NODE);
|
||||
return (ret | ERROR_COMP_DATA_NODE);
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
int readGeneralGlobalData(u16 address, struct GeneralData *global)
|
||||
{
|
||||
u8 data[COMP_DATA_GLOBAL];
|
||||
|
||||
if (readCmdU16(FTS_CMD_FRAMEBUFFER_R, address, data, COMP_DATA_GLOBAL,
|
||||
DUMMY_FRAMEBUFFER) < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_I2C_R);
|
||||
return ERROR_I2C_R;
|
||||
}
|
||||
|
||||
global->ftsd_lp_timer_cal0 = data[0];
|
||||
global->ftsd_lp_timer_cal1 = data[1];
|
||||
global->ftsd_lp_timer_cal2 = data[2];
|
||||
global->ftsd_lp_timer_cal3 = data[3];
|
||||
global->ftsa_lp_timer_cal0 = data[4];
|
||||
global->ftsa_lp_timer_cal1 = data[5];
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
int readGeneralCompensationData(u16 type, struct GeneralData *data)
|
||||
{
|
||||
int ret;
|
||||
u16 address;
|
||||
|
||||
if (!(type == GENERAL_TUNING)) {
|
||||
logError(1, "%s %s:Choose a GENERAL type of compensation data ",
|
||||
tag);
|
||||
logError(1, "ERROR %02X\n", ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
ret = requestCompensationData(type);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_REQU_COMP_DATA);
|
||||
return ERROR_REQU_COMP_DATA;
|
||||
}
|
||||
|
||||
ret = readCompensationDataHeader(type, &(data->header), &address);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_COMP_DATA_HEADER);
|
||||
return ERROR_COMP_DATA_HEADER;
|
||||
}
|
||||
|
||||
ret = readGeneralGlobalData(address, data);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_COMP_DATA_GLOBAL);
|
||||
return ERROR_COMP_DATA_GLOBAL;
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int defaultChipInfo(int i2cError)
|
||||
{
|
||||
int i;
|
||||
|
||||
logError(0, "%s Setting default Chip Info...\n", tag);
|
||||
ftsInfo.u32_echoEn = 0x00000000;
|
||||
ftsInfo.u8_msScrConfigTuneVer = 0;
|
||||
ftsInfo.u8_ssTchConfigTuneVer = 0;
|
||||
ftsInfo.u8_msScrCxmemTuneVer = 0;
|
||||
ftsInfo.u8_ssTchCxmemTuneVer = 0;
|
||||
if (i2cError == 1) {
|
||||
ftsInfo.u16_fwVer = 0xFFFF;
|
||||
ftsInfo.u16_cfgId = 0xFFFF;
|
||||
for (i = 0; i < EXTERNAL_RELEASE_INFO_SIZE; i++)
|
||||
ftsInfo.u8_extReleaseInfo[i] = 0xFF;
|
||||
} else {
|
||||
ftsInfo.u16_fwVer = 0x0000;
|
||||
ftsInfo.u16_cfgId = 0x0000;
|
||||
for (i = 0; i < EXTERNAL_RELEASE_INFO_SIZE; i++)
|
||||
ftsInfo.u8_extReleaseInfo[i] = 0x00;
|
||||
}
|
||||
ftsInfo.u32_mpPassFlag = INIT_FIELD;
|
||||
ftsInfo.u16_errOffset = INVALID_ERROR_OFFS;
|
||||
logError(0, "%s default Chip Info DONE!\n", tag);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int readChipInfo(int doRequest)
|
||||
{
|
||||
int ret, i;
|
||||
u16 answer;
|
||||
u8 data[CHIP_INFO_SIZE + 3];
|
||||
/*+3 because need to read all the field of*/
|
||||
/*the struct plus the signature and 2 address bytes*/
|
||||
int index = 0;
|
||||
|
||||
logError(0, "%s Starting Read Chip Info...\n", tag);
|
||||
if (doRequest == 1) {
|
||||
ret = requestCompensationData(CHIP_INFO);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_REQU_COMP_DATA);
|
||||
ret = (ret | ERROR_REQU_COMP_DATA);
|
||||
goto FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
logError(0, "%s Byte to read = %d bytes\n", tag, CHIP_INFO_SIZE + 3);
|
||||
|
||||
if (readCmdU16(FTS_CMD_FRAMEBUFFER_R, ADDR_FRAMEBUFFER_DATA, data,
|
||||
CHIP_INFO_SIZE + 3, DUMMY_FRAMEBUFFER) < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_I2C_R);
|
||||
ret = ERROR_I2C_R;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
logError(0, "%s Read data ok!\n", tag);
|
||||
|
||||
logError(0, "%s Starting parsing of data...\n", tag);
|
||||
|
||||
if (data[0] != HEADER_SIGNATURE) {
|
||||
logError(1, "%s %s:ERROR ", tag, __func__);
|
||||
logError(1, "%02X The Header Signature is wrong!%02X != %02X\n",
|
||||
ERROR_WRONG_COMP_SIGN, data[0], HEADER_SIGNATURE);
|
||||
ret = ERROR_WRONG_COMP_SIGN;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
u8ToU16_le(&data[1], &answer);
|
||||
|
||||
if (answer != CHIP_INFO) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_DIFF_COMP_TYPE);
|
||||
ret = ERROR_DIFF_COMP_TYPE;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
index += 3;
|
||||
ftsInfo.u8_loadCnt = data[index++];
|
||||
ftsInfo.u8_infoVer = data[index++];
|
||||
u8ToU16(&data[index], &ftsInfo.u16_ftsdId);
|
||||
index += 2;
|
||||
ftsInfo.u8_ftsdVer = data[index++];
|
||||
ftsInfo.u8_ftsaId = data[index++];
|
||||
ftsInfo.u8_ftsaVer = data[index++];
|
||||
ftsInfo.u8_tchRptVer = data[index++];
|
||||
|
||||
logError(0, "%s External Release = ", tag);
|
||||
for (i = 0; i < EXTERNAL_RELEASE_INFO_SIZE; i++) {
|
||||
ftsInfo.u8_extReleaseInfo[i] = data[index++];
|
||||
logError(0, "%02X ", ftsInfo.u8_extReleaseInfo[i]);
|
||||
}
|
||||
logError(0, "\n");
|
||||
|
||||
for (i = 0; i < sizeof(ftsInfo.u8_custInfo); i++)
|
||||
ftsInfo.u8_custInfo[i] = data[index++];
|
||||
|
||||
u8ToU16(&data[index], &ftsInfo.u16_fwVer);
|
||||
index += 2;
|
||||
logError(1, "%s FW VERSION = %04X\n", tag, ftsInfo.u16_fwVer);
|
||||
|
||||
u8ToU16(&data[index], &ftsInfo.u16_cfgId);
|
||||
index += 2;
|
||||
logError(1, "%s CONFIG ID = %04X\n", tag, ftsInfo.u16_cfgId);
|
||||
|
||||
ftsInfo.u32_projId = ((data[index + 3] & 0x000000FF) << 24) +
|
||||
((data[index + 2] & 0x000000FF) << 16) +
|
||||
((data[index + 1] & 0x000000FF) << 8) +
|
||||
(data[index] & 0x000000FF);
|
||||
index += 4;
|
||||
|
||||
u8ToU16(&data[index], &ftsInfo.u16_scrXRes);
|
||||
index += 2;
|
||||
|
||||
u8ToU16(&data[index], &ftsInfo.u16_scrYRes);
|
||||
index += 2;
|
||||
|
||||
ftsInfo.u8_scrForceLen = data[index++];
|
||||
logError(0, "%s Force Len = %d\n", tag, ftsInfo.u8_scrForceLen);
|
||||
|
||||
ftsInfo.u8_scrSenseLen = data[index++];
|
||||
logError(0, "%s Sense Len = %d\n", tag, ftsInfo.u8_scrSenseLen);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
ftsInfo.u64_scrForceEn[i] = data[index++];
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
ftsInfo.u64_scrSenseEn[i] = data[index++];
|
||||
|
||||
ftsInfo.u8_msKeyLen = data[index++];
|
||||
logError(0, "%s MS Key Len = %d\n", tag, ftsInfo.u8_msKeyLen);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
ftsInfo.u64_msKeyForceEn[i] = data[index++];
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
ftsInfo.u64_msKeySenseEn[i] = data[index++];
|
||||
|
||||
ftsInfo.u8_ssKeyLen = data[index++];
|
||||
logError(0, "%s SS Key Len = %d\n", tag, ftsInfo.u8_ssKeyLen);
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
ftsInfo.u64_ssKeyForceEn[i] = data[index++];
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
ftsInfo.u64_ssKeySenseEn[i] = data[index++];
|
||||
|
||||
ftsInfo.u8_frcTchXLen = data[index++];
|
||||
|
||||
ftsInfo.u8_frcTchYLen = data[index++];
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
ftsInfo.u64_frcTchForceEn[i] = data[index++];
|
||||
|
||||
for (i = 0; i < 8; i++)
|
||||
ftsInfo.u64_frcTchSenseEn[i] = data[index++];
|
||||
|
||||
|
||||
ftsInfo.u8_msScrConfigTuneVer = data[index++];
|
||||
logError(0, "%s CFG MS TUNING VERSION = %02X\n",
|
||||
tag, ftsInfo.u8_msScrConfigTuneVer);
|
||||
ftsInfo.u8_msScrLpConfigTuneVer = data[index++];
|
||||
ftsInfo.u8_msScrHwulpConfigTuneVer = data[index++];
|
||||
ftsInfo.u8_msKeyConfigTuneVer = data[index++];
|
||||
ftsInfo.u8_ssTchConfigTuneVer = data[index++];
|
||||
logError(0, "%s CFG SS TUNING VERSION = %02X\n",
|
||||
tag, ftsInfo.u8_ssTchConfigTuneVer);
|
||||
ftsInfo.u8_ssKeyConfigTuneVer = data[index++];
|
||||
ftsInfo.u8_ssHvrConfigTuneVer = data[index++];
|
||||
ftsInfo.u8_frcTchConfigTuneVer = data[index++];
|
||||
ftsInfo.u8_msScrCxmemTuneVer = data[index++];
|
||||
logError(0, "%s CX MS TUNING VERSION = %02X\n",
|
||||
tag, ftsInfo.u8_msScrCxmemTuneVer);
|
||||
ftsInfo.u8_msScrLpCxmemTuneVer = data[index++];
|
||||
ftsInfo.u8_msScrHwulpCxmemTuneVer = data[index++];
|
||||
ftsInfo.u8_msKeyCxmemTuneVer = data[index++];
|
||||
ftsInfo.u8_ssTchCxmemTuneVer = data[index++];
|
||||
logError(0, "%s CX SS TUNING VERSION = %02X\n",
|
||||
tag, ftsInfo.u8_ssTchCxmemTuneVer);
|
||||
ftsInfo.u8_ssKeyCxmemTuneVer = data[index++];
|
||||
ftsInfo.u8_ssHvrCxmemTuneVer = data[index++];
|
||||
ftsInfo.u8_frcTchCxmemTuneVer = data[index++];
|
||||
ftsInfo.u32_mpPassFlag = ((data[index + 3] & 0x000000FF) << 24)
|
||||
+ ((data[index + 2] & 0x000000FF) << 16) +
|
||||
((data[index + 1] & 0x000000FF) << 8) +
|
||||
(data[index] & 0x000000FF);
|
||||
index += 4;
|
||||
logError(0, "%s MP SIGNATURE = %08X\n", tag, ftsInfo.u32_mpPassFlag);
|
||||
ftsInfo.u32_featEn = ((data[index + 3] & 0x000000FF) << 24) +
|
||||
((data[index + 2] & 0x000000FF) << 16) +
|
||||
((data[index + 1] & 0x000000FF) << 8) +
|
||||
(data[index] & 0x000000FF);
|
||||
index += 4;
|
||||
ftsInfo.u32_echoEn = ((data[index + 3] & 0x000000FF) << 24) +
|
||||
((data[index + 2] & 0x000000FF) << 16) +
|
||||
((data[index + 1] & 0x000000FF) << 8) +
|
||||
(data[index] & 0x000000FF);
|
||||
index += 4;
|
||||
logError(0, "%s FEATURES = %08X\n", tag, ftsInfo.u32_echoEn);
|
||||
ftsInfo.u8_sideTchConfigTuneVer = data[index++];
|
||||
ftsInfo.u8_sideTchCxmemTuneVer = data[index++];
|
||||
ftsInfo.u8_sideTchForceLen = data[index++];
|
||||
logError(0, "%s Side Touch Force Len = %d\n",
|
||||
tag, ftsInfo.u8_sideTchForceLen);
|
||||
ftsInfo.u8_sideTchSenseLen = data[index++];
|
||||
logError(0, "%s Side Touch Sense Len = %d\n",
|
||||
tag, ftsInfo.u8_sideTchSenseLen);
|
||||
for (i = 0; i < 8; i++)
|
||||
ftsInfo.u64_sideTchForceEn[i] = data[index++];
|
||||
for (i = 0; i < 8; i++)
|
||||
ftsInfo.u64_sideTchSenseEn[i] = data[index++];
|
||||
ftsInfo.u8_errSign = data[index++];
|
||||
logError(0, "%s ERROR SIGNATURE = %02X\n", tag, ftsInfo.u8_errSign);
|
||||
if (ftsInfo.u8_errSign == ERROR_SIGN_HEAD) {
|
||||
logError(0, "%s Correct Error Signature found!\n", tag);
|
||||
u8ToU16(&data[index], &ftsInfo.u16_errOffset);
|
||||
} else {
|
||||
logError(1, "%s Error Signature NOT FOUND!\n", tag);
|
||||
ftsInfo.u16_errOffset = INVALID_ERROR_OFFS;
|
||||
}
|
||||
logError(0, "%s ERROR OFFSET = %04X\n", tag, ftsInfo.u16_errOffset);
|
||||
index += 2;
|
||||
logError(0, "%s Parsed %d bytes!\n", tag, index);
|
||||
|
||||
|
||||
if (index != CHIP_INFO_SIZE + 3) {
|
||||
logError(1, "%s %s: index = %d different from %d ERROR %02X\n",
|
||||
tag, __func__, index, CHIP_INFO_SIZE + 3,
|
||||
ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
logError(0, "%s Chip Info Read DONE!\n", tag);
|
||||
return OK;
|
||||
|
||||
FAIL:
|
||||
defaultChipInfo(isI2cError(ret));
|
||||
return ret;
|
||||
}
|
||||
|
||||
207
drivers/input/touchscreen/st/fts_lib/ftsCompensation.h
Normal file
207
drivers/input/touchscreen/st/fts_lib/ftsCompensation.h
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS API for Flashing the IC *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FTS_COMPENSATION_H
|
||||
#define __FTS_COMPENSATION_H
|
||||
|
||||
|
||||
#include "ftsCrossCompile.h"
|
||||
#include "ftsSoftware.h"
|
||||
|
||||
|
||||
#define COMP_DATA_READ_RETRY 2
|
||||
|
||||
//Bytes dimension of Compensation Data Format
|
||||
|
||||
#define COMP_DATA_HEADER 8
|
||||
#define COMP_DATA_GLOBAL 8
|
||||
|
||||
|
||||
#define HEADER_SIGNATURE 0xA5
|
||||
#define INVALID_ERROR_OFFS 0xFFFF
|
||||
|
||||
//Possible Compensation/Frame Data Type
|
||||
#define GENERAL_TUNING 0x0100
|
||||
#define MS_TOUCH_ACTIVE 0x0200
|
||||
#define MS_TOUCH_LOW_POWER 0x0400
|
||||
#define MS_TOUCH_ULTRA_LOW_POWER 0x0800
|
||||
#define MS_KEY 0x1000
|
||||
#define SS_TOUCH 0x2000
|
||||
#define SS_KEY 0x4000
|
||||
#define SS_HOVER 0x8000
|
||||
#define SS_PROXIMITY 0x0001
|
||||
#define CHIP_INFO 0xFFFF
|
||||
|
||||
|
||||
#define TIMEOUT_REQU_COMP_DATA 1000 //ms
|
||||
|
||||
//CHIP INFO
|
||||
#define CHIP_INFO_SIZE 161
|
||||
/*bytes to read from framebuffer (exclude the signature and the type*/
|
||||
/*because already checked during the reading)*/
|
||||
#define EXTERNAL_RELEASE_INFO_SIZE 8 //bytes
|
||||
|
||||
struct DataHeader {
|
||||
int force_node, sense_node;
|
||||
u16 type;
|
||||
};
|
||||
|
||||
|
||||
struct MutualSenseData {
|
||||
struct DataHeader header;
|
||||
u8 tuning_ver;
|
||||
u8 cx1;
|
||||
u8 *node_data;
|
||||
int node_data_size;
|
||||
};
|
||||
|
||||
|
||||
struct SelfSenseData {
|
||||
struct DataHeader header;
|
||||
u8 tuning_ver;
|
||||
u8 f_ix1, s_ix1;
|
||||
u8 f_cx1, s_cx1;
|
||||
u8 f_max_n, s_max_n;
|
||||
|
||||
u8 *ix2_fm;
|
||||
u8 *ix2_sn;
|
||||
u8 *cx2_fm;
|
||||
u8 *cx2_sn;
|
||||
};
|
||||
|
||||
|
||||
struct GeneralData {
|
||||
struct DataHeader header;
|
||||
u8 ftsd_lp_timer_cal0;
|
||||
u8 ftsd_lp_timer_cal1;
|
||||
u8 ftsd_lp_timer_cal2;
|
||||
|
||||
u8 ftsd_lp_timer_cal3;
|
||||
u8 ftsa_lp_timer_cal0;
|
||||
u8 ftsa_lp_timer_cal1;
|
||||
};
|
||||
|
||||
struct chipInfo {
|
||||
u8 u8_loadCnt; ///< 03 - Load Counter
|
||||
u8 u8_infoVer; ///< 04 - New chip info version
|
||||
u16 u16_ftsdId; ///< 05 - FTSD ID
|
||||
u8 u8_ftsdVer; ///< 07 - FTSD version
|
||||
u8 u8_ftsaId; ///< 08 - FTSA ID
|
||||
u8 u8_ftsaVer; ///< 09 - FTSA version
|
||||
u8 u8_tchRptVer; ///< 0A - Touch report version (e.g. ST, Samsung etc)
|
||||
|
||||
///< 0B - External release information
|
||||
u8 u8_extReleaseInfo[EXTERNAL_RELEASE_INFO_SIZE];
|
||||
u8 u8_custInfo[12]; ///< 13 - Customer information
|
||||
u16 u16_fwVer; ///< 1F - Firmware version
|
||||
u16 u16_cfgId; ///< 21 - Configuration ID
|
||||
u32 u32_projId; ///< 23 - Project ID
|
||||
u16 u16_scrXRes; ///< 27 - X resolution on main screen
|
||||
u16 u16_scrYRes; ///< 29 - Y resolution on main screen
|
||||
u8 u8_scrForceLen; ///< 2B - Number of force channel on main screen
|
||||
u8 u8_scrSenseLen; ///< 2C - Number of sense channel on main screen
|
||||
u8 u64_scrForceEn[8]; ///< 2D - Force channel enabled on main screen
|
||||
u8 u64_scrSenseEn[8]; ///< 35 - Sense channel enabled on main screen
|
||||
u8 u8_msKeyLen; ///< 3D - Number of MS Key channel
|
||||
u8 u64_msKeyForceEn[8]; ///< 3E - MS Key force channel enable
|
||||
u8 u64_msKeySenseEn[8]; ///< 46 - MS Key sense channel enable
|
||||
u8 u8_ssKeyLen; ///< 4E - Number of SS Key channel
|
||||
u8 u64_ssKeyForceEn[8]; ///< 4F - SS Key force channel enable
|
||||
u8 u64_ssKeySenseEn[8]; ///< 57 - SS Key sense channel enable
|
||||
u8 u8_frcTchXLen; ///< 5F - Number of force touch force channel
|
||||
u8 u8_frcTchYLen; ///< 60 - Number of force touch sense channel
|
||||
u8 u64_frcTchForceEn[8];///< 61 - Force touch force channel enable
|
||||
u8 u64_frcTchSenseEn[8];///< 69 - Force touch sense channel enable
|
||||
u8 u8_msScrConfigTuneVer; ///< 71 - MS screen tuning version in config
|
||||
|
||||
///< 72 - MS screen LP mode tuning version in config
|
||||
u8 u8_msScrLpConfigTuneVer;
|
||||
|
||||
///< 73 - MS screen ultra low power mode tuning version in config
|
||||
u8 u8_msScrHwulpConfigTuneVer;
|
||||
u8 u8_msKeyConfigTuneVer; ///< 74 - MS Key tuning version in config
|
||||
u8 u8_ssTchConfigTuneVer; ///< 75 - SS touch tuning version in config
|
||||
u8 u8_ssKeyConfigTuneVer; ///< 76 - SS Key tuning version in config
|
||||
u8 u8_ssHvrConfigTuneVer; ///< 77 - SS hover tuning version in config
|
||||
|
||||
///< 78 - Force touch tuning version in config
|
||||
u8 u8_frcTchConfigTuneVer;
|
||||
u8 u8_msScrCxmemTuneVer; ///< 79 - MS screen tuning version in cxmem
|
||||
|
||||
///< 7A - MS screen LP mode tuning version in cxmem
|
||||
u8 u8_msScrLpCxmemTuneVer;
|
||||
|
||||
///< 7B - MS screen ultra low power mode tuning version in cxmem
|
||||
u8 u8_msScrHwulpCxmemTuneVer;
|
||||
u8 u8_msKeyCxmemTuneVer; ///< 7C - MS Key tuning version in cxmem
|
||||
u8 u8_ssTchCxmemTuneVer; ///< 7D - SS touch tuning version in cxmem
|
||||
u8 u8_ssKeyCxmemTuneVer; ///< 7E - SS Key tuning version in cxmem
|
||||
u8 u8_ssHvrCxmemTuneVer; ///< 7F - SS hover tuning version in cxmem
|
||||
|
||||
///< 80 - Force touch tuning version in cxmem
|
||||
u8 u8_frcTchCxmemTuneVer;
|
||||
u32 u32_mpPassFlag; ///< 81 - Mass production pass flag
|
||||
u32 u32_featEn; ///< 85 - Supported features
|
||||
|
||||
///< 89 - enable of particular features: first bit is Echo Enables
|
||||
u32 u32_echoEn;
|
||||
|
||||
///< 8D - Side Touch tuning version in config
|
||||
u8 u8_sideTchConfigTuneVer;
|
||||
u8 u8_sideTchCxmemTuneVer; ///< 8E - Side Touch tuning version in cxmem
|
||||
u8 u8_sideTchForceLen; ///< 8F - Number of force channel on side touch
|
||||
u8 u8_sideTchSenseLen; ///< 90 - Number of sense channel on side touch
|
||||
u8 u64_sideTchForceEn[8];///< 91 - Side touch force channel enable
|
||||
u8 u64_sideTchSenseEn[8];///< 99 - Side touch sense channel enable
|
||||
u8 u8_errSign; ///< A1 - Signature for error field
|
||||
u16 u16_errOffset; ///< A2 - Error Offset
|
||||
};
|
||||
|
||||
int requestCompensationData(u16 type);
|
||||
int readCompensationDataHeader(u16 type, struct DataHeader *header,
|
||||
u16 *address);
|
||||
int readMutualSenseGlobalData(u16 *address, struct MutualSenseData *global);
|
||||
int readMutualSenseNodeData(u16 address, struct MutualSenseData *node);
|
||||
int readMutualSenseCompensationData(u16 type, struct MutualSenseData *data);
|
||||
int readSelfSenseGlobalData(u16 *address, struct SelfSenseData *global);
|
||||
int readSelfSenseNodeData(u16 address, struct SelfSenseData *node);
|
||||
int readSelfSenseCompensationData(u16 type, struct SelfSenseData *data);
|
||||
int readGeneralGlobalData(u16 address, struct GeneralData *global);
|
||||
int readGeneralCompensationData(u16 type, struct GeneralData *data);
|
||||
int defaultChipInfo(int i2cError);
|
||||
int readChipInfo(int doRequest);
|
||||
|
||||
#endif
|
||||
77
drivers/input/touchscreen/st/fts_lib/ftsCrossCompile.c
Normal file
77
drivers/input/touchscreen/st/fts_lib/ftsCrossCompile.c
Normal file
|
|
@ -0,0 +1,77 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS Cross Compile *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/of_gpio.h>
|
||||
//#include <linux/sec_sysfs.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/syscalls.h>
|
||||
|
||||
#include "ftsCrossCompile.h"
|
||||
#include "ftsError.h"
|
||||
|
||||
void *stmalloc(size_t size)
|
||||
{
|
||||
return kmalloc(size, GFP_KERNEL);
|
||||
}
|
||||
|
||||
void stfree(void *ptr)
|
||||
{
|
||||
kfree(ptr);
|
||||
}
|
||||
75
drivers/input/touchscreen/st/fts_lib/ftsCrossCompile.h
Normal file
75
drivers/input/touchscreen/st/fts_lib/ftsCrossCompile.h
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2018, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS cross compile *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FTS_CROSS_COMPILE_H
|
||||
#define __FTS_CROSS_COMPILE_H
|
||||
|
||||
//#define NDK
|
||||
//#define DEBUG
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/of_gpio.h>
|
||||
//#include <linux/sec_sysfs.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
#include <linux/fcntl.h>
|
||||
#include <linux/syscalls.h>
|
||||
|
||||
void *stmalloc(size_t size);
|
||||
void stfree(void *ptr);
|
||||
|
||||
#endif
|
||||
262
drivers/input/touchscreen/st/fts_lib/ftsError.c
Normal file
262
drivers/input/touchscreen/st/fts_lib/ftsError.c
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS error/info kernel log reporting *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
|
||||
#include <linux/device.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/hrtimer.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <linux/completion.h>
|
||||
//#include <linux/wakelock.h>
|
||||
#include <linux/pm_wakeup.h>
|
||||
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include "../fts.h"
|
||||
#include "ftsCrossCompile.h"
|
||||
#include "ftsError.h"
|
||||
#include "ftsIO.h"
|
||||
#include "ftsTool.h"
|
||||
#include "ftsCompensation.h"
|
||||
|
||||
static char tag[8] = "[ FTS ]\0";
|
||||
|
||||
|
||||
void logError(int force, const char *msg, ...)
|
||||
{
|
||||
|
||||
if (force == 1
|
||||
#ifdef DEBUG
|
||||
|| 1
|
||||
#endif
|
||||
) {
|
||||
va_list args;
|
||||
|
||||
va_start(args, msg);
|
||||
vprintk(msg, args);
|
||||
va_end(args);
|
||||
}
|
||||
}
|
||||
|
||||
int isI2cError(int error)
|
||||
{
|
||||
if (((error & 0x000000FF) >= (ERROR_I2C_R & 0x000000FF))
|
||||
&& ((error & 0x000000FF) <= (ERROR_I2C_O & 0x000000FF)))
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dumpErrorInfo(void)
|
||||
{
|
||||
int ret, i;
|
||||
u8 data[ERROR_INFO_SIZE] = {0};
|
||||
u32 sign = 0;
|
||||
|
||||
logError(0, "%s %s: Starting dump of error info...\n", tag, __func__);
|
||||
if (ftsInfo.u16_errOffset == INVALID_ERROR_OFFS) {
|
||||
logError(1, "%s %s: Invalid error offset ERROR %02X\n",
|
||||
tag, __func__, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
ret = readCmdU16(FTS_CMD_FRAMEBUFFER_R, ftsInfo.u16_errOffset,
|
||||
data, ERROR_INFO_SIZE, DUMMY_FRAMEBUFFER);
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: reading data ERROR %02X\n",
|
||||
tag, __func__, ret);
|
||||
return ret;
|
||||
}
|
||||
logError(0, "%s %s: Error Info =\n", tag, __func__);
|
||||
u8ToU32(data, &sign);
|
||||
if (sign != ERROR_SIGNATURE)
|
||||
logError(1, "%s %s:Wrong Signature! Data may be invalid!\n",
|
||||
tag, __func__);
|
||||
else
|
||||
logError(1, "%s %s: Error Signature OK! Data are valid!\n",
|
||||
tag, __func__);
|
||||
|
||||
for (i = 0; i < ERROR_INFO_SIZE; i++) {
|
||||
if (i % 4 == 0)
|
||||
logError(1, KERN_ERR "\n%s %s: %d) ",
|
||||
tag, __func__, i / 4);
|
||||
logError(1, "%02X ", data[i]);
|
||||
}
|
||||
logError(1, "\n");
|
||||
|
||||
logError(0, "%s %s: dump of error info FINISHED!\n", tag, __func__);
|
||||
return OK;
|
||||
|
||||
}
|
||||
|
||||
int errorHandler(u8 *event, int size)
|
||||
{
|
||||
int res = OK;
|
||||
struct fts_ts_info *info = NULL;
|
||||
|
||||
if (getClient() != NULL)
|
||||
info = i2c_get_clientdata(getClient());
|
||||
|
||||
if (info == NULL || event == NULL || size <= 1 || event[0] !=
|
||||
EVENTID_ERROR_EVENT) {
|
||||
logError(1, "%s %s: event Null or not correct size! ",
|
||||
tag, __func__, ERROR_OP_NOT_ALLOW);
|
||||
logError(1, "ERROR %08X\n", ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
logError(0, "%s %s: Starting handling...\n", tag, __func__);
|
||||
//TODO: write an error log for undefinied command subtype 0xBA
|
||||
switch (event[1]) {
|
||||
case EVENT_TYPE_ESD_ERROR: //esd
|
||||
res = fts_chip_powercycle(info);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s: ", tag, res);
|
||||
logError(1, "Error performing powercycle ERROR %08X\n");
|
||||
}
|
||||
|
||||
res = fts_system_reset();
|
||||
if (res < OK)
|
||||
logError(1, "%s %s:Cannot reset device ERROR%08X\n",
|
||||
tag, __func__, res);
|
||||
res = (ERROR_HANDLER_STOP_PROC | res);
|
||||
break;
|
||||
|
||||
case EVENT_TYPE_WATCHDOG_ERROR: //watchdog
|
||||
dumpErrorInfo();
|
||||
res = fts_system_reset();
|
||||
if (res < OK)
|
||||
logError(1, "%s %s:Cannot reset device:ERROR%08X\n",
|
||||
tag, __func__, res);
|
||||
res = (ERROR_HANDLER_STOP_PROC | res);
|
||||
break;
|
||||
case EVENT_TYPE_CHECKSUM_ERROR: //CRC ERRORS
|
||||
switch (event[2]) {
|
||||
case CRC_CONFIG_SIGNATURE:
|
||||
logError(1, "%s %s: Config Signature ERROR!\n",
|
||||
tag, __func__);
|
||||
break;
|
||||
case CRC_CONFIG:
|
||||
logError(1, "%s %s:Config CRC ERROR!\n", tag, __func__);
|
||||
break;
|
||||
case CRC_CX_MEMORY:
|
||||
logError(1, "%s %s: CX CRC ERROR!\n", tag, __func__);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case EVENT_TYPE_LOCKDOWN_ERROR:
|
||||
//res = (ERROR_HANDLER_STOP_PROC|res);
|
||||
//stop lockdown code routines in order to retry
|
||||
switch (event[2]) {
|
||||
case 0x01:
|
||||
logError(1, "%s %s:Lockdown code alredy ",
|
||||
tag, __func__);
|
||||
logError(1, "written into the IC!\n");
|
||||
break;
|
||||
case 0x02:
|
||||
logError(1, "%s %s:Lockdown CRC ", tag, __func__);
|
||||
logError(1, "check fail during a WRITE!\n");
|
||||
break;
|
||||
|
||||
case 0x03:
|
||||
logError(1,
|
||||
"%s %s:Lockdown WRITE command format wrong!\n",
|
||||
tag, __func__);
|
||||
break;
|
||||
case 0x04:
|
||||
pr_err("Lockdown Memory Corrupted!\n");
|
||||
logError(1, "%s %s:Please contact ST for support!\n",
|
||||
tag, __func__);
|
||||
break;
|
||||
case 0x11:
|
||||
logError(1,
|
||||
"%s %s:NO Lockdown code to READ into the IC!\n",
|
||||
tag, __func__);
|
||||
break;
|
||||
case 0x12:
|
||||
logError(1,
|
||||
"%s %s:Lockdown code data corrupted\n",
|
||||
tag, __func__);
|
||||
break;
|
||||
case 0x13:
|
||||
logError(1,
|
||||
"%s %s:Lockdown READ command format wrong!\n",
|
||||
tag, __func__);
|
||||
break;
|
||||
case 0x21:
|
||||
pr_err("Exceeded maximum number of\n");
|
||||
logError(1,
|
||||
"%s %s:Lockdown code REWRITE into IC!\n",
|
||||
tag, __func__);
|
||||
break;
|
||||
case 0x22:
|
||||
logError(1, "%s %s:Lockdown CRC check", tag, __func__);
|
||||
logError(1, " fail during a REWRITE!\n");
|
||||
break;
|
||||
case 0x23:
|
||||
logError(1, "%s %s:", tag, __func__);
|
||||
logError(1, "Lockdown REWRITE command format wrong!\n");
|
||||
break;
|
||||
case 0x24:
|
||||
pr_err("Lockdown Memory Corrupted!\n");
|
||||
logError(1, "%s %s:Please contact ST for support!\n",
|
||||
tag, __func__);
|
||||
break;
|
||||
default:
|
||||
logError(1, "%s %s:No valid error type for LOCKDOWN!\n",
|
||||
tag, __func__);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
logError(0, "%s %s: No Action taken!\n", tag, __func__);
|
||||
break;
|
||||
}
|
||||
logError(0, "%s %s: handling Finished! res = %08X\n",
|
||||
tag, __func__, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
181
drivers/input/touchscreen/st/fts_lib/ftsError.h
Normal file
181
drivers/input/touchscreen/st/fts_lib/ftsError.h
Normal file
|
|
@ -0,0 +1,181 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS error/info kernel log reporting *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __FTS_ERROR_H
|
||||
#define __FTS_ERROR_H
|
||||
|
||||
|
||||
//FIRST LEVEL ERROR CODE
|
||||
#define OK (int)(0x00000000)/* No ERROR*/
|
||||
/*allocation of memory failed*/
|
||||
#define ERROR_ALLOC (int)(0x80000001)
|
||||
#define ERROR_I2C_R (int)(0x80000002)//i2c read failed
|
||||
#define ERROR_I2C_W (int)(0x80000003)//i2c write failed
|
||||
#define ERROR_I2C_WR (int)(0x80000004)//i2c write/read failed
|
||||
|
||||
//error during opening i2c device
|
||||
#define ERROR_I2C_O (int)(0x80000005)
|
||||
#define ERROR_OP_NOT_ALLOW (int)(0x80000006)//operation not allowed
|
||||
|
||||
//timeout expired! exceed the max number of
|
||||
//retries or the max waiting time
|
||||
#define ERROR_TIMEOUT (int)(0x80000007)
|
||||
|
||||
//the file that i want to open is not found
|
||||
#define ERROR_FILE_NOT_FOUND (int)(0x80000008)
|
||||
//error during parsing the file
|
||||
#define ERROR_FILE_PARSE (int)(0x80000009)
|
||||
//error during reading the file
|
||||
#define ERROR_FILE_READ (int)(0x8000000A)
|
||||
#define ERROR_LABEL_NOT_FOUND (int)(0x8000000B)//label not found
|
||||
|
||||
//fw in the chip newer than the one in the memmh
|
||||
#define ERROR_FW_NO_UPDATE (int)(0x8000000C)
|
||||
//flash status busy or unknown
|
||||
#define ERROR_FLASH_UNKNOWN (int)(0x8000000D)
|
||||
|
||||
//SECOND LEVEL ERROR CODE
|
||||
//unable to disable the interrupt
|
||||
#define ERROR_DISABLE_INTER (int)(0x80000200)
|
||||
|
||||
//unable to activate the interrupt
|
||||
#define ERROR_ENABLE_INTER (int)(0x80000300)
|
||||
|
||||
#define ERROR_READ_B2 (int)(0x80000400)//B2 command failed
|
||||
|
||||
//unable to read an offset from memory
|
||||
#define ERROR_GET_OFFSET (int)(0x80000500)
|
||||
|
||||
//unable to retrieve the data of a required frame
|
||||
#define ERROR_GET_FRAME_DATA (int)(0x80000600)
|
||||
|
||||
//FW answers with an event that has a
|
||||
//different address respect the request done
|
||||
#define ERROR_DIFF_COMP_TYPE (int)(0x80000700)
|
||||
|
||||
//the signature of the compensation data is not A5
|
||||
#define ERROR_WRONG_COMP_SIGN (int)(0x80000800)
|
||||
//the command Sense On failed
|
||||
#define ERROR_SENSE_ON_FAIL (int)(0x80000900)
|
||||
//the command Sense Off failed
|
||||
#define ERROR_SENSE_OFF_FAIL (int)(0x80000A00)
|
||||
|
||||
//the command SYSTEM RESET failed
|
||||
#define ERROR_SYSTEM_RESET_FAIL (int)(0x80000B00)
|
||||
|
||||
//flash status not ready within a timeout
|
||||
#define ERROR_FLASH_NOT_READY (int)(0x80000C00)
|
||||
|
||||
//unable to retrieve fw_vers or the config_id
|
||||
#define ERROR_FW_VER_READ (int)(0x80000D00)
|
||||
|
||||
//unable to enable/disable the gesture
|
||||
#define ERROR_GESTURE_ENABLE_FAIL (int)(0x80000E00)
|
||||
|
||||
//unable to start to add custom gesture
|
||||
#define ERROR_GESTURE_START_ADD (int)(0x80000F00)
|
||||
|
||||
//unable to finish to add custom gesture
|
||||
#define ERROR_GESTURE_FINISH_ADD (int)(0x80001000)
|
||||
|
||||
//unable to add custom gesture data
|
||||
#define ERROR_GESTURE_DATA_ADD (int)(0x80001100)
|
||||
|
||||
//unable to remove custom gesture data
|
||||
#define ERROR_GESTURE_REMOVE (int)(0x80001200)
|
||||
|
||||
//unable to enable/disable a feature mode in the IC
|
||||
#define ERROR_FEATURE_ENABLE_DISABLE (int)(0x80001300)
|
||||
|
||||
//unable to set/read noise parameter in the IC
|
||||
#define ERROR_NOISE_PARAMETERS (int)(0x80001400)
|
||||
|
||||
//unable to write/rewrite/read lockdown code in the IC
|
||||
#define ERROR_LOCKDOWN_CODE (int)(0x80001500)
|
||||
|
||||
//THIRD LEVEL ERROR CODE
|
||||
//unable to retrieve the force and/or sense length
|
||||
#define ERROR_CH_LEN (int)(0x80010000)
|
||||
|
||||
//compensation data request failed
|
||||
#define ERROR_REQU_COMP_DATA (int)(0x80020000)
|
||||
|
||||
//unable to retrieve the compensation data header
|
||||
#define ERROR_COMP_DATA_HEADER (int)(0x80030000)
|
||||
|
||||
//unable to retrieve the global compensation data
|
||||
#define ERROR_COMP_DATA_GLOBAL (int)(0x80040000)
|
||||
|
||||
//unable to retrieve the compensation data for each node
|
||||
#define ERROR_COMP_DATA_NODE (int)(0x80050000)
|
||||
|
||||
//check of production limits or of fw answers failed
|
||||
#define ERROR_TEST_CHECK_FAIL (int)(0x80060000)
|
||||
#define ERROR_MEMH_READ (int)(0x80070000)//memh reading failed
|
||||
#define ERROR_FLASH_BURN_FAILED (int)(0x80080000)//flash burn failed
|
||||
#define ERROR_MS_TUNING (int)(0x80090000)//ms tuning failed
|
||||
#define ERROR_SS_TUNING (int)(0x800A0000)//ss tuning failed
|
||||
//lp timer calibration failed
|
||||
#define ERROR_LP_TIMER_TUNING (int)(0x800B0000)
|
||||
//save cx data to flash failed
|
||||
#define ERROR_SAVE_CX_TUNING (int)(0x800C0000)
|
||||
|
||||
//stop the poll of the FIFO if particular errors are found
|
||||
#define ERROR_HANDLER_STOP_PROC (int)(0x800D0000)
|
||||
//unable to retrieve echo event
|
||||
#define ERROR_CHECK_ECHO_FAIL (int)(0x800E0000)
|
||||
|
||||
//FOURTH LEVEL ERROR CODE
|
||||
//production data test failed
|
||||
#define ERROR_PROD_TEST_DATA (int)(0x81000000)
|
||||
|
||||
//complete flash procedure failed
|
||||
#define ERROR_FLASH_PROCEDURE (int)(0x82000000)
|
||||
//production ito test failed
|
||||
#define ERROR_PROD_TEST_ITO (int)(0x83000000)
|
||||
|
||||
//production initialization test failed
|
||||
#define ERROR_PROD_TEST_INITIALIZATION (int)(0x84000000)
|
||||
|
||||
//mismatch of the MS or SS tuning_version
|
||||
#define ERROR_GET_INIT_STATUS (int)(0x85000000)
|
||||
|
||||
|
||||
void logError(int force, const char *msg, ...);
|
||||
int isI2cError(int error);
|
||||
int dumpErrorInfo(void);
|
||||
int errorHandler(u8 *event, int size);
|
||||
|
||||
#endif
|
||||
1178
drivers/input/touchscreen/st/fts_lib/ftsFlash.c
Normal file
1178
drivers/input/touchscreen/st/fts_lib/ftsFlash.c
Normal file
File diff suppressed because it is too large
Load diff
109
drivers/input/touchscreen/st/fts_lib/ftsFlash.h
Normal file
109
drivers/input/touchscreen/st/fts_lib/ftsFlash.h
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS API for Flashing the IC *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FTS_FLASH_H
|
||||
#define __FTS_FLASH_H
|
||||
|
||||
|
||||
#include "ftsSoftware.h"
|
||||
|
||||
//Flash possible status
|
||||
#define FLASH_READY 0
|
||||
#define FLASH_BUSY 1
|
||||
#define FLASH_UNKNOWN -1
|
||||
#define FLASH_STATUS_BYTES 1
|
||||
|
||||
|
||||
//Flash timing parameters
|
||||
#define FLASH_RETRY_COUNT 1000
|
||||
#define FLASH_WAIT_BEFORE_RETRY 50 //ms
|
||||
#define FLASH_WAIT_TIME 200 //ms
|
||||
|
||||
|
||||
//PATHS FW FILES
|
||||
//#define PATH_FILE_FW "fw.memh"
|
||||
#ifdef FTM3_CHIP
|
||||
#define PATH_FILE_FW "st_fts.bin"
|
||||
#else
|
||||
#define PATH_FILE_FW "st_fts.ftb"//new bin file structure
|
||||
#endif
|
||||
|
||||
#ifndef FTM3_CHIP
|
||||
#define FLASH_CHUNK (64 * 1024)
|
||||
#define DMA_CHUNK (2 * 1024)
|
||||
#endif
|
||||
|
||||
|
||||
struct Firmware {
|
||||
u8 *data;
|
||||
u16 fw_ver;
|
||||
u16 config_id;
|
||||
u8 externalRelease[EXTERNAL_RELEASE_INFO_SIZE];
|
||||
int data_size;
|
||||
#ifndef FTM3_CHIP
|
||||
u32 sec0_size;
|
||||
u32 sec1_size;
|
||||
u32 sec2_size;
|
||||
u32 sec3_size;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef FTM3_CHIP
|
||||
int flash_status(void);
|
||||
int flash_status_ready(void);
|
||||
int wait_for_flash_ready(void);
|
||||
#else
|
||||
int wait_for_flash_ready(u8 type);
|
||||
int fts_warm_boot(void);
|
||||
int flash_erase_unlock(void);
|
||||
int flash_full_erase(void);
|
||||
int flash_erase_page_by_page(int keep_cx);
|
||||
//int flash_erase_page_by_page_info(int page);
|
||||
int start_flash_dma(void);
|
||||
int fillFlash(u32 address, u8 *data, int size);
|
||||
#endif
|
||||
|
||||
int flash_unlock(void);
|
||||
int fillMemory(u32 address, u8 *data, int size);
|
||||
int getFirmwareVersion(u16 *fw_vers, u16 *config_id);
|
||||
int getFWdata(const char *pathToFile, u8 **data, int *size, int from);
|
||||
int getFWdata_nocheck(const char *pathToFile, u8 **data, int *size, int from);
|
||||
int parseBinFile(u8 *fw_data, int fw_size, struct Firmware *fw, int keep_cx);
|
||||
int readFwFile(const char *path, struct Firmware *fw, int keep_cx);
|
||||
int flash_burn(struct Firmware *fw, int force_burn, int keep_cx);
|
||||
int flashProcedure(const char *path, int force, int keep_cx);
|
||||
|
||||
#endif
|
||||
519
drivers/input/touchscreen/st/fts_lib/ftsFrame.c
Normal file
519
drivers/input/touchscreen/st/fts_lib/ftsFrame.c
Normal file
|
|
@ -0,0 +1,519 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS functions for getting frames *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <stdarg.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/of_gpio.h>
|
||||
//#include <linux/sec_sysfs.h>
|
||||
|
||||
#include "ftsCrossCompile.h"
|
||||
#include "ftsCompensation.h"
|
||||
#include "ftsError.h"
|
||||
#include "ftsFrame.h"
|
||||
#include "ftsHardware.h"
|
||||
#include "ftsIO.h"
|
||||
#include "ftsSoftware.h"
|
||||
#include "ftsTool.h"
|
||||
#include "ftsTime.h"
|
||||
#include "../fts.h"
|
||||
|
||||
static char tag[8] = "[ FTS ]\0";
|
||||
static int sense_len, force_len;
|
||||
|
||||
int getOffsetFrame(u16 address, u16 *offset)
|
||||
{
|
||||
u8 data[2];
|
||||
u8 cmd = { FTS_CMD_FRAMEBUFFER_R };
|
||||
char *temp = NULL;
|
||||
|
||||
if (readCmdU16(cmd, address, data, OFFSET_LENGTH,
|
||||
DUMMY_FRAMEBUFFER) < 0) {
|
||||
logError(1, "%s %S: ERROR %02X\n", tag, __func__, ERROR_I2C_R);
|
||||
return ERROR_I2C_R;
|
||||
}
|
||||
|
||||
u8ToU16(data, offset);
|
||||
temp = printHex("Offest = ", data, OFFSET_LENGTH);
|
||||
if (temp != NULL)
|
||||
logError(0, "%s %s", tag, temp);
|
||||
kfree(temp);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getChannelsLength(void)
|
||||
{
|
||||
int ret;
|
||||
u8 *data = (u8 *)kmalloc_array(2, sizeof(u8), GFP_KERNEL);
|
||||
|
||||
if (data == NULL) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
ret = readB2(ADDR_SENSE_LEN, data, 2);
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_READ_B2);
|
||||
kfree(data);
|
||||
return (ret|ERROR_READ_B2);
|
||||
}
|
||||
|
||||
sense_len = (int)data[0];
|
||||
force_len = (int)data[1];
|
||||
|
||||
logError(0, "%s Force_len = %d Sense_Len = %d\n",
|
||||
tag, force_len, sense_len);
|
||||
kfree(data);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
int getFrameData(u16 address, int size, short **frame)
|
||||
{
|
||||
int i, j, ret;
|
||||
u8 *data = (u8 *)kmalloc_array(size, sizeof(u8), GFP_KERNEL);
|
||||
|
||||
if (data == NULL) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
ret = readCmdU16(FTS_CMD_FRAMEBUFFER_R, address,
|
||||
data, size, DUMMY_FRAMEBUFFER);
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_I2C_R);
|
||||
kfree(data);
|
||||
return ERROR_I2C_R;
|
||||
}
|
||||
j = 0;
|
||||
for (i = 0; i < size; i += 2) {
|
||||
(*frame)[j] = (short)((data[i + 1] << 8) + data[i]);
|
||||
j++;
|
||||
}
|
||||
kfree(data);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
int getMSFrame(u16 type, struct MutualSenseFrame *frame, int keep_first_row)
|
||||
{
|
||||
u16 offset;
|
||||
int ret;
|
||||
|
||||
if (getSenseLen() == 0 || getForceLen() == 0) {
|
||||
ret = getChannelsLength();
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_CH_LEN);
|
||||
return (ret|ERROR_CH_LEN);
|
||||
}
|
||||
}
|
||||
|
||||
ret = getOffsetFrame(type, &offset);
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_GET_OFFSET);
|
||||
return (ret | ERROR_GET_OFFSET);
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case ADDR_RAW_TOUCH:
|
||||
case ADDR_FILTER_TOUCH:
|
||||
case ADDR_NORM_TOUCH:
|
||||
case ADDR_CALIB_TOUCH:
|
||||
if (keep_first_row == 1) {
|
||||
frame->node_data_size = ((force_len + 1) * sense_len);
|
||||
frame->header.force_node = force_len + 1;
|
||||
} else {
|
||||
frame->node_data_size = ((force_len) * sense_len);
|
||||
offset += (sense_len * BYTES_PER_NODE);
|
||||
frame->header.force_node = force_len;
|
||||
}
|
||||
frame->header.sense_node = sense_len;
|
||||
break;
|
||||
case ADDR_NORM_MS_KEY:
|
||||
case ADDR_RAW_MS_KEY:
|
||||
frame->header.force_node = 1;
|
||||
frame->header.sense_node = ftsInfo.u8_msKeyLen;
|
||||
frame->node_data_size = ftsInfo.u8_msKeyLen;
|
||||
break;
|
||||
default:
|
||||
logError(1, "%s %s: ERROR % 02X\n",
|
||||
tag, __func__, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
frame->node_data = (short *)kmalloc_array(frame->node_data_size,
|
||||
sizeof(short), GFP_KERNEL);
|
||||
if (frame->node_data == NULL) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
ret = getFrameData(offset,
|
||||
frame->node_data_size * BYTES_PER_NODE,
|
||||
&(frame->node_data));
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_GET_FRAME_DATA);
|
||||
kfree(frame->node_data);
|
||||
return (ret | ERROR_GET_FRAME_DATA);
|
||||
}
|
||||
// if you want to access one node i,j,
|
||||
//you should compute the offset like:
|
||||
//offset = i * columns + j => frame[i, j]
|
||||
logError(0, "%s Frame acquired!\n", tag);
|
||||
//return the number of data put inside frame
|
||||
return frame->node_data_size;
|
||||
}
|
||||
|
||||
int getSenseLen(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (sense_len != 0)
|
||||
return sense_len;
|
||||
|
||||
if (ftsInfo.u8_scrSenseLen != 0) {
|
||||
sense_len = ftsInfo.u8_scrSenseLen;
|
||||
} else {
|
||||
ret = getChannelsLength();
|
||||
if (ret < OK)
|
||||
return ret;
|
||||
}
|
||||
return sense_len;
|
||||
}
|
||||
|
||||
int getForceLen(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (force_len != 0)
|
||||
return force_len;
|
||||
|
||||
if (ftsInfo.u8_scrForceLen != 0) {
|
||||
force_len = ftsInfo.u8_scrForceLen;
|
||||
} else {
|
||||
ret = getChannelsLength();
|
||||
if (ret < OK)
|
||||
return ret;
|
||||
}
|
||||
return force_len;
|
||||
}
|
||||
|
||||
int requestFrame(u16 type)
|
||||
{
|
||||
int retry = 0;
|
||||
int ret;
|
||||
u16 answer;
|
||||
char *temp = NULL;
|
||||
|
||||
int event_to_search[1];
|
||||
u8 readEvent[FIFO_EVENT_SIZE];
|
||||
|
||||
u8 cmd[3] = { FTS_CMD_REQU_FRAME_DATA, 0x00, 0x00};
|
||||
// B7 is the command for asking frame data
|
||||
event_to_search[0] = (int)EVENTID_FRAME_DATA_READ;
|
||||
|
||||
|
||||
u16ToU8(type, &cmd[1]);
|
||||
|
||||
while (retry < FRAME_DATA_READ_RETRY) {
|
||||
temp = printHex("Command = ", cmd, 3);
|
||||
if (temp != NULL)
|
||||
logError(0, "%s %s", tag, temp);
|
||||
kfree(temp);
|
||||
|
||||
//send the request to the chip to load in memory the Frame Data
|
||||
ret = fts_writeFwCmd(cmd, 3);
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_I2C_W);
|
||||
return ERROR_I2C_W;
|
||||
}
|
||||
ret = pollForEvent(event_to_search,
|
||||
1,
|
||||
readEvent,
|
||||
TIMEOUT_REQU_COMP_DATA);
|
||||
if (ret < OK) {
|
||||
logError(0, "%s Event did not Found at %d attemp!\n",
|
||||
tag, retry + 1);
|
||||
retry += 1;
|
||||
} else {
|
||||
retry = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (retry == FRAME_DATA_READ_RETRY) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_TIMEOUT);
|
||||
return ERROR_TIMEOUT;
|
||||
}
|
||||
u8ToU16_le(&readEvent[1], &answer);
|
||||
|
||||
if (answer == type)
|
||||
return OK;
|
||||
|
||||
logError(1, "%s The event found has a different type of ", tag);
|
||||
logError(1, "Frame data:%02X\n", ERROR_DIFF_COMP_TYPE);
|
||||
return ERROR_DIFF_COMP_TYPE;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int readFrameDataHeader(u16 type, struct DataHeader *header)
|
||||
{
|
||||
u16 offset = ADDR_FRAMEBUFFER_DATA;
|
||||
u16 answer;
|
||||
u8 data[FRAME_DATA_HEADER];
|
||||
|
||||
if (readCmdU16(FTS_CMD_FRAMEBUFFER_R, offset, data,
|
||||
FRAME_DATA_HEADER, DUMMY_FRAMEBUFFER) < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_I2C_R);
|
||||
return ERROR_I2C_R;
|
||||
}
|
||||
logError(0, "%s Read Data Header done!\n", tag);
|
||||
|
||||
if (data[0] != FRAME_HEADER_SIGNATURE) {
|
||||
logError(1, "%s %s %02X Wrong Header Signature !%02X != %02X\n",
|
||||
tag, __func__, ERROR_WRONG_COMP_SIGN, data[0],
|
||||
HEADER_SIGNATURE);
|
||||
return ERROR_WRONG_COMP_SIGN;
|
||||
}
|
||||
|
||||
u8ToU16_le(&data[1], &answer);
|
||||
|
||||
if (answer != type) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_DIFF_COMP_TYPE);
|
||||
return ERROR_DIFF_COMP_TYPE;
|
||||
}
|
||||
|
||||
logError(0, "%s Type of Frame data OK!\n", tag);
|
||||
|
||||
header->type = type;
|
||||
header->force_node = (int)data[4];
|
||||
header->sense_node = (int)data[5];
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getMSFrame2(u16 type, struct MutualSenseFrame *frame)
|
||||
{
|
||||
u16 offset = ADDR_FRAMEBUFFER_DATA+FRAME_DATA_HEADER;
|
||||
int size, ret;
|
||||
|
||||
frame->node_data = NULL;
|
||||
|
||||
if (!(type == MS_TOUCH_ACTIVE || type == MS_TOUCH_LOW_POWER
|
||||
|| type == MS_TOUCH_ULTRA_LOW_POWER
|
||||
|| type == MS_KEY)) {
|
||||
logError(1, "%s %s:Choose a MS type of frame data ERROR %02X\n",
|
||||
tag, __func__, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
ret = requestFrame(type);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s readMutualSenseCompensation:ERROR %02X\n",
|
||||
tag, ERROR_REQU_COMP_DATA);
|
||||
return (ret | ERROR_REQU_COMP_DATA);
|
||||
}
|
||||
|
||||
ret = readFrameDataHeader(type, &(frame->header));
|
||||
if (ret < 0) {
|
||||
logError(1, "%s readMutualSenseCompensationData:ERROR %02X\n",
|
||||
tag, ERROR_COMP_DATA_HEADER);
|
||||
return (ret | ERROR_COMP_DATA_HEADER);
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case MS_TOUCH_ACTIVE:
|
||||
case MS_TOUCH_LOW_POWER:
|
||||
case MS_TOUCH_ULTRA_LOW_POWER:
|
||||
size = frame->header.force_node * frame->header.sense_node;
|
||||
break;
|
||||
case MS_KEY:
|
||||
//or use directly the number in the ftsChip
|
||||
if (frame->header.force_node > frame->header.sense_node)
|
||||
size = frame->header.force_node;
|
||||
else
|
||||
size = frame->header.sense_node;
|
||||
frame->header.force_node = 1;
|
||||
frame->header.sense_node = size;
|
||||
break;
|
||||
|
||||
default:
|
||||
logError(1, "%s %s: ERROR % 02X\n",
|
||||
tag, __func__, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
frame->node_data = (short *)kmalloc_array(size,
|
||||
sizeof(short), GFP_KERNEL);
|
||||
if (frame->node_data == NULL) {
|
||||
logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
ret = getFrameData(offset, size*BYTES_PER_NODE, &(frame->node_data));
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_GET_FRAME_DATA);
|
||||
kfree(frame->node_data);
|
||||
return (ret | ERROR_GET_FRAME_DATA);
|
||||
}
|
||||
// if you want to access one node i,j,
|
||||
//you should compute the offset like:
|
||||
//offset = i * columns + j = > frame[i, j]
|
||||
logError(0, "%s Frame acquired!\n", tag);
|
||||
frame->node_data_size = size;
|
||||
return size;//return the number of data put inside frame
|
||||
|
||||
}
|
||||
|
||||
int getSSFrame2(u16 type, struct SelfSenseFrame *frame)
|
||||
{
|
||||
u16 offset = ADDR_FRAMEBUFFER_DATA + FRAME_DATA_HEADER;
|
||||
int size, ret;
|
||||
short *temp = NULL;
|
||||
|
||||
frame->force_data = NULL;
|
||||
frame->sense_data = NULL;
|
||||
|
||||
if (!(type == SS_TOUCH || type == SS_KEY || type == SS_HOVER
|
||||
|| type == SS_PROXIMITY)) {
|
||||
logError(1, "%s %s:Choose a SS type of frame data ERROR %02X\n",
|
||||
tag, __func__, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
ret = requestFrame(type);
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_REQU_COMP_DATA);
|
||||
return (ret | ERROR_REQU_COMP_DATA);
|
||||
}
|
||||
|
||||
ret = readFrameDataHeader(type, &(frame->header));
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_COMP_DATA_HEADER);
|
||||
return (ret | ERROR_COMP_DATA_HEADER);
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case SS_TOUCH:
|
||||
case SS_HOVER:
|
||||
case SS_PROXIMITY:
|
||||
size = frame->header.force_node + frame->header.sense_node;
|
||||
break;
|
||||
|
||||
default:
|
||||
logError(1, "%s %s: ERROR % 02X\n",
|
||||
tag, __func__, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
|
||||
temp = (short *)kmalloc_array(size, sizeof(short), GFP_KERNEL);
|
||||
if (temp == NULL) {
|
||||
logError(1, "%s %s: temp ERROR %02X\n",
|
||||
tag, __func__, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
ret = getFrameData(offset, size*BYTES_PER_NODE, &temp);
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_GET_FRAME_DATA);
|
||||
kfree(temp);
|
||||
return (ret | ERROR_GET_FRAME_DATA);
|
||||
}
|
||||
|
||||
frame->force_data = (short *)kmalloc_array(frame->header.force_node,
|
||||
sizeof(short), GFP_KERNEL);
|
||||
if (frame->force_data == NULL) {
|
||||
logError(1, "%s %s: frame->force_data ERROR %02X\n",
|
||||
tag, __func__, ERROR_ALLOC);
|
||||
kfree(temp);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
memcpy(frame->force_data, temp,
|
||||
frame->header.force_node * sizeof(short));
|
||||
|
||||
frame->sense_data = (short *)kmalloc_array(frame->header.sense_node,
|
||||
sizeof(short), GFP_KERNEL);
|
||||
if (frame->sense_data == NULL) {
|
||||
logError(1, "%s %s: frame->sense_data ERROR %02X\n",
|
||||
tag, __func__, ERROR_ALLOC);
|
||||
kfree(temp);
|
||||
kfree(frame->force_data);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
memcpy(frame->sense_data, &temp[frame->header.force_node],
|
||||
frame->header.sense_node * sizeof(short));
|
||||
|
||||
logError(0, "%s Frame acquired!\n", tag);
|
||||
kfree(temp);
|
||||
return size; //return the number of data put inside frame
|
||||
}
|
||||
76
drivers/input/touchscreen/st/fts_lib/ftsFrame.h
Normal file
76
drivers/input/touchscreen/st/fts_lib/ftsFrame.h
Normal file
|
|
@ -0,0 +1,76 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS functions for getting frames *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __FTS_FRAME_H
|
||||
#define __FTS_FRAME_H
|
||||
|
||||
#include "ftsSoftware.h"
|
||||
|
||||
//Number of data bytes for each node
|
||||
#define BYTES_PER_NODE 2
|
||||
#define OFFSET_LENGTH 2
|
||||
#define FRAME_DATA_HEADER 8
|
||||
#define FRAME_HEADER_SIGNATURE 0xB5
|
||||
#define FRAME_DATA_READ_RETRY 2
|
||||
|
||||
struct MutualSenseFrame {
|
||||
struct DataHeader header;
|
||||
short *node_data;
|
||||
int node_data_size;
|
||||
};
|
||||
|
||||
struct SelfSenseFrame {
|
||||
struct DataHeader header;
|
||||
short *force_data;
|
||||
short *sense_data;
|
||||
};
|
||||
|
||||
int getOffsetFrame(u16 address, u16 *offset);
|
||||
int getChannelsLength(void);
|
||||
int getFrameData(u16 address, int size, short **frame);
|
||||
int getMSFrame(u16 type, struct MutualSenseFrame *frame, int keep_first_row);
|
||||
//int getMSKeyFrame(u16 type, short **frame);
|
||||
//int getSSFrame(u16 type, short **frame);
|
||||
//int getNmsFrame(u16 type, short ***frames, int * sizes,
|
||||
//int keep_first_row, int fs, int n);
|
||||
int getSenseLen(void);
|
||||
int getForceLen(void);
|
||||
int requestFrame(u16 type);
|
||||
int readFrameDataHeader(u16 type, struct DataHeader *header);
|
||||
int getMSFrame2(u16 type, struct MutualSenseFrame *frame);
|
||||
int getSSFrame2(u16 type, struct SelfSenseFrame *frame);
|
||||
|
||||
#endif
|
||||
|
||||
651
drivers/input/touchscreen/st/fts_lib/ftsGesture.c
Normal file
651
drivers/input/touchscreen/st/fts_lib/ftsGesture.c
Normal file
|
|
@ -0,0 +1,651 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS Gesture Utilities *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#include "ftsSoftware.h"
|
||||
#include "ftsError.h"
|
||||
#include "ftsGesture.h"
|
||||
#include "ftsIO.h"
|
||||
#include "ftsTool.h"
|
||||
|
||||
|
||||
static char tag[8] = "[ FTS ]\0";
|
||||
|
||||
static u8 gesture_mask[GESTURE_MASK_SIZE] = { 0 };
|
||||
static u8 custom_gestures[GESTURE_CUSTOM_NUMBER][GESTURE_CUSTOM_POINTS];
|
||||
static u8 custom_gesture_index[GESTURE_CUSTOM_NUMBER] = { 0 };
|
||||
static int refreshGestureMask;
|
||||
|
||||
u16 gesture_coordinates_x[GESTURE_COORDS_REPORT_MAX] = {0};
|
||||
u16 gesture_coordinates_y[GESTURE_COORDS_REPORT_MAX] = {0};
|
||||
int gesture_coords_reported = ERROR_OP_NOT_ALLOW;
|
||||
struct mutex gestureMask_mutex;
|
||||
|
||||
|
||||
int updateGestureMask(u8 *mask, int size, int en)
|
||||
{
|
||||
u8 temp;
|
||||
int i;
|
||||
|
||||
if (mask == NULL) {
|
||||
logError(1, "%s %s: Mask NULL! ERROR %08X\n",
|
||||
tag, __func__, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
if (size > GESTURE_MASK_SIZE) {
|
||||
logError(1, "%s %s:Size not valid! %d > %d ERROR %08X\n",
|
||||
tag, __func__, size, GESTURE_MASK_SIZE);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
if (en == FEAT_ENABLE) {
|
||||
mutex_lock(&gestureMask_mutex);
|
||||
logError(0, "%s %s:setting gesture mask to enable..\n",
|
||||
tag, __func__);
|
||||
if (mask != NULL) {
|
||||
for (i = 0; i < size; i++) {
|
||||
//back up the gesture enabled
|
||||
gesture_mask[i] = gesture_mask[i] | mask[i];
|
||||
}
|
||||
}
|
||||
refreshGestureMask = 1;
|
||||
logError(0, "%s %s:gesture mask to enable SET!\n",
|
||||
tag, __func__);
|
||||
mutex_unlock(&gestureMask_mutex);
|
||||
return OK;
|
||||
}
|
||||
if (en == FEAT_DISABLE) {
|
||||
mutex_lock(&gestureMask_mutex);
|
||||
logError(0, "%s %s:setting gesture ", tag, __func__);
|
||||
logError(0, "mask to disable...\n");
|
||||
for (i = 0; i < size; i++) {
|
||||
// enabled XOR disabled
|
||||
temp = gesture_mask[i] ^ mask[i];
|
||||
gesture_mask[i] = temp & gesture_mask[i];
|
||||
}
|
||||
logError(0, "%s %s:gesture mask to disable SET!\n",
|
||||
tag, __func__);
|
||||
refreshGestureMask = 1;
|
||||
mutex_unlock(&gestureMask_mutex);
|
||||
return OK;
|
||||
}
|
||||
logError(1, "%s%s:Enable parameter Invalid%d!=%d or%d%:08X",
|
||||
tag, __func__, FEAT_DISABLE,
|
||||
FEAT_ENABLE, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
|
||||
}
|
||||
|
||||
int enableGesture(u8 *mask, int size)
|
||||
{
|
||||
u8 cmd[GESTURE_MASK_SIZE + 2];
|
||||
u8 readData[FIFO_EVENT_SIZE] = {0};
|
||||
int i, res;
|
||||
int event_to_search[4] = { EVENTID_GESTURE,
|
||||
EVENT_TYPE_ENB, 0x00, GESTURE_ENABLE };
|
||||
|
||||
logError(0, "%s Trying to enable gesture...\n", tag);
|
||||
cmd[0] = FTS_CMD_GESTURE_CMD;
|
||||
cmd[1] = GESTURE_ENABLE;
|
||||
|
||||
|
||||
if (size > GESTURE_MASK_SIZE) {
|
||||
logError(1, "%s %s: Size not valid! %d > %d ERROR %08X\n",
|
||||
tag, __func__, size, GESTURE_MASK_SIZE);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
mutex_lock(&gestureMask_mutex);
|
||||
if (mask != NULL) {
|
||||
for (i = 0; i < size; i++) {
|
||||
cmd[i + 2] = mask[i];
|
||||
//back up of the gesture enabled
|
||||
gesture_mask[i] = gesture_mask[i] | mask[i];
|
||||
}
|
||||
while (i < GESTURE_MASK_SIZE) {
|
||||
cmd[i + 2] = gesture_mask[i];
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < GESTURE_MASK_SIZE; i++)
|
||||
cmd[i + 2] = gesture_mask[i];
|
||||
}
|
||||
|
||||
res = fts_writeFwCmd(cmd, GESTURE_MASK_SIZE + 2);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s: ERROR %08X\n", tag, __func__, res);
|
||||
goto END;
|
||||
}
|
||||
|
||||
res = pollForEvent(event_to_search, 4,
|
||||
readData, GENERAL_TIMEOUT);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s: pollForEvent ERROR %08X\n",
|
||||
tag, __func__, res);
|
||||
goto END;
|
||||
}
|
||||
|
||||
if (readData[4] != 0x00) {
|
||||
logError(1, "%s %s: ERROR %08X\n",
|
||||
tag, __func__, ERROR_GESTURE_ENABLE_FAIL);
|
||||
res = ERROR_GESTURE_ENABLE_FAIL;
|
||||
goto END;
|
||||
}
|
||||
|
||||
logError(0, "%s %s: DONE!\n", tag, __func__);
|
||||
res = OK;
|
||||
|
||||
END:
|
||||
mutex_unlock(&gestureMask_mutex);
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
int disableGesture(u8 *mask, int size)
|
||||
{
|
||||
u8 cmd[2 + GESTURE_MASK_SIZE];
|
||||
u8 readData[FIFO_EVENT_SIZE] = {0};
|
||||
u8 temp;
|
||||
int i, res;
|
||||
int event_to_search[4] = { EVENTID_GESTURE,
|
||||
EVENT_TYPE_ENB, 0x00, GESTURE_DISABLE };
|
||||
|
||||
logError(0, "%s Trying to disable gesture...\n", tag);
|
||||
cmd[0] = FTS_CMD_GESTURE_CMD;
|
||||
cmd[1] = GESTURE_DISABLE;
|
||||
|
||||
if (size > GESTURE_MASK_SIZE) {
|
||||
logError(1, "%s %s: Size not valid! %d > %d ERROR %08X\n",
|
||||
tag, __func__, size, GESTURE_MASK_SIZE);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
mutex_lock(&gestureMask_mutex);
|
||||
if (mask != NULL) {
|
||||
for (i = 0; i < size; i++) {
|
||||
cmd[i + 2] = mask[i];
|
||||
// enabled XOR disabled
|
||||
temp = gesture_mask[i] ^ mask[i];
|
||||
gesture_mask[i] = temp & gesture_mask[i];
|
||||
}
|
||||
while (i < GESTURE_MASK_SIZE) {
|
||||
//cmd[i + 2] = gesture_mask[i];
|
||||
//gesture_mask[i] = 0x00;
|
||||
|
||||
cmd[i + 2] = 0x00;
|
||||
//leave untouched the gestures not specified
|
||||
|
||||
i++;
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < GESTURE_MASK_SIZE; i++) {
|
||||
//cmd[i + 2] = gesture_mask[i];
|
||||
cmd[i + 2] = 0xFF;
|
||||
}
|
||||
}
|
||||
|
||||
res = fts_writeFwCmd(cmd, 2 + GESTURE_MASK_SIZE);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s:ERROR %08X\n", tag, __func__, res);
|
||||
goto END;
|
||||
}
|
||||
|
||||
res = pollForEvent(event_to_search, 4, readData, GENERAL_TIMEOUT);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s: pollForEvent ERROR %08X\n",
|
||||
tag, __func__, res);
|
||||
goto END;
|
||||
}
|
||||
|
||||
if (readData[4] != 0x00) {
|
||||
logError(1, "%s %s:ERROR %08X\n",
|
||||
tag, __func__, ERROR_GESTURE_ENABLE_FAIL);
|
||||
res = ERROR_GESTURE_ENABLE_FAIL;
|
||||
goto END;
|
||||
}
|
||||
|
||||
logError(0, "%s %s: DONE!\n", tag, __func__);
|
||||
res = OK;
|
||||
END:
|
||||
mutex_unlock(&gestureMask_mutex);
|
||||
return res;
|
||||
|
||||
}
|
||||
|
||||
int startAddCustomGesture(u8 gestureID)
|
||||
{
|
||||
u8 cmd[3] = { FTS_CMD_GESTURE_CMD, GESTURE_START_ADD, gestureID };
|
||||
int res;
|
||||
u8 readData[FIFO_EVENT_SIZE] = {0};
|
||||
int event_to_search[4] = { EVENTID_GESTURE, EVENT_TYPE_ENB,
|
||||
gestureID, GESTURE_START_ADD };
|
||||
|
||||
res = fts_writeFwCmd(cmd, 3);
|
||||
if (res < OK) {
|
||||
logError(1,
|
||||
"%s%s:Impossible to start adding custom gesture ID:%02X %08X\n",
|
||||
tag, __func__, gestureID, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
res = pollForEvent(event_to_search, 4, readData, GENERAL_TIMEOUT);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s:start add event not found! ERROR %08X\n",
|
||||
tag, __func__, res);
|
||||
return res;
|
||||
}
|
||||
//check of gestureID is redundant
|
||||
if (readData[2] != gestureID || readData[4] != 0x00) {
|
||||
logError(1, "%s %s:start add event status not OK! ERROR %08X\n",
|
||||
tag, __func__, readData[4]);
|
||||
return ERROR_GESTURE_START_ADD;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int finishAddCustomGesture(u8 gestureID)
|
||||
{
|
||||
u8 cmd[3] = { FTS_CMD_GESTURE_CMD,
|
||||
GESTURE_FINISH_ADD, gestureID };
|
||||
int res;
|
||||
u8 readData[FIFO_EVENT_SIZE] = {0};
|
||||
int event_to_search[4] = { EVENTID_GESTURE, EVENT_TYPE_ENB,
|
||||
gestureID, GESTURE_FINISH_ADD };
|
||||
|
||||
res = fts_writeFwCmd(cmd, 3);
|
||||
if (res < OK) {
|
||||
logError(1,
|
||||
"%s%s:Impossible to finish adding custom gestureID:%02X %08X\n",
|
||||
tag, __func__, gestureID, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
res = pollForEvent(event_to_search, 4, readData, GENERAL_TIMEOUT);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s: finish add event not found! ERROR %08X\n",
|
||||
tag, __func__, res);
|
||||
return res;
|
||||
}
|
||||
//check of gestureID is redundant
|
||||
if (readData[2] != gestureID || readData[4] != 0x00) {
|
||||
logError(1,
|
||||
"%s %s:finish add event status not OK! ERROR %08X\n",
|
||||
tag, __func__, readData[4]);
|
||||
return ERROR_GESTURE_FINISH_ADD;
|
||||
}
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int loadCustomGesture(u8 *template, u8 gestureID)
|
||||
{
|
||||
int res, i, wheel;
|
||||
int remaining = GESTURE_CUSTOM_POINTS;
|
||||
int toWrite, offset = 0;
|
||||
u8 cmd[TEMPLATE_CHUNK + 5];
|
||||
int event_to_search[4] = { EVENTID_GESTURE, EVENT_TYPE_ENB,
|
||||
gestureID, GESTURE_DATA_ADD };
|
||||
u8 readData[FIFO_EVENT_SIZE] = {0};
|
||||
|
||||
logError(0, "%s Starting adding custom gesture procedure...\n", tag);
|
||||
|
||||
res = startAddCustomGesture(gestureID);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s:unable to start adding procedure %08X\n",
|
||||
tag, __func__, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
cmd[0] = FTS_CMD_GESTURE_CMD;
|
||||
cmd[1] = GESTURE_DATA_ADD;
|
||||
cmd[2] = gestureID;
|
||||
wheel = 0;
|
||||
while (remaining > 0) {
|
||||
if (remaining > TEMPLATE_CHUNK)
|
||||
toWrite = TEMPLATE_CHUNK;
|
||||
else
|
||||
toWrite = remaining;
|
||||
|
||||
cmd[3] = toWrite;
|
||||
cmd[4] = offset;
|
||||
for (i = 0; i < toWrite; i++)
|
||||
cmd[i + 5] = template[wheel++];
|
||||
|
||||
res = fts_writeFwCmd(cmd, toWrite + 5);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s:unable to start ", tag, __func__);
|
||||
logError(1, "adding procedure %08X\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
res = pollForEvent(event_to_search,
|
||||
4,
|
||||
readData,
|
||||
GENERAL_TIMEOUT);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s: add event not found! ERROR %08X\n",
|
||||
tag, __func__, res);
|
||||
return res;
|
||||
}
|
||||
//check of gestureID is redundant
|
||||
if (readData[2] != gestureID || readData[4] != 0x00) {
|
||||
logError(1, "%s %s:add event status not OK! ",
|
||||
tag, __func__);
|
||||
logError(1, "ERROR %08X\n", readData[4]);
|
||||
return ERROR_GESTURE_DATA_ADD;
|
||||
}
|
||||
|
||||
remaining -= toWrite;
|
||||
offset += toWrite / 2;
|
||||
}
|
||||
|
||||
res = finishAddCustomGesture(gestureID);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s:unable to finish adding procedure! ",
|
||||
tag, __func__);
|
||||
logError(1, "ERROR %08X\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
logError(0, "%s Adding custom gesture procedure DONE!\n", tag);
|
||||
return OK;
|
||||
|
||||
}
|
||||
|
||||
|
||||
int reloadCustomGesture(void)
|
||||
{
|
||||
int res, i;
|
||||
|
||||
logError(0, "%s Starting reload Gesture Template...\n", tag);
|
||||
|
||||
for (i = 0; i < GESTURE_CUSTOM_NUMBER; i++) {
|
||||
if (custom_gesture_index[i] == 1) {
|
||||
res = loadCustomGesture(custom_gestures[i],
|
||||
GESTURE_CUSTOM_OFFSET + i);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s:Impossible load gesture ",
|
||||
tag, __func__);
|
||||
logError(1, "D:%02X %08X\n",
|
||||
GESTURE_CUSTOM_OFFSET + i, res);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
logError(0, "%s Reload Gesture Template DONE!\n", tag);
|
||||
return OK;
|
||||
|
||||
}
|
||||
|
||||
int enterGestureMode(int reload)
|
||||
{
|
||||
u8 cmd = FTS_CMD_GESTURE_MODE;
|
||||
int res, ret;
|
||||
|
||||
res = fts_disableInterrupt();
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s: ERROR %08X\n",
|
||||
tag, __func__, res | ERROR_DISABLE_INTER);
|
||||
return res | ERROR_DISABLE_INTER;
|
||||
}
|
||||
|
||||
if (reload == 1 || refreshGestureMask == 1) {
|
||||
if (reload == 1) {
|
||||
res = reloadCustomGesture();
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s:impossible reload ",
|
||||
tag, __func__);
|
||||
logError(1, "custom gesture %08X\n", res);
|
||||
goto END;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* mandatory steps to set the correct gesture
|
||||
* mask defined by the user
|
||||
*/
|
||||
res = disableGesture(NULL, 0);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s:disableGesture ERROR %08X\n",
|
||||
tag, res);
|
||||
goto END;
|
||||
}
|
||||
|
||||
res = enableGesture(NULL, 0);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s:enableGesture ERROR %08X\n",
|
||||
tag, __func__, res);
|
||||
goto END;
|
||||
}
|
||||
|
||||
refreshGestureMask = 0;
|
||||
/**************************************************/
|
||||
}
|
||||
|
||||
res = fts_writeFwCmd(&cmd, 1);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s:enter gesture mode ERROR %08X\n",
|
||||
tag, __func__, res);
|
||||
goto END;
|
||||
}
|
||||
|
||||
res = OK;
|
||||
END:
|
||||
ret = fts_enableInterrupt();
|
||||
if (ret < OK) {
|
||||
logError(1, "%s %s:fts_enableInterrupt ERROR %08X\n",
|
||||
tag, __func__, res | ERROR_ENABLE_INTER);
|
||||
res |= ret | ERROR_ENABLE_INTER;
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
int addCustomGesture(u8 *data, int size, u8 gestureID)
|
||||
{
|
||||
int index, res, i;
|
||||
|
||||
index = gestureID - GESTURE_CUSTOM_OFFSET;
|
||||
|
||||
logError(0, "%s Starting Custom Gesture Adding procedure...\n", tag);
|
||||
if (size != GESTURE_CUSTOM_POINTS || (gestureID != GES_ID_CUST1
|
||||
&& gestureID != GES_ID_CUST2 && gestureID != GES_ID_CUST3
|
||||
&& gestureID != GES_ID_CUST4 && gestureID != GES_ID_CUST5)) {
|
||||
logError(1, "%s %s:Invalid size(%d) or Custom GestureID ",
|
||||
tag, __func__, size);
|
||||
logError(1, "(%02X)!ERROR%08X\n",
|
||||
size, gestureID, ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
for (i = 0; i < GESTURE_CUSTOM_POINTS; i++)
|
||||
custom_gestures[index][i] = data[i];
|
||||
|
||||
res = loadCustomGesture(custom_gestures[index], gestureID);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s:impossible to load the custom gesture! ",
|
||||
tag, __func__);
|
||||
logError(1, "ERROR %08X\n", res);
|
||||
return res;
|
||||
}
|
||||
|
||||
custom_gesture_index[index] = 1;
|
||||
logError(0, "%s Custom Gesture Adding procedure DONE!\n", tag);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int removeCustomGesture(u8 gestureID)
|
||||
{
|
||||
int res, index;
|
||||
u8 cmd[3] = { FTS_CMD_GESTURE_CMD, GETURE_REMOVE_CUSTOM, gestureID };
|
||||
int event_to_search[4] = { EVENTID_GESTURE, EVENT_TYPE_ENB,
|
||||
gestureID, GETURE_REMOVE_CUSTOM };
|
||||
u8 readData[FIFO_EVENT_SIZE] = {0};
|
||||
|
||||
index = gestureID - GESTURE_CUSTOM_OFFSET;
|
||||
|
||||
logError(0, "%s Starting Custom Gesture Removing procedure...\n", tag);
|
||||
if (gestureID != GES_ID_CUST1 && gestureID != GES_ID_CUST2 &&
|
||||
gestureID != GES_ID_CUST3 && gestureID !=
|
||||
GES_ID_CUST4 && gestureID != GES_ID_CUST5) {
|
||||
logError(1, "%s %s:Invalid Custom GestureID (%02X)! ",
|
||||
tag, __func__, gestureID);
|
||||
logError(1, "ERROR %08X\n", ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
//when a gesture is removed, it is also disabled automatically
|
||||
res = fts_writeFwCmd(cmd, 3);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s:Impossible to remove custom ",
|
||||
tag, __func__);
|
||||
logError(1, "%gesture ID:%02X %08X\n", gestureID, res);
|
||||
return res;
|
||||
}
|
||||
|
||||
res = pollForEvent(event_to_search, 4, readData, GENERAL_TIMEOUT);
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s:remove event not found! ERROR %08X\n",
|
||||
tag, __func__, res);
|
||||
return res;
|
||||
}
|
||||
//check of gestureID is redundant
|
||||
if (readData[2] != gestureID || readData[4] != 0x00) {
|
||||
logError(1, "%s %s:remove event status not OK! ERROR %08X\n",
|
||||
tag, __func__, readData[4]);
|
||||
return ERROR_GESTURE_REMOVE;
|
||||
}
|
||||
|
||||
custom_gesture_index[index] = 0;
|
||||
logError(0, "%s Custom Gesture Remove procedure DONE!\n", tag);
|
||||
return OK;
|
||||
|
||||
}
|
||||
|
||||
int isAnyGestureActive(void)
|
||||
{
|
||||
int res = 0;
|
||||
/*-1 because in any case the last gesture mask byte will*/
|
||||
/*be evaluated with the following if*/
|
||||
while (res < (GESTURE_MASK_SIZE - 1) && gesture_mask[res] == 0)
|
||||
res++;
|
||||
|
||||
if (gesture_mask[res] == 0) {
|
||||
logError(0, "%s %s: All Gestures Disabled!\n", tag, __func__);
|
||||
return FEAT_DISABLE;
|
||||
}
|
||||
|
||||
logError(0, "%s %s:Active Gestures Found! gesture_mask[%d] = %02X!\n",
|
||||
tag, __func__, res, gesture_mask[res]);
|
||||
return FEAT_ENABLE;
|
||||
}
|
||||
|
||||
int gestureIDtoGestureMask(u8 id, u8 *mask)
|
||||
{
|
||||
logError(0, "%s %s: Index = %d Position = %d!\n",
|
||||
tag, __func__, ((int)((id) / 8)), (id % 8));
|
||||
mask[((int)((id) / 8))] |= 0x01 << (id % 8);
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
int readGestureCoords(u8 *event)
|
||||
{
|
||||
int i = 0;
|
||||
u8 rCmd[3] = {FTS_CMD_FRAMEBUFFER_R, 0x00, 0x00 };
|
||||
int res;
|
||||
unsigned char val[GESTURE_COORDS_REPORT_MAX * 4 + 1];
|
||||
|
||||
//the max coordinates to read are GESTURE_COORDS_REPORT_MAX*4
|
||||
//(because each coordinate is a short(*2) and we have x and y)
|
||||
//+ dummy byte
|
||||
if (event[0] != EVENTID_GESTURE
|
||||
|| event[1] != EVENT_TYPE_GESTURE_DTC2) {
|
||||
|
||||
logError(1, "%s %s:The event passsed as argument is invalid! ",
|
||||
tag, __func__);
|
||||
logError(1, "ERROR %08X\n", ERROR_OP_NOT_ALLOW);
|
||||
return ERROR_OP_NOT_ALLOW;
|
||||
}
|
||||
|
||||
rCmd[1] = event[4]; // Offset address L
|
||||
rCmd[2] = event[3]; // Offset address H
|
||||
//number of coords reported L
|
||||
gesture_coords_reported = event[6];
|
||||
//number of coords reported H
|
||||
gesture_coords_reported = (gesture_coords_reported << 8) | event[5];
|
||||
if (gesture_coords_reported > GESTURE_COORDS_REPORT_MAX) {
|
||||
logError(1, "%s%s:FW reported more than:%d points ",
|
||||
tag, __func__, gesture_coords_reported);
|
||||
logError(1, "for gestures!\n");
|
||||
logError(1, " Decreasing to %d\n", GESTURE_COORDS_REPORT_MAX);
|
||||
gesture_coords_reported = GESTURE_COORDS_REPORT_MAX;
|
||||
}
|
||||
|
||||
logError(1, "%s %s: Offset: %02X %02X points = %d\n", tag,
|
||||
__func__, rCmd[1], rCmd[2], gesture_coords_reported);
|
||||
res = fts_readCmd(rCmd, 3, (unsigned char *)val,
|
||||
1 + (gesture_coords_reported * 2));
|
||||
if (res < OK) {
|
||||
logError(1, "%s %s: Cannot read the coordinates! ERROR %08X\n",
|
||||
tag, __func__, res);
|
||||
gesture_coords_reported = ERROR_OP_NOT_ALLOW;
|
||||
return res;
|
||||
}
|
||||
//all the points of the gesture are stored in val
|
||||
for (i = 0; i < gesture_coords_reported; i++) {
|
||||
//ignore first byte data because it is a dummy byte
|
||||
gesture_coordinates_x[i] = (((u16) val[i * 2 + 1 + 1])
|
||||
& 0x0F) << 8 | (((u16) val[i * 2 + 1]) & 0xFF);
|
||||
gesture_coordinates_y[i] =
|
||||
(((u16)val[gesture_coords_reported * 2
|
||||
+ i * 2 + 1 + 1]) & 0x0F) << 8
|
||||
| (((u16)val[gesture_coords_reported * 2
|
||||
+ i * 2 + 1]) & 0xFF);
|
||||
}
|
||||
|
||||
logError(1, "%s %s: Reading Gesture Coordinates DONE!\n",
|
||||
tag, __func__);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int getGestureCoords(u16 *x, u16 *y)
|
||||
{
|
||||
x = gesture_coordinates_x;
|
||||
y = gesture_coordinates_y;
|
||||
logError(1, "%s %s:Number of gesture coordinates returned = %d\n",
|
||||
tag, __func__, gesture_coords_reported);
|
||||
return gesture_coords_reported;
|
||||
}
|
||||
123
drivers/input/touchscreen/st/fts_lib/ftsGesture.h
Normal file
123
drivers/input/touchscreen/st/fts_lib/ftsGesture.h
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS Gesture Utilities *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef _FTS_GESTURE_H_
|
||||
#define _FTS_GESTURE_H_
|
||||
|
||||
#include "ftsHardware.h"
|
||||
|
||||
#define GESTURE_MASK_SIZE 8
|
||||
|
||||
//max number of gestures coordinates reported
|
||||
#define GESTURE_COORDS_REPORT_MAX 32
|
||||
|
||||
// for each custom gesture should be provided 30
|
||||
//points (each point is a couple of x,y)
|
||||
#define GESTURE_CUSTOM_POINTS (30 * 2)
|
||||
|
||||
//fw support up to 5 custom gestures
|
||||
#define GESTURE_CUSTOM_NUMBER 5
|
||||
|
||||
#ifdef FTM3
|
||||
|
||||
//number of points to transfer with each I2C transaction
|
||||
#define TEMPLATE_CHUNK (10 * 2)
|
||||
#else
|
||||
//number of points to transfer with each I2C transaction
|
||||
#define TEMPLATE_CHUNK (5 * 2)
|
||||
#endif
|
||||
|
||||
|
||||
//Gesture IDs
|
||||
#define GES_ID_UNKNOWN 0x00 //no meaningful gesture
|
||||
#define GES_ID_DBLTAP 0x01 //Double Tap
|
||||
#define GES_ID_O 0x02 //'O'
|
||||
#define GES_ID_C 0x03 //'C'
|
||||
#define GES_ID_M 0x04 //'M'
|
||||
#define GES_ID_W 0x05 //'W'
|
||||
#define GES_ID_E 0x06 //'e'
|
||||
#define GES_ID_HFLIP_L2R 0x07 //Left to right line
|
||||
#define GES_ID_HFLIP_R2L 0x08 //Right to left line
|
||||
#define GES_ID_VFLIP_T2D 0x09 //Top to bottom line
|
||||
#define GES_ID_VFLIP_D2T 0x0A //Bottom to Top line
|
||||
#define GES_ID_L 0x0B //'L'
|
||||
#define GES_ID_F 0x0C //'F'
|
||||
#define GES_ID_V 0x0D //'V'
|
||||
#define GES_ID_AT 0x0E //'@'
|
||||
#define GES_ID_S 0x0F //'S'
|
||||
#define GES_ID_Z 0x10 //'Z'
|
||||
#define GES_ID_CUST1 0x11 //Custom gesture 1
|
||||
#define GES_ID_CUST2 0x12 //Custom gesture 2
|
||||
#define GES_ID_CUST3 0x13 //Custom gesture 3
|
||||
#define GES_ID_CUST4 0x14 //Custom gesture 4
|
||||
#define GES_ID_CUST5 0x15 //Custom gesture 5
|
||||
#define GES_ID_LEFTBRACE 0x20 //'<'
|
||||
#define GES_ID_RIGHTBRACE 0x21 //'>'
|
||||
|
||||
#define GESTURE_CUSTOM_OFFSET GES_ID_CUST1
|
||||
|
||||
//Command sub-type
|
||||
#define GESTURE_ENABLE 0x01
|
||||
#define GESTURE_DISABLE 0x02
|
||||
#define GESTURE_ENB_CHECK 0x03
|
||||
#define GESTURE_START_ADD 0x10
|
||||
#define GESTURE_DATA_ADD 0x11
|
||||
#define GESTURE_FINISH_ADD 0x12
|
||||
#define GETURE_REMOVE_CUSTOM 0x13
|
||||
#define GESTURE_CHECK_CUSTOM 0x14
|
||||
|
||||
|
||||
//Event sub-type
|
||||
#define EVENT_TYPE_ENB 0x04
|
||||
#define EVENT_TYPE_CHECK_ENB 0x03
|
||||
#define EVENT_TYPE_GESTURE_DTC1 0x01
|
||||
#define EVENT_TYPE_GESTURE_DTC2 0x02
|
||||
|
||||
int updateGestureMask(u8 *mask, int size, int en);
|
||||
int disableGesture(u8 *mask, int size);
|
||||
int enableGesture(u8 *mask, int size);
|
||||
int startAddCustomGesture(u8 gestureID);
|
||||
int finishAddCustomGesture(u8 gestureID);
|
||||
int loadCustomGesture(u8 *template, u8 gestureID);
|
||||
int reloadCustomGesture(void);
|
||||
int enterGestureMode(int reload);
|
||||
int addCustomGesture(u8 *data, int size, u8 gestureID);
|
||||
int removeCustomGesture(u8 gestureID);
|
||||
int isAnyGestureActive(void);
|
||||
int gestureIDtoGestureMask(u8 id, u8 *mask);
|
||||
int readGestureCoords(u8 *event);
|
||||
int getGestureCoords(u16 *x, u16 *y);
|
||||
|
||||
#endif
|
||||
213
drivers/input/touchscreen/st/fts_lib/ftsHardware.h
Normal file
213
drivers/input/touchscreen/st/fts_lib/ftsHardware.h
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* HW related data **
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __FTS_HARDWARE_H
|
||||
#define __FTS_HARDWARE_H
|
||||
|
||||
//DUMMY BYTES DATA
|
||||
#define DUMMY_HW_REG 1
|
||||
#define DUMMY_FRAMEBUFFER 1
|
||||
#define DUMMY_MEMORY 1
|
||||
|
||||
//DIGITAL CHIP INFO
|
||||
#ifdef FTM3_CHIP
|
||||
#define DCHIP_ID_0 0x39
|
||||
#define DCHIP_ID_1 0x6C
|
||||
#else
|
||||
#define DCHIP_ID_0 0x36
|
||||
#define DCHIP_ID_1 0x70
|
||||
#endif
|
||||
|
||||
#ifdef FTM3_CHIP
|
||||
#define DCHIP_ID_ADDR 0x0007
|
||||
#define DCHIP_FW_VER_ADDR 0x000A
|
||||
#else
|
||||
#define DCHIP_ID_ADDR 0x0004
|
||||
#define DCHIP_FW_VER_ADDR 0x0008
|
||||
#endif
|
||||
|
||||
#define DCHIP_FW_VER_BYTE 2
|
||||
|
||||
//CHUNKS
|
||||
#define READ_CHUNK (2 * 1024)
|
||||
#define WRITE_CHUNK (2 * 1024)
|
||||
#define MEMORY_CHUNK (2 * 1024)
|
||||
|
||||
//PROTOCOL INFO
|
||||
#ifdef FTM3_CHIP
|
||||
#define I2C_SAD 0x49
|
||||
#else
|
||||
#define I2C_SAD 0x49
|
||||
#endif
|
||||
|
||||
#define I2C_INTERFACE //comment if the chip use SPI
|
||||
#define ICR_ADDR 0x0024
|
||||
#define ICR_SPI_VALUE 0x02
|
||||
|
||||
//SYSTEM RESET INFO
|
||||
#ifdef FTM3_CHIP
|
||||
#define SYSTEM_RESET_ADDRESS 0x0023
|
||||
#define SYSTEM_RESET_VALUE 0x01
|
||||
#else
|
||||
#define SYSTEM_RESET_ADDRESS 0x0028
|
||||
#define SYSTEM_RESET_VALUE 0x80
|
||||
#endif
|
||||
|
||||
//INTERRUPT INFO
|
||||
#ifdef FTM3_CHIP
|
||||
#define IER_ADDR 0x001C
|
||||
#else
|
||||
#define IER_ADDR 0x002C
|
||||
#endif
|
||||
|
||||
#define IER_ENABLE 0x41
|
||||
#define IER_DISABLE 0x00
|
||||
|
||||
//FLASH COMMAND
|
||||
|
||||
#define FLASH_CMD_UNLOCK 0xF7
|
||||
|
||||
|
||||
#ifdef FTM3_CHIP
|
||||
#define FLASH_CMD_WRITE_LOWER_64 0xF0
|
||||
#define FLASH_CMD_WRITE_UPPER_64 0xF1
|
||||
#define FLASH_CMD_BURN 0xF2
|
||||
#define FLASH_CMD_ERASE 0xF3
|
||||
#define FLASH_CMD_READSTATUS 0xF4
|
||||
#else
|
||||
#define FLASH_CMD_WRITE_64K 0xF8
|
||||
#define FLASH_CMD_READ_REGISTER 0xF9
|
||||
#define FLASH_CMD_WRITE_REGISTER 0xFA
|
||||
#endif
|
||||
|
||||
//FLASH UNLOCK PARAMETER
|
||||
#define FLASH_UNLOCK_CODE0 0x74
|
||||
#define FLASH_UNLOCK_CODE1 0x45
|
||||
|
||||
#ifndef FTM3_CHIP
|
||||
//FLASH ERASE and DMA PARAMETER
|
||||
#define FLASH_ERASE_UNLOCK_CODE0 0x72
|
||||
#define FLASH_ERASE_UNLOCK_CODE1 0x03
|
||||
#define FLASH_ERASE_UNLOCK_CODE2 0x02
|
||||
#define FLASH_ERASE_CODE0 0x02
|
||||
#define FLASH_ERASE_CODE1 0xC0
|
||||
#define FLASH_DMA_CODE0 0x05
|
||||
#define FLASH_DMA_CODE1 0xC0
|
||||
#define FLASH_DMA_CONFIG 0x06
|
||||
#define FLASH_ERASE_START 0x80
|
||||
#define FLASH_NUM_PAGE 64//number of pages
|
||||
#define FLASH_CX_PAGE_START 61
|
||||
#define FLASH_CX_PAGE_END 62
|
||||
#endif
|
||||
|
||||
|
||||
//FLASH ADDRESS
|
||||
#ifdef FTM3_CHIP
|
||||
#define FLASH_ADDR_SWITCH_CMD 0x00010000
|
||||
#define FLASH_ADDR_CODE 0x00000000
|
||||
#define FLASH_ADDR_CONFIG 0x0001E800
|
||||
#define FLASH_ADDR_CX 0x0001F000
|
||||
#else
|
||||
#define ADDR_WARM_BOOT 0x001E
|
||||
#define WARM_BOOT_VALUE 0x38
|
||||
#define FLASH_ADDR_CODE 0x00000000
|
||||
#define FLASH_ADDR_CONFIG 0x0000FC00
|
||||
#endif
|
||||
|
||||
|
||||
//CRC ADDR
|
||||
#ifdef FTM3_CHIP
|
||||
#define ADDR_CRC_BYTE0 0x00
|
||||
#define ADDR_CRC_BYTE1 0x86
|
||||
#define CRC_MASK 0x02
|
||||
#else
|
||||
#define ADDR_CRC_BYTE0 0x00
|
||||
#define ADDR_CRC_BYTE1 0x74
|
||||
#define CRC_MASK 0x03
|
||||
#endif
|
||||
|
||||
//SIZES FW, CODE, CONFIG, MEMH
|
||||
#ifdef FTM3_CHIP
|
||||
#define FW_HEADER_SIZE 32
|
||||
#define FW_SIZE (int)(128*1024)
|
||||
#define FW_CODE_SIZE (int)(122*1024)
|
||||
#define FW_CONFIG_SIZE (int)(2*1024)
|
||||
#define FW_CX_SIZE (int)(FW_SIZE-FW_CODE_SIZE-FW_CONFIG_SIZE)
|
||||
#define FW_VER_MEMH_BYTE1 193
|
||||
#define FW_VER_MEMH_BYTE0 192
|
||||
#define FW_OFF_CONFID_MEMH_BYTE1 2
|
||||
#define FW_OFF_CONFID_MEMH_BYTE0 1
|
||||
#define FW_BIN_VER_OFFSET 4
|
||||
#define FW_BIN_CONFIG_VER_OFFSET (FW_HEADER_SIZE+FW_CODE_SIZE+1)
|
||||
#else
|
||||
#define FW_HEADER_SIZE 64
|
||||
#define FW_HEADER_SIGNATURE 0xAA55AA55
|
||||
#define FW_FTB_VER 0x00000001
|
||||
#define FW_BYTES_ALIGN 4
|
||||
#define FW_BIN_VER_OFFSET 16
|
||||
#define FW_BIN_CONFIG_VER_OFFSET 20
|
||||
#endif
|
||||
|
||||
//FIFO
|
||||
#define FIFO_EVENT_SIZE 8
|
||||
|
||||
#ifdef FTM3_CHIP
|
||||
#define FIFO_DEPTH 32
|
||||
#else
|
||||
#define FIFO_DEPTH 64
|
||||
#endif
|
||||
|
||||
#define FIFO_CMD_READONE 0x85
|
||||
#define FIFO_CMD_READALL 0x86
|
||||
#define FIFO_CMD_LAST 0x87
|
||||
#define FIFO_CMD_FLUSH 0xA1
|
||||
|
||||
|
||||
//CONSTANT TOTAL CX
|
||||
#ifdef FTM3_CHIP
|
||||
#define CX1_WEIGHT 4
|
||||
#define CX2_WEIGHT 1
|
||||
#else
|
||||
#define CX1_WEIGHT 8
|
||||
#define CX2_WEIGHT 1
|
||||
#endif
|
||||
|
||||
//OP CODES FOR MEMORY (based on protocol)
|
||||
|
||||
#define FTS_CMD_HW_REG_R 0xB6
|
||||
#define FTS_CMD_HW_REG_W 0xB6
|
||||
#define FTS_CMD_FRAMEBUFFER_R 0xD0
|
||||
#define FTS_CMD_FRAMEBUFFER_W 0xD0
|
||||
|
||||
#endif
|
||||
526
drivers/input/touchscreen/st/fts_lib/ftsIO.c
Normal file
526
drivers/input/touchscreen/st/fts_lib/ftsIO.c
Normal file
|
|
@ -0,0 +1,526 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* I2C/SPI Communication **
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <stdarg.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <linux/spi/spidev.h>
|
||||
#include <linux/timekeeping.h>
|
||||
|
||||
#include "ftsSoftware.h"
|
||||
#include "ftsCrossCompile.h"
|
||||
#include "ftsError.h"
|
||||
#include "ftsHardware.h"
|
||||
#include "ftsIO.h"
|
||||
#include "ftsTool.h"
|
||||
#include "../fts.h"
|
||||
|
||||
static char tag[8] = "[ FTS ]\0";
|
||||
static struct i2c_client *client;
|
||||
static u16 I2CSAD;
|
||||
|
||||
int openChannel(struct i2c_client *clt)
|
||||
{
|
||||
client = clt;
|
||||
I2CSAD = clt->addr;
|
||||
logError(0, "%s %s: SAD: %02X\n", tag, __func__, I2CSAD);
|
||||
return OK;
|
||||
}
|
||||
|
||||
struct device *getDev()
|
||||
{
|
||||
if (client != NULL)
|
||||
return &(client->dev);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct i2c_client *getClient()
|
||||
{
|
||||
if (client != NULL)
|
||||
return client;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int fts_readCmd(u8 *cmd, int cmdLength, u8 *outBuf, int byteToRead)
|
||||
{
|
||||
int ret = -1;
|
||||
int retry = 0;
|
||||
struct i2c_msg I2CMsg[2];
|
||||
struct fts_ts_info *info = i2c_get_clientdata(client);
|
||||
uint8_t *buf = info->i2c_data;
|
||||
|
||||
/*
|
||||
* Reassign memory for i2c_data in case length is greater than 32 bytes
|
||||
*/
|
||||
if (info->i2c_data_len < cmdLength + byteToRead + 1) {
|
||||
kfree(info->i2c_data);
|
||||
info->i2c_data = kmalloc(cmdLength + byteToRead + 1,
|
||||
GFP_KERNEL);
|
||||
if (!info->i2c_data) {
|
||||
info->i2c_data_len = 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
info->i2c_data_len = cmdLength + byteToRead + 1;
|
||||
buf = info->i2c_data;
|
||||
}
|
||||
|
||||
//write msg
|
||||
I2CMsg[0].addr = (__u16)I2CSAD;
|
||||
I2CMsg[0].flags = (__u16)0;
|
||||
I2CMsg[0].len = (__u16)cmdLength;
|
||||
I2CMsg[0].buf = buf;
|
||||
|
||||
//read msg
|
||||
I2CMsg[1].addr = (__u16)I2CSAD;
|
||||
I2CMsg[1].flags = I2C_M_RD;
|
||||
I2CMsg[1].len = byteToRead;
|
||||
I2CMsg[1].buf = buf + cmdLength;
|
||||
|
||||
memcpy(buf, cmd, cmdLength);
|
||||
|
||||
if (client == NULL)
|
||||
return ERROR_I2C_O;
|
||||
while (retry < I2C_RETRY && ret < OK) {
|
||||
ret = i2c_transfer(client->adapter, I2CMsg, 2);
|
||||
retry++;
|
||||
if (ret < OK)
|
||||
msleep(I2C_WAIT_BEFORE_RETRY);
|
||||
}
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_I2C_R);
|
||||
return ERROR_I2C_R;
|
||||
}
|
||||
|
||||
memcpy(outBuf, buf + cmdLength, byteToRead);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
int fts_writeCmd(u8 *cmd, int cmdLength)
|
||||
{
|
||||
int ret = -1;
|
||||
int retry = 0;
|
||||
struct i2c_msg I2CMsg[1];
|
||||
struct fts_ts_info *info = i2c_get_clientdata(client);
|
||||
uint8_t *buf = info->i2c_data;
|
||||
|
||||
/*
|
||||
* Reassign memory for i2c_data in case length is greater than 32 bytes
|
||||
*/
|
||||
if (info->i2c_data_len < cmdLength + 1) {
|
||||
kfree(info->i2c_data);
|
||||
info->i2c_data = kmalloc(cmdLength + 1, GFP_KERNEL);
|
||||
if (!info->i2c_data) {
|
||||
info->i2c_data_len = 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
info->i2c_data_len = cmdLength + 1;
|
||||
buf = info->i2c_data;
|
||||
}
|
||||
|
||||
I2CMsg[0].addr = (__u16)I2CSAD;
|
||||
I2CMsg[0].flags = (__u16)0;
|
||||
I2CMsg[0].len = (__u16)cmdLength;
|
||||
I2CMsg[0].buf = buf;
|
||||
|
||||
memcpy(buf, cmd, cmdLength);
|
||||
|
||||
if (client == NULL)
|
||||
return ERROR_I2C_O;
|
||||
while (retry < I2C_RETRY && ret < OK) {
|
||||
ret = i2c_transfer(client->adapter, I2CMsg, 1);
|
||||
retry++;
|
||||
if (ret < OK)
|
||||
msleep(I2C_WAIT_BEFORE_RETRY);
|
||||
//logError(1,"%s fts_writeCmd: attempt %d\n", tag, retry);
|
||||
}
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_I2C_W);
|
||||
return ERROR_I2C_W;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
int fts_writeFwCmd(u8 *cmd, int cmdLength)
|
||||
{
|
||||
int ret = -1;
|
||||
int ret2 = -1;
|
||||
int retry = 0;
|
||||
struct i2c_msg I2CMsg[1];
|
||||
struct fts_ts_info *info = i2c_get_clientdata(client);
|
||||
uint8_t *buf = info->i2c_data;
|
||||
|
||||
/*
|
||||
* Reassign memory for i2c_data in case length is greater than 32 bytes
|
||||
*/
|
||||
if (info->i2c_data_len < cmdLength + 1) {
|
||||
kfree(info->i2c_data);
|
||||
info->i2c_data = kmalloc(cmdLength + 1, GFP_KERNEL);
|
||||
if (!info->i2c_data) {
|
||||
info->i2c_data_len = 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
info->i2c_data_len = cmdLength + 1;
|
||||
buf = info->i2c_data;
|
||||
}
|
||||
|
||||
I2CMsg[0].addr = (__u16)I2CSAD;
|
||||
I2CMsg[0].flags = (__u16)0;
|
||||
I2CMsg[0].len = (__u16)cmdLength;
|
||||
I2CMsg[0].buf = buf;
|
||||
|
||||
memcpy(buf, cmd, cmdLength);
|
||||
|
||||
if (client == NULL)
|
||||
return ERROR_I2C_O;
|
||||
while (retry < I2C_RETRY && (ret < OK || ret2 < OK)) {
|
||||
ret = i2c_transfer(client->adapter, I2CMsg, 1);
|
||||
retry++;
|
||||
if (ret >= 0)
|
||||
ret2 = checkEcho(cmd, cmdLength);
|
||||
if (ret < OK || ret2 < OK)
|
||||
msleep(I2C_WAIT_BEFORE_RETRY);
|
||||
//logError(1,"%s fts_writeCmd: attempt %d\n", tag, retry);
|
||||
}
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_I2C_W);
|
||||
return ERROR_I2C_W;
|
||||
}
|
||||
if (ret2 < OK) {
|
||||
logError(1, "%s %s: check echo ERROR %02X\n",
|
||||
tag, __func__, ret2);
|
||||
return (ret | ERROR_I2C_W);
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
int writeReadCmd(u8 *writeCmd1, int writeCmdLength, u8 *readCmd1,
|
||||
int readCmdLength, u8 *outBuf, int byteToRead)
|
||||
{
|
||||
int ret = -1;
|
||||
int retry = 0;
|
||||
struct i2c_msg I2CMsg[3];
|
||||
struct fts_ts_info *info = i2c_get_clientdata(client);
|
||||
uint8_t *buf = info->i2c_data;
|
||||
uint8_t wr_len = writeCmdLength + readCmdLength + byteToRead;
|
||||
|
||||
/*
|
||||
* Reassign memory for i2c_data in case length is greater than 32 bytes
|
||||
*/
|
||||
if (info->i2c_data_len < wr_len + 1) {
|
||||
kfree(info->i2c_data);
|
||||
info->i2c_data = kmalloc(wr_len + 1, GFP_KERNEL);
|
||||
if (!info->i2c_data) {
|
||||
info->i2c_data_len = 0;
|
||||
return -ENOMEM;
|
||||
}
|
||||
info->i2c_data_len = wr_len + 1;
|
||||
buf = info->i2c_data;
|
||||
}
|
||||
|
||||
//write msg
|
||||
I2CMsg[0].addr = (__u16)I2CSAD;
|
||||
I2CMsg[0].flags = (__u16)0;
|
||||
I2CMsg[0].len = (__u16)writeCmdLength;
|
||||
I2CMsg[0].buf = buf;
|
||||
|
||||
//write msg
|
||||
I2CMsg[1].addr = (__u16)I2CSAD;
|
||||
I2CMsg[1].flags = (__u16)0;
|
||||
I2CMsg[1].len = (__u16)readCmdLength;
|
||||
I2CMsg[1].buf = buf + writeCmdLength;
|
||||
|
||||
//read msg
|
||||
I2CMsg[2].addr = (__u16)I2CSAD;
|
||||
I2CMsg[2].flags = I2C_M_RD;
|
||||
I2CMsg[2].len = byteToRead;
|
||||
I2CMsg[2].buf = buf + writeCmdLength + readCmdLength;
|
||||
|
||||
memcpy(buf, writeCmd1, writeCmdLength);
|
||||
memcpy(buf + writeCmdLength, readCmd1, readCmdLength);
|
||||
|
||||
if (client == NULL)
|
||||
return ERROR_I2C_O;
|
||||
while (retry < I2C_RETRY && ret < OK) {
|
||||
ret = i2c_transfer(client->adapter, I2CMsg, 3);
|
||||
retry++;
|
||||
if (ret < OK)
|
||||
msleep(I2C_WAIT_BEFORE_RETRY);
|
||||
}
|
||||
|
||||
if (ret < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_I2C_WR);
|
||||
return ERROR_I2C_WR;
|
||||
}
|
||||
|
||||
memcpy(outBuf, buf + writeCmdLength + readCmdLength, byteToRead);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
int readCmdU16(u8 cmd, u16 address, u8 *outBuf, int byteToRead,
|
||||
int hasDummyByte)
|
||||
{
|
||||
int remaining = byteToRead;
|
||||
int toRead = 0;
|
||||
u8 rCmd[3] = { cmd, 0x00, 0x00 };
|
||||
|
||||
u8 *buff = (u8 *)kmalloc_array(READ_CHUNK + 1, sizeof(u8), GFP_KERNEL);
|
||||
|
||||
if (buff == NULL) {
|
||||
logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
while (remaining > 0) {
|
||||
if (remaining >= READ_CHUNK) {
|
||||
toRead = READ_CHUNK;
|
||||
remaining -= READ_CHUNK;
|
||||
} else {
|
||||
toRead = remaining;
|
||||
remaining = 0;
|
||||
}
|
||||
|
||||
rCmd[1] = (u8)((address & 0xFF00) >> 8);
|
||||
rCmd[2] = (u8)(address & 0xFF);
|
||||
|
||||
if (hasDummyByte) {
|
||||
if (fts_readCmd(rCmd, 3, buff, toRead + 1) < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_I2C_R);
|
||||
kfree(buff);
|
||||
return ERROR_I2C_R;
|
||||
}
|
||||
memcpy(outBuf, buff + 1, toRead);
|
||||
} else {
|
||||
if (fts_readCmd(rCmd, 3, buff, toRead) < 0)
|
||||
return ERROR_I2C_R;
|
||||
memcpy(outBuf, buff, toRead);
|
||||
}
|
||||
|
||||
address += toRead;
|
||||
outBuf += toRead;
|
||||
}
|
||||
kfree(buff);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
int writeCmdU16(u8 WriteCmd, u16 address, u8 *dataToWrite, int byteToWrite)
|
||||
{
|
||||
int remaining = byteToWrite;
|
||||
int toWrite = 0;
|
||||
|
||||
u8 *buff = (u8 *)kmalloc_array(WRITE_CHUNK + 3, sizeof(u8), GFP_KERNEL);
|
||||
|
||||
if (buff == NULL) {
|
||||
logError(1, "%s %s: ERROR %02X\n", tag, __func__, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
buff[0] = WriteCmd;
|
||||
|
||||
while (remaining > 0) {
|
||||
if (remaining >= WRITE_CHUNK) {
|
||||
toWrite = WRITE_CHUNK;
|
||||
remaining -= WRITE_CHUNK;
|
||||
} else {
|
||||
toWrite = remaining;
|
||||
remaining = 0;
|
||||
}
|
||||
|
||||
buff[1] = (u8)((address & 0xFF00) >> 8);
|
||||
buff[2] = (u8)(address & 0xFF);
|
||||
memcpy(buff + 3, dataToWrite, toWrite);
|
||||
if (fts_writeCmd(buff, 3 + toWrite) < 0) {
|
||||
logError(1, "%s %s: ERROR %02\n",
|
||||
tag, __func__, ERROR_I2C_W);
|
||||
kfree(buff);
|
||||
return ERROR_I2C_W;
|
||||
}
|
||||
address += toWrite;
|
||||
dataToWrite += toWrite;
|
||||
}
|
||||
|
||||
kfree(buff);
|
||||
return OK;
|
||||
}
|
||||
|
||||
int writeCmdU32(u8 writeCmd1, u8 writeCmd2, u32 address, u8 *dataToWrite,
|
||||
int byteToWrite)
|
||||
{
|
||||
int remaining = byteToWrite;
|
||||
int toWrite = 0;
|
||||
int ret;
|
||||
|
||||
u8 buff1[3] = { writeCmd1, 0x00, 0x00 };
|
||||
u8 *buff2 = (u8 *)kmalloc_array(WRITE_CHUNK + 3,
|
||||
sizeof(u8), GFP_KERNEL);
|
||||
|
||||
if (buff2 == NULL) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
buff2[0] = writeCmd2;
|
||||
|
||||
|
||||
while (remaining > 0) {
|
||||
if (remaining >= WRITE_CHUNK) {
|
||||
toWrite = WRITE_CHUNK;
|
||||
remaining -= WRITE_CHUNK;
|
||||
} else {
|
||||
toWrite = remaining;
|
||||
remaining = 0;
|
||||
}
|
||||
|
||||
buff1[1] = (u8)((address & 0xFF000000) >> 24);
|
||||
buff1[2] = (u8)((address & 0x00FF0000) >> 16);
|
||||
buff2[1] = (u8)((address & 0x0000FF00) >> 8);
|
||||
buff2[2] = (u8)(address & 0xFF);
|
||||
memcpy(buff2 + 3, dataToWrite, toWrite);
|
||||
|
||||
if (fts_writeCmd(buff1, 3) < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_I2C_W);
|
||||
ret = ERROR_I2C_W;
|
||||
goto END;
|
||||
}
|
||||
if (fts_writeCmd(buff2, 3 + toWrite) < 0) {
|
||||
logError(1, "%s %s: ERROR %02X\n",
|
||||
tag, __func__, ERROR_I2C_W);
|
||||
ret = ERROR_I2C_W;
|
||||
goto END;
|
||||
}
|
||||
|
||||
address += toWrite;
|
||||
dataToWrite += toWrite;
|
||||
}
|
||||
|
||||
ret = OK;
|
||||
END:
|
||||
kfree(buff2);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int writeReadCmdU32(u8 wCmd, u8 rCmd, u32 address, u8 *outBuf,
|
||||
int byteToRead, int hasDummyByte)
|
||||
{
|
||||
int remaining = byteToRead;
|
||||
int toRead = 0;
|
||||
u8 reaCmd[3];
|
||||
u8 wriCmd[3];
|
||||
|
||||
u8 *buff = (u8 *)kmalloc_array(READ_CHUNK + 1, sizeof(u8), GFP_KERNEL);
|
||||
|
||||
if (buff == NULL) {
|
||||
logError(1, "%s writereadCmd32: ERROR %02X\n",
|
||||
tag, ERROR_ALLOC);
|
||||
return ERROR_ALLOC;
|
||||
}
|
||||
|
||||
reaCmd[0] = rCmd;
|
||||
wriCmd[0] = wCmd;
|
||||
|
||||
while (remaining > 0) {
|
||||
if (remaining >= READ_CHUNK) {
|
||||
toRead = READ_CHUNK;
|
||||
remaining -= READ_CHUNK;
|
||||
} else {
|
||||
toRead = remaining;
|
||||
remaining = 0;
|
||||
}
|
||||
|
||||
wriCmd[1] = (u8)((address & 0xFF000000) >> 24);
|
||||
wriCmd[2] = (u8)((address & 0x00FF0000) >> 16);
|
||||
|
||||
reaCmd[1] = (u8)((address & 0x0000FF00) >> 8);
|
||||
reaCmd[2] = (u8)(address & 0x000000FF);
|
||||
|
||||
if (hasDummyByte) {
|
||||
if (writeReadCmd(wriCmd, 3, reaCmd, 3,
|
||||
buff, toRead + 1) < 0) {
|
||||
logError(1, "%s writeCmdU32: ERROR %02X\n",
|
||||
tag, ERROR_I2C_WR);
|
||||
kfree(buff);
|
||||
return ERROR_I2C_WR;
|
||||
}
|
||||
memcpy(outBuf, buff + 1, toRead);
|
||||
} else {
|
||||
if (writeReadCmd(wriCmd, 3, reaCmd,
|
||||
3, buff, toRead) < 0)
|
||||
return ERROR_I2C_WR;
|
||||
memcpy(outBuf, buff, toRead);
|
||||
}
|
||||
|
||||
address += toRead;
|
||||
outBuf += toRead;
|
||||
}
|
||||
|
||||
kfree(buff);
|
||||
return OK;
|
||||
}
|
||||
64
drivers/input/touchscreen/st/fts_lib/ftsIO.h
Normal file
64
drivers/input/touchscreen/st/fts_lib/ftsIO.h
Normal file
|
|
@ -0,0 +1,64 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* I2C/SPI Communication **
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __FTS_IO_H
|
||||
#define __FTS_IO_H
|
||||
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
|
||||
#include "ftsSoftware.h"
|
||||
#include "ftsCrossCompile.h"
|
||||
|
||||
#define I2C_RETRY 3 //number of retry
|
||||
#define I2C_WAIT_BEFORE_RETRY 2 //ms
|
||||
|
||||
int openChannel(struct i2c_client *clt);
|
||||
struct device *getDev(void);
|
||||
struct i2c_client *getClient(void);
|
||||
int fts_readCmd(u8 *cmd, int cmdLenght, u8 *outBuf, int byteToRead);
|
||||
int fts_writeCmd(u8 *cmd, int cmdLenght);
|
||||
int fts_writeFwCmd(u8 *cmd, int cmdLenght);
|
||||
int writeReadCmd(u8 *writeCmd, int writeCmdLenght, u8 *readCmd,
|
||||
int readCmdLenght, u8 *outBuf, int byteToRead);
|
||||
int readCmdU16(u8 cmd, u16 address, u8 *outBuf, int byteToRead,
|
||||
int hasDummyByte);
|
||||
int writeCmdU16(u8 WriteCmd, u16 address, u8 *dataToWrite, int byteToWrite);
|
||||
int writeCmdU32(u8 writeCmd1, u8 writeCmd2, u32 address, u8 *dataToWrite,
|
||||
int byteToWrite);
|
||||
int writeReadCmdU32(u8 wCmd, u8 rCmd, u32 address, u8 *outBuf, int byteToRead,
|
||||
int hasDummyByte);
|
||||
|
||||
#endif
|
||||
191
drivers/input/touchscreen/st/fts_lib/ftsSoftware.h
Normal file
191
drivers/input/touchscreen/st/fts_lib/ftsSoftware.h
Normal file
|
|
@ -0,0 +1,191 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
*************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FW related data *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FTS_SOFTWARE_H
|
||||
#define __FTS_SOFTWARE_H
|
||||
|
||||
#include <linux/types.h>
|
||||
|
||||
#include "ftsHardware.h"
|
||||
|
||||
#define ECHO_ENABLED 0x00000001
|
||||
|
||||
//FTS FW COMMAND
|
||||
#define FTS_CMD_MS_MT_SENSE_OFF 0x92
|
||||
#define FTS_CMD_MS_MT_SENSE_ON 0x93
|
||||
#define FTS_CMD_SS_HOVER_OFF 0x94
|
||||
#define FTS_CMD_SS_HOVER_ON 0x95
|
||||
#define FTS_CMD_LP_TIMER_CALIB 0x97
|
||||
#define FTS_CMD_MS_KEY_OFF 0x9A
|
||||
#define FTS_CMD_MS_KEY_ON 0x9B
|
||||
#define FTS_CMD_MS_COMP_TUNING 0xA3
|
||||
#define FTS_CMD_SS_COMP_TUNING 0xA4
|
||||
#define FTS_CMD_FULL_INITIALIZATION 0xA5
|
||||
#define FTS_CMD_ITO_CHECK 0xA7
|
||||
#define FTS_CMD_RELEASE_INFO 0xAA
|
||||
#define FTS_CMD_GESTURE_MODE 0xAD
|
||||
#define FTS_CMD_REQU_FW_CONF 0xB2
|
||||
#define FTS_CMD_REQU_FRAME_DATA 0xB7
|
||||
#define FTS_CMD_REQU_COMP_DATA 0xB8
|
||||
#define FTS_CMD_WRITE_MP_FLAG 0xC0
|
||||
#define FTS_CMD_FEATURE_ENABLE 0xC1
|
||||
#define FTS_CMD_FEATURE_DISABLE 0xC2
|
||||
#define FTS_CMD_GESTURE_CMD 0xC3
|
||||
#define FTS_CMD_LOCKDOWN_CMD 0xC4
|
||||
#define FTS_CMD_NOISE_WRITE 0xC7
|
||||
#define FTS_CMD_NOISE_READ 0xC8
|
||||
#define FTS_CMD_LOCKDOWN_FILL 0xCA
|
||||
#define FTS_CMD_LOCKDOWN_WRITE 0xCB
|
||||
#define FTS_CMD_LOCKDOWN_READ 0xCC
|
||||
#define FTS_CMD_SAVE_CX_TUNING 0xFC
|
||||
|
||||
//Event ID
|
||||
#define EVENTID_NO_EVENT 0x00
|
||||
#define EVENTID_ERROR_EVENT 0x0F
|
||||
#define EVENTID_CONTROL_READY 0x10
|
||||
#define EVENTID_FW_CONFIGURATION 0x12
|
||||
#define EVENTID_COMP_DATA_READ 0x13
|
||||
#define EVENTID_STATUS_UPDATE 0x16
|
||||
#define EVENTID_RELEASE_INFO 0x1C
|
||||
#define EVENTID_LOCKDOWN_INFO 0x1E
|
||||
#define EVENTID_ENTER_POINTER 0x03
|
||||
#define EVENTID_LEAVE_POINTER 0x04
|
||||
#define EVENTID_MOTION_POINTER 0x05
|
||||
#define EVENTID_HOVER_ENTER_POINTER 0x07
|
||||
#define EVENTID_HOVER_LEAVE_POINTER 0x08
|
||||
#define EVENTID_HOVER_MOTION_POINTER 0x09
|
||||
#define EVENTID_PROXIMITY_ENTER 0x0B
|
||||
#define EVENTID_PROXIMITY_LEAVE 0x0C
|
||||
#define EVENTID_KEY_STATUS 0x0E
|
||||
#define EVENTID_LOCKDOWN_INFO_READ 0x1E
|
||||
#define EVENTID_NOISE_READ 0x17
|
||||
#define EVENTID_NOISE_WRITE 0x18
|
||||
#define EVENTID_GESTURE 0x22
|
||||
#define EVENTID_FRAME_DATA_READ 0x25
|
||||
#define EVENTID_ECHO 0xEC
|
||||
#define EVENTID_LAST (EVENTID_FRAME_DATA_READ+1)
|
||||
|
||||
//EVENT TYPE
|
||||
#define EVENT_TYPE_MS_TUNING_CMPL 0x01
|
||||
#define EVENT_TYPE_SS_TUNING_CMPL 0x02
|
||||
#define EVENT_TYPE_COMP_DATA_SAVED 0x04
|
||||
#define EVENT_TYPE_ITO 0x05
|
||||
#define EVENT_TYPE_FULL_INITIALIZATION 0x07
|
||||
#define EVENT_TYPE_LPTIMER_TUNING_CMPL 0x20
|
||||
#define EVENT_TYPE_ESD_ERROR 0x0A
|
||||
#define EVENT_TYPE_WATCHDOG_ERROR 0x01
|
||||
#define EVENT_TYPE_CHECKSUM_ERROR 0x03
|
||||
#define EVENT_TYPE_LOCKDOWN 0x0A
|
||||
#define EVENT_TYPE_LOCKDOWN_WRITE 0x08
|
||||
#define EVENT_TYPE_LOCKDOWN_ERROR 0x0B
|
||||
|
||||
//CRC type
|
||||
#define CRC_CONFIG_SIGNATURE 0x01
|
||||
#define CRC_CONFIG 0x02
|
||||
#define CRC_CX_MEMORY 0x03
|
||||
|
||||
// CONFIG ID INFO
|
||||
#define CONFIG_ID_ADDR 0x0001
|
||||
#define CONFIG_ID_BYTE 2
|
||||
|
||||
//ADDRESS OFFSET IN SYSINFO
|
||||
#define ADDR_RAW_TOUCH 0x0000
|
||||
#define ADDR_FILTER_TOUCH 0x0002
|
||||
#define ADDR_NORM_TOUCH 0x0004
|
||||
#define ADDR_CALIB_TOUCH 0x0006
|
||||
#define ADDR_RAW_HOVER_FORCE 0x000A
|
||||
#define ADDR_RAW_HOVER_SENSE 0x000C
|
||||
#define ADDR_FILTER_HOVER_FORCE 0x000E
|
||||
#define ADDR_FILTER_HOVER_SENSE 0x0010
|
||||
#define ADDR_NORM_HOVER_FORCE 0x0012
|
||||
#define ADDR_NORM_HOVER_SENSE 0x0014
|
||||
#define ADDR_CALIB_HOVER_FORCE 0x0016
|
||||
#define ADDR_CALIB_HOVER_SENSE 0x0018
|
||||
#define ADDR_RAW_PRX_FORCE 0x001A
|
||||
#define ADDR_RAW_PRX_SENSE 0x001C
|
||||
#define ADDR_FILTER_PRX_FORCE 0x001E
|
||||
#define ADDR_FILTER_PRX_SENSE 0x0020
|
||||
#define ADDR_NORM_PRX_FORCE 0x0022
|
||||
#define ADDR_NORM_PRX_SENSE 0x0024
|
||||
#define ADDR_CALIB_PRX_FORCE 0x0026
|
||||
#define ADDR_CALIB_PRX_SENSE 0x0028
|
||||
#define ADDR_RAW_MS_KEY 0x0032
|
||||
#define ADDR_NORM_MS_KEY 0x0036
|
||||
#define ADDR_COMP_DATA 0x0050
|
||||
#define ADDR_FRAMEBUFFER_DATA 0x8000
|
||||
|
||||
//ADDRESS FW REGISTER
|
||||
#define ADDR_SENSE_LEN 0x0014
|
||||
#define ADDR_FORCE_LEN 0x0015
|
||||
#define ADDR_MS_TUNING_VER 0x0729
|
||||
#define ADDR_SS_TUNING_VER 0x074E
|
||||
|
||||
//B2 INFO
|
||||
#define B2_DATA_BYTES 4
|
||||
//number of bytes
|
||||
#define B2_CHUNK ((FIFO_DEPTH/2)*B2_DATA_BYTES)
|
||||
|
||||
//FEATURES
|
||||
#define FEAT_GLOVE 0x00000001
|
||||
#define FEAT_STYLUS 0x00000002
|
||||
#define FEAT_COVER 0x00000004
|
||||
#define FEAT_CHARGER 0x00000008
|
||||
#define FEAT_VR 0x00000010
|
||||
#define FEAT_EDGE_REJECTION 0x00000020
|
||||
#define FEAT_CORNER_REJECTION 0x00000040
|
||||
#define FEAT_EDGE_PALM_REJECTION 0x00000100
|
||||
|
||||
//TOUCH SIZE
|
||||
#define STYLUS_SIZE 0x01
|
||||
#define FINGER_SIZE 0x02
|
||||
#define LARGE_SIZE 0x03
|
||||
|
||||
//C7/C8 parameters
|
||||
#define NOISE_PARAMETERS 0x01
|
||||
|
||||
//MP_FLAG_VALUE
|
||||
#define INIT_MP 0xA5A5A501
|
||||
#define INIT_FIELD 0xA5A5A502
|
||||
|
||||
//NOISE PARAMS
|
||||
#define NOISE_PARAMETERS_SIZE 4 //bytes
|
||||
|
||||
//ERROR INFO
|
||||
#define ERROR_INFO_SIZE (20*4) // bytes
|
||||
#define ERROR_SIGNATURE 0xFA5005AF
|
||||
#define ERROR_SIGN_HEAD 0xA5
|
||||
|
||||
#endif
|
||||
3844
drivers/input/touchscreen/st/fts_lib/ftsTest.c
Normal file
3844
drivers/input/touchscreen/st/fts_lib/ftsTest.c
Normal file
File diff suppressed because it is too large
Load diff
193
drivers/input/touchscreen/st/fts_lib/ftsTest.h
Normal file
193
drivers/input/touchscreen/st/fts_lib/ftsTest.h
Normal file
|
|
@ -0,0 +1,193 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS API for MP test **
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*/
|
||||
|
||||
#ifndef __FTS_TEST_H
|
||||
#define __FTS_TEST_H
|
||||
|
||||
#include "ftsSoftware.h"
|
||||
|
||||
#define LIMITS_FILE "stm_fts_production_limits.csv"
|
||||
|
||||
#define WAIT_FOR_FRESH_FRAMES 100 //ms
|
||||
#define WAIT_AFTER_SENSEOFF 50 //ms
|
||||
|
||||
#define TIMEOUT_ITO_TEST_RESULT 200 //ms
|
||||
#define TIMEOUT_INITIALIZATION_TEST_RESULT 5000 //ms
|
||||
|
||||
//LABELS PRODUCTION TEST LIMITS FILE
|
||||
#define MS_RAW_MIN_MAX "MS_RAW_DATA_MIN_MAX"
|
||||
#define MS_RAW_GAP "MS_RAW_DATA_GAP"
|
||||
#define MS_CX1_MIN_MAX "MS_TOUCH_ACTIVE_CX1_MIN_MAX"
|
||||
#define MS_CX2_MAP_MIN "MS_TOUCH_ACTIVE_CX2_MIN"
|
||||
#define MS_CX2_MAP_MAX "MS_TOUCH_ACTIVE_CX2_MAX"
|
||||
#define MS_CX2_ADJH_MAP_MAX "MS_TOUCH_ACTIVE_CX2_ADJ_HORIZONTAL"
|
||||
#define MS_CX2_ADJV_MAP_MAX "MS_TOUCH_ACTIVE_CX2_ADJ_VERTICAL"
|
||||
#define MS_TOTAL_CX_MAP_MIN "MS_TOUCH_ACTIVE_TOTAL_CX_MIN"
|
||||
#define MS_TOTAL_CX_MAP_MAX "MS_TOUCH_ACTIVE_TOTAL_CX_MAX"
|
||||
#define MS_TOTAL_CX_ADJH_MAP_MAX "MS_TOUCH_ACTIVE_TOTAL_CX_ADJ_HORIZONTAL"
|
||||
#define MS_TOTAL_CX_ADJV_MAP_MAX "MS_TOUCH_ACTIVE_TOTAL_CX_ADJ_VERTICAL"
|
||||
#define SS_RAW_FORCE_MIN_MAX "SS_RAW_DATA_FORCE_MIN_MAX"
|
||||
#define SS_RAW_SENSE_MIN_MAX "SS_RAW_DATA_SENSE_MIN_MAX"
|
||||
#define SS_RAW_FORCE_GAP "SS_RAW_DATA_FORCE_GAP"
|
||||
#define SS_RAW_SENSE_GAP "SS_RAW_DATA_SENSE_GAP"
|
||||
#define SS_IX1_FORCE_MIN_MAX "SS_TOUCH_ACTIVE_IX1_FORCE_MIN_MAX"
|
||||
#define SS_IX1_SENSE_MIN_MAX "SS_TOUCH_ACTIVE_IX1_SENSE_MIN_MAX"
|
||||
#define SS_CX1_FORCE_MIN_MAX "SS_TOUCH_ACTIVE_CX1_FORCE_MIN_MAX"
|
||||
#define SS_CX1_SENSE_MIN_MAX "SS_TOUCH_ACTIVE_CX1_SENSE_MIN_MAX"
|
||||
#define SS_IX2_FORCE_MAP_MIN "SS_TOUCH_ACTIVE_IX2_FORCE_MIN"
|
||||
#define SS_IX2_FORCE_MAP_MAX "SS_TOUCH_ACTIVE_IX2_FORCE_MAX"
|
||||
#define SS_IX2_SENSE_MAP_MIN "SS_TOUCH_ACTIVE_IX2_SENSE_MIN"
|
||||
#define SS_IX2_SENSE_MAP_MAX "SS_TOUCH_ACTIVE_IX2_SENSE_MAX"
|
||||
#define SS_IX2_FORCE_ADJV_MAP_MAX "SS_TOUCH_ACTIVE_IX2_ADJ_VERTICAL"
|
||||
#define SS_IX2_SENSE_ADJH_MAP_MAX "SS_TOUCH_ACTIVE_IX2_ADJ_HORIZONTAL"
|
||||
#define SS_CX2_FORCE_MAP_MIN "SS_TOUCH_ACTIVE_CX2_FORCE_MIN"
|
||||
#define SS_CX2_FORCE_MAP_MAX "SS_TOUCH_ACTIVE_CX2_FORCE_MAX"
|
||||
#define SS_CX2_SENSE_MAP_MIN "SS_TOUCH_ACTIVE_CX2_SENSE_MIN"
|
||||
#define SS_CX2_SENSE_MAP_MAX "SS_TOUCH_ACTIVE_CX2_SENSE_MAX"
|
||||
#define SS_CX2_FORCE_ADJV_MAP_MAX "SS_TOUCH_ACTIVE_CX2_ADJ_VERTICAL"
|
||||
#define SS_CX2_SENSE_ADJH_MAP_MAX "SS_TOUCH_ACTIVE_CX2_ADJ_HORIZONTAL"
|
||||
|
||||
// TOTAL SS
|
||||
#define SS_TOTAL_IX_FORCE_MAP_MIN "SS_TOUCH_ACTIVE_TOTAL_IX_FORCE_MIN"
|
||||
#define SS_TOTAL_IX_FORCE_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_IX_FORCE_MAX"
|
||||
#define SS_TOTAL_IX_SENSE_MAP_MIN "SS_TOUCH_ACTIVE_TOTAL_IX_SENSE_MIN"
|
||||
#define SS_TOTAL_IX_SENSE_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_IX_SENSE_MAX"
|
||||
#define SS_TOTAL_IX_FORCE_ADJV_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_IX_ADJ_VERTICAL"
|
||||
#define SS_TOTAL_IX_SENSE_ADJH_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_IX_ADJ_HORIZONTAL"
|
||||
#define SS_TOTAL_CX_FORCE_MAP_MIN "SS_TOUCH_ACTIVE_TOTAL_CX_FORCE_MIN"
|
||||
#define SS_TOTAL_CX_FORCE_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_CX_FORCE_MAX"
|
||||
#define SS_TOTAL_CX_SENSE_MAP_MIN "SS_TOUCH_ACTIVE_TOTAL_CX_SENSE_MIN"
|
||||
#define SS_TOTAL_CX_SENSE_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_CX_SENSE_MAX"
|
||||
#define SS_TOTAL_CX_FORCE_ADJV_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_CX_ADJ_VERTICAL"
|
||||
#define SS_TOTAL_CX_SENSE_ADJH_MAP_MAX "SS_TOUCH_ACTIVE_TOTAL_CX_ADJ_HORIZONTAL"
|
||||
|
||||
//KEYS
|
||||
#define MS_KEY_RAW_MIN_MAX "MS_KEY_RAW_DATA_MIN_MAX"
|
||||
#define MS_KEY_CX1_MIN_MAX "MS_KEY_CX1_MIN_MAX"
|
||||
#define MS_KEY_CX2_MAP_MIN "MS_KEY_CX2_MIN"
|
||||
#define MS_KEY_CX2_MAP_MAX "MS_KEY_CX2_MAX"
|
||||
#define MS_KEY_TOTAL_CX_MAP_MIN "MS_KEY_TOTAL_CX_MIN"
|
||||
#define MS_KEY_TOTAL_CX_MAP_MAX "MS_KEY_TOTAL_CX_MAX"
|
||||
|
||||
//CONSTANT TOTAL IX
|
||||
#define SS_IX1_FORCE_W "IX1_FORCE_W"
|
||||
#define SS_IX2_FORCE_W "IX2_FORCE_W"
|
||||
#define SS_IX1_SENSE_W "IX1_SENSE_W"
|
||||
#define SS_IX2_SENSE_W "IX2_SENSE_W"
|
||||
|
||||
|
||||
#define SAVE_FLAG_RETRY 3
|
||||
|
||||
|
||||
struct TestToDo {
|
||||
int MutualRaw;
|
||||
int MutualRawGap;
|
||||
int MutualCx1;
|
||||
int MutualCx2;
|
||||
int MutualCx2Adj;
|
||||
int MutualCxTotal;
|
||||
int MutualCxTotalAdj;
|
||||
|
||||
int MutualKeyRaw;
|
||||
int MutualKeyCx1;
|
||||
int MutualKeyCx2;
|
||||
int MutualKeyCxTotal;
|
||||
|
||||
int SelfForceRaw;
|
||||
int SelfForceRawGap;
|
||||
int SelfForceIx1;
|
||||
int SelfForceIx2;
|
||||
int SelfForceIx2Adj;
|
||||
int SelfForceIxTotal;
|
||||
int SelfForceIxTotalAdj;
|
||||
int SelfForceCx1;
|
||||
int SelfForceCx2;
|
||||
int SelfForceCx2Adj;
|
||||
int SelfForceCxTotal;
|
||||
int SelfForceCxTotalAdj;
|
||||
|
||||
int SelfSenseRaw;
|
||||
int SelfSenseRawGap;
|
||||
int SelfSenseIx1;
|
||||
int SelfSenseIx2;
|
||||
int SelfSenseIx2Adj;
|
||||
int SelfSenseIxTotal;
|
||||
int SelfSenseIxTotalAdj;
|
||||
int SelfSenseCx1;
|
||||
int SelfSenseCx2;
|
||||
int SelfSenseCx2Adj;
|
||||
int SelfSenseCxTotal;
|
||||
int SelfSenseCxTotalAdj;
|
||||
|
||||
};
|
||||
|
||||
int computeAdjHoriz(u8 *data, int row, int column, u8 **result);
|
||||
int computeAdjHorizTotal(u16 *data, int row, int column, u16 **result);
|
||||
int computeAdjVert(u8 *data, int row, int column, u8 **result);
|
||||
int computeAdjVertTotal(u16 *data, int row, int column, u16 **result);
|
||||
int computeTotal(u8 *data, u8 main, int row, int column, int m,
|
||||
int n, u16 **result);
|
||||
int checkLimitsMinMax(short *data, int row, int column, int min, int max);
|
||||
int checkLimitsMap(u8 *data, int row, int column, int *min, int *max);
|
||||
int checkLimitsMapTotal(u16 *data, int row, int column, int *min, int *max);
|
||||
int checkLimitsMapAdj(u8 *data, int row, int column, int *max);
|
||||
int checkLimitsMapAdjTotal(u16 *data, int row, int column, int *max);
|
||||
int production_test_ito(void);
|
||||
int production_test_initialization(void);
|
||||
int ms_compensation_tuning(void);
|
||||
int ss_compensation_tuning(void);
|
||||
int lp_timer_calibration(void);
|
||||
int save_cx_tuning(void);
|
||||
int production_test_split_initialization(int saveToFlash);
|
||||
int production_test_main(char *pathThresholds, int stop_on_fail, int saveInit,
|
||||
struct TestToDo *todo, u32 signature);
|
||||
int production_test_ms_raw(char *path_limits, int stop_on_fail,
|
||||
struct TestToDo *todo);
|
||||
int production_test_ms_cx(char *path_limits, int stop_on_fail,
|
||||
struct TestToDo *todo);
|
||||
int production_test_ss_raw(char *path_limits, int stop_on_fail,
|
||||
struct TestToDo *todo);
|
||||
int production_test_ss_ix_cx(char *path_limits, int stop_on_fail,
|
||||
struct TestToDo *todo);
|
||||
int production_test_data(char *path_limits, int stop_on_fail,
|
||||
struct TestToDo *todo);
|
||||
int production_test_ms_key_cx(char *path_limits, int stop_on_fail,
|
||||
struct TestToDo *todo);
|
||||
int production_test_ms_key_raw(char *path_limits);
|
||||
int save_mp_flag(u32 signature);
|
||||
int parseProductionTestLimits(char *path, char *label, int **data,
|
||||
int *row, int *column);
|
||||
int readLine(char *data, char *line, int size, int *n);
|
||||
#endif
|
||||
109
drivers/input/touchscreen/st/fts_lib/ftsTime.c
Normal file
109
drivers/input/touchscreen/st/fts_lib/ftsTime.c
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
// SPDX-License-Identifier: GPL-2.0-only
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS Utility for mesuring/handling the time *
|
||||
* *
|
||||
**************************************************************************
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#include <linux/init.h>
|
||||
#include <linux/errno.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/kernel.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/string.h>
|
||||
#include <stdarg.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/serio.h>
|
||||
#include <linux/time.h>
|
||||
#include <linux/pm.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/ctype.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/i2c-dev.h>
|
||||
#include <linux/fs.h>
|
||||
#include <linux/uaccess.h>
|
||||
#include <linux/power_supply.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/regulator/consumer.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/timekeeping.h>
|
||||
//#include <linux/sec_sysfs.h>
|
||||
|
||||
#include "ftsCrossCompile.h"
|
||||
#include "ftsTime.h"
|
||||
|
||||
|
||||
void startStopWatch(struct StopWatch *w)
|
||||
{
|
||||
ktime_get_ts(&w->start);
|
||||
}
|
||||
|
||||
void stopStopWatch(struct StopWatch *w)
|
||||
{
|
||||
ktime_get_ts(&w->end);
|
||||
}
|
||||
|
||||
int elapsedMillisecond(struct StopWatch *w)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = ((w->end.tv_sec - w->start.tv_sec) * 1000)
|
||||
+ (w->end.tv_nsec - w->start.tv_nsec) / 1000000;
|
||||
return result;
|
||||
}
|
||||
|
||||
int elapsedNanosecond(struct StopWatch *w)
|
||||
{
|
||||
int result;
|
||||
|
||||
result = ((w->end.tv_sec - w->start.tv_sec) * 1000000000)
|
||||
+ (w->end.tv_nsec - w->start.tv_nsec);
|
||||
return result;
|
||||
}
|
||||
|
||||
char *timestamp()
|
||||
{
|
||||
char *result = NULL;
|
||||
|
||||
result = (char *)kmalloc_array(1, sizeof(char), GFP_KERNEL);
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
result[0] = ' ';
|
||||
return result;
|
||||
}
|
||||
|
||||
void stdelay(unsigned long ms)
|
||||
{
|
||||
msleep(ms);
|
||||
}
|
||||
54
drivers/input/touchscreen/st/fts_lib/ftsTime.h
Normal file
54
drivers/input/touchscreen/st/fts_lib/ftsTime.h
Normal file
|
|
@ -0,0 +1,54 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS Utility for mesuring/handling the time *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FTS_TIME_H
|
||||
#define __FTS_TIME_H
|
||||
|
||||
#include <linux/time.h>
|
||||
|
||||
#include "ftsCrossCompile.h"
|
||||
|
||||
struct StopWatch {
|
||||
struct timespec start, end;
|
||||
};
|
||||
|
||||
void startStopWatch(struct StopWatch *w);
|
||||
void stopStopWatch(struct StopWatch *w);
|
||||
int elapsedMillisecond(struct StopWatch *w);
|
||||
int elapsedNanosecond(struct StopWatch *w);
|
||||
char *timestamp(void);
|
||||
void stdelay(unsigned long ms);
|
||||
#endif
|
||||
1348
drivers/input/touchscreen/st/fts_lib/ftsTool.c
Normal file
1348
drivers/input/touchscreen/st/fts_lib/ftsTool.c
Normal file
File diff suppressed because it is too large
Load diff
107
drivers/input/touchscreen/st/fts_lib/ftsTool.h
Normal file
107
drivers/input/touchscreen/st/fts_lib/ftsTool.h
Normal file
|
|
@ -0,0 +1,107 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0-only */
|
||||
/*
|
||||
* FTS Capacitive touch screen controller (FingerTipS)
|
||||
*
|
||||
* Copyright (C) 2016-2019, STMicroelectronics Limited.
|
||||
* Authors: AMG(Analog Mems Group) <marco.cali@st.com>
|
||||
*
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License version 2 as published by
|
||||
* the Free Software Foundation.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along with
|
||||
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
*
|
||||
**************************************************************************
|
||||
** STMicroelectronics **
|
||||
**************************************************************************
|
||||
** marco.cali@st.com **
|
||||
**************************************************************************
|
||||
* *
|
||||
* FTS Utility Functions *
|
||||
* *
|
||||
**************************************************************************
|
||||
**************************************************************************
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __FTS_TOOL_H
|
||||
#define __FTS_TOOL_H
|
||||
|
||||
#define GPIO_NOT_DEFINED -1
|
||||
#define TIMEOUT_RESOLUTION 10 //ms
|
||||
#define GENERAL_TIMEOUT (50*TIMEOUT_RESOLUTION) //ms
|
||||
#define RELEASE_INFO_TIMEOUT (15*TIMEOUT_RESOLUTION) //ms
|
||||
|
||||
|
||||
#define FEAT_ENABLE 1
|
||||
#define FEAT_DISABLE 0
|
||||
|
||||
#define SYSTEM_RESET_RETRY 3
|
||||
|
||||
#define B2_RETRY 2
|
||||
//for FTM4 can not be greater than 13 bytes
|
||||
#define LOCKDOWN_CODE_SIZE 10
|
||||
|
||||
#define LOCKDOWN_CODE_MAX_SIZE 63
|
||||
#define LOCKDOWN_CODE_WRITE_CHUNK 12
|
||||
#define LOCKDOWN_CODE_READ_CHUNK 4
|
||||
#define LOCKDOWN_CODE_RETRY 2
|
||||
|
||||
int readB2(u16 address, u8 *outBuf, int len);
|
||||
int readB2U16(u16 address, u8 *outBuf, int byteToRead);
|
||||
int releaseInformation(void);
|
||||
int lockDownInfo(u8 *data, int len);
|
||||
int calculateCRC8(u8 *u8_srcBuff, int size, u8 *crc);
|
||||
int writeLockDownInfo(u8 *data, int size);
|
||||
int rewriteLockDownInfo(u8 *data, int size);
|
||||
int readLockDownInfo(u8 *lockData, int *size);
|
||||
char *printHex(char *label, u8 *buff, int count);
|
||||
int pollForEvent(int *event_to_search, int event_bytes,
|
||||
u8 *readData, int time_to_wait);
|
||||
int fts_disableInterrupt(void);
|
||||
int fts_enableInterrupt(void);
|
||||
int u8ToU16(u8 *src, u16 *dst);
|
||||
int u8ToU16_le(u8 *src, u16 *dst);
|
||||
int u8ToU16n(u8 *src, int src_length, u16 *dst);
|
||||
int u16ToU8(u16 src, u8 *dst);
|
||||
int u16ToU8_le(u16 src, u8 *dst);
|
||||
int u16ToU8_be(u16 src, u8 *dst);
|
||||
int u16ToU8n(u16 *src, int src_length, u8 *dst);
|
||||
int u8ToU32(u8 *src, u32 *dst);
|
||||
int u32ToU8(u32 src, u8 *dst);
|
||||
int attempt_function(int(*code)(void), unsigned long wait_before_retry,
|
||||
int retry_count);
|
||||
void setResetGpio(int gpio);
|
||||
int fts_system_reset(void);
|
||||
int isSystemResettedUp(void);
|
||||
int isSystemResettedDown(void);
|
||||
void setSystemResettedUp(int val);
|
||||
void setSystemResettedDown(int val);
|
||||
int senseOn(void);
|
||||
int senseOff(void);
|
||||
int keyOn(void);
|
||||
int keyOff(void);
|
||||
int featureEnableDisable(int on_off, u32 feature);
|
||||
int writeNoiseParameters(u8 *noise);
|
||||
int readNoiseParameters(u8 *noise);
|
||||
int checkEcho(u8 *cmd, int size);
|
||||
void print_frame_short(char *label, short **matrix, int row, int column);
|
||||
short **array1dTo2d_short(short *data, int size, int columns);
|
||||
u8 **array1dTo2d_u8(u8 *data, int size, int columns);
|
||||
void print_frame_u8(char *label, u8 **matrix, int row, int column);
|
||||
void print_frame_u32(char *label, u32 **matrix, int row, int column);
|
||||
void print_frame_int(char *label, int **matrix, int row, int column);
|
||||
int cleanUp(int enableTouch);
|
||||
int flushFIFO(void);
|
||||
|
||||
#endif
|
||||
Loading…
Reference in a new issue