dlkm: bo: Clean up focaltech_0flash_8756_mmi

- Clean up focaltech_0flash_8756_mmi because it's not really used
in any of our products now.

Change-Id: I585df913007e0bd3fc190a9a2851008e0a388109
Signed-off-by: wengjun1 <wengjun1@motorola.com>
Reviewed-on: https://gerrit.mot.com/1583839
SLTApproved: Slta Waiver
SME-Granted: SME Approvals Granted
Tested-by: Jira Key
Reviewed-by: Jialei Hao <haojl2@motorola.com>
Reviewed-by: Konstantin Makariev <kmakariev@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
wengjun1 2020-05-28 09:59:47 +08:00 • committed by Jun Weng
commit 3dddb0ddfb
27 changed files with 0 additions and 12679 deletions

View file

@ -1,14 +0,0 @@
DLKM_DIR := motorola/kernel/modules
LOCAL_PATH := $(call my-dir)
ifneq ($(FOCALTECH_TOUCH_IC_NAME),)
KERNEL_CFLAGS += CONFIG_INPUT_FOCALTECH_0FLASH_MMI_IC_NAME=$(FOCALTECH_TOUCH_IC_NAME)
else
KERNEL_CFLAGS += CONFIG_INPUT_FOCALTECH_0FLASH_MMI_IC_NAME=ft8719
endif
include $(CLEAR_VARS)
LOCAL_MODULE := focaltech_0flash_8756_mmi.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(KERNEL_MODULES_OUT)
include $(DLKM_DIR)/AndroidKernelModule.mk

View file

@ -1,29 +0,0 @@
# add -Wall to try to catch everything we can.
EXTRA_CFLAGS += -Wall
EXTRA_CFLAGS += -I$(TOP)/motorola/kernel/modules/include \
-I$(TOP)/motorola/kernel/modules/drivers/input/touchscreen/focaltech_0flash_8756_mmi \
-I$(TOP)/motorola/kernel/modules/drivers/input/touchscreen/focaltech_0flash_8756_mmi/include \
-I$(TOP)/motorola/kernel/modules/drivers/input/touchscreen/focaltech_0flash_8756_mmi/focaltech_test
obj-m := focaltech_0flash_8756_mmi.o
focaltech_0flash_8756_mmi-objs += focaltech_core.o
focaltech_0flash_8756_mmi-objs += focaltech_esdcheck.o
focaltech_0flash_8756_mmi-objs += focaltech_ex_fun.o
focaltech_0flash_8756_mmi-objs += focaltech_ex_mode.o
focaltech_0flash_8756_mmi-objs += focaltech_flash.o
focaltech_0flash_8756_mmi-objs += focaltech_gesture.o
focaltech_0flash_8756_mmi-objs += focaltech_point_report_check.o
focaltech_0flash_8756_mmi-objs += focaltech_spi.o
focaltech_0flash_8756_mmi-objs += focaltech_test/focaltech_test.o
focaltech_0flash_8756_mmi-objs += focaltech_test/focaltech_test_ini.o
ifneq ($(filter ft8719,$(CONFIG_INPUT_FOCALTECH_0FLASH_MMI_IC_NAME)),)
EXTRA_CFLAGS += -DCONFIG_INPUT_FOCALTECH_0FLASH_MMI_IC_NAME_FT8719
focaltech_0flash_8756_mmi-objs += focaltech_test/supported_ic/focaltech_test_ft8719.o
focaltech_0flash_8756_mmi-objs += focaltech_flash_ft8719.o
endif
ifneq ($(filter ft8756,$(CONFIG_INPUT_FOCALTECH_0FLASH_MMI_IC_NAME)),)
EXTRA_CFLAGS += -DCONFIG_INPUT_FOCALTECH_0FLASH_MMI_IC_NAME_FT8756
focaltech_0flash_8756_mmi-objs += focaltech_test/supported_ic/focaltech_test_ft8756.o
focaltech_0flash_8756_mmi-objs += focaltech_flash_ft8756.o
endif

View file

@ -1,17 +0,0 @@
#
# Focaltech Touchscreen driver configuration
#
config TOUCHSCREEN_FTS
bool "Focaltech Touchscreen"
depends on I2C
default n
help
Say Y here if you have Focaltech touch panel.
If unsure, say N.
config TOUCHSCREEN_FTS_DIRECTORY
string "Focaltech ts directory name"
default "focaltech_touch"
depends on TOUCHSCREEN_FTS

View file

@ -1,10 +0,0 @@
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
all:
$(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS)
modules_install:
$(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(shell pwd) modules_install
clean:
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean

View file

@ -1,15 +0,0 @@
# Makefile for the focaltech touchscreen drivers.
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_core.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_ex_fun.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_ex_mode.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_gesture.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_esdcheck.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_point_report_check.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_test/
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_spi.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_flash.o

View file

@ -1,172 +0,0 @@
/*
*
* FocalTech fts TouchScreen driver.
*
* Copyright (c) 2012-2019, Focaltech Ltd. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/*****************************************************************************
*
* File Name: focaltech_common.h
*
* Author: Focaltech Driver Team
*
* Created: 2016-08-16
*
* Abstract:
*
* Reference:
*
*****************************************************************************/
#ifndef __LINUX_FOCALTECH_COMMON_H__
#define __LINUX_FOCALTECH_COMMON_H__
#include "focaltech_config.h"
/*****************************************************************************
* Macro definitions using #define
*****************************************************************************/
#define FTS_DRIVER_VERSION "Focaltech V3.1 20190420"
#define BYTE_OFF_0(x) (u8)((x) & 0xFF)
#define BYTE_OFF_8(x) (u8)((x >> 8) & 0xFF)
#define BYTE_OFF_16(x) (u8)((x >> 16) & 0xFF)
#define BYTE_OFF_24(x) (u8)((x >> 24) & 0xFF)
#define FLAGBIT(x) (0x00000001 << (x))
#define FLAGBITS(x, y) ((0xFFFFFFFF >> (32 - (y) - 1)) & (0xFFFFFFFF << (x)))
#define FLAG_ICSERIALS_LEN 8
#define FLAG_HID_BIT 10
#define FLAG_IDC_BIT 11
#define IC_SERIALS (FTS_CHIP_TYPE & FLAGBITS(0, FLAG_ICSERIALS_LEN-1))
#define IC_TO_SERIALS(x) ((x) & FLAGBITS(0, FLAG_ICSERIALS_LEN-1))
#define FTS_CHIP_IDC ((FTS_CHIP_TYPE & FLAGBIT(FLAG_IDC_BIT)) == FLAGBIT(FLAG_IDC_BIT))
#define FTS_HID_SUPPORTTED ((FTS_CHIP_TYPE & FLAGBIT(FLAG_HID_BIT)) == FLAGBIT(FLAG_HID_BIT))
#if defined(CONFIG_INPUT_FOCALTECH_0FLASH_MMI_IC_NAME_FT8756)
#define FTS_CHIP_TYPE_MAPPING {{0x15, 0x87, 0x56, 0x87, 0x56, 0xF7, 0xA6, 0x00, 0x00}}
#elif defined(CONFIG_INPUT_FOCALTECH_0FLASH_MMI_IC_NAME_FT8719)
#define FTS_CHIP_TYPE_MAPPING {{0x0D,0x87, 0x19, 0x87, 0x19, 0x87, 0xA9, 0x87, 0xB9}}
#else
#define FTS_CHIP_TYPE_MAPPING {{0x0D,0x87, 0x19, 0x87, 0x19, 0x87, 0xA9, 0x87, 0xB9}}
#endif
#define FILE_NAME_LENGTH 128
#define ENABLE 1
#define DISABLE 0
#define VALID 1
#define INVALID 0
#define FTS_CMD_START1 0x55
#define FTS_CMD_START2 0xAA
#define FTS_CMD_START_DELAY 10
#define FTS_CMD_READ_ID 0x90
#define FTS_CMD_READ_ID_LEN 4
#define FTS_CMD_READ_ID_LEN_INCELL 1
/*register address*/
#define FTS_REG_INT_CNT 0x8F
#define FTS_REG_FLOW_WORK_CNT 0x91
#define FTS_REG_WORKMODE 0x00
#define FTS_REG_WORKMODE_FACTORY_VALUE 0x40
#define FTS_REG_WORKMODE_WORK_VALUE 0x00
#define FTS_REG_ESDCHECK_DISABLE 0x8D
#define FTS_REG_CHIP_ID 0xA3
#define FTS_REG_CHIP_ID2 0x9F
#define FTS_REG_POWER_MODE 0xA5
#define FTS_REG_POWER_MODE_SLEEP_VALUE 0x03
#define FTS_REG_FW_VER 0xA6
#define FTS_REG_VENDOR_ID 0xA8
#define FTS_REG_LCD_BUSY_NUM 0xAB
#define FTS_REG_FACE_DEC_MODE_EN 0xB0
#define FTS_REG_FACTORY_MODE_DETACH_FLAG 0xB4
#define FTS_REG_FACE_DEC_MODE_STATUS 0x01
#define FTS_REG_IDE_PARA_VER_ID 0xB5
#define FTS_REG_IDE_PARA_STATUS 0xB6
#define FTS_REG_GLOVE_MODE_EN 0xC0
#define FTS_REG_COVER_MODE_EN 0xC1
#define FTS_REG_CHARGER_MODE_EN 0x8B
#define FTS_REG_GESTURE_EN 0xD0
#define FTS_REG_GESTURE_OUTPUT_ADDRESS 0xD3
#define FTS_REG_MODULE_ID 0xE3
#define FTS_REG_LIC_VER 0xE4
#define FTS_REG_ESD_SATURATE 0xED
#define FTS_SYSFS_ECHO_ON(buf) (buf[0] == '1')
#define FTS_SYSFS_ECHO_OFF(buf) (buf[0] == '0')
#define kfree_safe(pbuf) do {\
if (pbuf) {\
kfree(pbuf);\
pbuf = NULL;\
}\
} while(0)
/*****************************************************************************
* Alternative mode (When something goes wrong, the modules may be able to solve the problem.)
*****************************************************************************/
/*
* point report check
* default: disable
*/
#define FTS_POINT_REPORT_CHECK_EN 0
/*****************************************************************************
* Global variable or extern global variabls/functions
*****************************************************************************/
struct ft_chip_t {
u64 type;
u8 chip_idh;
u8 chip_idl;
u8 rom_idh;
u8 rom_idl;
u8 pb_idh;
u8 pb_idl;
u8 bl_idh;
u8 bl_idl;
};
struct ts_ic_info {
bool is_incell;
bool hid_supported;
struct ft_chip_t ids;
};
/*****************************************************************************
* DEBUG function define here
*****************************************************************************/
#if FTS_DEBUG_EN
#define FTS_DEBUG(fmt, args...) do { \
printk("[FTS_TS]%s:"fmt"\n", __func__, ##args); \
} while (0)
#define FTS_FUNC_ENTER() do { \
printk("[FTS_TS]%s: Enter\n", __func__); \
} while (0)
#define FTS_FUNC_EXIT() do { \
printk("[FTS_TS]%s: Exit(%d)\n", __func__, __LINE__); \
} while (0)
#else /* #if FTS_DEBUG_EN*/
#define FTS_DEBUG(fmt, args...)
#define FTS_FUNC_ENTER()
#define FTS_FUNC_EXIT()
#endif
#define FTS_INFO(fmt, args...) do { \
printk(KERN_INFO "[FTS_TS/I]%s:"fmt"\n", __func__, ##args); \
} while (0)
#define FTS_ERROR(fmt, args...) do { \
printk(KERN_ERR "[FTS_TS/E]%s:"fmt"\n", __func__, ##args); \
} while (0)
#endif /* __LINUX_FOCALTECH_COMMON_H__ */

View file

@ -1,260 +0,0 @@
/*
*
* FocalTech TouchScreen driver.
*
* Copyright (c) 2012-2019, FocalTech Systems, Ltd., all rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/************************************************************************
*
* File Name: focaltech_config.h
*
* Author: Focaltech Driver Team
*
* Created: 2016-08-08
*
* Abstract: global configurations
*
* Version: v1.0
*
************************************************************************/
#ifndef _LINUX_FOCLATECH_CONFIG_H_
#define _LINUX_FOCLATECH_CONFIG_H_
/**************************************************/
/****** G: A, I: B, S: C, U: D ******************/
/****** chip type defines, do not modify *********/
#define _FT8716 0x87160805
#define _FT8736 0x87360806
#define _FT8006M 0x80060807
#define _FT7250 0x72500807
#define _FT8607 0x86070809
#define _FT8006U 0x8006D80B
#define _FT8006S 0x8006A80B
#define _FT8613 0x8613080C
#define _FT8719 0x8719080D
#define _FT8739 0x8739080E
#define _FT8615 0x8615080F
#define _FT8201 0x82010810
#define _FT8006P 0x86220811
#define _FT7251 0x72510812
#define _FT7252 0x72520813
#define _FT8613S 0x8613C814
#define _FT8756 0x87560815
#define _FT8302 0x83020816
#define _FT8009 0x80090817
#define _FT8656 0x86560818
#define _FT5416 0x54160402
#define _FT5426 0x54260402
#define _FT5435 0x54350402
#define _FT5436 0x54360402
#define _FT5526 0x55260402
#define _FT5526I 0x5526B402
#define _FT5446 0x54460402
#define _FT5346 0x53460402
#define _FT5446I 0x5446B402
#define _FT5346I 0x5346B402
#define _FT7661 0x76610402
#define _FT7511 0x75110402
#define _FT7421 0x74210402
#define _FT7681 0x76810402
#define _FT3C47U 0x3C47D402
#define _FT3417 0x34170402
#define _FT3517 0x35170402
#define _FT3327 0x33270402
#define _FT3427 0x34270402
#define _FT7311 0x73110402
#define _FT5626 0x56260401
#define _FT5726 0x57260401
#define _FT5826B 0x5826B401
#define _FT5826S 0x5826C401
#define _FT7811 0x78110401
#define _FT3D47 0x3D470401
#define _FT3617 0x36170401
#define _FT3717 0x37170401
#define _FT3817B 0x3817B401
#define _FT3517U 0x3517D401
#define _FT6236U 0x6236D003
#define _FT6336G 0x6336A003
#define _FT6336U 0x6336D003
#define _FT6436U 0x6436D003
#define _FT3267 0x32670004
#define _FT3367 0x33670004
#define _FT3327DQQ_XXX 0x3327D482
#define _FT5446DQS_XXX 0x5446D482
#define _FT3518 0x35180481
#define _FT3558 0x35580481
#define _FT3528 0x35280481
#define _FT5536 0x55360481
#define _FT5446U 0x5446D083
#define _FT5456U 0x5456D083
#define _FT3417U 0x3417D083
#define _FT5426U 0x5426D083
#define _FT3428 0x34280083
#define _FT3437U 0x3437D083
#define _FT7302 0x73020084
#define _FT7202 0x72020084
#define _FT3308 0x33080084
#define _FT6346U 0x6346D085
#define _FT6346G 0x6346A085
#define _FT3067 0x30670085
#define _FT3068 0x30680085
#define _FT3168 0x31680085
#define _FT3268 0x32680085
/*************************************************/
/*
* choose your ic chip type of focaltech
*/
#if defined(CONFIG_INPUT_FOCALTECH_0FLASH_MMI_IC_NAME_FT8756)
#define FTS_CHIP_TYPE _FT8756
#define FTS_CHIP_NAME "ft8756"
#elif defined(CONFIG_INPUT_FOCALTECH_0FLASH_MMI_IC_NAME_FT8719)
#define FTS_CHIP_TYPE _FT8719
#define FTS_CHIP_NAME "ft8719"
#else
#define FTS_CHIP_TYPE _FT8719
#define FTS_CHIP_NAME "ft8719"
#endif
/******************* Enables *********************/
/*********** 1 to enable, 0 to disable ***********/
/*
* show debug log info
* enable it for debug, disable it for release
*/
#define FTS_DEBUG_EN 1
/*
* Linux MultiTouch Protocol
* 1: Protocol B(default), 0: Protocol A
*/
#define FTS_MT_PROTOCOL_B_EN 1
/*
* Report Pressure in multitouch
* 1:enable(default),0:disable
*/
#define FTS_REPORT_PRESSURE_EN 1
/*
* Gesture function enable
* default: disable
*/
#define FTS_GESTURE_EN 0
/*
* ESD check & protection
* default: disable
*/
#define FTS_ESDCHECK_EN 0
/*
* Production test enable
* 1: enable, 0:disable(default)
*/
#define FTS_TEST_EN 1
/*
* Nodes for tools, please keep enable
*/
#define FTS_SYSFS_NODE_EN 1
#define FTS_APK_NODE_EN 1
/*
* Pinctrl enable
* default: disable
*/
#define FTS_PINCTRL_EN 0
/*
* Customer power enable
* enable it when customer need control TP power
* default: disable
*/
#define FTS_POWER_SOURCE_CUST_EN 0
/****************************************************/
/********************** Upgrade ****************************/
/*
* auto upgrade
*/
#define FTS_AUTO_UPGRADE_EN 0
/*
* auto upgrade for lcd cfg
*/
#define FTS_AUTO_LIC_UPGRADE_EN 0
/*
* Numbers of modules support
*/
#define FTS_GET_MODULE_NUM 0
/*
* module_id: mean vendor_id generally, also maybe gpio or lcm_id...
* If means vendor_id, the FTS_MODULE_ID = PANEL_ID << 8 + VENDOR_ID
* FTS_GET_MODULE_NUM == 0/1, no check module id, you may ignore them
* FTS_GET_MODULE_NUM >= 2, compatible with FTS_MODULE2_ID
* FTS_GET_MODULE_NUM >= 3, compatible with FTS_MODULE3_ID
*/
#define FTS_MODULE_ID 0x0000
#define FTS_MODULE2_ID 0x0000
#define FTS_MODULE3_ID 0x0000
/*
* Need set the following when get firmware via firmware_request()
* For example: if module'vendor is tianma,
* #define FTS_MODULE_NAME "tianma"
* then file_name will be "focaltech_ts_fw_tianma"
* You should rename fw to "focaltech_ts_fw_tianma", and push it into
* etc/firmware or by customers
*/
#define FTS_MODULE_NAME ""
#define FTS_MODULE2_NAME ""
#define FTS_MODULE3_NAME ""
/*
* FW.i file for auto upgrade, you must replace it with your own
* define your own fw_file, the sample one to be replaced is invalid
* NOTE: if FTS_GET_MODULE_NUM > 1, it's the fw corresponding with FTS_VENDOR_ID
* NOTE: git may ignore xxx.i file
*/
#define FTS_UPGRADE_FW_FILE "include/firmware/fw_sample.i"
/*
* if FTS_GET_MODULE_NUM >= 2, fw corrsponding with FTS_VENDOR_ID2
* define your own fw_file, the sample one is invalid
*/
#define FTS_UPGRADE_FW2_FILE "include/firmware/fw_sample.h"
/*
* if FTS_GET_MODULE_NUM >= 3, fw corrsponding with FTS_VENDOR_ID3
* define your own fw_file, the sample one is invalid
*/
#define FTS_UPGRADE_FW3_FILE "include/firmware/fw_sample.h"
/*********************************************************/
#endif /* _LINUX_FOCLATECH_CONFIG_H_ */

View file

@ -1,273 +0,0 @@
/*
*
* FocalTech TouchScreen driver.
*
* Copyright (c) 2012-2019, Focaltech Ltd. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/*****************************************************************************
*
* File Name: focaltech_core.h
* Author: Focaltech Driver Team
*
* Created: 2016-08-08
*
* Abstract:
*
* Reference:
*
*****************************************************************************/
#ifndef __LINUX_FOCALTECH_CORE_H__
#define __LINUX_FOCALTECH_CORE_H__
/*****************************************************************************
* Included header files
*****************************************************************************/
#include <linux/kernel.h>
#include <linux/device.h>
#include <linux/i2c.h>
#include <linux/spi/spi.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
#include <linux/gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/uaccess.h>
#include <linux/firmware.h>
#include <linux/debugfs.h>
#include <linux/mutex.h>
#include <linux/workqueue.h>
#include <linux/wait.h>
#include <linux/time.h>
#include <linux/jiffies.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/version.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/dma-mapping.h>
#include "focaltech_common.h"
/*****************************************************************************
* Private constant and macro definitions using #define
*****************************************************************************/
#define FTS_MAX_POINTS_SUPPORT 10 /* constant value, can't be changed */
#define FTS_MAX_KEYS 4
#define FTS_KEY_DIM 10
#define FTS_ONE_TCH_LEN 6
#define FTS_TOUCH_DATA_LEN (FTS_MAX_POINTS_SUPPORT * FTS_ONE_TCH_LEN + 3)
#define FTS_SPI_CLK_MAX 10000000
#define FTS_GESTURE_POINTS_MAX 6
#define FTS_GESTURE_DATA_LEN (FTS_GESTURE_POINTS_MAX * 4 + 4)
#define FTS_MAX_ID 0x0A
#define FTS_TOUCH_X_H_POS 3
#define FTS_TOUCH_X_L_POS 4
#define FTS_TOUCH_Y_H_POS 5
#define FTS_TOUCH_Y_L_POS 6
#define FTS_TOUCH_PRE_POS 7
#define FTS_TOUCH_AREA_POS 8
#define FTS_TOUCH_POINT_NUM 2
#define FTS_TOUCH_EVENT_POS 3
#define FTS_TOUCH_ID_POS 5
#define FTS_COORDS_ARR_SIZE 4
#define FTS_X_MIN_DISPLAY_DEFAULT 0
#define FTS_Y_MIN_DISPLAY_DEFAULT 0
#define FTS_X_MAX_DISPLAY_DEFAULT 720
#define FTS_Y_MAX_DISPLAY_DEFAULT 1280
#define FTS_TOUCH_DOWN 0
#define FTS_TOUCH_UP 1
#define FTS_TOUCH_CONTACT 2
#define EVENT_DOWN(flag) ((FTS_TOUCH_DOWN == flag) || (FTS_TOUCH_CONTACT == flag))
#define EVENT_UP(flag) (FTS_TOUCH_UP == flag)
#define EVENT_NO_DOWN(data) (!data->point_num)
#define FTX_MAX_COMPATIBLE_TYPE 4
#define FTX_MAX_COMMMAND_LENGTH 16
/*****************************************************************************
* Private enumerations, structures and unions using typedef
*****************************************************************************/
struct ftxxxx_proc {
struct proc_dir_entry *proc_entry;
u8 opmode;
u8 cmd_len;
u8 cmd[FTX_MAX_COMMMAND_LENGTH];
};
struct fts_ts_platform_data {
u32 irq_gpio;
u32 irq_gpio_flags;
u32 reset_gpio;
u32 reset_gpio_flags;
bool have_key;
u32 key_number;
u32 keys[FTS_MAX_KEYS];
u32 key_y_coords[FTS_MAX_KEYS];
u32 key_x_coords[FTS_MAX_KEYS];
u32 x_max;
u32 y_max;
u32 x_min;
u32 y_min;
u32 max_touch_number;
};
struct ts_event {
int x; /*x coordinate */
int y; /*y coordinate */
int p; /* pressure */
int flag; /* touch event flag: 0 -- down; 1-- up; 2 -- contact */
int id; /*touch ID */
int area;
};
struct fts_ts_data {
struct i2c_client *client;
struct spi_device *spi;
struct device *dev;
struct input_dev *input_dev;
struct fts_ts_platform_data *pdata;
struct ts_ic_info ic_info;
struct workqueue_struct *ts_workqueue;
struct work_struct fwupg_work;
struct delayed_work esdcheck_work;
struct delayed_work prc_work;
struct work_struct resume_work;
struct ftxxxx_proc proc;
spinlock_t irq_lock;
struct mutex report_mutex;
struct mutex bus_lock;
int irq;
int log_level;
int fw_is_running; /* confirm fw is running when using spi:default 0 */
bool suspended;
bool fw_loading;
bool force_reflash;
bool irq_disabled;
bool power_disabled;
bool glove_mode;
bool cover_mode;
bool charger_mode;
/* multi-touch */
struct ts_event *events;
u8 *bus_tx_buf;
u8 *bus_rx_buf;
u8 *point_buf;
int pnt_buf_size;
int touchs;
int key_state;
int touch_point;
int point_num;
struct regulator *vdd;
struct regulator *vcc_i2c;
#if FTS_PINCTRL_EN
struct pinctrl *pinctrl;
struct pinctrl_state *pins_active;
struct pinctrl_state *pins_suspend;
struct pinctrl_state *pins_release;
#endif
#if defined(CONFIG_FB) || defined(CONFIG_DRM)
struct notifier_block fb_notif;
#elif defined(CONFIG_HAS_EARLYSUSPEND)
struct early_suspend early_suspend;
#endif
};
/*****************************************************************************
* Global variable or extern global variabls/functions
*****************************************************************************/
extern struct fts_ts_data *fts_data;
/* communication interface */
int fts_read(u8 *cmd, u32 cmdlen, u8 *data, u32 datalen);
int fts_read_reg(u8 addr, u8 *value);
int fts_write(u8 *writebuf, u32 writelen);
int fts_write_reg(u8 addr, u8 value);
void fts_hid2std(void);
int fts_bus_init(struct fts_ts_data *ts_data);
int fts_bus_exit(struct fts_ts_data *ts_data);
/* Gesture functions */
#if FTS_GESTURE_EN
int fts_gesture_init(struct fts_ts_data *ts_data);
int fts_gesture_exit(struct fts_ts_data *ts_data);
void fts_gesture_recovery(struct fts_ts_data *ts_data);
int fts_gesture_readdata(struct fts_ts_data *ts_data, u8 *data);
int fts_gesture_suspend(struct fts_ts_data *ts_data);
int fts_gesture_resume(struct fts_ts_data *ts_data);
#endif
/* Apk and functions */
#if FTS_APK_NODE_EN
int fts_create_apk_debug_channel(struct fts_ts_data *);
void fts_release_apk_debug_channel(struct fts_ts_data *);
#endif
/* ADB functions */
#if FTS_SYSFS_NODE_EN
int fts_create_sysfs(struct fts_ts_data *ts_data);
int fts_remove_sysfs(struct fts_ts_data *ts_data);
#endif
/* ESD */
#if FTS_ESDCHECK_EN
int fts_esdcheck_init(struct fts_ts_data *ts_data);
int fts_esdcheck_exit(struct fts_ts_data *ts_data);
int fts_esdcheck_switch(bool enable);
int fts_esdcheck_proc_busy(bool proc_debug);
int fts_esdcheck_set_intr(bool intr);
int fts_esdcheck_suspend(void);
int fts_esdcheck_resume(void);
#endif
/* Production test */
#if FTS_TEST_EN
int fts_test_init(struct fts_ts_data *ts_data);
int fts_test_exit(struct fts_ts_data *ts_data);
#endif
/* Point Report Check*/
#if FTS_POINT_REPORT_CHECK_EN
int fts_point_report_check_init(struct fts_ts_data *ts_data);
int fts_point_report_check_exit(struct fts_ts_data *ts_data);
void fts_prc_queue_work(struct fts_ts_data *ts_data);
#endif
/* FW upgrade */
int fts_fwupg_init(struct fts_ts_data *ts_data);
int fts_fwupg_exit(struct fts_ts_data *ts_data);
int fts_fw_recovery(void);
int fts_upgrade_bin(char *fw_name, bool force);
int fts_enter_test_environment(bool test_state);
int fts_fw_update_vendor_name(const char* name);
/* Other */
int fts_reset_proc(int hdelayms);
int fts_wait_tp_to_valid(void);
void fts_release_all_finger(void);
void fts_tp_state_recovery(struct fts_ts_data *ts_data);
int fts_ex_mode_init(struct fts_ts_data *ts_data);
int fts_ex_mode_exit(struct fts_ts_data *ts_data);
int fts_ex_mode_recovery(struct fts_ts_data *ts_data);
void fts_irq_disable(void);
void fts_irq_enable(void);
#endif /* __LINUX_FOCALTECH_CORE_H__ */

View file

@ -1,464 +0,0 @@
/*
*
* FocalTech TouchScreen driver.
*
* Copyright (c) 2012-2019, FocalTech Systems, Ltd., all rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/*****************************************************************************
*
* File Name: focaltech_esdcheck.c
*
* Author: Focaltech Driver Team
*
* Created: 2016-08-03
*
* Abstract: ESD check function
*
* Version: v1.0
*
* Revision History:
* v1.0:
* First release. By luougojin 2016-08-03
* v1.1: By luougojin 2017-02-15
* 1. Add LCD_ESD_PATCH to control idc_esdcheck_lcderror
*****************************************************************************/
/*****************************************************************************
* Included header files
*****************************************************************************/
#include "focaltech_core.h"
#if FTS_ESDCHECK_EN
/*****************************************************************************
* Private constant and macro definitions using #define
*****************************************************************************/
#define ESDCHECK_WAIT_TIME 1000 /* ms */
#define LCD_ESD_PATCH 0
/*****************************************************************************
* Private enumerations, structures and unions using typedef
*****************************************************************************/
struct fts_esdcheck_st {
u8 mode : 1; /* 1- need check esd 0- no esd check */
u8 suspend : 1;
u8 proc_debug : 1; /* apk or adb use */
u8 intr : 1; /* 1- Interrupt trigger */
u8 unused : 4;
u8 flow_work_hold_cnt; /* Flow Work Cnt(reg0x91) keep a same value for x times. >=5 times is ESD, need reset */
u8 flow_work_cnt_last; /* Save Flow Work Cnt(reg0x91) value */
u32 hardware_reset_cnt;
u32 nack_cnt;
u32 dataerror_cnt;
};
/*****************************************************************************
* Static variables
*****************************************************************************/
static struct fts_esdcheck_st fts_esdcheck_data;
/*****************************************************************************
* Global variable or extern global variabls/functions
*****************************************************************************/
/*****************************************************************************
* Static function prototypes
*****************************************************************************/
/*****************************************************************************
* functions body
*****************************************************************************/
#if LCD_ESD_PATCH
int lcd_need_reset;
static int tp_need_recovery; /* LCD reset cause Tp reset */
int idc_esdcheck_lcderror(struct fts_ts_data *ts_data)
{
int ret = 0;
u8 val = 0;
FTS_DEBUG("[ESD]Check LCD ESD");
if ( (tp_need_recovery == 1) && (lcd_need_reset == 0) ) {
tp_need_recovery = 0;
/* LCD reset, need recover TP state */
fts_release_all_finger();
fts_tp_state_recovery(ts_data);
}
ret = fts_read_reg(FTS_REG_ESD_SATURATE, &val);
if ( ret < 0) {
FTS_ERROR("[ESD]: Read ESD_SATURATE(0xED) failed ret=%d!", ret);
return -EIO;
}
if (val == 0xAA) {
/*
* 1. Set flag lcd_need_reset = 1;
* 2. LCD driver need reset(recovery) LCD and set lcd_need_reset to 0
* 3. recover TP state
*/
FTS_INFO("LCD ESD, Execute LCD reset!");
lcd_need_reset = 1;
tp_need_recovery = 1;
}
return 0;
}
#endif
static int fts_esdcheck_tp_reset(struct fts_ts_data *ts_data)
{
FTS_FUNC_ENTER();
fts_esdcheck_data.flow_work_hold_cnt = 0;
fts_esdcheck_data.hardware_reset_cnt++;
fts_reset_proc(200);
fts_release_all_finger();
fts_tp_state_recovery(ts_data);
FTS_FUNC_EXIT();
return 0;
}
/*****************************************************************************
* Name: get_chip_id
* Brief: Read Chip Id 3 times
* Input:
* Output:
* Return: 1(ture) - Read Chip Id 3 times failed
* 0(false) - Read Chip Id pass
*****************************************************************************/
static bool get_chip_id(struct fts_ts_data *ts_data)
{
int ret = 0;
int i = 0;
u8 reg_value = 0;
u8 reg_addr = 0;
u8 chip_id = ts_data->ic_info.ids.chip_idh;
for (i = 0; i < 3; i++) {
reg_addr = FTS_REG_CHIP_ID;
ret = fts_read(&reg_addr, 1, &reg_value, 1);
if (ret < 0) {
FTS_ERROR("[ESD]: Read Reg 0xA3 failed ret = %d!!", ret);
fts_esdcheck_data.nack_cnt++;
} else {
if (reg_value == chip_id) {
break;
} else {
FTS_DEBUG("read chip_id:%x,retry:%d", reg_value, i);
fts_esdcheck_data.dataerror_cnt++;
}
}
msleep(10);
}
/* if can't get correct data in 3 times, then need hardware reset */
if (i >= 3) {
FTS_ERROR("[ESD]: Read Chip id 3 times failed, need execute TP reset!!");
return true;
}
return false;
}
/*****************************************************************************
* Name: get_flow_cnt
* Brief: Read flow cnt(0x91)
* Input:
* Output:
* Return: 1(true) - Reg 0x91(flow cnt) abnormal: hold a value for 5 times
* 0(false) - Reg 0x91(flow cnt) normal
*****************************************************************************/
static bool get_flow_cnt(struct fts_ts_data *ts_data)
{
int ret = 0;
u8 reg_value = 0;
u8 reg_addr = 0;
reg_addr = FTS_REG_FLOW_WORK_CNT;
ret = fts_read(&reg_addr, 1, &reg_value, 1);
if (ret < 0) {
FTS_ERROR("[ESD]: Read Reg 0x91 failed ret = %d!!", ret);
fts_esdcheck_data.nack_cnt++;
} else {
if ( reg_value == fts_esdcheck_data.flow_work_cnt_last ) {
fts_esdcheck_data.flow_work_hold_cnt++;
} else {
fts_esdcheck_data.flow_work_hold_cnt = 0;
}
fts_esdcheck_data.flow_work_cnt_last = reg_value;
}
/* if read flow work cnt 5 times and the value are all the same, then need hardware_reset */
if (fts_esdcheck_data.flow_work_hold_cnt >= 5) {
FTS_DEBUG("[ESD]: Flow Work Cnt(reg0x91) keep a value for 5 times, need execute TP reset!!");
return true;
}
return false;
}
static int esdcheck_algorithm(struct fts_ts_data *ts_data)
{
int ret = 0;
u8 reg_value = 0;
u8 reg_addr = 0;
bool hardware_reset = 0;
/* 1. esdcheck is interrupt, then return */
if (fts_esdcheck_data.intr == 1) {
FTS_DEBUG("[ESD]: In interrupt state, not check esd, return immediately!!");
return 0;
}
/* 2. check power state, if suspend, no need check esd */
if (fts_esdcheck_data.suspend == 1) {
FTS_DEBUG("[ESD]: In suspend, not check esd, return immediately!!");
/* because in suspend state, adb can be used, when upgrade FW, will active ESD check(active = 1)
* But in suspend, then will don't queue_delayed_work, when resume, don't check ESD again
*/
return 0;
}
/* 3. check fts_esdcheck_data.proc_debug state, if 1-proc busy, no need check esd*/
if (fts_esdcheck_data.proc_debug == 1) {
FTS_INFO("[ESD]: In apk or adb command mode, not check esd, return immediately!!");
return 0;
}
/* 4. In factory mode, can't check esd */
reg_addr = FTS_REG_WORKMODE;
ret = fts_read_reg(reg_addr, &reg_value);
if ( ret < 0 ) {
fts_esdcheck_data.nack_cnt++;
} else if ( (reg_value & 0x70) != FTS_REG_WORKMODE_WORK_VALUE) {
FTS_DEBUG("[ESD]: not in work mode, no check esd, return immediately!!");
return 0;
}
/* 5. IDC esd check lcd default:close */
#if LCD_ESD_PATCH
idc_esdcheck_lcderror(ts_data);
#endif
/* 6. Get Chip ID */
hardware_reset = get_chip_id(ts_data);
/* 7. get Flow work cnt: 0x91 If no change for 5 times, then ESD and reset */
if (!hardware_reset) {
hardware_reset = get_flow_cnt(ts_data);
}
/* 8. If need hardware reset, then handle it here */
if ( hardware_reset == 1) {
FTS_DEBUG("[ESD]: NoACK=%d, Error Data=%d, Hardware Reset=%d", \
fts_esdcheck_data.nack_cnt, fts_esdcheck_data.dataerror_cnt, \
fts_esdcheck_data.hardware_reset_cnt);
fts_esdcheck_tp_reset(ts_data);
}
return 0;
}
static void esdcheck_func(struct work_struct *work)
{
u8 val = 0;
struct fts_ts_data *ts_data = container_of(work,
struct fts_ts_data, esdcheck_work.work);
if (ENABLE == fts_esdcheck_data.mode) {
if (ts_data->ic_info.is_incell) {
fts_read_reg(FTS_REG_ESDCHECK_DISABLE, &val);
if (0xA5 == val) {
fts_esdcheck_data.mode = DISABLE;
return;
}
}
esdcheck_algorithm(ts_data);
queue_delayed_work(ts_data->ts_workqueue, &ts_data->esdcheck_work,
msecs_to_jiffies(ESDCHECK_WAIT_TIME));
}
}
int fts_esdcheck_set_intr(bool intr)
{
/* interrupt don't add debug message */
fts_esdcheck_data.intr = intr;
return 0;
}
int fts_esdcheck_get_status(void)
{
/* interrupt don't add debug message */
return fts_esdcheck_data.mode;
}
/*****************************************************************************
* Name: fts_esdcheck_proc_busy
* Brief: When APK or ADB command access TP via driver, then need set proc_debug,
* then will not check ESD.
* Input:
* Output:
* Return:
*****************************************************************************/
int fts_esdcheck_proc_busy(bool proc_debug)
{
fts_esdcheck_data.proc_debug = proc_debug;
return 0;
}
/*****************************************************************************
* Name: fts_esdcheck_switch
* Brief: FTS esd check function switch.
* Input: enable: 1 - Enable esd check
* 0 - Disable esd check
* Output:
* Return:
*****************************************************************************/
int fts_esdcheck_switch(bool enable)
{
struct fts_ts_data *ts_data = fts_data;
FTS_FUNC_ENTER();
if (fts_esdcheck_data.mode == ENABLE) {
if (enable) {
FTS_DEBUG("[ESD]: ESD check start!!");
fts_esdcheck_data.flow_work_hold_cnt = 0;
fts_esdcheck_data.flow_work_cnt_last = 0;
queue_delayed_work(ts_data->ts_workqueue, &ts_data->esdcheck_work,
msecs_to_jiffies(ESDCHECK_WAIT_TIME));
} else {
FTS_DEBUG("[ESD]: ESD check stop!!");
cancel_delayed_work_sync(&ts_data->esdcheck_work);
}
} else {
FTS_DEBUG("[ESD]: ESD should disable!!");
cancel_delayed_work_sync(&ts_data->esdcheck_work);
}
FTS_FUNC_EXIT();
return 0;
}
int fts_esdcheck_suspend(void)
{
FTS_FUNC_ENTER();
fts_esdcheck_switch(DISABLE);
fts_esdcheck_data.suspend = 1;
FTS_FUNC_EXIT();
return 0;
}
int fts_esdcheck_resume( void )
{
FTS_FUNC_ENTER();
fts_esdcheck_switch(ENABLE);
fts_esdcheck_data.suspend = 0;
FTS_FUNC_EXIT();
return 0;
}
static ssize_t fts_esdcheck_store(
struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct input_dev *input_dev = fts_data->input_dev;
mutex_lock(&input_dev->mutex);
if (FTS_SYSFS_ECHO_ON(buf)) {
FTS_DEBUG("enable esdcheck");
fts_esdcheck_data.mode = ENABLE;
fts_esdcheck_switch(ENABLE);
} else if (FTS_SYSFS_ECHO_OFF(buf)) {
FTS_DEBUG("disable esdcheck");
fts_esdcheck_data.mode = DISABLE;
fts_esdcheck_switch(DISABLE);
}
mutex_unlock(&input_dev->mutex);
return count;
}
static ssize_t fts_esdcheck_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
int count;
struct input_dev *input_dev = fts_data->input_dev;
mutex_lock(&input_dev->mutex);
count = snprintf(buf, PAGE_SIZE, "Esd check: %s\n", \
fts_esdcheck_get_status() ? "On" : "Off");
mutex_unlock(&input_dev->mutex);
return count;
}
/* sysfs esd node
* read example: cat fts_esd_mode ---read esd mode
* write example:echo 01 > fts_esd_mode ---make esdcheck enable
*
*/
static DEVICE_ATTR (fts_esd_mode, S_IRUGO | S_IWUSR, fts_esdcheck_show, fts_esdcheck_store);
static struct attribute *fts_esd_mode_attrs[] = {
&dev_attr_fts_esd_mode.attr,
NULL,
};
static struct attribute_group fts_esd_group = {
.attrs = fts_esd_mode_attrs,
};
int fts_create_esd_sysfs(struct device *dev)
{
int ret = 0;
ret = sysfs_create_group(&dev->kobj, &fts_esd_group);
if ( ret != 0) {
FTS_ERROR("fts_create_esd_sysfs(sysfs) create failed!");
sysfs_remove_group(&dev->kobj, &fts_esd_group);
return ret;
}
return 0;
}
int fts_esdcheck_init(struct fts_ts_data *ts_data)
{
FTS_FUNC_ENTER();
if (ts_data->ts_workqueue) {
INIT_DELAYED_WORK(&ts_data->esdcheck_work, esdcheck_func);
} else {
FTS_ERROR("fts workqueue is NULL, can't run esd check function");
return -EINVAL;
}
memset((u8 *)&fts_esdcheck_data, 0, sizeof(struct fts_esdcheck_st));
fts_esdcheck_data.mode = ENABLE;
fts_esdcheck_switch(ENABLE);
fts_create_esd_sysfs(ts_data->dev);
FTS_FUNC_EXIT();
return 0;
}
int fts_esdcheck_exit(struct fts_ts_data *ts_data)
{
sysfs_remove_group(&ts_data->dev->kobj, &fts_esd_group);
return 0;
}
#endif /* FTS_ESDCHECK_EN */

View file

@ -1,307 +0,0 @@
/*
*
* FocalTech ftxxxx TouchScreen driver.
*
* Copyright (c) 2012-2019, Focaltech Ltd. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/*****************************************************************************
*
* File Name: focaltech_ex_mode.c
*
* Author: Focaltech Driver Team
*
* Created: 2016-08-31
*
* Abstract:
*
* Reference:
*
*****************************************************************************/
/*****************************************************************************
* 1.Included header files
*****************************************************************************/
#include "focaltech_core.h"
/*****************************************************************************
* 2.Private constant and macro definitions using #define
*****************************************************************************/
/*****************************************************************************
* 3.Private enumerations, structures and unions using typedef
*****************************************************************************/
enum _ex_mode {
MODE_GLOVE = 0,
MODE_COVER,
MODE_CHARGER,
};
/*****************************************************************************
* 4.Static variables
*****************************************************************************/
/*****************************************************************************
* 5.Global variable or extern global variabls/functions
*****************************************************************************/
/*****************************************************************************
* 6.Static function prototypes
*******************************************************************************/
static int fts_ex_mode_switch(enum _ex_mode mode, u8 value)
{
int ret = 0;
u8 m_val = 0;
if (value)
m_val = 0x01;
else
m_val = 0x00;
switch (mode) {
case MODE_GLOVE:
ret = fts_write_reg(FTS_REG_GLOVE_MODE_EN, m_val);
if (ret < 0) {
FTS_ERROR("MODE_GLOVE switch to %d fail", m_val);
}
break;
case MODE_COVER:
ret = fts_write_reg(FTS_REG_COVER_MODE_EN, m_val);
if (ret < 0) {
FTS_ERROR("MODE_COVER switch to %d fail", m_val);
}
break;
case MODE_CHARGER:
ret = fts_write_reg(FTS_REG_CHARGER_MODE_EN, m_val);
if (ret < 0) {
FTS_ERROR("MODE_CHARGER switch to %d fail", m_val);
}
break;
default:
FTS_ERROR("mode(%d) unsupport", mode);
ret = -EINVAL;
break;
}
return ret;
}
static ssize_t fts_glove_mode_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
int count = 0;
u8 val = 0;
struct fts_ts_data *ts_data = fts_data;
struct input_dev *input_dev = ts_data->input_dev;
mutex_lock(&input_dev->mutex);
fts_read_reg(FTS_REG_GLOVE_MODE_EN, &val);
count = snprintf(buf + count, PAGE_SIZE, "Glove Mode:%s\n",
ts_data->glove_mode ? "On" : "Off");
count += snprintf(buf + count, PAGE_SIZE, "Glove Reg(0xC0):%d\n", val);
mutex_unlock(&input_dev->mutex);
return count;
}
static ssize_t fts_glove_mode_store(
struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int ret = 0;
struct fts_ts_data *ts_data = fts_data;
if (FTS_SYSFS_ECHO_ON(buf)) {
if (!ts_data->glove_mode) {
FTS_DEBUG("enter glove mode");
ret = fts_ex_mode_switch(MODE_GLOVE, ENABLE);
if (ret >= 0) {
ts_data->glove_mode = ENABLE;
}
}
} else if (FTS_SYSFS_ECHO_OFF(buf)) {
if (ts_data->glove_mode) {
FTS_DEBUG("exit glove mode");
ret = fts_ex_mode_switch(MODE_GLOVE, DISABLE);
if (ret >= 0) {
ts_data->glove_mode = DISABLE;
}
}
}
FTS_DEBUG("glove mode:%d", ts_data->glove_mode);
return count;
}
static ssize_t fts_cover_mode_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
int count = 0;
u8 val = 0;
struct fts_ts_data *ts_data = fts_data;
struct input_dev *input_dev = ts_data->input_dev;
mutex_lock(&input_dev->mutex);
fts_read_reg(FTS_REG_COVER_MODE_EN, &val);
count = snprintf(buf + count, PAGE_SIZE, "Cover Mode:%s\n",
ts_data->cover_mode ? "On" : "Off");
count += snprintf(buf + count, PAGE_SIZE, "Cover Reg(0xC1):%d\n", val);
mutex_unlock(&input_dev->mutex);
return count;
}
static ssize_t fts_cover_mode_store(
struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int ret = 0;
struct fts_ts_data *ts_data = fts_data;
if (FTS_SYSFS_ECHO_ON(buf)) {
if (!ts_data->cover_mode) {
FTS_DEBUG("enter cover mode");
ret = fts_ex_mode_switch(MODE_COVER, ENABLE);
if (ret >= 0) {
ts_data->cover_mode = ENABLE;
}
}
} else if (FTS_SYSFS_ECHO_OFF(buf)) {
if (ts_data->cover_mode) {
FTS_DEBUG("exit cover mode");
ret = fts_ex_mode_switch(MODE_COVER, DISABLE);
if (ret >= 0) {
ts_data->cover_mode = DISABLE;
}
}
}
FTS_DEBUG("cover mode:%d", ts_data->cover_mode);
return count;
}
static ssize_t fts_charger_mode_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
int count = 0;
u8 val = 0;
struct fts_ts_data *ts_data = fts_data;
struct input_dev *input_dev = ts_data->input_dev;
mutex_lock(&input_dev->mutex);
fts_read_reg(FTS_REG_CHARGER_MODE_EN, &val);
count = snprintf(buf + count, PAGE_SIZE, "Charger Mode:%s\n",
ts_data->charger_mode ? "On" : "Off");
count += snprintf(buf + count, PAGE_SIZE, "Charger Reg(0x8B):%d\n", val);
mutex_unlock(&input_dev->mutex);
return count;
}
static ssize_t fts_charger_mode_store(
struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
int ret = 0;
struct fts_ts_data *ts_data = fts_data;
if (FTS_SYSFS_ECHO_ON(buf)) {
if (!ts_data->charger_mode) {
FTS_DEBUG("enter charger mode");
ret = fts_ex_mode_switch(MODE_CHARGER, ENABLE);
if (ret >= 0) {
ts_data->charger_mode = ENABLE;
}
}
} else if (FTS_SYSFS_ECHO_OFF(buf)) {
if (ts_data->charger_mode) {
FTS_DEBUG("exit charger mode");
ret = fts_ex_mode_switch(MODE_CHARGER, DISABLE);
if (ret >= 0) {
ts_data->charger_mode = DISABLE;
}
}
}
FTS_DEBUG("charger mode:%d", ts_data->glove_mode);
return count;
}
/* read and write charger mode
* read example: cat fts_glove_mode ---read glove mode
* write example:echo 1 > fts_glove_mode ---write glove mode to 01
*/
static DEVICE_ATTR(fts_glove_mode, S_IRUGO | S_IWUSR,
fts_glove_mode_show, fts_glove_mode_store);
static DEVICE_ATTR(fts_cover_mode, S_IRUGO | S_IWUSR,
fts_cover_mode_show, fts_cover_mode_store);
static DEVICE_ATTR(fts_charger_mode, S_IRUGO | S_IWUSR,
fts_charger_mode_show, fts_charger_mode_store);
static struct attribute *fts_touch_mode_attrs[] = {
&dev_attr_fts_glove_mode.attr,
&dev_attr_fts_cover_mode.attr,
&dev_attr_fts_charger_mode.attr,
NULL,
};
static struct attribute_group fts_touch_mode_group = {
.attrs = fts_touch_mode_attrs,
};
int fts_ex_mode_recovery(struct fts_ts_data *ts_data)
{
if (ts_data->glove_mode) {
fts_ex_mode_switch(MODE_GLOVE, ENABLE);
}
if (ts_data->cover_mode) {
fts_ex_mode_switch(MODE_COVER, ENABLE);
}
if (ts_data->charger_mode) {
fts_ex_mode_switch(MODE_CHARGER, ENABLE);
}
return 0;
}
int fts_ex_mode_init(struct fts_ts_data *ts_data)
{
int ret = 0;
ts_data->glove_mode = DISABLE;
ts_data->cover_mode = DISABLE;
ts_data->charger_mode = DISABLE;
ret = sysfs_create_group(&ts_data->dev->kobj, &fts_touch_mode_group);
if (ret < 0) {
FTS_ERROR("create sysfs(ex_mode) fail");
sysfs_remove_group(&ts_data->dev->kobj, &fts_touch_mode_group);
return ret;
} else {
FTS_DEBUG("create sysfs(ex_mode) succeedfully");
}
return 0;
}
int fts_ex_mode_exit(struct fts_ts_data *ts_data)
{
sysfs_remove_group(&ts_data->dev->kobj, &fts_touch_mode_group);
return 0;
}

View file

@ -1,618 +0,0 @@
/*
*
* FocalTech fts TouchScreen driver.
*
* Copyright (c) 2012-2019, Focaltech Ltd. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/*****************************************************************************
*
* File Name: focaltech_flash.c
*
* Author: Focaltech Driver Team
*
* Created: 2017-12-06
*
* Abstract:
*
* Reference:
*
*****************************************************************************/
/*****************************************************************************
* 1.Included header files
*****************************************************************************/
#include "focaltech_core.h"
#include "focaltech_flash.h"
/*****************************************************************************
* Static variables
*****************************************************************************/
#define FTS_FW_REQUEST_SUPPORT 1
/* Example: focaltech_ts_fw_tianma.bin */
#define FTS_FW_NAME_PREX_WITH_REQUEST ""
/*****************************************************************************
* Global variable or extern global variabls/functions
*****************************************************************************/
u8 fw_file[] = {
};
u8 fw_file2[] = {
};
u8 fw_file3[] = {
};
struct upgrade_module module_list[] = {
{FTS_MODULE_ID, FTS_MODULE_NAME, fw_file, sizeof(fw_file)},
{FTS_MODULE2_ID, FTS_MODULE2_NAME, fw_file2, sizeof(fw_file2)},
{FTS_MODULE3_ID, FTS_MODULE3_NAME, fw_file3, sizeof(fw_file3)},
};
struct fts_upgrade *fwupgrade;
int fts_check_bootid(void)
{
int ret = 0;
u8 cmd = 0;
u8 id[2] = { 0 };
struct ft_chip_t *chip_id = &fts_data->ic_info.ids;
cmd = FTS_CMD_READ_ID;
ret = fts_read(&cmd, 1, id, 2);
if (ret < 0) {
FTS_ERROR("read boot id fail");
return ret;
}
FTS_INFO("read boot id:0x%02x 0x%02x", id[0], id[1]);
if ((chip_id->chip_idh == id[0]) && (chip_id->chip_idl == id[1])) {
return 0;
}
return -EIO;
}
static int fts_fw_download(const u8 *buf, u32 len, bool need_reset)
{
int ret = 0;
int i = 0;
struct fts_ts_data *ts_data = fts_data;
FTS_INFO("fw upgrade download function");
if (!buf || (len < FTS_MIN_LEN)) {
FTS_ERROR("fw/len(%d) is invalid", len);
return -EINVAL;
}
ts_data->fw_loading = 1;
fts_irq_disable();
#if FTS_ESDCHECK_EN
fts_esdcheck_switch(DISABLE);
#endif
for (i = 0; i < 3; i++) {
FTS_INFO("fw download times:%d", i + 1);
ret = fts_fw_write_start(buf, len, need_reset);
if (0 == ret)
break;
}
if (i >= 3) {
FTS_ERROR("fw download fail");
ret = -EIO;
goto err_fw_download;
}
#if FTS_ESDCHECK_EN
fts_esdcheck_switch(ENABLE);
#endif
ret = 0;
err_fw_download:
fts_irq_enable();
ts_data->fw_loading = 0;
return ret;
}
static int fts_read_file(char *file_name, u8 **file_buf)
{
int ret = 0;
char file_path[FILE_NAME_LENGTH] = { 0 };
struct file *filp = NULL;
struct inode *inode;
mm_segment_t old_fs;
loff_t pos;
loff_t file_len = 0;
if ((NULL == file_name) || (NULL == file_buf)) {
FTS_ERROR("filename/filebuf is NULL");
return -EINVAL;
}
snprintf(file_path, FILE_NAME_LENGTH, "%s%s", FTS_FW_BIN_FILEPATH, file_name);
filp = filp_open(file_path, O_RDONLY, 0);
if (IS_ERR(filp)) {
FTS_ERROR("open %s file fail", file_path);
return -ENOENT;
}
#if 1
inode = filp->f_inode;
#else
/* reserved for linux earlier verion */
inode = filp->f_dentry->d_inode;
#endif
file_len = inode->i_size;
*file_buf = (u8 *)vmalloc(file_len);
if (NULL == *file_buf) {
FTS_ERROR("file buf malloc fail");
filp_close(filp, NULL);
return -ENOMEM;
}
old_fs = get_fs();
set_fs(KERNEL_DS);
pos = 0;
ret = vfs_read(filp, *file_buf, file_len , &pos);
if (ret < 0)
FTS_ERROR("read file fail");
FTS_INFO("file len:%d read len:%d pos:%d", (u32)file_len, ret, (u32)pos);
filp_close(filp, NULL);
set_fs(old_fs);
return ret;
}
int fts_upgrade_bin(char *fw_name, bool force)
{
int ret = 0;
u32 fw_file_len = 0;
u8 *fw_file_buf = NULL;
struct fts_upgrade *upg = fwupgrade;
FTS_INFO("start upgrade with fw bin");
if (NULL == upg) {
FTS_ERROR("upgrade/func is null");
return -EINVAL;
}
if (upg->ts_data->fw_loading) {
FTS_INFO("fw is loading, not download again");
return -EINVAL;
}
ret = fts_read_file(fw_name, &fw_file_buf);
if ((ret < 0) || (ret < FTS_MIN_LEN) || (ret > FTS_MAX_LEN_FILE)) {
FTS_ERROR("read fw bin file(sdcard) fail, len:%d", fw_file_len);
goto err_bin;
}
fw_file_len = ret;
FTS_INFO("fw bin file len:%d", fw_file_len);
ret = fts_fw_download(fw_file_buf, fw_file_len, true);
if (ret < 0) {
FTS_ERROR("upgrade fw bin failed");
goto err_bin;
}
FTS_INFO("upgrade fw bin success");
err_bin:
if (fw_file_buf) {
vfree(fw_file_buf);
fw_file_buf = NULL;
}
return ret;
}
int fts_enter_test_environment(bool test_state)
{
int ret = 0;
u8 detach_flag = 0;
struct fts_upgrade *upg = fwupgrade;
FTS_INFO("fw test download function");
if (!upg) {
FTS_ERROR("upg is null");
return -EINVAL;
}
if (fts_data->fw_loading) {
FTS_INFO("fw is loading, not download again");
return -EINVAL;
}
if (!upg->fw || (upg->fw_length <= FTS_MAX_LEN_APP)) {
FTS_INFO("not multi-app");
return 0;
}
if (test_state) {
ret = fts_fw_download(upg->fw + FTS_MAX_LEN_APP, upg->fw_length, true);
} else {
ret = fts_fw_download(upg->fw, upg->fw_length, true);
}
if (ret < 0) {
FTS_ERROR("fw(app2) download fail");
return ret;
}
msleep(50);
ret = fts_read_reg(FTS_REG_FACTORY_MODE_DETACH_FLAG, &detach_flag);
FTS_INFO("regb4:0x%02x", detach_flag);
return 0;
}
static int fts_fw_resume(void)
{
int ret = 0;
struct fts_upgrade *upg = fwupgrade;
const struct firmware *fw = NULL;
char fwname[FILE_NAME_LENGTH] = { 0 };
FTS_INFO("fw upgrade resume function");
if (!upg || !upg->fw) {
FTS_ERROR("upg/fw is null");
return -EINVAL;
}
if (upg->ts_data->fw_loading) {
FTS_INFO("fw is loading, not download again");
return -EINVAL;
}
snprintf(fwname, FILE_NAME_LENGTH, "%s%s.bin", \
FTS_FW_NAME_PREX_WITH_REQUEST, upg->module_info->vendor_name);
/* 1. request firmware */
ret = request_firmware(&fw, fwname, upg->ts_data->dev);
if (ret != 0) {
FTS_ERROR("%s:firmware(%s) request fail,ret=%d\n",
__func__, fwname, ret);
FTS_INFO("download fw from bootimage");
ret = fts_fw_download(upg->fw, upg->fw_length, false);
} else {
FTS_INFO("firmware(%s) request successfully", fwname);
ret = fts_fw_download(fw->data, fw->size, false);
}
if (ret < 0) {
FTS_ERROR("fw resume download failed");
return ret;
}
/* update to newest fw if needed */
if (fw != NULL) {
u8 *tmpbuf = NULL;
if (upg->fw_from_request)
vfree(upg->fw);
tmpbuf = vmalloc(fw->size);
if (NULL == tmpbuf) {
FTS_ERROR("fw buffer vmalloc fail");
ret = -ENOMEM;
goto FTS_FW_RESUME_VMALLOC_ERROR;
} else {
memcpy(tmpbuf, fw->data, fw->size);
upg->fw = tmpbuf;
upg->fw_length = fw->size;
upg->fw_from_request = 1;
}
}
FTS_FW_RESUME_VMALLOC_ERROR:
if (fw != NULL) {
release_firmware(fw);
fw = NULL;
}
return ret;
}
int fts_fw_recovery(void)
{
int ret = 0;
u8 boot_state = 0;
u8 chip_id = 0;
struct fts_upgrade *upg = fwupgrade;
FTS_INFO("check if boot recovery");
if (!upg || !upg->ts_data) {
FTS_ERROR("upg/ts_data is null");
return -EINVAL;
}
if (upg->ts_data->fw_loading) {
FTS_INFO("fw is loading, not download again");
return -EINVAL;
}
upg->ts_data->fw_is_running = false;
if (!upg->ts_data->force_reflash) {
ret = fts_check_bootid();
if (ret < 0) {
FTS_ERROR("check boot id fail");
upg->ts_data->fw_is_running = true;
return ret;
}
ret = fts_read_reg(0xD0, &boot_state);
if (ret < 0) {
FTS_ERROR("read boot state failed, ret=%d", ret);
upg->ts_data->fw_is_running = true;
return ret;
}
if (boot_state != 0x01) {
FTS_INFO("not in boot mode(0x%x),exit", boot_state);
upg->ts_data->fw_is_running = true;
return -EIO;
}
FTS_INFO("abnormal situation,need download fw");
}
ret = fts_fw_resume();
if (ret < 0) {
FTS_ERROR("fts_fw_resume fail");
return ret;
}
msleep(10);
ret = fts_read_reg(FTS_REG_CHIP_ID, &chip_id);
FTS_INFO("read chip id:0x%02x", chip_id);
fts_tp_state_recovery(upg->ts_data);
FTS_INFO("boot recovery pass");
return ret;
}
int fts_fw_update_vendor_name(const char* name) {
struct fts_upgrade *upg = fwupgrade;
char* pos;
int len;
if (!upg || !upg->module_info) {
FTS_ERROR("upgrade struct not init");
return -EINVAL;
}
len = strlen(name);
if (len > FILE_NAME_LENGTH) {
FTS_ERROR("vendor name is too long");
return -EINVAL;
}
pos = strstr(name, ".bin");
if (pos == NULL)
snprintf(upg->module_info->vendor_name, FILE_NAME_LENGTH, "%s", name);
else {
len = len - strlen(".bin");
snprintf(upg->module_info->vendor_name, len + 1, "%s", name);
}
return 0;
}
static int fts_fwupg_get_module_info(struct fts_upgrade *upg)
{
int i = 0;
struct upgrade_module *info = &module_list[0];
if (!upg || !upg->ts_data) {
FTS_ERROR("upg/ts_data is null");
return -EINVAL;
}
if (FTS_GET_MODULE_NUM > 1) {
FTS_INFO("module id:%04x", upg->module_id);
for (i = 0; i < FTS_GET_MODULE_NUM; i++) {
info = &module_list[i];
if (upg->module_id == info->id) {
FTS_INFO("module id match, get fw file successfully");
break;
}
}
if (i >= FTS_GET_MODULE_NUM) {
FTS_ERROR("no module id match, don't get file");
return -ENODATA;
}
}
upg->module_info = info;
return 0;
}
static int fts_get_fw_file_via_request_firmware(struct fts_upgrade *upg)
{
int ret = 0;
const struct firmware *fw = NULL;
u8 *tmpbuf = NULL;
char fwname[FILE_NAME_LENGTH] = { 0 };
snprintf(fwname, FILE_NAME_LENGTH, "%s%s.bin", \
FTS_FW_NAME_PREX_WITH_REQUEST, \
upg->module_info->vendor_name);
ret = request_firmware(&fw, fwname, upg->ts_data->dev);
if (0 == ret) {
FTS_INFO("firmware(%s) request successfully", fwname);
tmpbuf = vmalloc(fw->size);
if (NULL == tmpbuf) {
FTS_ERROR("fw buffer vmalloc fail");
ret = -ENOMEM;
} else {
memcpy(tmpbuf, fw->data, fw->size);
upg->fw = tmpbuf;
upg->fw_length = fw->size;
upg->fw_from_request = 1;
}
} else {
FTS_INFO("firmware(%s) request fail,ret=%d", fwname, ret);
}
if (fw != NULL) {
release_firmware(fw);
fw = NULL;
}
return ret;
}
static int fts_get_fw_file_via_i(struct fts_upgrade *upg)
{
upg->fw = upg->module_info->fw_file;
upg->fw_length = upg->module_info->fw_len;
upg->fw_from_request = 0;
return 0;
}
/*****************************************************************************
* Name: fts_fwupg_get_fw_file
* Brief: get fw image/file,
* If support muitl modules, please set FTS_GET_MODULE_NUM, and FTS_-
* MODULE_ID/FTS_MODULE_NAME;
* If get fw via .i file, please set FTS_FW_REQUEST_SUPPORT=0, and F-
* TS_MODULE_ID; will use module id to distingwish different modules;
* If get fw via reques_firmware(), please set FTS_FW_REQUEST_SUPPORT
* =1, and FTS_MODULE_NAME; fw file name will be composed of "focalt-
* ech_ts_fw_" & FTS_VENDOR_NAME;
*
* If have flash, module_id=vendor_id, If non-flash,module_id need
* transfer from LCD driver(gpio or lcm_id or ...);
* Input:
* Output:
* Return: return 0 if success, otherwise return error code
*****************************************************************************/
static int fts_fwupg_get_fw_file(struct fts_upgrade *upg)
{
int ret = 0;
bool get_fw_i_flag = false;
FTS_DEBUG("get upgrade fw file");
if (!upg || !upg->ts_data) {
FTS_ERROR("upg/ts_data is null");
return -EINVAL;
}
ret = fts_fwupg_get_module_info(upg);
if ((ret < 0) || (!upg->module_info)) {
FTS_ERROR("get module info fail");
return ret;
}
if (FTS_FW_REQUEST_SUPPORT) {
msleep(500);
ret = fts_get_fw_file_via_request_firmware(upg);
if (ret != 0) {
get_fw_i_flag = true;
}
} else {
get_fw_i_flag = true;
}
if (get_fw_i_flag) {
ret = fts_get_fw_file_via_i(upg);
}
FTS_INFO("upgrade fw file len:%d", upg->fw_length);
if ((upg->fw_length < FTS_MIN_LEN)
|| (upg->fw_length > FTS_MAX_LEN_FILE)) {
FTS_ERROR("fw file len(%d) fail", upg->fw_length);
return -ENODATA;
}
return ret;
}
static void fts_fwupg_work(struct work_struct *work)
{
int ret = 0;
u8 chip_id = 0;
struct fts_upgrade *upg = fwupgrade;
FTS_INFO("fw upgrade work function");
if (!upg || !upg->ts_data) {
FTS_ERROR("upg/ts_data is null");
return ;
}
/* get fw */
ret = fts_fwupg_get_fw_file(upg);
if (ret < 0) {
FTS_ERROR("get file fail, can't upgrade");
return ;
}
#if !FTS_AUTO_UPGRADE_EN
FTS_INFO("FTS_AUTO_UPGRADE_EN is disabled, not upgrade when power on");
return ;
#endif
if (upg->ts_data->fw_loading) {
FTS_INFO("fw is loading, not download again");
return ;
}
ret = fts_fw_download(upg->fw, upg->fw_length, true);
if (ret < 0) {
FTS_ERROR("fw auto download failed");
} else {
msleep(50);
ret = fts_read_reg(FTS_REG_CHIP_ID, &chip_id);
FTS_INFO("read chip id:0x%02x", chip_id);
}
}
int fts_fwupg_init(struct fts_ts_data *ts_data)
{
FTS_INFO("fw upgrade init function");
if (!ts_data || !ts_data->ts_workqueue) {
FTS_ERROR("ts_data/workqueue is NULL, can't run upgrade function");
return -EINVAL;
}
fwupgrade = (struct fts_upgrade *)kzalloc(sizeof(*fwupgrade), GFP_KERNEL);
if (NULL == fwupgrade) {
FTS_ERROR("malloc memory for upgrade fail");
return -ENOMEM;
}
#if FTS_ESDCHECK_EN
fts_esdcheck_switch(DISABLE);
#endif
fwupgrade->ts_data = ts_data;
INIT_WORK(&ts_data->fwupg_work, fts_fwupg_work);
queue_work(ts_data->ts_workqueue, &ts_data->fwupg_work);
return 0;
}
int fts_fwupg_exit(struct fts_ts_data *ts_data)
{
FTS_FUNC_ENTER();
if (fwupgrade) {
if (fwupgrade->fw_from_request) {
vfree(fwupgrade->fw);
fwupgrade->fw = NULL;
}
kfree(fwupgrade);
fwupgrade = NULL;
}
FTS_FUNC_EXIT();
return 0;
}

View file

@ -1,185 +0,0 @@
/************************************************************************
* Copyright (C) 2012-2019, Focaltech Systems (R)£¬All Rights Reserved.
*
* File Name: focaltech_flash.h
*
* Author: Focaltech Driver Team
*
* Created: 2016-08-07
*
* Abstract:
*
************************************************************************/
#ifndef __LINUX_FOCALTECH_FLASH_H__
#define __LINUX_FOCALTECH_FLASH_H__
/*****************************************************************************
* 1.Included header files
*****************************************************************************/
#include "focaltech_core.h"
/*****************************************************************************
* Private constant and macro definitions using #define
*****************************************************************************/
#define FTS_CMD_RESET 0x07
#define FTS_ROMBOOT_CMD_SET_PRAM_ADDR 0xAD
#define FTS_ROMBOOT_CMD_SET_PRAM_ADDR_LEN 4
#define FTS_ROMBOOT_CMD_WRITE 0xAE
#define FTS_ROMBOOT_CMD_START_APP 0x08
#define FTS_DELAY_PRAMBOOT_START 10
#define FTS_ROMBOOT_CMD_ECC 0xCC
#define FTS_PRAM_SADDR 0x000000
#define FTS_DRAM_SADDR 0xD00000
#define FTS_CMD_READ 0x03
#define FTS_CMD_READ_DELAY 1
#define FTS_CMD_READ_LEN 4
#define FTS_CMD_FLASH_TYPE 0x05
#define FTS_CMD_FLASH_MODE 0x09
#define FLASH_MODE_WRITE_FLASH_VALUE 0x0A
#define FLASH_MODE_UPGRADE_VALUE 0x0B
#define FLASH_MODE_LIC_VALUE 0x0C
#define FLASH_MODE_PARAM_VALUE 0x0D
#define FTS_CMD_ERASE_APP 0x61
#define FTS_REASE_APP_DELAY 1350
#define FTS_ERASE_SECTOR_DELAY 60
#define FTS_RETRIES_REASE 50
#define FTS_RETRIES_DELAY_REASE 200
#define FTS_CMD_FLASH_STATUS 0x6A
#define FTS_CMD_FLASH_STATUS_LEN 2
#define FTS_CMD_FLASH_STATUS_NOP 0x0000
#define FTS_CMD_FLASH_STATUS_ECC_OK 0xF055
#define FTS_CMD_FLASH_STATUS_ERASE_OK 0xF0AA
#define FTS_CMD_FLASH_STATUS_WRITE_OK 0x1000
#define FTS_CMD_ECC_INIT 0x64
#define FTS_CMD_ECC_CAL 0x65
#define FTS_CMD_ECC_CAL_LEN 6
#define FTS_RETRIES_ECC_CAL 10
#define FTS_RETRIES_DELAY_ECC_CAL 50
#define FTS_CMD_ECC_READ 0x66
#define FTS_CMD_DATA_LEN 0xB0
#define FTS_CMD_APP_DATA_LEN_INCELL 0x7A
#define FTS_CMD_DATA_LEN_LEN 4
#define FTS_CMD_WRITE 0xBF
#define FTS_RETRIES_WRITE 100
#define FTS_RETRIES_DELAY_WRITE 1
#define FTS_CMD_WRITE_LEN 6
#define FTS_DELAY_READ_ID 20
#define FTS_DELAY_UPGRADE_RESET 80
#define PRAMBOOT_MIN_SIZE 0x120
#define PRAMBOOT_MAX_SIZE (64*1024)
#define FTS_FLASH_PACKET_LENGTH 32 /* max=128 */
#define FTS_MAX_LEN_ECC_CALC 0xFFFE /* must be even */
#define FTS_MIN_LEN 0x120
#define FTS_MAX_LEN_FILE (128 * 1024)
#define FTS_MAX_LEN_APP (64 * 1024)
#define FTS_MAX_LEN_APP_PARAMS (32 * 1024)
#define FTS_MAX_LEN_SECTOR (4 * 1024)
#define FTS_CONIFG_VENDORID_OFF 0x04
#define FTS_CONIFG_MODULEID_OFF 0x1E
#define FTS_CONIFG_PROJECTID_OFF 0x20
#define FTS_APPINFO_OFF 0x100
#define FTS_APPINFO_APPLEN_OFF 0x00
#define FTS_APPINFO_APPLEN2_OFF 0x12
#define FTS_REG_UPGRADE 0xFC
#define FTS_REG_UPGRADE2 0xBC
#define FTS_UPGRADE_AA 0xAA
#define FTS_UPGRADE_55 0x55
#define FTS_DELAY_UPGRADE_AA 10
#define FTS_UPGRADE_LOOP 30
#define FTS_HEADER_LEN 32
#define FTS_FW_BIN_FILEPATH "/sdcard/"
#define FTS_FW_IDE_SIG "IDE_"
#define FTS_FW_IDE_SIG_LEN 4
#define MAX_MODULE_VENDOR_NAME_LEN 16
#define FTS_ROMBOOT_CMD_ECC_NEW_LEN 7
#define FTS_ECC_FINISH_TIMEOUT 100
#define FTS_ROMBOOT_CMD_ECC_FINISH 0xCE
#define FTS_ROMBOOT_CMD_ECC_FINISH_OK_A5 0xA5
#define FTS_ROMBOOT_CMD_ECC_FINISH_OK_00 0x00
#define FTS_ROMBOOT_CMD_ECC_READ 0xCD
#define AL2_FCS_COEF ((1 << 15) + (1 << 10) + (1 << 3))
#define FTS_APP_INFO_OFFSET 0x100
enum FW_STATUS {
FTS_RUN_IN_ERROR,
FTS_RUN_IN_APP,
FTS_RUN_IN_ROM,
FTS_RUN_IN_PRAM,
FTS_RUN_IN_BOOTLOADER,
};
enum FW_FLASH_MODE {
FLASH_MODE_APP,
FLASH_MODE_LIC,
FLASH_MODE_PARAM,
FLASH_MODE_ALL,
};
enum ECC_CHECK_MODE {
ECC_CHECK_MODE_XOR,
ECC_CHECK_MODE_CRC16,
};
/*****************************************************************************
* Private enumerations, structures and unions using typedef
*****************************************************************************/
/* IC info */
struct upgrade_func {
u64 ctype[FTX_MAX_COMPATIBLE_TYPE];
u32 fwveroff;
u32 fwcfgoff;
u32 appoff;
u32 licoff;
u32 paramcfgoff;
u32 paramcfgveroff;
u32 paramcfg2off;
int pram_ecc_check_mode;
int fw_ecc_check_mode;
bool new_return_value_from_ic;
bool appoff_handle_in_ic;
bool is_reset_register_BC;
bool read_boot_id_need_reset;
bool hid_supported;
bool pramboot_supported;
u8 *pramboot;
u32 pb_length;
int (*init)(u8 *, u32);
int (*upgrade)(u8 *, u32);
int (*get_hlic_ver)(u8 *);
int (*lic_upgrade)(u8 *, u32);
int (*param_upgrade)(u8 *, u32);
int (*force_upgrade)(u8 *, u32);
};
struct upgrade_module {
int id;
char vendor_name[MAX_MODULE_VENDOR_NAME_LEN];
u8 *fw_file;
u32 fw_len;
};
struct fts_upgrade {
struct fts_ts_data *ts_data;
struct upgrade_module *module_info;
struct upgrade_func *func;
int module_id;
bool fw_from_request;
u8 *fw;
u32 fw_length;
u8 *lic;
u32 lic_length;
};
/*****************************************************************************
* Global variable or extern global variabls/functions
*****************************************************************************/
int fts_check_bootid(void);
int fts_fw_write_start(const u8 *buf, u32 len, bool need_reset);
/*****************************************************************************
* Static function prototypes
*****************************************************************************/
#endif

View file

@ -1,364 +0,0 @@
/*
*
* FocalTech fts TouchScreen driver.
*
* Copyright (c) 2012-2019, Focaltech Ltd. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/*****************************************************************************
*
* File Name: focaltech_flash.c
*
* Author: Focaltech Driver Team
*
* Created: 2017-12-06
*
* Abstract:
*
* Reference:
*
*****************************************************************************/
/*****************************************************************************
* 1.Included header files
*****************************************************************************/
#include "focaltech_core.h"
#include "focaltech_flash.h"
/*****************************************************************************
* Static variables
*****************************************************************************/
#define FTS_READ_BOOT_ID_TIMEOUT 3
#define FTS_FLASH_PACKET_LENGTH_SPI_LOW (4 * 1024 - 4)
#define FTS_FLASH_PACKET_LENGTH_SPI (64 * 1024)
/*****************************************************************************
* Global variable or extern global variabls/functions
*****************************************************************************/
static int fts_fwupg_hardware_reset_to_boot(void)
{
fts_reset_proc(0);
mdelay(8);
return 0;
}
static int fts_enter_into_boot(void)
{
int ret = 0;
int i = 0;
int j = 0;
u8 cmd = 0;
FTS_INFO("enter into boot environment");
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
/* hardware tp reset to boot */
fts_fwupg_hardware_reset_to_boot();
/* enter into boot & check boot id*/
for (j = 0; j < FTS_READ_BOOT_ID_TIMEOUT; j++) {
cmd = FTS_CMD_START1;
ret = fts_write(&cmd, 1);
if (ret >= 0) {
mdelay(8);
ret = fts_check_bootid();
if (0 == ret) {
FTS_INFO("boot id check pass, retry=%d", i);
return 0;
}
}
}
}
return -EIO;
}
static bool fts_check_fast_download(void)
{
int ret = 0;
u8 cmd[6] = {0xF2, 0x00, 0x78, 0x0A, 0x00, 0x02};
u8 value = 0;
u8 value2[2] = { 0 };
ret = fts_read_reg(0xdb, &value);
if (ret < 0) {
FTS_ERROR("read 0xdb fail");
goto read_err;
}
ret = fts_read(cmd, 6, value2, 2);
if (ret < 0) {
FTS_ERROR("read f2 fail");
goto read_err;
}
FTS_INFO("0xdb = 0x%x, 0xF2 = 0x%x", value, value2[0]);
if ((value >= 0x18) && (value2[0] == 0x55)) {
FTS_INFO("IC support fast-download");
return true;
}
read_err:
FTS_INFO("IC not support fast-download");
return false;
}
static int fts_pram_write(u32 saddr, const u8 *buf, u32 len)
{
int ret = 0;
int i = 0;
int j = 0;
u8 *cmd;
u32 addr = 0;
u32 offset = 0;
u32 remainder = 0;
u32 packet_number;
u32 packet_len = 0;
u32 packet_size = FTS_FLASH_PACKET_LENGTH_SPI;
bool fd_support = true;
FTS_INFO("pram write");
if (NULL == buf) {
FTS_ERROR("fw buf is null");
return -EINVAL;
}
if ((len < FTS_MIN_LEN) || (len > FTS_MAX_LEN_APP)) {
FTS_ERROR("fw length(%d) fail", len);
return -EINVAL;
}
fd_support = fts_check_fast_download();
if (!fd_support)
packet_size = FTS_FLASH_PACKET_LENGTH_SPI_LOW;
cmd = kzalloc(packet_size + FTS_CMD_WRITE_LEN, GFP_KERNEL);
if (NULL == cmd) {
FTS_ERROR("malloc memory for pram write buffer fail");
return -ENOMEM;
}
packet_number = len / packet_size;
remainder = len % packet_size;
if (remainder > 0)
packet_number++;
packet_len = packet_size;
cmd[0] = FTS_ROMBOOT_CMD_WRITE;
for (i = 0; i < packet_number; i++) {
offset = i * packet_size;
addr = saddr + offset;
cmd[1] = BYTE_OFF_16(addr);
cmd[2] = BYTE_OFF_8(addr);
cmd[3] = BYTE_OFF_0(addr);
/* last packet */
if ((i == (packet_number - 1)) && remainder)
packet_len = remainder;
cmd[4] = BYTE_OFF_8(packet_len);
cmd[5] = BYTE_OFF_0(packet_len);
for (j = 0; j < packet_len; j++) {
cmd[FTS_CMD_WRITE_LEN + j] = buf[offset + j];
}
ret = fts_write(&cmd[0], FTS_CMD_WRITE_LEN + packet_len);
if (ret < 0) {
FTS_ERROR("write fw to pram(%d) fail", i);
goto write_pram_err;
}
if (!fd_support)
mdelay(3);
}
write_pram_err:
if (cmd) {
kfree(cmd);
cmd = NULL;
}
return ret;
}
static int fts_ecc_cal_tp(u32 ecc_saddr, u32 ecc_len, u16 *ecc_value)
{
int ret = 0;
int i = 0;
u8 cmd[FTS_ROMBOOT_CMD_ECC_NEW_LEN] = { 0 };
u8 value[2] = { 0 };
FTS_INFO("ecc calc in tp");
cmd[0] = FTS_ROMBOOT_CMD_ECC;
cmd[1] = BYTE_OFF_16(ecc_saddr);
cmd[2] = BYTE_OFF_8(ecc_saddr);
cmd[3] = BYTE_OFF_0(ecc_saddr);
cmd[4] = BYTE_OFF_16(ecc_len);
cmd[5] = BYTE_OFF_8(ecc_len);
cmd[6] = BYTE_OFF_0(ecc_len);
/* make boot to calculate ecc in pram */
ret = fts_write(cmd, FTS_ROMBOOT_CMD_ECC_NEW_LEN);
if (ret < 0) {
FTS_ERROR("ecc calc cmd fail");
return ret;
}
mdelay(3);
/* wait boot calculate ecc finish */
cmd[0] = FTS_ROMBOOT_CMD_ECC_FINISH;
for (i = 0; i < FTS_ECC_FINISH_TIMEOUT; i++) {
ret = fts_read(cmd, 1, value, 1);
if (ret < 0) {
FTS_ERROR("ecc finish cmd fail");
return ret;
}
if (0 == value[0])
break;
mdelay(1);
}
if (i >= FTS_ECC_FINISH_TIMEOUT) {
FTS_ERROR("wait ecc finish timeout");
return -EIO;
}
/* get ecc value calculate in boot */
cmd[0] = FTS_ROMBOOT_CMD_ECC_READ;
ret = fts_read(cmd, 1, value, 2);
if (ret < 0) {
FTS_ERROR("ecc read cmd fail");
return ret;
}
*ecc_value = ((u16)(value[0] << 8) + value[1]) & 0x0000FFFF;
return 0;
}
static int fts_ecc_cal_host(const u8 *data, u32 data_len, u16 *ecc_value)
{
u16 ecc = 0;
u16 i = 0;
u16 j = 0;
u16 al2_fcs_coef = AL2_FCS_COEF;
for (i = 0; i < data_len; i += 2 ) {
ecc ^= ((data[i] << 8) | (data[i + 1]));
for (j = 0; j < 16; j ++) {
if (ecc & 0x01)
ecc = (u16)((ecc >> 1) ^ al2_fcs_coef);
else
ecc >>= 1;
}
}
*ecc_value = ecc & 0x0000FFFF;
return 0;
}
static int fts_pram_start(void)
{
int ret = 0;
u8 cmd = FTS_ROMBOOT_CMD_START_APP;
FTS_INFO("remap to start pram");
ret = fts_write(&cmd, 1);
if (ret < 0) {
FTS_ERROR("write start pram cmd fail");
return ret;
}
return 0;
}
/*
* description: download fw to IC and run
*
* param - buf: const, fw data buffer
* len: length of fw
*
* return 0 if success, otherwise return error code
*/
int fts_fw_write_start(const u8 *buf, u32 len, bool need_reset)
{
int ret = 0;
u16 ecc_in_host = 0;
u16 ecc_in_tp = 0;
u32 fw_start_addr = 0;
u32 fw_len = 0;
u16 code_len = 0;
u16 code_len_n = 0;
FTS_INFO("begin to write and start fw(bin len:%d)", len);
/* get app length */
code_len = ((u16)buf[FTS_APP_INFO_OFFSET + 0] << 8)
+ buf[FTS_APP_INFO_OFFSET + 1];
code_len_n = ((u16)buf[FTS_APP_INFO_OFFSET + 2] << 8)
+ buf[FTS_APP_INFO_OFFSET + 3];
if ((code_len + code_len_n) != 0xFFFF) {
FTS_ERROR("code len(%x %x) fail", code_len, code_len_n);
return -EINVAL;
}
fw_len = (u32)code_len;
if ((fw_len < FTS_MIN_LEN) || (fw_len > FTS_MAX_LEN_APP)) {
FTS_ERROR("fw length(%d) is invalid", fw_len);
return -EINVAL;
}
FTS_INFO("fw length in fact:%d", fw_len);
fts_data->fw_is_running = false;
if (need_reset) {
/* enter into boot environment */
ret = fts_enter_into_boot();
if (ret < 0) {
FTS_ERROR("enter into boot environment fail");
return ret;
}
}
/* write pram */
ret = fts_pram_write(fw_start_addr, buf, fw_len);
if (ret < 0) {
FTS_ERROR("write pram fail");
return ret;
}
/* ecc check */
ret = fts_ecc_cal_host(buf, fw_len, &ecc_in_host);
if (ret < 0) {
FTS_ERROR("ecc in host calc fail");
return ret;
}
ret = fts_ecc_cal_tp(fw_start_addr, fw_len, &ecc_in_tp);
if (ret < 0) {
FTS_ERROR("ecc in tp calc fail");
return ret;
}
FTS_INFO("ecc in tp:%04x host:%04x", ecc_in_tp, ecc_in_host);
if (ecc_in_tp != ecc_in_host) {
FTS_ERROR("ecc check fail");
return -EIO;
}
/* remap pram and run fw */
ret = fts_pram_start();
if (ret < 0) {
FTS_ERROR("pram start fail");
return ret;
}
fts_data->fw_is_running = true;
FTS_INFO("fw download successfully");
return 0;
}

View file

@ -1,448 +0,0 @@
/*
*
* FocalTech fts TouchScreen driver.
*
* Copyright (c) 2012-2019, Focaltech Ltd. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/*****************************************************************************
*
* File Name: focaltech_flash.c
*
* Author: Focaltech Driver Team
*
* Created: 2017-12-06
*
* Abstract:
*
* Reference:
*
*****************************************************************************/
/*****************************************************************************
* 1.Included header files
*****************************************************************************/
#include "focaltech_core.h"
#include "focaltech_flash.h"
/*****************************************************************************
* Static variables
*****************************************************************************/
#define FTS_READ_BOOT_ID_TIMEOUT 3
#define FTS_FLASH_PACKET_LENGTH_SPI (32 * 1024 - 16)
#define FTS_CMD_ECC_LENGTH_MAX 32766
#define FTS_ROMBOOT_CMD_ECC_FINISH_OK 0xA5
/*****************************************************************************
* Global variable or extern global variabls/functions
*****************************************************************************/
static int fts_fwupg_hardware_reset_to_boot(void)
{
fts_reset_proc(0);
mdelay(8);
return 0;
}
static int fts_enter_into_boot(void)
{
int ret = 0;
int i = 0;
int j = 0;
u8 cmd[2] = { 0 };
FTS_INFO("enter into boot environment");
for (i = 0; i < FTS_UPGRADE_LOOP; i++) {
/* hardware tp reset to boot */
fts_fwupg_hardware_reset_to_boot();
/* enter into boot & check boot id*/
for (j = 0; j < FTS_READ_BOOT_ID_TIMEOUT; j++) {
cmd[0] = FTS_CMD_START1;
ret = fts_write(cmd, 1);
if (ret >= 0) {
mdelay(8);
ret = fts_check_bootid();
if (0 == ret) {
FTS_INFO("boot id check pass, retry=%d", i);
return 0;
}
}
}
}
return -EIO;
}
static int fts_dpram_write(u32 saddr, const u8 *buf, u32 len, bool wpram)
{
int ret = 0;
int i = 0;
int j = 0;
u8 *cmd = NULL;
u32 addr = 0;
u32 baseaddr = wpram ? FTS_PRAM_SADDR : FTS_DRAM_SADDR;
u32 offset = 0;
u32 remainder = 0;
u32 packet_number = 0;
u32 packet_len = 0;
u32 packet_size = FTS_FLASH_PACKET_LENGTH_SPI;
FTS_INFO("dpram write");
if (NULL == buf) {
FTS_ERROR("fw buf is null");
return -EINVAL;
}
if ((len < FTS_MIN_LEN) || (len > FTS_MAX_LEN_APP)) {
FTS_ERROR("fw length(%d) fail", len);
return -EINVAL;
}
cmd = vmalloc(packet_size + FTS_CMD_WRITE_LEN);
if (NULL == cmd) {
FTS_ERROR("malloc memory for pram write buffer fail");
return -ENOMEM;
}
memset(cmd, 0, packet_size + FTS_CMD_WRITE_LEN);
packet_number = len / packet_size;
remainder = len % packet_size;
if (remainder > 0)
packet_number++;
packet_len = packet_size;
FTS_INFO("write data, num:%d remainder:%d", packet_number, remainder);
for (i = 0; i < packet_number; i++) {
offset = i * packet_size;
addr = saddr + offset + baseaddr;
/* last packet */
if ((i == (packet_number - 1)) && remainder)
packet_len = remainder;
/* set pram address */
cmd[0] = FTS_ROMBOOT_CMD_SET_PRAM_ADDR;
cmd[1] = BYTE_OFF_16(addr);
cmd[2] = BYTE_OFF_8(addr);
cmd[3] = BYTE_OFF_0(addr);
ret = fts_write(&cmd[0], FTS_ROMBOOT_CMD_SET_PRAM_ADDR_LEN);
if (ret < 0) {
FTS_ERROR("set pram(%d) addr(%d) fail", i, addr);
goto write_pram_err;
}
/* write pram data */
cmd[0] = FTS_ROMBOOT_CMD_WRITE;
for (j = 0; j < packet_len; j++) {
cmd[1 + j] = buf[offset + j];
}
ret = fts_write(&cmd[0], 1 + packet_len);
if (ret < 0) {
FTS_ERROR("write fw to pram(%d) fail", i);
goto write_pram_err;
}
}
write_pram_err:
if (cmd) {
vfree(cmd);
cmd = NULL;
}
return ret;
}
static int fts_ecc_cal_tp(u32 ecc_saddr, u32 ecc_len, u16 *ecc_value)
{
int ret = 0;
int i = 0;
u8 cmd[FTS_ROMBOOT_CMD_ECC_NEW_LEN] = { 0 };
u8 value[2] = { 0 };
FTS_INFO("ecc calc in tp");
cmd[0] = FTS_ROMBOOT_CMD_ECC;
cmd[1] = BYTE_OFF_16(ecc_saddr);
cmd[2] = BYTE_OFF_8(ecc_saddr);
cmd[3] = BYTE_OFF_0(ecc_saddr);
cmd[4] = BYTE_OFF_16(ecc_len);
cmd[5] = BYTE_OFF_8(ecc_len);
cmd[6] = BYTE_OFF_0(ecc_len);
/* make boot to calculate ecc in pram */
ret = fts_write(cmd, FTS_ROMBOOT_CMD_ECC_NEW_LEN);
if (ret < 0) {
FTS_ERROR("ecc calc cmd fail");
return ret;
}
mdelay(2);
/* wait boot calculate ecc finish */
cmd[0] = FTS_ROMBOOT_CMD_ECC_FINISH;
for (i = 0; i < FTS_ECC_FINISH_TIMEOUT; i++) {
ret = fts_read(cmd, 1, value, 1);
if (ret < 0) {
FTS_ERROR("ecc finish cmd fail");
return ret;
}
if (FTS_ROMBOOT_CMD_ECC_FINISH_OK == value[0])
break;
mdelay(1);
}
if (i >= FTS_ECC_FINISH_TIMEOUT) {
FTS_ERROR("wait ecc finish timeout,ecc_finish=%x", value[0]);
return -EIO;
}
/* get ecc value calculate in boot */
cmd[0] = FTS_ROMBOOT_CMD_ECC_READ;
ret = fts_read(cmd, 1, value, 2);
if (ret < 0) {
FTS_ERROR("ecc read cmd fail");
return ret;
}
*ecc_value = ((u16)(value[0] << 8) + value[1]) & 0x0000FFFF;
return 0;
}
static int fts_ecc_cal_host(const u8 *data, u32 data_len, u16 *ecc_value)
{
u16 ecc = 0;
u16 i = 0;
u16 j = 0;
u16 al2_fcs_coef = AL2_FCS_COEF;
for (i = 0; i < data_len; i += 2 ) {
ecc ^= ((data[i] << 8) | (data[i + 1]));
for (j = 0; j < 16; j ++) {
if (ecc & 0x01)
ecc = (u16)((ecc >> 1) ^ al2_fcs_coef);
else
ecc >>= 1;
}
}
*ecc_value = ecc & 0x0000FFFF;
return 0;
}
static int fts_ecc_check(const u8 *buf, u32 len, u32 ecc_saddr)
{
int ret = 0;
int i = 0;
u16 ecc_in_host = 0;
u16 ecc_in_tp = 0;
int packet_length = 0;
int packet_number = 0;
int packet_remainder = 0;
int offset = 0;
u32 packet_size = FTS_CMD_ECC_LENGTH_MAX;
packet_number = len / packet_size;
packet_remainder = len % packet_size;
if (packet_remainder)
packet_number++;
packet_length = packet_size;
for (i = 0; i < packet_number; i++) {
/* last packet */
if ((i == (packet_number - 1)) && packet_remainder)
packet_length = packet_remainder;
ret = fts_ecc_cal_host(buf + offset, packet_length, &ecc_in_host);
if (ret < 0) {
FTS_ERROR("ecc in host calc fail");
return ret;
}
ret = fts_ecc_cal_tp(ecc_saddr + offset, packet_length, &ecc_in_tp);
if (ret < 0) {
FTS_ERROR("ecc in tp calc fail");
return ret;
}
FTS_DEBUG("ecc in tp:%04x,host:%04x,i:%d", ecc_in_tp, ecc_in_host, i);
if (ecc_in_tp != ecc_in_host) {
FTS_ERROR("ecc_in_tp(%x) != ecc_in_host(%x), ecc check fail",
ecc_in_tp, ecc_in_host);
return -EIO;
}
offset += packet_length;
}
return 0;
}
static int fts_pram_write_ecc(const u8 *buf, u32 len)
{
int ret = 0;
u32 pram_app_size = 0;
u16 code_len = 0;
u16 code_len_n = 0;
u32 pram_start_addr = 0;
FTS_INFO("begin to write pram app(bin len:%d)", len);
/* get pram app length */
code_len = ((u16)buf[FTS_APP_INFO_OFFSET + 0] << 8)
+ buf[FTS_APP_INFO_OFFSET + 1];
code_len_n = ((u16)buf[FTS_APP_INFO_OFFSET + 2] << 8)
+ buf[FTS_APP_INFO_OFFSET + 3];
if ((code_len + code_len_n) != 0xFFFF) {
FTS_ERROR("pram code len(%x %x) fail", code_len, code_len_n);
return -EINVAL;
}
pram_app_size = (u32)code_len;
pram_app_size = pram_app_size * 2;
if ((pram_app_size < FTS_MIN_LEN) || (pram_app_size > FTS_MAX_LEN_APP)) {
FTS_ERROR("pram app length(%d) is invalid", pram_app_size);
return -EINVAL;
}
FTS_INFO("pram app length in fact:%d", pram_app_size);
/* write pram */
ret = fts_dpram_write(pram_start_addr, buf, pram_app_size, true);
if (ret < 0) {
FTS_ERROR("write pram fail");
return ret;
}
/* check ecc */
ret = fts_ecc_check(buf, pram_app_size, pram_start_addr);
if (ret < 0) {
FTS_ERROR("pram ecc check fail");
return ret;
}
FTS_INFO("pram app write successfully");
return 0;
}
static int fts_dram_write_ecc(const u8 *buf, u32 len)
{
int ret = 0;
u32 dram_size = 0;
u32 pram_app_size = 0;
u32 dram_start_addr = 0;
u16 const_len = 0;
u16 const_len_n = 0;
const u8 *dram_buf = NULL;
FTS_INFO("begin to write dram data(bin len:%d)", len);
/* get dram data length */
const_len = ((u16)buf[FTS_APP_INFO_OFFSET + 0x8] << 8)
+ buf[FTS_APP_INFO_OFFSET + 0x9];
const_len_n = ((u16)buf[FTS_APP_INFO_OFFSET + 0x0A] << 8)
+ buf[FTS_APP_INFO_OFFSET + 0x0B];
if (((const_len + const_len_n) != 0xFFFF) || (const_len == 0)) {
FTS_INFO("no support dram,const len(%x %x)", const_len, const_len_n);
return 0;
}
dram_size = ((u32)const_len) * 2;
if ((dram_size <= 0) || (dram_size > FTS_MAX_LEN_APP_PARAMS)) {
FTS_ERROR("dram data length(%d) is invalid", dram_size);
return -EINVAL;
}
pram_app_size = ((u32)(((u16)buf[FTS_APP_INFO_OFFSET + 0] << 8)
+ buf[FTS_APP_INFO_OFFSET + 1])) * 2;
dram_buf = buf + pram_app_size;
FTS_INFO("dram buf length in fact:%d,offset:%d", dram_size, pram_app_size);
/* write pram */
ret = fts_dpram_write(dram_start_addr, dram_buf, dram_size, false);
if (ret < 0) {
FTS_ERROR("write dram fail");
return ret;
}
/* check ecc */
ret = fts_ecc_check(dram_buf, dram_size, dram_start_addr);
if (ret < 0) {
FTS_ERROR("dram ecc check fail");
return ret;
}
FTS_INFO("dram data write successfully");
return 0;
}
static int fts_pram_start(void)
{
int ret = 0;
u8 cmd = FTS_ROMBOOT_CMD_START_APP;
FTS_INFO("remap to start pram");
ret = fts_write(&cmd, 1);
if (ret < 0) {
FTS_ERROR("write start pram cmd fail");
return ret;
}
return 0;
}
/*
* description: download fw to IC and run
*
* param - buf: const, fw data buffer
* len: length of fw
*
* return 0 if success, otherwise return error code
*/
int fts_fw_write_start(const u8 *buf, u32 len, bool need_reset)
{
int ret = 0;
FTS_INFO("begin to write and start fw(bin len:%d)", len);
fts_data->fw_is_running = false;
if (need_reset) {
/* enter into boot environment */
ret = fts_enter_into_boot();
if (ret < 0) {
FTS_ERROR("enter into boot environment fail");
return ret;
}
}
/* write pram */
ret = fts_pram_write_ecc(buf, len);
if (ret < 0) {
FTS_ERROR("write pram fail");
return ret;
}
/* write dram */
ret = fts_dram_write_ecc(buf, len);
if (ret < 0) {
FTS_ERROR("write dram fail");
return ret;
}
/* remap pram and run fw */
ret = fts_pram_start();
if (ret < 0) {
FTS_ERROR("pram start fail");
return ret;
}
fts_data->fw_is_running = true;
FTS_INFO("fw download successfully");
return 0;
}

View file

@ -1,486 +0,0 @@
/*
*
* FocalTech TouchScreen driver.
*
* Copyright (c) 2012-2019, Focaltech Ltd. All rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/*****************************************************************************
*
* File Name: focaltech_gestrue.c
*
* Author: Focaltech Driver Team
*
* Created: 2016-08-08
*
* Abstract:
*
* Reference:
*
*****************************************************************************/
/*****************************************************************************
* 1.Included header files
*****************************************************************************/
#include "focaltech_core.h"
#if FTS_GESTURE_EN
/******************************************************************************
* Private constant and macro definitions using #define
*****************************************************************************/
#define KEY_GESTURE_U KEY_U
#define KEY_GESTURE_UP KEY_UP
#define KEY_GESTURE_DOWN KEY_DOWN
#define KEY_GESTURE_LEFT KEY_LEFT
#define KEY_GESTURE_RIGHT KEY_RIGHT
#define KEY_GESTURE_O KEY_O
#define KEY_GESTURE_E KEY_E
#define KEY_GESTURE_M KEY_M
#define KEY_GESTURE_L KEY_L
#define KEY_GESTURE_W KEY_W
#define KEY_GESTURE_S KEY_S
#define KEY_GESTURE_V KEY_V
#define KEY_GESTURE_C KEY_C
#define KEY_GESTURE_Z KEY_Z
#define GESTURE_LEFT 0x20
#define GESTURE_RIGHT 0x21
#define GESTURE_UP 0x22
#define GESTURE_DOWN 0x23
#define GESTURE_DOUBLECLICK 0x24
#define GESTURE_O 0x30
#define GESTURE_W 0x31
#define GESTURE_M 0x32
#define GESTURE_E 0x33
#define GESTURE_L 0x44
#define GESTURE_S 0x46
#define GESTURE_V 0x54
#define GESTURE_Z 0x41
#define GESTURE_C 0x34
/*****************************************************************************
* Private enumerations, structures and unions using typedef
*****************************************************************************/
/*
* gesture_id - mean which gesture is recognised
* point_num - points number of this gesture
* coordinate_x - All gesture point x coordinate
* coordinate_y - All gesture point y coordinate
* mode - gesture enable/disable, need enable by host
* - 1:enable gesture function(default) 0:disable
* active - gesture work flag,
* always set 1 when suspend, set 0 when resume
*/
struct fts_gesture_st {
u8 gesture_id;
u8 point_num;
u16 coordinate_x[FTS_GESTURE_POINTS_MAX];
u16 coordinate_y[FTS_GESTURE_POINTS_MAX];
u8 mode;
u8 active;
};
/*****************************************************************************
* Static variables
*****************************************************************************/
static struct fts_gesture_st fts_gesture_data;
/*****************************************************************************
* Global variable or extern global variabls/functions
*****************************************************************************/
/*****************************************************************************
* Static function prototypes
*****************************************************************************/
static ssize_t fts_gesture_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
int count = 0;
u8 val = 0;
struct input_dev *input_dev = fts_data->input_dev;
mutex_lock(&input_dev->mutex);
fts_read_reg(FTS_REG_GESTURE_EN, &val);
count = snprintf(buf, PAGE_SIZE, "Gesture Mode:%s\n",
fts_gesture_data.mode ? "On" : "Off");
count += snprintf(buf + count, PAGE_SIZE, "Reg(0xD0)=%d\n", val);
mutex_unlock(&input_dev->mutex);
return count;
}
static ssize_t fts_gesture_store(
struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct input_dev *input_dev = fts_data->input_dev;
mutex_lock(&input_dev->mutex);
if (FTS_SYSFS_ECHO_ON(buf)) {
FTS_DEBUG("enable gesture");
fts_gesture_data.mode = ENABLE;
} else if (FTS_SYSFS_ECHO_OFF(buf)) {
FTS_DEBUG("disable gesture");
fts_gesture_data.mode = DISABLE;
}
mutex_unlock(&input_dev->mutex);
return count;
}
static ssize_t fts_gesture_buf_show(
struct device *dev, struct device_attribute *attr, char *buf)
{
int count = 0;
int i = 0;
struct input_dev *input_dev = fts_data->input_dev;
struct fts_gesture_st *gesture = &fts_gesture_data;
mutex_lock(&input_dev->mutex);
count = snprintf(buf, PAGE_SIZE, "Gesture ID:%d\n", gesture->gesture_id);
count += snprintf(buf + count, PAGE_SIZE, "Gesture PointNum:%d\n",
gesture->point_num);
count += snprintf(buf + count, PAGE_SIZE, "Gesture Points Buffer:\n");
/* save point data,max:6 */
for (i = 0; i < FTS_GESTURE_POINTS_MAX; i++) {
count += snprintf(buf + count, PAGE_SIZE, "%3d(%4d,%4d) ", i,
gesture->coordinate_x[i], gesture->coordinate_y[i]);
if ((i + 1) % 4 == 0)
count += snprintf(buf + count, PAGE_SIZE, "\n");
}
count += snprintf(buf + count, PAGE_SIZE, "\n");
mutex_unlock(&input_dev->mutex);
return count;
}
static ssize_t fts_gesture_buf_store(
struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
return -EPERM;
}
/* sysfs gesture node
* read example: cat fts_gesture_mode ---read gesture mode
* write example:echo 1 > fts_gesture_mode --- write gesture mode to 1
*
*/
static DEVICE_ATTR(fts_gesture_mode, S_IRUGO | S_IWUSR, fts_gesture_show,
fts_gesture_store);
/*
* read example: cat fts_gesture_buf --- read gesture buf
*/
static DEVICE_ATTR(fts_gesture_buf, S_IRUGO | S_IWUSR,
fts_gesture_buf_show, fts_gesture_buf_store);
static struct attribute *fts_gesture_mode_attrs[] = {
&dev_attr_fts_gesture_mode.attr,
&dev_attr_fts_gesture_buf.attr,
NULL,
};
static struct attribute_group fts_gesture_group = {
.attrs = fts_gesture_mode_attrs,
};
int fts_create_gesture_sysfs(struct device *dev)
{
int ret = 0;
ret = sysfs_create_group(&dev->kobj, &fts_gesture_group);
if (ret) {
FTS_ERROR("gesture sys node create fail");
sysfs_remove_group(&dev->kobj, &fts_gesture_group);
return ret;
}
return 0;
}
static void fts_gesture_report(struct input_dev *input_dev, int gesture_id)
{
int gesture;
FTS_DEBUG("gesture_id:0x%x", gesture_id);
switch (gesture_id) {
case GESTURE_LEFT:
gesture = KEY_GESTURE_LEFT;
break;
case GESTURE_RIGHT:
gesture = KEY_GESTURE_RIGHT;
break;
case GESTURE_UP:
gesture = KEY_GESTURE_UP;
break;
case GESTURE_DOWN:
gesture = KEY_GESTURE_DOWN;
break;
case GESTURE_DOUBLECLICK:
gesture = KEY_GESTURE_U;
break;
case GESTURE_O:
gesture = KEY_GESTURE_O;
break;
case GESTURE_W:
gesture = KEY_GESTURE_W;
break;
case GESTURE_M:
gesture = KEY_GESTURE_M;
break;
case GESTURE_E:
gesture = KEY_GESTURE_E;
break;
case GESTURE_L:
gesture = KEY_GESTURE_L;
break;
case GESTURE_S:
gesture = KEY_GESTURE_S;
break;
case GESTURE_V:
gesture = KEY_GESTURE_V;
break;
case GESTURE_Z:
gesture = KEY_GESTURE_Z;
break;
case GESTURE_C:
gesture = KEY_GESTURE_C;
break;
default:
gesture = -1;
break;
}
/* report event key */
if (gesture != -1) {
FTS_DEBUG("Gesture Code=%d", gesture);
input_report_key(input_dev, gesture, 1);
input_sync(input_dev);
input_report_key(input_dev, gesture, 0);
input_sync(input_dev);
}
}
/*****************************************************************************
* Name: fts_gesture_readdata
* Brief: Read information about gesture: enable flag/gesture points..., if ges-
* ture enable, save gesture points' information, and report to OS.
* It will be called this function every intrrupt when FTS_GESTURE_EN = 1
*
* gesture data length: 1(enable) + 1(reserve) + 2(header) + 6 * 4
* Input: ts_data - global struct data
* data - gesture data buffer if non-flash, else NULL
* Output:
* Return: 0 - read gesture data successfully, the report data is gesture data
* 1 - tp not in suspend/gesture not enable in TP FW
* -Exx - error
*****************************************************************************/
int fts_gesture_readdata(struct fts_ts_data *ts_data, u8 *data)
{
int ret = 0;
int i = 0;
int index = 0;
u8 buf[FTS_GESTURE_DATA_LEN] = { 0 };
struct input_dev *input_dev = ts_data->input_dev;
struct fts_gesture_st *gesture = &fts_gesture_data;
if (!ts_data->suspended || (DISABLE == gesture->mode)) {
return 1;
}
if (!data) {
FTS_ERROR("gesture data buffer is null");
ret = -EINVAL;
return ret;
}
memcpy(buf, data, FTS_GESTURE_DATA_LEN);
if (buf[0] != ENABLE) {
FTS_DEBUG("gesture not enable in fw, don't process gesture");
return 1;
}
/* init variable before read gesture point */
memset(gesture->coordinate_x, 0, FTS_GESTURE_POINTS_MAX * sizeof(u16));
memset(gesture->coordinate_y, 0, FTS_GESTURE_POINTS_MAX * sizeof(u16));
gesture->gesture_id = buf[2];
gesture->point_num = buf[3];
FTS_DEBUG("gesture_id=%d, point_num=%d",
gesture->gesture_id, gesture->point_num);
/* save point data,max:6 */
for (i = 0; i < FTS_GESTURE_POINTS_MAX; i++) {
index = 4 * i + 4;
gesture->coordinate_x[i] = (u16)(((buf[0 + index] & 0x0F) << 8)
+ buf[1 + index]);
gesture->coordinate_y[i] = (u16)(((buf[2 + index] & 0x0F) << 8)
+ buf[3 + index]);
}
/* report gesture to OS */
fts_gesture_report(input_dev, gesture->gesture_id);
return 0;
}
void fts_gesture_recovery(struct fts_ts_data *ts_data)
{
if ((ENABLE == fts_gesture_data.mode) && (ENABLE == fts_gesture_data.active)) {
FTS_DEBUG("gesture recovery...");
fts_write_reg(0xD1, 0xFF);
fts_write_reg(0xD2, 0xFF);
fts_write_reg(0xD5, 0xFF);
fts_write_reg(0xD6, 0xFF);
fts_write_reg(0xD7, 0xFF);
fts_write_reg(0xD8, 0xFF);
fts_write_reg(FTS_REG_GESTURE_EN, ENABLE);
}
}
int fts_gesture_suspend(struct fts_ts_data *ts_data)
{
int ret = 0;
int i = 0;
u8 state = 0xFF;
FTS_INFO("gesture suspend...");
/* gesture not enable, return immediately */
if (fts_gesture_data.mode == DISABLE) {
FTS_DEBUG("gesture is disabled");
return -EINVAL;
}
for (i = 0; i < 5; i++) {
fts_write_reg(0xD1, 0xFF);
fts_write_reg(0xD2, 0xFF);
fts_write_reg(0xD5, 0xFF);
fts_write_reg(0xD6, 0xFF);
fts_write_reg(0xD7, 0xFF);
fts_write_reg(0xD8, 0xFF);
fts_write_reg(FTS_REG_GESTURE_EN, ENABLE);
msleep(1);
fts_read_reg(FTS_REG_GESTURE_EN, &state);
if (state == ENABLE)
break;
}
if (i >= 5) {
FTS_ERROR("Enter into gesture(suspend) fail");
fts_gesture_data.active = DISABLE;
return -EIO;
}
ret = enable_irq_wake(ts_data->irq);
if (ret) {
FTS_DEBUG("enable_irq_wake(irq:%d) fail", ts_data->irq);
}
fts_gesture_data.active = ENABLE;
FTS_INFO("Enter into gesture(suspend) successfully!");
return 0;
}
int fts_gesture_resume(struct fts_ts_data *ts_data)
{
int ret = 0;
int i = 0;
u8 state = 0xFF;
FTS_INFO("gesture resume...");
/* gesture not enable, return immediately */
if (fts_gesture_data.mode == DISABLE) {
FTS_DEBUG("gesture is disabled");
return -EINVAL;
}
if (fts_gesture_data.active == DISABLE) {
FTS_DEBUG("gesture active is disable, return immediately");
return -EINVAL;
}
fts_gesture_data.active = DISABLE;
for (i = 0; i < 5; i++) {
fts_write_reg(FTS_REG_GESTURE_EN, DISABLE);
msleep(1);
fts_read_reg(FTS_REG_GESTURE_EN, &state);
if (state == DISABLE)
break;
}
if (i >= 5) {
FTS_ERROR("exit gesture(resume) fail");
return -EIO;
}
ret = disable_irq_wake(ts_data->irq);
if (ret) {
FTS_DEBUG("disable_irq_wake(irq:%d) fail", ts_data->irq);
}
FTS_INFO("resume from gesture successfully");
return 0;
}
int fts_gesture_init(struct fts_ts_data *ts_data)
{
struct input_dev *input_dev = ts_data->input_dev;
FTS_FUNC_ENTER();
input_set_capability(input_dev, EV_KEY, KEY_POWER);
input_set_capability(input_dev, EV_KEY, KEY_GESTURE_U);
input_set_capability(input_dev, EV_KEY, KEY_GESTURE_UP);
input_set_capability(input_dev, EV_KEY, KEY_GESTURE_DOWN);
input_set_capability(input_dev, EV_KEY, KEY_GESTURE_LEFT);
input_set_capability(input_dev, EV_KEY, KEY_GESTURE_RIGHT);
input_set_capability(input_dev, EV_KEY, KEY_GESTURE_O);
input_set_capability(input_dev, EV_KEY, KEY_GESTURE_E);
input_set_capability(input_dev, EV_KEY, KEY_GESTURE_M);
input_set_capability(input_dev, EV_KEY, KEY_GESTURE_L);
input_set_capability(input_dev, EV_KEY, KEY_GESTURE_W);
input_set_capability(input_dev, EV_KEY, KEY_GESTURE_S);
input_set_capability(input_dev, EV_KEY, KEY_GESTURE_V);
input_set_capability(input_dev, EV_KEY, KEY_GESTURE_Z);
input_set_capability(input_dev, EV_KEY, KEY_GESTURE_C);
__set_bit(KEY_GESTURE_RIGHT, input_dev->keybit);
__set_bit(KEY_GESTURE_LEFT, input_dev->keybit);
__set_bit(KEY_GESTURE_UP, input_dev->keybit);
__set_bit(KEY_GESTURE_DOWN, input_dev->keybit);
__set_bit(KEY_GESTURE_U, input_dev->keybit);
__set_bit(KEY_GESTURE_O, input_dev->keybit);
__set_bit(KEY_GESTURE_E, input_dev->keybit);
__set_bit(KEY_GESTURE_M, input_dev->keybit);
__set_bit(KEY_GESTURE_W, input_dev->keybit);
__set_bit(KEY_GESTURE_L, input_dev->keybit);
__set_bit(KEY_GESTURE_S, input_dev->keybit);
__set_bit(KEY_GESTURE_V, input_dev->keybit);
__set_bit(KEY_GESTURE_C, input_dev->keybit);
__set_bit(KEY_GESTURE_Z, input_dev->keybit);
fts_create_gesture_sysfs(ts_data->dev);
memset(&fts_gesture_data, 0, sizeof(struct fts_gesture_st));
fts_gesture_data.mode = ENABLE;
fts_gesture_data.active = DISABLE;
FTS_FUNC_EXIT();
return 0;
}
int fts_gesture_exit(struct fts_ts_data *ts_data)
{
FTS_FUNC_ENTER();
sysfs_remove_group(&ts_data->dev->kobj, &fts_gesture_group);
FTS_FUNC_EXIT();
return 0;
}
#endif

View file

@ -1,135 +0,0 @@
/*
*
* FocalTech TouchScreen driver.
*
* Copyright (c) 2012-2019, FocalTech Systems, Ltd., all rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/*****************************************************************************
*
* File Name: focaltech_point_report_check.c
*
* Author: Focaltech Driver Team
*
* Created: 2016-11-16
*
* Abstract: point report check function
*
* Version: v1.0
*
* Revision History:
*
*****************************************************************************/
/*****************************************************************************
* Included header files
*****************************************************************************/
#include "focaltech_core.h"
#if FTS_POINT_REPORT_CHECK_EN
/*****************************************************************************
* Private constant and macro definitions using #define
*****************************************************************************/
#define POINT_REPORT_CHECK_WAIT_TIME 200 /* unit:ms */
/*****************************************************************************
* functions body
*****************************************************************************/
/*****************************************************************************
* Name: fts_prc_func
* Brief: fts point report check work func, report whole up of points
* Input:
* Output:
* Return:
*****************************************************************************/
static void fts_prc_func(struct work_struct *work)
{
struct fts_ts_data *ts_data = container_of(work,
struct fts_ts_data, prc_work.work);
struct input_dev *input_dev = ts_data->input_dev;
#if FTS_MT_PROTOCOL_B_EN
u32 finger_count = 0;
u32 max_touches = fts_data->pdata->max_touch_number;
#endif
FTS_FUNC_ENTER();
mutex_lock(&ts_data->report_mutex);
#if FTS_MT_PROTOCOL_B_EN
for (finger_count = 0; finger_count < max_touches; finger_count++) {
input_mt_slot(input_dev, finger_count);
input_mt_report_slot_state(input_dev, MT_TOOL_FINGER, false);
}
#else
input_mt_sync(input_dev);
#endif
input_report_key(input_dev, BTN_TOUCH, 0);
input_sync(input_dev);
mutex_unlock(&ts_data->report_mutex);
FTS_FUNC_EXIT();
}
/*****************************************************************************
* Name: fts_prc_queue_work
* Brief: fts point report check queue work, call it when interrupt comes
* Input:
* Output:
* Return:
*****************************************************************************/
void fts_prc_queue_work(struct fts_ts_data *ts_data)
{
cancel_delayed_work_sync(&ts_data->prc_work);
queue_delayed_work(ts_data->ts_workqueue, &ts_data->prc_work,
msecs_to_jiffies(POINT_REPORT_CHECK_WAIT_TIME));
}
/*****************************************************************************
* Name: fts_point_report_check_init
* Brief:
* Input:
* Output:
* Return: < 0: Fail to create esd check queue
*****************************************************************************/
int fts_point_report_check_init(struct fts_ts_data *ts_data)
{
FTS_FUNC_ENTER();
if (ts_data->ts_workqueue) {
INIT_DELAYED_WORK(&ts_data->prc_work, fts_prc_func);
} else {
FTS_ERROR("fts workqueue is NULL, can't run point report check function");
return -EINVAL;
}
FTS_FUNC_EXIT();
return 0;
}
/*****************************************************************************
* Name: fts_point_report_check_exit
* Brief:
* Input:
* Output:
* Return:
*****************************************************************************/
int fts_point_report_check_exit(struct fts_ts_data *ts_data)
{
FTS_FUNC_ENTER();
FTS_FUNC_EXIT();
return 0;
}
#endif /* FTS_POINT_REPORT_CHECK_EN */

View file

@ -1,338 +0,0 @@
/*
*
* FocalTech TouchScreen driver.
*
* Copyright (c) 2012-2019, FocalTech Systems, Ltd., all rights reserved.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*/
/************************************************************************
*
* File Name: focaltech_spi.c
*
* Author: FocalTech Driver Team
*
* Created: 2019-03-21
*
* Abstract: new spi protocol communication with TP
*
* Version: v1.0
*
* Revision History:
*
************************************************************************/
/*****************************************************************************
* Included header files
*****************************************************************************/
#include "focaltech_core.h"
/*****************************************************************************
* Private constant and macro definitions using #define
*****************************************************************************/
#define SPI_RETRY_NUMBER 3
#define CS_HIGH_DELAY 150 /* unit: us */
#define SPI_BUF_LENGTH 256
#define DATA_CRC_EN 0x20
#define WRITE_CMD 0x00
#define READ_CMD (0x80 | DATA_CRC_EN)
#define SPI_DUMMY_BYTE 3
#define SPI_HEADER_LENGTH (SPI_DUMMY_BYTE + 6)
/*****************************************************************************
* Private enumerations, structures and unions using typedef
*****************************************************************************/
/*****************************************************************************
* Static variables
*****************************************************************************/
/*****************************************************************************
* Global variable or extern global variabls/functions
*****************************************************************************/
/*****************************************************************************
* Static function prototypes
*****************************************************************************/
/*****************************************************************************
* functions body
*****************************************************************************/
/* spi interface */
static int fts_spi_transfer(u8 *tx_buf, u8 *rx_buf, u32 len)
{
int ret = 0;
struct spi_device *spi = fts_data->spi;
struct spi_message msg;
struct spi_transfer xfer = {
.tx_buf = tx_buf,
.rx_buf = rx_buf,
.len = len,
};
spi_message_init(&msg);
spi_message_add_tail(&xfer, &msg);
ret = spi_sync(spi, &msg);
if (ret) {
FTS_ERROR("spi_sync fail,ret:%d", ret);
return ret;
}
return ret;
}
static void crckermit(u8 *data, u16 len, u16 *crc_out)
{
u16 i = 0;
u16 j = 0;
u16 crc = 0xFFFF;
for ( i = 0; i < len; i++) {
crc ^= data[i];
for (j = 0; j < 8; j++) {
if (crc & 0x01)
crc = (crc >> 1) ^ 0x8408;
else
crc = (crc >> 1);
}
}
*crc_out = crc;
}
static int rdata_check(u8 *rdata, u32 rlen)
{
u16 crc_calc = 0;
u16 crc_read = 0;
crckermit(rdata, rlen - 2, &crc_calc);
crc_read = (u16)(rdata[rlen - 1] << 8) + rdata[rlen - 2];
if (crc_calc != crc_read) {
return -EIO;
}
return 0;
}
int fts_write(u8 *writebuf, u32 writelen)
{
int ret = 0;
int i = 0;
struct fts_ts_data *ts_data = fts_data;
u8 *txbuf = NULL;
u8 *rxbuf = NULL;
u32 txlen = 0;
u32 txlen_need = writelen + SPI_HEADER_LENGTH;
u32 datalen = writelen - 1;
if (!writebuf || !writelen) {
FTS_ERROR("writebuf/len is invalid");
return -EINVAL;
}
mutex_lock(&ts_data->bus_lock);
if (txlen_need > SPI_BUF_LENGTH) {
txbuf = kzalloc(txlen_need, GFP_KERNEL);
if (NULL == txbuf) {
FTS_ERROR("txbuf malloc fail");
ret = -ENOMEM;
goto err_write;
}
rxbuf = kzalloc(txlen_need, GFP_KERNEL);
if (NULL == rxbuf) {
FTS_ERROR("rxbuf malloc fail");
ret = -ENOMEM;
goto err_write;
}
} else {
txbuf = ts_data->bus_tx_buf;
rxbuf = ts_data->bus_rx_buf;
memset(txbuf, 0x0, SPI_BUF_LENGTH);
memset(rxbuf, 0x0, SPI_BUF_LENGTH);
}
txbuf[txlen++] = writebuf[0];
txbuf[txlen++] = WRITE_CMD;
txbuf[txlen++] = (datalen >> 8) & 0xFF;
txbuf[txlen++] = datalen & 0xFF;
if (datalen > 0) {
txlen = txlen + SPI_DUMMY_BYTE;
memcpy(&txbuf[txlen], &writebuf[1], datalen);
txlen = txlen + datalen;
}
for (i = 0; i < SPI_RETRY_NUMBER; i++) {
ret = fts_spi_transfer(txbuf, rxbuf, txlen);
if ((0 == ret) && ((rxbuf[3] & 0xA0) == 0)) {
break;
} else {
FTS_DEBUG("data write(status=%x),retry=%d,ret=%d",
rxbuf[3], i, ret);
ret = -EIO;
udelay(CS_HIGH_DELAY);
}
}
err_write:
if (txlen_need > SPI_BUF_LENGTH) {
if (txbuf) {
kfree(txbuf);
txbuf = NULL;
}
if (rxbuf) {
kfree(rxbuf);
rxbuf = NULL;
}
}
mutex_unlock(&ts_data->bus_lock);
return ret;
}
int fts_write_reg(u8 addr, u8 value)
{
u8 writebuf[2] = { 0 };
writebuf[0] = addr;
writebuf[1] = value;
return fts_write(writebuf, 2);
}
int fts_read(u8 *cmd, u32 cmdlen, u8 *data, u32 datalen)
{
int ret = 0;
int i = 0;
struct fts_ts_data *ts_data = fts_data;
u8 *txbuf = NULL;
u8 *rxbuf = NULL;
u32 txlen = 0;
u32 txlen_need = datalen + SPI_HEADER_LENGTH;
u8 ctrl = READ_CMD;
u32 dp = 0;
if (!cmd || !cmdlen || !data || !datalen) {
FTS_ERROR("cmd/cmdlen/data/datalen is invalid");
return -EINVAL;
}
mutex_lock(&ts_data->bus_lock);
if (txlen_need > SPI_BUF_LENGTH) {
txbuf = kzalloc(txlen_need, GFP_KERNEL);
if (NULL == txbuf) {
FTS_ERROR("txbuf malloc fail");
ret = -ENOMEM;
goto err_read;
}
rxbuf = kzalloc(txlen_need, GFP_KERNEL);
if (NULL == rxbuf) {
FTS_ERROR("rxbuf malloc fail");
ret = -ENOMEM;
goto err_read;
}
} else {
txbuf = ts_data->bus_tx_buf;
rxbuf = ts_data->bus_rx_buf;
memset(txbuf, 0x0, SPI_BUF_LENGTH);
memset(rxbuf, 0x0, SPI_BUF_LENGTH);
}
txbuf[txlen++] = cmd[0];
txbuf[txlen++] = ctrl;
txbuf[txlen++] = (datalen >> 8) & 0xFF;
txbuf[txlen++] = datalen & 0xFF;
dp = txlen + SPI_DUMMY_BYTE;
txlen = dp + datalen;
if (ctrl & DATA_CRC_EN) {
txlen = txlen + 2;
}
for (i = 0; i < SPI_RETRY_NUMBER; i++) {
ret = fts_spi_transfer(txbuf, rxbuf, txlen);
if ((0 == ret) && ((rxbuf[3] & 0xA0) == 0)) {
memcpy(data, &rxbuf[dp], datalen);
/* crc check */
if (ctrl & DATA_CRC_EN) {
ret = rdata_check(&rxbuf[dp], txlen - dp);
if (ret < 0) {
FTS_INFO("read data(addr:%x) crc check incorrect", cmd[0]);
goto err_read;
}
}
break;
} else {
FTS_DEBUG("data read(status=%x),retry=%d,ret=%d",
rxbuf[3], i, ret);
ret = -EIO;
udelay(CS_HIGH_DELAY);
}
}
err_read:
if (txlen_need > SPI_BUF_LENGTH) {
if (txbuf) {
kfree(txbuf);
txbuf = NULL;
}
if (rxbuf) {
kfree(rxbuf);
rxbuf = NULL;
}
}
mutex_unlock(&ts_data->bus_lock);
return ret;
}
int fts_read_reg(u8 addr, u8 *value)
{
return fts_read(&addr, 1, value, 1);
}
int fts_bus_init(struct fts_ts_data *ts_data)
{
FTS_FUNC_ENTER();
ts_data->bus_tx_buf = kzalloc(SPI_BUF_LENGTH, GFP_KERNEL);
if (NULL == ts_data->bus_tx_buf) {
FTS_ERROR("failed to allocate memory for bus_tx_buf");
return -ENOMEM;
}
ts_data->bus_rx_buf = kzalloc(SPI_BUF_LENGTH, GFP_KERNEL);
if (NULL == ts_data->bus_rx_buf) {
FTS_ERROR("failed to allocate memory for bus_rx_buf");
return -ENOMEM;
}
FTS_FUNC_EXIT();
return 0;
}
int fts_bus_exit(struct fts_ts_data *ts_data)
{
FTS_FUNC_ENTER();
if (ts_data && ts_data->bus_tx_buf) {
kfree(ts_data->bus_tx_buf);
ts_data->bus_tx_buf = NULL;
}
if (ts_data && ts_data->bus_rx_buf) {
kfree(ts_data->bus_rx_buf);
ts_data->bus_rx_buf = NULL;
}
FTS_FUNC_EXIT();
return 0;
}

View file

@ -1,3 +0,0 @@
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_test.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_test_ini.o
obj-$(CONFIG_TOUCHSCREEN_FTS) += supported_ic/

View file

@ -1,602 +0,0 @@
/************************************************************************
* Copyright (C) 2012-2019, Focaltech Systems (R)£¬All Rights Reserved.
*
* File Name: focaltech_test.h
*
* Author: Focaltech Driver Team
*
* Created: 2016-08-01
*
* Abstract: test entry for all IC
*
************************************************************************/
#ifndef _TEST_LIB_H
#define _TEST_LIB_H
/*****************************************************************************
* Included header files
*****************************************************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/debugfs.h>
#include <asm/uaccess.h>
#include <linux/i2c.h>//iic
#include <linux/delay.h>//msleep
#include <linux/string.h>
#include <asm/unistd.h>
#include <linux/vmalloc.h>
#include "../focaltech_core.h"
#include "focaltech_test_ini.h"
/*****************************************************************************
* Macro definitions using #define
*****************************************************************************/
#define FTS_INI_FILE_PATH "/mnt/sdcard/"
#define FTS_CSV_FILE_NAME "testdata.csv"
#define FTS_TXT_FILE_NAME "testresult.txt"
#define false 0
#define true 1
#define TEST_ICSERIES_LEN (8)
#define TEST_ICSERIES(x) ((x) >> TEST_ICSERIES_LEN)
#define TEST_OPEN_MAX_VALUE (255)
#define BYTES_PER_TIME (32) /* max:128 */
/* CSV & TXT */
#define CSV_LINE2_BUFFER_LEN (1024)
#define CSV_BUFFER_LEN (1024*80*5)
#define TXT_BUFFER_LEN (1024*80*5)
/*-----------------------------------------------------------
Test Status
-----------------------------------------------------------*/
#define RESULT_NULL 0
#define RESULT_PASS 1
#define RESULT_NG 2
#define TX_NUM_MAX 60
#define RX_NUM_MAX 60
#define NUM_MAX ((TX_NUM_MAX)*(RX_NUM_MAX))
#define NUM_MAX_SC (144)
#define KEY_NUM_MAX 6
#define TEST_ITEM_COUNT_MAX 32
#define TEST_ITEM_NAME_MAX 32
#define TEST_SHORT_RES_MAX 0xFFFF
/*
* factory test registers
*/
#define ENTER_WORK_FACTORY_RETRIES 5
#define START_SCAN_RETRIES_INCELL 20
#define START_SCAN_RETRIES_DELAY_INCELL 16
#define FACTORY_TEST_RETRY 50
#define FACTORY_TEST_DELAY 18
#define FACTORY_TEST_RETRY_DELAY 100
#define DEVIDE_MODE_ADDR 0x00
#define REG_FW_VERSION 0xA6
#define REG_VA_TOUCH_THR 0x80
#define REG_VKEY_TOUCH_THR 0x82
#define FACTORY_REG_LINE_ADDR 0x01
#define FACTORY_REG_CHX_NUM 0x02
#define FACTORY_REG_CHY_NUM 0x03
#define FACTORY_REG_CLB 0x04
#define FACTORY_REG_DATA_SELECT 0x06
#define FACTORY_REG_RAWBUF_SELECT 0x09
#define FACTORY_REG_KEY_CBWIDTH 0x0B
#define FACTORY_REG_PARAM_UPDATE_STATE 0x0E
#define FACTORY_REG_SHORT_TEST_EN 0x0F
#define FACTORY_REG_SHORT_TEST_STATE 0x10
#define FACTORY_REG_LCD_NOISE_START 0x11
#define FACTORY_REG_LCD_NOISE_FRAME 0x12
#define FACTORY_REG_LCD_NOISE_NUMBER 0x13
#define FACTORY_REG_LCD_NOISE_TEST_STATE 0x13
#define FACTORY_REG_LCD_NOISE_TTHR 0x14
#define FACTORY_REG_OPEN_START 0x15
#define FACTORY_REG_OPEN_STATE 0x16
#define FACTORY_REG_OPEN_IDLE 0x03
#define FACTORY_REG_OPEN_BUSY 0x01
#define FACTORY_REG_CB_ADDR_H 0x18
#define FACTORY_REG_CB_ADDR_L 0x19
#define FACTORY_REG_ORDER_ADDR_H 0x1A
#define FACTORY_REG_ORDER_ADDR_L 0x1B
#define FACTORY_REG_LCD_NOISE_STATE 0x1E
#define FACTORY_REG_KEYSHORT_EN 0x2E
#define FACTORY_REG_KEYSHORT_STATE 0x2F
#define FACTORY_REG_LEFT_KEY 0x1E
#define FACTORY_REG_RIGHT_KEY 0x1F
#define FACTORY_REG_OPEN_REG20 0x20
#define FACTORY_REG_OPEN_REG21 0x21
#define FACTORY_REG_OPEN_REG22 0x22
#define FACTORY_REG_OPEN_REG23 0x23
#define FACTORY_REG_OPEN_REG2E 0x2E
#define FACTORY_REG_OPEN_REG86 0x86
#define FACTORY_REG_K1 0x31
#define FACTORY_REG_K2 0x32
#define FACTORY_REG_RAWDATA_ADDR 0x6A
#define FACTORY_REG_ORDER_ADDR 0x6C
#define FACTORY_REG_CB_ADDR 0x6E
#define FACTORY_REG_SHORT_ADDR 0x89
#define FACTORY_REG_RAWDATA_TEST_EN 0x9E
#define FACTORY_REG_CB_TEST_EN 0x9F
#define FACTORY_REG_OPEN_TEST_EN 0xA0
/* mc_sc */
#define FACTORY_REG_FRE_LIST 0x0A
#define FACTORY_REG_NORMALIZE 0x16
#define FACTORY_REG_RAWDATA_ADDR_MC_SC 0x36
#define FACTORY_REG_PATTERN 0x53
#define FACTORY_REG_NOMAPPING 0x54
#define FACTORY_REG_CHX_NUM_NOMAP 0x55
#define FACTORY_REG_CHY_NUM_NOMAP 0x56
#define FACTORY_REG_WC_SEL 0x09
#define FACTORY_REG_MC_SC_MODE 0x44
#define FACTORY_REG_MC_SC_CB_ADDR_OFF 0x45
#define FACTORY_REG_MC_SC_CB_ADDR 0x4E
#define FACTROY_REG_SHORT_TEST_EN 0x07
#define FACTROY_REG_SHORT_CA 0x01
#define FACTROY_REG_SHORT_CC 0x02
#define FACTROY_REG_SHORT_CG 0x03
#define FACTROY_REG_SHORT_OFFSET 0x04
#define FACTROY_REG_SHORT_AB_CH 0x58
#define FACTROY_REG_SHORT_DELAY 0x5A
#define FACTORY_REG_SHORT_ADDR_MC 0xF4
#define FACTORY_REG_FIR 0xFB
/* sc */
#define FACTORY_REG_SCAN_ADDR2 0x08
#define FACTORY_REG_CH_NUM_SC 0x0A
#define FACTORY_REG_KEY_NUM_SC 0x0B
#define FACTORY_REG_SC_CB_ADDR_OFF 0x33
#define FACTORY_REG_SC_CB_ADDR 0x39
#define FACTORY_REG_RAWDATA_SADDR_SC 0x34
#define FACTORY_REG_RAWDATA_ADDR_SC 0x35
#define FACTORY_REG_CB_SEL 0x41
#define FACTORY_REG_FMODE 0xAE
#define TEST_RETVAL_00 0x00
#define TEST_RETVAL_AA 0xAA
/*****************************************************************************
* enumerations, structures and unions
*****************************************************************************/
struct item_info {
char name[TEST_ITEM_NAME_MAX];
int code;
int *data;
int datalen;
int result;
int mc_sc;
int key_support;
};
struct fts_test_data {
int item_count;
struct item_info info[TEST_ITEM_COUNT_MAX];
};
/* incell */
struct incell_testitem {
u32 short_test : 1;
u32 open_test : 1;
u32 cb_test : 1;
u32 rawdata_test : 1;
u32 lcdnoise_test : 1;
u32 keyshort_test : 1;
u32 mux_open_test : 1;
};
struct incell_threshold_b {
int short_res_min;
int short_res_vk_min;
int open_cb_min;
int open_k1_check;
int open_k1_value;
int open_k2_check;
int open_k2_value;
int cb_min;
int cb_max;
int cb_vkey_check;
int cb_min_vk;
int cb_max_vk;
int rawdata_min;
int rawdata_max;
int rawdata_vkey_check;
int rawdata_min_vk;
int rawdata_max_vk;
int lcdnoise_frame;
int lcdnoise_coefficient;
int lcdnoise_coefficient_vkey;
int open_nmos;
int keyshort_k1;
int keyshort_cb_max;
int rawdata2_min;
int rawdata2_max;
int mux_open_cb_min;
};
struct incell_threshold {
struct incell_threshold_b basic;
int *rawdata_min;
int *rawdata_max;
int *rawdata2_min;
int *rawdata2_max;
int *cb_min;
int *cb_max;
};
struct incell_test {
struct incell_threshold thr;
union {
int tmp;
struct incell_testitem item;
} u;
};
/* mc_sc */
enum mapping_type {
MAPPING = 0,
NO_MAPPING = 1,
};
struct mc_sc_testitem {
u32 rawdata_test : 1;
u32 rawdata_uniformity_test : 1;
u32 scap_cb_test : 1;
u32 scap_rawdata_test : 1;
u32 short_test : 1;
u32 panel_differ_test : 1;
};
struct mc_sc_threshold_b {
int rawdata_h_min;
int rawdata_h_max;
int rawdata_set_hfreq;
int rawdata_l_min;
int rawdata_l_max;
int rawdata_set_lfreq;
int uniformity_check_tx;
int uniformity_check_rx;
int uniformity_check_min_max;
int uniformity_tx_hole;
int uniformity_rx_hole;
int uniformity_min_max_hole;
int scap_cb_off_min;
int scap_cb_off_max;
int scap_cb_wp_off_check;
int scap_cb_on_min;
int scap_cb_on_max;
int scap_cb_wp_on_check;
int scap_rawdata_off_min;
int scap_rawdata_off_max;
int scap_rawdata_wp_off_check;
int scap_rawdata_on_min;
int scap_rawdata_on_max;
int scap_rawdata_wp_on_check;
int short_cg;
int short_cc;
int panel_differ_min;
int panel_differ_max;
};
struct mc_sc_threshold {
struct mc_sc_threshold_b basic;
int *rawdata_h_min;
int *rawdata_h_max;
int *rawdata_l_min;
int *rawdata_l_max;
int *tx_linearity_max;
int *tx_linearity_min;
int *rx_linearity_max;
int *rx_linearity_min;
int *scap_cb_off_min;
int *scap_cb_off_max;
int *scap_cb_on_min;
int *scap_cb_on_max;
int *scap_rawdata_off_min;
int *scap_rawdata_off_max;
int *scap_rawdata_on_min;
int *scap_rawdata_on_max;
int *panel_differ_min;
int *panel_differ_max;
};
struct mc_sc_test {
struct mc_sc_threshold thr;
union {
u32 tmp;
struct mc_sc_testitem item;
} u;
};
/* sc */
struct sc_testitem {
u32 rawdata_test : 1;
u32 cb_test : 1;
u32 delta_cb_test : 1;
u32 short_test : 1;
};
struct sc_threshold_b {
int rawdata_min;
int rawdata_max;
int cb_min;
int cb_max;
int dcb_base;
int dcb_differ_max;
int dcb_key_check;
int dcb_key_differ_max;
int dcb_ds1;
int dcb_ds2;
int dcb_ds3;
int dcb_ds4;
int dcb_ds5;
int dcb_ds6;
int dcb_critical_check;
int dcb_cs1;
int dcb_cs2;
int dcb_cs3;
int dcb_cs4;
int dcb_cs5;
int dcb_cs6;
int short_min;
};
struct sc_threshold {
struct sc_threshold_b basic;
int *rawdata_min;
int *rawdata_max;
int *cb_min;
int *cb_max;
int *dcb_sort;
int *dcb_base;
};
struct sc_test {
struct sc_threshold thr;
union {
u32 tmp;
struct sc_testitem item;
} u;
};
enum test_hw_type {
IC_HW_INCELL = 1,
IC_HW_MC_SC,
IC_HW_SC,
};
enum test_scan_mode {
SCAN_NORMAL = 0,
SCAN_SC,
};
struct fts_test_node {
int channel_num;
int tx_num;
int rx_num;
int node_num;
int key_num;
};
struct fts_test {
struct fts_ts_data *ts_data;
struct fts_test_node node;
struct fts_test_node sc_node;
u8 fw_ver;
u8 va_touch_thr;
u8 vk_touch_thr;
bool key_support;
bool v3_pattern;
u8 mapping;
u8 normalize;
int test_num;
int *buffer;
int buffer_length;
int *node_valid;
int *node_valid_sc;
int basic_thr_count;
int code1;
int code2;
int offset;
union {
struct incell_test incell;
struct mc_sc_test mc_sc;
struct sc_test sc;
} ic;
struct test_funcs *func;
struct fts_test_data testdata;
char *testresult;
int testresult_len;
struct ini_data ini;
};
struct test_funcs {
u64 ctype[FTX_MAX_COMPATIBLE_TYPE];
enum test_hw_type hwtype;
int startscan_mode;
int key_num_total;
bool rawdata2_support;
bool force_touch;
int (*param_init)(void);
int (*init)(void);
int (*start_test)(void);
};
enum byte_mode {
DATA_ONE_BYTE,
DATA_TWO_BYTE,
};
/* mc_sc */
enum normalize_type {
NORMALIZE_OVERALL,
NORMALIZE_AUTO,
};
enum wp_type {
WATER_PROOF_OFF = 0,
WATER_PROOF_ON = 1,
WATER_PROOF_ON_TX,
WATER_PROOF_ON_RX,
WATER_PROOF_OFF_TX,
WATER_PROOF_OFF_RX,
};
/* mc end */
/* sc */
enum factory_mode {
FACTORY_NORMAL,
FACTORY_TESTMODE_1,
FACTORY_TESTMODE_2,
};
enum dcb_sort_num {
DCB_SORT_MIN = 1,
DCB_SORT_MAX = 6,
};
struct dcb_sort_d {
int ch_num;
int deviation;
int critical;
int min;
int max;
};
/* sc end */
enum csv_itemcode_incell {
CODE_ENTER_FACTORY_MODE = 0,
CODE_RAWDATA_TEST = 7,
CODE_CB_TEST = 12,
CODE_SHORT_TEST = 15,
CODE_OPEN_TEST = 25,
CODE_LCD_NOISE_TEST = 27,
CODE_MUX_OPEN_TEST = 41,
};
enum csv_itemcode_mc_sc {
CODE_M_RAWDATA_TEST = 7,
CODE_M_SCAP_CB_TEST = 9,
CODE_M_SCAP_RAWDATA_TEST = 10,
CODE_M_WEAK_SHORT_CIRCUIT_TEST = 15,
CODE_M_RAWDATA_UNIFORMITY_TEST = 16,
CODE_M_PANELDIFFER_TEST = 20,
};
enum csv_itemcode_sc {
CODE_S_RAWDATA_TEST = 7,
CODE_S_CB_TEST = 13,
CODE_S_DCB_TEST = 14,
};
/*****************************************************************************
* Global variable or extern global variabls/functions
*****************************************************************************/
#ifdef CONFIG_INPUT_FOCALTECH_0FLASH_MMI_IC_NAME_FT8719
extern struct test_funcs test_func_ft8719;
#endif
#ifdef CONFIG_INPUT_FOCALTECH_0FLASH_MMI_IC_NAME_FT8756
extern struct test_funcs test_func_ft8756;
#endif
extern struct fts_test *fts_ftest;
void sys_delay(int ms);
int focal_abs(int value);
void print_buffer(int *buffer, int length, int line_num);
int fts_test_read_reg(u8 addr, u8 *val);
int fts_test_write_reg(u8 addr, u8 val);
int fts_test_read(u8 addr, u8 *readbuf, int readlen);
int fts_test_write(u8 addr, u8 *writebuf, int writelen);
int enter_work_mode(void);
int enter_factory_mode(void);
int read_mass_data(u8 addr, int byte_num, int *buf);
int chip_clb(void);
int wait_state_update(u8 retval);
int get_cb_incell(u16 saddr, int byte_num, int *cb_buf);
int short_get_adcdata_incell(u8 retval, u8 ch_num, int byte_num, int *adc_buf);
int start_scan(void);
int get_rawdata(int *data);
int get_cb_sc(int byte_num, int *cb_buf, enum byte_mode mode);
bool compare_data(int *data, int min, int max, int min_vk, int max_vk, bool key);
bool compare_array(int *data, int *min, int *max, bool key);
void show_data(int *data, bool key);
/* mc_sc */
int mapping_switch(u8 mapping);
bool get_fw_wp(u8 wp_channel_select, enum wp_type water_proof_type);
int get_cb_mc_sc(u8 wp, int byte_num, int *cb_buf, enum byte_mode mode);
int get_rawdata_mc_sc(enum wp_type wp, int *data);
int get_rawdata_mc(u8 fre, u8 fir, int *rawdata);
int short_get_adc_data_mc(u8 retval, int byte_num, int *adc_buf, u8 mode);
bool compare_mc_sc(bool, bool, int *, int *, int *);
void show_data_mc_sc(int *data);
void *fts_malloc(size_t size);
void fts_free_proc(void *p);
void fts_test_save_data(char *name, int code, int *data, int datacnt,
bool mc_sc, bool key, bool result);
#define fts_malloc_r(p, size) do {\
if (NULL == p) {\
p = fts_malloc(size);\
if (NULL == p) {\
return -ENOMEM;\
}\
}\
} while(0)
#define fts_free(p) do {\
if (p) {\
fts_free_proc(p);\
p = NULL;\
}\
} while(0)
#define CSV_SUPPORT 1
#define TXT_SUPPORT 1
#define FTS_TEST_DBG(fmt, args...) do { \
printk("[FTS_TS][TEST]%s:"fmt"\n", __func__, ##args); \
} while (0)
#define FTS_TEST_FUNC_ENTER() do { \
printk("[FTS_TS][TEST]%s: Enter\n", __func__); \
} while (0)
#define FTS_TEST_FUNC_EXIT() do { \
printk("[FTS_TS][TEST]%s: Exit(%d)\n", __func__, __LINE__); \
} while (0)
#define FTS_TEST_INFO(fmt, args...) do { \
printk(KERN_ERR "[FTS_TS/I][TEST]%s:"fmt"\n", __func__, ##args); \
} while (0)
#define FTS_TEST_ERROR(fmt, args...) do { \
printk(KERN_ERR "[FTS_TS/E][TEST]%s:"fmt"\n", __func__, ##args); \
} while (0)
#define FTS_TEST_SAVE_INFO(fmt, args...) do { \
if (fts_ftest->testresult) { \
fts_ftest->testresult_len += snprintf( \
fts_ftest->testresult + fts_ftest->testresult_len, \
TXT_BUFFER_LEN, \
fmt, ##args);\
} \
} while (0)
#define FTS_TEST_SAVE_ERR(fmt, args...) do { \
if (fts_ftest->testresult && (fts_ftest->testresult_len < TXT_BUFFER_LEN)) { \
fts_ftest->testresult_len += snprintf( \
fts_ftest->testresult + fts_ftest->testresult_len, \
TXT_BUFFER_LEN, \
fmt, ##args);\
} \
printk(KERN_ERR "[FTS_TS/E][TEST]%s:"fmt"\n", __func__, ##args);\
} while (0)
#endif

View file

@ -1,141 +0,0 @@
/************************************************************************
* Copyright (C) 2012-2019, Focaltech Systems (R)£¬All Rights Reserved.
*
* File Name: focaltech_test_ini.h
*
* Author: Focaltech Driver Team
*
* Created: 2016-08-01
*
* Abstract: parsing function of INI file
*
************************************************************************/
#ifndef _INI_H
#define _INI_H
/*****************************************************************************
* Private constant and macro definitions using #define
*****************************************************************************/
#define MAX_KEYWORD_NUM (1000)
#define MAX_KEYWORD_NAME_LEN (50)
#define MAX_KEYWORD_VALUE_LEN (512)
#define MAX_KEYWORD_VALUE_ONE_LEN (16)
#define MAX_INI_LINE_LEN (MAX_KEYWORD_NAME_LEN + MAX_KEYWORD_VALUE_LEN)
#define MAX_INI_SECTION_NUM (20)
#define MAX_IC_NAME_LEN (32)
#define MAX_TEST_ITEM (20)
#define IC_CODE_OFFSET (16)
/*****************************************************************************
* enumerations, structures and unions
*****************************************************************************/
struct ini_ic_type {
char ic_name[MAX_IC_NAME_LEN];
u32 ic_type;
};
enum line_type {
LINE_SECTION = 1,
LINE_KEYWORD = 2 ,
LINE_OTHER = 3,
};
struct ini_keyword {
char name[MAX_KEYWORD_NAME_LEN];
char value[MAX_KEYWORD_VALUE_LEN];
};
struct ini_section {
char name[MAX_KEYWORD_NAME_LEN];
int keyword_num;
/* point to ini.tmp, don't need free */
struct ini_keyword *keyword;
};
struct ini_data {
char *data;
int length;
int keyword_num_total;
int section_num;
struct ini_section section[MAX_INI_SECTION_NUM];
struct ini_keyword *tmp;
char ic_name[MAX_IC_NAME_LEN];
u32 ic_code;
};
#define TEST_ITEM_INCELL { \
"SHORT_CIRCUIT_TEST", \
"OPEN_TEST", \
"CB_TEST", \
"RAWDATA_TEST", \
"LCD_NOISE_TEST", \
"KEY_SHORT_TEST", \
"MUX_OPEN_TEST", \
}
#define BASIC_THRESHOLD_INCELL { \
"ShortCircuit_ResMin", "ShortCircuit_VkResMin", \
"OpenTest_CBMin", "OpenTest_Check_K1", "OpenTest_K1Threshold", "OpenTest_Check_K2", "OpenTest_K2Threshold", \
"CBTest_Min", "CBTest_Max", \
"CBTest_VKey_Check", "CBTest_Min_Vkey", "CBTest_Max_Vkey", \
"RawDataTest_Min", "RawDataTest_Max", \
"RawDataTest_VKey_Check", "RawDataTest_Min_VKey", "RawDataTest_Max_VKey", \
"LCD_NoiseTest_Frame", "LCD_NoiseTest_Coefficient", "LCD_NoiseTest_Coefficient_key", \
}
#define TEST_ITEM_MC_SC { \
"RAWDATA_TEST", \
"UNIFORMITY_TEST", \
"SCAP_CB_TEST", \
"SCAP_RAWDATA_TEST", \
"WEAK_SHORT_CIRCUIT_TEST", \
"PANEL_DIFFER_TEST", \
}
#define BASIC_THRESHOLD_MC_SC { \
"RawDataTest_High_Min", "RawDataTest_High_Max", "RawDataTest_HighFreq", \
"RawDataTest_Low_Min", "RawDataTest_Low_Max", "RawDataTest_LowFreq", \
"UniformityTest_Check_Tx", "UniformityTest_Check_Rx","UniformityTest_Check_MinMax", \
"UniformityTest_Tx_Hole", "UniformityTest_Rx_Hole", "UniformityTest_MinMax_Hole", \
"SCapCbTest_OFF_Min", "SCapCbTest_OFF_Max", "ScapCBTest_SetWaterproof_OFF", \
"SCapCbTest_ON_Min", "SCapCbTest_ON_Max", "ScapCBTest_SetWaterproof_ON", \
"SCapRawDataTest_OFF_Min", "SCapRawDataTest_OFF_Max", "SCapRawDataTest_SetWaterproof_OFF", \
"SCapRawDataTest_ON_Min", "SCapRawDataTest_ON_Max", "SCapRawDataTest_SetWaterproof_ON", \
"WeakShortTest_CG", "WeakShortTest_CC", \
"PanelDifferTest_Min", "PanelDifferTest_Max", \
}
#define TEST_ITEM_SC { \
"RAWDATA_TEST", \
"CB_TEST", \
"DELTA_CB_TEST", \
"WEAK_SHORT_TEST", \
}
#define BASIC_THRESHOLD_SC { \
"RawDataTest_Min", "RawDataTest_Max", \
"CbTest_Min", "CbTest_Max", \
"DeltaCbTest_Base", "DeltaCbTest_Differ_Max", \
"DeltaCbTest_Include_Key_Test", "DeltaCbTest_Key_Differ_Max", \
"DeltaCbTest_Deviation_S1", "DeltaCbTest_Deviation_S2", "DeltaCbTest_Deviation_S3", \
"DeltaCbTest_Deviation_S4", "DeltaCbTest_Deviation_S5", "DeltaCbTest_Deviation_S6", \
"DeltaCbTest_Set_Critical", "DeltaCbTest_Critical_S1", "DeltaCbTest_Critical_S2", \
"DeltaCbTest_Critical_S3", "DeltaCbTest_Critical_S4", \
"DeltaCbTest_Critical_S5", "DeltaCbTest_Critical_S6", \
}
/*****************************************************************************
* Global variable or extern global variabls/functions
*****************************************************************************/
int fts_test_get_testparam_from_ini(char *config_name);
int get_keyword_value(char *section, char *name, int *value);
#define get_value_interface(name, value) \
get_keyword_value("Interface", name, value)
#define get_value_basic(name, value) \
get_keyword_value("Basic_Threshold", name, value)
#define get_value_detail(name, value) \
get_keyword_value("SpecialSet", name, value)
#define get_value_testitem(name, value) \
get_keyword_value("TestItem", name, value)
#endif /* _INI_H */

View file

@ -1 +0,0 @@
obj-$(CONFIG_TOUCHSCREEN_FTS) += focaltech_test_ft8719.o

View file

@ -1,618 +0,0 @@
/************************************************************************
* Copyright (C) 2012-2019, Focaltech Systems (R), All Rights Reserved.
*
* File Name: Focaltech_test_ft8719.c
*
* Author: Focaltech Driver Team
*
* Created: 2017-12-01
*
* Abstract:
*
************************************************************************/
/*****************************************************************************
* Included header files
*****************************************************************************/
#include "../focaltech_test.h"
/*******************************************************************************
* Private constant and macro definitions using #define
*******************************************************************************/
#define CODE2_SHORT_TEST 14
#define CODE2_OPEN_TEST 24
#define CODE2_LCD_NOISE_TEST 15
/*******************************************************************************
* Private enumerations, structures and unions using typedef
*******************************************************************************/
/*******************************************************************************
* Static variables
*******************************************************************************/
/*******************************************************************************
* Global variable or extern global variabls/functions
*******************************************************************************/
/*******************************************************************************
* Static function prototypes
*******************************************************************************/
static int ft8719_short_test(struct fts_test *tdata, bool *test_result)
{
int ret = 0;
int i = 0;
bool tmp_result = false;
int byte_num = 0;
int ch_num = 0;
int min = 0;
int max = 0;
int tmp_adc = 0;
int *adcdata = NULL;
struct incell_threshold *thr = &tdata->ic.incell.thr;
FTS_TEST_FUNC_ENTER();
FTS_TEST_SAVE_INFO("\n============ Test Item: Short Circuit Test\n");
memset(tdata->buffer, 0, tdata->buffer_length);
adcdata = tdata->buffer;
ret = enter_factory_mode();
if (ret < 0) {
FTS_TEST_SAVE_ERR("enter factory mode fail,ret=%d\n", ret);
goto test_err;
}
byte_num = tdata->node.node_num * 2;
ch_num = tdata->node.rx_num;
ret = short_get_adcdata_incell(TEST_RETVAL_AA, ch_num, byte_num, adcdata);
if (ret < 0) {
FTS_TEST_SAVE_ERR("get adc data fail\n");
goto test_err;
}
/* calculate resistor */
for (i = 0; i < tdata->node.node_num; i++) {
tmp_adc = adcdata[i];
if (tmp_adc < 50) {
adcdata[i] = -1;
continue;
} else if (tmp_adc < 200) {
tmp_adc = 200;
}
adcdata[i] = 252000 / (tmp_adc - 120) - 60;
}
/* save */
show_data(adcdata, true);
/* compare */
min = thr->basic.short_res_min;
max = TEST_SHORT_RES_MAX;
tmp_result = compare_data(adcdata, min, max, min, max, true);
ret = 0;
test_err:
if (tmp_result) {
*test_result = true;
FTS_TEST_SAVE_INFO("------ Short Circuit Test PASS\n");
} else {
*test_result = false;
FTS_TEST_SAVE_INFO("------ Short Circuit Test NG\n");
}
/*save test data*/
fts_test_save_data("Short Circuit Test", CODE2_SHORT_TEST,
adcdata, 0, false, true, *test_result);
FTS_TEST_FUNC_EXIT();
return ret;
}
static int ft8719_open_test(struct fts_test *tdata, bool *test_result)
{
int ret = 0;
bool tmp_result = false;
int byte_num = 0;
u8 reg20_val = 0;
u8 reg21_val = 0;
u8 k1 = 0;
u8 k2 = 0;
int min = 0;
int max = 0;
int *opendata = NULL;
struct incell_threshold *thr = &tdata->ic.incell.thr;
FTS_TEST_FUNC_ENTER();
FTS_TEST_SAVE_INFO("\n============ Test Item: Open Test\n");
memset(tdata->buffer, 0, tdata->buffer_length);
opendata = tdata->buffer;
ret = enter_factory_mode();
if (ret < 0) {
FTS_TEST_SAVE_ERR("enter factory mode fail,ret=%d\n", ret);
goto test_err;
}
/* backup defaul value */
ret = fts_test_read_reg(FACTORY_REG_OPEN_REG20, &reg20_val);
if (ret < 0) {
FTS_TEST_SAVE_ERR("read reg 0x20 fail\n");
goto test_err;
}
ret = fts_test_read_reg(FACTORY_REG_OPEN_REG21, &reg21_val);
if (ret < 0) {
FTS_TEST_SAVE_ERR("read reg 0x21 fail\n");
goto test_err;
}
if (thr->basic.open_k1_check) {
ret = fts_test_read_reg(FACTORY_REG_K1, &k1);
if (ret < 0) {
FTS_TEST_SAVE_ERR("read k1 fail\n");
goto test_err;
}
}
if (thr->basic.open_k2_check) {
ret = fts_test_read_reg(FACTORY_REG_K2, &k2);
if (ret < 0) {
FTS_TEST_SAVE_ERR("read k2 fail\n");
goto test_err;
}
}
/* open test enable */
ret = fts_test_write_reg(FACTORY_REG_OPEN_TEST_EN, 0x01);
if (ret < 0) {
FTS_TEST_SAVE_ERR("open test enable fail\n");
goto test_err;
}
/* set open test environment */
ret = fts_test_write_reg(FACTORY_REG_OPEN_REG20, 0x01);
if (ret < 0) {
FTS_TEST_SAVE_ERR("write reg 0x20 fail\n");
goto restore_reg;
}
ret = fts_test_write_reg(FACTORY_REG_OPEN_REG21, 0x01);
if (ret < 0) {
FTS_TEST_SAVE_ERR("write reg 0x21 fail\n");
goto restore_reg;
}
if (thr->basic.open_k1_check) {
ret = fts_test_write_reg(FACTORY_REG_K1, thr->basic.open_k1_value);
if (ret < 0) {
FTS_TEST_SAVE_ERR("write reg k1 fail\n");
goto restore_reg;
}
}
if (thr->basic.open_k2_check) {
ret = fts_test_write_reg(FACTORY_REG_K2, thr->basic.open_k2_value);
if (ret < 0) {
FTS_TEST_SAVE_ERR("write reg k2 fail\n");
goto restore_reg;
}
}
/* wait fw state update before clb */
ret = wait_state_update(TEST_RETVAL_00);
if (ret < 0) {
FTS_TEST_SAVE_ERR("wait state update fail\n");
goto restore_reg;
}
/* auto clb */
ret = chip_clb();
if (ret < 0) {
FTS_TEST_SAVE_ERR("auto clb fail\n");
goto restore_reg;
}
/* get cb data */
byte_num = tdata->node.tx_num * tdata->node.rx_num;
ret = get_cb_incell(0, byte_num, opendata);
if (ret) {
FTS_TEST_SAVE_ERR("get CB fail\n");
goto restore_reg;
}
/* save */
show_data(opendata, false);
/* compare */
min = thr->basic.open_cb_min;
max = TEST_OPEN_MAX_VALUE;
tmp_result = compare_data(opendata, min, max, 0, 0, false);
restore_reg:
ret = fts_test_write_reg(FACTORY_REG_OPEN_REG20, reg20_val);
if (ret < 0) {
FTS_TEST_SAVE_ERR("restore reg 0x20 fail\n");
}
ret = fts_test_write_reg(FACTORY_REG_OPEN_REG21, reg21_val);
if (ret < 0) {
FTS_TEST_SAVE_ERR("restore reg 0x21 fail\n");
}
if (thr->basic.open_k1_check) {
ret = fts_test_write_reg(FACTORY_REG_K1, k1);
if (ret < 0) {
FTS_TEST_SAVE_ERR("restore reg k1 fail\n");
}
}
if (thr->basic.open_k2_check) {
ret = fts_test_write_reg(FACTORY_REG_K2, k2);
if (ret < 0) {
FTS_TEST_SAVE_ERR("restore reg k2 fail\n");
}
}
/* open test disable */
ret = fts_test_write_reg(FACTORY_REG_OPEN_TEST_EN, 0x00);
if (ret < 0) {
FTS_TEST_SAVE_ERR("open test disable fail\n");
}
/* wait fw state update before clb */
ret = wait_state_update(TEST_RETVAL_00);
if (ret < 0) {
FTS_TEST_SAVE_ERR("wait state update fail\n");
}
/* auto clb */
ret = chip_clb();
if (ret < 0) {
FTS_TEST_SAVE_ERR("auto clb fail\n");
}
test_err:
if (tmp_result) {
*test_result = true;
FTS_TEST_SAVE_INFO("------ Open Test PASS\n");
} else {
*test_result = false;
FTS_TEST_SAVE_INFO("------ Open Test NG\n");
}
/* save test data */
fts_test_save_data("Open Test", CODE2_OPEN_TEST,
opendata, 0, false, false, *test_result);
FTS_TEST_FUNC_EXIT();
return ret;
}
static int ft8719_cb_test(struct fts_test *tdata, bool *test_result)
{
int ret = 0;
bool tmp_result = false;
bool key_check = false;
int byte_num = 0;
int *cbdata = NULL;
struct incell_threshold *thr = &tdata->ic.incell.thr;
FTS_TEST_FUNC_ENTER();
FTS_TEST_SAVE_INFO("\n============ Test Item: CB Test\n");
memset(tdata->buffer, 0, tdata->buffer_length);
cbdata = tdata->buffer;
key_check = thr->basic.cb_vkey_check;
if (!thr->cb_min || !thr->cb_max || !test_result) {
FTS_TEST_SAVE_ERR("cb_min/max test_result is null\n");
ret = -EINVAL;
goto test_err;
}
ret = enter_factory_mode();
if (ret < 0) {
FTS_TEST_SAVE_ERR("enter factory mode fail,ret=%d\n", ret);
goto test_err;
}
/* cb test enable */
ret = fts_test_write_reg(FACTORY_REG_CB_TEST_EN, 0x01);
if (ret < 0) {
FTS_TEST_SAVE_ERR("cb test enable fail\n");
goto test_err;
}
/* auto clb */
ret = chip_clb();
if (ret < 0) {
FTS_TEST_SAVE_ERR("auto clb fail\n");
goto test_err;
}
byte_num = tdata->node.node_num;
ret = get_cb_incell(0, byte_num, cbdata);
if (ret < 0) {
FTS_TEST_SAVE_ERR("get cb fail\n");
goto test_err;
}
/* save */
show_data(cbdata, key_check);
/* compare */
tmp_result = compare_array(cbdata, thr->cb_min, thr->cb_max, key_check);
test_err:
/* cb test disable */
ret = fts_test_write_reg(FACTORY_REG_CB_TEST_EN, 0x00);
if (ret < 0) {
FTS_TEST_SAVE_ERR("cb test disable fail\n");
}
if (tmp_result) {
*test_result = true;
FTS_TEST_SAVE_INFO("------ CB Test PASS\n");
} else {
*test_result = false;
FTS_TEST_SAVE_INFO("------ CB Test NG\n");
}
/* save test data */
fts_test_save_data("CB Test", CODE_CB_TEST,
cbdata, 0, false, key_check, *test_result);
FTS_TEST_FUNC_EXIT();
return ret;
}
static int ft8719_rawdata_test(struct fts_test *tdata, bool *test_result)
{
int ret = 0;
int i = 0;
bool tmp_result = false;
bool key_check = false;
int *rawdata = NULL;
struct incell_threshold *thr = &tdata->ic.incell.thr;
FTS_TEST_FUNC_ENTER();
FTS_TEST_SAVE_INFO("\n============ Test Item: RawData Test\n");
memset(tdata->buffer, 0, tdata->buffer_length);
rawdata = tdata->buffer;
key_check = thr->basic.rawdata_vkey_check;
if (!thr->rawdata_min || !thr->rawdata_max || !test_result) {
FTS_TEST_SAVE_ERR("rawdata_min/max test_result is null\n");
ret = -EINVAL;
goto test_err;
}
ret = enter_factory_mode();
if (ret < 0) {
FTS_TEST_SAVE_ERR("enter factory mode fail,ret=%d\n", ret);
goto test_err;
}
/* rawdata test enable */
ret = fts_test_write_reg(FACTORY_REG_RAWDATA_TEST_EN, 0x01);
if (ret < 0) {
FTS_TEST_SAVE_ERR("rawdata test enable fail\n");
goto test_err;
}
/* read rawdata */
for (i = 0 ; i < 3; i++) {
ret = get_rawdata(rawdata);
}
if (ret < 0) {
FTS_TEST_SAVE_ERR("get RawData fail,ret=%d\n", ret);
goto test_err;
}
/* save */
show_data(rawdata, key_check);
/* compare */
tmp_result = compare_array(rawdata,
thr->rawdata_min,
thr->rawdata_max,
key_check);
test_err:
/* rawdata test disble */
ret = fts_test_write_reg(FACTORY_REG_RAWDATA_TEST_EN, 0x00);
if (ret < 0) {
FTS_TEST_SAVE_ERR("rawdata test disable fail\n");
}
if (tmp_result) {
*test_result = true;
FTS_TEST_SAVE_INFO("------ RawData Test PASS\n");
} else {
*test_result = false;
FTS_TEST_SAVE_INFO("------ RawData Test NG\n");
}
/* save test data */
fts_test_save_data("RawData Test", CODE_RAWDATA_TEST,
rawdata, 0, false, key_check, *test_result);
FTS_TEST_FUNC_EXIT();
return ret;
}
static int ft8719_lcdnoise_test(struct fts_test *tdata, bool *test_result)
{
int ret = 0;
int i = 0;
bool tmp_result = false;
int byte_num = 0;
u8 old_mode = 0;
u8 status = 0;
int frame_num = 0;
int max = 0;
int max_vk = 0;
int *lcdnoise = NULL;
struct incell_threshold *thr = &tdata->ic.incell.thr;
FTS_TEST_FUNC_ENTER();
FTS_TEST_SAVE_INFO("\n============ Test Item: LCD Noise Test\n");
memset(tdata->buffer, 0, tdata->buffer_length);
lcdnoise = tdata->buffer;
ret = enter_factory_mode();
if (ret < 0) {
FTS_TEST_SAVE_ERR("enter factory mode fail,ret=%d\n", ret);
goto test_err;
}
ret = fts_test_read_reg(FACTORY_REG_DATA_SELECT, &old_mode);
if (ret < 0) {
FTS_TEST_SAVE_ERR("read reg06 fail\n");
goto test_err;
}
ret = fts_test_write_reg(FACTORY_REG_DATA_SELECT, 0x01);
if (ret < 0) {
FTS_TEST_SAVE_ERR("write 1 to reg06 fail\n");
goto restore_reg;
}
ret = fts_test_write_reg(FACTORY_REG_LINE_ADDR, 0xAD);
if (ret < 0) {
FTS_TEST_SAVE_ERR("write reg01 fail\n");
goto restore_reg;
}
frame_num = thr->basic.lcdnoise_frame;
ret = fts_test_write_reg(FACTORY_REG_LCD_NOISE_FRAME, frame_num / 4);
if (ret < 0) {
FTS_TEST_SAVE_INFO("write frame num fail\n");
goto restore_reg;
}
/* start test */
ret = fts_test_write_reg(FACTORY_REG_LCD_NOISE_START, 0x01);
if (ret < 0) {
FTS_TEST_SAVE_INFO("start lcdnoise test fail\n");
goto restore_reg;
}
/* check test status */
sys_delay(frame_num * FACTORY_TEST_DELAY / 2);
for (i = 0; i < FACTORY_TEST_RETRY; i++) {
status = 0xFF;
ret = fts_test_read_reg(FACTORY_REG_LCD_NOISE_START, &status);
if ((ret >= 0) && (TEST_RETVAL_AA == status)) {
break;
} else {
FTS_TEST_DBG("reg%x=%x,retry:%d\n",
FACTORY_REG_LCD_NOISE_START, status, i);
}
sys_delay(FACTORY_TEST_RETRY_DELAY);
}
if (i >= FACTORY_TEST_RETRY) {
FTS_TEST_SAVE_ERR("lcdnoise test timeout\n");
goto restore_reg;
}
/* read lcdnoise */
byte_num = tdata->node.node_num * 2;
ret = read_mass_data(FACTORY_REG_RAWDATA_ADDR, byte_num, lcdnoise);
if (ret < 0) {
FTS_TEST_SAVE_ERR("read rawdata fail\n");
goto restore_reg;
}
/* save */
show_data(lcdnoise, true);
/* compare */
max = thr->basic.lcdnoise_coefficient * tdata->va_touch_thr * 32 / 100;
max_vk = thr->basic.lcdnoise_coefficient_vkey * tdata->vk_touch_thr * 32 / 100;
tmp_result = compare_data(lcdnoise, 0, max, 0, max_vk, true);
restore_reg:
ret = fts_test_write_reg(FACTORY_REG_LCD_NOISE_START, 0x00);
if (ret < 0) {
FTS_TEST_SAVE_ERR("write 0 to reg11 fail\n");
}
ret = fts_test_write_reg(FACTORY_REG_DATA_SELECT, old_mode);
if (ret < 0) {
FTS_TEST_SAVE_ERR("restore reg06 fail\n");
}
test_err:
if (tmp_result) {
*test_result = true;
FTS_TEST_SAVE_INFO("------ LCD Noise Test PASS\n");
} else {
*test_result = false;
FTS_TEST_SAVE_INFO("------ LCD Noise Test NG\n");
}
/* save test data */
fts_test_save_data("LCD Noise Test", CODE2_LCD_NOISE_TEST,
lcdnoise, 0, false, true, *test_result);
FTS_TEST_FUNC_EXIT();
return ret;
}
static int start_test_ft8719(void)
{
int ret = 0;
struct fts_test *tdata = fts_ftest;
struct incell_testitem *test_item = &tdata->ic.incell.u.item;
bool temp_result = false;
bool test_result = true;
FTS_TEST_FUNC_ENTER();
FTS_TEST_INFO("test item:0x%x", fts_ftest->ic.incell.u.tmp);
if (!tdata || !tdata->buffer) {
FTS_TEST_ERROR("tdata is null");
return -EINVAL;
}
/* short test */
if (true == test_item->short_test) {
ret = ft8719_short_test(tdata, &temp_result);
if ((ret < 0) || (false == temp_result)) {
test_result = false;
}
}
/* open test */
if (true == test_item->open_test) {
ret = ft8719_open_test(tdata, &temp_result);
if ((ret < 0) || (false == temp_result)) {
test_result = false;
}
}
/* cb test */
if (true == test_item->cb_test) {
ret = ft8719_cb_test(tdata, &temp_result);
if ((ret < 0) || (false == temp_result)) {
test_result = false;
}
}
/* rawdata test */
if (true == test_item->rawdata_test) {
ret = ft8719_rawdata_test(tdata, &temp_result);
if ((ret < 0) || (false == temp_result)) {
test_result = false;
}
}
/* lcd noise test */
if (true == test_item->lcdnoise_test) {
ret = ft8719_lcdnoise_test(tdata, &temp_result);
if ((ret < 0) || (false == temp_result)) {
test_result = false;
}
}
return test_result;
}
struct test_funcs test_func_ft8719 = {
.ctype = {0x0D, 0x0F},
.hwtype = IC_HW_INCELL,
.key_num_total = 4,
.start_test = start_test_ft8719,
};

View file

@ -1,578 +0,0 @@
/************************************************************************
* Copyright (C) 2012-2019, Focaltech Systems (R), All Rights Reserved.
*
* File Name: Focaltech_test_ft8756.c
*
* Author: Focaltech Driver Team
*
* Created: 2019-03-02
*
* Abstract:
*
************************************************************************/
/*****************************************************************************
* Included header files
*****************************************************************************/
#include "../focaltech_test.h"
/*****************************************************************************
* Private constant and macro definitions using #define
*****************************************************************************/
/*****************************************************************************
* Private constant and macro definitions using #define
*****************************************************************************/
/*****************************************************************************
* Private enumerations, structures and unions using typedef
*****************************************************************************/
/*****************************************************************************
* Static variables
*****************************************************************************/
/*****************************************************************************
* Global variable or extern global variabls/functions
*****************************************************************************/
/*****************************************************************************
* Static function prototypes
*****************************************************************************/
static int ft8756_short_test(struct fts_test *tdata, bool *test_result)
{
int ret = 0;
int i = 0;
bool tmp_result = false;
int byte_num = 0;
int ch_num = 0;
int min = 0;
int max = 0;
int tmp_adc = 0;
int *adcdata = NULL;
struct incell_threshold *thr = &tdata->ic.incell.thr;
FTS_TEST_FUNC_ENTER();
FTS_TEST_SAVE_INFO("\n============ Test Item: Short Circuit Test\n");
memset(tdata->buffer, 0, tdata->buffer_length);
adcdata = tdata->buffer;
ret = enter_factory_mode();
if (ret < 0) {
FTS_TEST_SAVE_ERR("enter factory mode fail,ret=%d\n", ret);
goto test_err;
}
byte_num = tdata->node.node_num * 2;
ch_num = tdata->node.rx_num;
ret = short_get_adcdata_incell(TEST_RETVAL_AA, ch_num, byte_num, adcdata);
if (ret < 0) {
FTS_TEST_SAVE_ERR("get adc data fail\n");
goto test_err;
}
/* calculate resistor */
for (i = 0; i < tdata->node.node_num; i++) {
tmp_adc = adcdata[i];
if (tmp_adc > 3500) {
tmp_adc = 3500;
}
adcdata[i] = (5160960 + 555 * 32 * tmp_adc) / (1146880 - 320 * tmp_adc);
}
/* save */
show_data(adcdata, false);
/* compare */
min = thr->basic.short_res_min;
max = TEST_SHORT_RES_MAX;
tmp_result = compare_data(adcdata, min, max, min, max, false);
ret = 0;
test_err:
ret = fts_test_write_reg(FACTORY_REG_SHORT_TEST_STATE, 0x03);
if (ret < 0) {
FTS_TEST_SAVE_ERR("write idle to short test state fail\n");
}
if (tmp_result) {
*test_result = true;
FTS_TEST_SAVE_INFO("------ Short Circuit Test PASS\n");
} else {
*test_result = false;
FTS_TEST_SAVE_INFO("------ Short Circuit Test NG\n");
}
/* save test data */
fts_test_save_data("Short Circuit Test", CODE_SHORT_TEST,
adcdata, 0, false, false, *test_result);
FTS_TEST_FUNC_EXIT();
return ret;
}
static int ft8756_open_test(struct fts_test *tdata, bool *test_result)
{
int ret = 0;
int i = 0;
bool tmp_result = false;
u8 state = 0;
int byte_num = 0;
int min = 0;
int max = 0;
u8 k1 = 0;
u8 k2 = 0;
int *opendata = NULL;
struct incell_threshold *thr = &tdata->ic.incell.thr;
FTS_TEST_FUNC_ENTER();
FTS_TEST_SAVE_INFO("\n============ Test Item: Open Test\n");
memset(tdata->buffer, 0, tdata->buffer_length);
opendata = tdata->buffer;
ret = enter_factory_mode();
if (ret < 0) {
FTS_TEST_SAVE_ERR("enter factory mode fail,ret=%d\n", ret);
goto test_err;
}
if (thr->basic.open_k1_check) {
ret = fts_test_read_reg(FACTORY_REG_K1, &k1);
if (ret < 0) {
FTS_TEST_SAVE_ERR("read k1 fail\n");
goto test_err;
}
}
if (thr->basic.open_k2_check) {
ret = fts_test_read_reg(FACTORY_REG_K2, &k2);
if (ret < 0) {
FTS_TEST_SAVE_ERR("read k2 fail\n");
goto restore_reg;
}
}
if (thr->basic.open_k1_check) {
ret = fts_test_write_reg(FACTORY_REG_K1, thr->basic.open_k1_value);
if (ret < 0) {
FTS_TEST_SAVE_ERR("write reg k1 fail\n");
goto restore_reg;
}
}
if (thr->basic.open_k2_check) {
ret = fts_test_write_reg(FACTORY_REG_K2, thr->basic.open_k2_value);
if (ret < 0) {
FTS_TEST_SAVE_ERR("write reg k2 fail\n");
goto restore_reg;
}
}
ret = fts_test_write_reg(FACTORY_REG_OPEN_START, 0x01);
if (ret < 0) {
FTS_TEST_SAVE_ERR("start open test fail\n");
goto restore_reg;
}
/* check test status */
for (i = 0; i < FACTORY_TEST_RETRY; i++) {
sys_delay(FACTORY_TEST_RETRY_DELAY);
ret = fts_test_read_reg(FACTORY_REG_OPEN_STATE, &state);
if ((ret >= 0) && (TEST_RETVAL_AA == state)) {
break;
} else {
FTS_TEST_DBG("reg%x=%x,retry:%d\n",
FACTORY_REG_OPEN_STATE, state, i);
}
}
if (i >= FACTORY_TEST_RETRY) {
FTS_TEST_SAVE_ERR("open test timeout\n");
goto restore_reg;
}
/* get cb data */
byte_num = tdata->node.node_num;
ret = get_cb_incell(0, byte_num, opendata);
if (ret) {
FTS_TEST_SAVE_ERR("get CB fail\n");
goto restore_reg;
}
/* save */
show_data(opendata, false);
/* compare */
min = thr->basic.open_cb_min;
max = TEST_OPEN_MAX_VALUE;
tmp_result = compare_data(opendata, min, max, 0, 0, false);
restore_reg:
/* Restore reg */
if (thr->basic.open_k1_check) {
ret = fts_test_write_reg(FACTORY_REG_K1, k1);
if (ret < 0) {
FTS_TEST_SAVE_ERR("restore reg k1 fail\n");
}
}
if (thr->basic.open_k2_check) {
ret = fts_test_write_reg(FACTORY_REG_K2, k2);
if (ret < 0) {
FTS_TEST_SAVE_ERR("restore reg k2 fail\n");
}
}
/* auto clb */
ret = chip_clb();
if (ret < 0) {
FTS_TEST_SAVE_ERR("auto clb fail\n");
}
test_err:
ret = fts_test_write_reg(FACTORY_REG_OPEN_STATE, 0x03);
if (ret < 0) {
FTS_TEST_SAVE_ERR("write idle to open test state fail\n");
}
if (tmp_result) {
*test_result = true;
FTS_TEST_SAVE_INFO("------ Open Test PASS\n");
} else {
*test_result = false;
FTS_TEST_SAVE_INFO("------ Open Test NG\n");
}
/*save test data*/
fts_test_save_data("Open Test", CODE_OPEN_TEST,
opendata, 0, false, false, *test_result);
FTS_TEST_FUNC_EXIT();
return ret;
}
static int ft8756_cb_test(struct fts_test *tdata, bool *test_result)
{
int ret = 0;
bool tmp_result = false;
int byte_num = 0;
int *cbdata = NULL;
struct incell_threshold *thr = &tdata->ic.incell.thr;
FTS_TEST_FUNC_ENTER();
FTS_TEST_SAVE_INFO("\n============ Test Item: CB Test\n");
memset(tdata->buffer, 0, tdata->buffer_length);
cbdata = tdata->buffer;
if (!thr->cb_min || !thr->cb_max || !test_result) {
FTS_TEST_SAVE_ERR("cb_min/max test_result is null\n");
ret = -EINVAL;
goto test_err;
}
ret = enter_factory_mode();
if (ret < 0) {
FTS_TEST_SAVE_ERR("enter factory mode fail,ret=%d\n", ret);
goto test_err;
}
/* cb test enable */
ret = fts_test_write_reg(FACTORY_REG_CB_TEST_EN, 0x01);
if (ret < 0) {
FTS_TEST_SAVE_ERR("cb test enable fail\n");
goto test_err;
}
/* auto clb */
ret = chip_clb();
if (ret < 0) {
FTS_TEST_SAVE_ERR("auto clb fail\n");
goto test_err;
}
byte_num = tdata->node.node_num;
ret = get_cb_incell(0, byte_num, cbdata);
if (ret < 0) {
FTS_TEST_SAVE_ERR("get cb fail\n");
goto test_err;
}
/* save */
show_data(cbdata, false);
/* compare */
tmp_result = compare_array(cbdata, thr->cb_min, thr->cb_max, false);
test_err:
/* cb test disable */
ret = fts_test_write_reg(FACTORY_REG_CB_TEST_EN, 0x00);
if (ret < 0) {
FTS_TEST_SAVE_ERR("cb test disable fail\n");
}
if (tmp_result) {
*test_result = true;
FTS_TEST_SAVE_INFO("------ CB Test PASS\n");
} else {
*test_result = false;
FTS_TEST_SAVE_INFO("------ CB Test NG\n");
}
/*save test data*/
fts_test_save_data("CB Test", CODE_CB_TEST,
cbdata, 0, false, false, *test_result);
FTS_TEST_FUNC_EXIT();
return ret;
}
static int ft8756_rawdata_test(struct fts_test *tdata, bool *test_result)
{
int ret = 0;
bool tmp_result = false;
int *rawdata = NULL;
struct incell_threshold *thr = &tdata->ic.incell.thr;
FTS_TEST_FUNC_ENTER();
FTS_TEST_SAVE_INFO("\n============ Test Item: RawData Test\n");
memset(tdata->buffer, 0, tdata->buffer_length);
rawdata = tdata->buffer;
if (!thr->rawdata_min || !thr->rawdata_max || !test_result) {
FTS_TEST_SAVE_ERR("rawdata_min/max test_result is null\n");
ret = -EINVAL;
goto test_err;
}
ret = enter_factory_mode();
if (ret < 0) {
FTS_TEST_SAVE_ERR("enter factory mode fail,ret=%d\n", ret);
goto test_err;
}
/* rawdata test enable */
ret = fts_test_write_reg(FACTORY_REG_RAWDATA_TEST_EN, 0x01);
if (ret < 0) {
FTS_TEST_SAVE_ERR("rawdata test enable fail\n");
goto test_err;
}
/* read rawdata */
ret = get_rawdata(rawdata);
if (ret < 0) {
FTS_TEST_SAVE_ERR("get RawData fail,ret=%d\n", ret);
goto test_err;
}
/* save */
show_data(rawdata, false);
/* compare */
tmp_result = compare_array(rawdata,
thr->rawdata_min,
thr->rawdata_max,
false);
ret = 0;
test_err:
/* rawdata test disble */
ret = fts_test_write_reg(FACTORY_REG_RAWDATA_TEST_EN, 0x00);
if (ret < 0) {
FTS_TEST_SAVE_ERR("rawdata test disable fail\n");
}
if (tmp_result) {
*test_result = true;
FTS_TEST_SAVE_INFO("------ RawData Test PASS\n");
} else {
*test_result = false;
FTS_TEST_SAVE_INFO("------ RawData Test NG\n");
}
/*save test data*/
fts_test_save_data("RawData Test", CODE_RAWDATA_TEST,
rawdata, 0, false, false, *test_result);
FTS_TEST_FUNC_EXIT();
return ret;
}
static int ft8756_lcdnoise_test(struct fts_test *tdata, bool *test_result)
{
int ret = 0;
int i = 0;
bool tmp_result = false;
u8 old_mode = 0;
u8 status = 0;
int byte_num = 0;
int frame_num = 0;
int max = 0;
int *lcdnoise = NULL;
struct incell_threshold *thr = &tdata->ic.incell.thr;
FTS_TEST_FUNC_ENTER();
FTS_TEST_SAVE_INFO("\n============ Test Item: LCD Noise Test\n");
memset(tdata->buffer, 0, tdata->buffer_length);
lcdnoise = tdata->buffer;
ret = enter_factory_mode();
if (ret < 0) {
FTS_TEST_SAVE_ERR("enter factory mode fail,ret=%d\n", ret);
goto test_err;
}
ret = fts_test_read_reg(FACTORY_REG_DATA_SELECT, &old_mode);
if (ret < 0) {
FTS_TEST_SAVE_ERR("read reg06 fail\n");
goto test_err;
}
ret = fts_test_write_reg(FACTORY_REG_DATA_SELECT, 0x01);
if (ret < 0) {
FTS_TEST_SAVE_ERR("write 1 to reg06 fail\n");
goto test_err;
}
ret = fts_test_write_reg(FACTORY_REG_LINE_ADDR, 0xAD);
if (ret < 0) {
FTS_TEST_SAVE_ERR("write reg01 fail\n");
goto test_err;
}
frame_num = thr->basic.lcdnoise_frame;
ret = fts_test_write_reg(FACTORY_REG_LCD_NOISE_FRAME, frame_num / 4);
if (ret < 0) {
FTS_TEST_SAVE_INFO("write frame num fail\n");
goto test_err;
}
/* start test */
ret = fts_test_write_reg(FACTORY_REG_LCD_NOISE_START, 0x01);
if (ret < 0) {
FTS_TEST_SAVE_INFO("start lcdnoise test fail\n");
goto test_err;
}
/* check test status */
sys_delay(frame_num * FACTORY_TEST_DELAY / 2);
for (i = 0; i < FACTORY_TEST_RETRY; i++) {
status = 0xFF;
ret = fts_test_read_reg(FACTORY_REG_LCD_NOISE_TEST_STATE, &status);
if ((ret >= 0) && (TEST_RETVAL_AA == status)) {
break;
} else {
FTS_TEST_DBG("reg%x=%x,retry:%d\n",
FACTORY_REG_LCD_NOISE_TEST_STATE, status, i);
}
sys_delay(FACTORY_TEST_RETRY_DELAY);
}
if (i >= FACTORY_TEST_RETRY) {
FTS_TEST_SAVE_ERR("lcdnoise test timeout\n");
goto test_err;
}
/* read lcdnoise */
byte_num = tdata->node.node_num * 2;
ret = read_mass_data(FACTORY_REG_RAWDATA_ADDR, byte_num, lcdnoise);
if (ret < 0) {
FTS_TEST_SAVE_ERR("read rawdata fail\n");
goto test_err;
}
/* save */
show_data(lcdnoise, false);
/* compare */
max = thr->basic.lcdnoise_coefficient * tdata->va_touch_thr * 32 / 100;
FTS_TEST_DBG("touch thr:%d, max:%d", tdata->va_touch_thr, max);
tmp_result = compare_data(lcdnoise, 0, max, 0, 0, false);
test_err:
ret = fts_test_write_reg(FACTORY_REG_LCD_NOISE_START, 0x00);
if (ret < 0) {
FTS_TEST_SAVE_ERR("write 0 to reg11 fail\n");
}
ret = fts_test_write_reg(FACTORY_REG_DATA_SELECT, old_mode);
if (ret < 0) {
FTS_TEST_SAVE_ERR("restore reg06 fail\n");
}
ret = fts_test_write_reg(FACTORY_REG_LCD_NOISE_TEST_STATE, 0x03);
if (ret < 0) {
FTS_TEST_SAVE_ERR("write idle to lcdnoise test state fail\n");
}
if (tmp_result) {
*test_result = true;
FTS_TEST_SAVE_INFO("------ LCD Noise Test PASS\n");
} else {
*test_result = false;
FTS_TEST_SAVE_INFO("------ LCD Noise Test NG\n");
}
/*save test data*/
fts_test_save_data("LCD Noise Test", CODE_LCD_NOISE_TEST,
lcdnoise, 0, false, false, *test_result);
FTS_TEST_FUNC_EXIT();
return ret;
}
static int start_test_ft8756(void)
{
int ret = 0;
struct fts_test *tdata = fts_ftest;
struct incell_testitem *test_item = &tdata->ic.incell.u.item;
bool temp_result = false;
bool test_result = true;
FTS_TEST_FUNC_ENTER();
FTS_TEST_INFO("test item:0x%x", fts_ftest->ic.incell.u.tmp);
if (!tdata || !tdata->testresult || !tdata->buffer) {
FTS_TEST_ERROR("tdata is null");
return -EINVAL;
}
/* short test */
if (true == test_item->short_test) {
ret = ft8756_short_test(tdata, &temp_result);
if ((ret < 0) || (false == temp_result)) {
test_result = false;
}
}
/* open test */
if (true == test_item->open_test) {
ret = ft8756_open_test(tdata, &temp_result);
if ((ret < 0) || (false == temp_result)) {
test_result = false;
}
}
/* cb test */
if (true == test_item->cb_test) {
ret = ft8756_cb_test(tdata, &temp_result);
if ((ret < 0) || (false == temp_result)) {
test_result = false;
}
}
/* rawdata test */
if (true == test_item->rawdata_test) {
ret = ft8756_rawdata_test(tdata, &temp_result);
if ((ret < 0) || (false == temp_result)) {
test_result = false;
}
}
/* lcd noise test */
if (true == test_item->lcdnoise_test) {
ret = ft8756_lcdnoise_test(tdata, &temp_result);
if ((ret < 0) || (false == temp_result)) {
test_result = false;
}
}
return test_result;
}
struct test_funcs test_func_ft8756 = {
.ctype = {0x15, 0x18},
.hwtype = IC_HW_INCELL,
.key_num_total = 0,
.start_test = start_test_ft8756,
};