mirror of
https://github.com/BobTheBlinker/android_kernel_motorola_sm6375.git
synced 2026-10-14 16:46:15 -04:00
dlkm: chipone_tddi_fhd: add initial chipone fhd tddi driver
chipone_tddi_fhd_mmi: Add initial fhd tddi touch driver. This driver is for icnl9922 and later fhd driver. Change-Id: I2cce6e8d624e56fbaae963c4da47ad0c063f7e65 Reviewed-on: https://gerrit.mot.com/2209608 SME-Granted: SME Approvals Granted SLTApproved: Slta Waiver Tested-by: Jira Key Reviewed-by: Yeqing Wang <wangyq13@motorola.com> Reviewed-by: Huosheng Liao <liaohs@motorola.com> Reviewed-by: Jun Weng <wengjun1@motorola.com> Submit-Approved: panyq6 <panyq6@motorola.com>
This commit is contained in:
parent
a83c42120f
commit
a0a0b42641
28 changed files with 17707 additions and 0 deletions
17
drivers/input/touchscreen/chipone_tddi_fhd_mmi/Android.mk
Normal file
17
drivers/input/touchscreen/chipone_tddi_fhd_mmi/Android.mk
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
DLKM_DIR := motorola/kernel/modules
|
||||
LOCAL_PATH := $(call my-dir)
|
||||
|
||||
ifeq ($(DLKM_INSTALL_TO_VENDOR_OUT),true)
|
||||
CHIPONE_MMI_MODULE_PATH := $(TARGET_OUT_VENDOR)/lib/modules/
|
||||
else
|
||||
CHIPONE_MMI_MODULE_PATH := $(KERNEL_MODULES_OUT)
|
||||
endif
|
||||
ifeq ($(CHIPONE_ESD),true)
|
||||
KERNEL_CFLAGS += CONFIG_CHIPONE_ESD=y
|
||||
endif
|
||||
|
||||
include $(CLEAR_VARS)
|
||||
LOCAL_MODULE := chipone_tddi_fhd_mmi.ko
|
||||
LOCAL_MODULE_TAGS := optional
|
||||
LOCAL_MODULE_PATH := $(CHIPONE_MMI_MODULE_PATH)
|
||||
include $(DLKM_DIR)/AndroidKernelModule.mk
|
||||
26
drivers/input/touchscreen/chipone_tddi_fhd_mmi/Kbuild
Normal file
26
drivers/input/touchscreen/chipone_tddi_fhd_mmi/Kbuild
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
# add -Wall to try to catch everything we can.
|
||||
EXTRA_CFLAGS += -Wall
|
||||
EXTRA_CFLAGS += -I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/include \
|
||||
-I$(ANDROID_BUILD_TOP)/motorola/kernel/modules/drivers/input/touchscreen/chipone_tddi_fhd_mmi
|
||||
ifneq ($(filter m y,$(CONFIG_CHIPONE_ESD)),)
|
||||
EXTRA_CFLAGS += -DCONFIG_CTS_ESD_PROTECTION
|
||||
endif
|
||||
|
||||
#EXTRA_CFLAGS += -DCONFIG_CTS_I2C_HOST
|
||||
|
||||
|
||||
obj-m := chipone_tddi_fhd_mmi.o
|
||||
|
||||
chipone_tddi_fhd_mmi-objs += cts_i2c_driver.o
|
||||
chipone_tddi_fhd_mmi-objs += cts_core.o
|
||||
chipone_tddi_fhd_mmi-objs += cts_platform.o
|
||||
chipone_tddi_fhd_mmi-objs += cts_sfctrlv2.o
|
||||
chipone_tddi_fhd_mmi-objs += cts_spi_flash.o
|
||||
chipone_tddi_fhd_mmi-objs += cts_firmware.o
|
||||
chipone_tddi_fhd_mmi-objs += cts_tool.o
|
||||
chipone_tddi_fhd_mmi-objs += cts_sysfs.o
|
||||
chipone_tddi_fhd_mmi-objs += cts_test.o
|
||||
chipone_tddi_fhd_mmi-objs += cts_charger_detect.o
|
||||
chipone_tddi_fhd_mmi-objs += cts_hostcomm.o
|
||||
chipone_tddi_fhd_mmi-objs += cts_tcs.o
|
||||
|
||||
22
drivers/input/touchscreen/chipone_tddi_fhd_mmi/Makefile
Normal file
22
drivers/input/touchscreen/chipone_tddi_fhd_mmi/Makefile
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
KERNEL_SRC ?= /lib/modules/$(shell uname -r)/build
|
||||
|
||||
all:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(shell pwd) modules $(KBUILD_OPTIONS)
|
||||
|
||||
modules_install:
|
||||
$(MAKE) INSTALL_MOD_STRIP=1 -C $(KERNEL_SRC) M=$(shell pwd) modules_install
|
||||
|
||||
clean:
|
||||
$(MAKE) -C $(KERNEL_SRC) M=$(PWD) clean
|
||||
|
||||
obj-$(CONFIG_TOUCHSCREEN_CHIPONE) += chipone-tddi.o
|
||||
|
||||
chipone-tddi-objs := cts_i2c_driver.o
|
||||
chipone-tddi-objs += cts_core.o cts_sfctrlv2.o cts_spi_flash.o cts_firmware.o cts_test.o
|
||||
chipone-tddi-objs += cts_charger_detect.o
|
||||
chipone-tddi-objs += cts_hostcomm.o
|
||||
chipone-tddi-objs += cts_tcs.o
|
||||
chipone-tddi-objs += cts_platform.o
|
||||
chipone-tddi-objs += cts_tool.o
|
||||
chipone-tddi-objs += cts_sysfs.o
|
||||
|
||||
|
|
@ -0,0 +1,24 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
static u8 icnl9911s_driver_builtin_firmware[] = {
|
||||
};
|
||||
|
||||
static u8 icnl9911c_driver_builtin_firmware[] = {
|
||||
};
|
||||
|
||||
const static struct cts_firmware cts_driver_builtin_firmwares[] = {
|
||||
{
|
||||
.name = "OEM-Project", /* MUST set non-NULL */
|
||||
.hwid = CTS_DEV_HWID_ICNL9911S,
|
||||
.fwid = CTS_DEV_FWID_ICNL9911S,
|
||||
.data = icnl9911s_driver_builtin_firmware,
|
||||
.size = ARRAY_SIZE(icnl9911s_driver_builtin_firmware),
|
||||
},
|
||||
{
|
||||
.name = "OEM-Project", /* MUST set non-NULL */
|
||||
.hwid = CTS_DEV_HWID_ICNL9911C,
|
||||
.fwid = CTS_DEV_FWID_ICNL9911C,
|
||||
.data = icnl9911c_driver_builtin_firmware,
|
||||
.size = ARRAY_SIZE(icnl9911c_driver_builtin_firmware),
|
||||
},
|
||||
|
||||
};
|
||||
1104
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_charger_detect.c
Normal file
1104
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_charger_detect.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,44 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#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 */
|
||||
143
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_config.h
Normal file
143
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_config.h
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef CTS_CONFIG_H
|
||||
#define CTS_CONFIG_H
|
||||
|
||||
/** Driver version */
|
||||
#define CFG_CTS_DRIVER_MAJOR_VERSION 3
|
||||
#define CFG_CTS_DRIVER_MINOR_VERSION 0
|
||||
#define CFG_CTS_DRIVER_PATCH_VERSION 0
|
||||
|
||||
#define CFG_CTS_DRIVER_VERSION "v3.0.9"
|
||||
|
||||
/** Whether reset pin is used */
|
||||
#define CFG_CTS_HAS_RESET_PIN
|
||||
|
||||
/* #define CONFIG_CTS_I2C_HOST */
|
||||
#ifndef CONFIG_CTS_I2C_HOST
|
||||
|
||||
#ifndef CFG_CTS_HAS_RESET_PIN
|
||||
#define CFG_CTS_HAS_RESET_PIN
|
||||
#endif
|
||||
|
||||
#define CFG_CTS_SPI_SPEED_KHZ 6000
|
||||
|
||||
#endif
|
||||
|
||||
#define CFG_CTS_FORCE_UP
|
||||
#define CONFIG_GENERIC_HARDIRQS
|
||||
//#define CFG_CTS_FW_LOG_REDIRECT
|
||||
|
||||
/** 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
|
||||
/* Add FW custom process. */
|
||||
/* #define CFG_CTS_FW_UPDATE_SYS */
|
||||
|
||||
/* Load config fw bin as default. */
|
||||
/* #define CFG_CTS_FW_UPDATE_FILE_LOAD */
|
||||
#ifdef CFG_CTS_FW_UPDATE_FILE_LOAD
|
||||
#define CFG_CTS_FW_FILE_NAME_MAX_LEN 128
|
||||
#define CFG_CTS_FW_FILE_PATH "/vendor/firmware/"
|
||||
#define CFG_CTS_FW_FILE_NAME_VENDOR "chipone"
|
||||
#endif /*CFG_CTS_FW_UPDATE_FILE_LOAD */
|
||||
|
||||
#define CFG_CTS_FIRMWARE_FILENAME_9911 "ICNL9911.bin"
|
||||
#define CFG_CTS_FIRMWARE_FILENAME_9916 "ICNL9916.bin"
|
||||
#define CFG_CTS_FIRMWARE_FILENAME_9922 "ICNL9922.bin"
|
||||
|
||||
#define CFG_CTS_FIRMWARE_FILEPATH_9911 "/vendor/firmware/ICNL9911.bin"
|
||||
#define CFG_CTS_FIRMWARE_FILEPATH_9916 "/vendor/firmware/ICNL9916.bin"
|
||||
#define CFG_CTS_FIRMWARE_FILEPATH_9922 "/vendor/firmware/ICNL9922.bin"
|
||||
#endif /* CFG_CTS_FIRMWARE_IN_FS */
|
||||
|
||||
/* IC type support */
|
||||
#define CFG_CTS_CHIP_NAME "ICNL9911S"
|
||||
|
||||
#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) // 5
|
||||
|
||||
/* 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 CFG_CTS_NUM_GESTURE (13u)
|
||||
#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,},
|
||||
})
|
||||
#define CFG_CTS_GESTURE_REPORT_TRACE 0
|
||||
#endif /* CFG_CTS_GESTURE */
|
||||
|
||||
/* #define CONFIG_CTS_GLOVE */
|
||||
|
||||
#define CONFIG_CTS_CHARGER_DETECT
|
||||
|
||||
/* 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
|
||||
|
||||
#ifdef CONFIG_CTS_LEGACY_TOOL
|
||||
#define CFG_CTS_TOOL_PROC_FILENAME "icn85xx_tool"
|
||||
#endif /* CONFIG_CTS_LEGACY_TOOL */
|
||||
|
||||
#define CFG_CTS_UPDATE_CRCCHECK
|
||||
/****************************************************************************
|
||||
* Platform configurations
|
||||
****************************************************************************/
|
||||
|
||||
#include "cts_plat_qcom_config.h"
|
||||
|
||||
#endif /* CTS_CONFIG_H */
|
||||
3263
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_core.c
Normal file
3263
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_core.c
Normal file
File diff suppressed because it is too large
Load diff
890
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_core.h
Normal file
890
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_core.h
Normal file
|
|
@ -0,0 +1,890 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef CTS_CORE_H
|
||||
#define CTS_CORE_H
|
||||
|
||||
#include "cts_config.h"
|
||||
|
||||
enum cts_dev_hw_reg {
|
||||
CTS_DEV_HW_REG_HARDWARE_ID = 0x30000u,
|
||||
CTS_DEV_HW_REG_CLOCK_GATING = 0x30004u,
|
||||
CTS_DEV_HW_REG_RESET_CONFIG = 0x30008u,
|
||||
CTS_DEV_HW_REG_BOOT_MODE = 0x30010u,
|
||||
CTS_DEV_HW_REG_CURRENT_MODE = 0x30011u,
|
||||
};
|
||||
|
||||
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,
|
||||
};
|
||||
|
||||
/** 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, /* Unit us */
|
||||
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, /* RW */
|
||||
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_ICNL9911 = 0x990100u,
|
||||
CTS_DEV_HWID_ICNL9911S = 0x990110u,
|
||||
CTS_DEV_HWID_ICNL9911C = 0x991110u,
|
||||
CTS_DEV_HWID_ICNL9916 = 0x990160u,
|
||||
CTS_DEV_HWID_ICNL9922 = 0x990220u,
|
||||
|
||||
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_ICNL9911 = 0x9911u,
|
||||
CTS_DEV_FWID_ICNL9911S = 0x9964u,
|
||||
CTS_DEV_FWID_ICNL9911C = 0x9954u,
|
||||
CTS_DEV_FWID_ICNL9916 = 0x9916u,
|
||||
CTS_DEV_FWID_ICNL9922 = 0x9922u,
|
||||
|
||||
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,
|
||||
|
||||
};
|
||||
|
||||
#pragma pack(1)
|
||||
/** Touch message read back from chip */
|
||||
struct cts_device_touch_msg {
|
||||
u8 id;
|
||||
__le16 x;
|
||||
__le16 y;
|
||||
u8 pressure;
|
||||
u8 event;
|
||||
|
||||
#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)
|
||||
|
||||
};
|
||||
|
||||
/** Touch information read back from chip */
|
||||
struct cts_device_touch_info {
|
||||
u8 vkey_state;
|
||||
u8 num_msg;
|
||||
|
||||
struct cts_device_touch_msg msgs[CFG_CTS_MAX_TOUCH_NUM];
|
||||
};
|
||||
|
||||
/** Gesture trace point read back from chip */
|
||||
struct cts_device_gesture_point {
|
||||
__le16 x;
|
||||
__le16 y;
|
||||
u8 pressure;
|
||||
u8 event;
|
||||
};
|
||||
|
||||
/** Gesture information read back from chip */
|
||||
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)
|
||||
|
||||
u8 num_points;
|
||||
|
||||
#define CTS_CHIP_MAX_GESTURE_TRACE_POINT (64u)
|
||||
struct cts_device_gesture_point points[CTS_CHIP_MAX_GESTURE_TRACE_POINT];
|
||||
|
||||
};
|
||||
#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 = 0x3F,
|
||||
};
|
||||
|
||||
enum int_data_method {
|
||||
INT_DATA_METHOD_NONE,
|
||||
INT_DATA_METHOD_HOST,
|
||||
INT_DATA_METHOD_POLLING,
|
||||
};
|
||||
|
||||
/** 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;
|
||||
};
|
||||
|
||||
/** 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 charger_exist;
|
||||
bool fw_log_redirect_enabled;
|
||||
bool glove_mode_enabled;
|
||||
|
||||
struct cts_device_touch_info touch_info;
|
||||
|
||||
u8 *int_data;
|
||||
};
|
||||
|
||||
struct cts_dev_ops {
|
||||
int (*get_fw_ver)(const struct cts_device *cts_dev, u16 *fwver);
|
||||
int (*get_lib_ver)(const struct cts_device *cts_dev, u16 *libver);
|
||||
int (*get_ddi_ver)(const struct cts_device *cts_dev, u8 *ddiver);
|
||||
int (*get_res_x)(const struct cts_device *cts_dev, u16 *res_x);
|
||||
int (*get_res_y)(const struct cts_device *cts_dev, u16 *res_y);
|
||||
int (*get_rows)(const struct cts_device *cts_dev, u8 *rows);
|
||||
int (*get_cols)(const struct cts_device *cts_dev, u8 *cols);
|
||||
int (*get_flip_x)(const struct cts_device *cts_dev, bool *flip_x);
|
||||
int (*get_flip_y)(const struct cts_device *cts_dev, bool *flip_y);
|
||||
int (*get_swap_axes)(const struct cts_device *cts_dev,
|
||||
bool *swap_axes);
|
||||
int (*get_int_mode)(const struct cts_device *cts_dev, u8 *int_mode);
|
||||
int (*get_int_keep_time)(const struct cts_device *cts_dev,
|
||||
u16 *int_keep_time);
|
||||
int (*get_esd_method)(const struct cts_device *cts_dev,
|
||||
u8 *esd_method);
|
||||
int (*get_touchinfo)(const struct cts_device *cts_dev,
|
||||
struct cts_device_touch_info *touch_info);
|
||||
int (*get_esd_protection)(const struct cts_device *cts_dev,
|
||||
u8 *esd_protection);
|
||||
int (*get_data_ready_flag)(const struct cts_device *cts_dev,
|
||||
u8 *ready);
|
||||
int (*clr_data_ready_flag)(const struct cts_device *cts_dev);
|
||||
int (*enable_get_rawdata)(const struct cts_device *cts_dev);
|
||||
int (*is_enabled_get_rawdata)(const struct cts_device *cts_dev,
|
||||
u8 *enabled);
|
||||
int (*disable_get_rawdata)(const struct cts_device *cts_dev);
|
||||
int (*enable_get_cneg)(const struct cts_device *cts_dev);
|
||||
int (*disable_get_cneg)(const struct cts_device *cts_dev);
|
||||
int (*is_cneg_ready)(const struct cts_device *cts_dev, u8 *ready);
|
||||
int (*quit_guesture_mode)(const struct cts_device *cts_dev);
|
||||
int (*get_rawdata)(const struct cts_device *cts_dev, u8 *buf);
|
||||
int (*get_diffdata)(const struct cts_device *cts_dev, u8 *buf);
|
||||
int (*get_basedata)(const struct cts_device *cts_dev, u8 *buf);
|
||||
int (*get_cneg)(const struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size);
|
||||
int (*read_hw_reg)(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *buf, size_t size);
|
||||
int (*write_hw_reg)(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *buf, size_t size);
|
||||
int (*read_ddi_reg)(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *regbuf, size_t size);
|
||||
int (*write_ddi_reg)(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *regbuf, size_t size);
|
||||
int (*read_fw_reg)(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *buf, size_t size);
|
||||
int (*write_fw_reg)(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *buf, size_t size);
|
||||
int (*read_reg)(const struct cts_device *cts_dev, uint16_t cmd,
|
||||
u8 *rbuf, size_t rlen);
|
||||
int (*write_reg)(const struct cts_device *cts_dev, uint16_t cmd,
|
||||
u8 *wbuf, size_t wlen);
|
||||
int (*get_fw_id)(const struct cts_device *cts_dev, u16 *fwid);
|
||||
int (*get_workmode)(const struct cts_device *cts_dev, u8 *workmode);
|
||||
int (*set_workmode)(const struct cts_device *cts_dev, u8 workmode);
|
||||
int (*set_openshort_mode)(const struct cts_device *cts_dev, u8 mode);
|
||||
int (*set_tx_vol)(const struct cts_device *cts_dev, u8 txvol);
|
||||
int (*set_short_test_type)(const struct cts_device *cts_dev,
|
||||
u8 short_type);
|
||||
int (*set_openshort_enable)(const struct cts_device *cts_dev,
|
||||
u8 enable);
|
||||
int (*is_openshort_enabled)(const struct cts_device *cts_dev,
|
||||
u8 *enabled);
|
||||
int (*set_esd_enable)(const struct cts_device *cts_dev, u8 enable);
|
||||
int (*set_cneg_enable)(const struct cts_device *cts_dev, u8 enable);
|
||||
int (*set_mnt_enable)(const struct cts_device *cts_dev, u8 enable);
|
||||
int (*is_display_on)(const struct cts_device *cts_dev,
|
||||
u8 *display_on);
|
||||
int (*set_display_on)(const struct cts_device *cts_dev, u8 display_on);
|
||||
int (*is_cneg_enabled)(const struct cts_device *cts_dev, u8 *enabled);
|
||||
int (*is_mnt_enabled)(const struct cts_device *cts_dev, u8 *enabled);
|
||||
int (*set_pwr_mode)(const struct cts_device *cts_dev, u8 pwr_mode);
|
||||
int (*read_sram_normal_mode)(const struct cts_device *cts_dev,
|
||||
u32 addr, void *dst, size_t len, int retry,
|
||||
int delay);
|
||||
int (*init_int_data)(struct cts_device *cts_dev);
|
||||
int (*deinit_int_data)(struct cts_device *cts_dev);
|
||||
int (*get_has_int_data)(const struct cts_device *cts_dev,
|
||||
bool *has_int_data);
|
||||
int (*get_int_data_method)(const struct cts_device *cts_dev,
|
||||
u8 *int_data_method);
|
||||
int (*set_int_data_method)(const struct cts_device *cts_dev,
|
||||
u8 int_data_method);
|
||||
int (*get_int_data_types)(const struct cts_device *cts_dev,
|
||||
u16 *int_data_types);
|
||||
int (*set_int_data_types)(const struct cts_device *cts_dev,
|
||||
u16 int_data_types);
|
||||
int (*calc_int_data_size)(struct cts_device *cts_dev);
|
||||
int (*polling_data)(const struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size);
|
||||
int (*polling_test_data)(const struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size);
|
||||
|
||||
int (*top_get_rawdata)(struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size);
|
||||
int (*top_get_manual_diff)(struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size);
|
||||
int (*top_get_real_diff)(struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size);
|
||||
int (*top_get_noise_diff)(struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size);
|
||||
int (*top_get_basedata)(struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size);
|
||||
int (*top_get_cnegdata)(struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size);
|
||||
|
||||
int (*reset_device)(const struct cts_device *cts_dev);
|
||||
};
|
||||
|
||||
struct cts_device {
|
||||
struct cts_platform_data *pdata;
|
||||
|
||||
const struct cts_device_hwdata *hwdata;
|
||||
struct cts_device_fwdata fwdata;
|
||||
struct cts_device_rtdata rtdata;
|
||||
const struct cts_flash *flash;
|
||||
bool enabled;
|
||||
#ifdef CFG_CTS_FW_UPDATE_FILE_LOAD
|
||||
char config_fw_name[CFG_CTS_FW_FILE_NAME_MAX_LEN + 1];
|
||||
#endif /* CFG_CTS_FW_UPDATE_FILE_LOAD */
|
||||
|
||||
struct cts_dev_ops *ops;
|
||||
u8 *tx;
|
||||
u8 *rx;
|
||||
};
|
||||
|
||||
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 /* CONFIG_CTS_I2C_HOST */
|
||||
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 /* CONFIG_CTS_CHARGER_DETECT */
|
||||
|
||||
#ifdef CONFIG_CTS_ESD_PROTECTION
|
||||
struct workqueue_struct *esd_workqueue;
|
||||
struct delayed_work esd_work;
|
||||
bool esd_enabled;
|
||||
int esd_check_fail_cnt;
|
||||
#endif /* CONFIG_CTS_ESD_PROTECTION */
|
||||
|
||||
#ifdef CONFIG_CTS_LEGACY_TOOL
|
||||
struct proc_dir_entry *procfs_entry;
|
||||
#endif /* CONFIG_CTS_LEGACY_TOOL */
|
||||
|
||||
bool force_reflash;
|
||||
|
||||
};
|
||||
|
||||
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(const struct cts_device *cts_dev);
|
||||
extern void cts_unlock_device(const struct cts_device *cts_dev);
|
||||
|
||||
extern int cts_dev_readb(const struct cts_device *cts_dev,
|
||||
u32 addr, u8 *b, int retry, int delay);
|
||||
extern int cts_dev_writeb(const struct cts_device *cts_dev,
|
||||
u32 addr, u8 b, int retry, int delay);
|
||||
|
||||
extern int cts_sram_writeb_retry(const struct cts_device *cts_dev,
|
||||
u32 addr, u8 b, int retry, int delay);
|
||||
extern int cts_sram_writew_retry(const struct cts_device *cts_dev,
|
||||
u32 addr, u16 w, int retry, int delay);
|
||||
extern int cts_sram_writel_retry(const struct cts_device *cts_dev,
|
||||
u32 addr, u32 l, int retry, int delay);
|
||||
extern int cts_sram_writesb_retry(const 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(const struct cts_device *cts_dev,
|
||||
u32 addr, const void *src,
|
||||
size_t len, u32 crc, int retry);
|
||||
|
||||
extern int cts_sram_readb_retry(const struct cts_device *cts_dev,
|
||||
u32 addr, u8 *b, int retry, int delay);
|
||||
extern int cts_sram_readw_retry(const struct cts_device *cts_dev,
|
||||
u32 addr, u16 *w, int retry, int delay);
|
||||
extern int cts_sram_readl_retry(const struct cts_device *cts_dev,
|
||||
u32 addr, u32 *l, int retry, int delay);
|
||||
extern int cts_sram_readsb_retry(const struct cts_device *cts_dev,
|
||||
u32 addr, void *dst, size_t len, int retry,
|
||||
int delay);
|
||||
|
||||
extern int cts_fw_reg_writeb_retry(const struct cts_device *cts_dev,
|
||||
u32 reg_addr, u8 b, int retry, int delay);
|
||||
extern int cts_fw_reg_writew_retry(const struct cts_device *cts_dev,
|
||||
u32 reg_addr, u16 w, int retry, int delay);
|
||||
extern int cts_fw_reg_writel_retry(const struct cts_device *cts_dev,
|
||||
u32 reg_addr, u32 l, int retry, int delay);
|
||||
extern int cts_fw_reg_writesb_retry(const 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(const struct cts_device *cts_dev,
|
||||
u32 reg_addr, u8 *b, int retry, int delay);
|
||||
extern int cts_fw_reg_readw_retry(const struct cts_device *cts_dev,
|
||||
u32 reg_addr, u16 *w, int retry, int delay);
|
||||
extern int cts_fw_reg_readl_retry(const struct cts_device *cts_dev,
|
||||
u32 reg_addr, u32 *l, int retry, int delay);
|
||||
extern int cts_fw_reg_readsb_retry(const 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(const 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(const struct cts_device *cts_dev,
|
||||
u32 reg_addr, u8 b, int retry, int delay);
|
||||
extern int cts_hw_reg_writew_retry(const struct cts_device *cts_dev,
|
||||
u32 reg_addr, u16 w, int retry, int delay);
|
||||
extern int cts_hw_reg_writel_retry(const struct cts_device *cts_dev,
|
||||
u32 reg_addr, u32 l, int retry, int delay);
|
||||
extern int cts_hw_reg_writesb_retry(const 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(const struct cts_device *cts_dev,
|
||||
u32 reg_addr, u8 *b, int retry, int delay);
|
||||
extern int cts_hw_reg_readw_retry(const struct cts_device *cts_dev,
|
||||
u32 reg_addr, u16 *w, int retry, int delay);
|
||||
extern int cts_hw_reg_readl_retry(const struct cts_device *cts_dev,
|
||||
u32 reg_addr, u32 *l, int retry, int delay);
|
||||
extern int cts_hw_reg_readsb_retry(const struct cts_device *cts_dev,
|
||||
u32 reg_addr, void *dst, size_t len,
|
||||
int retry, int delay);
|
||||
|
||||
static inline int cts_hw_reg_readb(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const struct cts_device *cts_dev, u32 addr,
|
||||
const void *src, size_t len)
|
||||
{
|
||||
return cts_sram_writesb_retry(cts_dev, addr, src, len, 1, 0);
|
||||
}
|
||||
|
||||
static inline int cts_sram_readb(const 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(const 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(const 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(const 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;
|
||||
}
|
||||
#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(const 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(const 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_set_work_mode(const struct cts_device *cts_dev, u8 mode);
|
||||
extern int cts_get_work_mode(const struct cts_device *cts_dev, u8 *mode);
|
||||
extern int cts_get_firmware_version(const struct cts_device *cts_dev,
|
||||
u16 *version);
|
||||
extern int cts_get_ddi_version(const struct cts_device *cts_dev, u8 *version);
|
||||
extern int cts_get_lib_version(const struct cts_device *cts_dev,
|
||||
u16 *lib_version);
|
||||
extern int cts_get_data_ready_flag(const struct cts_device *cts_dev, u8 *flag);
|
||||
extern int cts_clr_data_ready_flag(const struct cts_device *cts_dev);
|
||||
extern int cts_send_command(const struct cts_device *cts_dev, u8 cmd);
|
||||
extern int cts_get_panel_param(const struct cts_device *cts_dev,
|
||||
void *param, size_t size);
|
||||
extern int cts_set_panel_param(const struct cts_device *cts_dev,
|
||||
const void *param, size_t size);
|
||||
extern int cts_get_x_resolution(const struct cts_device *cts_dev,
|
||||
u16 *resolution);
|
||||
extern int cts_get_y_resolution(const struct cts_device *cts_dev,
|
||||
u16 *resolution);
|
||||
extern int cts_get_num_rows(const struct cts_device *cts_dev, u8 *num_rows);
|
||||
extern int cts_get_num_cols(const struct cts_device *cts_dev, u8 *num_cols);
|
||||
extern int cts_enable_get_rawdata(const struct cts_device *cts_dev);
|
||||
extern int cts_disable_get_rawdata(const struct cts_device *cts_dev);
|
||||
extern int cts_polling_data(const struct cts_device *cts_dev, void *buf,
|
||||
size_t size);
|
||||
extern int cts_polling_test_data(const struct cts_device *cts_dev, void *buf,
|
||||
size_t size);
|
||||
extern int cts_get_rawdata(const struct cts_device *cts_dev, void *buf);
|
||||
extern int cts_get_diffdata(const struct cts_device *cts_dev, void *buf);
|
||||
extern int cts_get_basedata(const struct cts_device *cts_dev, void *buf);
|
||||
extern int cts_get_compensate_cap(struct cts_device *cts_dev, u8 *cap);
|
||||
extern int cts_get_fwid(struct cts_device *cts_dev, u16 *fwid);
|
||||
extern int cts_get_hwid(struct cts_device *cts_dev, u32 *hwid);
|
||||
extern int cts_read_sram_normal_mode(const 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(const struct cts_device *cts_dev);
|
||||
extern int cts_get_gesture_info(const struct cts_device *cts_dev,
|
||||
void *gesture_info, bool trace_point);
|
||||
#endif /* CFG_CTS_GESTURE */
|
||||
|
||||
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 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(const struct cts_device *cts_dev);
|
||||
#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(const struct cts_device *cts_dev)
|
||||
{
|
||||
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_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(const 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_FW_LOG_REDIRECT
|
||||
extern int cts_enable_fw_log_redirect(struct cts_device *cts_dev);
|
||||
extern int cts_disable_fw_log_redirect(struct cts_device *cts_dev);
|
||||
extern bool cts_is_fw_log_redirect(struct cts_device *cts_dev);
|
||||
extern int cts_fw_log_show_finish(struct cts_device *cts_dev);
|
||||
#endif
|
||||
|
||||
#ifdef CFG_CTS_UPDATE_CRCCHECK
|
||||
extern int cts_sram_writesb_boot_crc_retry(const 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 void cts_deinit_rtdata(struct cts_device *cts_dev);
|
||||
|
||||
extern int cts_reset_device(struct cts_device *cts_dev);
|
||||
#endif /* CTS_CORE_H */
|
||||
1162
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_firmware.c
Normal file
1162
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_firmware.c
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,74 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef CTS_FIRMWARE_H
|
||||
#define CTS_FIRMWARE_H
|
||||
|
||||
#include "cts_config.h"
|
||||
#include <linux/firmware.h>
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
#define FIRMWARE_VERSION_OFFSET 0x100
|
||||
#define FIRMWARE_VERSION(firmware) \
|
||||
get_unaligned_le16((firmware)->data + FIRMWARE_VERSION_OFFSET)
|
||||
|
||||
struct cts_device;
|
||||
|
||||
extern const struct cts_firmware *cts_request_firmware(const struct cts_device
|
||||
*cts_dev, u32 hwid,
|
||||
u16 fwid,
|
||||
u16 device_fw_ver);
|
||||
extern void cts_release_firmware(const struct cts_firmware *firmware);
|
||||
|
||||
#ifdef CFG_CTS_DRIVER_BUILTIN_FIRMWARE
|
||||
extern int cts_get_num_driver_builtin_firmware(void);
|
||||
extern const struct cts_firmware
|
||||
*cts_request_driver_builtin_firmware_by_name(const char *name);
|
||||
extern const struct cts_firmware
|
||||
*cts_request_driver_builtin_firmware_by_index(u32 index);
|
||||
#else /* CFG_CTS_DRIVER_BUILTIN_FIRMWARE */
|
||||
static inline int cts_get_num_driver_builtin_firmware(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline const struct cts_firmware
|
||||
*cts_request_driver_builtin_firmware_by_name(const char *name)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static inline const struct cts_firmware
|
||||
*cts_request_driver_builtin_firmware_by_index(u32 index)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
#endif /* CFG_CTS_DRIVER_BUILTIN_FIRMWARE */
|
||||
extern bool cts_is_firmware_updating(const struct cts_device *cts_dev);
|
||||
|
||||
extern int cts_update_firmware(struct cts_device *cts_dev,
|
||||
const struct cts_firmware *firmware,
|
||||
bool to_flash);
|
||||
|
||||
#ifdef CFG_CTS_FIRMWARE_IN_FS
|
||||
extern const struct cts_firmware *cts_request_firmware_from_fs(const struct
|
||||
cts_device
|
||||
*cts_dev,
|
||||
const char
|
||||
*filepath);
|
||||
extern int cts_update_firmware_from_file(struct cts_device *cts_dev,
|
||||
const char *filepath, bool to_flash);
|
||||
|
||||
#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 */
|
||||
533
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_hostcomm.c
Normal file
533
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_hostcomm.c
Normal file
|
|
@ -0,0 +1,533 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#include "cts_config.h"
|
||||
#include "cts_firmware.h"
|
||||
#include "cts_platform.h"
|
||||
|
||||
#include "cts_hostcomm.h"
|
||||
|
||||
extern bool set_short_test_type(const struct cts_device *cts_dev, u8 type);
|
||||
extern int disable_fw_monitor_mode(const struct cts_device *cts_dev);
|
||||
extern int disable_fw_auto_compensate(const struct cts_device *cts_dev);
|
||||
extern int disable_fw_esd_protection(const struct cts_device *cts_dev);
|
||||
extern int set_fw_work_mode(const struct cts_device *cts_dev, u8 mode);
|
||||
extern int set_display_state(const struct cts_device *cts_dev, bool active);
|
||||
|
||||
int cts_hostcomm_get_fw_ver(const struct cts_device *cts_dev, u16 *fwver)
|
||||
{
|
||||
return cts_get_firmware_version(cts_dev, fwver);
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_lib_ver(const struct cts_device *cts_dev, u16 *libver)
|
||||
{
|
||||
return cts_get_lib_version(cts_dev, libver);
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_ddi_ver(const struct cts_device *cts_dev, u8 *ddiver)
|
||||
{
|
||||
return cts_get_ddi_version(cts_dev, ddiver);
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_res_x(const struct cts_device *cts_dev, u16 *res_x)
|
||||
{
|
||||
return cts_get_x_resolution(cts_dev, res_x);
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_res_y(const struct cts_device *cts_dev, u16 *res_y)
|
||||
{
|
||||
return cts_get_y_resolution(cts_dev, res_y);
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_rows(const struct cts_device *cts_dev, u8 *rows)
|
||||
{
|
||||
return cts_get_num_rows(cts_dev, rows);
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_cols(const struct cts_device *cts_dev, u8 *cols)
|
||||
{
|
||||
return cts_get_num_cols(cts_dev, cols);
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_flip_x(const struct cts_device *cts_dev, bool *flip_x)
|
||||
{
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
ret = cts_fw_reg_readb(cts_dev, CTS_DEVICE_FW_REG_FLAG_BITS, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*flip_x = !!(val & BIT(2));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_flip_y(const struct cts_device *cts_dev, bool *flip_y)
|
||||
{
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
ret = cts_fw_reg_readb(cts_dev, CTS_DEVICE_FW_REG_FLAG_BITS, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*flip_y = !!(val & BIT(3));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_swap_axes(const struct cts_device *cts_dev,
|
||||
bool *swap_axes)
|
||||
{
|
||||
u8 val;
|
||||
int ret;
|
||||
|
||||
ret = cts_fw_reg_readb(cts_dev, CTS_DEVICE_FW_REG_SWAP_AXES, &val);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
*swap_axes = !!val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_int_mode(const struct cts_device *cts_dev, u8 *int_mode)
|
||||
{
|
||||
return cts_fw_reg_readb(cts_dev, CTS_DEVICE_FW_REG_INT_MODE, int_mode);
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_int_keep_time(const struct cts_device *cts_dev,
|
||||
u16 *int_keep_time)
|
||||
{
|
||||
return cts_fw_reg_readw(cts_dev, CTS_DEVICE_FW_REG_INT_KEEP_TIME,
|
||||
int_keep_time);
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_esd_method(const struct cts_device *cts_dev,
|
||||
u8 *esd_method)
|
||||
{
|
||||
return cts_fw_reg_readb(cts_dev, CTS_DEVICE_FW_REG_ESD_PROTECTION,
|
||||
esd_method);
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_esd_protection(const struct cts_device *cts_dev,
|
||||
u8 *esd_protection)
|
||||
{
|
||||
return cts_fw_reg_readb(cts_dev, 0x8000 + 342, esd_protection);
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_data_ready_flag(const struct cts_device *cts_dev,
|
||||
u8 *ready)
|
||||
{
|
||||
return cts_get_data_ready_flag(cts_dev, ready);
|
||||
}
|
||||
|
||||
int cts_hostcomm_clr_data_ready_flag(const struct cts_device *cts_dev)
|
||||
{
|
||||
return cts_clr_data_ready_flag(cts_dev);
|
||||
}
|
||||
|
||||
int cts_hostcomm_enable_get_rawdata(const struct cts_device *cts_dev)
|
||||
{
|
||||
return cts_enable_get_rawdata(cts_dev);
|
||||
}
|
||||
|
||||
int cts_hostcomm_disable_get_rawdata(const struct cts_device *cts_dev)
|
||||
{
|
||||
return cts_disable_get_rawdata(cts_dev);
|
||||
}
|
||||
|
||||
int cts_hostcomm_enable_get_cneg(const struct cts_device *cts_dev)
|
||||
{
|
||||
return cts_send_command(cts_dev, CTS_CMD_ENABLE_READ_CNEG);
|
||||
}
|
||||
|
||||
int cts_hostcomm_disable_get_cneg(const struct cts_device *cts_dev)
|
||||
{
|
||||
return cts_send_command(cts_dev, CTS_CMD_DISABLE_READ_CNEG);
|
||||
}
|
||||
|
||||
int cts_hostcomm_is_cneg_ready(const struct cts_device *cts_dev, u8 *ready)
|
||||
{
|
||||
return cts_fw_reg_readb(cts_dev,
|
||||
CTS_DEVICE_FW_REG_COMPENSATE_CAP_READY, ready);
|
||||
}
|
||||
|
||||
int cts_hostcomm_quit_guesture_mode(const struct cts_device *cts_dev)
|
||||
{
|
||||
//TODO:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_rawdata(const struct cts_device *cts_dev, u8 *buf)
|
||||
{
|
||||
return cts_fw_reg_readsb_delay_idle(cts_dev,
|
||||
CTS_DEVICE_FW_REG_RAW_DATA,
|
||||
buf,
|
||||
cts_dev->fwdata.rows *
|
||||
cts_dev->fwdata.cols * 2, 500);
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_diffdata(const struct cts_device *cts_dev, u8 *buf)
|
||||
{
|
||||
return cts_fw_reg_readsb_delay_idle(cts_dev,
|
||||
CTS_DEVICE_FW_REG_DIFF_DATA,
|
||||
buf,
|
||||
(cts_dev->fwdata.rows + 2) *
|
||||
(cts_dev->fwdata.cols + 2) * 2,
|
||||
500);
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_basedata(const struct cts_device *cts_dev, u8 *buf)
|
||||
{
|
||||
//TODO:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_cneg(const struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size)
|
||||
{
|
||||
return cts_fw_reg_readsb_delay_idle(cts_dev,
|
||||
CTS_DEVICE_FW_REG_COMPENSATE_CAP,
|
||||
buf,
|
||||
cts_dev->hwdata->num_row *
|
||||
cts_dev->hwdata->num_col, 500);
|
||||
}
|
||||
|
||||
int cts_hostcomm_read_hw_reg(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *regbuf, size_t size)
|
||||
{
|
||||
|
||||
return cts_hw_reg_readsb_retry(cts_dev, addr, regbuf, size, 3, 100);
|
||||
}
|
||||
|
||||
int cts_hostcomm_write_hw_reg(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *regbuf, size_t size)
|
||||
{
|
||||
return cts_hw_reg_writesb_retry(cts_dev, addr, regbuf, size, 3, 100);
|
||||
}
|
||||
|
||||
int cts_hostcomm_read_ddi_reg(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *regbuf, size_t size)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
cts_err("%s: BUG! Should not be here!", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_hostcomm_write_ddi_reg(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *regbuf, size_t size)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
cts_err("%s: BUG! Should not be here!", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_hostcomm_read_reg(const struct cts_device *cts_dev, uint16_t cmd,
|
||||
u8 *rbuf, size_t rlen)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
cts_err("%s: BUG! Should not be here!", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_hostcomm_write_reg(const struct cts_device *cts_dev, uint16_t cmd,
|
||||
u8 *wbuf, size_t wlen)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
cts_err("%s: BUG! Should not be here!", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_hostcomm_read_fw_reg(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *regbuf, size_t size)
|
||||
{
|
||||
return cts_fw_reg_readsb(cts_dev, addr, regbuf, size);
|
||||
}
|
||||
|
||||
int cts_hostcomm_write_fw_reg(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *regbuf, size_t size)
|
||||
{
|
||||
return cts_fw_reg_writesb(cts_dev, addr, regbuf, size);
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_touchinfo(const struct cts_device *cts_dev,
|
||||
struct cts_device_touch_info *touch_info)
|
||||
{
|
||||
memset(touch_info, 0, sizeof(*touch_info));
|
||||
return cts_fw_reg_readsb(cts_dev, CTS_DEVICE_FW_REG_TOUCH_INFO,
|
||||
touch_info, sizeof(*touch_info));
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_fw_id(const struct cts_device *cts_dev, u16 *fwid)
|
||||
{
|
||||
u16 tmp = 0xffff;
|
||||
int ret;
|
||||
|
||||
ret = cts_fw_reg_readw(cts_dev, CTS_DEVICE_FW_REG_CHIP_TYPE, &tmp);
|
||||
tmp = be16_to_cpu(tmp);
|
||||
*fwid = tmp;
|
||||
cts_info("%s:%04X", __func__, tmp);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_hostcomm_get_workmode(const struct cts_device *cts_dev, u8 *workmode)
|
||||
{
|
||||
return cts_fw_reg_readb(cts_dev, CTS_DEVICE_FW_REG_GET_WORK_MODE,
|
||||
workmode);
|
||||
}
|
||||
|
||||
int cts_hostcomm_set_workmode(const struct cts_device *cts_dev, u8 workmode)
|
||||
{
|
||||
return set_fw_work_mode(cts_dev, workmode);
|
||||
}
|
||||
|
||||
int cts_hostcomm_set_openshort_mode(const struct cts_device *cts_dev, u8 type)
|
||||
{
|
||||
int i, ret;
|
||||
|
||||
cts_info("Set test type %d", type);
|
||||
|
||||
for (i = 0; i < 5; i++) {
|
||||
u8 type_readback;
|
||||
|
||||
ret = cts_fw_reg_writeb(cts_dev, 0x34, type);
|
||||
if (ret) {
|
||||
cts_err("Write test type register to failed %d", ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret = cts_fw_reg_readb(cts_dev, 0x34, &type_readback);
|
||||
if (ret) {
|
||||
cts_err("Read test type register failed %d", ret);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (type != type_readback) {
|
||||
cts_err("Set test type %u != readback %u", type,
|
||||
type_readback);
|
||||
ret = -EFAULT;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_hostcomm_set_tx_vol(const struct cts_device *cts_dev, u8 txvol)
|
||||
{
|
||||
return cts_send_command(cts_dev, CTS_CMD_RECOVERY_TX_VOL);
|
||||
}
|
||||
|
||||
int cts_hostcomm_is_enabled_get_rawdata(const struct cts_device *cts_dev,
|
||||
u8 *enabled)
|
||||
{
|
||||
return cts_fw_reg_readb(cts_dev, 0x12, enabled);
|
||||
}
|
||||
|
||||
int cts_hostcomm_set_short_test_type(const struct cts_device *cts_dev,
|
||||
u8 short_type)
|
||||
{
|
||||
return set_short_test_type(cts_dev, short_type);
|
||||
}
|
||||
|
||||
int cts_hostcomm_is_openshort_enabled(const struct cts_device *cts_dev,
|
||||
u8 *enabled)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
cts_err("BUG! Should not be here!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_hostcomm_set_openshort_enable(const struct cts_device *cts_dev,
|
||||
u8 enable)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
cts_err("BUG! Should not be here!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_hostcomm_set_esd_enable(const struct cts_device *cts_dev, u8 enable)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (!enable)
|
||||
return disable_fw_esd_protection(cts_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_hostcomm_is_cneg_enabled(const struct cts_device *cts_dev, u8 *enabled)
|
||||
{
|
||||
return cts_fw_reg_readb(cts_dev, 0x8000 + 276, enabled);
|
||||
}
|
||||
|
||||
int cts_hostcomm_is_mnt_enabled(const struct cts_device *cts_dev, u8 *enabled)
|
||||
{
|
||||
return cts_fw_reg_readb(cts_dev, 0x8000 + 344, enabled);
|
||||
}
|
||||
|
||||
int cts_hostcomm_set_cneg_enable(const struct cts_device *cts_dev, u8 enable)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (!enable)
|
||||
return disable_fw_auto_compensate(cts_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_hostcomm_set_mnt_enable(const struct cts_device *cts_dev, u8 enable)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
if (!enable)
|
||||
return disable_fw_monitor_mode(cts_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_hostcomm_is_display_on(const struct cts_device *cts_dev,
|
||||
u8 *display_on)
|
||||
{
|
||||
return cts_fw_reg_readb(cts_dev, 0x8000 + 163, display_on);
|
||||
}
|
||||
|
||||
int cts_hostcomm_set_pwr_mode(const struct cts_device *cts_dev, u8 pwr_mode)
|
||||
{
|
||||
//TODO:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_hostcomm_set_display_on(const struct cts_device *cts_dev, u8 display_on)
|
||||
{
|
||||
return set_display_state(cts_dev, false);
|
||||
}
|
||||
|
||||
int cts_hostcomm_top_get_rawdata(struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size)
|
||||
{
|
||||
//TODO: moved from sysfs:rawdata_show
|
||||
//TODO:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_hostcomm_top_get_manual_diff(struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size)
|
||||
{
|
||||
//TODO:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_hostcomm_top_get_real_diff(struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size)
|
||||
{
|
||||
//TODO:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_hostcomm_top_get_noise_diff(struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size)
|
||||
{
|
||||
//TODO:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_hostcomm_top_get_basedata(struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size)
|
||||
{
|
||||
//TODO:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_hostcomm_top_get_cnegdata(struct cts_device *cts_dev, u8 *buf,
|
||||
size_t size)
|
||||
{
|
||||
return cts_get_compensate_cap(cts_dev, buf);
|
||||
}
|
||||
|
||||
int cts_hostcomm_reset_device(const struct cts_device *cts_dev)
|
||||
{
|
||||
return cts_plat_reset_device(cts_dev->pdata);
|
||||
}
|
||||
|
||||
struct cts_dev_ops hostcomm_ops = {
|
||||
.get_fw_ver = cts_hostcomm_get_fw_ver,
|
||||
.get_lib_ver = cts_hostcomm_get_lib_ver,
|
||||
.get_ddi_ver = cts_hostcomm_get_ddi_ver,
|
||||
.get_res_x = cts_hostcomm_get_res_x,
|
||||
.get_res_y = cts_hostcomm_get_res_y,
|
||||
.get_rows = cts_hostcomm_get_rows,
|
||||
.get_cols = cts_hostcomm_get_cols,
|
||||
.get_flip_x = cts_hostcomm_get_flip_x,
|
||||
.get_flip_y = cts_hostcomm_get_flip_y,
|
||||
.get_swap_axes = cts_hostcomm_get_swap_axes,
|
||||
.get_int_mode = cts_hostcomm_get_int_mode,
|
||||
.get_int_keep_time = cts_hostcomm_get_int_keep_time,
|
||||
.get_esd_method = cts_hostcomm_get_esd_method,
|
||||
.get_touchinfo = cts_hostcomm_get_touchinfo,
|
||||
.get_esd_protection = cts_hostcomm_get_esd_protection,
|
||||
.get_data_ready_flag = cts_hostcomm_get_data_ready_flag,
|
||||
.clr_data_ready_flag = cts_hostcomm_clr_data_ready_flag,
|
||||
.enable_get_rawdata = cts_hostcomm_enable_get_rawdata,
|
||||
.is_enabled_get_rawdata = cts_hostcomm_is_enabled_get_rawdata,
|
||||
.disable_get_rawdata = cts_hostcomm_disable_get_rawdata,
|
||||
.enable_get_cneg = cts_hostcomm_enable_get_cneg,
|
||||
.disable_get_cneg = cts_hostcomm_disable_get_cneg,
|
||||
.is_cneg_ready = cts_hostcomm_is_cneg_ready,
|
||||
.quit_guesture_mode = cts_hostcomm_quit_guesture_mode,
|
||||
.get_rawdata = cts_hostcomm_get_rawdata,
|
||||
.get_diffdata = cts_hostcomm_get_diffdata,
|
||||
.get_basedata = cts_hostcomm_get_basedata,
|
||||
.get_cneg = cts_hostcomm_get_cneg,
|
||||
.read_hw_reg = cts_hostcomm_read_hw_reg,
|
||||
.write_hw_reg = cts_hostcomm_write_hw_reg,
|
||||
.read_ddi_reg = cts_hostcomm_read_ddi_reg,
|
||||
.write_ddi_reg = cts_hostcomm_write_ddi_reg,
|
||||
.read_fw_reg = cts_hostcomm_read_fw_reg,
|
||||
.write_fw_reg = cts_hostcomm_write_fw_reg,
|
||||
.read_reg = cts_hostcomm_read_reg,
|
||||
.write_reg = cts_hostcomm_write_reg,
|
||||
.get_fw_id = cts_hostcomm_get_fw_id,
|
||||
.get_workmode = cts_hostcomm_get_workmode,
|
||||
.set_workmode = cts_hostcomm_set_workmode,
|
||||
.set_openshort_mode = cts_hostcomm_set_openshort_mode,
|
||||
.set_tx_vol = cts_hostcomm_set_tx_vol,
|
||||
.set_short_test_type = cts_hostcomm_set_short_test_type,
|
||||
.set_openshort_enable = cts_hostcomm_set_openshort_enable,
|
||||
.is_openshort_enabled = cts_hostcomm_is_openshort_enabled,
|
||||
.set_esd_enable = cts_hostcomm_set_esd_enable,
|
||||
.set_cneg_enable = cts_hostcomm_set_cneg_enable,
|
||||
.set_mnt_enable = cts_hostcomm_set_mnt_enable,
|
||||
.is_display_on = cts_hostcomm_is_display_on,
|
||||
.set_display_on = cts_hostcomm_set_display_on,
|
||||
.is_cneg_enabled = cts_hostcomm_is_cneg_enabled,
|
||||
.is_mnt_enabled = cts_hostcomm_is_mnt_enabled,
|
||||
.set_pwr_mode = cts_hostcomm_set_pwr_mode,
|
||||
.read_sram_normal_mode = cts_read_sram_normal_mode,
|
||||
.init_int_data = NULL, //TODO
|
||||
.deinit_int_data = NULL, //TODO
|
||||
.get_has_int_data = NULL,
|
||||
.get_int_data_types = NULL,
|
||||
.set_int_data_types = NULL,
|
||||
.get_int_data_method = NULL,
|
||||
.set_int_data_method = NULL,
|
||||
.calc_int_data_size = NULL,
|
||||
.polling_data = NULL,
|
||||
.polling_test_data = NULL,
|
||||
|
||||
.top_get_rawdata = cts_hostcomm_top_get_rawdata,
|
||||
.top_get_manual_diff = cts_hostcomm_top_get_manual_diff,
|
||||
.top_get_real_diff = cts_hostcomm_top_get_real_diff,
|
||||
.top_get_noise_diff = cts_hostcomm_top_get_noise_diff,
|
||||
.top_get_basedata = cts_hostcomm_top_get_basedata,
|
||||
.top_get_cnegdata = cts_hostcomm_top_get_cnegdata,
|
||||
|
||||
.reset_device = cts_hostcomm_reset_device,
|
||||
};
|
||||
|
||||
//TODO:
|
||||
//fwdata->rawdata_target;
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef CTS_HOSTCOMM_H
|
||||
#define CTS_HOSTCOMM_H
|
||||
|
||||
#include "cts_config.h"
|
||||
#include "cts_core.h"
|
||||
extern struct cts_dev_ops hostcomm_ops;
|
||||
|
||||
#endif /* CTS_HOSTCOMM_H */
|
||||
960
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_i2c_driver.c
Normal file
960
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_i2c_driver.c
Normal file
|
|
@ -0,0 +1,960 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#define LOG_TAG "I2CDrv"
|
||||
|
||||
#include "cts_config.h"
|
||||
#include "cts_platform.h"
|
||||
#include "cts_core.h"
|
||||
#include "cts_sysfs.h"
|
||||
#include "cts_charger_detect.h"
|
||||
|
||||
static void cts_resume_work_func(struct work_struct *work);
|
||||
#ifdef CFG_CTS_DRM_NOTIFIER
|
||||
#include <drm/drm_panel.h>
|
||||
static struct drm_panel *active_panel;
|
||||
static int check_dt(struct device_node *np);
|
||||
#endif
|
||||
bool cts_show_debug_log;
|
||||
#ifdef CTS_MTK_GET_PANEL
|
||||
static char *active_panel_name;
|
||||
#endif
|
||||
|
||||
module_param_named(debug_log, cts_show_debug_log, bool, 0660);
|
||||
MODULE_PARM_DESC(debug_log, "Show debug log control");
|
||||
|
||||
static int cts_suspend(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cts_info("Suspend");
|
||||
|
||||
cts_lock_device(&cts_data->cts_dev);
|
||||
ret = cts_suspend_device(&cts_data->cts_dev);
|
||||
cts_unlock_device(&cts_data->cts_dev);
|
||||
|
||||
if (ret)
|
||||
cts_err("Suspend device failed %d", ret);
|
||||
|
||||
ret = cts_stop_device(&cts_data->cts_dev);
|
||||
if (ret) {
|
||||
cts_err("Stop device failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
#ifdef CFG_CTS_GESTURE
|
||||
/* Enable IRQ wake if gesture wakeup enabled */
|
||||
if (cts_is_gesture_wakeup_enabled(&cts_data->cts_dev)) {
|
||||
ret = cts_plat_enable_irq_wake(cts_data->pdata);
|
||||
if (ret) {
|
||||
cts_err("Enable IRQ wake failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
ret = cts_plat_enable_irq(cts_data->pdata);
|
||||
if (ret) {
|
||||
cts_err("Enable IRQ failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif /* CFG_CTS_GESTURE */
|
||||
|
||||
/** - To avoid waking up while not sleeping,
|
||||
*delay 20ms to ensure reliability
|
||||
*/
|
||||
msleep(20);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int cts_resume(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
int ret;
|
||||
|
||||
cts_info("Resume");
|
||||
|
||||
#ifdef CFG_CTS_GESTURE
|
||||
if (cts_is_gesture_wakeup_enabled(&cts_data->cts_dev)) {
|
||||
ret = cts_plat_disable_irq_wake(cts_data->pdata);
|
||||
if (ret)
|
||||
cts_warn("Disable IRQ wake failed %d", ret);
|
||||
ret = cts_plat_disable_irq(cts_data->pdata);
|
||||
if (ret < 0)
|
||||
cts_err("Disable IRQ failed %d", ret);
|
||||
}
|
||||
#endif /* CFG_CTS_GESTURE */
|
||||
|
||||
cts_lock_device(&cts_data->cts_dev);
|
||||
ret = cts_resume_device(&cts_data->cts_dev);
|
||||
cts_unlock_device(&cts_data->cts_dev);
|
||||
if (ret) {
|
||||
cts_warn("Resume device failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = cts_start_device(&cts_data->cts_dev);
|
||||
if (ret) {
|
||||
cts_err("Start device failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void cts_resume_work_func(struct work_struct *work)
|
||||
{
|
||||
struct chipone_ts_data *cts_data =
|
||||
container_of(work, struct chipone_ts_data, ts_resume_work);
|
||||
cts_info("%s", __func__);
|
||||
cts_resume(cts_data);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CTS_PM_FB_NOTIFIER
|
||||
#ifdef CFG_CTS_DRM_NOTIFIER
|
||||
static int fb_notifier_callback(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
volatile int blank;
|
||||
const struct cts_platform_data *pdata =
|
||||
container_of(nb, struct cts_platform_data, fb_notifier);
|
||||
struct chipone_ts_data *cts_data =
|
||||
container_of(pdata->cts_dev, struct chipone_ts_data, cts_dev);
|
||||
struct drm_panel_notifier *evdata = data;
|
||||
|
||||
cts_info("FB notifier callback");
|
||||
if (!evdata || !cts_data)
|
||||
return 0;
|
||||
|
||||
blank = *(int *)evdata->data;
|
||||
cts_info("action=%lu, blank=%d\n", action, blank);
|
||||
|
||||
if (action == DRM_PANEL_EARLY_EVENT_BLANK) {
|
||||
if (blank == DRM_PANEL_BLANK_POWERDOWN)
|
||||
cts_suspend(cts_data);
|
||||
} else if (evdata->data) {
|
||||
blank = *(int *)evdata->data;
|
||||
if (action == DRM_PANEL_EVENT_BLANK) {
|
||||
if (blank == DRM_PANEL_BLANK_UNBLANK)
|
||||
/* cts_resume(cts_data); */
|
||||
queue_work(cts_data->workqueue,
|
||||
&cts_data->ts_resume_work);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
static int fb_notifier_callback(struct notifier_block *nb,
|
||||
unsigned long action, void *data)
|
||||
{
|
||||
volatile int blank;
|
||||
const struct cts_platform_data *pdata =
|
||||
container_of(nb, struct cts_platform_data, fb_notifier);
|
||||
struct chipone_ts_data *cts_data =
|
||||
container_of(pdata->cts_dev, struct chipone_ts_data, cts_dev);
|
||||
struct fb_event *evdata = data;
|
||||
|
||||
cts_info("FB notifier callback");
|
||||
|
||||
if (evdata && evdata->data) {
|
||||
if (action == FB_EVENT_BLANK) {
|
||||
blank = *(int *)evdata->data;
|
||||
if (blank == FB_BLANK_UNBLANK) {
|
||||
/* cts_resume(cts_data); */
|
||||
queue_work(cts_data->workqueue,
|
||||
&cts_data->ts_resume_work);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
} else if (action == FB_EARLY_EVENT_BLANK) {
|
||||
blank = *(int *)evdata->data;
|
||||
if (blank == FB_BLANK_POWERDOWN) {
|
||||
cts_suspend(cts_data);
|
||||
return NOTIFY_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int cts_init_pm_fb_notifier(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
cts_info("Init FB notifier");
|
||||
|
||||
cts_data->pdata->fb_notifier.notifier_call = fb_notifier_callback;
|
||||
|
||||
#ifdef CFG_CTS_DRM_NOTIFIER
|
||||
{
|
||||
int ret = -ENODEV;
|
||||
|
||||
if (active_panel) {
|
||||
ret =
|
||||
drm_panel_notifier_register(active_panel,
|
||||
&cts_data->pdata->fb_notifier);
|
||||
if (ret)
|
||||
cts_err
|
||||
("register drm_notifier failed. ret=%d\n",
|
||||
ret);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
return fb_register_client(&cts_data->pdata->fb_notifier);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int cts_deinit_pm_fb_notifier(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
cts_info("Deinit FB notifier");
|
||||
#ifdef CFG_CTS_DRM_NOTIFIER
|
||||
{
|
||||
int ret = 0;
|
||||
|
||||
if (active_panel) {
|
||||
ret =
|
||||
drm_panel_notifier_unregister(active_panel,
|
||||
&cts_data->pdata->fb_notifier);
|
||||
if (ret)
|
||||
cts_err
|
||||
("Error occurred while unregistering drm_notifier.\n");
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
return fb_unregister_client(&cts_data->pdata->fb_notifier);
|
||||
#endif
|
||||
}
|
||||
#endif /* CONFIG_CTS_PM_FB_NOTIFIER */
|
||||
|
||||
#ifdef CFG_CTS_DRM_NOTIFIER
|
||||
static int check_dt(struct device_node *np)
|
||||
{
|
||||
int i;
|
||||
int count;
|
||||
struct device_node *node;
|
||||
struct drm_panel *panel;
|
||||
|
||||
count = of_count_phandle_with_args(np, "panel", NULL);
|
||||
if (count <= 0)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
node = of_parse_phandle(np, "panel", i);
|
||||
panel = of_drm_find_panel(node);
|
||||
of_node_put(node);
|
||||
if (!IS_ERR(panel)) {
|
||||
cts_info("check active_panel");
|
||||
active_panel = panel;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (node)
|
||||
pr_err("%s: %s not actived\n", __func__, node->name);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int check_default_tp(struct device_node *dt, const char *prop)
|
||||
{
|
||||
const char *active_tp;
|
||||
const char *compatible;
|
||||
char *start;
|
||||
int ret;
|
||||
|
||||
ret = of_property_read_string(dt->parent, prop, &active_tp);
|
||||
if (ret) {
|
||||
cts_err(" %s:fail to read %s %d\n", __func__, prop, ret);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ret = of_property_read_string(dt, "compatible", &compatible);
|
||||
if (ret < 0) {
|
||||
cts_err(" %s:fail to read %s %d\n", __func__, "compatible",
|
||||
ret);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
start = strnstr(active_tp, compatible, strlen(active_tp));
|
||||
if (start == NULL) {
|
||||
cts_err(" %s:no match compatible, %s, %s\n",
|
||||
__func__, compatible, active_tp);
|
||||
ret = -ENODEV;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CTS_MTK_GET_PANEL
|
||||
char panel_name[50] = { 0 };
|
||||
|
||||
static int cts_get_panel(void)
|
||||
{
|
||||
int ret = -1;
|
||||
|
||||
cts_info("enter");
|
||||
if (saved_command_line) {
|
||||
char *sub;
|
||||
char key_prefix[] = "mipi_mot_vid_";
|
||||
char ic_prefix[] = "icnl";
|
||||
|
||||
cts_info("saved_command_line is %s", saved_command_line);
|
||||
sub = strstr(saved_command_line, key_prefix);
|
||||
if (sub) {
|
||||
char *d;
|
||||
int n, len, len_max = 50;
|
||||
|
||||
d = strstr(sub, " ");
|
||||
if (d)
|
||||
n = strlen(sub) - strlen(d);
|
||||
else
|
||||
n = strlen(sub);
|
||||
|
||||
if (n > len_max)
|
||||
len = len_max;
|
||||
else
|
||||
len = n;
|
||||
|
||||
strncpy(panel_name, sub, len);
|
||||
active_panel_name = panel_name;
|
||||
if (strstr(active_panel_name, ic_prefix))
|
||||
cts_info("active_panel_name=%s",
|
||||
active_panel_name);
|
||||
else {
|
||||
cts_info("Not chipone panel!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
} else {
|
||||
cts_info("chipone active panel not found!");
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
cts_info("saved_command_line null!");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
static int cts_driver_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
#else
|
||||
static int cts_driver_probe(struct spi_device *client)
|
||||
#endif
|
||||
{
|
||||
struct chipone_ts_data *cts_data = NULL;
|
||||
int ret = 0;
|
||||
|
||||
#ifdef CTS_MTK_GET_PANEL
|
||||
ret = cts_get_panel();
|
||||
if (ret) {
|
||||
cts_info("MTK get chipone panel error");
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CFG_CTS_DRM_NOTIFIER
|
||||
{
|
||||
struct device_node *dp = client->dev.of_node;
|
||||
|
||||
if (check_dt(dp)) {
|
||||
if (!check_default_tp(dp, "qcom,i2c-touch-active"))
|
||||
ret = -EPROBE_DEFER;
|
||||
else
|
||||
ret = -ENODEV;
|
||||
|
||||
cts_err("%s: %s not actived\n", __func__, dp->name);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
cts_info("Probe i2c client: name='%s' addr=0x%02x flags=0x%02x irq=%d",
|
||||
client->name, client->addr, client->flags, client->irq);
|
||||
|
||||
#if !defined(CONFIG_MTK_PLATFORM)
|
||||
if (client->addr != CTS_DEV_NORMAL_MODE_I2CADDR) {
|
||||
cts_err("Probe i2c addr 0x%02x != driver config addr 0x%02x",
|
||||
client->addr, CTS_DEV_NORMAL_MODE_I2CADDR);
|
||||
return -ENODEV;
|
||||
};
|
||||
#endif
|
||||
|
||||
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
|
||||
cts_err("Check functionality failed");
|
||||
return -ENODEV;
|
||||
}
|
||||
#endif
|
||||
|
||||
cts_data =
|
||||
(struct chipone_ts_data *)kzalloc(sizeof(*cts_data), GFP_KERNEL);
|
||||
if (cts_data == NULL) {
|
||||
cts_err("Allocate chipone_ts_data failed");
|
||||
return -ENOMEM;
|
||||
}
|
||||
cts_data->pdata = (struct cts_platform_data *)
|
||||
kzalloc(sizeof(struct cts_platform_data), GFP_KERNEL);
|
||||
if (cts_data->pdata == NULL) {
|
||||
cts_err("Allocate cts_platform_data failed");
|
||||
ret = -ENOMEM;
|
||||
goto err_free_cts_data;
|
||||
}
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
i2c_set_clientdata(client, cts_data);
|
||||
cts_data->i2c_client = client;
|
||||
cts_data->device = &client->dev;
|
||||
#else
|
||||
spi_set_drvdata(client, cts_data);
|
||||
cts_data->spi_client = client;
|
||||
cts_data->device = &client->dev;
|
||||
#endif
|
||||
|
||||
cts_init_platform_data(cts_data->pdata, client);
|
||||
|
||||
cts_data->cts_dev.pdata = cts_data->pdata;
|
||||
cts_data->pdata->cts_dev = &cts_data->cts_dev;
|
||||
|
||||
cts_data->workqueue =
|
||||
create_singlethread_workqueue(CFG_CTS_DEVICE_NAME "-workqueue");
|
||||
if (cts_data->workqueue == NULL) {
|
||||
cts_err("Create workqueue failed");
|
||||
ret = -ENOMEM;
|
||||
goto err_deinit_platform_data;
|
||||
}
|
||||
#ifdef CONFIG_CTS_ESD_PROTECTION
|
||||
cts_data->esd_workqueue =
|
||||
create_singlethread_workqueue(CFG_CTS_DEVICE_NAME "-esd_workqueue");
|
||||
if (cts_data->esd_workqueue == NULL) {
|
||||
cts_err("Create esd workqueue failed");
|
||||
ret = -ENOMEM;
|
||||
goto err_destroy_workqueue;
|
||||
}
|
||||
#endif
|
||||
ret = cts_plat_request_resource(cts_data->pdata);
|
||||
if (ret < 0) {
|
||||
cts_err("Request resource failed %d", ret);
|
||||
goto err_destroy_esd_workqueue;
|
||||
}
|
||||
|
||||
ret = cts_reset_device(&cts_data->cts_dev);
|
||||
if (ret < 0) {
|
||||
cts_err("Reset device failed %d", ret);
|
||||
goto err_free_resource;
|
||||
}
|
||||
|
||||
ret = cts_probe_device(&cts_data->cts_dev);
|
||||
if (ret) {
|
||||
cts_err("Probe device failed %d", ret);
|
||||
goto err_free_resource;
|
||||
}
|
||||
|
||||
ret = cts_plat_init_touch_device(cts_data->pdata);
|
||||
if (ret < 0) {
|
||||
cts_err("Init touch device failed %d", ret);
|
||||
goto err_free_resource;
|
||||
}
|
||||
|
||||
ret = cts_plat_init_vkey_device(cts_data->pdata);
|
||||
if (ret < 0) {
|
||||
cts_err("Init vkey device failed %d", ret);
|
||||
goto err_deinit_touch_device;
|
||||
}
|
||||
|
||||
ret = cts_plat_init_gesture(cts_data->pdata);
|
||||
if (ret < 0) {
|
||||
cts_err("Init gesture failed %d", ret);
|
||||
goto err_deinit_vkey_device;
|
||||
}
|
||||
|
||||
cts_init_esd_protection(cts_data);
|
||||
|
||||
ret = cts_tool_init(cts_data);
|
||||
if (ret < 0)
|
||||
cts_warn("Init tool node failed %d", ret);
|
||||
|
||||
ret = cts_sysfs_add_device(&client->dev);
|
||||
if (ret < 0)
|
||||
cts_warn("Add sysfs entry for device failed %d", ret);
|
||||
|
||||
#ifdef CONFIG_CTS_PM_FB_NOTIFIER
|
||||
ret = cts_init_pm_fb_notifier(cts_data);
|
||||
if (ret) {
|
||||
cts_err("Init FB notifier failed %d", ret);
|
||||
goto err_deinit_sysfs;
|
||||
}
|
||||
#endif /* CONFIG_CTS_PM_FB_NOTIFIER */
|
||||
|
||||
ret = cts_plat_request_irq(cts_data->pdata);
|
||||
if (ret < 0) {
|
||||
cts_err("Request IRQ failed %d", ret);
|
||||
goto err_register_fb;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CTS_CHARGE_DETECT
|
||||
ret = cts_charger_detect_init(cts_data);
|
||||
if (ret)
|
||||
cts_err("Init charger detect failed %d", ret);
|
||||
/* Ignore this error */
|
||||
#endif
|
||||
|
||||
/* Init firmware upgrade work and schedule */
|
||||
INIT_DELAYED_WORK(&cts_data->fw_upgrade_work,
|
||||
cts_firmware_upgrade_work);
|
||||
queue_delayed_work(cts_data->workqueue, &cts_data->fw_upgrade_work,
|
||||
msecs_to_jiffies(15 * 1000));
|
||||
|
||||
INIT_WORK(&cts_data->ts_resume_work, cts_resume_work_func);
|
||||
|
||||
return 0;
|
||||
|
||||
err_register_fb:
|
||||
#ifdef CONFIG_CTS_PM_FB_NOTIFIER
|
||||
cts_deinit_pm_fb_notifier(cts_data);
|
||||
err_deinit_sysfs:
|
||||
#endif /* CONFIG_CTS_PM_FB_NOTIFIER */
|
||||
cts_sysfs_remove_device(&client->dev);
|
||||
#ifdef CONFIG_CTS_LEGACY_TOOL
|
||||
cts_tool_deinit(cts_data);
|
||||
#endif /* CONFIG_CTS_LEGACY_TOOL */
|
||||
|
||||
#ifdef CONFIG_CTS_ESD_PROTECTION
|
||||
cts_deinit_esd_protection(cts_data);
|
||||
#endif /* CONFIG_CTS_ESD_PROTECTION */
|
||||
|
||||
#ifdef CFG_CTS_GESTURE
|
||||
cts_plat_deinit_gesture(cts_data->pdata);
|
||||
#endif /* CFG_CTS_GESTURE */
|
||||
|
||||
err_deinit_vkey_device:
|
||||
#ifdef CONFIG_CTS_VIRTUALKEY
|
||||
cts_plat_deinit_vkey_device(cts_data->pdata);
|
||||
#endif /* CONFIG_CTS_VIRTUALKEY */
|
||||
|
||||
err_deinit_touch_device:
|
||||
cts_plat_deinit_touch_device(cts_data->pdata);
|
||||
|
||||
err_free_resource:
|
||||
cts_plat_free_resource(cts_data->pdata);
|
||||
err_destroy_esd_workqueue:
|
||||
#ifdef CONFIG_CTS_ESD_PROTECTION
|
||||
destroy_workqueue(cts_data->esd_workqueue);
|
||||
err_destroy_workqueue:
|
||||
#endif
|
||||
destroy_workqueue(cts_data->workqueue);
|
||||
err_deinit_platform_data:
|
||||
cts_deinit_platform_data(cts_data->pdata);
|
||||
kfree(cts_data->pdata);
|
||||
err_free_cts_data:
|
||||
kfree(cts_data);
|
||||
|
||||
cts_err("Probe failed %d", ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
static int cts_driver_remove(struct i2c_client *client)
|
||||
#else
|
||||
static int cts_driver_remove(struct spi_device *client)
|
||||
#endif
|
||||
{
|
||||
struct chipone_ts_data *cts_data;
|
||||
int ret = 0;
|
||||
|
||||
cts_info("Remove");
|
||||
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
cts_data = (struct chipone_ts_data *)i2c_get_clientdata(client);
|
||||
#else
|
||||
cts_data = (struct chipone_ts_data *)spi_get_drvdata(client);
|
||||
#endif
|
||||
if (cts_data) {
|
||||
ret = cts_stop_device(&cts_data->cts_dev);
|
||||
if (ret)
|
||||
cts_warn("Stop device failed %d", ret);
|
||||
|
||||
#ifdef CONFIG_CTS_CHARGE_DETECT
|
||||
cts_charger_detect_deinit(cts_data);
|
||||
#endif
|
||||
|
||||
cts_plat_free_irq(cts_data->pdata);
|
||||
|
||||
#ifdef CONFIG_CTS_PM_FB_NOTIFIER
|
||||
cts_deinit_pm_fb_notifier(cts_data);
|
||||
#endif /* CONFIG_CTS_PM_FB_NOTIFIER */
|
||||
|
||||
cts_tool_deinit(cts_data);
|
||||
|
||||
cts_sysfs_remove_device(&client->dev);
|
||||
|
||||
cts_deinit_esd_protection(cts_data);
|
||||
|
||||
cts_plat_deinit_touch_device(cts_data->pdata);
|
||||
|
||||
cts_plat_deinit_vkey_device(cts_data->pdata);
|
||||
|
||||
cts_plat_deinit_gesture(cts_data->pdata);
|
||||
|
||||
cts_plat_free_resource(cts_data->pdata);
|
||||
|
||||
#ifdef CONFIG_CTS_ESD_PROTECTION
|
||||
if (cts_data->esd_workqueue)
|
||||
destroy_workqueue(cts_data->esd_workqueue);
|
||||
#endif
|
||||
|
||||
if (cts_data->workqueue)
|
||||
destroy_workqueue(cts_data->workqueue);
|
||||
|
||||
cts_deinit_platform_data(cts_data->pdata);
|
||||
|
||||
cts_deinit_rtdata(&cts_data->cts_dev);
|
||||
|
||||
if (cts_data->pdata)
|
||||
kfree(cts_data->pdata);
|
||||
kfree(cts_data);
|
||||
} else {
|
||||
cts_warn
|
||||
("Chipone i2c driver remove while NULL chipone_ts_data");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_CTS_PM_LEGACY
|
||||
static int cts_i2c_driver_suspend(struct device *dev, pm_message_t state)
|
||||
{
|
||||
cts_info("Suspend by legacy power management");
|
||||
return cts_suspend(dev_get_drvdata(dev));
|
||||
}
|
||||
|
||||
static int cts_i2c_driver_resume(struct device *dev)
|
||||
{
|
||||
cts_info("Resume by legacy power management");
|
||||
return cts_resume(dev_get_drvdata(dev));
|
||||
}
|
||||
#endif /* CONFIG_CTS_PM_LEGACY */
|
||||
|
||||
#ifdef CONFIG_CTS_PM_GENERIC
|
||||
static int cts_i2c_driver_pm_suspend(struct device *dev)
|
||||
{
|
||||
cts_info("Suspend by bus power management");
|
||||
return cts_suspend(dev_get_drvdata(dev));
|
||||
}
|
||||
|
||||
static int cts_i2c_driver_pm_resume(struct device *dev)
|
||||
{
|
||||
cts_info("Resume by bus power management");
|
||||
return cts_resume(dev_get_drvdata(dev));
|
||||
}
|
||||
|
||||
/* bus control the suspend/resume procedure */
|
||||
static const struct dev_pm_ops cts_i2c_driver_pm_ops = {
|
||||
.suspend = cts_i2c_driver_pm_suspend,
|
||||
.resume = cts_i2c_driver_pm_resume,
|
||||
};
|
||||
#endif /* CONFIG_CTS_PM_GENERIC */
|
||||
|
||||
#ifdef CONFIG_CTS_SYSFS
|
||||
static ssize_t reset_pin_show(struct device_driver *driver, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "CFG_CTS_HAS_RESET_PIN: %c\n",
|
||||
#ifdef CFG_CTS_HAS_RESET_PIN
|
||||
'Y'
|
||||
#else
|
||||
'N'
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||
static DRIVER_ATTR(reset_pin, S_IRUGO, reset_pin_show, NULL);
|
||||
#else
|
||||
static DRIVER_ATTR_RO(reset_pin);
|
||||
#endif
|
||||
|
||||
static ssize_t swap_xy_show(struct device_driver *dev, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "CFG_CTS_SWAP_XY: %c\n",
|
||||
#ifdef CFG_CTS_SWAP_XY
|
||||
'Y'
|
||||
#else
|
||||
'N'
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||
static DRIVER_ATTR(swap_xy, S_IRUGO, swap_xy_show, NULL);
|
||||
#else
|
||||
static DRIVER_ATTR_RO(swap_xy);
|
||||
#endif
|
||||
|
||||
static ssize_t wrap_x_show(struct device_driver *dev, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "CFG_CTS_WRAP_X: %c\n",
|
||||
#ifdef CFG_CTS_WRAP_X
|
||||
'Y'
|
||||
#else
|
||||
'N'
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||
static DRIVER_ATTR(wrap_x, S_IRUGO, wrap_x_show, NULL);
|
||||
#else
|
||||
static DRIVER_ATTR_RO(wrap_x);
|
||||
#endif
|
||||
|
||||
static ssize_t wrap_y_show(struct device_driver *dev, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "CFG_CTS_WRAP_Y: %c\n",
|
||||
#ifdef CFG_CTS_WRAP_Y
|
||||
'Y'
|
||||
#else
|
||||
'N'
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||
static DRIVER_ATTR(wrap_y, S_IRUGO, wrap_y_show, NULL);
|
||||
#else
|
||||
static DRIVER_ATTR_RO(wrap_y);
|
||||
#endif
|
||||
|
||||
static ssize_t force_update_show(struct device_driver *dev, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "CFG_CTS_HAS_RESET_PIN: %c\n",
|
||||
#ifdef CFG_CTS_FIRMWARE_FORCE_UPDATE
|
||||
'Y'
|
||||
#else
|
||||
'N'
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||
static DRIVER_ATTR(force_update, S_IRUGO, force_update_show, NULL);
|
||||
#else
|
||||
static DRIVER_ATTR_RO(force_update);
|
||||
#endif
|
||||
|
||||
static ssize_t max_touch_num_show(struct device_driver *dev, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "CFG_CTS_MAX_TOUCH_NUM: %d\n",
|
||||
CFG_CTS_MAX_TOUCH_NUM);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||
static DRIVER_ATTR(max_touch_num, S_IRUGO, max_touch_num_show, NULL);
|
||||
#else
|
||||
static DRIVER_ATTR_RO(max_touch_num);
|
||||
#endif
|
||||
|
||||
static ssize_t vkey_show(struct device_driver *dev, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "CONFIG_CTS_VIRTUALKEY: %c\n",
|
||||
#ifdef CONFIG_CTS_VIRTUALKEY
|
||||
'Y'
|
||||
#else
|
||||
'N'
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||
static DRIVER_ATTR(vkey, S_IRUGO, vkey_show, NULL);
|
||||
#else
|
||||
static DRIVER_ATTR_RO(vkey);
|
||||
#endif
|
||||
|
||||
static ssize_t gesture_show(struct device_driver *dev, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "CFG_CTS_GESTURE: %c\n",
|
||||
#ifdef CFG_CTS_GESTURE
|
||||
'Y'
|
||||
#else
|
||||
'N'
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||
static DRIVER_ATTR(gesture, S_IRUGO, gesture_show, NULL);
|
||||
#else
|
||||
static DRIVER_ATTR_RO(gesture);
|
||||
#endif
|
||||
|
||||
static ssize_t esd_protection_show(struct device_driver *dev, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "CONFIG_CTS_ESD_PROTECTION: %c\n",
|
||||
#ifdef CONFIG_CTS_ESD_PROTECTION
|
||||
'Y'
|
||||
#else
|
||||
'N'
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||
static DRIVER_ATTR(esd_protection, S_IRUGO, esd_protection_show, NULL);
|
||||
#else
|
||||
static DRIVER_ATTR_RO(esd_protection);
|
||||
#endif
|
||||
|
||||
static ssize_t slot_protocol_show(struct device_driver *dev, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "CONFIG_CTS_SLOTPROTOCOL: %c\n",
|
||||
#ifdef CONFIG_CTS_SLOTPROTOCOL
|
||||
'Y'
|
||||
#else
|
||||
'N'
|
||||
#endif
|
||||
);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||
static DRIVER_ATTR(slot_protocol, S_IRUGO, slot_protocol_show, NULL);
|
||||
#else
|
||||
static DRIVER_ATTR_RO(slot_protocol);
|
||||
#endif
|
||||
|
||||
static ssize_t max_xfer_size_show(struct device_driver *dev, char *buf)
|
||||
{
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
return snprintf(buf, PAGE_SIZE, "CFG_CTS_MAX_I2C_XFER_SIZE: %d\n",
|
||||
CFG_CTS_MAX_I2C_XFER_SIZE);
|
||||
#else
|
||||
return snprintf(buf, PAGE_SIZE, "CFG_CTS_MAX_SPI_XFER_SIZE: %d\n",
|
||||
CFG_CTS_MAX_SPI_XFER_SIZE);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||
static DRIVER_ATTR(max_xfer_size, S_IRUGO, max_xfer_size_show, NULL);
|
||||
#else
|
||||
static DRIVER_ATTR_RO(max_xfer_size);
|
||||
#endif
|
||||
|
||||
static ssize_t driver_info_show(struct device_driver *dev, char *buf)
|
||||
{
|
||||
return snprintf(buf, PAGE_SIZE, "Driver version: %s\n",
|
||||
CFG_CTS_DRIVER_VERSION);
|
||||
}
|
||||
|
||||
#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 0)
|
||||
static DRIVER_ATTR(driver_info, S_IRUGO, driver_info_show, NULL);
|
||||
#else
|
||||
static DRIVER_ATTR_RO(driver_info);
|
||||
#endif
|
||||
|
||||
static struct attribute *cts_i2c_driver_config_attrs[] = {
|
||||
&driver_attr_reset_pin.attr,
|
||||
&driver_attr_swap_xy.attr,
|
||||
&driver_attr_wrap_x.attr,
|
||||
&driver_attr_wrap_y.attr,
|
||||
&driver_attr_force_update.attr,
|
||||
&driver_attr_max_touch_num.attr,
|
||||
&driver_attr_vkey.attr,
|
||||
&driver_attr_gesture.attr,
|
||||
&driver_attr_esd_protection.attr,
|
||||
&driver_attr_slot_protocol.attr,
|
||||
&driver_attr_max_xfer_size.attr,
|
||||
&driver_attr_driver_info.attr,
|
||||
NULL
|
||||
};
|
||||
|
||||
static const struct attribute_group cts_i2c_driver_config_group = {
|
||||
.name = "config",
|
||||
.attrs = cts_i2c_driver_config_attrs,
|
||||
};
|
||||
|
||||
static const struct attribute_group *cts_i2c_driver_config_groups[] = {
|
||||
&cts_i2c_driver_config_group,
|
||||
NULL,
|
||||
};
|
||||
#endif /* CONFIG_CTS_SYSFS */
|
||||
|
||||
#ifdef CONFIG_CTS_OF
|
||||
static const struct of_device_id cts_i2c_of_match_table[] = {
|
||||
{.compatible = CFG_CTS_OF_DEVICE_ID_NAME, },
|
||||
{ },
|
||||
};
|
||||
|
||||
MODULE_DEVICE_TABLE(of, cts_i2c_of_match_table);
|
||||
#endif /* CONFIG_CTS_OF */
|
||||
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
static const struct i2c_device_id cts_device_id_table[] = {
|
||||
{ CFG_CTS_DEVICE_NAME, 0 },
|
||||
{ }
|
||||
};
|
||||
#else
|
||||
static const struct spi_device_id cts_device_id_table[] = {
|
||||
{ CFG_CTS_DEVICE_NAME, 0 },
|
||||
{ }
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
static struct i2c_driver cts_i2c_driver = {
|
||||
#else
|
||||
static struct spi_driver cts_spi_driver = {
|
||||
#endif
|
||||
.probe = cts_driver_probe,
|
||||
.remove = cts_driver_remove,
|
||||
.driver = {
|
||||
.name = CFG_CTS_DRIVER_NAME,
|
||||
.owner = THIS_MODULE,
|
||||
#ifdef CONFIG_CTS_OF
|
||||
.of_match_table = of_match_ptr(cts_i2c_of_match_table),
|
||||
#endif /* CONFIG_CTS_OF */
|
||||
#ifdef CONFIG_CTS_SYSFS
|
||||
.groups = cts_i2c_driver_config_groups,
|
||||
#endif /* CONFIG_CTS_SYSFS */
|
||||
#ifdef CONFIG_CTS_PM_LEGACY
|
||||
.suspend = cts_i2c_driver_suspend,
|
||||
.resume = cts_i2c_driver_resume,
|
||||
#endif /* CONFIG_CTS_PM_LEGACY */
|
||||
#ifdef CONFIG_CTS_PM_GENERIC
|
||||
.pm = &cts_i2c_driver_pm_ops,
|
||||
#endif /* CONFIG_CTS_PM_GENERIC */
|
||||
|
||||
},
|
||||
.id_table = cts_device_id_table,
|
||||
};
|
||||
|
||||
static int __init cts_driver_init(void)
|
||||
{
|
||||
cts_info("Init");
|
||||
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
return i2c_add_driver(&cts_i2c_driver);
|
||||
#else
|
||||
pr_err("%s spi", __func__);
|
||||
return spi_register_driver(&cts_spi_driver);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void __exit cts_driver_exit(void)
|
||||
{
|
||||
cts_info("Exit");
|
||||
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
i2c_del_driver(&cts_i2c_driver);
|
||||
#else
|
||||
spi_unregister_driver(&cts_spi_driver);
|
||||
#endif
|
||||
}
|
||||
|
||||
module_init(cts_driver_init);
|
||||
module_exit(cts_driver_exit);
|
||||
|
||||
#if KERNEL_VERSION(5, 4, 0) <= LINUX_VERSION_CODE
|
||||
MODULE_IMPORT_NS(VFS_internal_I_am_really_a_filesystem_and_am_NOT_a_driver);
|
||||
#endif
|
||||
MODULE_DESCRIPTION("Chipone TDDI touchscreen Driver for QualComm platform");
|
||||
MODULE_VERSION(CFG_CTS_DRIVER_VERSION);
|
||||
MODULE_AUTHOR("Miao Defang <dfmiao@chiponeic.com>");
|
||||
MODULE_LICENSE("GPL");
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef CTS_PLAT_QCOM_CONFIG_H
|
||||
#define CTS_PLAT_QCOM_CONFIG_H
|
||||
|
||||
#define CONFIG_CTS_PM_FB_NOTIFIER
|
||||
|
||||
#ifdef CONFIG_CTS_PM_FB_NOTIFIER
|
||||
/*
|
||||
* #ifdef CONFIG_DRM
|
||||
* #define CFG_CTS_DRM_NOTIFIER
|
||||
* #endif
|
||||
*/
|
||||
#ifdef CONFIG_DRM
|
||||
#define CFG_CTS_DRM_NOTIFIER
|
||||
#endif /*CONFIG_DRM_MSM */
|
||||
#else /*CONFIG_CTS_PM_FB_NOTIFIER */
|
||||
#if defined(CONFIG_PM_SLEEP) && defined(CONFIG_PM_SUSPEND)
|
||||
/* #define CONFIG_CTS_PM_GENERIC */
|
||||
#endif /* CONFIG_PM_SLEEP */
|
||||
|
||||
#if !defined(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_SPI_XFER_SIZE (8192u)
|
||||
|
||||
#define CTS_FW_LOG_REDIRECT_SIGN 0x60
|
||||
#define CTS_FW_LOG_BUF_LEN 128
|
||||
|
||||
/**
|
||||
* #define CFG_CTS_SWAP_XY
|
||||
* #define CFG_CTS_WRAP_X
|
||||
* #define CFG_CTS_WRAP_Y
|
||||
*/
|
||||
|
||||
#define CFG_CTS_DEVICE_NAME "chipone-tddi"
|
||||
#define CFG_CTS_DRIVER_NAME "chipone-tddi"
|
||||
|
||||
#if CFG_CTS_MAX_I2C_XFER_SIZE < 8
|
||||
#error "I2C transfer size should large than 8"
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_OF
|
||||
#define CONFIG_CTS_OF
|
||||
#endif
|
||||
#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 /* CTS_PLAT_QCOM_CONFIG_H */
|
||||
1259
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_platform.c
Normal file
1259
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_platform.c
Normal file
File diff suppressed because it is too large
Load diff
262
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_platform.h
Normal file
262
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_platform.h
Normal file
|
|
@ -0,0 +1,262 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#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 <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>
|
||||
|
||||
#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"
|
||||
|
||||
extern bool cts_show_debug_log;
|
||||
|
||||
#ifndef LOG_TAG
|
||||
#define LOG_TAG ""
|
||||
#endif /* LOG_TAG */
|
||||
|
||||
#define cts_err(fmt, ...) \
|
||||
printk("<E>CTS-" LOG_TAG " " fmt"\n", ##__VA_ARGS__)
|
||||
#define cts_warn(fmt, ...) \
|
||||
printk("<W>CTS-" LOG_TAG " " fmt"\n", ##__VA_ARGS__)
|
||||
#define cts_info(fmt, ...) \
|
||||
printk("<I>CTS-" LOG_TAG " " fmt"\n", ##__VA_ARGS__)
|
||||
#define cts_dbg(fmt, ...) \
|
||||
do { \
|
||||
if (cts_show_debug_log) \
|
||||
printk("<D>CTS-" LOG_TAG " "fmt"\n", ##__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
struct cts_device;
|
||||
struct cts_device_touch_msg;
|
||||
struct cts_device_gesture_info;
|
||||
|
||||
struct cts_platform_data {
|
||||
int irq;
|
||||
int int_gpio;
|
||||
#ifdef CFG_CTS_HAS_RESET_PIN
|
||||
int rst_gpio;
|
||||
#endif /* CFG_CTS_HAS_RESET_PIN */
|
||||
|
||||
#ifdef CFG_CTS_MANUAL_CS
|
||||
int cs_gpio;
|
||||
#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 /* CONFIG_CTS_VIRTUALKEY */
|
||||
|
||||
#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;
|
||||
|
||||
#ifndef CONFIG_GENERIC_HARDIRQS
|
||||
struct work_struct ts_irq_work;
|
||||
#endif /* CONFIG_GENERIC_HARDIRQS */
|
||||
|
||||
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 /* CFG_CTS_GESTURE */
|
||||
|
||||
#ifdef CONFIG_CTS_PM_FB_NOTIFIER
|
||||
struct notifier_block fb_notifier;
|
||||
#endif /* CONFIG_CTS_PM_FB_NOTIFIER */
|
||||
|
||||
#ifdef CFG_CTS_FORCE_UP
|
||||
struct delayed_work touch_event_timeout_work;
|
||||
#endif
|
||||
|
||||
#ifdef CFG_CTS_FW_LOG_REDIRECT
|
||||
u8 fw_log_buf[CTS_FW_LOG_BUF_LEN];
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
struct i2c_client *i2c_client;
|
||||
u8 i2c_fifo_buf[CFG_CTS_MAX_I2C_XFER_SIZE];
|
||||
#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;
|
||||
#endif /* CONFIG_CTS_I2C_HOST */
|
||||
};
|
||||
|
||||
#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);
|
||||
extern int cts_plat_is_i2c_online(struct cts_platform_data *pdata, u8 i2c_addr);
|
||||
#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_plat_is_normal_mode(struct cts_platform_data *pdata);
|
||||
extern int cts_init_platform_data(struct cts_platform_data *pdata,
|
||||
struct spi_device *spi);
|
||||
#endif
|
||||
|
||||
extern int cts_deinit_platform_data(struct cts_platform_data *pdata);
|
||||
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);
|
||||
extern int cts_plat_process_touch_msg(struct cts_platform_data *pdata,
|
||||
struct cts_device_touch_msg *msgs,
|
||||
int num);
|
||||
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 */
|
||||
|
||||
#ifdef CFG_CTS_FW_LOG_REDIRECT
|
||||
extern size_t cts_plat_get_max_fw_log_size(struct cts_platform_data *pdata);
|
||||
extern u8 *cts_plat_get_fw_log_buf(struct cts_platform_data *pdata,
|
||||
size_t size);
|
||||
#endif
|
||||
|
||||
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 */
|
||||
38
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_sfctrl.h
Normal file
38
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_sfctrl.h
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#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)(const struct cts_device *cts_dev, u32 *id);
|
||||
int (*se)(const struct cts_device *cts_dev, u32 sector_addr);
|
||||
int (*be)(const struct cts_device *cts_dev, u32 sector_addr);
|
||||
int (*read)(const struct cts_device *cts_dev,
|
||||
u32 flash_addr, void *dst, size_t len);
|
||||
int (*read_to_sram)(const struct cts_device *cts_dev,
|
||||
u32 flash_addr, u32 sram_addr, size_t len);
|
||||
int (*program)(const struct cts_device *cts_dev,
|
||||
u32 flash_addr, const void *src, size_t len);
|
||||
int (*program_from_sram)(const struct cts_device *cts_dev,
|
||||
u32 flash_addr, u32 sram_addr, size_t len);
|
||||
int (*calc_sram_crc)(const struct cts_device *cts_dev,
|
||||
u32 sram_addr, size_t len, u32 *crc);
|
||||
int (*calc_flash_crc)(const 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 */
|
||||
354
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_sfctrlv2.c
Normal file
354
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_sfctrlv2.c
Normal file
|
|
@ -0,0 +1,354 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#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(const 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(const 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(20);
|
||||
} while (status && retries++ < 50);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int sfctrlv2_rdsr(const struct cts_device *cts_dev, u8 *status)
|
||||
{
|
||||
#define RDSR_XCHG_SRAM_ADDR (cts_dev->hwdata->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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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(const 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);
|
||||
}
|
||||
|
||||
int sfctrlv2_calc_sram_crc(const 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;
|
||||
}
|
||||
|
||||
int sfctrlv2_calc_flash_crc(const 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,
|
||||
};
|
||||
532
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_spi_flash.c
Normal file
532
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_spi_flash.c
Normal file
|
|
@ -0,0 +1,532 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#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"
|
||||
|
||||
/* 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 int probe_flash(struct cts_device *cts_dev)
|
||||
{
|
||||
/* for no-flash project */
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/** Make sure sector addr is sector aligned && < flash total size */
|
||||
static int erase_sector_retry(const 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 retries %d",
|
||||
sector_addr, ret, retries);
|
||||
continue;
|
||||
}
|
||||
} while (retries < retry);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Make sure sector addr is sector aligned && < flash total size */
|
||||
static inline int erase_sector(const 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(const 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 retries %d",
|
||||
block_addr, ret, retries);
|
||||
continue;
|
||||
}
|
||||
} while (retries < retry);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Make sure block addr is block aligned && < flash total size */
|
||||
static inline int erase_block(const 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);
|
||||
bool enabled = cts_is_device_enabled(cts_dev);
|
||||
|
||||
cts_info("Prepare for flash operation");
|
||||
|
||||
if (enabled) {
|
||||
ret = cts_stop_device(cts_dev);
|
||||
if (ret) {
|
||||
cts_err("Stop device failed %d", ret);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (!program_mode) {
|
||||
ret = cts_enter_program_mode(cts_dev);
|
||||
if (ret) {
|
||||
cts_err("Enter program mode failed %d", ret);
|
||||
goto err_start_device;
|
||||
}
|
||||
}
|
||||
|
||||
ret = cts_hw_reg_readb_retry(cts_dev, 0x30033, &diva, 5, 0);
|
||||
if (ret)
|
||||
cts_warn("Read DIVA failed %d", 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 */
|
||||
ret = cts_hw_reg_writeb_retry(cts_dev, 0x30033, 0x0C, 5, 0);
|
||||
if (ret) {
|
||||
cts_err("Write DIVA failed %d", ret);
|
||||
goto err_enter_normal_mode;
|
||||
}
|
||||
|
||||
/* Reset SFCTL */
|
||||
ret = cts_hw_reg_writeb_retry(cts_dev, 0x30008, 0xFB, 5, 0);
|
||||
if (ret) {
|
||||
cts_err("Reset sfctl failed %d", ret);
|
||||
goto err_enter_normal_mode;
|
||||
}
|
||||
|
||||
retries = 0;
|
||||
do {
|
||||
u8 state;
|
||||
|
||||
ret =
|
||||
cts_hw_reg_readb_relaxed(cts_dev, 0x3401B, &state);
|
||||
if (ret == 0 && (state & 0x40) != 0)
|
||||
goto init_flash;
|
||||
|
||||
mdelay(2);
|
||||
} while (++retries < 1000);
|
||||
|
||||
cts_warn("Wait SFCTRL ready failed %d", ret);
|
||||
}
|
||||
|
||||
init_flash:
|
||||
if (cts_dev->flash == NULL) {
|
||||
cts_info("Flash is not initialized, try to probe...");
|
||||
ret = probe_flash(cts_dev);
|
||||
if (ret != 0) {
|
||||
cts_dev->rtdata.has_flash = false;
|
||||
cts_warn("Probe flash failed %d", 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", r);
|
||||
}
|
||||
err_start_device:
|
||||
if (enabled) {
|
||||
int r = cts_start_device(cts_dev);
|
||||
|
||||
if (r)
|
||||
cts_err("Start device failed %d", r);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_post_flash_operation(struct cts_device *cts_dev)
|
||||
{
|
||||
cts_info("Post flash operation");
|
||||
|
||||
return cts_hw_reg_writeb_retry(cts_dev, 0x30033, 4, 5, 0);
|
||||
}
|
||||
|
||||
int cts_read_flash_retry(const 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",
|
||||
flash_addr, size, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dst += l;
|
||||
size -= l;
|
||||
flash_addr += l;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_read_flash_to_sram_retry(const struct cts_device *cts_dev,
|
||||
u32 flash_addr, u32 sram_addr, size_t size,
|
||||
int retry)
|
||||
{
|
||||
const struct cts_sfctrl *sfctrl;
|
||||
const struct cts_flash *flash;
|
||||
int ret, retries;
|
||||
|
||||
cts_info("Read from 0x%06x to 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->read_to_sram == NULL) {
|
||||
cts_err("Read to sram not supported");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
if (flash_addr > flash->total_size) {
|
||||
cts_err("Read to sram 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 to sram actually from 0x%06x size %zu", flash_addr,
|
||||
size);
|
||||
|
||||
retries = 0;
|
||||
do {
|
||||
retries++;
|
||||
ret =
|
||||
sfctrl->ops->read_to_sram(cts_dev, flash_addr, sram_addr,
|
||||
size);
|
||||
if (ret) {
|
||||
cts_err
|
||||
("Read from 0x%06x to sram 0x%06x size %zu failed %d retries %d",
|
||||
flash_addr, sram_addr, size, ret, retries);
|
||||
continue;
|
||||
}
|
||||
} while (retries < retry);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_read_flash_to_sram_check_crc_retry(const struct cts_device *cts_dev,
|
||||
u32 flash_addr, u32 sram_addr,
|
||||
size_t size, u32 crc, int retry)
|
||||
{
|
||||
const struct cts_sfctrl *sfctrl;
|
||||
const struct cts_flash *flash;
|
||||
int ret, retries;
|
||||
|
||||
cts_info("Read from 0x%06x to sram 0x%06x size %zu with crc check",
|
||||
flash_addr, sram_addr, size);
|
||||
|
||||
sfctrl = cts_dev->hwdata->sfctrl;
|
||||
flash = cts_dev->flash;
|
||||
|
||||
if (flash == NULL ||
|
||||
sfctrl == NULL ||
|
||||
sfctrl->ops == NULL ||
|
||||
sfctrl->ops->read_to_sram == NULL ||
|
||||
sfctrl->ops->calc_sram_crc == NULL) {
|
||||
cts_err("Read to sram check crc not supported");
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
if (flash_addr > flash->total_size) {
|
||||
cts_err("Read to sram 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 to sram actually from 0x%06x size %zu with crc check",
|
||||
flash_addr, size);
|
||||
|
||||
retries = 0;
|
||||
do {
|
||||
u32 crc_sram;
|
||||
|
||||
retries++;
|
||||
|
||||
ret =
|
||||
sfctrl->ops->read_to_sram(cts_dev, flash_addr, sram_addr,
|
||||
size);
|
||||
if (ret) {
|
||||
cts_err
|
||||
("Read from 0x%06x to sram 0x%06x size %zu failed %d retries %d",
|
||||
flash_addr, sram_addr, size, ret, retries);
|
||||
continue;
|
||||
}
|
||||
|
||||
ret =
|
||||
sfctrl->ops->calc_sram_crc(cts_dev, sram_addr, size,
|
||||
&crc_sram);
|
||||
if (ret) {
|
||||
cts_err
|
||||
("Get crc for read from 0x%06x to sram 0x%06x size %zu "
|
||||
"failed %d retries %d", flash_addr, sram_addr,
|
||||
size, ret, retries);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (crc == crc_sram)
|
||||
return 0;
|
||||
|
||||
cts_err
|
||||
("Check crc for read from 0x%06x to sram 0x%06x size %zu "
|
||||
"mismatch %x != %x, retries %d", flash_addr, sram_addr,
|
||||
size, crc, crc_sram, retries);
|
||||
ret = -EFAULT;
|
||||
} while (retries < retry);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int cts_program_flash(const 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",
|
||||
flash_addr, l, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
src += l;
|
||||
size -= l;
|
||||
flash_addr += l;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_program_flash_from_sram(const 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",
|
||||
flash_addr, sram_addr, l, ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
size -= l;
|
||||
flash_addr += l;
|
||||
sram_addr += l;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cts_erase_flash(const 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",
|
||||
addr, flash->sector_size, 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",
|
||||
addr, flash->block_size, 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",
|
||||
addr, flash->sector_size, ret);
|
||||
return ret;
|
||||
}
|
||||
addr += flash->sector_size;
|
||||
size -= flash->sector_size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,73 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#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(const struct cts_device *cts_dev,
|
||||
u32 flash_addr, void *dst, size_t size,
|
||||
int retry);
|
||||
static inline int cts_read_flash(const 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_read_flash_to_sram_retry(const struct cts_device *cts_dev,
|
||||
u32 flash_addr, u32 sram_addr,
|
||||
size_t size, int retry);
|
||||
static inline int cts_read_flash_to_sram(const struct cts_device *cts_dev,
|
||||
u32 flash_addr, u32 sram_addr,
|
||||
size_t size)
|
||||
{
|
||||
return cts_read_flash_to_sram_retry(cts_dev,
|
||||
flash_addr, sram_addr, size,
|
||||
CTS_FLASH_READ_DEFAULT_RETRY);
|
||||
}
|
||||
|
||||
extern int cts_read_flash_to_sram_check_crc_retry(const struct cts_device
|
||||
*cts_dev, u32 flash_addr,
|
||||
u32 sram_addr, size_t size,
|
||||
u32 crc, int retry);
|
||||
static inline int cts_read_flash_to_sram_check_crc(const struct cts_device
|
||||
*cts_dev, u32 flash_addr,
|
||||
u32 sram_addr, size_t size,
|
||||
u32 crc)
|
||||
{
|
||||
return cts_read_flash_to_sram_check_crc_retry(cts_dev,
|
||||
flash_addr, sram_addr,
|
||||
size, crc,
|
||||
CTS_FLASH_READ_DEFAULT_RETRY);
|
||||
}
|
||||
|
||||
extern int cts_erase_flash(const struct cts_device *cts_dev, u32 addr,
|
||||
size_t size);
|
||||
|
||||
extern int cts_program_flash(const struct cts_device *cts_dev,
|
||||
u32 flash_addr, const void *src, size_t size);
|
||||
extern int cts_program_flash_from_sram(const struct cts_device *cts_dev,
|
||||
u32 flash_addr, u32 sram_addr,
|
||||
size_t size);
|
||||
|
||||
#endif /* CTS_SPI_FLASH_H */
|
||||
2778
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_sysfs.c
Normal file
2778
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_sysfs.c
Normal file
File diff suppressed because it is too large
Load diff
25
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_sysfs.h
Normal file
25
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_sysfs.h
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef CTS_SYSFS_H
|
||||
#define CTS_SYSFS_H
|
||||
|
||||
#include "cts_config.h"
|
||||
|
||||
struct device;
|
||||
|
||||
extern u16 speed;
|
||||
|
||||
#ifdef CONFIG_CTS_SYSFS
|
||||
extern int cts_sysfs_add_device(struct device *dev);
|
||||
extern void cts_sysfs_remove_device(struct device *dev);
|
||||
#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 */
|
||||
1651
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tcs.c
Normal file
1651
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tcs.c
Normal file
File diff suppressed because it is too large
Load diff
228
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tcs.h
Normal file
228
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tcs.h
Normal file
|
|
@ -0,0 +1,228 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef _CTS_TCS_H_
|
||||
#define _CTS_TCS_H_
|
||||
|
||||
#include "cts_config.h"
|
||||
|
||||
#define TCS_RD_ADDR 0xF1
|
||||
#define TCS_WR_ADDR 0xF0
|
||||
|
||||
#define INT_DATA_MAX_SIZ 8192
|
||||
|
||||
#pragma pack(1)
|
||||
typedef struct {
|
||||
u8 addr;
|
||||
u16 cmd;
|
||||
u16 datlen;
|
||||
u16 crc16;
|
||||
} tcs_tx_head;
|
||||
|
||||
typedef struct {
|
||||
u8 ecode;
|
||||
u16 cmd;
|
||||
u16 crc16;
|
||||
} tcs_rx_tail;
|
||||
|
||||
typedef struct {
|
||||
u8 baseFlag;
|
||||
u8 classID;
|
||||
u8 cmdID;
|
||||
u8 isRead;
|
||||
u8 isWrite;
|
||||
u8 isData;
|
||||
} TcsCmdValue_t;
|
||||
#pragma pack(0)
|
||||
|
||||
int cts_tcs_get_fw_ver(const struct cts_device *cts_dev, u16 *fwver);
|
||||
int cts_tcs_get_lib_ver(const struct cts_device *cts_dev, u16 *libver);
|
||||
int cts_tcs_get_ddi_ver(const struct cts_device *cts_dev, u8 *ddiver);
|
||||
int cts_tcs_get_res_x(const struct cts_device *cts_dev, u16 *res_x);
|
||||
int cts_tcs_get_res_y(const struct cts_device *cts_dev, u16 *res_y);
|
||||
int cts_tcs_get_rows(const struct cts_device *cts_dev, u8 *rows);
|
||||
int cts_tcs_get_cols(const struct cts_device *cts_dev, u8 *cols);
|
||||
int cts_tcs_get_flip_x(const struct cts_device *cts_dev, bool *flip_x);
|
||||
int cts_tcs_get_flip_y(const struct cts_device *cts_dev, bool *flip_y);
|
||||
int cts_tcs_get_swap_axes(const struct cts_device *cts_dev, bool *swap_axes);
|
||||
|
||||
int cts_tcs_get_int_mode(const struct cts_device *cts_dev, u8 *int_mode);
|
||||
int cts_tcs_get_int_keep_time(const struct cts_device *cts_dev,
|
||||
u16 *int_keep_time);
|
||||
int cts_tcs_get_esd_method(const struct cts_device *cts_dev, u8 *esd_method);
|
||||
|
||||
int cts_tcs_get_touchinfo(const struct cts_device *cts_dev,
|
||||
struct cts_device_touch_info *touch_info);
|
||||
int cts_tcs_get_esd_protection(const struct cts_device *cts_dev,
|
||||
u8 *esd_protection);
|
||||
|
||||
int cts_tcs_get_data_ready_flag(const struct cts_device *cts_dev, u8 *ready);
|
||||
int cts_tcs_clr_data_ready_flag(const struct cts_device *cts_dev);
|
||||
int cts_tcs_enable_get_rawdata(const struct cts_device *cts_dev);
|
||||
int cts_tcs_is_enabled_get_rawdata(const struct cts_device *cts_dev,
|
||||
u8 *enabled);
|
||||
int cts_tcs_disable_get_rawdata(const struct cts_device *cts_dev);
|
||||
int cts_tcs_enable_get_cneg(const struct cts_device *cts_dev);
|
||||
int cts_tcs_disable_get_cneg(const struct cts_device *cts_dev);
|
||||
int cts_tcs_is_cneg_ready(const struct cts_device *cts_dev, u8 *ready);
|
||||
|
||||
int cts_tcs_quit_guesture_mode(const struct cts_device *cts_dev);
|
||||
|
||||
int cts_tcs_get_rawdata(const struct cts_device *cts_dev, u8 *buf);
|
||||
int cts_tcs_get_diffdata(const struct cts_device *cts_dev, u8 *buf);
|
||||
int cts_tcs_get_basedata(const struct cts_device *cts_dev, u8 *buf);
|
||||
int cts_tcs_get_cneg(const struct cts_device *cts_dev, u8 *buf, size_t size);
|
||||
|
||||
int cts_tcs_read_hw_reg(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *buf, size_t size);
|
||||
int cts_tcs_write_hw_reg(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *buf, size_t size);
|
||||
int cts_tcs_read_ddi_reg(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *regbuf, size_t size);
|
||||
int cts_tcs_write_ddi_reg(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *regbuf, size_t size);
|
||||
int cts_tcs_read_fw_reg(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *buf, size_t size);
|
||||
int cts_tcs_write_fw_reg(const struct cts_device *cts_dev, u32 addr,
|
||||
u8 *buf, size_t size);
|
||||
int cts_tcs_read_reg(const struct cts_device *cts_dev, uint16_t cmd,
|
||||
u8 *rbuf, size_t rlen);
|
||||
int cts_tcs_write_reg(const struct cts_device *cts_dev, uint16_t cmd,
|
||||
u8 *wbuf, size_t wlen);
|
||||
|
||||
int cts_tcs_get_fw_id(const struct cts_device *cts_dev, u16 *fwid);
|
||||
int cts_tcs_get_workmode(const struct cts_device *cts_dev, u8 *workmode);
|
||||
int cts_tcs_set_workmode(const struct cts_device *cts_dev, u8 workmode);
|
||||
int cts_tcs_set_openshort_mode(const struct cts_device *cts_dev, u8 mode);
|
||||
int cts_tcs_set_tx_vol(const struct cts_device *cts_dev, u8 txvol);
|
||||
|
||||
int cts_tcs_set_short_test_type(const struct cts_device *cts_dev,
|
||||
u8 short_type);
|
||||
int cts_tcs_set_openshort_enable(const struct cts_device *cts_dev, u8 enable);
|
||||
int cts_tcs_is_openshort_enabled(const struct cts_device *cts_dev,
|
||||
u8 *enabled);
|
||||
|
||||
int cts_tcs_set_esd_enable(const struct cts_device *cts_dev, u8 enable);
|
||||
int cts_tcs_set_cneg_enable(const struct cts_device *cts_dev, u8 enable);
|
||||
int cts_tcs_set_mnt_enable(const struct cts_device *cts_dev, u8 enable);
|
||||
int cts_tcs_is_display_on(const struct cts_device *cts_dev, u8 *display_on);
|
||||
int cts_tcs_set_display_on(const struct cts_device *cts_dev, u8 display_on);
|
||||
int cts_tcs_is_cneg_enabled(const struct cts_device *cts_dev, u8 *enabled);
|
||||
int cts_tcs_is_mnt_enabled(const struct cts_device *cts_dev, u8 *enabled);
|
||||
int cts_tcs_set_pwr_mode(const struct cts_device *cts_dev, u8 pwr_mode);
|
||||
|
||||
int cts_tcs_read_sram_normal_mode(const struct cts_device *cts_dev,
|
||||
u32 addr, void *dst, size_t len, int retry,
|
||||
int delay);
|
||||
|
||||
enum TcsCmdIndex {
|
||||
TP_STD_CMD_INFO_CHIP_FW_ID_RO,
|
||||
TP_STD_CMD_INFO_FW_VER_RO,
|
||||
TP_STD_CMD_INFO_TOUCH_XY_INFO_RO,
|
||||
|
||||
TP_STD_CMD_TP_DATA_OFFSET_AND_TYPE_CFG_RW,
|
||||
TP_STD_CMD_TP_DATA_READ_START_RO,
|
||||
TP_STD_CMD_TP_DATA_COORDINATES_RO,
|
||||
TP_STD_CMD_TP_DATA_RAW_RO,
|
||||
TP_STD_CMD_TP_DATA_DIFF_RO,
|
||||
TP_STD_CMD_TP_DATA_BASE_RO,
|
||||
TP_STD_CMD_TP_DATA_CNEG_RO,
|
||||
TP_STD_CMD_TP_DATA_WR_REG_RAM_SEQUENCE_WO,
|
||||
TP_STD_CMD_TP_DATA_WR_REG_RAM_BATCH_WO,
|
||||
TP_STD_CMD_TP_DATA_WR_DDI_REG_SEQUENCE_WO,
|
||||
TP_STD_CMD_GET_DATA_BY_POLLING_RO,
|
||||
|
||||
TP_STD_CMD_SYS_STS_READ_RO,
|
||||
TP_STD_CMD_SYS_STS_WORK_MODE_RW,
|
||||
TP_STD_CMD_SYS_STS_DAT_RDY_FLAG_RW,
|
||||
TP_STD_CMD_SYS_STS_PWR_STATE_RW,
|
||||
TP_STD_CMD_SYS_STS_DDI_CODE_VER_RO,
|
||||
TP_STD_CMD_SYS_STS_DAT_TRANS_IN_NORMAL_RW,
|
||||
TP_STD_CMD_SYS_STS_VSTIM_LVL_RW,
|
||||
TP_STD_CMD_SYS_STS_CNEG_RDY_FLAG_RW,
|
||||
TP_STD_CMD_SYS_STS_RESET_WO,
|
||||
TP_STD_CMD_SYS_STS_CNEG_RD_EN_RW,
|
||||
TP_STD_CMD_SYS_STS_INT_MODE_RW,
|
||||
TP_STD_CMD_SYS_STS_INT_KEEP_TIME_RW,
|
||||
TP_STD_CMD_SYS_STS_CURRENT_WORKMODE_RO,
|
||||
TP_STD_CMD_SYS_STS_DATA_CAPTURE_SUPPORT_RO,
|
||||
TP_STD_CMD_SYS_STS_DATA_CAPTURE_EN_RW,
|
||||
TP_STD_CMD_SYS_STS_DATA_CAPTURE_FUNC_MAP_RW,
|
||||
|
||||
TP_STD_CMD_MNT_EN_RW,
|
||||
TP_STD_CMD_MNT_FORCE_EXIT_MNT_WO,
|
||||
|
||||
TP_STD_CMD_DDI_ESD_EN_RW,
|
||||
TP_STD_CMD_DDI_ESD_OPTIONS_RW,
|
||||
|
||||
TP_STD_CMD_CNEG_EN_RW,
|
||||
|
||||
TP_STD_CMD_COORD_FLIP_X_EN_RW,
|
||||
TP_STD_CMD_COORD_FLIP_Y_EN_RW,
|
||||
TP_STD_CMD_COORD_SWAP_AXES_EN_RW,
|
||||
|
||||
TP_STD_CMD_OPENSHORT_EN_RW,
|
||||
TP_STD_CMD_OPENSHORT_MODE_SEL_RW,
|
||||
TP_STD_CMD_OPENSHORT_SHORT_SEL_RW,
|
||||
TP_STD_CMD_OPENSHORT_SHORT_DISP_ON_EN_RW,
|
||||
};
|
||||
|
||||
#ifdef _CTS_TCS_C_
|
||||
static TcsCmdValue_t TcsCmdValue[] = {
|
||||
/*---------------------------------------------------
|
||||
*baseFlage, classID, cmdID, isRead, isWrite, isData
|
||||
*---------------------------------------------------
|
||||
*/
|
||||
{ 0, 0, 3, 1, 0, 0 }, /* TP_STD_CMD_INFO_CHIP_FW_ID_RO */
|
||||
{ 0, 0, 5, 1, 0, 0 }, /* TP_STD_CMD_INFO_FW_VER_RO */
|
||||
{ 0, 0, 7, 1, 0, 0 }, /* TP_STD_CMD_INFO_TOUCH_XY_INFO_RO */
|
||||
|
||||
{ 0, 1, 1, 1, 1, 0 }, /* TP_STD_CMD_TP_DATA_OFFSET_AND_TYPE_CFG_RW */
|
||||
{ 0, 1, 2, 1, 0, 1 }, /* TP_STD_CMD_TP_DATA_READ_START_RO */
|
||||
{ 0, 1, 3, 1, 0, 1 }, /* TP_STD_CMD_TP_DATA_COORDINATES_RO */
|
||||
{ 0, 1, 4, 1, 0, 1 }, /* TP_STD_CMD_TP_DATA_RAW_RO */
|
||||
{ 0, 1, 5, 1, 0, 1 }, /* TP_STD_CMD_TP_DATA_DIFF_RO */
|
||||
{ 0, 1, 6, 1, 0, 1 }, /* TP_STD_CMD_TP_DATA_BASE_RO */
|
||||
{ 0, 1, 10, 1, 0, 1 }, /* TP_STD_CMD_TP_DATA_CNEG_RO */
|
||||
{ 0, 1, 20, 0, 1, 1 }, /* TP_STD_CMD_TP_DATA_WR_REG_RAM_SEQUENCE_WO */
|
||||
{ 0, 1, 21, 0, 1, 1 }, /* TP_STD_CMD_TP_DATA_WR_REG_RAM_BATCH_WO */
|
||||
{ 0, 1, 22, 0, 1, 1 }, /* TP_STD_CMD_TP_DATA_WR_DDI_REG_SEQUENCE_WO */
|
||||
{ 0, 1, 35, 1, 0, 0 }, /* TP_STD_CMD_GET_DATA_BY_POLLING_RO */
|
||||
|
||||
{ 0, 2, 0, 1, 0, 1 }, /* TP_STD_CMD_SYS_STS_READ_RO *//*CHECK!!*/
|
||||
{ 0, 2, 1, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_WORK_MODE_RW */
|
||||
{ 0, 2, 3, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_DAT_RDY_FLAG_RW */
|
||||
{ 0, 2, 4, 1, 1, 1 }, /* TP_STD_CMD_SYS_STS_PWR_STATE_RW */
|
||||
{ 0, 2, 6, 1, 0, 0 }, /* TP_STD_CMD_SYS_STS_DDI_CODE_VER_RO */
|
||||
{ 0, 2, 7, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_DAT_TRANS_IN_NORMAL_RW */
|
||||
{ 0, 2, 8, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_VSTIM_LVL_RW */
|
||||
{ 0, 2, 17, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_CNEG_RDY_FLAG_RW */
|
||||
{ 0, 2, 22, 0, 1, 0 }, /* TP_STD_CMD_SYS_STS_RESET_WO */
|
||||
{ 0, 2, 25, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_CNEG_RD_EN_RW */
|
||||
{ 0, 2, 35, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_INT_MODE_RW */
|
||||
{ 0, 2, 36, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_INT_KEEP_TIME_RW */
|
||||
{ 0, 2, 51, 1, 0, 0 }, /* TP_STD_CMD_SYS_STS_CURRENT_WORKMODE_RO */
|
||||
{ 0, 2, 63, 1, 0, 0 }, /* TP_STD_CMD_SYS_STS_DATA_CAPTURE_SUPPORT_RO */
|
||||
{ 0, 2, 64, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_DATA_CAPTURE_EN_RW */
|
||||
{ 0, 2, 65, 1, 1, 0 }, /* TP_STD_CMD_SYS_STS_DATA_CAPTURE_FUNC_MAP_RW */
|
||||
|
||||
{ 0, 4, 1, 1, 1, 0 }, /* TP_STD_CMD_MNT_EN_RW */
|
||||
{ 0, 4, 3, 0, 1, 0 }, /* TP_STD_CMD_MNT_FORCE_EXIT_MNT_WO */
|
||||
|
||||
{ 0, 5, 1, 1, 1, 0 }, /* TP_STD_CMD_DDI_ESD_EN_RW */
|
||||
{ 0, 5, 2, 1, 1, 0 }, /* TP_STD_CMD_DDI_ESD_OPTIONS_RW */
|
||||
|
||||
{ 0, 6, 1, 1, 1, 0 }, /* TP_STD_CMD_CNEG_EN_RW */
|
||||
|
||||
{ 0, 7, 2, 1, 1, 0 }, /* TP_STD_CMD_COORD_FLIP_X_EN_RW */
|
||||
{ 0, 7, 3, 1, 1, 0 }, /* TP_STD_CMD_COORD_FLIP_Y_EN_RW */
|
||||
{ 0, 7, 4, 1, 1, 0 }, /* TP_STD_CMD_COORD_SWAP_AXES_EN_RW */
|
||||
|
||||
{ 0, 11, 1, 1, 1, 0 }, /* TP_STD_CMD_OPENSHORT_EN_RW */
|
||||
{ 0, 11, 2, 1, 1, 0 }, /* TP_STD_CMD_OPENSHORT_MODE_SEL_RW */
|
||||
{ 0, 11, 3, 1, 1, 0 }, /* TP_STD_CMD_OPENSHORT_SHORT_SEL_RW */
|
||||
{ 0, 11, 4, 1, 1, 0 }, /* TP_STD_CMD_OPENSHORT_SHORT_DISP_ON_EN_RW */
|
||||
};
|
||||
#endif /* _CTS_TCS_C_ */
|
||||
|
||||
extern struct cts_dev_ops tcs_ops;
|
||||
|
||||
#endif /* _CTS_TCS_H_ */
|
||||
1350
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_test.c
Normal file
1350
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_test.c
Normal file
File diff suppressed because it is too large
Load diff
17
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_test.h
Normal file
17
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_test.h
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0 */
|
||||
#ifndef CTS_TEST_H
|
||||
#define CTS_TEST_H
|
||||
|
||||
struct cts_device;
|
||||
|
||||
extern int cts_short_test(struct cts_device *cts_dev, u16 threshold);
|
||||
extern int cts_open_test(struct cts_device *cts_dev, u16 threshold);
|
||||
extern int cts_reset_test(struct cts_device *cts_dev);
|
||||
extern int cts_compensate_cap_test(struct cts_device *cts_dev, u8 min_thres,
|
||||
u8 max_thres);
|
||||
extern int cts_rawdata_test(struct cts_device *cts_dev, u16 min_thres,
|
||||
u16 max_thres);
|
||||
extern int cts_noise_test(struct cts_device *cts_dev, u32 frames, u16 max);
|
||||
extern int cts_test_int_pin(struct cts_device *cts_dev);
|
||||
|
||||
#endif /* CTS_TEST_H */
|
||||
803
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tool.c
Normal file
803
drivers/input/touchscreen/chipone_tddi_fhd_mmi/cts_tool.c
Normal file
|
|
@ -0,0 +1,803 @@
|
|||
// SPDX-License-Identifier: GPL-2.0
|
||||
#define LOG_TAG "Tool"
|
||||
|
||||
#include "cts_config.h"
|
||||
#include "cts_platform.h"
|
||||
#include "cts_core.h"
|
||||
#include "cts_firmware.h"
|
||||
#include "cts_test.h"
|
||||
|
||||
#ifdef CONFIG_CTS_LEGACY_TOOL
|
||||
|
||||
#pragma pack(1)
|
||||
/** Tool command structure */
|
||||
struct cts_tool_cmd {
|
||||
u8 cmd;
|
||||
u8 flag;
|
||||
u8 circle;
|
||||
u8 times;
|
||||
u8 retry;
|
||||
u32 data_len;
|
||||
u8 addr_len;
|
||||
u8 addr[4];
|
||||
u8 tcs[2];
|
||||
u8 data[PAGE_SIZE];
|
||||
|
||||
};
|
||||
#pragma pack()
|
||||
|
||||
#define CTS_TOOL_CMD_HEADER_LENGTH (16)
|
||||
|
||||
enum cts_tool_cmd_code {
|
||||
CTS_TOOL_CMD_GET_PANEL_PARAM = 0,
|
||||
CTS_TOOL_CMD_GET_DOWNLOAD_STATUS = 2,
|
||||
CTS_TOOL_CMD_GET_RAW_DATA = 4,
|
||||
CTS_TOOL_CMD_GET_DIFF_DATA = 6,
|
||||
CTS_TOOL_CMD_READ_HOSTCOMM = 12,
|
||||
CTS_TOOL_CMD_READ_ADC_STATUS = 14,
|
||||
CTS_TOOL_CMD_READ_GESTURE_INFO = 16,
|
||||
CTS_TOOL_CMD_READ_HOSTCOMM_MULTIBYTE = 18,
|
||||
CTS_TOOL_CMD_READ_PROGRAM_MODE_MULTIBYTE = 20,
|
||||
CTS_TOOL_CMD_READ_ICTYPE = 22,
|
||||
CTS_TOOL_CMD_I2C_DIRECT_READ = 24,
|
||||
CTS_TOOL_CMD_GET_DRIVER_INFO = 26,
|
||||
CTS_TOOL_CMD_TCS_READ_HW_CMD = 28,
|
||||
CTS_TOOL_CMD_TCS_READ_DDI_CMD = 30,
|
||||
CTS_TOOL_CMD_TCS_READ_FW_CMD = 32,
|
||||
CTS_TOOL_CMD_GET_BASE_DATA = 34,
|
||||
|
||||
CTS_TOOL_CMD_UPDATE_PANEL_PARAM_IN_SRAM = 1,
|
||||
CTS_TOOL_CMD_DOWNLOAD_FIRMWARE_WITH_FILENAME = 3,
|
||||
CTS_TOOL_CMD_DOWNLOAD_FIRMWARE = 5,
|
||||
CTS_TOOL_CMD_WRITE_HOSTCOMM = 11,
|
||||
CTS_TOOL_CMD_WRITE_HOSTCOMM_MULTIBYTE = 15,
|
||||
CTS_TOOL_CMD_WRITE_PROGRAM_MODE_MULTIBYTE = 17,
|
||||
CTS_TOOL_CMD_I2C_DIRECT_WRITE = 19,
|
||||
CTS_TOOL_CMD_TCS_WRITE_HW_CMD = 21,
|
||||
CTS_TOOL_CMD_TCS_WRITE_DDI_CMD = 23,
|
||||
CTS_TOOL_CMD_TCS_WRITE_FW_CMD = 25,
|
||||
CTS_TOOL_CMD_TCS_ENABLE_GET_RAWDATA_CMD = 27,
|
||||
CTS_TOOL_CMD_TCS_DISABLE_GET_RAWDATA_CMD = 29,
|
||||
|
||||
};
|
||||
|
||||
struct cts_test_rawdata_ioctl_data {
|
||||
int frames;
|
||||
int min;
|
||||
int max;
|
||||
};
|
||||
|
||||
struct cts_test_noise_ioctl_data {
|
||||
int frames;
|
||||
int max;
|
||||
};
|
||||
|
||||
struct cts_test_open_ioctl_data {
|
||||
int min;
|
||||
int max;
|
||||
};
|
||||
|
||||
struct cts_test_short_ioctl_data {
|
||||
int min;
|
||||
int max;
|
||||
bool display_on;
|
||||
bool disable_gas;
|
||||
};
|
||||
|
||||
struct cts_test_comp_cap_ioctl_data {
|
||||
int min;
|
||||
int max;
|
||||
};
|
||||
|
||||
#define CTS_TOOL_IOCTL_GET_DRIVER_VERSION _IOR('C', 0x00, unsigned int)
|
||||
#define CTS_TOOL_IOCTL_GET_DEVICE_TYPE _IOR('C', 0x01, unsigned int)
|
||||
#define CTS_TOOL_IOCTL_GET_FW_VERSION _IOR('C', 0x02, unsigned short)
|
||||
|
||||
#define CTS_TOOL_IOCTL_TEST_RESET_PIN _IO('C', 0x11)
|
||||
#define CTS_TOOL_IOCTL_TEST_INT_PIN _IO('C', 0x12)
|
||||
#define CTS_TOOL_IOCTL_TEST_DEVICE_TYPE _IOW('C', 0x13, unsigned int)
|
||||
#define CTS_TOOL_IOCTL_TEST_FW_VERSION _IOW('C', 0x14, unsigned short)
|
||||
#define CTS_TOOL_IOCTL_TEST_RAWDATA \
|
||||
_IOW('C', 0x15, struct cts_test_rawdata_ioctl_data *)
|
||||
#define CTS_TOOL_IOCTL_TEST_NOISE \
|
||||
_IOW('C', 0x16, struct cts_test_noise_ioctl_data *)
|
||||
#define CTS_TOOL_IOCTL_TEST_OPEN \
|
||||
_IOW('C', 0x17, struct cts_test_open_ioctl_data *)
|
||||
#define CTS_TOOL_IOCTL_TEST_SHORT \
|
||||
_IOW('C', 0x18, struct cts_test_short_ioctl_data *)
|
||||
#define CTS_TOOL_IOCTL_TEST_COMP_CAP \
|
||||
_IOW('C', 0x19, struct cts_test_comp_cap_ioctl_data *)
|
||||
|
||||
#define CTS_DRIVER_VERSION_CODE ((CFG_CTS_DRIVER_MAJOR_VERSION << 16) | \
|
||||
(CFG_CTS_DRIVER_MINOR_VERSION << 8) | \
|
||||
(CFG_CTS_DRIVER_PATCH_VERSION << 0))
|
||||
|
||||
static struct cts_tool_cmd cts_tool_cmd;
|
||||
static char cts_tool_firmware_filepath[PATH_MAX];
|
||||
/* If CFG_CTS_MAX_I2C_XFER_SIZE < 58(PC tool length), this is neccessary */
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
/*static u32 cts_tool_direct_access_addr = 0;*/
|
||||
#endif /* CONFIG_CTS_I2C_HOST */
|
||||
|
||||
static int cts_tool_open(struct inode *inode, struct file *file)
|
||||
{
|
||||
file->private_data = PDE_DATA(inode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t cts_tool_read(struct file *file,
|
||||
char __user *buffer, size_t count, loff_t *ppos)
|
||||
{
|
||||
#define RAWDATA_BUFFER_SIZE(cts_dev) \
|
||||
(cts_dev->hwdata->num_row * cts_dev->hwdata->num_col * 2)
|
||||
struct chipone_ts_data *cts_data;
|
||||
struct cts_tool_cmd *cmd;
|
||||
struct cts_device *cts_dev;
|
||||
int ret = 0;
|
||||
|
||||
cts_data = (struct chipone_ts_data *)file->private_data;
|
||||
if (cts_data == NULL) {
|
||||
cts_err("Read with private_data = NULL");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
cmd = &cts_tool_cmd;
|
||||
cts_dev = &cts_data->cts_dev;
|
||||
cts_lock_device(cts_dev);
|
||||
|
||||
cts_info("read: flag:%d, addr:0x%06x, tcm:0x%04x, datalen:%d",
|
||||
cmd->cmd, get_unaligned_le32(cmd->addr),
|
||||
get_unaligned_le16(cmd->tcs), cmd->data_len);
|
||||
|
||||
switch (cmd->cmd) {
|
||||
case CTS_TOOL_CMD_TCS_READ_HW_CMD:
|
||||
cts_dev->ops->read_hw_reg(cts_dev,
|
||||
get_unaligned_le32(cmd->addr),
|
||||
cmd->data, cmd->data_len);
|
||||
break;
|
||||
case CTS_TOOL_CMD_TCS_READ_DDI_CMD:
|
||||
cts_dev->ops->read_ddi_reg(cts_dev,
|
||||
get_unaligned_le32(cmd->addr),
|
||||
cmd->data, cmd->data_len);
|
||||
break;
|
||||
case CTS_TOOL_CMD_TCS_READ_FW_CMD:
|
||||
cts_dev->ops->read_reg(cts_dev, get_unaligned_le16(cmd->tcs),
|
||||
cmd->data, cmd->data_len);
|
||||
break;
|
||||
case CTS_TOOL_CMD_GET_PANEL_PARAM:
|
||||
cts_info("Get panel param len: %u", cmd->data_len);
|
||||
ret = cts_get_panel_param(cts_dev, cmd->data, cmd->data_len);
|
||||
if (ret) {
|
||||
cts_err("Get panel param len: %u failed %d",
|
||||
cmd->data_len, ret);
|
||||
}
|
||||
break;
|
||||
|
||||
case CTS_TOOL_CMD_GET_DOWNLOAD_STATUS:
|
||||
cmd->data[0] = 100;
|
||||
cts_info("Get update status = %hhu", cmd->data[0]);
|
||||
break;
|
||||
|
||||
case CTS_TOOL_CMD_GET_RAW_DATA:
|
||||
case CTS_TOOL_CMD_GET_DIFF_DATA:
|
||||
case CTS_TOOL_CMD_GET_BASE_DATA:
|
||||
cts_info("Get %s data row: %u col: %u len: %u",
|
||||
cmd->cmd == CTS_TOOL_CMD_GET_RAW_DATA ? "raw" : "diff",
|
||||
cmd->addr[1], cmd->addr[0], cmd->data_len);
|
||||
|
||||
if (cmd->cmd == CTS_TOOL_CMD_GET_RAW_DATA) {
|
||||
// ret = cts_get_rawdata(cts_dev, cmd->data);
|
||||
ret =
|
||||
cts_dev->ops->top_get_rawdata(cts_dev,
|
||||
(u8 *) cmd->data,
|
||||
RAWDATA_BUFFER_SIZE
|
||||
(cts_dev));
|
||||
} else if (cmd->cmd == CTS_TOOL_CMD_GET_DIFF_DATA) {
|
||||
// ret = cts_get_diffdata(cts_dev, cmd->data);
|
||||
ret =
|
||||
cts_dev->ops->top_get_manual_diff(cts_dev,
|
||||
(u8 *) cmd->data,
|
||||
RAWDATA_BUFFER_SIZE
|
||||
(cts_dev));
|
||||
} else if (cmd->cmd == CTS_TOOL_CMD_GET_BASE_DATA) {
|
||||
// ret = cts_get_basedata(cts_dev, cmd->data);
|
||||
ret =
|
||||
cts_dev->ops->top_get_basedata(cts_dev,
|
||||
(u8 *) cmd->data,
|
||||
RAWDATA_BUFFER_SIZE
|
||||
(cts_dev));
|
||||
}
|
||||
if (ret) {
|
||||
cts_err("Get %s data failed %d",
|
||||
cmd->cmd == CTS_TOOL_CMD_GET_RAW_DATA ? "raw" :
|
||||
cmd->cmd ==
|
||||
CTS_TOOL_CMD_GET_DIFF_DATA ? "diff" : "base",
|
||||
ret);
|
||||
}
|
||||
break;
|
||||
|
||||
case CTS_TOOL_CMD_READ_HOSTCOMM:
|
||||
ret = cts_fw_reg_readb(cts_dev, get_unaligned_le16(cmd->addr),
|
||||
cmd->data);
|
||||
if (ret) {
|
||||
cts_err("Read firmware reg addr 0x%04x failed %d",
|
||||
get_unaligned_le16(cmd->addr), ret);
|
||||
} else {
|
||||
cts_dbg("Read firmware reg addr 0x%04x, val=0x%02x",
|
||||
get_unaligned_le16(cmd->addr), cmd->data[0]);
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef CFG_CTS_GESTURE
|
||||
case CTS_TOOL_CMD_READ_GESTURE_INFO:
|
||||
ret = cts_get_gesture_info(cts_dev, cmd->data, true);
|
||||
if (ret)
|
||||
cts_err("Get gesture info failed %d", ret);
|
||||
break;
|
||||
#endif /* CFG_CTS_GESTURE */
|
||||
|
||||
case CTS_TOOL_CMD_READ_HOSTCOMM_MULTIBYTE:
|
||||
cmd->data_len = min((size_t)cmd->data_len, sizeof(cmd->data));
|
||||
ret = cts_fw_reg_readsb(cts_dev, get_unaligned_le16(cmd->addr),
|
||||
cmd->data, cmd->data_len);
|
||||
if (ret) {
|
||||
cts_err
|
||||
("Read firmware reg addr 0x%04x len %u failed %d",
|
||||
get_unaligned_le16(cmd->addr), cmd->data_len, ret);
|
||||
} else {
|
||||
cts_dbg("Read firmware reg addr 0x%04x len %u",
|
||||
get_unaligned_le16(cmd->addr), cmd->data_len);
|
||||
}
|
||||
break;
|
||||
|
||||
case CTS_TOOL_CMD_READ_PROGRAM_MODE_MULTIBYTE:
|
||||
cts_dbg("Read under program mode addr 0x%06x len %u",
|
||||
(cmd->flag << 16) | get_unaligned_le16(cmd->addr),
|
||||
cmd->data_len);
|
||||
ret = cts_enter_program_mode(cts_dev);
|
||||
if (ret) {
|
||||
cts_err("Enter program mode failed %d", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = cts_sram_readsb(&cts_data->cts_dev,
|
||||
get_unaligned_le16(cmd->addr), cmd->data,
|
||||
cmd->data_len);
|
||||
if (ret) {
|
||||
cts_err("Read under program mode I2C xfer failed %d",
|
||||
ret);
|
||||
}
|
||||
|
||||
ret = cts_enter_normal_mode(cts_dev);
|
||||
if (ret) {
|
||||
cts_err("Enter normal mode failed %d", ret);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CTS_TOOL_CMD_READ_ICTYPE:
|
||||
cts_info("Get IC type");
|
||||
if (cts_dev->hwdata) {
|
||||
switch (cts_dev->hwdata->hwid) {
|
||||
case CTS_DEV_HWID_ICNL9911:
|
||||
cmd->data[0] = 0x91;
|
||||
break;
|
||||
case CTS_DEV_HWID_ICNL9911S:
|
||||
cmd->data[0] = 0x91;
|
||||
break;
|
||||
case CTS_DEV_HWID_ICNL9911C:
|
||||
cmd->data[0] = 0x91;
|
||||
break;
|
||||
default:
|
||||
cmd->data[0] = 0x00;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
cmd->data[0] = 0x10;
|
||||
}
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
case CTS_TOOL_CMD_I2C_DIRECT_READ:
|
||||
{
|
||||
u32 addr_width;
|
||||
char *wr_buff = NULL;
|
||||
u8 addr_buff[4];
|
||||
size_t left_size, max_xfer_size;
|
||||
u8 *data;
|
||||
|
||||
if (cmd->addr[0] != CTS_DEV_PROGRAM_MODE_I2CADDR) {
|
||||
cmd->addr[0] = CTS_DEV_NORMAL_MODE_I2CADDR;
|
||||
addr_width = 2;
|
||||
} else {
|
||||
addr_width =
|
||||
cts_dev->hwdata->program_addr_width;
|
||||
}
|
||||
|
||||
cts_dbg
|
||||
("Direct read from i2c_addr 0x%02x addr 0x%06x size %u",
|
||||
cmd->addr[0], cts_tool_direct_access_addr,
|
||||
cmd->data_len);
|
||||
|
||||
left_size = cmd->data_len;
|
||||
max_xfer_size =
|
||||
cts_plat_get_max_i2c_xfer_size(cts_dev->pdata);
|
||||
data = cmd->data;
|
||||
while (left_size) {
|
||||
size_t xfer_size =
|
||||
min(left_size, max_xfer_size);
|
||||
ret =
|
||||
cts_plat_i2c_read(cts_data->pdata,
|
||||
cmd->addr[0], wr_buff,
|
||||
addr_width, data,
|
||||
xfer_size, 1, 0);
|
||||
if (ret) {
|
||||
cts_err
|
||||
("Direct read i2c_addr 0x%02x addr 0x%06x "
|
||||
"len %zu failed %d", cmd->addr[0],
|
||||
cts_tool_direct_access_addr,
|
||||
xfer_size, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
left_size -= xfer_size;
|
||||
if (left_size) {
|
||||
data += xfer_size;
|
||||
cts_tool_direct_access_addr +=
|
||||
xfer_size;
|
||||
if (addr_width == 2) {
|
||||
put_unaligned_be16
|
||||
(cts_tool_direct_access_addr,
|
||||
addr_buff);
|
||||
} else if (addr_width == 3) {
|
||||
put_unaligned_be24
|
||||
(cts_tool_direct_access_addr,
|
||||
addr_buff);
|
||||
}
|
||||
wr_buff = addr_buff;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case CTS_TOOL_CMD_GET_DRIVER_INFO:
|
||||
break;
|
||||
|
||||
default:
|
||||
cts_warn("Read unknown command %u", cmd->cmd);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
cts_unlock_device(cts_dev);
|
||||
|
||||
if (ret == 0) {
|
||||
if (cmd->cmd == CTS_TOOL_CMD_I2C_DIRECT_READ) {
|
||||
ret = copy_to_user(buffer + CTS_TOOL_CMD_HEADER_LENGTH,
|
||||
cmd->data, cmd->data_len);
|
||||
} else {
|
||||
ret = copy_to_user(buffer, cmd->data, cmd->data_len);
|
||||
}
|
||||
if (ret) {
|
||||
cts_err("Copy data to user buffer failed %d", ret);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return cmd->data_len;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static ssize_t cts_tool_write(struct file *file,
|
||||
const char __user *buffer, size_t count,
|
||||
loff_t *ppos)
|
||||
{
|
||||
struct chipone_ts_data *cts_data;
|
||||
struct cts_device *cts_dev;
|
||||
struct cts_tool_cmd *cmd;
|
||||
int ret = 0;
|
||||
|
||||
if (count < CTS_TOOL_CMD_HEADER_LENGTH || count > PAGE_SIZE) {
|
||||
cts_err("Write len %zu invalid", count);
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
cts_data = (struct chipone_ts_data *)file->private_data;
|
||||
if (cts_data == NULL) {
|
||||
cts_err("Write with private_data = NULL");
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
cmd = &cts_tool_cmd;
|
||||
ret = copy_from_user(cmd, buffer, CTS_TOOL_CMD_HEADER_LENGTH);
|
||||
cts_info
|
||||
("write: flag:%d, addr:0x%06x, tcmd:0x%04x data:0x%02x, datalen:%d",
|
||||
cmd->cmd, get_unaligned_le32(cmd->addr),
|
||||
get_unaligned_le16(cmd->tcs), cmd->data[0], cmd->data_len);
|
||||
|
||||
if (ret) {
|
||||
cts_err("Copy command header from user buffer failed %d", ret);
|
||||
return -EIO;
|
||||
} else
|
||||
ret = CTS_TOOL_CMD_HEADER_LENGTH;
|
||||
|
||||
if (cmd->data_len > PAGE_SIZE) {
|
||||
cts_err("Write with invalid count %d", cmd->data_len);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
if (cmd->cmd & BIT(0)) {
|
||||
if (cmd->data_len) {
|
||||
ret =
|
||||
copy_from_user(cmd->data,
|
||||
buffer + CTS_TOOL_CMD_HEADER_LENGTH,
|
||||
cmd->data_len);
|
||||
if (ret) {
|
||||
cts_err
|
||||
("Copy command payload from user buffer len %u failed %d",
|
||||
cmd->data_len, ret);
|
||||
return -EIO;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Prepare for read command */
|
||||
cts_dbg("Write read command(%d) header, prepare read size: %d",
|
||||
cmd->cmd, cmd->data_len);
|
||||
return CTS_TOOL_CMD_HEADER_LENGTH + cmd->data_len;
|
||||
}
|
||||
|
||||
cts_dev = &cts_data->cts_dev;
|
||||
cts_lock_device(cts_dev);
|
||||
|
||||
switch (cmd->cmd) {
|
||||
case CTS_TOOL_CMD_TCS_WRITE_HW_CMD:
|
||||
cts_dev->ops->write_hw_reg(cts_dev,
|
||||
get_unaligned_le32(cmd->addr),
|
||||
cmd->data, cmd->data_len);
|
||||
break;
|
||||
case CTS_TOOL_CMD_TCS_WRITE_DDI_CMD:
|
||||
cts_dev->ops->write_ddi_reg(cts_dev,
|
||||
get_unaligned_le32(cmd->addr),
|
||||
cmd->data, cmd->data_len);
|
||||
break;
|
||||
case CTS_TOOL_CMD_TCS_WRITE_FW_CMD:
|
||||
cts_dev->ops->write_reg(cts_dev, get_unaligned_le16(cmd->tcs),
|
||||
cmd->data, cmd->data_len);
|
||||
break;
|
||||
case CTS_TOOL_CMD_TCS_ENABLE_GET_RAWDATA_CMD:
|
||||
cts_info("Enable touch data");
|
||||
ret = cts_dev->ops->enable_get_rawdata(cts_dev);
|
||||
if (ret)
|
||||
cts_err("Enable get touch data failed");
|
||||
break;
|
||||
case CTS_TOOL_CMD_TCS_DISABLE_GET_RAWDATA_CMD:
|
||||
cts_info("Disable touch data");
|
||||
ret = cts_dev->ops->disable_get_rawdata(cts_dev);
|
||||
if (ret)
|
||||
cts_err("Disable get touch data failed");
|
||||
break;
|
||||
case CTS_TOOL_CMD_UPDATE_PANEL_PARAM_IN_SRAM:
|
||||
cts_info("Write panel param len %u data\n", cmd->data_len);
|
||||
ret = cts_fw_reg_writesb(cts_dev, CTS_DEVICE_FW_REG_PANEL_PARAM,
|
||||
cmd->data, cmd->data_len);
|
||||
if (ret) {
|
||||
cts_err("Write panel param failed %d", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = cts_send_command(cts_dev, CTS_CMD_RESET);
|
||||
|
||||
ret = cts_set_work_mode(cts_dev, 1);
|
||||
|
||||
mdelay(100);
|
||||
|
||||
ret = cts_set_work_mode(cts_dev, 0);
|
||||
|
||||
mdelay(100);
|
||||
|
||||
break;
|
||||
|
||||
case CTS_TOOL_CMD_DOWNLOAD_FIRMWARE_WITH_FILENAME:
|
||||
cts_info("Write firmware path: '%.*s'",
|
||||
cmd->data_len, cmd->data);
|
||||
|
||||
memcpy(cts_tool_firmware_filepath, cmd->data, cmd->data_len);
|
||||
cts_tool_firmware_filepath[cmd->data_len] = '\0';
|
||||
break;
|
||||
|
||||
case CTS_TOOL_CMD_DOWNLOAD_FIRMWARE:
|
||||
cts_info("Start download firmware path: '%s'",
|
||||
cts_tool_firmware_filepath);
|
||||
|
||||
ret = cts_stop_device(cts_dev);
|
||||
if (ret) {
|
||||
cts_err("Stop device failed %d", ret);
|
||||
break;
|
||||
}
|
||||
/**
|
||||
*TODO: Use async mode such as thread, otherwise,
|
||||
*host can not get update status.
|
||||
*/
|
||||
ret = cts_update_firmware_from_file(cts_dev,
|
||||
cts_tool_firmware_filepath,
|
||||
true);
|
||||
if (ret)
|
||||
cts_err("Updata firmware failed %d", ret);
|
||||
|
||||
ret = cts_start_device(cts_dev);
|
||||
if (ret) {
|
||||
cts_err("Start device failed %d", ret);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case CTS_TOOL_CMD_WRITE_HOSTCOMM:
|
||||
cts_dbg("Write firmware reg addr: 0x%04x val=0x%02x",
|
||||
get_unaligned_le16(cmd->addr), cmd->data[0]);
|
||||
|
||||
ret = cts_fw_reg_writeb(cts_dev, get_unaligned_le16(cmd->addr),
|
||||
cmd->data[0]);
|
||||
if (ret) {
|
||||
cts_err
|
||||
("Write firmware reg addr: 0x%04x val=0x%02x failed %d",
|
||||
get_unaligned_le16(cmd->addr), cmd->data[0], ret);
|
||||
}
|
||||
break;
|
||||
|
||||
case CTS_TOOL_CMD_WRITE_HOSTCOMM_MULTIBYTE:
|
||||
cts_dbg("Write firmare reg addr: 0x%04x len %u",
|
||||
get_unaligned_le16(cmd->addr), cmd->data_len);
|
||||
ret = cts_fw_reg_writesb(cts_dev, get_unaligned_le16(cmd->addr),
|
||||
cmd->data, cmd->data_len);
|
||||
if (ret) {
|
||||
cts_err
|
||||
("Write firmare reg addr: 0x%04x len %u failed %d",
|
||||
get_unaligned_le16(cmd->addr), cmd->data_len, ret);
|
||||
}
|
||||
break;
|
||||
|
||||
case CTS_TOOL_CMD_WRITE_PROGRAM_MODE_MULTIBYTE:
|
||||
cts_dbg("Write to addr 0x%06x size %u under program mode",
|
||||
(cmd->flag << 16) | (cmd->addr[1] << 8) | cmd->addr[0],
|
||||
cmd->data_len);
|
||||
ret = cts_enter_program_mode(cts_dev);
|
||||
if (ret) {
|
||||
cts_err("Enter program mode failed %d", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
ret = cts_sram_writesb(cts_dev,
|
||||
(cmd->flag << 16) | (cmd->addr[1] << 8) |
|
||||
cmd->addr[0], cmd->data, cmd->data_len);
|
||||
if (ret)
|
||||
cts_err("Write program mode multibyte failed %d", ret);
|
||||
|
||||
ret = cts_enter_normal_mode(cts_dev);
|
||||
if (ret) {
|
||||
cts_err("Enter normal mode failed %d", ret);
|
||||
break;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
#ifdef CONFIG_CTS_I2C_HOST
|
||||
case CTS_TOOL_CMD_I2C_DIRECT_WRITE:
|
||||
{
|
||||
u32 addr_width;
|
||||
size_t left_payload_size; /* Payload exclude address field */
|
||||
size_t max_xfer_size;
|
||||
char *payload;
|
||||
|
||||
if (cmd->addr[0] != CTS_DEV_PROGRAM_MODE_I2CADDR) {
|
||||
cmd->addr[0] = CTS_DEV_NORMAL_MODE_I2CADDR;
|
||||
addr_width = 2;
|
||||
cts_tool_direct_access_addr =
|
||||
get_unaligned_be16(cmd->data);
|
||||
} else {
|
||||
addr_width =
|
||||
cts_dev->hwdata->program_addr_width;
|
||||
cts_tool_direct_access_addr =
|
||||
get_unaligned_be24(cmd->data);
|
||||
}
|
||||
|
||||
if (cmd->data_len < addr_width) {
|
||||
cts_err
|
||||
("Direct write too short %d < address width %d",
|
||||
cmd->data_len, addr_width);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
cts_dbg
|
||||
("Direct write to i2c_addr 0x%02x addr 0x%06x size %u",
|
||||
cmd->addr[0], cts_tool_direct_access_addr,
|
||||
cmd->data_len);
|
||||
|
||||
left_payload_size = cmd->data_len - addr_width;
|
||||
max_xfer_size =
|
||||
cts_plat_get_max_i2c_xfer_size(cts_dev->pdata);
|
||||
payload = cmd->data + addr_width;
|
||||
do {
|
||||
size_t xfer_payload_size =
|
||||
min(left_payload_size,
|
||||
max_xfer_size - addr_width);
|
||||
size_t xfer_len =
|
||||
xfer_payload_size + addr_width;
|
||||
|
||||
ret = cts_plat_i2c_write(cts_data->pdata,
|
||||
cmd->addr[0],
|
||||
payload - addr_width,
|
||||
xfer_len, 1, 0);
|
||||
if (ret) {
|
||||
cts_err
|
||||
("Direct write i2c_addr 0x%02x addr 0x%06x len %zu failed %d",
|
||||
cmd->addr[0],
|
||||
cts_tool_direct_access_addr,
|
||||
xfer_len, ret);
|
||||
break;
|
||||
}
|
||||
|
||||
left_payload_size -= xfer_payload_size;
|
||||
if (left_payload_size) {
|
||||
payload += xfer_payload_size;
|
||||
cts_tool_direct_access_addr +=
|
||||
xfer_payload_size;
|
||||
if (addr_width == 2) {
|
||||
put_unaligned_be16
|
||||
(cts_tool_direct_access_addr,
|
||||
payload - addr_width);
|
||||
} else if (addr_width == 3) {
|
||||
put_unaligned_be24
|
||||
(cts_tool_direct_access_addr,
|
||||
payload - addr_width);
|
||||
}
|
||||
}
|
||||
} while (left_payload_size);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
cts_warn("Write unknown command %u", cmd->cmd);
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
cts_unlock_device(cts_dev);
|
||||
|
||||
return ret ? 0 : cmd->data_len + CTS_TOOL_CMD_HEADER_LENGTH;
|
||||
}
|
||||
|
||||
static long cts_tool_ioctl(struct file *file, unsigned int cmd,
|
||||
unsigned long arg)
|
||||
{
|
||||
struct chipone_ts_data *cts_data;
|
||||
struct cts_device *cts_dev;
|
||||
|
||||
cts_info("ioctl, cmd=0x%04x, arg=0x%02lx", cmd, arg);
|
||||
|
||||
cts_data = file->private_data;
|
||||
if (cts_data == NULL) {
|
||||
cts_err("IOCTL with private data = NULL");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
cts_dev = &cts_data->cts_dev;
|
||||
|
||||
switch (cmd) {
|
||||
case CTS_TOOL_IOCTL_GET_DRIVER_VERSION:
|
||||
return put_user(CTS_DRIVER_VERSION_CODE,
|
||||
(unsigned int __user *)arg);
|
||||
case CTS_TOOL_IOCTL_GET_DEVICE_TYPE:
|
||||
return put_user(cts_dev->hwdata->hwid,
|
||||
(unsigned int __user *)arg);
|
||||
case CTS_TOOL_IOCTL_GET_FW_VERSION:
|
||||
return put_user(cts_dev->fwdata.version,
|
||||
(unsigned short __user *)arg);
|
||||
|
||||
case CTS_TOOL_IOCTL_TEST_RESET_PIN:
|
||||
return cts_reset_test(cts_dev);
|
||||
case CTS_TOOL_IOCTL_TEST_INT_PIN:
|
||||
return cts_test_int_pin(cts_dev);
|
||||
case CTS_TOOL_IOCTL_TEST_DEVICE_TYPE:
|
||||
if (cts_dev->hwdata->hwid == (u32) arg)
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
case CTS_TOOL_IOCTL_TEST_FW_VERSION:
|
||||
if (cts_dev->fwdata.version == (u16) arg)
|
||||
return 0;
|
||||
return -EINVAL;
|
||||
case CTS_TOOL_IOCTL_TEST_RAWDATA:{
|
||||
struct cts_test_rawdata_ioctl_data param;
|
||||
|
||||
if (copy_from_user(¶m,
|
||||
(struct cts_test_rawdata_ioctl_data
|
||||
__user *)arg, sizeof(param)))
|
||||
return -EFAULT;
|
||||
|
||||
return cts_rawdata_test(cts_dev, param.min, param.max);
|
||||
}
|
||||
case CTS_TOOL_IOCTL_TEST_NOISE:{
|
||||
struct cts_test_noise_ioctl_data param;
|
||||
|
||||
if (copy_from_user(¶m,
|
||||
(struct
|
||||
cts_test_noise_ioctl_data__user *)
|
||||
arg, sizeof(param)))
|
||||
return -EFAULT;
|
||||
|
||||
return cts_noise_test(cts_dev, param.frames, param.max);
|
||||
}
|
||||
case CTS_TOOL_IOCTL_TEST_OPEN:{
|
||||
struct cts_test_open_ioctl_data param;
|
||||
|
||||
if (copy_from_user(¶m,
|
||||
(struct cts_test_open_ioctl_data
|
||||
__user *)arg, sizeof(param)))
|
||||
return -EFAULT;
|
||||
|
||||
return cts_open_test(cts_dev, param.max);
|
||||
}
|
||||
case CTS_TOOL_IOCTL_TEST_SHORT:{
|
||||
struct cts_test_short_ioctl_data param;
|
||||
|
||||
if (copy_from_user
|
||||
(¶m,
|
||||
(struct cts_test_short_ioctl_data __user *)arg,
|
||||
sizeof(param)))
|
||||
return -EFAULT;
|
||||
|
||||
return cts_short_test(cts_dev, param.max);
|
||||
}
|
||||
case CTS_TOOL_IOCTL_TEST_COMP_CAP:{
|
||||
struct cts_test_comp_cap_ioctl_data param;
|
||||
|
||||
if (copy_from_user
|
||||
(¶m,
|
||||
(struct cts_test_comp_cap_ioctl_data __user *)arg,
|
||||
sizeof(param)))
|
||||
return -EFAULT;
|
||||
|
||||
return cts_compensate_cap_test(cts_dev, param.min,
|
||||
param.max);
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return -ENOTSUPP;
|
||||
}
|
||||
|
||||
static struct file_operations cts_tool_fops = {
|
||||
.owner = THIS_MODULE,
|
||||
.llseek = no_llseek,
|
||||
.open = cts_tool_open,
|
||||
.read = cts_tool_read,
|
||||
.write = cts_tool_write,
|
||||
.unlocked_ioctl = cts_tool_ioctl,
|
||||
};
|
||||
|
||||
int cts_tool_init(struct chipone_ts_data *cts_data)
|
||||
{
|
||||
cts_info("Init");
|
||||
|
||||
cts_data->procfs_entry = proc_create_data(CFG_CTS_TOOL_PROC_FILENAME,
|
||||
0600, NULL, &cts_tool_fops,
|
||||
cts_data);
|
||||
if (cts_data->procfs_entry == NULL) {
|
||||
cts_err("Create proc entry failed");
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void cts_tool_deinit(struct chipone_ts_data *data)
|
||||
{
|
||||
cts_info("Deinit");
|
||||
|
||||
if (data->procfs_entry)
|
||||
remove_proc_entry(CFG_CTS_TOOL_PROC_FILENAME, NULL);
|
||||
}
|
||||
#endif /* CONFIG_CTS_LEGACY_TOOL */
|
||||
Loading…
Reference in a new issue