input: touchscreen: support tp chipone_9551r

Signed-off-by: Binyuan Lan <lby@rock-chips.com>
Change-Id: Ia62dfe3670af23c69f857ab0fcc251607187974d
This commit is contained in:
Binyuan Lan
2024-01-28 03:13:43 +00:00
committed by Tao Huang
parent d21a7378aa
commit 44f70fc15b
32 changed files with 22949 additions and 0 deletions

View File

@@ -198,6 +198,8 @@ config TOUCHSCREEN_CHIPONE_ICN8505
To compile this driver as a module, choose M here: the
module will be called chipone_icn8505.
source "drivers/input/touchscreen/chipone_tddi/Kconfig"
config TOUCHSCREEN_CY8CTMA140
tristate "cy8ctma140 touchscreen"
depends on I2C

View File

@@ -22,6 +22,7 @@ obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o
obj-$(CONFIG_TOUCHSCREEN_BU21029) += bu21029_ts.o
obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8318) += chipone_icn8318.o
obj-$(CONFIG_TOUCHSCREEN_CHIPONE_ICN8505) += chipone_icn8505.o
obj-$(CONFIG_TOUCHSCREEN_CHIPONE_9551R) += chipone_tddi/
obj-$(CONFIG_TOUCHSCREEN_CY8CTMA140) += cy8ctma140.o
obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o
obj-$(CONFIG_TOUCHSCREEN_CYTTSP_CORE) += cyttsp_core.o

View File

@@ -0,0 +1,12 @@
# SPDX-License-Identifier: GPL-2.0-or-later
#
# chipone Touchscreen driver configuration
#
config TOUCHSCREEN_CHIPONE_9551R
tristate "chipone Touchscreen"
depends on I2C
default n
help
Say Y here if you have chipone touch panel.
If unsure, say N.

View File

@@ -0,0 +1,17 @@
# SPDX-License-Identifier: GPL-2.0-or-later
obj-$(CONFIG_TOUCHSCREEN_CHIPONE_9551R) += chipone-ts.o
chipone-ts-y += cts_driver.o
chipone-ts-y += cts_core.o
chipone-ts-y += cts_sfctrlv2.o
chipone-ts-y += cts_spi_flash.o
chipone-ts-y += cts_firmware.o
chipone-ts-y += cts_test.o
chipone-ts-y += cts_charger_detect.o
chipone-ts-y += cts_earjack_detect.o
chipone-ts-y += cts_tcs.o
chipone-ts-y += cts_platform.o
chipone-ts-y += cts_tool.o
chipone-ts-y += cts_sysfs.o
chipone-ts-y += cts_strerror.o
chipone-ts-y += cts_oem.o

View File

@@ -0,0 +1,25 @@
// SPDX-License-Identifier: GPL-2.0-or-later
static u8 icnl9951_driver_builtin_firmware[] = {
};
static u8 icnl9951r_driver_builtin_firmware[] = {
};
static struct cts_firmware cts_driver_builtin_firmwares[] = {
{
.name = "OEM-Project", /* MUST set non-NULL */
.hwid = CTS_DEV_HWID_ICNL9951,
.fwid = CTS_DEV_FWID_ICNL9951,
.data = icnl9951_driver_builtin_firmware,
.size = ARRAY_SIZE(icnl9951_driver_builtin_firmware),
},
{
.name = "OEM-Project", /* MUST set non-NULL */
.hwid = CTS_DEV_HWID_ICNL9951R,
.fwid = CTS_DEV_FWID_ICNL9951R,
.data = icnl9951r_driver_builtin_firmware,
.size = ARRAY_SIZE(icnl9951r_driver_builtin_firmware),
},
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,45 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef CTS_CHARGER_DETECT_H
#define CTS_CHARGER_DETECT_H
#include "cts_config.h"
struct chipone_ts_data;
#ifdef CONFIG_CTS_CHARGER_DETECT
extern int cts_charger_detect_init(struct chipone_ts_data *cts_data);
extern int cts_charger_detect_deinit(struct chipone_ts_data *cts_data);
extern int cts_start_charger_detect(struct chipone_ts_data *cts_data);
extern int cts_stop_charger_detect(struct chipone_ts_data *cts_data);
extern int cts_is_charger_attached(struct chipone_ts_data *cts_data,
bool *attached);
#else /* CONFIG_CTS_CHARGER_DETECT */
static inline int cts_charger_detect_init(struct chipone_ts_data *cts_data)
{
return -ENOTSUPP;
}
static inline int cts_charger_detect_deinit(struct chipone_ts_data *cts_data)
{
return -ENOTSUPP;
}
static inline int cts_start_charger_detect(struct chipone_ts_data *cts_data)
{
return -ENODEV;
}
static inline int cts_stop_charger_detect(struct chipone_ts_data *cts_data)
{
return -ENODEV;
}
static inline int cts_is_charger_attached(struct chipone_ts_data *cts_data,
bool *attached)
{
return -ENODEV;
}
#endif /* CONFIG_CTS_CHARGER_DETECT */
#endif /* CTS_CHARGER_DETECT_H */

View File

@@ -0,0 +1,242 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef CTS_CONFIG_H
#define CTS_CONFIG_H
/** Driver version */
#define CFG_CTS_DRIVER_MAJOR_VERSION 3
#define CFG_CTS_DRIVER_MINOR_VERSION 6
#define CFG_CTS_DRIVER_PATCH_VERSION 3
#define CFG_CTS_DRIVER_VERSION "v3.6.3"
/* Support Mediatek TPD arch */
/* #define CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED */
/* Support Spreadtrum platform */
#define CFG_CTS_PLATFORM_SPRD_SUPPORTED
/* Support cascade application */
//#define CFG_CTS_CASCADE_SUPPORTED
/* Support RK dsi extcon notifier for suspend and resume */
#define CONFIG_PM_DSI_EXTCON_NOTIFIER
/* Support both finger and stylus protocol, 11 */
// #define CFG_CTS_FINGER_STYLUS_SUPPORTED
/* #define CFG_CTS_STYLUS_BTN_SUPPORTED */
#define CONFIG_CTS_I2C_HOST
/* For Goole Security */
#define CFG_CTS_FOR_GKI
/** Whether reset pin is used */
#define CFG_CTS_HAS_RESET_PIN
#ifndef CONFIG_CTS_I2C_HOST
#ifndef CFG_CTS_HAS_RESET_PIN
#define CFG_CTS_HAS_RESET_PIN
#endif
#define CFG_CTS_SPI_SPEED_KHZ 9600
#endif /* CONFIG_CTS_I2C_HOST */
/* #define CFG_CTS_FORCE_UP */
/* #define CFG_CTS_HEARTBEAT_MECHANISM */
/* #define CFG_CTS_PALM_DETECT */
#ifdef CFG_CTS_PALM_DETECT
#define CFG_CTS_PALM_EVENT 240
#define CFG_CTS_PALM_ID 0x80
#endif
#define CONFIG_GENERIC_HARDIRQS
/** Whether force download firmware to chip */
/* #define CFG_CTS_FIRMWARE_FORCE_UPDATE */
/** Use build in firmware or firmware file in fs*/
#define CFG_CTS_DRIVER_BUILTIN_FIRMWARE
#define CFG_CTS_FIRMWARE_IN_FS
#ifdef CFG_CTS_FIRMWARE_IN_FS
/* #define CFG_CTS_FW_UPDATE_SYS */
#define CFG_CTS_FIRMWARE_FILENAME "chipone_firmware.bin"
#endif /* CFG_CTS_FIRMWARE_IN_FS */
#define CFG_CTS_FIRMWARE_SIZE (120 * 1024)
#define CFG_CTS_FACTORY_LIMIT_FILENAME "chipone_limit.bin"
/* IC type support */
#define CFG_CTS_CHIP_NAME "CHIPONE-TDDI"
#ifdef CONFIG_PROC_FS
/* Proc FS for backward compatibility for APK tool com.ICN85xx */
#define CONFIG_CTS_LEGACY_TOOL
#endif /* CONFIG_PROC_FS */
#ifdef CONFIG_SYSFS
/* Sys FS for gesture report, debug feature etc. */
#define CONFIG_CTS_SYSFS
#endif /* CONFIG_SYSFS */
#define CFG_CTS_MAX_TOUCH_NUM (10)
#define CFG_CTS_MAX_STYLUS_NUM (4)
/* Virtual key support */
/* #define CONFIG_CTS_VIRTUALKEY */
#ifdef CONFIG_CTS_VIRTUALKEY
#define CFG_CTS_MAX_VKEY_NUM (4)
#define CFG_CTS_NUM_VKEY (3)
#define CFG_CTS_VKEY_KEYCODES {KEY_BACK, KEY_HOME, KEY_MENU}
#endif /* CONFIG_CTS_VIRTUALKEY */
/* Gesture wakeup */
#define CFG_CTS_GESTURE
#ifdef CFG_CTS_GESTURE
#define GESTURE_UP 0x11
#define GESTURE_C 0x12
#define GESTURE_O 0x13
#define GESTURE_M 0x14
#define GESTURE_W 0x15
#define GESTURE_E 0x16
#define GESTURE_S 0x17
#define GESTURE_Z 0x1d
#define GESTURE_V 0x1e
#define GESTURE_D_TAP 0x50
#define GESTURE_DOWN 0x22
#define GESTURE_LEFT 0x23
#define GESTURE_RIGHT 0x24
#define GESTURE_TAP 0x7f
#define CFG_CTS_NUM_GESTURE (14u)
#define CFG_CTS_GESTURE_REPORT_KEY
#define CFG_CTS_GESTURE_KEYMAP \
{ \
{ GESTURE_C, KEY_C,}, \
{ GESTURE_W, KEY_W,}, \
{ GESTURE_V, KEY_V,}, \
{ GESTURE_D_TAP, KEY_F1,}, \
{ GESTURE_Z, KEY_Z,}, \
{ GESTURE_M, KEY_M,}, \
{ GESTURE_O, KEY_O,}, \
{ GESTURE_E, KEY_E,}, \
{ GESTURE_S, KEY_S,}, \
{ GESTURE_UP, KEY_UP,}, \
{ GESTURE_DOWN, KEY_DOWN,}, \
{ GESTURE_LEFT, KEY_LEFT,}, \
{ GESTURE_RIGHT, KEY_RIGHT,}, \
{ GESTURE_TAP, KEY_F2,}, \
}
#define CFG_CTS_GESTURE_REPORT_TRACE 0
#endif /* CFG_CTS_GESTURE */
#define CONFIG_CTS_GLOVE
//#define CONFIG_CTS_EARJACK_DETECT
//#define CONFIG_CTS_CHARGER_DETECT
/* #define CONFIG_CTS_TP_PROXIMITY */
/* ESD protection */
//#define CONFIG_CTS_ESD_PROTECTION
#ifdef CONFIG_CTS_ESD_PROTECTION
#define CFG_CTS_ESD_PROTECTION_CHECK_PERIOD (2 * HZ)
#define CFG_CTS_ESD_FAILED_CONFIRM_CNT 3
#endif /* CONFIG_CTS_ESD_PROTECTION */
/* Use slot protocol (protocol B), comment it if use protocol A. */
#define CONFIG_CTS_SLOTPROTOCOL
/* #define CTS_CONFIG_MKDIR_FOR_CTS_TEST */
#ifdef CONFIG_CTS_LEGACY_TOOL
#define CFG_CTS_TOOL_PROC_FILENAME "cts_tool"
#endif /* CONFIG_CTS_LEGACY_TOOL */
#define CFG_CTS_UPDATE_CRCCHECK
#ifdef CONFIG_OF
#define CONFIG_CTS_OF
#endif
#ifdef CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED
/****************************************************************************
* MTK Platform configurations
****************************************************************************/
#ifdef CONFIG_MTK_I2C_EXTENSION
#define TPD_SUPPORT_I2C_DMA
#define CFG_CTS_MAX_I2C_XFER_SIZE (250)
#define CFG_CTS_MAX_I2C_FIFO_XFER_SIZE (8)
#else
#define CFG_CTS_MAX_I2C_XFER_SIZE (128)
#endif /* CONFIG_MTK_I2C_EXTENSION */
#define CFG_CTS_MAX_I2C_READ_SIZE (8192u)
#define CFG_CTS_MAX_SPI_XFER_SIZE (8192u)
#define CFG_CTS_INT_DATA_MAX_SIZE (8192u)
#define CTS_FW_LOG_REDIRECT_SIGN 0x60
#define CTS_FW_LOG_BUF_LEN 128
//#define CFG_MTK_LEGEND_PLATFORM
#define CFG_CTS_DEVICE_NAME TPD_DEVICE
#define CFG_CTS_DRIVER_NAME "chipone-tddi"
#ifdef CONFIG_CTS_OF
#define CFG_CTS_OF_DEVICE_ID_NAME "mediatek,cap_touch"
#endif /* CONFIG_CTS_OF */
#else /* CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED */
/****************************************************************************
* QCOM Platform configurations
****************************************************************************/
#ifndef CFG_CTS_PLATFORM_SPRD_SUPPORTED
#define CONFIG_CTS_PM_FB_NOTIFIER
#endif
#ifdef CONFIG_CTS_PM_FB_NOTIFIER
#ifdef CONFIG_DRM
#define CFG_CTS_DRM_NOTIFIER
#endif /*CONFIG_DRM */
#else /*CONFIG_CTS_PM_FB_NOTIFIER */
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PM_SUSPEND)
/* #define CONFIG_CTS_PM_GENERIC */
#endif /* CONFIG_PM_SLEEP */
#ifndef CONFIG_CTS_PM_GENERIC
#define CONFIG_CTS_PM_LEGACY
#endif /*CONFIG_CTS_PM_GENERIC */
#endif /*CONFIG_CTS_PM_FB_NOTIFIER */
#define CFG_CTS_MAX_I2C_XFER_SIZE (48u)
#define CFG_CTS_MAX_I2C_READ_SIZE (8192u)
#define CFG_CTS_MAX_SPI_XFER_SIZE (8192u)
#define CFG_CTS_INT_DATA_MAX_SIZE (8192u)
#define CTS_FW_LOG_REDIRECT_SIGN 0x60
#define CTS_FW_LOG_BUF_LEN 128
#define CFG_CTS_DEVICE_NAME "chipone-tddi"
#define CFG_CTS_DRIVER_NAME "chipone-tddi"
#ifdef CONFIG_CTS_OF
#define CFG_CTS_OF_DEVICE_ID_NAME "chipone-tddi"
#define CFG_CTS_OF_INT_GPIO_NAME "chipone,irq-gpio"
#define CFG_CTS_OF_RST_GPIO_NAME "chipone,rst-gpio"
#ifdef CFG_CTS_MANUAL_CS
#define CFG_CTS_OF_CS_GPIO_NAME "chipone,cs-gpio"
#endif
#define CFG_CTS_OF_X_RESOLUTION_NAME "chipone,x-res"
#define CFG_CTS_OF_Y_RESOLUTION_NAME "chipone,y-res"
#ifdef CFG_CTS_FW_UPDATE_SYS
#define CFG_CTS_OF_PANEL_SUPPLIER "chipone,panel-supplier"
#endif
#endif /* CONFIG_CTS_OF */
#endif /* CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED */
#endif /* CTS_CONFIG_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,988 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef CTS_CORE_H
#define CTS_CORE_H
#include "cts_config.h"
enum cts_dev_hw_reg {
CTS_DEV_HW_REG_HARDWARE_ID = 0x70000u,
CTS_DEV_HW_REG_CLOCK_GATING = 0x70004u,
CTS_DEV_HW_REG_RESET_CONFIG = 0x70008u,
CTS_DEV_HW_REG_SW_RST_CTRL = 0x7000Au,
CTS_DEV_HW_REG_BOOT_MODE = 0x70010u,
CTS_DEV_HW_REG_CURRENT_MODE = 0x70011u,
CTS_DEV_HW_REG_DDI_REG_CTRL = 0x7002Cu,
CTS_DEV_HW_REG_CLK_DIV_CFG = 0x70033u,
CTS_DEV_HW_REG_HPPROG = 0x70074u,
CTS_DEV_HW_REG_SET_RESET = 0x700F8u,
CTS_DEV_HW_REG_HW_STATUS = 0x7401Bu,
CTS_DEV_HW_REG_I2C_CFG = 0x77001u,
CTS_DEV_HW_REG_SPI_CFG = 0x78438u,
};
enum cts_dev_boot_mode {
CTS_DEV_BOOT_MODE_IDLE = 0,
CTS_DEV_BOOT_MODE_FLASH = 1,
CTS_DEV_BOOT_MODE_I2C_PRG_9911C = 2,
CTS_DEV_BOOT_MODE_TCH_PRG_9916 = 2,
CTS_DEV_BOOT_MODE_SRAM = 3,
CTS_DEV_BOOT_MODE_DDI_PRG = 4,
CTS_DEV_BOOT_MODE_SPI_PRG_9911C = 5,
CTS_DEV_BOOT_MODE_MASK = 7,
};
/* ICNL9951/ICNL9951R */
#define CTS_PWR_MODE_ACTIVE (0x00)
#define CTS_PWR_MODE_MNT (0x01)
#define CTS_PWR_MODE_HIBERNATE (0x02)
#define CTS_PWR_MODE_GSTR_WAKEUP (0x03)
#define CTS_PWR_MODE_MNT_DBG (0x04)
#define CTS_PWR_MODE_GSTR_DBG (0x05)
#define CTS_PWR_MODE_WAIT_TO_HIBERNATE (0x06)
#define CTS_PWR_MODE_WAIT_TO_GSTR (0x07)
//Krang work mode value
#define CTS_KRANG_NORMAL_MODE (0x00)
#define CTS_KRANG_STY_DBG_MODE (0x01)
#define CTS_KRANG_FIN_DBG_MODE (0x02)
#define CTS_KRANG_MNT_DBG_MODE (0x03)
#define CTS_KRANG_GS_DBG_MODE (0x04)
#define CTS_KRANG_OPEN_SHORT_DET_MODE (0x05)
#define CTS_KRANG_CFG_MODE (0x06)
#define CTS_KRANG_TEST_MODE (0x07)
#define CTS_KRANG_DEF_MODE (0x08)
/** I2C addresses(7bits), transfer size and bitrate */
#define CTS_DEV_NORMAL_MODE_I2CADDR (0x48)
#define CTS_DEV_PROGRAM_MODE_I2CADDR (0x30)
#define CTS_DEV_NORMAL_MODE_ADDR_WIDTH (2)
#define CTS_DEV_PROGRAM_MODE_ADDR_WIDTH (3)
#define CTS_DEV_NORMAL_MODE_SPIADDR (0xF0)
#define CTS_DEV_PROGRAM_MODE_SPIADDR (0x60)
/** Chipone firmware register addresses under normal mode */
enum cts_device_fw_reg {
CTS_DEVICE_FW_REG_WORK_MODE = 0x0000,
CTS_DEVICE_FW_REG_SYS_BUSY = 0x0001,
CTS_DEVICE_FW_REG_DATA_READY = 0x0002,
CTS_DEVICE_FW_REG_CMD = 0x0004,
CTS_DEVICE_FW_REG_POWER_MODE = 0x0005,
CTS_DEVICE_FW_REG_FW_LIB_MAIN_VERSION = 0x0009,
CTS_DEVICE_FW_REG_CHIP_TYPE = 0x000A,
CTS_DEVICE_FW_REG_VERSION = 0x000C,
CTS_DEVICE_FW_REG_DDI_VERSION = 0x0010,
CTS_DEVICE_FW_REG_GET_WORK_MODE = 0x003F,
CTS_DEVICE_FW_REG_FW_LIB_SUB_VERSION = 0x0047,
CTS_DEVICE_FW_REG_COMPENSATE_CAP_READY = 0x004E,
CTS_DEVICE_FW_REG_TOUCH_INFO = 0x1000,
CTS_DEVICE_FW_REG_RAW_DATA = 0x2000,
CTS_DEVICE_FW_REG_DIFF_DATA = 0x3000,
CTS_DEVICE_FW_REG_GESTURE_INFO = 0x7000,
CTS_DEVICE_FW_REG_PANEL_PARAM = 0x8000,
CTS_DEVICE_FW_REG_NUM_TX = 0x8007,
CTS_DEVICE_FW_REG_NUM_RX = 0x8008,
CTS_DEVICE_FW_REG_INT_KEEP_TIME = 0x8047,
CTS_DEVICE_FW_REG_RAWDATA_TARGET = 0x8049,
CTS_DEVICE_FW_REG_X_RESOLUTION = 0x8090,
CTS_DEVICE_FW_REG_Y_RESOLUTION = 0x8092,
CTS_DEVICE_FW_REG_SWAP_AXES = 0x8094,
CTS_DEVICE_FW_REG_GLOVE_MODE = 0x8095,
CTS_DEVICE_FW_REG_TEST_WITH_DISPLAY_ON = 0x80A3,
CTS_DEVICE_FW_REG_INT_MODE = 0x80D8,
CTS_DEVICE_FW_REG_EARJACK_DETECT_SUPP = 0x8113,
CTS_DEVICE_FW_REG_AUTO_COMPENSATE_EN = 0x8114,
CTS_DEVICE_FW_REG_ESD_PROTECTION = 0x8156,
CTS_DEVICE_FW_REG_FLAG_BITS = 0x8158,
CTS_DEVICE_FW_REG_COMPENSATE_CAP = 0xA000,
CTS_DEVICE_FW_REG_DEBUG_INTF = 0xF000,
};
/** Hardware IDs, read from hardware id register */
enum cts_dev_hwid {
CTS_DEV_HWID_ICNL9951 = 0x990510u,
CTS_DEV_HWID_ICNL9951R = 0x991510u,
CTS_DEV_HWID_ANY = 0,
CTS_DEV_HWID_INVALID = 0xFFFFFFFFu,
};
/* Firmware IDs, read from firmware register @ref CTS_DEV_FW_REG_CHIP_TYPE
* under normal mode
*/
enum cts_dev_fwid {
CTS_DEV_FWID_ICNL9951 = 0x9951u,
CTS_DEV_FWID_ICNL9951R = 0x99a3u,
CTS_DEV_FWID_ANY = 0u,
CTS_DEV_FWID_INVALID = 0xFFFFu
};
/** Commands written to firmware register @ref CTS_DEVICE_FW_REG_CMD under normal mode */
enum cts_firmware_cmd {
CTS_CMD_RESET = 1,
CTS_CMD_SUSPEND = 2,
CTS_CMD_ENTER_WRITE_PARA_TO_FLASH_MODE = 3,
CTS_CMD_WRITE_PARA_TO_FLASH = 4,
CTS_CMD_WRTITE_INT_HIGH = 5,
CTS_CMD_WRTITE_INT_LOW = 6,
CTS_CMD_RELASE_INT_TEST = 7,
CTS_CMD_RECOVERY_TX_VOL = 0x10,
CTS_CMD_DEC_TX_VOL_1 = 0x11,
CTS_CMD_DEC_TX_VOL_2 = 0x12,
CTS_CMD_DEC_TX_VOL_3 = 0x13,
CTS_CMD_DEC_TX_VOL_4 = 0x14,
CTS_CMD_DEC_TX_VOL_5 = 0x15,
CTS_CMD_DEC_TX_VOL_6 = 0x16,
CTS_CMD_ENABLE_READ_RAWDATA = 0x20,
CTS_CMD_DISABLE_READ_RAWDATA = 0x21,
CTS_CMD_SUSPEND_WITH_GESTURE = 0x40,
CTS_CMD_QUIT_GESTURE_MONITOR = 0x41,
CTS_CMD_CHARGER_ATTACHED = 0x55,
CTS_CMD_EARJACK_ATTACHED = 0x57,
CTS_CMD_EARJACK_DETACHED = 0x58,
CTS_CMD_CHARGER_DETACHED = 0x66,
CTS_CMD_ENABLE_FW_LOG_REDIRECT = 0x86,
CTS_CMD_DISABLE_FW_LOG_REDIRECT = 0x87,
CTS_CMD_ENABLE_READ_CNEG = 0x88,
CTS_CMD_DISABLE_READ_CNEG = 0x89,
CTS_CMD_FW_LOG_SHOW_FINISH = 0xE0,
#ifdef CONFIG_CTS_TP_PROXIMITY
CTS_CMD_PROXIMITY_STATUS = 0x80,
/* For vivo code, make a distinction between palm func and proximity func */
CTS_CMD_PROXIMITY_NEAR_VIVO = 0x30,
CTS_CMD_PROXIMITY_FAR_VIVO = 0x31,
#endif
};
#pragma pack(1)
/** Touch message read back from chip */
struct cts_device_touch_msg {
u8 event:4;
u8 id:4;
u8 xh:4;
u8 yh:4;
u8 xl;
u8 yl;
u8 pressure;
#define CTS_DEVICE_TOUCH_EVENT_NONE (0)
#define CTS_DEVICE_TOUCH_EVENT_DOWN (1)
#define CTS_DEVICE_TOUCH_EVENT_MOVE (2)
#define CTS_DEVICE_TOUCH_EVENT_STAY (3)
#define CTS_DEVICE_TOUCH_EVENT_UP (4)
};
/** Stylus message read back from chip */
struct cts_device_stylus_msg {
u8 event:4;
u8 id:4;
u8 tip_xh:4;
u8 tip_yh:4;
u8 tip_xl;
u8 tip_yl;
u8 ring_xh:4;
u8 ring_yh:4;
u8 ring_xl;
u8 ring_yl;
u8 battary;
u8 tilt;
u8 pressure_l;
u8 pressure_h:5;//use low 5 bits
u8 btn0:1;
u8 btn1:1;
u8 btn2:1;
u8 tiltx;
u8 tilty;
};
struct cts_firmware_status {
uint16_t charger:1;
uint16_t proximity:1;
uint16_t earjack:1;
uint16_t knuckle:1;
uint16_t glove:1;
uint16_t pocket:1;
uint16_t game:1;
uint16_t reserved:1;
uint16_t high_temperature:1;
uint16_t low_temperature:1;
uint16_t bend_mode:1;
uint16_t palm_status:1;
uint16_t noise_mode:1;
uint16_t base_trace:1;
uint16_t water_mode:1;
uint16_t ground:1;
};
/** Touch debug messages read back from chip [40 bytes] */
struct cts_touch_debug_msg {
u8 protocol_version;
u8 fw_version;
u32 reset_flag;
u16 frame_index;
u16 firmware_status;
u8 proximity;
u8 work_mode;
u8 power_mode;
u8 curr_freq;
u8 esd_0a_status;
u8 fw_esd_status;
u8 landscape_mode;
u16 curr_freq_noise;
u16 max_diff;
u8 max_diff_row;
u8 max_diff_col;
u16 max_neg_diff;
u8 max_neg_diff_row;
u8 max_neg_diff_col;
u8 data_method;
u8 data_type;
u8 reserved[11];
};
/** Touch information read back from chip */
struct cts_device_touch_info {
u8 vkey_state;
u8 num_msg:4;
#define PROTO_NORMAL 0x00
#define PROTO_COMPRESSED 0x01
u8 compressed_proto:2;
#define FINGER_ONLY 0x01
#define STYLUS_ONLY 0x02
#define FINGER_STYLUS 0x03
u8 finger_or_stylus:2;
u8 reserved0;
struct cts_device_touch_msg msgs[CFG_CTS_MAX_TOUCH_NUM];
u8 proximity;
u8 palm_major;
u8 palm_minor;
u8 palm_flags;
#ifdef CFG_CTS_FINGER_STYLUS_SUPPORTED
u8 stylus_num:4;
u8 stylus_vernum:4;
struct cts_device_stylus_msg smsgs[CFG_CTS_MAX_STYLUS_NUM];
u8 reserved1;
u8 reserved2;
#endif
};
struct cts_device_stylus_info {
u8 vkey_state;
u8 num_msg:4;
u8 compressed_proto:2;
u8 finger_or_stylus:2;
u8 reserved0;
u8 event_num:4;
u8 stylus_vernum:4;
struct cts_device_stylus_msg msgs[CFG_CTS_MAX_STYLUS_NUM];
u8 reserved1;
};
/** Gesture trace point read back from chip */
struct cts_device_gesture_point {
__le16 x;
__le16 y;
};
/** Gesture information read back from chip */
/* total size 112 bytes */
struct cts_device_gesture_info {
u8 gesture_id;
#define CTS_GESTURE_UP (0x11)
#define CTS_GESTURE_C (0x12)
#define CTS_GESTURE_O (0x13)
#define CTS_GESTURE_M (0x14)
#define CTS_GESTURE_W (0x15)
#define CTS_GESTURE_E (0x16)
#define CTS_GESTURE_S (0x17)
#define CTS_GESTURE_B (0x18)
#define CTS_GESTURE_T (0x19)
#define CTS_GESTURE_H (0x1A)
#define CTS_GESTURE_F (0x1B)
#define CTS_GESTURE_X (0x1C)
#define CTS_GESTURE_Z (0x1D)
#define CTS_GESTURE_V (0x1E)
#define CTS_GESTURE_D_TAP (0x50)
#define CTS_GESTURE_TAP (0x7F)
u8 num_points;
#define CTS_CHIP_MAX_GESTURE_TRACE_POINT (27u)
struct cts_device_gesture_point points[CTS_CHIP_MAX_GESTURE_TRACE_POINT];
u8 reserved[2];
};
struct cts_tcs_cmd {
uint16_t cmd_id : 8;
uint16_t class_id : 5;
uint16_t is_write : 1;
uint16_t is_read : 1;
uint16_t base_flag : 1;
};
#pragma pack()
struct cts_device;
enum cts_crc_type {
CTS_CRC16 = 1,
CTS_CRC32 = 2,
};
/** Chip hardware data, will never change */
struct cts_device_hwdata {
const char *name;
u32 hwid;
u16 fwid;
u8 num_row;
u8 num_col;
u32 sram_size;
/* Address width under program mode */
u8 program_addr_width;
const struct cts_sfctrl *sfctrl;
int (*enable_access_ddi_reg)(struct cts_device *cts_dev, bool enable);
};
enum int_data_type {
INT_DATA_TYPE_NONE = 0,
INT_DATA_TYPE_RAWDATA = BIT(0),
INT_DATA_TYPE_MANUAL_DIFF = BIT(1),
INT_DATA_TYPE_REAL_DIFF = BIT(2),
INT_DATA_TYPE_NOISE_DIFF = BIT(3),
INT_DATA_TYPE_BASEDATA = BIT(4),
INT_DATA_TYPE_CNEGDATA = BIT(5),
INT_DATA_TYPE_MASK = 0xF03F,
};
enum int_data_method {
INT_DATA_METHOD_NONE = 0,
INT_DATA_METHOD_HOST = 1,
INT_DATA_METHOD_POLLING = 2,
INT_DATA_METHOD_DEBUG = 3,
INT_DATA_METHOD_CNT = 4,
};
/** Chip firmware data */
struct cts_device_fwdata {
u16 version;
u16 res_x;
u16 res_y;
u8 rows;
u8 cols;
bool flip_x;
bool flip_y;
bool swap_axes;
u8 ddi_version;
u8 int_mode;
u8 esd_method;
u16 lib_version;
u16 int_keep_time;
u16 rawdata_target;
bool has_int_data;
u8 int_data_method;
u16 int_data_types;
size_t int_data_size;
u8 ic_application;
u8 pen_freq_num;
u8 cascade_num;
u8 pc_cols;
u8 pc_rows;
u8 pr_cols;
u8 pr_rows;
u8 pc_cols_used;
u8 pc_rows_used;
u8 pr_cols_used;
u8 pr_rows_used;
};
/** Chip runtime data */
struct cts_device_rtdata {
u8 slave_addr;
int addr_width;
bool program_mode;
bool has_flash;
bool suspended;
bool updating;
bool testing;
bool gesture_wakeup_enabled;
bool gesture_d_tap_enabled;
bool charger_exist;
bool fw_log_redirect_enabled;
bool glove_mode_enabled;
u8 esd_count;
u16 firmware_status;
struct cts_device_touch_info touch_info;
struct cts_device_gesture_info gesture_info;
#ifdef CONFIG_CTS_TP_PROXIMITY
bool proximity_status;
int proximity_num;
#endif
u16 tcscmd[ALIGN(PAGE_SIZE + 10, 4)];
int tcscmd_len;
u16 curr_cmd;
int curr_len;
};
struct cts_firmware {
const char *name; /* MUST set to non-NULL if driver builtin firmware */
u32 hwid;
u16 fwid;
u8 *data;
size_t size;
const struct firmware *fw;
};
struct cts_device {
struct cts_platform_data *pdata;
const struct cts_device_hwdata *hwdata;
struct cts_device_fwdata fwdata;
struct cts_device_rtdata rtdata;
struct cts_firmware *firmware;
const struct cts_flash *flash;
bool enabled;
u8 int_data[ALIGN(CFG_CTS_INT_DATA_MAX_SIZE + 10, 4)];
};
struct cts_platform_data;
struct chipone_ts_data {
#ifdef CONFIG_CTS_I2C_HOST
struct i2c_client *i2c_client;
#else
struct spi_device *spi_client;
#endif
struct device *device;
struct cts_device cts_dev;
struct cts_platform_data *pdata;
struct workqueue_struct *workqueue;
struct delayed_work fw_upgrade_work;
struct work_struct ts_resume_work;
#ifdef CONFIG_CTS_CHARGER_DETECT
void *charger_detect_data;
#endif
#ifdef CONFIG_CTS_EARJACK_DETECT
void *earjack_detect_data;
#endif
#ifdef CONFIG_CTS_ESD_PROTECTION
struct workqueue_struct *esd_workqueue;
struct delayed_work esd_work;
bool esd_enabled;
int esd_check_fail_cnt;
#endif
#ifdef CFG_CTS_HEARTBEAT_MECHANISM
struct workqueue_struct *heart_workqueue;
struct delayed_work heart_work;
#endif
#ifdef CONFIG_CTS_LEGACY_TOOL
struct proc_dir_entry *procfs_entry;
#endif
void *oem_data;
bool force_reflash;
// struct kobject *suspend_kobj;
#ifdef CONFIG_PM_DSI_EXTCON_NOTIFIER
struct extcon_dev *edev;
struct notifier_block extcon_nb;
#endif
};
/*static inline u32 get_unaligned_le24(const void *p)
{
const u8 *puc = (const u8 *)p;
return (puc[0] | (puc[1] << 8) | (puc[2] << 16));
}
static inline u32 get_unaligned_be24(const void *p)
{
const u8 *puc = (const u8 *)p;
return (puc[2] | (puc[1] << 8) | (puc[0] << 16));
}
static inline void put_unaligned_be24(u32 v, void *p)
{
u8 *puc = (u8 *) p;
puc[0] = (v >> 16) & 0xFF;
puc[1] = (v >> 8) & 0xFF;
puc[2] = (v >> 0) & 0xFF;
}*/
#define wrap(max, x) ((max) - 1 - (x))
extern void cts_lock_device(struct cts_device *cts_dev);
extern void cts_unlock_device(struct cts_device *cts_dev);
extern int cts_dev_readb(struct cts_device *cts_dev,
u32 addr, u8 *b, int retry, int delay);
extern int cts_dev_writeb(struct cts_device *cts_dev,
u32 addr, u8 b, int retry, int delay);
extern int cts_sram_writeb_retry(struct cts_device *cts_dev,
u32 addr, u8 b, int retry, int delay);
extern int cts_sram_writew_retry(struct cts_device *cts_dev,
u32 addr, u16 w, int retry, int delay);
extern int cts_sram_writel_retry(struct cts_device *cts_dev,
u32 addr, u32 l, int retry, int delay);
extern int cts_sram_writesb_retry(struct cts_device *cts_dev,
u32 addr, const void *src, size_t len, int retry, int delay);
extern int cts_sram_writesb_check_crc_retry(struct cts_device *cts_dev,
u32 addr, const void *src, size_t len, u32 crc, int retry);
extern int cts_sram_readb_retry(struct cts_device *cts_dev,
u32 addr, u8 *b, int retry, int delay);
extern int cts_sram_readw_retry(struct cts_device *cts_dev,
u32 addr, u16 *w, int retry, int delay);
extern int cts_sram_readl_retry(struct cts_device *cts_dev,
u32 addr, u32 *l, int retry, int delay);
extern int cts_sram_readsb_retry(struct cts_device *cts_dev,
u32 addr, void *dst, size_t len, int retry, int delay);
extern int cts_fw_reg_writeb_retry(struct cts_device *cts_dev,
u32 reg_addr, u8 b, int retry, int delay);
extern int cts_fw_reg_writew_retry(struct cts_device *cts_dev,
u32 reg_addr, u16 w, int retry, int delay);
extern int cts_fw_reg_writel_retry(struct cts_device *cts_dev,
u32 reg_addr, u32 l, int retry, int delay);
extern int cts_fw_reg_writesb_retry(struct cts_device *cts_dev,
u32 reg_addr, const void *src, size_t len, int retry, int delay);
extern int cts_fw_reg_readb_retry(struct cts_device *cts_dev,
u32 reg_addr, u8 *b, int retry, int delay);
extern int cts_fw_reg_readw_retry(struct cts_device *cts_dev,
u32 reg_addr, u16 *w, int retry, int delay);
extern int cts_fw_reg_readl_retry(struct cts_device *cts_dev,
u32 reg_addr, u32 *l, int retry, int delay);
extern int cts_fw_reg_readsb_retry(struct cts_device *cts_dev,
u32 reg_addr, void *dst, size_t len,
int retry, int delay);
extern int cts_fw_reg_readsb_retry_delay_idle(struct cts_device *cts_dev,
u32 reg_addr, void *dst, size_t len, int retry, int delay, int idle);
extern int cts_hw_reg_writeb_retry(struct cts_device *cts_dev,
u32 reg_addr, u8 b, int retry, int delay);
extern int cts_hw_reg_writew_retry(struct cts_device *cts_dev,
u32 reg_addr, u16 w, int retry, int delay);
extern int cts_hw_reg_writel_retry(struct cts_device *cts_dev,
u32 reg_addr, u32 l, int retry, int delay);
extern int cts_hw_reg_writesb_retry(struct cts_device *cts_dev,
u32 reg_addr, const void *src, size_t len, int retry, int delay);
extern int cts_hw_reg_readb_retry(struct cts_device *cts_dev,
u32 reg_addr, u8 *b, int retry, int delay);
extern int cts_hw_reg_readw_retry(struct cts_device *cts_dev,
u32 reg_addr, u16 *w, int retry, int delay);
extern int cts_hw_reg_readl_retry(struct cts_device *cts_dev,
u32 reg_addr, u32 *l, int retry, int delay);
extern int cts_hw_reg_readsb_retry(struct cts_device *cts_dev,
u32 reg_addr, void *dst, size_t len, int retry, int delay);
static inline int cts_hw_reg_readb(struct cts_device *cts_dev,
u32 reg_addr, u8 *b)
{
return cts_hw_reg_readb_retry(cts_dev, reg_addr, b, 1, 0);
}
static inline int cts_hw_reg_writeb(struct cts_device *cts_dev,
u32 reg_addr, u8 b)
{
return cts_hw_reg_writeb_retry(cts_dev, reg_addr, b, 1, 0);
}
static inline int cts_hw_reg_writew(struct cts_device *cts_dev,
u32 reg_addr, u16 w)
{
return cts_hw_reg_writew_retry(cts_dev, reg_addr, w, 1, 0);
}
static inline int cts_fw_reg_writeb(struct cts_device *cts_dev,
u32 reg_addr, u8 b)
{
return cts_fw_reg_writeb_retry(cts_dev, reg_addr, b, 1, 0);
}
static inline int cts_fw_reg_writew(struct cts_device *cts_dev,
u32 reg_addr, u16 w)
{
return cts_fw_reg_writew_retry(cts_dev, reg_addr, w, 1, 0);
}
static inline int cts_fw_reg_writel(struct cts_device *cts_dev,
u32 reg_addr, u32 l)
{
return cts_fw_reg_writel_retry(cts_dev, reg_addr, l, 1, 0);
}
static inline int cts_fw_reg_writesb(struct cts_device *cts_dev,
u32 reg_addr, const void *src, size_t len)
{
return cts_fw_reg_writesb_retry(cts_dev, reg_addr, src, len, 1, 0);
}
static inline int cts_fw_reg_readb(struct cts_device *cts_dev,
u32 reg_addr, u8 *b)
{
return cts_fw_reg_readb_retry(cts_dev, reg_addr, b, 1, 0);
}
static inline int cts_fw_reg_readw(struct cts_device *cts_dev,
u32 reg_addr, u16 *w)
{
return cts_fw_reg_readw_retry(cts_dev, reg_addr, w, 1, 0);
}
static inline int cts_fw_reg_readl(struct cts_device *cts_dev,
u32 reg_addr, u32 *l)
{
return cts_fw_reg_readl_retry(cts_dev, reg_addr, l, 1, 0);
}
static inline int cts_fw_reg_readsb(struct cts_device *cts_dev,
u32 reg_addr, void *dst, size_t len)
{
return cts_fw_reg_readsb_retry(cts_dev, reg_addr, dst, len, 1, 0);
}
static inline int cts_fw_reg_readsb_delay_idle(struct cts_device *cts_dev,
u32 reg_addr, void *dst, size_t len, int idle)
{
return cts_fw_reg_readsb_retry_delay_idle(cts_dev, reg_addr, dst, len,
1, 0, idle);
}
static inline int cts_hw_reg_writeb_relaxed(struct cts_device *cts_dev,
u32 reg_addr, u8 b)
{
return cts_hw_reg_writeb_retry(cts_dev, reg_addr, b, 1, 0);
}
static inline int cts_hw_reg_writew_relaxed(struct cts_device *cts_dev,
u32 reg_addr, u16 w)
{
return cts_hw_reg_writew_retry(cts_dev, reg_addr, w, 1, 0);
}
static inline int cts_hw_reg_writel_relaxed(struct cts_device *cts_dev,
u32 reg_addr, u32 l)
{
return cts_hw_reg_writel_retry(cts_dev, reg_addr, l, 1, 0);
}
static inline int cts_hw_reg_writesb(struct cts_device *cts_dev,
u32 reg_addr, const void *src, size_t len)
{
return cts_hw_reg_writesb_retry(cts_dev, reg_addr, src, len, 1, 0);
}
static inline int cts_hw_reg_readb_relaxed(struct cts_device *cts_dev,
u32 reg_addr, u8 *b)
{
return cts_hw_reg_readb_retry(cts_dev, reg_addr, b, 1, 0);
}
static inline int cts_hw_reg_readw_relaxed(struct cts_device *cts_dev,
u32 reg_addr, u16 *w)
{
return cts_hw_reg_readw_retry(cts_dev, reg_addr, w, 1, 0);
}
static inline int cts_hw_reg_readl_relaxed(struct cts_device *cts_dev,
u32 reg_addr, u32 *l)
{
return cts_hw_reg_readl_retry(cts_dev, reg_addr, l, 1, 0);
}
static inline int cts_hw_reg_readsb(struct cts_device *cts_dev,
u32 reg_addr, void *dst, size_t len)
{
return cts_hw_reg_readsb_retry(cts_dev, reg_addr, dst, len, 1, 0);
}
static inline int cts_sram_writeb(struct cts_device *cts_dev,
u32 addr, u8 b)
{
return cts_sram_writeb_retry(cts_dev, addr, b, 1, 0);
}
static inline int cts_sram_writew(struct cts_device *cts_dev,
u32 addr, u16 w)
{
return cts_sram_writew_retry(cts_dev, addr, w, 1, 0);
}
static inline int cts_sram_writel(struct cts_device *cts_dev,
u32 addr, u32 l)
{
return cts_sram_writel_retry(cts_dev, addr, l, 1, 0);
}
static inline int cts_sram_writesb(struct cts_device *cts_dev, u32 addr,
const void *src, size_t len)
{
return cts_sram_writesb_retry(cts_dev, addr, src, len, 10, 0);
}
static inline int cts_sram_readb(struct cts_device *cts_dev,
u32 addr, u8 *b)
{
return cts_sram_readb_retry(cts_dev, addr, b, 1, 0);
}
static inline int cts_sram_readw(struct cts_device *cts_dev,
u32 addr, u16 *w)
{
return cts_sram_readw_retry(cts_dev, addr, w, 1, 0);
}
static inline int cts_sram_readl(struct cts_device *cts_dev,
u32 addr, u32 *l)
{
return cts_sram_readl_retry(cts_dev, addr, l, 1, 0);
}
static inline int cts_sram_readsb(struct cts_device *cts_dev,
u32 addr, void *dst, size_t len)
{
return cts_sram_readsb_retry(cts_dev, addr, dst, len, 1, 0);
}
#ifdef CONFIG_CTS_I2C_HOST
static inline void cts_set_program_addr(struct cts_device *cts_dev)
{
cts_dev->rtdata.slave_addr = CTS_DEV_PROGRAM_MODE_I2CADDR;
cts_dev->rtdata.program_mode = true;
cts_dev->rtdata.addr_width = CTS_DEV_PROGRAM_MODE_ADDR_WIDTH;
}
static inline void cts_set_normal_addr(struct cts_device *cts_dev)
{
cts_dev->rtdata.slave_addr = CTS_DEV_NORMAL_MODE_I2CADDR;
cts_dev->rtdata.program_mode = false;
cts_dev->rtdata.addr_width = CTS_DEV_NORMAL_MODE_ADDR_WIDTH;
}
int cts_i2c_writeb(struct cts_device *cts_dev,
u32 addr, u8 b, int retry, int delay);
int cts_i2c_writeb(struct cts_device *cts_dev,
u32 addr, u8 b, int retry, int delay);
int cts_i2c_writesb(struct cts_device *cts_dev, u32 addr,
const u8 *src, size_t len, int retry, int delay);
int cts_i2c_readb(struct cts_device *cts_dev,
u32 addr, u8 *b, int retry, int delay);
int cts_i2c_readl(struct cts_device *cts_dev,
u32 addr, u32 *l, int retry, int delay);
#else
static inline void cts_set_program_addr(struct cts_device *cts_dev)
{
cts_dev->rtdata.slave_addr = CTS_DEV_PROGRAM_MODE_SPIADDR;
cts_dev->rtdata.program_mode = true;
cts_dev->rtdata.addr_width = CTS_DEV_PROGRAM_MODE_ADDR_WIDTH;
}
static inline void cts_set_normal_addr(struct cts_device *cts_dev)
{
cts_dev->rtdata.slave_addr = CTS_DEV_NORMAL_MODE_SPIADDR;
cts_dev->rtdata.program_mode = false;
cts_dev->rtdata.addr_width = CTS_DEV_NORMAL_MODE_ADDR_WIDTH;
}
#endif
extern int cts_irq_handler(struct cts_device *cts_dev);
extern void cts_firmware_upgrade_work(struct work_struct *work);
extern bool cts_is_device_suspended(struct cts_device *cts_dev);
extern int cts_suspend_device(struct cts_device *cts_dev);
extern int cts_resume_device(struct cts_device *cts_dev);
extern bool cts_is_device_program_mode(struct cts_device *cts_dev);
extern int cts_enter_program_mode(struct cts_device *cts_dev);
extern int cts_enter_normal_mode(struct cts_device *cts_dev);
extern int cts_probe_device(struct cts_device *cts_dev);
extern int cts_send_command(struct cts_device *cts_dev, u8 cmd);
extern int cts_read_sram_normal_mode(struct cts_device *cts_dev,
u32 addr, void *dst, size_t len, int retry, int delay);
#ifdef CFG_CTS_GESTURE
extern void cts_enable_gesture_wakeup(struct cts_device *cts_dev);
extern void cts_disable_gesture_wakeup(struct cts_device *cts_dev);
extern bool cts_is_gesture_wakeup_enabled(struct cts_device *cts_dev);
extern int cts_get_gesture_info(struct cts_device *cts_dev, void *gesture_info);
#endif /* CFG_CTS_GESTURE */
extern bool cts_is_d_tap_supported(struct cts_device *cts_dev);
extern int cts_set_d_tap_enabled(struct cts_device *cts_dev, bool enabled);
extern int cts_set_int_data_types(struct cts_device *cts_dev, u16 types);
extern int cts_set_int_data_method(struct cts_device *cts_dev, u8 method);
#ifdef CONFIG_CTS_ESD_PROTECTION
extern void cts_init_esd_protection(struct chipone_ts_data *cts_data);
extern void cts_enable_esd_protection(struct chipone_ts_data *cts_data);
extern void cts_disable_esd_protection(struct chipone_ts_data *cts_data);
extern void cts_deinit_esd_protection(struct chipone_ts_data *cts_data);
#else /* CONFIG_CTS_ESD_PROTECTION */
static inline void cts_init_esd_protection(struct chipone_ts_data *cts_data)
{
}
static inline void cts_enable_esd_protection(struct chipone_ts_data *cts_data)
{
}
static inline void cts_disable_esd_protection(struct chipone_ts_data *cts_data)
{
}
static inline void cts_deinit_esd_protection(struct chipone_ts_data *cts_data)
{
}
#endif /* CONFIG_CTS_ESD_PROTECTION */
#ifdef CFG_CTS_HEARTBEAT_MECHANISM
void cts_show_touch_debug_msg(void *debug);
void cts_heartbeat_mechanism_work(struct work_struct *work);
void cts_enable_heartbeat_mechanism(struct chipone_ts_data *cts_data);
void cts_disable_heartbeat_mechanism(struct chipone_ts_data *cts_data);
#endif
#ifdef CONFIG_CTS_GLOVE
extern int cts_enter_glove_mode(struct cts_device *cts_dev);
extern int cts_exit_glove_mode(struct cts_device *cts_dev);
int cts_is_glove_enabled(struct cts_device *cts_dev);
int cts_set_glove_enabled(struct cts_device *cts_dev, bool enabled);
#else
static inline int cts_enter_glove_mode(struct cts_device *cts_dev)
{
return 0;
}
static inline int cts_exit_glove_mode(struct cts_device *cts_dev)
{
return 0;
}
static inline int cts_is_glove_enabled(struct cts_device *cts_dev)
{
return 0;
}
static inline int cts_set_glove_enabled(struct cts_device *cts_dev, bool enabled)
{
return 0;
}
#endif
#ifdef CONFIG_CTS_CHARGER_DETECT
extern bool cts_is_charger_exist(struct cts_device *cts_dev);
extern int cts_set_dev_charger_attached(struct cts_device *cts_dev,
bool attached);
#else /* CONFIG_CTS_CHARGER_DETECT */
static inline bool cts_is_charger_exist(struct cts_device *cts_dev)
{
return false;
}
static inline int cts_set_dev_charger_attached(struct cts_device *cts_dev,
bool attached)
{
return 0;
}
#endif /* CONFIG_CTS_CHARGER_DETECT */
#ifdef CONFIG_CTS_EARJACK_DETECT
extern bool cts_is_earjack_exist(struct cts_device *cts_dev);
extern int cts_set_dev_earjack_attached(struct cts_device *cts_dev, bool attached);
#else /* CONFIG_CTS_EARJACK_DETECT */
static inline bool cts_is_earjack_exist(struct cts_device *cts_dev)
{
return false;
}
static inline int cts_set_dev_earjack_attached(struct cts_device *cts_dev, bool attached)
{
return 0;
}
#endif /* CONFIG_CTS_EARJACK_DETECT */
#ifdef CONFIG_CTS_LEGACY_TOOL
extern int cts_tool_init(struct chipone_ts_data *cts_data);
extern void cts_tool_deinit(struct chipone_ts_data *data);
#else /* CONFIG_CTS_LEGACY_TOOL */
static inline int cts_tool_init(struct chipone_ts_data *cts_data)
{
return 0;
}
static inline void cts_tool_deinit(struct chipone_ts_data *data)
{
}
#endif /* CONFIG_CTS_LEGACY_TOOL */
extern bool cts_is_device_enabled(struct cts_device *cts_dev);
extern int cts_start_device(struct cts_device *cts_dev);
extern int cts_stop_device(struct cts_device *cts_dev);
#ifdef CFG_CTS_UPDATE_CRCCHECK
extern int cts_sram_writesb_boot_crc_retry(struct cts_device *cts_dev,
size_t len, u32 crc, int retry);
#endif
extern const char *cts_dev_boot_mode2str(u8 boot_mode);
extern bool cts_is_fwid_valid(u16 fwid);
extern int cts_reset_device(struct cts_device *cts_dev);
extern int cts_wait_current_mode(struct cts_device *cts_dev, u8 tar_mode);
extern int kstrtobool(const char *s, bool *res);
extern int cts_suspend(struct chipone_ts_data *cts_data);
extern int cts_resume(struct chipone_ts_data *cts_data);
extern struct chipone_ts_data *g_cts_data;
#endif /* CTS_CORE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,649 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#define LOG_TAG "Earjack"
#include "cts_config.h"
#include "cts_platform.h"
#include "cts_core.h"
#include "cts_sysfs.h"
#include "cts_strerror.h"
#ifdef CONFIG_CTS_EARJACK_DETECT
struct cts_earjack_detect_data {
bool enable;
bool running;
bool state;
const char *earjack_state_filepath;
struct delayed_work poll_work;
u32 poll_interval;
#ifdef CONFIG_CTS_SYSFS
bool sysfs_attr_group_created;
#endif /* CONFIG_CTS_SYSFS */
struct chipone_ts_data *cts_data;
};
/* Over-ride setting for DTS */
//#define CFG_CTS_DEF_EARJACK_DET_ENABLE
#define CFG_CTS_DEF_EARJACK_POLL_INTERVAL 2000u
#if defined(CONFIG_MTK_PLATFORM)
#define CFG_CTS_DEF_EARJACK_STATE_FILEPATH \
"/sys/bus/platform/drivers/Accdet_Driver/state"
#elif defined(CONFIG_ARCH_SPREADRUM)
#define CFG_CTS_DEF_EARJACK_STATE_FILEPATH \
"/sys/kernel/headset/state"
#else
/* Current QCOM NOT support earjack detect, please disable it or define the file path */
#define CFG_CTS_DEF_EARJACK_STATE_FILEPATH ""
#endif
static const char *earjack_state_str(bool state)
{
return state ? "ATTACHED" : "DETACHED";
}
static int parse_earjack_detect_dt(struct cts_earjack_detect_data *ed_data,
struct device_node *np)
{
const char *filepath;
int ret;
cts_info("Parse dt");
#ifdef CFG_CTS_DEF_EARJACK_DET_ENABLE
ed_data->enable = true;
#else /* CFG_CTS_DEF_EARJACK_DET_ENABLE */
ed_data->enable =
of_property_read_bool(np, "chipone,touch-earjack-detect-enable");
#endif /* CFG_CTS_DEF_EARJACK_DET_ENABLE */
ret = of_property_read_string(np,
"chipone,touch-earjack-state-filepath", &filepath);
if (ret) {
cts_warn("Parse state filepath failed %d(%s)", ret, cts_strerror(ret));
filepath = CFG_CTS_DEF_EARJACK_STATE_FILEPATH;
}
ed_data->earjack_state_filepath = kstrdup(filepath, GFP_KERNEL);
if (ed_data->earjack_state_filepath == NULL) {
cts_err("Dup earjack state filepath failed");
return -ENOMEM;
}
ed_data->poll_interval = CFG_CTS_DEF_EARJACK_POLL_INTERVAL;
ret = of_property_read_u32(np,
"chipone,touch-earjack-poll-interval", &ed_data->poll_interval);
if (ret) {
cts_warn("Parse poll interval failed %d(%s)", ret, cts_strerror(ret));
}
return 0;
}
static int start_earjack_detect(struct cts_earjack_detect_data *ed_data)
{
if (!ed_data->enable) {
cts_warn("Start detect while NOT enabled");
return -EINVAL;
}
if (ed_data->running) {
cts_warn("Start detect while already RUNNING");
return 0;
}
if (ed_data->earjack_state_filepath == NULL ||
ed_data->earjack_state_filepath[0] == '\n') {
cts_warn("Start detect with filepath = NULL/NUL");
return -EINVAL;
}
cts_info("Start detect check file: '%s'", ed_data->earjack_state_filepath);
if (!queue_delayed_work(ed_data->cts_data->workqueue,
&ed_data->poll_work,
msecs_to_jiffies(ed_data->poll_interval))) {
cts_warn("Queue detect work while already on the queue");
}
ed_data->running = true;
return 0;
}
static int stop_earjack_detect(struct cts_earjack_detect_data *ed_data)
{
if (!ed_data->running) {
cts_warn("Stop detect while NOT running");
return 0;
}
cts_info("Stop detect");
if (!cancel_delayed_work_sync(&ed_data->poll_work)) {
cts_warn("Cancel poll work while NOT pending");
}
ed_data->running = false;
return 0;
}
static int get_earjack_state(struct cts_earjack_detect_data *ed_data)
{
int ret;
char buff[10];
u32 state;
#ifndef CFG_CTS_FOR_GKI
struct file *file = NULL;
loff_t pos = 0;
int read_size;
#endif
cts_dbg("Get state from file '%s'", ed_data->earjack_state_filepath);
#ifdef CFG_CTS_FOR_GKI
cts_info("%s(): filp_open is forbiddon with GKI Version!", __func__);
#else
file = filp_open(ed_data->earjack_state_filepath, O_RDONLY, 0);
if (IS_ERR(file)) {
ret = (int)PTR_ERR(file);
cts_err("Open file '%s' failed %d(%s)",
ed_data->earjack_state_filepath, ret, cts_strerror(ret));
return PTR_ERR(file);
}
memset(buff, 0, sizeof(buff));
#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,14,0)
read_size = kernel_read(file, buff, sizeof(buff), &pos);
#else
read_size = kernel_read(file, pos, buff, sizeof(buff));
#endif
if (read_size < 0) {
cts_err("Read state file '%s' failed %d(%s)",
ed_data->earjack_state_filepath,
read_size, cts_strerror(read_size));
filp_close(file, NULL);
return read_size;
}
cts_dbg("Read state file content: '%s'", buff);
ret = filp_close(file, NULL);
if (ret) {
cts_warn("Close file '%s' failed %d(%s)",
ed_data->earjack_state_filepath, ret, cts_strerror(ret));
}
#endif
ret = kstrtou32(buff, 0, &state);
if (ret) {
cts_err("Invalid string from state file: '%s'", buff);
return ret;
}
/* Assume "0" means detached */
ed_data->state = !!state;
cts_dbg("State: %s", earjack_state_str(ed_data->state));
return 0;
}
/* Sysfs */
#ifdef CONFIG_CTS_SYSFS
#define EARJACK_DET_SYSFS_GROUP_NAME "earjack-det"
static int enable_earjack_detect(struct cts_earjack_detect_data *ed_data)
{
cts_info("Enable detect");
ed_data->enable = true;
return 0;
}
static int disable_earjack_detect(struct cts_earjack_detect_data *ed_data)
{
int ret;
cts_info("Disable detect");
ret = stop_earjack_detect(ed_data);
if (ret) {
cts_err("Stop detect failed %d(%s)", ret, cts_strerror(ret));
}
ed_data->enable = false;
return 0;
}
static ssize_t earjack_detect_enable_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct chipone_ts_data *cts_data = dev_get_drvdata(dev);
struct cts_earjack_detect_data *ed_data = cts_data->earjack_detect_data;
cts_info("Read sysfs '"EARJACK_DET_SYSFS_GROUP_NAME"/%s'", attr->attr.name);
return scnprintf(buf, PAGE_SIZE,
"Earjack detect: %s\n",
ed_data->enable ? "ENABLED" : "DISABLED");
}
/* Echo 0/n/N/of/Of/Of/OF/1/y/Y/on/oN/On/ON > enable */
static ssize_t earjack_detect_enable_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct chipone_ts_data *cts_data = dev_get_drvdata(dev);
struct cts_earjack_detect_data *ed_data = cts_data->earjack_detect_data;
bool enable;
int ret;
cts_info("Write sysfs '"EARJACK_DET_SYSFS_GROUP_NAME"/%s' size %zu",
attr->attr.name, count);
cts_parse_arg(buf, count);
if (cts_argc != 1) {
cts_err("Invalid num of args");
return -EINVAL;
}
ret = kstrtobool(cts_argv[0], &enable);
if (ret) {
cts_err("Invalid param of enable");
return ret;
}
if (enable) {
ret = enable_earjack_detect(ed_data);
} else {
ret = disable_earjack_detect(ed_data);
}
if (ret) {
cts_err("%s earjack detect failed %d(%s)",
enable ? "Enable" : "Disable", ret, cts_strerror(ret));
return ret;
}
return count;
}
static DEVICE_ATTR(enable, S_IWUSR | S_IRUGO,
earjack_detect_enable_show, earjack_detect_enable_store);
static ssize_t earjack_detect_running_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct chipone_ts_data *cts_data = dev_get_drvdata(dev);
struct cts_earjack_detect_data *ed_data = cts_data->earjack_detect_data;
cts_info("Read sysfs '"EARJACK_DET_SYSFS_GROUP_NAME"/%s'",
attr->attr.name);
return scnprintf(buf, PAGE_SIZE,
"Earjack detect: %sRunning\n",
ed_data->running ? "" : "Not-");
}
/* Echo 0/n/N/of/Of/Of/OF/1/y/Y/on/oN/On/ON > runing */
static ssize_t earjack_detect_running_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct chipone_ts_data *cts_data = dev_get_drvdata(dev);
struct cts_earjack_detect_data *ed_data = cts_data->earjack_detect_data;
bool running;
int ret;
cts_info("Write sysfs '"EARJACK_DET_SYSFS_GROUP_NAME"/%s' size %zu",
attr->attr.name, count);
cts_parse_arg(buf, count);
if (cts_argc != 1) {
cts_err("Invalid num of args");
return -EINVAL;
}
ret = kstrtobool(cts_argv[0], &running);
if (ret) {
cts_err("Invalid param of running");
return ret;
}
if (running) {
ret = start_earjack_detect(ed_data);
} else {
ret = stop_earjack_detect(ed_data);
}
if (ret) {
cts_err("%s earjack detect failed %d(%s)",
running ? "Start" : "Stop", ret, cts_strerror(ret));
return ret;
}
return count;
}
static DEVICE_ATTR(running, S_IWUSR | S_IRUGO,
earjack_detect_running_show, earjack_detect_running_store);
static ssize_t earjack_state_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct chipone_ts_data *cts_data = dev_get_drvdata(dev);
struct cts_earjack_detect_data *ed_data = cts_data->earjack_detect_data;
int ret;
cts_info("Read sysfs '"EARJACK_DET_SYSFS_GROUP_NAME"/%s'",
attr->attr.name);
ret = get_earjack_state(ed_data);
if (ret) {
return scnprintf(buf, PAGE_SIZE,
"Get earjack state failed %d(%s)\n",
ret, cts_strerror(ret));
}
return scnprintf(buf, PAGE_SIZE,
"Earjack state: %s\n", earjack_state_str(ed_data->state));
}
static DEVICE_ATTR(state, S_IRUGO, earjack_state_show, NULL);
static ssize_t earjack_detect_param_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct chipone_ts_data *cts_data = dev_get_drvdata(dev);
struct cts_earjack_detect_data *ed_data = cts_data->earjack_detect_data;
cts_info("Read sysfs '"EARJACK_DET_SYSFS_GROUP_NAME"/%s'",
attr->attr.name);
return scnprintf(buf, PAGE_SIZE,
"Filepath: '%s'\n"
"Poll int: %dms\n",
ed_data->earjack_state_filepath, ed_data->poll_interval);
}
/* echo filepath [interval] > param */
static ssize_t earjack_detect_param_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t count)
{
struct chipone_ts_data *cts_data = dev_get_drvdata(dev);
struct cts_earjack_detect_data *ed_data = cts_data->earjack_detect_data;
u32 interval;
int ret;
cts_info("Write sysfs '"EARJACK_DET_SYSFS_GROUP_NAME"/%s' size %zu",
attr->attr.name, count);
cts_parse_arg(buf, count);
if (cts_argc < 1 || cts_argc > 2) {
cts_err("Invalid num of args");
return -EINVAL;
}
interval = ed_data->poll_interval;
if (cts_argc > 1) {
ret = kstrtou32(cts_argv[1], 0, &interval);
if (ret) {
cts_err("Arg interval is invalid");
return -EINVAL;
}
}
if (ed_data->earjack_state_filepath) {
kfree(ed_data->earjack_state_filepath);
}
ed_data->earjack_state_filepath = kstrdup(cts_argv[0], GFP_KERNEL);
if (ed_data->earjack_state_filepath == NULL) {
cts_err("Dup earjack state filepath failed");
return -ENOMEM;
}
ed_data->poll_interval = interval;
return count;
}
static DEVICE_ATTR(param, S_IWUSR | S_IRUGO,
earjack_detect_param_show, earjack_detect_param_store);
static struct attribute *earjack_detect_attrs[] = {
&dev_attr_enable.attr,
&dev_attr_running.attr,
&dev_attr_state.attr,
&dev_attr_param.attr,
NULL
};
static const struct attribute_group earjack_detect_attr_group = {
.name = EARJACK_DET_SYSFS_GROUP_NAME,
.attrs = earjack_detect_attrs,
};
#endif /* CONFIG_CTS_SYSFS */
static void poll_earjack_state_work(struct work_struct *work)
{
struct cts_earjack_detect_data *ed_data;
bool prev_state = false;
int ret;
cts_dbg("Poll earjack state work");
ed_data = container_of(to_delayed_work(work),
struct cts_earjack_detect_data, poll_work);
prev_state = ed_data->state;
ret = get_earjack_state(ed_data);
if (ret) {
cts_err("Get state failed %d(%s)", ret, cts_strerror(ret));
} else {
if (ed_data->state != prev_state) {
cts_info("State changed: %s -> %s",
earjack_state_str(prev_state),
earjack_state_str(ed_data->state));
cts_lock_device(&ed_data->cts_data->cts_dev);
ret = cts_set_dev_earjack_attached(
&ed_data->cts_data->cts_dev, ed_data->state);
cts_unlock_device(&ed_data->cts_data->cts_dev);
if (ret) {
cts_err("Set dev earjack attached to %s failed %d(%s)",
earjack_state_str(ed_data->state),
ret, cts_strerror(ret));
/* Set to previous state, try set again in next loop */
ed_data->state = prev_state;
}
}
}
if (!queue_delayed_work(ed_data->cts_data->workqueue,
&ed_data->poll_work,
msecs_to_jiffies(ed_data->poll_interval))) {
cts_warn("Queue detect work while already on the queue");
}
}
int cts_earjack_detect_init(struct chipone_ts_data *cts_data)
{
struct cts_earjack_detect_data *ed_data;
int ret = 0;
if (cts_data == NULL) {
cts_err("Init detect with cts_data = NULL");
return -EFAULT;
}
ed_data = kzalloc(sizeof(*ed_data), GFP_KERNEL);
if (ed_data == NULL) {
cts_err("Alloc earjack detect data failed");
return -ENOMEM;
}
cts_info("Init detect");
#ifdef CONFIG_CTS_OF
ret = parse_earjack_detect_dt(ed_data, cts_data->device->of_node);
#else /* CONFIG_CTS_OF */
#ifdef CFG_CTS_DEF_EARJACK_DET_ENABLE
ed_data->enable = true;
#else /* CFG_CTS_DEF_EARJACK_DET_ENABLE */
ed_data->enable = false;
#endif /* CFG_CTS_DEF_EARJACK_DET_ENABLE */
ed_data->poll_interval = CFG_CTS_DEF_EARJACK_POLL_INTERVAL;
ed_data->earjack_state_filepath = kstrdup(
CFG_CTS_DEF_EARJACK_STATE_FILEPATH, GFP_KERNEL);
if (ed_data->earjack_state_filepath == NULL) {
cts_err("Dup earjack state filepath failed");
ret = -ENOMEM;
}
#endif /* CONFIG_CTS_OF */
if (ret) {
cts_err("Get detect param failed %d(%s)",
ret, cts_strerror(ret));
goto free_ed_data;
}
cts_info("Detect: %sABLED", ed_data->enable ? "EN" : "DIS");
cts_info(" Filepath: '%s'", ed_data->earjack_state_filepath);
cts_info(" Poll Int: %dms", ed_data->poll_interval);
INIT_DELAYED_WORK(&ed_data->poll_work, poll_earjack_state_work);
#ifdef CONFIG_CTS_SYSFS
cts_info("Create sysfs attr group '%s'", EARJACK_DET_SYSFS_GROUP_NAME);
ret = sysfs_create_group(&cts_data->device->kobj,
&earjack_detect_attr_group);
if (ret) {
cts_warn("Create sysfs attr group '%s' failed %d(%s)",
EARJACK_DET_SYSFS_GROUP_NAME, ret, cts_strerror(ret));
} else {
ed_data->sysfs_attr_group_created = true;
}
#endif /* CONFIG_CTS_SYSFS */
cts_data->earjack_detect_data = ed_data;
ed_data->cts_data = cts_data;
return 0;
free_ed_data:
kfree(ed_data);
return ret;
}
int cts_earjack_detect_deinit(struct chipone_ts_data *cts_data)
{
struct cts_earjack_detect_data *ed_data;
int ret;
if (cts_data == NULL) {
cts_err("Deinit detect with cts_data = NULL");
return -EFAULT;
}
ed_data = cts_data->earjack_detect_data;
if (ed_data == NULL) {
cts_warn("Deinit detect with earjack_detect_data = NULL");
return 0;
}
cts_info("Deinit detect");
if (ed_data->running) {
ret = stop_earjack_detect(ed_data);
if (ret) {
cts_err("Stop detect failed %d(%s)",
ret, cts_strerror(ret));
}
}
#ifdef CONFIG_CTS_SYSFS
if (ed_data->sysfs_attr_group_created) {
cts_info("Remove sysfs attr group '%s'", EARJACK_DET_SYSFS_GROUP_NAME);
sysfs_remove_group(&cts_data->device->kobj, &earjack_detect_attr_group);
ed_data->sysfs_attr_group_created = false;
}
#endif /* CONFIG_CTS_SYSFS */
if(ed_data->earjack_state_filepath) {
kfree(ed_data->earjack_state_filepath);
ed_data->earjack_state_filepath = NULL;
}
kfree(ed_data);
cts_data->earjack_detect_data = NULL;
return 0;
}
int cts_is_earjack_attached(struct chipone_ts_data *cts_data, bool *attached)
{
struct cts_earjack_detect_data *ed_data;
int ret;
if (cts_data == NULL) {
cts_err("Get state with cts_data = NULL");
return -EFAULT;
}
ed_data = cts_data->earjack_detect_data;
if (ed_data == NULL) {
cts_err("Get state with earjack_detect_data = NULL");
return -ENODEV;
}
ret = get_earjack_state(ed_data);
if (ret) {
cts_err("Get state failed %d(%s)", ret, cts_strerror(ret));
return ret;
}
cts_info("Get curr state: %s", earjack_state_str(ed_data->state));
*attached = ed_data->state;
return 0;
}
int cts_start_earjack_detect(struct chipone_ts_data *cts_data)
{
struct cts_earjack_detect_data *ed_data;
if (cts_data == NULL) {
cts_err("Start detect with cts_data = NULL");
return -EFAULT;
}
ed_data = cts_data->earjack_detect_data;
if (ed_data == NULL) {
cts_err("Start detect with earjack_detect_data = NULL");
return -ENODEV;
}
return start_earjack_detect(ed_data);
}
int cts_stop_earjack_detect(struct chipone_ts_data *cts_data)
{
struct cts_earjack_detect_data *ed_data;
if (cts_data == NULL) {
cts_err("Stop detect with cts_data = NULL");
return -EFAULT;
}
ed_data = cts_data->earjack_detect_data;
if (ed_data == NULL) {
cts_err("Stop detect with earjack_detect_data = NULL");
return -ENODEV;
}
return stop_earjack_detect(ed_data);
}
#endif /* CONFIG_CTS_EARJACK_DETECT */

View File

@@ -0,0 +1,42 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef CTS_EARJACK_DETECT_H
#define CTS_EARJACK_DETECT_H
#include "cts_config.h"
//struct chipone_ts_data;
#ifdef CONFIG_CTS_EARJACK_DETECT
extern int cts_earjack_detect_init(struct chipone_ts_data *cts_data);
extern int cts_earjack_detect_deinit(struct chipone_ts_data *cts_data);
extern int cts_start_earjack_detect(struct chipone_ts_data *cts_data);
extern int cts_stop_earjack_detect(struct chipone_ts_data *cts_data);
extern int cts_is_earjack_attached(struct chipone_ts_data *cts_data,
bool *attached);
#else /* CONFIG_CTS_EARJACK_DETECT */
static inline int cts_earjack_detect_init(struct chipone_ts_data *cts_data)
{
return -ENOTSUPP;
}
static inline int cts_earjack_detect_deinit(struct chipone_ts_data *cts_data)
{
return -ENOTSUPP;
}
static inline int cts_start_earjack_detect(struct chipone_ts_data *cts_data)
{
return -ENODEV;
}
static inline int cts_stop_earjack_detect(struct chipone_ts_data *cts_data)
{
return -ENODEV;
}
static inline int cts_is_earjack_attached(struct chipone_ts_data *cts_data,
bool *attached)
{
return -ENODEV;
}
#endif /* CONFIG_CTS_EARJACK_DETECT */
#endif /* CTS_EARJACK_DETECT_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,33 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef CTS_FIRMWARE_H
#define CTS_FIRMWARE_H
#include "cts_config.h"
#include <linux/firmware.h>
#include <linux/vmalloc.h>
#define FIRMWARE_VERSION_OFFSET 0x100
#define FIRMWARE_VERSION(firmware) \
get_unaligned_le16((firmware)->data + FIRMWARE_VERSION_OFFSET)
struct cts_device;
extern int cts_request_newer_firmware_from_fs(struct cts_device *cts_dev,
const char *filepath, u16 curr_version);
extern bool cts_is_firmware_updating(struct cts_device *cts_dev);
extern int cts_request_firmware(struct cts_device *cts_dev,
u32 hwid, u16 fwid, u16 device_fw_ver);
extern int cts_update_firmware(struct cts_device *cts_dev);
#ifdef CFG_CTS_FIRMWARE_IN_FS
extern int cts_update_firmware_from_file(struct cts_device *cts_dev,
const char *filepath);
#endif /* CFG_CTS_FIRMWARE_IN_FS */
extern u16 cts_crc16(const u8 *data, size_t len);
extern u32 cts_crc32(const u8 *data, size_t len);
#endif /* CTS_FIRMWARE_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,12 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef CTS_OEM_H
#define CTS_OEM_H
struct chipone_ts_data;
extern int cts_oem_init(struct chipone_ts_data *cts_data);
extern int cts_oem_deinit(struct chipone_ts_data *cts_data);
#endif /* CTS_VENDOR_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,309 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef CTS_PLATFORM_H
#define CTS_PLATFORM_H
#include <linux/types.h>
#include <asm/byteorder.h>
#include <linux/bitops.h>
#include <linux/ctype.h>
//#include <linux/unaligned/access_ok.h>
#include <asm-generic/unaligned.h>
#include <linux/kernel.h>
#include <linux/slab.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/input.h>
#include <linux/input/mt.h>
#include <linux/spinlock.h>
#include <linux/rtmutex.h>
#include <linux/byteorder/generic.h>
#include <linux/proc_fs.h>
#include <linux/delay.h>
#include <linux/version.h>
#include <linux/jiffies.h>
#include <linux/hrtimer.h>
#include <linux/string.h>
#include <linux/suspend.h>
/* #include <linux/wakelock.h> */
#include <linux/firmware.h>
#include <linux/vmalloc.h>
#ifdef CONFIG_OF
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/of_irq.h>
#endif /* CONFIG_OF */
#include <linux/fb.h>
#include <linux/notifier.h>
#include <linux/spi/spi.h>
#include <linux/spi/spidev.h>
#include "cts_config.h"
#include "cts_core.h"
#ifdef CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED
#ifdef TPD_SUPPORT_I2C_DMA
#include <linux/dma-mapping.h>
#endif /* TPD_SUPPORT_I2C_DMA */
#ifdef CONFIG_MTK_BOOT
#include "mtk_boot_common.h"
#endif /* CONFIG_MTK_BOOT */
#include "tpd.h"
#include "tpd_debug.h"
#include "upmu_common.h"
#endif
extern bool cts_show_debug_log;
#ifndef LOG_TAG
#define LOG_TAG ""
#endif /* LOG_TAG */
enum cts_driver_log_level {
CTS_DRIVER_LOG_ERROR,
CTS_DRIVER_LOG_WARN,
CTS_DRIVER_LOG_INFO,
CTS_DRIVER_LOG_DEBUG,
};
extern int cts_start_driver_log_redirect(const char *filepath, bool append_to_file,
char *log_buffer, int log_buf_size, int log_level);
extern void cts_stop_driver_log_redirect(void);
extern int cts_get_driver_log_redirect_size(void);
extern void cts_log(int level, const char *fmt, ...);
#define cts_err(fmt, ...) \
cts_log(CTS_DRIVER_LOG_ERROR, "<E>CTS-" LOG_TAG " " fmt"\n", ##__VA_ARGS__)
#define cts_warn(fmt, ...) \
cts_log(CTS_DRIVER_LOG_WARN, "<W>CTS-" LOG_TAG " " fmt"\n", ##__VA_ARGS__)
#define cts_info(fmt, ...) \
cts_log(CTS_DRIVER_LOG_INFO, "<I>CTS-" LOG_TAG " " fmt"\n", ##__VA_ARGS__)
#define cts_dbg(fmt, ...) \
cts_log(CTS_DRIVER_LOG_DEBUG, "<D>CTS-" LOG_TAG " " fmt"\n", ##__VA_ARGS__)
struct cts_device;
struct cts_device_touch_msg;
struct cts_device_gesture_info;
struct cts_platform_data {
int irq;
#ifndef CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED
int int_gpio;
#ifdef CFG_CTS_HAS_RESET_PIN
int rst_gpio;
#endif
#ifdef CFG_CTS_MANUAL_CS
int cs_gpio;
#endif
#endif
u32 res_x;
u32 res_y;
#ifdef CONFIG_CTS_VIRTUALKEY
u8 vkey_num;
u8 vkey_state;
u8 vkey_keycodes[CFG_CTS_MAX_VKEY_NUM];
#endif
#ifdef CFG_CTS_FW_UPDATE_SYS
const char *panel_supplier;
#endif
u32 build_id;
u32 config_id;
struct cts_device *cts_dev;
struct input_dev *ts_input_dev;
struct input_dev *pen_input_dev;
#ifndef CONFIG_GENERIC_HARDIRQS
struct work_struct ts_irq_work;
#endif
struct mutex dev_lock;
struct spinlock irq_lock;
bool irq_is_disable;
#ifdef CFG_CTS_GESTURE
u8 gesture_num;
u8 gesture_keymap[CFG_CTS_NUM_GESTURE][2];
bool irq_wake_enabled;
#endif
#ifdef CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED
#ifdef TPD_SUPPORT_I2C_DMA
u8 *i2c_dma_buff_va;
dma_addr_t i2c_dma_buff_pa;
#endif /* TPD_SUPPORT_I2C_DMA */
#else
#ifdef CONFIG_CTS_PM_FB_NOTIFIER
struct notifier_block fb_notifier;
#endif
#endif
#ifdef CFG_CTS_FORCE_UP
struct delayed_work touch_timeout;
#endif
#ifdef CONFIG_CTS_I2C_HOST
struct i2c_client *i2c_client;
u8 i2c_fifo_buf[CFG_CTS_MAX_I2C_XFER_SIZE];
u8 i2c_rbuf[ALIGN(CFG_CTS_MAX_I2C_READ_SIZE, 4)];
#else
struct spi_device *spi_client;
u8 spi_cache_buf[ALIGN(CFG_CTS_MAX_SPI_XFER_SIZE + 10, 4)];
u8 spi_rx_buf[ALIGN(CFG_CTS_MAX_SPI_XFER_SIZE + 10, 4)];
u8 spi_tx_buf[ALIGN(CFG_CTS_MAX_SPI_XFER_SIZE + 10, 4)];
u32 spi_speed;
#ifdef CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED
#ifdef CFG_CTS_MANUAL_CS
struct pinctrl *pinctrl1;
struct pinctrl_state *spi_cs_low, *spi_cs_high;
#endif
#endif/* CONFIG_CTS_I2C_HOST */
#ifdef TPD_SUPPORT_I2C_DMA
bool i2c_dma_available;
#endif /* TPD_SUPPORT_I2C_DMA */
#endif
};
#ifdef CONFIG_CTS_I2C_HOST
extern size_t cts_plat_get_max_i2c_xfer_size(struct cts_platform_data *pdata);
extern u8 *cts_plat_get_i2c_xfer_buf(struct cts_platform_data *pdata,
size_t xfer_size);
extern int cts_plat_i2c_write(struct cts_platform_data *pdata, u8 i2c_addr,
const void *src, size_t len, int retry, int delay);
extern int cts_plat_i2c_read(struct cts_platform_data *pdata, u8 i2c_addr,
const u8 *wbuf, size_t wlen, void *rbuf,
size_t rlen, int retry, int delay);
#else /* CONFIG_CTS_I2C_HOST */
extern size_t cts_plat_get_max_spi_xfer_size(struct cts_platform_data *pdata);
extern u8 *cts_plat_get_spi_xfer_buf(struct cts_platform_data *pdata,
size_t xfer_size);
extern int cts_plat_spi_write(struct cts_platform_data *pdata, u8 i2c_addr,
const void *src, size_t len, int retry, int delay);
extern int cts_plat_spi_read(struct cts_platform_data *pdata, u8 i2c_addr,
const u8 *wbuf, size_t wlen, void *rbuf,
size_t rlen, int retry, int delay);
extern int cts_plat_spi_read_delay_idle(struct cts_platform_data *pdata,
u8 dev_addr, const u8 *wbuf, size_t wlen, void *rbuf, size_t rlen,
int retry, int delay, int idle);
extern int cts_spi_send_recv(struct cts_platform_data *pdata, size_t len,
u8 *tx_buffer, u8 *rx_buffer);
#endif /* CONFIG_CTS_I2C_HOST */
#ifdef CONFIG_CTS_I2C_HOST
extern int cts_init_platform_data(struct cts_platform_data *pdata,
struct i2c_client *i2c_client);
#else
extern int cts_init_platform_data(struct cts_platform_data *pdata,
struct spi_device *spi);
#endif
extern int cts_plat_is_normal_mode(struct cts_platform_data *pdata);
#ifndef CFG_CTS_PLATFORM_MTK_TPD_SUPPORTED
extern int cts_deinit_platform_data(struct cts_platform_data *pdata);
#endif
extern int cts_plat_request_resource(struct cts_platform_data *pdata);
extern void cts_plat_free_resource(struct cts_platform_data *pdata);
extern int cts_plat_request_irq(struct cts_platform_data *pdata);
extern void cts_plat_free_irq(struct cts_platform_data *pdata);
extern int cts_plat_enable_irq(struct cts_platform_data *pdata);
extern int cts_plat_disable_irq(struct cts_platform_data *pdata);
#ifdef CFG_CTS_HAS_RESET_PIN
extern int cts_plat_reset_device(struct cts_platform_data *pdata);
#else /* CFG_CTS_HAS_RESET_PIN */
static inline int cts_plat_reset_device(struct cts_platform_data *pdata)
{
return 0;
}
#endif /* CFG_CTS_HAS_RESET_PIN */
extern int cts_plat_init_touch_device(struct cts_platform_data *pdata);
extern void cts_plat_deinit_touch_device(struct cts_platform_data *pdata);
#ifdef CFG_CTS_PALM_DETECT
void cts_report_palm_event(struct cts_platform_data *pdata);
#endif
extern int cts_plat_process_touch_msg(struct cts_platform_data *pdata,
struct cts_device_touch_msg *msgs, int num);
extern int cts_plat_process_stylus_msg(struct cts_platform_data *pdata,
struct cts_device_stylus_msg *msgs, int num);
#ifdef CFG_CTS_FINGER_STYLUS_SUPPORTED
extern int cts_plat_process_touch_stylus(struct cts_platform_data *pdata,
struct cts_device_touch_info *touch_info);
#endif
extern int cts_plat_release_all_touch(struct cts_platform_data *pdata);
#ifdef CONFIG_CTS_VIRTUALKEY
extern int cts_plat_init_vkey_device(struct cts_platform_data *pdata);
extern void cts_plat_deinit_vkey_device(struct cts_platform_data *pdata);
extern int cts_plat_process_vkey(struct cts_platform_data *pdata,
u8 vkey_state);
extern int cts_plat_release_all_vkey(struct cts_platform_data *pdata);
#else /* CONFIG_CTS_VIRTUALKEY */
static inline int cts_plat_init_vkey_device(struct cts_platform_data *pdata)
{
return 0;
}
static inline void cts_plat_deinit_vkey_device(struct cts_platform_data *pdata)
{
}
static inline int cts_plat_process_vkey(struct cts_platform_data *pdata,
u8 vkey_state)
{
return 0;
}
static inline int cts_plat_release_all_vkey(struct cts_platform_data *pdata)
{
return 0;
}
#endif /* CONFIG_CTS_VIRTUALKEY */
#ifdef CFG_CTS_GESTURE
extern int cts_plat_enable_irq_wake(struct cts_platform_data *pdata);
extern int cts_plat_disable_irq_wake(struct cts_platform_data *pdata);
extern int cts_plat_init_gesture(struct cts_platform_data *pdata);
extern void cts_plat_deinit_gesture(struct cts_platform_data *pdata);
extern int cts_plat_process_gesture_info(struct cts_platform_data *pdata,
struct cts_device_gesture_info *gesture_info);
#else /* CFG_CTS_GESTURE */
static inline int cts_plat_init_gesture(struct cts_platform_data *pdata)
{
return 0;
}
static inline void cts_plat_deinit_gesture(struct cts_platform_data *pdata)
{
}
#endif /* CFG_CTS_GESTURE */
extern int cts_plat_set_reset(struct cts_platform_data *pdata, int val);
extern int cts_plat_get_int_pin(struct cts_platform_data *pdata);
#ifdef CFG_CTS_MANUAL_CS
extern int cts_plat_set_cs(struct cts_platform_data *pdata, int val);
#endif
#endif /* CTS_PLATFORM_H */

View File

@@ -0,0 +1,38 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef CTS_SFCTRL_H
#define CTS_SFCTRL_H
#include "cts_core.h"
#include "cts_spi_flash.h"
struct cts_device;
struct cts_sfctrl_ops {
int (*rdid)(struct cts_device *cts_dev, u32 *id);
int (*se)(struct cts_device *cts_dev, u32 sector_addr);
int (*be)(struct cts_device *cts_dev, u32 sector_addr);
int (*read)(struct cts_device *cts_dev,
u32 flash_addr, void *dst, size_t len);
int (*read_to_sram)(struct cts_device *cts_dev,
u32 flash_addr, u32 sram_addr, size_t len);
int (*program)(struct cts_device *cts_dev,
u32 flash_addr, const void *src, size_t len);
int (*program_from_sram)(struct cts_device *cts_dev,
u32 flash_addr, u32 sram_addr, size_t len);
int (*calc_sram_crc)(struct cts_device *cts_dev,
u32 sram_addr, size_t len, u32 *crc);
int (*calc_flash_crc)(struct cts_device *cts_dev,
u32 flash_addr, size_t len, u32 *crc);
};
struct cts_sfctrl {
u32 reg_base;
u32 xchg_sram_base;
size_t xchg_sram_size;
const struct cts_sfctrl_ops *ops;
};
extern const struct cts_sfctrl_ops cts_sfctrlv2_ops;
#endif /* CTS_SFCTRL_H */

View File

@@ -0,0 +1,342 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#define LOG_TAG "SFCtrl"
#include "cts_config.h"
#include "cts_platform.h"
#include "cts_core.h"
#include "cts_sfctrl.h"
#define rSFCTRLv2_CMD_SEL (0x0000)
#define rSFCTRLv2_FLASH_ADDR (0x0004)
#define rSFCTRLv2_SRAM_ADDR (0x0008)
#define rSFCTRLv2_DATA_LENGTH (0x000C)
#define rSFCTRLv2_START_DEXC (0x0010)
#define rSFCTRLv2_RELEASE_FLASH (0x0014)
#define rSFCTRLv2_HW_STATE (0x0018)
#define rSFCTRLv2_CRC_RESULT (0x001C)
#define rSFCTRLv2_SRAM_CRC_START (0x0020)
#define rSFCTRLv2_FLASH_CRC_START (0x0022)
#define rSFCTRLv2_SF_BUSY (0x0024)
/** Constants for register @ref rSFCTRLv2_CMD_SEL */
enum sfctrlv2_cmd {
SFCTRLv2_CMD_FAST_READ = 0x01u,
SFCTRLv2_CMD_SE = 0x02u,
SFCTRLv2_CMD_BE = 0x03u,
SFCTRLv2_CMD_PP = 0x04u,
SFCTRLv2_CMD_RDSR = 0x05u,
SFCTRLv2_CMD_RDID = 0x06u
};
/** SPI flash controller v2 operation flags. */
enum sfctrlv2_opflags {
SFCTRLv2_OPFLAG_READ = BIT(0),
SFCTRLv2_OPFLAG_SET_FLASH_ADDR = BIT(1),
SFCTRLv2_OPFLAG_SRAM_DATA_XCHG = BIT(2),
SFCTRLv2_OPFLAG_SET_DATA_LENGTH = BIT(3),
SFCTRLv2_OPFLAG_WAIT_WIP_CLR = BIT(4),
};
#define SFCTRLv2_CMD_RDID_FLAGS \
(SFCTRLv2_OPFLAG_READ | \
SFCTRLv2_OPFLAG_SRAM_DATA_XCHG)
#define SFCTRLv2_CMD_RDSR_FLAGS \
(SFCTRLv2_OPFLAG_READ | \
SFCTRLv2_OPFLAG_SRAM_DATA_XCHG)
#define SFCTRLv2_CMD_SE_FLAGS \
(SFCTRLv2_OPFLAG_SET_FLASH_ADDR | \
SFCTRLv2_OPFLAG_WAIT_WIP_CLR)
#define SFCTRLv2_CMD_BE_FLAGS \
(SFCTRLv2_OPFLAG_SET_FLASH_ADDR | \
SFCTRLv2_OPFLAG_WAIT_WIP_CLR)
#define SFCTRLv2_CMD_PP_FLAGS \
(SFCTRLv2_OPFLAG_SET_FLASH_ADDR | \
SFCTRLv2_OPFLAG_SRAM_DATA_XCHG | \
SFCTRLv2_OPFLAG_SET_DATA_LENGTH | \
SFCTRLv2_OPFLAG_WAIT_WIP_CLR)
#define SFCTRLv2_CMD_FAST_READ_FLAGS \
(SFCTRLv2_OPFLAG_READ | \
SFCTRLv2_OPFLAG_SET_FLASH_ADDR | \
SFCTRLv2_OPFLAG_SRAM_DATA_XCHG | \
SFCTRLv2_OPFLAG_SET_DATA_LENGTH)
#define sfctrl_reg_addr(cts_dev, offset) \
((cts_dev)->hwdata->sfctrl->reg_base + offset)
#define DEFINE_SFCTRL_REG_ACCESS_FUNC(access_type, data_type) \
static inline int sfctrl_reg_ ## access_type(struct cts_device *cts_dev, \
u32 reg, data_type data) { \
return cts_hw_reg_ ## access_type(cts_dev, sfctrl_reg_addr(cts_dev, reg), data); \
}
DEFINE_SFCTRL_REG_ACCESS_FUNC(writeb_relaxed, u8)
DEFINE_SFCTRL_REG_ACCESS_FUNC(writew_relaxed, u16)
DEFINE_SFCTRL_REG_ACCESS_FUNC(writel_relaxed, u32)
DEFINE_SFCTRL_REG_ACCESS_FUNC(readb_relaxed, u8 *)
DEFINE_SFCTRL_REG_ACCESS_FUNC(readw_relaxed, u16 *)
DEFINE_SFCTRL_REG_ACCESS_FUNC(readl_relaxed, u32 *)
#define sfctrl_write_reg_check_ret(access_type, reg, val) \
do { \
int ret; \
cts_dbg("Write " #reg " to 0x%x", val); \
ret = sfctrl_reg_ ## access_type(cts_dev, reg, val); \
if (ret) { \
cts_err("Write " #reg " failed %d", ret); \
return ret; \
} \
} while (0)
#define sfctrl_read_reg_check_ret(access_type, reg, val) \
do { \
int ret; \
cts_dbg("Read " #reg ""); \
ret = sfctrl_reg_ ## access_type(cts_dev, reg, val); \
if (ret) { \
cts_err("Read " #reg " failed %d", ret); \
return ret; \
} \
} while (0)
static int wait_sfctrl_xfer_comp(struct cts_device *cts_dev)
{
int retries = 0;
u8 status;
do {
sfctrl_read_reg_check_ret(readb_relaxed, rSFCTRLv2_SF_BUSY, &status);
if (status == 0)
return 0;
mdelay(1);
} while (status && retries++ < 1000);
return -ETIMEDOUT;
}
static int sfctrlv2_rdsr(struct cts_device *cts_dev, u8 *status)
{
#define RDSR_XCHG_SRAM_ADDR (cts_dev->hwdata->sfctrl->xchg_sram_base + cts_dev->hwdata->sfctrl->xchg_sram_size - 1)
int ret;
sfctrl_write_reg_check_ret(writeb_relaxed, rSFCTRLv2_CMD_SEL,
SFCTRLv2_CMD_RDSR);
sfctrl_write_reg_check_ret(writel_relaxed, rSFCTRLv2_SRAM_ADDR,
RDSR_XCHG_SRAM_ADDR);
sfctrl_write_reg_check_ret(writeb_relaxed, rSFCTRLv2_START_DEXC, 1);
ret = wait_sfctrl_xfer_comp(cts_dev);
if (ret != 0) {
cts_err("Wait sfctrl ready failed %d", ret);
return ret;
}
ret = cts_sram_readb(cts_dev, RDSR_XCHG_SRAM_ADDR, status);
if (ret) {
cts_err("Read exchange sram failed %d", ret);
return ret;
}
#undef RDSR_XCHG_SRAM_ADDR
return 0;
}
static int wait_flash_wip_clear(struct cts_device *cts_dev)
{
#define FLASH_SR_WIP BIT(0) /*!< Write in progress */
int ret, retries = 0;
u8 status;
do {
ret = sfctrlv2_rdsr(cts_dev, &status);
if (ret) {
cts_err("Read flash status register failed %d", ret);
return ret;
}
if (status & FLASH_SR_WIP)
mdelay(1);
else
return 0;
} while (status & FLASH_SR_WIP && retries++ < 1000);
return -ETIMEDOUT;
#undef FLASH_SR_WIP
}
static int sfctrlv2_transfer(struct cts_device *cts_dev,
u8 cmd, void *data, u32 flash_addr, u32 sram_addr,
size_t size, u32 flags)
{
int ret;
sfctrl_write_reg_check_ret(writeb_relaxed, rSFCTRLv2_CMD_SEL, cmd);
if (flags & SFCTRLv2_OPFLAG_SRAM_DATA_XCHG) {
sfctrl_write_reg_check_ret(writel_relaxed, rSFCTRLv2_SRAM_ADDR,
sram_addr);
/** - Write data to exchange SRAM if operation is write and
* data != NULL(data not in SRAM)
*/
if ((!(flags & SFCTRLv2_OPFLAG_READ)) && data) {
ret = cts_sram_writesb(cts_dev, sram_addr, data, size);
if (ret) {
cts_err("Write data to exchange sram 0x%06x size %zu failed %d",
sram_addr, size, ret);
return ret;
}
}
}
if (flags & SFCTRLv2_OPFLAG_SET_FLASH_ADDR) {
sfctrl_write_reg_check_ret(writel_relaxed, rSFCTRLv2_FLASH_ADDR,
flash_addr);
}
if (flags & SFCTRLv2_OPFLAG_SET_DATA_LENGTH) {
sfctrl_write_reg_check_ret(writel_relaxed,
rSFCTRLv2_DATA_LENGTH, (u32) size);
}
sfctrl_write_reg_check_ret(writeb_relaxed, rSFCTRLv2_START_DEXC, 1);
ret = wait_sfctrl_xfer_comp(cts_dev);
if (ret != 0) {
cts_err("Wait sfctrl ready failed %d", ret);
return ret;
}
ret = wait_flash_wip_clear(cts_dev);
if (flags & SFCTRLv2_OPFLAG_WAIT_WIP_CLR && ret != 0) {
cts_err("Wait WIP clear failed %d", ret);
return ret;
}
if ((flags & SFCTRLv2_OPFLAG_READ) && data) {
ret = cts_sram_readsb(cts_dev, sram_addr, data, size);
if (ret) {
cts_err("Read data from exchange sram 0x%06x size %zu failed %d",
sram_addr, size, ret);
return ret;
}
}
return 0;
}
static int sfctrlv2_rdid(struct cts_device *cts_dev, u32 *id)
{
int ret;
u8 buf[4];
ret = sfctrlv2_transfer(cts_dev, SFCTRLv2_CMD_RDID, buf,
0, cts_dev->hwdata->sfctrl->xchg_sram_base, 3,
SFCTRLv2_CMD_RDID_FLAGS);
*id = ret ? 0 : get_unaligned_be24(buf);
return ret;
}
static int sfctrlv2_se(struct cts_device *cts_dev, u32 sector_addr)
{
return sfctrlv2_transfer(cts_dev, SFCTRLv2_CMD_SE, NULL,
sector_addr, 0, 0, SFCTRLv2_CMD_SE_FLAGS);
}
static int sfctrlv2_be(struct cts_device *cts_dev, u32 block_addr)
{
return sfctrlv2_transfer(cts_dev, SFCTRLv2_CMD_BE, NULL,
block_addr, 0, 0, SFCTRLv2_CMD_BE_FLAGS);
}
static int sfctrlv2_pp(struct cts_device *cts_dev,
u32 flash_addr, const void *src, size_t size)
{
return sfctrlv2_transfer(cts_dev, SFCTRLv2_CMD_PP, (void *)src,
flash_addr, cts_dev->hwdata->sfctrl->xchg_sram_base, size,
SFCTRLv2_CMD_PP_FLAGS);
}
static int sfctrlv2_program_flash_from_sram(struct cts_device *cts_dev,
u32 flash_addr, u32 sram_addr, size_t len)
{
return sfctrlv2_transfer(cts_dev, SFCTRLv2_CMD_PP, NULL,
flash_addr, sram_addr, len, SFCTRLv2_CMD_PP_FLAGS);
}
static int sfctrlv2_read(struct cts_device *cts_dev,
u32 flash_addr, void *dst, size_t size)
{
return sfctrlv2_transfer(cts_dev, SFCTRLv2_CMD_FAST_READ, dst,
flash_addr, cts_dev->hwdata->sfctrl->xchg_sram_base, size,
SFCTRLv2_CMD_FAST_READ_FLAGS);
}
static int sfctrlv2_read_flash_to_sram(struct cts_device *cts_dev,
u32 flash_addr, u32 sram_addr, size_t size)
{
return sfctrlv2_transfer(cts_dev, SFCTRLv2_CMD_FAST_READ, NULL,
flash_addr, sram_addr, size, SFCTRLv2_CMD_FAST_READ_FLAGS);
}
static int sfctrlv2_calc_sram_crc(struct cts_device *cts_dev,
u32 sram_addr, size_t size, u32 *crc)
{
int ret;
sfctrl_write_reg_check_ret(writel_relaxed, rSFCTRLv2_SRAM_ADDR, sram_addr);
mdelay(1);
sfctrl_write_reg_check_ret(writel_relaxed, rSFCTRLv2_DATA_LENGTH, (u32) size);
mdelay(1);
sfctrl_write_reg_check_ret(writeb_relaxed, rSFCTRLv2_SRAM_CRC_START, 1);
mdelay(10);
ret = wait_sfctrl_xfer_comp(cts_dev);
if (ret != 0) {
cts_err("Wait sfctrl ready failed %d", ret);
return ret;
}
sfctrl_read_reg_check_ret(readl_relaxed, rSFCTRLv2_CRC_RESULT, crc);
return 0;
}
static int sfctrlv2_calc_flash_crc(struct cts_device *cts_dev,
u32 flash_addr, size_t size, u32 *crc)
{
int ret;
cts_info("Calc crc from flash 0x%06x size %zu", flash_addr, size);
sfctrl_write_reg_check_ret(writel_relaxed, rSFCTRLv2_FLASH_ADDR, flash_addr);
sfctrl_write_reg_check_ret(writel_relaxed, rSFCTRLv2_DATA_LENGTH, (u32) size);
sfctrl_write_reg_check_ret(writeb_relaxed, rSFCTRLv2_FLASH_CRC_START, 1);
ret = wait_sfctrl_xfer_comp(cts_dev);
if (ret != 0) {
cts_err("Wait sfctrl ready failed %d", ret);
return ret;
}
sfctrl_read_reg_check_ret(readl_relaxed, rSFCTRLv2_CRC_RESULT, crc);
return 0;
}
const struct cts_sfctrl_ops cts_sfctrlv2_ops = {
.rdid = sfctrlv2_rdid,
.se = sfctrlv2_se,
.be = sfctrlv2_be,
.read = sfctrlv2_read,
.read_to_sram = sfctrlv2_read_flash_to_sram,
.program = sfctrlv2_pp,
.program_from_sram = sfctrlv2_program_flash_from_sram,
.calc_sram_crc = sfctrlv2_calc_sram_crc,
.calc_flash_crc = sfctrlv2_calc_flash_crc,
};

View File

@@ -0,0 +1,536 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#define LOG_TAG "Flash"
#include "cts_config.h"
#include "cts_platform.h"
#include "cts_core.h"
#include "cts_sfctrl.h"
#include "cts_spi_flash.h"
#include "cts_strerror.h"
/* NOTE: double check command sets and memory organization when you add
* more flash chips. This current list focusses on newer chips, which
* have been converging on command sets which including JEDEC ID.
*/
static const struct cts_flash cts_flashes[] = {
/* Winbond */
{ "Winbond,W25Q10EW",
0xEF6011, 256, 0x1000, 0x8000, 0x20000},
{ "Winbond,W25Q20EW",
0xEF6012, 256, 0x1000, 0x8000, 0x40000},
{ "Winbond,W25Q40EW",
0xEF6013, 256, 0x1000, 0x8000, 0x80000},
{ "Winbond,W25Q20BW",
0xEF5012, 256, 0x1000, 0x8000, 0x40000},
{ "Winbond,W25Q40BW",
0xEF5013, 256, 0x1000, 0x8000, 0x80000},
/* Giga device */
{ "Giga,GD25LQ10B",
0xC86011, 256, 0x1000, 0x8000, 0x20000},
{ "Giga,GD25LD20CEIGR",
0xC86012, 256, 0x1000, 0x8000, 0x40000},
{ "Giga,GD25LD40CEIGR",
0xC86013, 256, 0x1000, 0x8000, 0x80000},
/* Macronix */
{ "Macronix,MX25U1001E",
0xC22531, 32, 0x1000, 0x10000, 0x20000},
{ "Macronix,MX25R2035F",
0xC22812, 256, 0x1000, 0x8000, 0x40000},
{ "Macronix,MX25R4035F",
0xC22813, 256, 0x1000, 0x8000, 0x80000},
/* Puya-Semi */
{ "Puya-Semi,P25Q20LUVHIR",
0x856012, 256, 0x1000, 0x8000, 0x40000},
{ "Puya-Semi,P25Q40LUXHIR",
0x856013, 256, 0x1000, 0x8000, 0x80000},
{ "Puya-Semi,P25Q11L",
0x854011, 256, 0x1000, 0x8000, 0x20000},
{ "Puya-Semi,P25Q21L",
0x854012, 256, 0x1000, 0x8000, 0x40000},
{ "Puya-Semi,P25T22L",
0x854412, 256, 0x1000, 0x8000, 0x40000},
/* Boya */
{ "Boya,BY25D10",
0x684011, 256, 0x1000, 0x8000, 0x20000},
/* EON */
{ "EoN,EN25S20A",
0x1C3812, 256, 0x1000, 0x8000, 0x40000},
/* XTXTECH */
{ "XTX,XT25Q01",
0x0B6011, 256, 0x1000, 0, 0x20000},
{ "XTX,XT25Q02",
0x0B6012, 256, 0x1000, 0, 0x40000},
/* Xinxin-Semi */
{ "Xinxin-Semi,XM25QU20B",
0x205012, 256, 0x1000, 0x8000, 0x40000},
{ "Xinxin-Semi,XM25QU40B",
0x205013, 256, 0x1000, 0x8000, 0x80000},
{ "KangYong,XK25Q20T",
0xEB6012, 256, 0x1000, 0x8000, 0x40000},
/*ZBIT*/
{ "ZBIT,ZB25LD40B",
0x5E1013, 256, 0x1000, 0x8000, 0x80000},
};
static const struct cts_flash *find_flash_by_jedec_id(u32 jedec_id)
{
int i;
for (i = 0; i < ARRAY_SIZE(cts_flashes); i++) {
if (cts_flashes[i].jedec_id == jedec_id) {
return &cts_flashes[i];
}
}
return NULL;
}
static int probe_flash(struct cts_device *cts_dev)
{
int ret;
cts_info("Probe flash");
if (cts_dev->hwdata->sfctrl->ops->rdid != NULL) {
u32 id;
cts_info("Read JEDEC ID");
ret = cts_dev->hwdata->sfctrl->ops->rdid(cts_dev, &id);
if (ret) {
cts_err("Read JEDEC ID failed %d(%s)",
ret, cts_strerror(ret));
return ret;
}
cts_dev->flash = find_flash_by_jedec_id(id);
if (cts_dev->flash == NULL) {
cts_err("Unknown JEDEC ID: %06x", id);
return -ENODEV;
}
cts_info("Flash type: '%s'", cts_dev->flash->name);
return 0;
} else {
cts_err("Probe flash with sfctrl->ops->rdid == NULL");
return -ENOTSUPP;
}
}
/** Make sure sector addr is sector aligned && < flash total size */
static int erase_sector_retry(struct cts_device *cts_dev,
u32 sector_addr, int retry)
{
int ret, retries;
cts_info(" Erase sector 0x%06x", sector_addr);
retries = 0;
do {
retries++;
ret = cts_dev->hwdata->sfctrl->ops->se(cts_dev, sector_addr);
if (ret) {
cts_err("Erase sector 0x%06x failed %d(%s) retries %d",
sector_addr, ret, cts_strerror(ret), retries);
continue;
}
} while (retries < retry);
return ret;
}
/** Make sure sector addr is sector aligned && < flash total size */
static inline int erase_sector(struct cts_device *cts_dev,
u32 sector_addr)
{
return erase_sector_retry(cts_dev, sector_addr, CTS_FLASH_ERASE_DEFAULT_RETRY);
}
/** Make sure block addr is block aligned && < flash total size */
static int erase_block_retry(struct cts_device *cts_dev,
u32 block_addr, int retry)
{
int ret, retries;
cts_info(" Erase block 0x%06x", block_addr);
retries = 0;
do {
retries++;
ret = cts_dev->hwdata->sfctrl->ops->be(cts_dev, block_addr);
if (ret) {
cts_err("Erase block 0x%06x failed %d(%s) retries %d",
block_addr, ret, cts_strerror(ret), retries);
continue;
}
} while (retries < retry);
return ret;
}
/** Make sure block addr is block aligned && < flash total size */
static inline int erase_block(struct cts_device *cts_dev,
u32 block_addr)
{
return erase_block_retry(cts_dev, block_addr,
CTS_FLASH_ERASE_DEFAULT_RETRY);
}
int cts_prepare_flash_operation(struct cts_device *cts_dev)
{
int ret;
u8 diva = 0;
bool program_mode = cts_is_device_program_mode(cts_dev);
u32 hwid;
bool enabled = cts_is_device_enabled(cts_dev);
cts_info("Prepare for flash operation");
if (!program_mode) {
ret = cts_enter_program_mode(cts_dev);
if (ret) {
cts_err("Enter program mode failed %d(%s)",
ret, cts_strerror(ret));
goto err_start_device;
}
}
ret = cts_hw_reg_readb_retry(cts_dev, CTS_DEV_HW_REG_CLK_DIV_CFG, &diva, 5, 0);
if (ret) {
cts_warn("Read DIVA failed %d(%s)", ret, cts_strerror(ret));
} else {
cts_dbg("Device DIVA = %d", diva);
}
if (ret == 0 && diva == 0x0C) {
cts_info("DIVA is ready already");
} else {
int retries;
/* Set HCLK to 10MHz */
hwid = cts_dev->hwdata->hwid;
if (hwid == CTS_DEV_HWID_ICNL9951) {
ret = cts_hw_reg_writeb_retry(cts_dev, CTS_DEV_HW_REG_CLK_DIV_CFG, 0x0C, 5, 0);
if (ret) {
cts_err("Write DIVA failed %d(%s)",
ret, cts_strerror(ret));
goto err_enter_normal_mode;
}
}
/* Reset SFCTL */
ret = cts_hw_reg_writeb_retry(cts_dev, CTS_DEV_HW_REG_RESET_CONFIG, 0xFB, 5, 0);
if (ret) {
cts_err("Reset sfctl failed %d(%s)",
ret, cts_strerror(ret));
goto err_enter_normal_mode;
}
retries = 0;
do {
u8 state;
ret = cts_hw_reg_readb_relaxed(cts_dev, CTS_DEV_HW_REG_HW_STATUS, &state);
if (ret == 0 && (state & 0x40) != 0)
goto init_flash;
mdelay(2);
} while (++retries < 1000);
if (ret) {
cts_warn("Wait SFCTRL ready failed %d(%s)", ret, cts_strerror(ret));
}
// Go through and try
}
init_flash:
if (cts_dev->flash == NULL) {
cts_info("Flash is not initialized, try to probe...");
if ((ret = probe_flash(cts_dev)) != 0) {
cts_dev->rtdata.has_flash = false;
cts_warn("Probe flash failed %d(%s)",
ret, cts_strerror(ret));
return 0;
}
}
cts_dev->rtdata.has_flash = true;
return 0;
err_enter_normal_mode:
if (!program_mode) {
int r = cts_enter_normal_mode(cts_dev);
if (r) {
cts_err("Enter normal mode failed %d(%s)",
r, cts_strerror(r));
}
}
err_start_device:
if (enabled) {
int r = cts_start_device(cts_dev);
if (r) {
cts_err("Start device failed %d(%s)",
r, cts_strerror(r));
}
}
return ret;
}
int cts_post_flash_operation(struct cts_device *cts_dev)
{
u32 hwid;
cts_info("Post flash operation");
hwid = cts_dev->hwdata->hwid;
if (hwid == CTS_DEV_HWID_ICNL9951) {
return cts_hw_reg_writeb_retry(cts_dev, CTS_DEV_HW_REG_CLK_DIV_CFG, 4, 5, 0);
}
return 0;
}
int cts_read_flash_retry(struct cts_device *cts_dev,
u32 flash_addr, void *dst, size_t size, int retry)
{
const struct cts_sfctrl *sfctrl;
const struct cts_flash *flash;
int ret;
cts_info("Read from 0x%06x size %zu", flash_addr, size);
sfctrl = cts_dev->hwdata->sfctrl;
flash = cts_dev->flash;
if (flash == NULL ||
sfctrl == NULL ||
sfctrl->ops == NULL ||
sfctrl->ops->read == NULL) {
cts_err("Read not supported");
return -ENOTSUPP;
}
if (flash_addr > flash->total_size) {
cts_err("Read from 0x%06x > flash size 0x%06zx",
flash_addr, flash->total_size);
return -EINVAL;
}
size = min(size, flash->total_size - flash_addr);
cts_info("Read actually from 0x%06x size %zu", flash_addr, size);
while (size) {
size_t l;
l = min(sfctrl->xchg_sram_size, size);
ret = sfctrl->ops->read(cts_dev, flash_addr, dst, l);
if(ret < 0) {
cts_err("Read from 0x%06x size %zu failed %d(%s)",
flash_addr, size, ret, cts_strerror(ret));
return ret;
}
dst += l;
size -= l;
flash_addr += l;
}
return 0;
}
int cts_program_flash(struct cts_device *cts_dev,
u32 flash_addr, const void *src, size_t size)
{
const struct cts_sfctrl *sfctrl;
const struct cts_flash *flash;
int ret;
cts_info("Program to 0x%06x size %zu", flash_addr, size);
sfctrl = cts_dev->hwdata->sfctrl;
flash = cts_dev->flash;
if (flash == NULL ||
sfctrl == NULL ||
sfctrl->ops == NULL ||
sfctrl->ops->program == NULL) {
cts_err("Program not supported");
return -ENOTSUPP;
}
if (flash_addr >= flash->total_size) {
cts_err("Program from 0x%06x >= flash size 0x%06zx",
flash_addr, flash->total_size);
return -EINVAL;
}
size = min(size, flash->total_size - flash_addr);
cts_info("Program actually to 0x%06x size %zu", flash_addr, size);
while (size) {
size_t l, offset;
l = min(flash->page_size, size);
offset = flash_addr & (flash->page_size - 1);
if (offset) {
l = min(flash->page_size - offset, l);
}
ret = sfctrl->ops->program(cts_dev, flash_addr, src, l);
if(ret) {
cts_err("Program to 0x%06x size %zu failed %d(%s)",
flash_addr, l, ret, cts_strerror(ret));
return ret;
}
src += l;
size -= l;
flash_addr += l;
}
return 0;
}
int cts_program_flash_from_sram(struct cts_device *cts_dev,
u32 flash_addr, u32 sram_addr, size_t size)
{
const struct cts_sfctrl *sfctrl;
const struct cts_flash *flash;
int ret;
cts_info("Program to 0x%06x from sram 0x%06x size %zu",
flash_addr, sram_addr, size);
sfctrl = cts_dev->hwdata->sfctrl;
flash = cts_dev->flash;
if (flash == NULL ||
sfctrl == NULL ||
sfctrl->ops == NULL ||
sfctrl->ops->program_from_sram == NULL) {
cts_err("Program from sram not supported");
return -ENOTSUPP;
}
if (flash_addr >= flash->total_size) {
cts_err("Program from 0x%06x >= flash size 0x%06zx",
flash_addr, flash->total_size);
return -EINVAL;
}
size = min(size, flash->total_size - flash_addr);
cts_info("Program actually to 0x%06x from sram 0x%06x size %zu",
flash_addr, sram_addr, size);
while (size) {
size_t l, offset;
l = min(flash->page_size, size);
offset = flash_addr & (flash->page_size - 1);
if (offset) {
l = min(flash->page_size - offset, l);
}
ret = sfctrl->ops->program_from_sram(cts_dev,
flash_addr, sram_addr, l);
if(ret) {
cts_err("Program to 0x%06x from sram 0x%06x size %zu "
"failed %d(%s)",
flash_addr, sram_addr, l, ret, cts_strerror(ret));
return ret;
}
size -= l;
flash_addr += l;
sram_addr += l;
}
return 0;
}
int cts_erase_flash(struct cts_device *cts_dev, u32 addr, size_t size)
{
const struct cts_sfctrl *sfctrl;
const struct cts_flash *flash;
int ret;
cts_info("Erase from 0x%06x size %zu", addr, size);
sfctrl = cts_dev->hwdata->sfctrl;
flash = cts_dev->flash;
if (flash == NULL ||
sfctrl == NULL || sfctrl->ops == NULL ||
sfctrl->ops->se == NULL || sfctrl->ops->be == NULL ||
flash == NULL) {
cts_err("Oops");
return -EINVAL;
}
/* Addr and size MUST sector aligned */
addr = rounddown(addr, flash->sector_size);
size = roundup(size, flash->sector_size);
if (addr > flash->total_size) {
cts_err("Erase from 0x%06x > flash size 0x%06zx",
addr, flash->total_size);
return -EINVAL;
}
size = min(size, flash->total_size - addr);
cts_info("Erase actually from 0x%06x size %zu", addr, size);
if (flash->block_size) {
while (addr != ALIGN(addr, flash->block_size) &&
size >= flash->sector_size) {
ret = erase_sector(cts_dev, addr);
if (ret) {
cts_err("Erase sector 0x%06x size 0x%04zx failed %d(%s)",
addr, flash->sector_size, ret, cts_strerror(ret));
return ret;
}
addr += flash->sector_size;
size -= flash->sector_size;
}
while (size >= flash->block_size) {
ret = erase_block(cts_dev, addr);
if (ret) {
cts_err("Erase block 0x%06x size 0x%04zx failed %d(%s)",
addr, flash->block_size, ret, cts_strerror(ret));
return ret;
}
addr += flash->block_size;
size -= flash->block_size;
}
}
while (size >= flash->sector_size) {
ret = erase_sector(cts_dev, addr);
if (ret) {
cts_err("Erase sector 0x%06x size 0x%04zx failed %d(%s)",
addr, flash->sector_size, ret, cts_strerror(ret));
return ret;
}
addr += flash->sector_size;
size -= flash->sector_size;
}
return 0;
}

View File

@@ -0,0 +1,45 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef CTS_SPI_FLASH_H
#define CTS_SPI_FLASH_H
struct cts_flash {
const char *name;
u32 jedec_id; /* Device ID by command 0x9F */
size_t page_size; /* Page size by command 0x02 */
size_t sector_size; /* Sector size by command 0x20 */
/* Block size by command 0x52,
* if 0 means block erase NOT supported
*/
size_t block_size;
size_t total_size;
};
#define CTS_FLASH_READ_DEFAULT_RETRY (3)
#define CTS_FLASH_ERASE_DEFAULT_RETRY (3)
struct cts_device;
extern int cts_prepare_flash_operation(struct cts_device *cts_dev);
extern int cts_post_flash_operation(struct cts_device *cts_dev);
extern int cts_read_flash_retry(struct cts_device *cts_dev,
u32 flash_addr, void *dst, size_t size, int retry);
static inline int cts_read_flash(struct cts_device *cts_dev,
u32 flash_addr, void *dst, size_t size)
{
return cts_read_flash_retry(cts_dev, flash_addr, dst, size,
CTS_FLASH_READ_DEFAULT_RETRY);
}
extern int cts_erase_flash(struct cts_device *cts_dev, u32 addr,
size_t size);
extern int cts_program_flash(struct cts_device *cts_dev,
u32 flash_addr, const void *src, size_t size);
extern int cts_program_flash_from_sram(struct cts_device *cts_dev,
u32 flash_addr, u32 sram_addr, size_t size);
#endif /* CTS_SPI_FLASH_H */

View File

@@ -0,0 +1,175 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#include <linux/kernel.h>
#include <linux/errno.h>
#include "cts_strerror.h"
#define ERROR_TEXT_ENTRY(errno, err_desc_str) \
[(errno)] = #errno ", " err_desc_str
static char *_error_text[] = {
[0] = "Success",
ERROR_TEXT_ENTRY(EPERM, "Operation not permitted"),
ERROR_TEXT_ENTRY(ENOENT, "No such file or directory"),
ERROR_TEXT_ENTRY(ESRCH, "No such process"),
ERROR_TEXT_ENTRY(EINTR, "Interrupted system call"),
ERROR_TEXT_ENTRY(EIO, "Input/output error"),
ERROR_TEXT_ENTRY(ENXIO, "No such device or address"),
ERROR_TEXT_ENTRY(E2BIG, "Argument list too long"),
ERROR_TEXT_ENTRY(ENOEXEC, "Exec format error"),
ERROR_TEXT_ENTRY(EBADF, "Bad file descriptor"),
ERROR_TEXT_ENTRY(ECHILD, "No child processes"),
ERROR_TEXT_ENTRY(EAGAIN, "Resource temporarily unavailable"),
ERROR_TEXT_ENTRY(ENOMEM, "Cannot allocate memory"),
ERROR_TEXT_ENTRY(EACCES, "Permission denied"),
ERROR_TEXT_ENTRY(EFAULT, "Bad address"),
ERROR_TEXT_ENTRY(ENOTBLK, "Block device required"),
ERROR_TEXT_ENTRY(EBUSY, "Device or resource busy"),
ERROR_TEXT_ENTRY(EEXIST, "File exists"),
ERROR_TEXT_ENTRY(EXDEV, "Invalid cross-device link"),
ERROR_TEXT_ENTRY(ENODEV, "No such device"),
ERROR_TEXT_ENTRY(ENOTDIR, "Not a directory"),
ERROR_TEXT_ENTRY(EISDIR, "Is a directory"),
ERROR_TEXT_ENTRY(EINVAL, "Invalid argument"),
ERROR_TEXT_ENTRY(EMFILE, "Too many open files"),
ERROR_TEXT_ENTRY(ENFILE, "Too many open files in system"),
ERROR_TEXT_ENTRY(ENOTTY, "Inappropriate ioctl for device"),
ERROR_TEXT_ENTRY(ETXTBSY, "Text file busy"),
ERROR_TEXT_ENTRY(EFBIG, "File too large"),
ERROR_TEXT_ENTRY(ENOSPC, "No space left on device"),
ERROR_TEXT_ENTRY(ESPIPE, "Illegal seek"),
ERROR_TEXT_ENTRY(EROFS, "Read-only file system"),
ERROR_TEXT_ENTRY(EMLINK, "Too many links"),
ERROR_TEXT_ENTRY(EPIPE, "Broken pipe"),
ERROR_TEXT_ENTRY(EDOM, "Numerical argument out of domain"),
ERROR_TEXT_ENTRY(ERANGE, "Numerical result out of range"),
ERROR_TEXT_ENTRY(EDEADLK, "Resource deadlock avoided"),
ERROR_TEXT_ENTRY(ENAMETOOLONG, "File name too long"),
ERROR_TEXT_ENTRY(ENOLCK, "No locks available"),
ERROR_TEXT_ENTRY(ENOSYS, "Function not implemented"),
ERROR_TEXT_ENTRY(ENOTEMPTY, "Directory not empty"),
ERROR_TEXT_ENTRY(ELOOP, "Too many levels of symbolic links"),
ERROR_TEXT_ENTRY(EWOULDBLOCK, "Operation would block"),
ERROR_TEXT_ENTRY(ENOMSG, "No message of desired type"),
ERROR_TEXT_ENTRY(EIDRM, "Identifier removed"),
ERROR_TEXT_ENTRY(ECHRNG, "Channel number out of range"),
ERROR_TEXT_ENTRY(EL2NSYNC, "Level 2 not synchronized"),
ERROR_TEXT_ENTRY(EL3HLT, "Level 3 halted"),
ERROR_TEXT_ENTRY(EL3RST, "Level 3 reset"),
ERROR_TEXT_ENTRY(ELNRNG, "Link number out of range"),
ERROR_TEXT_ENTRY(EUNATCH, "Protocol driver not attached"),
ERROR_TEXT_ENTRY(ENOCSI, "No CSI structure available"),
ERROR_TEXT_ENTRY(EL2HLT, "Level 2 halted"),
ERROR_TEXT_ENTRY(EBADE, "Invalid exchange"),
ERROR_TEXT_ENTRY(EBADR, "Invalid request descriptor"),
ERROR_TEXT_ENTRY(EXFULL, "Exchange full"),
ERROR_TEXT_ENTRY(ENOANO, "No anode"),
ERROR_TEXT_ENTRY(EBADRQC, "Invalid request code"),
ERROR_TEXT_ENTRY(EBADSLT, "Invalid slot"),
ERROR_TEXT_ENTRY(EDEADLOCK, "File locking deadlock error"),
ERROR_TEXT_ENTRY(EBFONT, "Bad font file format"),
ERROR_TEXT_ENTRY(ENOSTR, "Device not a stream"),
ERROR_TEXT_ENTRY(ENODATA, "No data available"),
ERROR_TEXT_ENTRY(ETIME, "Timer expired"),
ERROR_TEXT_ENTRY(ENOSR, "Out of streams resources"),
ERROR_TEXT_ENTRY(ENONET, "Machine is not on the network"),
ERROR_TEXT_ENTRY(ENOPKG, "Package not installed"),
ERROR_TEXT_ENTRY(EREMOTE, "Object is remote"),
ERROR_TEXT_ENTRY(ENOLINK, "Link has been severed"),
ERROR_TEXT_ENTRY(EADV, "Advertise error"),
ERROR_TEXT_ENTRY(ESRMNT, "Srmount error"),
ERROR_TEXT_ENTRY(ECOMM, "Communication error on send"),
ERROR_TEXT_ENTRY(EPROTO, "Protocol error"),
ERROR_TEXT_ENTRY(EMULTIHOP, "Multihop attempted"),
ERROR_TEXT_ENTRY(EDOTDOT, "RFS specific error"),
ERROR_TEXT_ENTRY(EBADMSG, "Bad message"),
ERROR_TEXT_ENTRY(EOVERFLOW, "Value too large for defined data type"),
ERROR_TEXT_ENTRY(ENOTUNIQ, "Name not unique on network"),
ERROR_TEXT_ENTRY(EBADFD, "File descriptor in bad state"),
ERROR_TEXT_ENTRY(EREMCHG, "Remote address changed"),
ERROR_TEXT_ENTRY(ELIBACC, "Can not access a needed shared library"),
ERROR_TEXT_ENTRY(ELIBBAD, "Accessing a corrupted shared library"),
ERROR_TEXT_ENTRY(ELIBSCN, ".lib section in a.out corrupted"),
ERROR_TEXT_ENTRY(ELIBMAX, "Attempting to link in too many shared libraries"),
ERROR_TEXT_ENTRY(ELIBEXEC, "Cannot exec a shared library directly"),
ERROR_TEXT_ENTRY(EILSEQ, "Invalid or incomplete multibyte or wide character"),
ERROR_TEXT_ENTRY(ERESTART, "Interrupted system call should be restarted"),
ERROR_TEXT_ENTRY(ESTRPIPE, "Streams pipe error"),
ERROR_TEXT_ENTRY(EUSERS, "Too many users"),
ERROR_TEXT_ENTRY(ENOTSOCK, "Socket operation on non-socket"),
ERROR_TEXT_ENTRY(EDESTADDRREQ, "Destination address required"),
ERROR_TEXT_ENTRY(EMSGSIZE, "Message too long"),
ERROR_TEXT_ENTRY(EPROTOTYPE, "Protocol wrong type for socket"),
ERROR_TEXT_ENTRY(ENOPROTOOPT, "Protocol not available"),
ERROR_TEXT_ENTRY(EPROTONOSUPPORT, "Protocol not supported"),
ERROR_TEXT_ENTRY(ESOCKTNOSUPPORT, "Socket type not supported"),
ERROR_TEXT_ENTRY(EOPNOTSUPP, "Operation not supported"),
ERROR_TEXT_ENTRY(EPFNOSUPPORT, "Protocol family not supported"),
ERROR_TEXT_ENTRY(EAFNOSUPPORT, "Address family not supported by protocol"),
ERROR_TEXT_ENTRY(EADDRINUSE, "Address already in use"),
ERROR_TEXT_ENTRY(EADDRNOTAVAIL, "Cannot assign requested address"),
ERROR_TEXT_ENTRY(ENETDOWN, "Network is down"),
ERROR_TEXT_ENTRY(ENETUNREACH, "Network is unreachable"),
ERROR_TEXT_ENTRY(ENETRESET, "Network dropped connection on reset"),
ERROR_TEXT_ENTRY(ECONNABORTED, "Software caused connection abort"),
ERROR_TEXT_ENTRY(ECONNRESET, "Connection reset by peer"),
ERROR_TEXT_ENTRY(ENOBUFS, "No buffer space available"),
ERROR_TEXT_ENTRY(EISCONN, "Transport endpoint is already connected"),
ERROR_TEXT_ENTRY(ENOTCONN, "Transport endpoint is not connected"),
ERROR_TEXT_ENTRY(ESHUTDOWN, "Cannot send after transport endpoint shutdown"),
ERROR_TEXT_ENTRY(ETOOMANYREFS, "Too many references: cannot splice"),
ERROR_TEXT_ENTRY(ETIMEDOUT, "Connection timed out"),
ERROR_TEXT_ENTRY(ECONNREFUSED, "Connection refused"),
ERROR_TEXT_ENTRY(EHOSTDOWN, "Host is down"),
ERROR_TEXT_ENTRY(EHOSTUNREACH, "No route to host"),
ERROR_TEXT_ENTRY(EALREADY, "Operation already in progress"),
ERROR_TEXT_ENTRY(EINPROGRESS, "Operation now in progress"),
ERROR_TEXT_ENTRY(ESTALE, "Stale file handle"),
ERROR_TEXT_ENTRY(EUCLEAN, "Structure needs cleaning"),
ERROR_TEXT_ENTRY(ENOTNAM, "Not a XENIX named type file"),
ERROR_TEXT_ENTRY(ENAVAIL, "No XENIX semaphores available"),
ERROR_TEXT_ENTRY(EISNAM, "Is a named type file"),
ERROR_TEXT_ENTRY(EREMOTEIO, "Remote I/O error"),
ERROR_TEXT_ENTRY(EDQUOT, "Disk quota exceeded"),
ERROR_TEXT_ENTRY(ENOMEDIUM, "No medium found"),
ERROR_TEXT_ENTRY(EMEDIUMTYPE, "Wrong medium type"),
ERROR_TEXT_ENTRY(ECANCELED, "Operation canceled"),
ERROR_TEXT_ENTRY(ENOKEY, "Required key not available"),
ERROR_TEXT_ENTRY(EKEYEXPIRED, "Key has expired"),
ERROR_TEXT_ENTRY(EKEYREVOKED, "Key has been revoked"),
ERROR_TEXT_ENTRY(EKEYREJECTED, "Key was rejected by service"),
ERROR_TEXT_ENTRY(EOWNERDEAD, "Owner died"),
ERROR_TEXT_ENTRY(ENOTRECOVERABLE, "State not recoverable"),
ERROR_TEXT_ENTRY(ERFKILL, "Operation not possible due to RF-kill"),
ERROR_TEXT_ENTRY(EHWPOISON, "Memory page has hardware error"),
ERROR_TEXT_ENTRY(ERESTARTSYS, "Restart system"),
ERROR_TEXT_ENTRY(ERESTARTNOINTR, "Restart monitor"),
ERROR_TEXT_ENTRY(ERESTARTNOHAND, "Restart if no handler"),
ERROR_TEXT_ENTRY(ENOIOCTLCMD, "No ioctl command"),
ERROR_TEXT_ENTRY(ERESTART_RESTARTBLOCK, "Restart by calling sys_restart_syscall"),
ERROR_TEXT_ENTRY(EPROBE_DEFER, "Driver requests probe retry"),
ERROR_TEXT_ENTRY(EOPENSTALE, "Open found a stale dentry"),
ERROR_TEXT_ENTRY(EBADHANDLE, "Illegal NFS file handle"),
ERROR_TEXT_ENTRY(ENOTSYNC, "Update synchronization mismatch"),
ERROR_TEXT_ENTRY(EBADCOOKIE, "Cookie is stale"),
ERROR_TEXT_ENTRY(ENOTSUPP, "Operation is not supported"),
ERROR_TEXT_ENTRY(ETOOSMALL, "Buffer or request is too small"),
ERROR_TEXT_ENTRY(ESERVERFAULT, "An untranslatable error occurred"),
ERROR_TEXT_ENTRY(EBADTYPE, "Type not supported by server"),
ERROR_TEXT_ENTRY(EJUKEBOX, "Request initiated, but will not complete before timeout"),
ERROR_TEXT_ENTRY(EIOCBQUEUED, "IOCB queued, will get completion event"),
};
#define ERROR_TEXT_ARRAY_SIZE (sizeof(_error_text) / sizeof(_error_text[0]))
char *cts_strerror(int errno)
{
if (errno > 0) {
return "<valid offset/length>";
} else if (-errno < (int) ERROR_TEXT_ARRAY_SIZE) {
char *s = _error_text[-errno];
if (s) {
return s;
}
}
return "<Unknown error>";
}

View File

@@ -0,0 +1,11 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef CTS_STRERROR_H
#define CTS_STRERROR_H
#define CTS_ERR_FMT_STR "%d(%s)"
#define CTS_ERR_ARG(errno) cts_strerror(errno)
char *cts_strerror(int errno);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,27 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef CTS_SYSFS_H
#define CTS_SYSFS_H
#include "cts_config.h"
struct device;
#ifdef CONFIG_CTS_SYSFS
extern int cts_argc;
extern char *cts_argv[];
extern int cts_sysfs_add_device(struct device *dev);
extern void cts_sysfs_remove_device(struct device *dev);
extern int cts_parse_arg(const char *buf, size_t count);
#else /* CONFIG_CTS_SYSFS */
static inline int cts_sysfs_add_device(struct device *dev)
{
return -ENOTSUPP;
}
static inline void cts_sysfs_remove_device(struct device *dev)
{
}
#endif /* CONFIG_CTS_SYSFS */
#endif /* CTS_SYSFS_H */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,127 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef _CTS_TCS_H_
#define _CTS_TCS_H_
int cts_tcs_read(struct cts_device *cts_dev,
u16 cmd, u8 *buf, size_t len);
int cts_tcs_write(struct cts_device *cts_dev,
u16 cmd, u8 *buf, size_t len);
int cts_tcs_get_hwid_info(struct cts_device *cts_dev, u8 *info);
int cts_tcs_get_fw_ver(struct cts_device *cts_dev, u16 *fwver);
int cts_tcs_get_lib_ver(struct cts_device *cts_dev, u16 *libver);
int cts_tcs_get_ddi_ver(struct cts_device *cts_dev, u8 *ddiver);
int cts_tcs_get_res_x(struct cts_device *cts_dev, u16 *res_x);
int cts_tcs_get_res_y(struct cts_device *cts_dev, u16 *res_y);
int cts_tcs_get_rows(struct cts_device *cts_dev, u8 *rows);
int cts_tcs_get_cols(struct cts_device *cts_dev, u8 *cols);
int cts_tcs_get_rx_tx_info(struct cts_device *cts_dev, u8 *info);
int cts_tcs_get_panel_rx_tx_info(struct cts_device *cts_dev, u8 *info);
int cts_tcs_get_flip_x(struct cts_device *cts_dev, bool *flip_x);
int cts_tcs_get_flip_y(struct cts_device *cts_dev, bool *flip_y);
int cts_tcs_get_swap_axes(struct cts_device *cts_dev, bool *swap_axes);
int cts_tcs_clr_gstr_ready_flag(struct cts_device *cts_dev);
int cts_tcs_get_int_mode(struct cts_device *cts_dev, u8 *int_mode);
int cts_tcs_get_int_keep_time(struct cts_device *cts_dev,
u16 *int_keep_time);
int cts_tcs_get_rawdata_target(struct cts_device *cts_dev,
u16 *rawdata_target);
int cts_tcs_get_esd_method(struct cts_device *cts_dev, u8 *esd_method);
int cts_tcs_get_touchinfo(struct cts_device *cts_dev,
struct cts_device_touch_info *touch_info);
int cts_tcs_get_gestureinfo(struct cts_device *cts_dev,
struct cts_device_gesture_info *gesture_info);
int cts_tcs_get_touch_status(struct cts_device *cts_dev);
int cts_tcs_get_esd_protection(struct cts_device *cts_dev,
u8 *esd_protection);
int cts_tcs_read_hw_reg(struct cts_device *cts_dev, u32 addr,
u8 *buf, size_t size);
int cts_tcs_write_hw_reg(struct cts_device *cts_dev, u32 addr,
u8 *buf, size_t size);
int cts_tcs_read_ddi_reg(struct cts_device *cts_dev, u32 addr,
u8 *regbuf, size_t size);
int cts_tcs_write_ddi_reg(struct cts_device *cts_dev, u32 addr,
u8 *regbuf, size_t size);
int cts_tcs_read_reg(struct cts_device *cts_dev, u32 addr,
u8 *buf, size_t size);
int cts_tcs_write_reg(struct cts_device *cts_dev, u32 addr,
u8 *buf, size_t size);
int cts_tcs_get_fw_id(struct cts_device *cts_dev, u16 *fwid);
int cts_tcs_get_workmode(struct cts_device *cts_dev, u8 *workmode);
int cts_tcs_set_workmode(struct cts_device *cts_dev, u8 workmode);
int cts_tcs_set_openshort_mode(struct cts_device *cts_dev, u8 mode);
int cts_tcs_get_curr_mode(struct cts_device *cts_dev, u8 *currmode);
int cts_tcs_get_krang_current_workmode(struct cts_device *cts_dev, u8 *workmode);
int cts_tcs_set_krang_workmode(struct cts_device *cts_dev, u8 workmode);
int cts_tcs_set_tx_vol(struct cts_device *cts_dev, u8 txvol);
int cts_tcs_set_short_test_type(struct cts_device *cts_dev, u8 short_type);
int cts_tcs_set_openshort_enable(struct cts_device *cts_dev, u8 enable);
int cts_tcs_is_openshort_enabled(struct cts_device *cts_dev, u8 *enabled);
int cts_tcs_set_esd_enable(struct cts_device *cts_dev, u8 enable);
int cts_tcs_set_cneg_enable(struct cts_device *cts_dev, u8 enable);
int cts_tcs_set_mnt_enable(struct cts_device *cts_dev, u8 enable);
int cts_tcs_is_display_on(struct cts_device *cts_dev, u8 *display_on);
int cts_tcs_set_display_on(struct cts_device *cts_dev, u8 display_on);
int cts_tcs_is_cneg_enabled(struct cts_device *cts_dev, u8 *enabled);
int cts_tcs_is_mnt_enabled(struct cts_device *cts_dev, u8 *enabled);
int cts_tcs_set_pwr_mode(struct cts_device *cts_dev, u8 pwr_mode);
int cts_tcs_get_has_int_data(struct cts_device *cts_dev, bool *has);
int cts_tcs_get_int_data_types(struct cts_device *cts_dev, u16 *type);
int cts_tcs_set_int_data_types(struct cts_device *cts_dev, u16 type);
int cts_tcs_get_int_data_method(struct cts_device *cts_dev, u8 *method);
int cts_tcs_set_int_data_method(struct cts_device *cts_dev, u8 method);
int cts_tcs_calc_int_data_size(struct cts_device *cts_dev);
int cts_tcs_polling_data(struct cts_device *cts_dev,u8 *buf, size_t size);
int cts_polling_test_data(struct cts_device *cts_dev,
u8 *buf, size_t size, enum int_data_type type);
int cts_tcs_tool_get_rawdata(struct cts_device *cts_dev, u8 *buf, u16 data_source);
int cts_tcs_tool_get_manual_diff(struct cts_device *cts_dev, u8 *buf, u16 data_source);
int cts_tcs_tool_get_real_diff(struct cts_device *cts_dev, u8 *buf, u16 data_source);
int cts_tcs_tool_get_basedata(struct cts_device *cts_dev, u8 *buf, u16 data_source);
int cts_tcs_top_get_rawdata(struct cts_device *cts_dev, u8 *buf, size_t size,
u16 data_source);
int cts_tcs_top_get_manual_diff(struct cts_device *cts_dev, u8 *buf,
size_t size, u16 data_source);
int cts_tcs_top_get_real_diff(struct cts_device *cts_dev, u8 *buf, size_t size,
u16 data_source);
int cts_tcs_top_get_noise_diff(struct cts_device *cts_dev, u8 *buf,size_t size,
u16 data_source);
int cts_tcs_top_get_basedata(struct cts_device *cts_dev, u8 *buf, size_t size,
u16 data_source);
int cts_tcs_top_get_cnegdata(struct cts_device *cts_dev, u8 *buf, size_t size,
u16 data_source);
int cts_tcs_reset_device(struct cts_device *cts_dev);
int cts_tcs_set_int_test(struct cts_device *cts_dev, u8 enable);
int cts_tcs_set_int_pin(struct cts_device *cts_dev, u8 high);
int cts_tcs_get_module_id(struct cts_device *cts_dev, u32 *modId);
int cts_tcs_tool_xtrans(struct cts_device *cts_dev, u8 *tx, size_t txlen,
u8 *rx, size_t rxlen);
int cts_tcs_set_charger_plug(struct cts_device *cts_dev, u8 set);
int cts_tcs_get_charger_plug(struct cts_device *cts_dev, u8 *isset);
int cts_tcs_set_earjack_plug(struct cts_device *cts_dev, u8 set);
int cts_tcs_get_earjack_plug(struct cts_device *cts_dev, u8 *isset);
int cts_tcs_set_panel_direction(struct cts_device *cts_dev, u8 direction);
int cts_tcs_get_panel_direction(struct cts_device *cts_dev, u8 *direction);
int cts_tcs_set_game_mode(struct cts_device *cts_dev, u8 enable);
int cts_tcs_get_game_mode(struct cts_device *cts_dev, u8 *enabled);
int cts_tcs_set_proximity_mode(struct cts_device *cts_dev, u8 enable);
void cts_tcs_reinit_fw_status(struct cts_device *cts_dev);
int cts_tcs_set_product_en(struct cts_device *cts_dev, u8 enable);
int cts_tcs_wait_krang_stop(struct cts_device *cts_dev);
extern int cts_tcs_set_glove_mode(struct cts_device *cts_dev, u8 enable);
#endif /* _CTS_TCS_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,113 @@
// SPDX-License-Identifier: GPL-2.0-or-later
#ifndef CTS_TEST_H
#define CTS_TEST_H
struct cts_device;
#define CTS_TEST_FLAG_RESET_BEFORE_TEST (1u << 0)
#define CTS_TEST_FLAG_RESET_AFTER_TEST (1u << 1)
#define CTS_TEST_FLAG_DISPLAY_ON (1u << 2)
#define CTS_TEST_FLAG_DISABLE_GAS (1u << 3)
#define CTS_TEST_FLAG_DISABLE_LINESHIFT (1u << 4)
#define CTS_TEST_FLAG_VALIDATE_DATA (1u << 8)
#define CTS_TEST_FLAG_VALIDATE_PER_NODE (1u << 9)
#define CTS_TEST_FLAG_VALIDATE_MIN (1u << 10)
#define CTS_TEST_FLAG_VALIDATE_MAX (1u << 11)
#define CTS_TEST_FLAG_VALIDATE_SKIP_INVALID_NODE (1u << 12)
#define CTS_TEST_FLAG_STOP_TEST_IF_VALIDATE_FAILED (1u << 13)
#define CTS_TEST_FLAG_DUMP_TEST_DATA_TO_CONSOLE (1u << 16)
#define CTS_TEST_FLAG_DUMP_TEST_DATA_TO_USERSPACE (1u << 17)
#define CTS_TEST_FLAG_DUMP_TEST_DATA_TO_FILE (1u << 18)
#define CTS_TEST_FLAG_DUMP_TEST_DATA_TO_FILE_APPEND (1u << 19)
#define CTS_TEST_FLAG_DUMP_TEST_DATA_TO_FILE_CSV (1u << 20)
#define CTS_TEST_FLAG_DRIVER_LOG_TO_USERSPACE (1u << 24)
#define CTS_TEST_FLAG_DRIVER_LOG_TO_FILE (1u << 25)
#define CTS_TEST_FLAG_DRIVER_LOG_TO_FILE_APPEND (1u << 26)
#define MAKE_INVALID_NODE(r, c) (((c) << 16) | (r))
#define INVALID_NODE_ROW(node) ((u16)(node))
#define INVALID_NODE_COL(node) ((u16)((node) >> 16))
enum cts_test_item {
CTS_TEST_RESET_PIN = 1,
CTS_TEST_INT_PIN,
CTS_TEST_RAWDATA,
CTS_TEST_NOISE,
CTS_TEST_OPEN,
CTS_TEST_SHORT,
CTS_TEST_COMPENSATE_CAP,
CTS_TEST_STYLUS_RAWDATA,
CTS_TEST_STYLUS_NOISE,
};
struct cts_test_param {
int test_item;
__u32 flags;
__u32 num_invalid_node;
__u32 *invalid_nodes;
int *min;
int *max;
int *test_result;
s64 *elapsed_time_ms;
void *test_data_buf;
int test_data_buf_size;
int *test_data_wr_size;
const char *test_data_filepath;
int driver_log_level;
char *driver_log_buf;
int driver_log_buf_size;
int *driver_log_wr_size;
const char *driver_log_filepath;
void *priv_param;
int priv_param_size;
};
struct cts_rawdata_test_priv_param {
__u32 frames;
//__u8 work_mode;
};
struct cts_noise_test_priv_param {
__u32 frames;
//__u8 work_mode;
};
extern const char *cts_test_item_str(int test_item);
extern int cts_write_file(struct file *filp, const void *data, size_t size);
extern int cts_mkdir_for_file(const char *filepath, umode_t mode);
extern int cts_start_dump_test_data_to_file(const char *filepath,
bool append_to_file);
extern void cts_stop_dump_test_data_to_file(void);
extern int cts_test_reset_pin(struct cts_device *cts_dev,
struct cts_test_param *param);
extern int cts_test_int_pin(struct cts_device *cts_dev,
struct cts_test_param *param);
extern int cts_test_rawdata(struct cts_device *cts_dev,
struct cts_test_param *param);
extern int cts_test_noise(struct cts_device *cts_dev,
struct cts_test_param *param);
extern int cts_test_open(struct cts_device *cts_dev,
struct cts_test_param *param);
extern int cts_test_short(struct cts_device *cts_dev,
struct cts_test_param *param);
extern int cts_test_compensate_cap(struct cts_device *cts_dev,
struct cts_test_param *param);
extern int cts_test_stylus_rawdata(struct cts_device *cts_dev,
struct cts_test_param *param);
extern int cts_test_stylus_noise(struct cts_device *cts_dev,
struct cts_test_param *param);
extern int cts_test_stylus_mnt_rawdata(struct cts_device *cts_dev,
struct cts_test_param *param);
#endif /* CTS_TEST_H */

File diff suppressed because it is too large Load Diff