guam: input update touch himax driver

base on himax vendor, update the driver
and add usb detect notify
NO_PROP_NEEDED: only for guam

Change-Id: I105e27a5bc548df7a4fcc18c64687553bec31eba
Signed-off-by: dengwei1 <dengwei1@motorola.com>
Reviewed-on: https://gerrit.mot.com/1551148
SME-Granted: SME Approvals Granted
SLTApproved: Slta Waiver
Tested-by: Jira Key
Reviewed-by: Xiangpo Zhao <zhaoxp3@motorola.com>
Submit-Approved: Jira Key
This commit is contained in:
dengwei1 2020-05-09 14:11:52 +08:00 • committed by Wei Deng
commit 171fc53147
24 changed files with 19547 additions and 19123 deletions

View file

@ -7,8 +7,23 @@ else
HIMAX_MMI_MODULE_PATH := $(KERNEL_MODULES_OUT)
endif
ifeq ($(HIMAX_V3_MMI_HX83102),true)
KERNEL_CFLAGS += CONFIG_INPUT_HIMAX_V3_MMI_IC_NAME=hx83102
ifeq ($(HIMAX_V2_MMI_0FLASH),true)
KERNEL_CFLAGS += CONFIG_INPUT_TOUCHSCREEN_HIMAX_V2_MMI_0FLASH=y
endif
ifneq ($(BOARD_USES_TOUCH_PALM),)
KERNEL_CFLAGS += CONFIG_INPUT_TOUCHSCREEN_HIMAX_V2_MMI_ENABLE_PALM=y
endif
ifneq ($(BOARD_USES_DOUBLE_TAP),)
KERNEL_CFLAGS += CONFIG_INPUT_HIMAX_V2_MMI_ENABLE_DOUBLE_TAP=y
endif
ifneq ($(BOARD_USES_HIMAX_MULTI_BIN),)
KERNEL_CFLAGS += CONFIG_INPUT_HIMAX_V2_MMI_ENABLE_MULTI_BIN=y
endif
ifeq ($(HIMAX_V2_MMI_HX83102D),true)
KERNEL_CFLAGS += CONFIG_INPUT_HIMAX_V2_MMI_IC_NAME_D=hx83102d
endif
include $(CLEAR_VARS)

View file

@ -2,23 +2,46 @@
EXTRA_CFLAGS += -Wall
EXTRA_CFLAGS += -I$(TOP)/motorola/kernel/modules/include \
-I$(TOP)/motorola/kernel/modules/drivers/input/touchscreen/himax_v3_mmi
EXTRA_CFLAGS += -DCONFIG_TOUCHSCREEN_HIMAX_CHIPSET \
-DCONFIG_TOUCHSCREEN_HIMAX_COMMON
EXTRA_CFLAGS += -DCONFIG_TOUCHSCREEN_HIMAX_DEBUG \
-DCONFIG_TOUCHSCREEN_HIMAX_INSPECT
EXTRA_CFLAGS += -DCONFIG_TOUCHSCREEN_HIMAX_INCELL
EXTRA_CFLAGS += -DCONFIG_HMX_DB
ifneq ($(filter hx83102,$(CONFIG_INPUT_HIMAX_V3_MMI_IC_NAME)),)
ifneq ($(filter hx83112,$(CONFIG_INPUT_HIMAX_V2_MMI_IC_NAME)),)
EXTRA_CFLAGS += -D__HIMAX_HX83112_MOD__
endif
ifneq ($(filter hx83102,$(CONFIG_INPUT_HIMAX_V2_MMI_IC_NAME)),)
EXTRA_CFLAGS += -D__HIMAX_HX83102_MOD__
endif
ifneq ($(filter hx83102d,$(CONFIG_INPUT_HIMAX_V2_MMI_IC_NAME_D)),)
EXTRA_CFLAGS += -D__HIMAX_HX83102D_MOD__
EXTRA_CFLAGS += -DHX_CODE_OVERLAY
endif
ifneq ($(filter m y,$(CONFIG_INPUT_TOUCHSCREEN_HIMAX_V2_MMI_ENABLE_PALM)),)
EXTRA_CFLAGS += -DHIMAX_PALM_SENSOR_EN
endif
ifneq ($(filter m y,$(CONFIG_INPUT_HIMAX_V2_MMI_ENABLE_DOUBLE_TAP)),)
EXTRA_CFLAGS += -DHIMAX_V2_SENSOR_EN
endif
ifneq ($(filter m y,$(CONFIG_INPUT_HIMAX_V2_MMI_ENABLE_MULTI_BIN)),)
EXTRA_CFLAGS += -DHIMAX_V2_MULTI_BIN
endif
obj-m := himax_v3_mmi.o
himax_v3_mmi-objs += himax_platform.o
ifneq ($(filter m y,$(CONFIG_INPUT_TOUCHSCREEN_HIMAX_V2_MMI_0FLASH)),)
himax_v3_mmi-objs += himax_platform_QCT_SPI.o
EXTRA_CFLAGS += -D__HIMAX_PLATFORM_SPI__ \
-DHX_ZERO_FLASH
endif
himax_v3_mmi-objs += himax_common.o
himax_v3_mmi-objs += himax_debug.o
himax_v3_mmi-objs += himax_ic_incell_core.o
himax_v3_mmi-objs += himax_inspection.o

7469
drivers/input/touchscreen/himax_v3_mmi/himax_common.c Normal file → Executable file

File diff suppressed because it is too large Load diff

1135
drivers/input/touchscreen/himax_v3_mmi/himax_common.h Normal file → Executable file

File diff suppressed because it is too large Load diff

5897
drivers/input/touchscreen/himax_v3_mmi/himax_debug.c Normal file → Executable file

File diff suppressed because it is too large Load diff

View file

@ -1,164 +1,149 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Himax Android Driver Sample Code for debug nodes
*
* Copyright (C) 2019 Himax Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef H_HIMAX_DEBUG
#define H_HIMAX_DEBUG
#include "himax_platform.h"
#include "himax_common.h"
#if defined(HX_ESD_RECOVERY)
extern u8 HX_ESD_RESET_ACTIVATE;
extern int hx_EB_event_flag;
extern int hx_EC_event_flag;
extern int hx_ED_event_flag;
#endif
#define HIMAX_PROC_VENDOR_FILE "vendor"
extern struct proc_dir_entry *himax_proc_vendor_file;
#define HIMAX_PROC_PEN_POS_FILE "pen_pos"
int himax_touch_proc_init(void);
void himax_touch_proc_deinit(void);
extern int himax_int_en_set(void);
extern uint8_t byte_length;
extern uint8_t register_command[4];
extern uint8_t cfg_flag;
#define HIMAX_PROC_DIAG_FOLDER "diag"
struct proc_dir_entry *himax_proc_diag_dir;
#define HIMAX_PROC_STACK_FILE "stack"
extern struct proc_dir_entry *himax_proc_stack_file;
#define HIMAX_PROC_DELTA_FILE "delta_s"
extern struct proc_dir_entry *himax_proc_delta_file;
#define HIMAX_PROC_DC_FILE "dc_s"
extern struct proc_dir_entry *himax_proc_dc_file;
#define HIMAX_PROC_BASELINE_FILE "baseline_s"
extern struct proc_dir_entry *himax_proc_baseline_file;
#if defined(HX_TP_PROC_2T2R)
extern uint32_t *diag_mutual_2;
int32_t *getMutualBuffer_2(void);
void setMutualBuffer_2(uint8_t x_num, uint8_t y_num);
#endif
extern int32_t *diag_mutual;
extern int32_t *diag_mutual_new;
extern int32_t *diag_mutual_old;
extern uint8_t diag_max_cnt;
extern uint8_t hx_state_info[2];
extern uint8_t diag_coor[128];
extern int32_t *diag_self;
extern int32_t *diag_self_new;
extern int32_t *diag_self_old;
int32_t *getMutualBuffer(void);
int32_t *getMutualNewBuffer(void);
int32_t *getMutualOldBuffer(void);
int32_t *getSelfBuffer(void);
int32_t *getSelfNewBuffer(void);
int32_t *getSelfOldBuffer(void);
void setMutualBuffer(uint8_t x_num, uint8_t y_num);
void setMutualNewBuffer(uint8_t x_num, uint8_t y_num);
void setMutualOldBuffer(uint8_t x_num, uint8_t y_num);
uint8_t process_type;
uint8_t mode_flag;
uint8_t overflow;
#define HIMAX_PROC_DEBUG_FILE "debug"
extern struct proc_dir_entry *himax_proc_debug_file;
extern bool fw_update_complete;
extern int handshaking_result;
extern unsigned char debug_level_cmd;
extern uint8_t cmd_set[8];
extern uint8_t mutual_set_flag;
#define HIMAX_PROC_FLASH_DUMP_FILE "flash_dump"
extern struct proc_dir_entry *himax_proc_flash_dump_file;
extern int Flash_Size;
extern uint8_t *flash_buffer;
extern uint8_t g_flash_cmd;
extern uint8_t g_flash_progress;
extern bool g_flash_dump_rst; /*Fail = 0, Pass = 1*/
void setFlashBuffer(void);
enum flash_dump_prog {
START,
ONGOING,
FINISHED,
};
extern uint32_t **raw_data_array;
extern uint8_t X_NUM4;
extern uint8_t Y_NUM;
extern uint8_t sel_type;
/* Moved from debug.c */
extern struct himax_debug *debug_data;
extern unsigned char IC_CHECKSUM;
extern int i2c_error_count;
extern struct proc_dir_entry *himax_touch_proc_dir;
#if defined(HX_TP_PROC_GUEST_INFO)
extern struct hx_guest_info *g_guest_info_data;
extern char *g_guest_info_item[];
#endif
extern int himax_input_register(struct himax_ts_data *ts);
#if defined(HX_TP_PROC_2T2R)
extern bool Is_2T2R;
#endif
#if defined(HX_RST_PIN_FUNC)
extern void himax_ic_reset(uint8_t loadconfig, uint8_t int_off);
#endif
#if defined(HX_ZERO_FLASH)
extern char *i_CTPM_firmware_name;
#endif
extern uint8_t HX_PROC_SEND_FLAG;
extern struct himax_target_report_data *g_target_report_data;
extern struct himax_report_data *hx_touch_data;
extern int g_ts_dbg;
/* Moved from debug.c end */
#define BUF_SIZE 1024
#define CMD_NUM 15
char *dbg_cmd_str[] = {
"crc_test",
"fw_debug",
"attn",
"layout",
"dd_debug",
"esd_cnt",
"senseonoff",
"debug_level",
"guest_info",
"int_en",
"register",
"reset",
"diag_arr",
"diag",
NULL
};
int dbg_cmd_flag;
char *dbg_cmd_par;
ssize_t (*dbg_func_ptr_r[CMD_NUM])(char *buf, size_t len);
ssize_t (*dbg_func_ptr_w[CMD_NUM])(char *buf, size_t len);
#endif
/* SPDX-License-Identifier: GPL-2.0 */
/* Himax Android Driver Sample Code for debug nodes
*
* Copyright (C) 2019 Himax Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef H_HIMAX_DEBUG
#define H_HIMAX_DEBUG
#include "himax_platform.h"
#include "himax_common.h"
#ifdef HX_ESD_RECOVERY
extern u8 HX_ESD_RESET_ACTIVATE;
extern int hx_EB_event_flag;
extern int hx_EC_event_flag;
extern int hx_ED_event_flag;
#endif
#define HIMAX_PROC_VENDOR_FILE "vendor"
extern struct proc_dir_entry *himax_proc_vendor_file;
#define HIMAX_PROC_PEN_POS_FILE "pen_pos"
int himax_touch_proc_init(void);
void himax_touch_proc_deinit(void);
extern int himax_int_en_set(void);
extern uint8_t byte_length;
extern uint8_t register_command[4];
extern uint8_t cfg_flag;
#define HIMAX_PROC_DIAG_FOLDER "diag"
struct proc_dir_entry *himax_proc_diag_dir;
#define HIMAX_PROC_STACK_FILE "stack"
extern struct proc_dir_entry *himax_proc_stack_file;
#define HIMAX_PROC_IIR_FILE "iir_s"
extern struct proc_dir_entry *himax_proc_iir_file;
#define HIMAX_PROC_DC_FILE "dc_s"
extern struct proc_dir_entry *himax_proc_dc_file;
#define HIMAX_PROC_BANK_FILE "bank_s"
extern struct proc_dir_entry *himax_proc_bank_file;
#ifdef HX_TP_PROC_2T2R
extern uint32_t *diag_mutual_2;
int32_t *getMutualBuffer_2(void);
void setMutualBuffer_2(uint8_t x_num, uint8_t y_num);
#endif
extern int32_t *diag_mutual;
extern int32_t *diag_mutual_new;
extern int32_t *diag_mutual_old;
extern uint8_t diag_max_cnt;
extern uint8_t hx_state_info[2];
extern uint8_t diag_coor[128];
extern int32_t diag_self[100];
extern int32_t diag_self_new[100];
extern int32_t diag_self_old[100];
int32_t *getMutualBuffer(void);
int32_t *getMutualNewBuffer(void);
int32_t *getMutualOldBuffer(void);
int32_t *getSelfBuffer(void);
int32_t *getSelfNewBuffer(void);
int32_t *getSelfOldBuffer(void);
void setMutualBuffer(uint8_t x_num, uint8_t y_num);
void setMutualNewBuffer(uint8_t x_num, uint8_t y_num);
void setMutualOldBuffer(uint8_t x_num, uint8_t y_num);
uint8_t process_type;
uint8_t mode_flag;
uint8_t overflow;
#define HIMAX_PROC_DEBUG_FILE "debug"
extern struct proc_dir_entry *himax_proc_debug_file;
extern bool fw_update_complete;
extern int handshaking_result;
extern unsigned char debug_level_cmd;
extern uint8_t cmd_set[8];
extern uint8_t mutual_set_flag;
#define HIMAX_PROC_FLASH_DUMP_FILE "flash_dump"
extern struct proc_dir_entry *himax_proc_flash_dump_file;
extern int Flash_Size;
extern uint8_t *flash_buffer;
extern uint8_t g_flash_cmd;
extern uint8_t g_flash_progress;
extern bool g_flash_dump_rst; /*Fail = 0, Pass = 1*/
void setFlashBuffer(void);
enum flash_dump_prog {
START,
ONGOING,
FINISHED,
};
extern uint32_t **raw_data_array;
extern uint8_t X_NUM4;
extern uint8_t Y_NUM;
extern uint8_t sel_type;
/* Moved from debug.c */
extern struct himax_debug *debug_data;
extern unsigned char IC_CHECKSUM;
extern int i2c_error_count;
extern struct proc_dir_entry *himax_touch_proc_dir;
#ifdef HX_TP_PROC_GUEST_INFO
extern struct hx_guest_info *g_guest_info_data;
extern char *g_guest_info_item[];
#endif
extern int himax_input_register(struct himax_ts_data *ts);
#ifdef HX_TP_PROC_2T2R
extern bool Is_2T2R;
#endif
#ifdef HX_RST_PIN_FUNC
extern void himax_ic_reset(uint8_t loadconfig, uint8_t int_off);
#endif
#if defined(HX_ZERO_FLASH)
extern char *i_CTPM_firmware_name;
#endif
extern uint8_t HX_PROC_SEND_FLAG;
extern struct himax_target_report_data *g_target_report_data;
extern struct himax_report_data *hx_touch_data;
extern int g_ts_dbg;
/* Moved from debug.c end */
#define BUF_SIZE 1024
#define CMD_NUM 15
char *dbg_cmd_str[] = {"crc_test", "fw_debug", "attn", "layout", "dd_debug",
"esd_cnt", "senseonoff", "debug_level", "guest_info", "int_en",
"register", "reset", "diag_arr", "diag", NULL};
int dbg_cmd_flag;
char *dbg_cmd_par;
ssize_t (*dbg_func_ptr_r[CMD_NUM])(char *buf, size_t len);
ssize_t (*dbg_func_ptr_w[CMD_NUM])(char *buf, size_t len);
#endif

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

4540
drivers/input/touchscreen/himax_v3_mmi/himax_inspection.c Normal file → Executable file

File diff suppressed because it is too large Load diff

View file

@ -1,292 +1,211 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Himax Android Driver Sample Code for inspection functions
*
* Copyright (C) 2019 Himax Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "himax_platform.h"
#include "himax_common.h"
#include "himax_ic_core.h"
/*#define HX_GAP_TEST*/
/*#define HX_INSP_LP_TEST*/
/*#define HX_ACT_IDLE_TEST*/
#define HX_RSLT_OUT_PATH "/sdcard/"
#define HX_RSLT_OUT_FILE "hx_test_result.txt"
#define PI(x...) pr_cont(x)
#define HX_SZ_ICID 60
#if defined(HX_ESD_RECOVERY)
extern u8 HX_ESD_RESET_ACTIVATE;
#endif
#define BS_RAWDATA 10
#define BS_NOISE 10
#define BS_OPENSHORT 0
#define BS_LPWUG 1
#define BS_LP_dile 1
#define BS_ACT_IDLE 1
/* skip notch & dummy */
#define SKIP_NOTCH_START 5
#define SKIP_NOTCH_END 10
/* TX+SKIP_NOTCH_START */
#define SKIP_DUMMY_START 23
/* TX+SKIP_NOTCH_END*/
#define SKIP_DUMMY_END 28
#define NOISEFRAME (BS_NOISE+1)
#define NORMAL_IDLE_RAWDATA_NOISEFRAME 10
#define LP_RAWDATAFRAME 1
#define LP_NOISEFRAME 1
#define LP_IDLE_RAWDATAFRAME 1
#define LP_IDLE_NOISEFRAME 1
#define OTHERSFRAME 2
#define UNIFMAX 500
/*Himax MP Password*/
#define PWD_OPEN_START 0x77
#define PWD_OPEN_END 0x88
#define PWD_SHORT_START 0x11
#define PWD_SHORT_END 0x33
#define PWD_RAWDATA_START 0x00
#define PWD_RAWDATA_END 0x99
#define PWD_NOISE_START 0x00
#define PWD_NOISE_END 0x99
#define PWD_SORTING_START 0xAA
#define PWD_SORTING_END 0xCC
#define PWD_ACT_IDLE_START 0x22
#define PWD_ACT_IDLE_END 0x44
#define PWD_LP_START 0x55
#define PWD_LP_END 0x66
#define PWD_LP_IDLE_START 0x50
#define PWD_LP_IDLE_END 0x60
#define PWD_TURN_ON_MPAP_OVL 0x107380
/*Himax DataType*/
#define DATA_SORTING 0x0A
#define DATA_OPEN 0x0B
#define DATA_MICRO_OPEN 0x0C
#define DATA_SHORT 0x0A
#define DATA_RAWDATA 0x0A
#define DATA_NOISE 0x0F
#define DATA_BACK_NORMAL 0x00
#define DATA_LP_RAWDATA 0x0C
#define DATA_LP_NOISE 0x0F
#define DATA_ACT_IDLE_RAWDATA 0x0A
#define DATA_ACT_IDLE_NOISE 0x0F
#define DATA_LP_IDLE_RAWDATA 0x0A
#define DATA_LP_IDLE_NOISE 0x0F
/*Himax Data Ready Password*/
#define Data_PWD0 0xA5
#define Data_PWD1 0x5A
/* ASCII format */
#define ASCII_LF (0x0A)
#define ASCII_CR (0x0D)
#define ASCII_COMMA (0x2C)
#define ASCII_ZERO (0x30)
#define CHAR_EL '\0'
#define CHAR_NL '\n'
#define ACSII_SPACE (0x20)
/* INSOECTION Setting */
void himax_inspection_init(void);
extern int *g_test_item_flag;
extern int HX_CRITERIA_ITEM;
extern int *g_test_item_flag;
extern char *g_himax_inspection_mode[];
/*Inspection register*/
#define addr_normal_noise_thx 0x1000708C
#define addr_lpwug_noise_thx 0x10007090
#define addr_recal_thx 0x10007090
#define addr_palm_num 0x100070A8
#define addr_weight_sup 0x100072C8
#define addr_normal_weight_a 0x1000709C
#define addr_lpwug_weight_a 0x100070A0
#define addr_weight_b 0x10007094
#define addr_max_dc 0x10007FC8
#define addr_skip_frame 0x100070F4
#define addr_neg_noise_sup 0x10007FD8
#define data_neg_noise 0x7F0C0000
#define addr_ctrl_mpap_ovl 0x100073EC
/*Need to map *g_himax_inspection_mode[]*/
enum THP_INSPECTION_ENUM {
HX_OPEN,
HX_MICRO_OPEN,
HX_SHORT,
HX_RAWDATA,
HX_BPN_RAWDATA,
HX_SC,
HX_WT_NOISE,
HX_ABS_NOISE,
HX_SORTING,
HX_GAPTEST_RAW,
/*HX_GAPTEST_RAW_X,*/
/*HX_GAPTEST_RAW_Y,*/
HX_ACT_IDLE_RAWDATA,
HX_ACT_IDLE_BPN_RAWDATA,
HX_ACT_IDLE_NOISE,
/*LPWUG test must put after Normal test*/
HX_LP_RAWDATA,
HX_LP_BPN_RAWDATA,
HX_LP_WT_NOISE,
HX_LP_ABS_NOISE,
HX_LP_IDLE_RAWDATA,
HX_LP_IDLE_BPN_RAWDATA,
HX_LP_IDLE_NOISE,
HX_BACK_NORMAL,/*Must put in the end*/
};
enum HX_CRITERIA_ENUM {
IDX_RAWMIN = 0,
IDX_RAWMAX,
IDX_BPN_RAWMIN,
IDX_BPN_RAWMAX,
IDX_SCMIN,
IDX_SCMAX,
IDX_SC_GOLDEN,
IDX_SHORTMIN,
IDX_SHORTMAX,
IDX_OPENMIN,
IDX_OPENMAX,
IDX_M_OPENMIN,
IDX_M_OPENMAX,
IDX_WT_NOISEMIN,
IDX_WT_NOISEMAX,
IDX_ABS_NOISEMIN,
IDX_ABS_NOISEMAX,
IDX_SORTMIN,
IDX_SORTMAX,
IDX_GAP_HOR_RAWMAX,
IDX_GAP_HOR_RAWMIN,
IDX_GAP_VER_RAWMAX,
IDX_GAP_VER_RAWMIN,
IDX_ACT_IDLE_NOISE_MIN,
IDX_ACT_IDLE_NOISE_MAX,
IDX_ACT_IDLE_RAWDATA_MIN,
IDX_ACT_IDLE_RAWDATA_MAX,
IDX_ACT_IDLE_RAW_BPN_MIN,
IDX_ACT_IDLE_RAW_BPN_MAX,
IDX_LP_WT_NOISEMIN,
IDX_LP_WT_NOISEMAX,
IDX_LP_NOISE_ABS_MIN,
IDX_LP_NOISE_ABS_MAX,
IDX_LP_RAWDATA_MIN,
IDX_LP_RAWDATA_MAX,
IDX_LP_RAW_BPN_MIN,
IDX_LP_RAW_BPN_MAX,
IDX_LP_IDLE_NOISE_MIN,
IDX_LP_IDLE_NOISE_MAX,
IDX_LP_IDLE_RAWDATA_MIN,
IDX_LP_IDLE_RAWDATA_MAX,
IDX_LP_IDLE_RAW_BPN_MIN,
IDX_LP_IDLE_RAW_BPN_MAX,
};
#define ERR_SFT 4
/* Error code of Inspection */
enum HX_INSP_ERR_ENUM {
/* OK */
HX_INSP_OK = 0,
/* Criteria file error*/
HX_INSP_EFILE = 1,
/* Get raw data errors */
HX_INSP_EGETRAW = 1 << 1,
/* Memory allocate errors */
HX_INSP_MEMALLCTFAIL = 1 << 2,
/* Switch mode error*/
HX_INSP_ESWITCHMODE = 1 << 3,
/* Sensor open error */
HX_EOPEN = 1 << (HX_OPEN + ERR_SFT),
/* Sensor micro open error */
HX_EMOPEN = 1 << (HX_MICRO_OPEN + ERR_SFT),
/* Sensor short error */
HX_ESHORT = 1 << (HX_SHORT + ERR_SFT),
/* Raw data error */
HX_ERAW = 1 << (HX_RAWDATA + ERR_SFT),
/* Raw data BPN error */
HX_EBPNRAW = 1 << (HX_BPN_RAWDATA + ERR_SFT),
/* Get SC errors */
HX_ESC = 1 << (HX_SC + ERR_SFT),
/* Noise error */
HX_WT_ENOISE = 1 << (HX_WT_NOISE + ERR_SFT),
/* Noise error */
HX_ABS_ENOISE = 1 << (HX_ABS_NOISE + ERR_SFT),
/* Sorting error*/
HX_ESORT = 1 << (HX_SORTING + ERR_SFT),
/* Raw Data GAP */
HX_EGAP_RAW = 1 << (HX_GAPTEST_RAW + ERR_SFT),
/* ACT_IDLE RAW ERROR */
HX_EACT_IDLE_RAW = 1 << (HX_ACT_IDLE_RAWDATA + ERR_SFT),
/* ACT_IDLE NOISE ERROR */
HX_EACT_IDLE_NOISE = 1 << (HX_ACT_IDLE_NOISE + ERR_SFT),
/* LPWUG RAW ERROR */
HX_ELP_RAW = 1 << (HX_LP_RAWDATA + ERR_SFT),
/* LPWUG NOISE ERROR */
HX_ELP_WT_NOISE = 1 << (HX_LP_WT_NOISE + ERR_SFT),
/* LPWUG NOISE ERROR */
HX_ELP_ABS_NOISE = 1 << (HX_LP_ABS_NOISE + ERR_SFT),
/* LPWUG IDLE RAW ERROR */
HX_ELP_IDLE_RAW = 1 << (HX_LP_IDLE_RAWDATA + ERR_SFT),
/* LPWUG IDLE NOISE ERROR */
HX_ELP_IDLE_NOISE = 1 << (HX_LP_IDLE_NOISE + ERR_SFT),
HX_EACT_IDLE_BPNRAW = 1 << (HX_ACT_IDLE_BPN_RAWDATA + ERR_SFT),
HX_ELP_BPNRAW = 1 << (HX_LP_BPN_RAWDATA + ERR_SFT),
HX_ELP_IDLE_BPNRAW = 1 << (HX_LP_IDLE_BPN_RAWDATA + ERR_SFT),
};
extern void himax_inspect_data_clear(void);
/* SPDX-License-Identifier: GPL-2.0 */
/* Himax Android Driver Sample Code for inspection functions
*
* Copyright (C) 2019 Himax Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "himax_platform.h"
#include "himax_common.h"
#include "himax_ic_core.h"
/*#define HX_GAP_TEST*/
/*#define HX_INSPECT_LPWUG_TEST*/
/*#define HX_ACT_IDLE_TEST*/
#define HX_RSLT_OUT_PATH "/sdcard/"
#define HX_RSLT_OUT_FILE "hx_test_result.txt"
#define PI(x...) pr_info(x)
#ifdef HX_ESD_RECOVERY
extern u8 HX_ESD_RESET_ACTIVATE;
#endif
#define BS_RAWDATA 10
#define BS_NOISE 10
#define BS_OPENSHORT 0
#define BS_LPWUG 1
#define BS_LPWUG_dile 1
#define BS_ACT_IDLE 1
/* skip notch & dummy */
#define SKIP_NOTCH_START 5
#define SKIP_NOTCH_END 10
/* TX+SKIP_NOTCH_START */
#define SKIP_DUMMY_START 23
/* TX+SKIP_NOTCH_END*/
#define SKIP_DUMMY_END 28
#define NOISEFRAME (BS_NOISE+1)
#define NORMAL_IDLE_RAWDATA_NOISEFRAME 10
#define LPWUG_RAWDATAFRAME 1
#define LPWUG_NOISEFRAME 1
#define LPWUG_IDLE_RAWDATAFRAME 1
#define LPWUG_IDLE_NOISEFRAME 1
#define OTHERSFRAME 2
#define UNIFMAX 500
/*Himax MP Password*/
#define PWD_OPEN_START 0x77
#define PWD_OPEN_END 0x88
#define PWD_SHORT_START 0x11
#define PWD_SHORT_END 0x33
#define PWD_RAWDATA_START 0x00
#define PWD_RAWDATA_END 0x99
#define PWD_NOISE_START 0x00
#define PWD_NOISE_END 0x99
#define PWD_SORTING_START 0xAA
#define PWD_SORTING_END 0xCC
#define PWD_ACT_IDLE_START 0x22
#define PWD_ACT_IDLE_END 0x44
#define PWD_LPWUG_START 0x55
#define PWD_LPWUG_END 0x66
#define PWD_LPWUG_IDLE_START 0x50
#define PWD_LPWUG_IDLE_END 0x60
/*Himax DataType*/
#define DATA_SORTING 0x0A
#define DATA_OPEN 0x0B
#define DATA_MICRO_OPEN 0x0C
#define DATA_SHORT 0x0A
#define DATA_RAWDATA 0x0A
#define DATA_NOISE 0x0F
#define DATA_BACK_NORMAL 0x00
#define DATA_LPWUG_RAWDATA 0x0C
#define DATA_LPWUG_NOISE 0x0F
#define DATA_ACT_IDLE_RAWDATA 0x0A
#define DATA_ACT_IDLE_NOISE 0x0F
#define DATA_LPWUG_IDLE_RAWDATA 0x0A
#define DATA_LPWUG_IDLE_NOISE 0x0F
/*Himax Data Ready Password*/
#define Data_PWD0 0xA5
#define Data_PWD1 0x5A
/* ASCII format */
#define ASCII_LF (0x0A)
#define ASCII_CR (0x0D)
#define ASCII_COMMA (0x2C)
#define ASCII_ZERO (0x30)
#define CHAR_EL '\0'
#define CHAR_NL '\n'
#define ACSII_SPACE (0x20)
/* INSOECTION Setting */
/*extern int HX_CRITERIA_ITEM;*/
/*extern int HX_CRITERIA_SIZE;*/
/*extern char *g_file_path;*/
/*extern char *g_rslt_data;*/
void himax_inspection_init(void);
extern int *g_inspt_crtra_flag;
enum THP_INSPECTION_ENUM {
HIMAX_INSPECTION_OPEN,
HIMAX_INSPECTION_MICRO_OPEN,
HIMAX_INSPECTION_SHORT,
HIMAX_INSPECTION_RAWDATA,
HIMAX_INSPECTION_BPN_RAWDATA,
HIMAX_INSPECTION_WEIGHT_NOISE,
HIMAX_INSPECTION_ABS_NOISE,
HIMAX_INSPECTION_SORTING,
HIMAX_INSPECTION_BACK_NORMAL,
HIMAX_INSPECTION_GAPTEST_RAW,
HIMAX_INSPECTION_ACT_IDLE_RAWDATA,
HIMAX_INSPECTION_ACT_IDLE_NOISE,
HIMAX_INSPECTION_LPWUG_RAWDATA,
HIMAX_INSPECTION_LPWUG_NOISE,
HIMAX_INSPECTION_LPWUG_IDLE_RAWDATA,
HIMAX_INSPECTION_LPWUG_IDLE_NOISE,
};
enum HX_CRITERIA_ENUM {
IDX_RAWMIN = 0,
IDX_RAWMAX,
IDX_BPN_RAWMIN,
IDX_BPN_RAWMAX,
IDX_SHORTMIN,
IDX_SHORTMAX,
IDX_OPENMIN,
IDX_OPENMAX,
IDX_M_OPENMIN,
IDX_M_OPENMAX,
IDX_WT_NOISEMIN,
IDX_WT_NOISEMAX,
IDX_ABS_NOISEMIN,
IDX_ABS_NOISEMAX,
IDX_SORTMIN,
IDX_SORTMAX,
IDX_GAP_HOR_RAWMAX,
IDX_GAP_HOR_RAWMIN,
IDX_GAP_VER_RAWMAX,
IDX_GAP_VER_RAWMIN,
IDX_ACT_IDLE_NOISE_MIN,
IDX_ACT_IDLE_NOISE_MAX,
IDX_ACT_IDLE_RAWDATA_MIN,
IDX_ACT_IDLE_RAWDATA_MAX,
IDX_LPWUG_NOISE_MIN,
IDX_LPWUG_NOISE_MAX,
IDX_LPWUG_RAWDATA_MIN,
IDX_LPWUG_RAWDATA_MAX,
IDX_LPWUG_IDLE_NOISE_MIN,
IDX_LPWUG_IDLE_NOISE_MAX,
IDX_LPWUG_IDLE_RAWDATA_MIN,
IDX_LPWUG_IDLE_RAWDATA_MAX,
};
/* Error code of Inspection */
enum HX_INSPECT_ERR_ENUM {
HX_INSPECT_OK = 0x00000000, /* OK */
HX_INSPECT_EFILE = 0x00000001, /*Criteria file error*/
HX_INSPECT_ERAW = 0x00000002, /* Raw data error */
HX_INSPECT_WT_ENOISE = 0x00000004, /* Noise error */
HX_INSPECT_ABS_ENOISE = 0x00000008, /* Noise error */
HX_INSPECT_EOPEN = 0x00000010, /* Sensor open error */
HX_INSPECT_EMOPEN = 0x00000020, /* Sensor micro open error */
HX_INSPECT_ESHORT = 0x00000040, /* Sensor short error */
HX_INSPECT_EGAP_RAW = 0x00000080, /* Raw Data GAP */
HX_INSPECT_EACT_IDLE_RAW = 0x00000100, /* ACT_IDLE RAW ERROR */
HX_INSPECT_EACT_IDLE_NOISE = 0x00000200, /* ACT_IDLE NOISE ERROR */
HX_INSPECT_ELPWUG_RAW = 0x00000400, /* LPWUG RAW ERROR */
HX_INSPECT_ELPWUG_NOISE = 0x00000800, /* LPWUG NOISE ERROR */
HX_INSPECT_ELPWUG_IDLE_RAW = 0x00001000, /* LPWUG IDLE RAW ERROR */
HX_INSPECT_ELPWUG_IDLE_NOISE = 0x00002000, /* LPWUG IDLE NOISE ERROR */
HX_INSPECT_EGETRAW = 0x00004000, /* Get raw data errors */
HX_INSPECT_MEMALLCTFAIL = 0x00008000, /* Get raw data errors */
/*HX_INSPECT_ESPI = , */ /*SPI communication error,no use*/
};
extern void himax_inspect_data_clear(void);
extern char *hx_self_test_file_name;

View file

@ -1,398 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Himax Android Driver Sample Code for modularize functions
*
* Copyright (C) 2019 Himax Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __HIMAX_MODULAR_H__
#define __HIMAX_MODULAR_H__
#include "himax_modular_table.h"
static bool (*this_detect_fp)(void);
#if defined(HX_USE_KSYM)
static void himax_add_chip_dt(bool (*detect_fp)(void))
{
int32_t idx;
struct himax_chip_entry *entry;
this_detect_fp = detect_fp;
idx = himax_get_ksym_idx();
if (idx < 0) {
/*TODO: No entry, handle this error*/
E("%s: no entry exist, please insert ic module first!",
__func__);
} else {
entry = (void *)kallsyms_lookup_name(himax_ksym_lookup[idx]);
if (/*!(entry->core_chip_dt)*/isEmpty(idx) == 1) {
entry->core_chip_dt = kcalloc(HX_DRIVER_MAX_IC_NUM,
sizeof(struct himax_chip_detect), GFP_KERNEL);
if (entry->core_chip_dt == NULL) {
E("%s: Failed to allocate core_chip_dt\n",
__func__);
return;
}
entry->hx_ic_dt_num = 0;
}
entry->core_chip_dt[entry->hx_ic_dt_num++].fp_chip_detect =
detect_fp;
}
}
#else
static void himax_add_chip_dt(bool (*detect_fp)(void))
{
this_detect_fp = detect_fp;
if (himax_ksym_lookup.core_chip_dt == NULL) {
himax_ksym_lookup.core_chip_dt = kcalloc(HX_DRIVER_MAX_IC_NUM,
sizeof(struct himax_chip_detect), GFP_KERNEL);
if (himax_ksym_lookup.core_chip_dt == NULL) {
E("%s: Failed to allocate core_chip_dt\n", __func__);
return;
}
himax_ksym_lookup.hx_ic_dt_num = 0;
}
himax_ksym_lookup.core_chip_dt
[himax_ksym_lookup.hx_ic_dt_num].fp_chip_detect = detect_fp;
himax_ksym_lookup.hx_ic_dt_num++;
}
#endif
static void free_chip_dt_table(void)
{
int i, j, idx;
struct himax_chip_entry *entry;
idx = himax_get_ksym_idx();
if (idx >= 0) {
if (isEmpty(idx) != 0) {
I("%s: no chip registered or entry clean up\n",
__func__);
return;
}
entry = get_chip_entry_by_index(idx);
for (i = 0; i < entry->hx_ic_dt_num; i++) {
if (entry->core_chip_dt
[i].fp_chip_detect == this_detect_fp) {
if (i == (entry->hx_ic_dt_num - 1)) {
entry->core_chip_dt
[i].fp_chip_detect = NULL;
entry->hx_ic_dt_num = 0;
} else {
for (j = i; j < entry
->hx_ic_dt_num; j++)
entry->core_chip_dt
[i].fp_chip_detect =
entry->core_chip_dt
[j].fp_chip_detect;
entry->core_chip_dt
[j].fp_chip_detect = NULL;
entry->hx_ic_dt_num--;
}
}
}
if (entry->hx_ic_dt_num == 0) {
kfree(entry->core_chip_dt);
entry->core_chip_dt = NULL;
}
}
}
#if !defined(HX_USE_KSYM)
#define setup_symbol(sym) ({kp_##sym = &(sym); kp_##sym; })
#define setup_symbol_func(sym) ({kp_##sym = (sym); kp_##sym; })
#else
#define setup_symbol(sym) ({kp_##sym = (void *)kallsyms_lookup_name(#sym); \
kp_##sym; })
#define setup_symbol_func(sym) setup_symbol(sym)
#endif
#define assert_on_symbol(sym) \
do { \
if (!setup_symbol(sym)) { \
E("%s: setup %s failed!\n", __func__, #sym); \
ret = -1; \
} \
} while (0)
#define assert_on_symbol_func(sym) \
do { \
if (!setup_symbol_func(sym)) { \
E("%s: setup %s failed!\n", __func__, #sym); \
ret = -1; \
} \
} while (0)
#if !defined(__HIMAX_HX852xH_MOD__) && !defined(__HIMAX_HX852xG_MOD__)
static struct fw_operation **kp_pfw_op;
static struct ic_operation **kp_pic_op;
static struct flash_operation **kp_pflash_op;
static struct driver_operation **kp_pdriver_op;
#endif
#if defined(HX_ZERO_FLASH) && defined(CONFIG_TOUCHSCREEN_HIMAX_INCELL)
static struct zf_operation **kp_pzf_op;
static int *kp_G_POWERONOF;
#endif
static unsigned char *kp_IC_CHECKSUM;
#if defined(HX_ESD_RECOVERY)
static u8 *kp_HX_ESD_RESET_ACTIVATE;
#endif
#if defined(HX_ZERO_FLASH) && defined(HX_CODE_OVERLAY)
#if defined(CONFIG_TOUCHSCREEN_HIMAX_INCELL)
static uint8_t **kp_ovl_idx;
#endif
#endif
static unsigned long *kp_FW_VER_MAJ_FLASH_ADDR;
static unsigned long *kp_FW_VER_MIN_FLASH_ADDR;
static unsigned long *kp_CFG_VER_MAJ_FLASH_ADDR;
static unsigned long *kp_CFG_VER_MIN_FLASH_ADDR;
static unsigned long *kp_CID_VER_MAJ_FLASH_ADDR;
static unsigned long *kp_CID_VER_MIN_FLASH_ADDR;
static unsigned long *kp_FW_VER_MAJ_FLASH_LENG;
static unsigned long *kp_FW_VER_MIN_FLASH_LENG;
static unsigned long *kp_CFG_VER_MAJ_FLASH_LENG;
static unsigned long *kp_CFG_VER_MIN_FLASH_LENG;
static unsigned long *kp_CID_VER_MAJ_FLASH_LENG;
static unsigned long *kp_CID_VER_MIN_FLASH_LENG;
#if defined(HX_AUTO_UPDATE_FW)
static int *kp_g_i_FW_VER;
static int *kp_g_i_CFG_VER;
static int *kp_g_i_CID_MAJ;
static int *kp_g_i_CID_MIN;
static unsigned char **kp_i_CTPM_FW;
#endif
#if defined(HX_TP_PROC_2T2R)
static bool *kp_Is_2T2R;
#endif
#if defined(HX_USB_DETECT_GLOBAL)
static void (*kp_himax_cable_detect_func)(bool force_renew);
#endif
#if defined(HX_RST_PIN_FUNC)
static void (*kp_himax_rst_gpio_set)(int pinnum, uint8_t value);
#endif
static struct himax_ts_data **kp_private_ts;
static struct himax_core_fp *kp_g_core_fp;
static struct himax_ic_data **kp_ic_data;
#if defined(__HIMAX_HX852xH_MOD__) || defined(__HIMAX_HX852xG_MOD__)
#if defined(__HIMAX_HX852xG_MOD__)
static struct on_driver_operation **kp_on_pdriver_op;
#endif
static void (*kp_himax_mcu_on_cmd_init)(void);
static int (*kp_himax_mcu_on_cmd_struct_init)(void);
#else
static void (*kp_himax_mcu_in_cmd_init)(void);
static int (*kp_himax_mcu_in_cmd_struct_init)(void);
#endif
static void (*kp_himax_parse_assign_cmd)(uint32_t addr, uint8_t *cmd,
int len);
static int (*kp_himax_bus_read)(uint8_t command, uint8_t *data,
uint32_t length, uint8_t toRetry);
static int (*kp_himax_bus_write)(uint8_t command, uint8_t *data,
uint32_t length, uint8_t toRetry);
static int (*kp_himax_bus_write_command)(uint8_t command, uint8_t toRetry);
static void (*kp_himax_int_enable)(int enable);
static int (*kp_himax_ts_register_interrupt)(void);
static uint8_t (*kp_himax_int_gpio_read)(int pinnum);
static int (*kp_himax_gpio_power_config)(struct himax_i2c_platform_data *pdata);
#if !defined(HX_USE_KSYM)
#if !defined(__HIMAX_HX852xH_MOD__) && !defined(__HIMAX_HX852xG_MOD__)
extern struct fw_operation *pfw_op;
extern struct ic_operation *pic_op;
extern struct flash_operation *pflash_op;
extern struct driver_operation *pdriver_op;
#endif
#if defined(HX_ZERO_FLASH) && defined(CONFIG_TOUCHSCREEN_HIMAX_INCELL)
extern struct zf_operation *pzf_op;
extern int G_POWERONOF;
#endif
extern unsigned char IC_CHECKSUM;
#if defined(HX_ESD_RECOVERY)
extern u8 HX_ESD_RESET_ACTIVATE;
#endif
#if defined(HX_ZERO_FLASH) && defined(HX_CODE_OVERLAY)
#if defined(CONFIG_TOUCHSCREEN_HIMAX_INCELL)
extern uint8_t *ovl_idx;
#endif
#endif
extern unsigned long FW_VER_MAJ_FLASH_ADDR;
extern unsigned long FW_VER_MIN_FLASH_ADDR;
extern unsigned long CFG_VER_MAJ_FLASH_ADDR;
extern unsigned long CFG_VER_MIN_FLASH_ADDR;
extern unsigned long CID_VER_MAJ_FLASH_ADDR;
extern unsigned long CID_VER_MIN_FLASH_ADDR;
extern unsigned long FW_VER_MAJ_FLASH_LENG;
extern unsigned long FW_VER_MIN_FLASH_LENG;
extern unsigned long CFG_VER_MAJ_FLASH_LENG;
extern unsigned long CFG_VER_MIN_FLASH_LENG;
extern unsigned long CID_VER_MAJ_FLASH_LENG;
extern unsigned long CID_VER_MIN_FLASH_LENG;
#if defined(HX_AUTO_UPDATE_FW)
extern int g_i_FW_VER;
extern int g_i_CFG_VER;
extern int g_i_CID_MAJ;
extern int g_i_CID_MIN;
extern unsigned char *i_CTPM_FW;
#endif
#if defined(HX_TP_PROC_2T2R)
extern bool Is_2T2R;
#endif
#if defined(HX_USB_DETECT_GLOBAL)
extern void (himax_cable_detect_func)(bool force_renew);
#endif
#if defined(HX_RST_PIN_FUNC)
extern void (himax_rst_gpio_set)(int pinnum, uint8_t value);
#endif
extern struct himax_ts_data *private_ts;
extern struct himax_core_fp g_core_fp;
extern struct himax_ic_data *ic_data;
#if defined(__HIMAX_HX852xH_MOD__) || defined(__HIMAX_HX852xG_MOD__)
#if defined(__HIMAX_HX852xG_MOD__)
extern struct on_driver_operation *on_pdriver_op;
#endif
extern void (himax_mcu_on_cmd_init)(void);
extern int (himax_mcu_on_cmd_struct_init)(void);
#else
extern void (himax_mcu_in_cmd_init)(void);
extern int (himax_mcu_in_cmd_struct_init)(void);
#endif
extern void (himax_parse_assign_cmd)(uint32_t addr, uint8_t *cmd, int len);
extern int (himax_bus_read)(uint8_t command, uint8_t *data, uint32_t length,
uint8_t toRetry);
extern int (himax_bus_write)(uint8_t command, uint8_t *data, uint32_t length,
uint8_t toRetry);
extern int (himax_bus_write_command)(uint8_t command, uint8_t toRetry);
extern void (himax_int_enable)(int enable);
extern int (himax_ts_register_interrupt)(void);
extern uint8_t (himax_int_gpio_read)(int pinnum);
extern int (himax_gpio_power_config)(struct himax_i2c_platform_data *pdata);
#endif
static int32_t himax_ic_setup_external_symbols(void)
{
int32_t ret = 0;
#if !defined(__HIMAX_HX852xH_MOD__) && !defined(__HIMAX_HX852xG_MOD__)
assert_on_symbol(pfw_op);
assert_on_symbol(pic_op);
assert_on_symbol(pflash_op);
assert_on_symbol(pdriver_op);
#endif
assert_on_symbol(private_ts);
assert_on_symbol(g_core_fp);
assert_on_symbol(ic_data);
#if defined(__HIMAX_HX852xH_MOD__) || defined(__HIMAX_HX852xG_MOD__)
#if defined(__HIMAX_HX852xG_MOD__)
assert_on_symbol(on_pdriver_op);
#endif
assert_on_symbol_func(himax_mcu_on_cmd_init);
assert_on_symbol_func(himax_mcu_on_cmd_struct_init);
#else
assert_on_symbol_func(himax_mcu_in_cmd_init);
assert_on_symbol_func(himax_mcu_in_cmd_struct_init);
#endif
assert_on_symbol_func(himax_parse_assign_cmd);
assert_on_symbol_func(himax_bus_read);
assert_on_symbol_func(himax_bus_write);
assert_on_symbol_func(himax_bus_write_command);
assert_on_symbol_func(himax_int_enable);
assert_on_symbol_func(himax_ts_register_interrupt);
assert_on_symbol_func(himax_int_gpio_read);
assert_on_symbol_func(himax_gpio_power_config);
#if defined(HX_ZERO_FLASH) && defined(CONFIG_TOUCHSCREEN_HIMAX_INCELL)
assert_on_symbol(pzf_op);
assert_on_symbol(G_POWERONOF);
#endif
assert_on_symbol(IC_CHECKSUM);
assert_on_symbol(FW_VER_MAJ_FLASH_ADDR);
assert_on_symbol(FW_VER_MIN_FLASH_ADDR);
assert_on_symbol(CFG_VER_MAJ_FLASH_ADDR);
assert_on_symbol(CFG_VER_MIN_FLASH_ADDR);
assert_on_symbol(CID_VER_MAJ_FLASH_ADDR);
assert_on_symbol(CID_VER_MIN_FLASH_ADDR);
assert_on_symbol(FW_VER_MAJ_FLASH_LENG);
assert_on_symbol(FW_VER_MIN_FLASH_LENG);
assert_on_symbol(CFG_VER_MAJ_FLASH_LENG);
assert_on_symbol(CFG_VER_MIN_FLASH_LENG);
assert_on_symbol(CID_VER_MAJ_FLASH_LENG);
assert_on_symbol(CID_VER_MIN_FLASH_LENG);
#if defined(HX_AUTO_UPDATE_FW)
assert_on_symbol(g_i_FW_VER);
assert_on_symbol(g_i_CFG_VER);
assert_on_symbol(g_i_CID_MAJ);
assert_on_symbol(g_i_CID_MIN);
assert_on_symbol(i_CTPM_FW);
#endif
#if defined(HX_TP_PROC_2T2R)
assert_on_symbol(Is_2T2R);
#endif
#if defined(HX_USB_DETECT_GLOBAL)
assert_on_symbol_func(himax_cable_detect_func);
#endif
#if defined(HX_RST_PIN_FUNC)
assert_on_symbol_func(himax_rst_gpio_set);
#endif
#if defined(HX_ESD_RECOVERY)
assert_on_symbol(HX_ESD_RESET_ACTIVATE);
#endif
#if defined(HX_ZERO_FLASH) && defined(HX_CODE_OVERLAY)
#if defined(CONFIG_TOUCHSCREEN_HIMAX_INCELL)
assert_on_symbol(ovl_idx);
#endif
#endif
return ret;
}
#endif

View file

@ -1,156 +1,115 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Himax Android Driver Sample Code for modularize functions
*
* Copyright (C) 2019 Himax Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __HIMAX_MODULAR_TABLE_H__
#define __HIMAX_MODULAR_TABLE_H__
#include "himax_ic_core.h"
#define TO_STR(VAR) #VAR
enum modular_table {
MODULE_NOT_FOUND = -1,
MODULE_FOUND,
MODULE_EMPTY,
};
#if defined(HX_USE_KSYM)
#define DECLARE(sym) struct himax_chip_entry sym; \
EXPORT_SYMBOL(sym)
static const char * const himax_ksym_lookup[] = {
#if defined(HX_MOD_KSYM_HX852xG)
TO_STR(HX_MOD_KSYM_HX852xG),
#endif
#if defined(HX_MOD_KSYM_HX852xH)
TO_STR(HX_MOD_KSYM_HX852xH),
#endif
#if defined(HX_MOD_KSYM_HX83102)
TO_STR(HX_MOD_KSYM_HX83102),
#endif
#if defined(HX_MOD_KSYM_HX83103)
TO_STR(HX_MOD_KSYM_HX83103),
#endif
#if defined(HX_MOD_KSYM_HX83106)
TO_STR(HX_MOD_KSYM_HX83106),
#endif
#if defined(HX_MOD_KSYM_HX83111)
TO_STR(HX_MOD_KSYM_HX83111),
#endif
#if defined(HX_MOD_KSYM_HX83112)
TO_STR(HX_MOD_KSYM_HX83112),
#endif
#if defined(HX_MOD_KSYM_HX83113)
TO_STR(HX_MOD_KSYM_HX83113),
#endif
#if defined(HX_MOD_KSYM_HX83192)
TO_STR(HX_MOD_KSYM_HX83192),
#endif
#if defined(HX_MOD_KSYM_HX83191)
TO_STR(HX_MOD_KSYM_HX83191),
#endif
NULL
};
static struct himax_chip_entry *get_chip_entry_by_index(int32_t idx)
{
return (void *)kallsyms_lookup_name(himax_ksym_lookup[idx]);
}
/*
* Return 1 when specified entry is empty, 0 when not, -1 when index error
*/
static int32_t isEmpty(int32_t idx)
{
int32_t size = sizeof(himax_ksym_lookup) / sizeof(char *);
struct himax_chip_entry *entry;
if (idx < 0 || idx >= size)
return MODULE_NOT_FOUND;
entry = get_chip_entry_by_index(idx);
if (entry)
return (entry->core_chip_dt == NULL)?MODULE_EMPTY:MODULE_FOUND;
return MODULE_NOT_FOUND;
}
/*
* Search for created entry, if not existed, return 1st
* Return index of himax_ksym_lookup
*/
static int32_t himax_get_ksym_idx(void)
{
int32_t i, first = -1;
int32_t size = sizeof(himax_ksym_lookup) / sizeof(char *);
struct himax_chip_entry *entry;
I("%s: symtable size: %d\n", __func__, size);
for (i = 0; i < size; i++) {
if (himax_ksym_lookup[i] == NULL)
break;
I("%s: %s\n", __func__, himax_ksym_lookup[i]);
entry = get_chip_entry_by_index(i);
if (entry) {
if (first < 0)
first = i;
if (isEmpty(i) == 0)
return i;
}
}
if (first >= 0)
return first;
/*incorrect use state, means no ic defined*/
return MODULE_NOT_FOUND;
}
#else
#define DECLARE(sym)
extern struct himax_chip_entry himax_ksym_lookup;
static struct himax_chip_entry *get_chip_entry_by_index(int32_t idx)
{
return &himax_ksym_lookup;
}
static int32_t isEmpty(int32_t idx)
{
struct himax_chip_entry *entry;
if (idx < 0)
return MODULE_NOT_FOUND;
entry = get_chip_entry_by_index(idx);
if (entry)
return (entry->core_chip_dt == NULL)?MODULE_EMPTY:MODULE_FOUND;
return MODULE_NOT_FOUND;
}
static int32_t himax_get_ksym_idx(void)
{
int32_t size;
size = himax_ksym_lookup.hx_ic_dt_num;
I("%s: symtable size: %d\n", __func__, size);
return 0;
}
#endif
#endif
/* SPDX-License-Identifier: GPL-2.0 */
/* Himax Android Driver Sample Code for modularize functions
*
* Copyright (C) 2019 Himax Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __HIMAX_MODULAR_TABLE_H__
#define __HIMAX_MODULAR_TABLE_H__
#include "himax_ic_core.h"
#define TO_STR(VAR) #VAR
#define DECLARE(sym) struct himax_chip_entry sym; \
EXPORT_SYMBOL(sym)
static const char * const himax_ksym_lookup[] = {
#if defined(HX_MOD_KSYM_HX852xG)
TO_STR(HX_MOD_KSYM_HX852xG),
#endif
#if defined(HX_MOD_KSYM_HX852xH)
TO_STR(HX_MOD_KSYM_HX852xH),
#endif
#if defined(HX_MOD_KSYM_HX83102)
TO_STR(HX_MOD_KSYM_HX83102),
#endif
#if defined(HX_MOD_KSYM_HX83103)
TO_STR(HX_MOD_KSYM_HX83103),
#endif
#if defined(HX_MOD_KSYM_HX83106)
TO_STR(HX_MOD_KSYM_HX83106),
#endif
#if defined(HX_MOD_KSYM_HX83111)
TO_STR(HX_MOD_KSYM_HX83111),
#endif
#if defined(HX_MOD_KSYM_HX83112)
TO_STR(HX_MOD_KSYM_HX83112),
#endif
#if defined(HX_MOD_KSYM_HX83113)
TO_STR(HX_MOD_KSYM_HX83113),
#endif
#if defined(HX_MOD_KSYM_HX83191)
TO_STR(HX_MOD_KSYM_HX83191),
#endif
NULL
};
static struct himax_chip_entry *get_chip_entry_by_index(int32_t idx)
{
return (void *)kallsyms_lookup_name(himax_ksym_lookup[idx]);
}
enum modular_table {
MODULE_NOT_FOUND = -1,
MODULE_FOUND,
MODULE_EMPTY,
};
/*
* Return 1 when specified entry is empty, 0 when not, -1 when index error
*/
static int32_t isEmpty(int32_t idx)
{
int32_t size = sizeof(himax_ksym_lookup) / sizeof(char *);
struct himax_chip_entry *entry;
if (idx < 0 || idx >= size)
return MODULE_NOT_FOUND;
entry = get_chip_entry_by_index(idx);
if (entry)
return (entry->core_chip_dt == NULL)?MODULE_EMPTY:MODULE_FOUND;
return MODULE_NOT_FOUND;
}
/*
* Search for created entry, if not existed, return 1st
* Return index of himax_ksym_lookup
*/
static int32_t himax_get_ksym_idx(void)
{
int32_t i, first = -1;
int32_t size = sizeof(himax_ksym_lookup) / sizeof(char *);
struct himax_chip_entry *entry;
I("%s: symtable size: %d\n", __func__, size);
for (i = 0; i < size; i++) {
if (himax_ksym_lookup[i] == NULL)
break;
I("%s: %s\n", __func__, himax_ksym_lookup[i]);
entry = get_chip_entry_by_index(i);
if (entry) {
if (first < 0)
first = i;
if (isEmpty(i) == 0)
return i;
}
}
if (first >= 0)
return first;
/*incorrect use state, means no ic defined*/
return MODULE_NOT_FOUND;
}
#endif

View file

@ -1,143 +1,5 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Himax Android Driver Sample Code for QCT platform
*
* Copyright (C) 2019 Himax Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef HIMAX_PLATFORM_H
#define HIMAX_PLATFORM_H
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <linux/types.h>
#include <linux/spi/spi.h>
#include <linux/interrupt.h>
#if defined(CONFIG_HMX_DB)
#include <linux/regulator/consumer.h>
#endif
#define HIMAX_SPI_FIFO_POLLING
#define HIMAX_I2C_RETRY_TIMES 3
#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
#define D(x...) pr_debug("[HXTP] " x)
#define I(x...) pr_info("[HXTP] " x)
#define W(x...) pr_warn("[HXTP][WARNING] " x)
#define E(x...) pr_err("[HXTP][ERROR] " x)
#define DIF(x...) \
do { \
if (debug_flag) \
pr_debug("[HXTP][DEBUG] " x) \
} while (0)
#else
#define D(x...)
#define I(x...)
#define W(x...)
#define E(x...)
#define DIF(x...)
#endif
#if defined(CONFIG_HMX_DB)
/* Analog voltage @2.7 V */
#define HX_VTG_MIN_UV 2700000
#define HX_VTG_MAX_UV 3300000
#define HX_ACTIVE_LOAD_UA 15000
#define HX_LPM_LOAD_UA 10
/* Digital voltage @1.8 V */
#define HX_VTG_DIG_MIN_UV 1800000
#define HX_VTG_DIG_MAX_UV 1800000
#define HX_ACTIVE_LOAD_DIG_UA 10000
#define HX_LPM_LOAD_DIG_UA 10
#define HX_I2C_VTG_MIN_UV 1800000
#define HX_I2C_VTG_MAX_UV 1800000
#define HX_I2C_LOAD_UA 10000
#define HX_I2C_LPM_LOAD_UA 10
#endif
#define HIMAX_common_NAME "himax_tp"
#define HIMAX_I2C_ADDR 0x48
#define INPUT_DEV_NAME "himax-touchscreen"
struct himax_i2c_platform_data {
int abs_x_min;
int abs_x_max;
int abs_x_fuzz;
int abs_y_min;
int abs_y_max;
int abs_y_fuzz;
int abs_pressure_min;
int abs_pressure_max;
int abs_pressure_fuzz;
int abs_width_min;
int abs_width_max;
int screenWidth;
int screenHeight;
uint8_t fw_version;
uint8_t tw_id;
uint8_t powerOff3V3;
uint8_t cable_config[2];
uint8_t protocol_type;
int gpio_irq;
int gpio_reset;
int gpio_3v3_en;
int (*power)(int on);
void (*reset)(void);
struct himax_virtual_key *virtual_key;
struct kobject *vk_obj;
struct kobj_attribute *vk2Use;
int hx_config_size;
#if defined(CONFIG_HMX_DB)
bool i2c_pull_up;
bool digital_pwr_regulator;
int reset_gpio;
u32 reset_gpio_flags;
int irq_gpio;
u32 irq_gpio_flags;
struct regulator *vcc_ana; /* For Dragon Board */
struct regulator *vcc_dig; /* For Dragon Board */
struct regulator *vcc_i2c; /* For Dragon Board */
#endif
};
extern struct himax_ic_data *ic_data;
extern struct himax_ts_data *private_ts;
int himax_chip_common_init(void);
void himax_chip_common_deinit(void);
void himax_ts_work(struct himax_ts_data *ts);
enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer);
extern int himax_bus_read(uint8_t command, uint8_t *data,
uint32_t length, uint8_t toRetry);
extern int himax_bus_write(uint8_t command, uint8_t *data,
uint32_t length, uint8_t toRetry);
extern int himax_bus_write_command(uint8_t command, uint8_t toRetry);
extern void himax_int_enable(int enable);
extern int himax_ts_register_interrupt(void);
int himax_ts_unregister_interrupt(void);
extern uint8_t himax_int_gpio_read(int pinnum);
extern int himax_gpio_power_config(struct himax_i2c_platform_data *pdata);
void himax_gpio_power_deconfig(struct himax_i2c_platform_data *pdata);
#if defined(HX_CONFIG_FB)
extern int fb_notifier_callback(struct notifier_block *self,
unsigned long event, void *data);
#elif defined(CONFIG_DRM)
extern int drm_notifier_callback(struct notifier_block *self,
unsigned long event, void *data);
#endif
#endif
#ifdef __HIMAX_PLATFORM_SPI__
#include "himax_platform_QCT_SPI.h"
#else
#include "himax_platform_QCT_I2C.h"
#endif

View file

@ -0,0 +1,972 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Himax Android Driver Sample Code for QCT platform
*
* Copyright (C) 2019 Himax Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "himax_platform.h"
#include "himax_common.h"
int i2c_error_count;
int irq_enable_count;
EXPORT_SYMBOL(irq_enable_count);
int himax_dev_set(struct himax_ts_data *ts)
{
int ret = 0;
ts->input_dev = input_allocate_device();
if (ts->input_dev == NULL) {
ret = -ENOMEM;
E("%s: Failed to allocate input device-input_dev\n", __func__);
return ret;
}
ts->input_dev->name = "himax-touchscreen";
#if defined(HX_PEN_FUNC_EN)
ts->hx_pen_dev = input_allocate_device();
if (ts->hx_pen_dev == NULL) {
ret = -ENOMEM;
E("%s: Failed to allocate input device-hx_pen_dev\n", __func__);
return ret;
}
ts->hx_pen_dev->name = "himax-pen";
#endif
return ret;
}
int himax_input_register_device(struct input_dev *input_dev)
{
return input_register_device(input_dev);
}
#if defined(HX_PLATFOME_DEFINE_KEY)
void himax_platform_key(void)
{
I("Nothing to be done! Plz cancel it!\n");
}
#endif
void himax_vk_parser(struct device_node *dt,
struct himax_i2c_platform_data *pdata)
{
u32 data = 0;
uint8_t cnt = 0, i = 0;
uint32_t coords[4] = {0};
struct device_node *node, *pp = NULL;
struct himax_virtual_key *vk;
node = of_parse_phandle(dt, "virtualkey", 0);
if (node == NULL) {
I(" DT-No vk info in DT\n");
} else {
while ((pp = of_get_next_child(node, pp)))
cnt++;
if (!cnt)
return;
vk = kcalloc(cnt, sizeof(struct himax_virtual_key), GFP_KERNEL);
pp = NULL;
while ((pp = of_get_next_child(node, pp))) {
if (of_property_read_u32(pp, "idx", &data) == 0)
vk[i].index = data;
if (of_property_read_u32_array(pp, "range", coords, 4) == 0) {
vk[i].x_range_min = coords[0], vk[i].x_range_max = coords[1];
vk[i].y_range_min = coords[2], vk[i].y_range_max = coords[3];
} else {
I(" range faile\n");
}
i++;
}
pdata->virtual_key = vk;
for (i = 0; i < cnt; i++)
I(" vk[%d] idx:%d x_min:%d, y_max:%d\n", i, pdata->virtual_key[i].index,
pdata->virtual_key[i].x_range_min, pdata->virtual_key[i].y_range_max);
}
}
int himax_parse_dt(struct himax_ts_data *ts,
struct himax_i2c_platform_data *pdata)
{
int rc, coords_size = 0;
uint32_t coords[4] = {0};
struct property *prop;
struct device_node *dt = private_ts->client->dev.of_node;
u32 data = 0;
prop = of_find_property(dt, "himax,panel-coords", NULL);
if (prop) {
coords_size = prop->length / sizeof(u32);
if (coords_size != 4)
D(" %s:Invalid panel coords size %d\n", __func__, coords_size);
}
if (of_property_read_u32_array(dt, "himax,panel-coords", coords, coords_size) == 0) {
pdata->abs_x_min = coords[0], pdata->abs_x_max = (coords[1] - 1);
pdata->abs_y_min = coords[2], pdata->abs_y_max = (coords[3] - 1);
I(" DT-%s:panel-coords = %d, %d, %d, %d\n", __func__, pdata->abs_x_min,
pdata->abs_x_max, pdata->abs_y_min, pdata->abs_y_max);
}
prop = of_find_property(dt, "himax,display-coords", NULL);
if (prop) {
coords_size = prop->length / sizeof(u32);
if (coords_size != 4)
D(" %s:Invalid display coords size %d\n", __func__, coords_size);
}
rc = of_property_read_u32_array(dt, "himax,display-coords", coords, coords_size);
if (rc && (rc != -EINVAL)) {
D(" %s:Fail to read display-coords %d\n", __func__, rc);
return rc;
}
pdata->screenWidth = coords[1];
pdata->screenHeight = coords[3];
I(" DT-%s:display-coords = (%d, %d)\n", __func__, pdata->screenWidth,
pdata->screenHeight);
pdata->gpio_irq = of_get_named_gpio(dt, "himax,irq-gpio", 0);
if (!gpio_is_valid(pdata->gpio_irq))
I(" DT:gpio_irq value is not valid\n");
#ifdef HX_SHARP_ENABLE_PON
pdata->gpio_reset = 262;
#else
pdata->gpio_reset = of_get_named_gpio(dt, "himax,rst-gpio", 0);
#endif
if (!gpio_is_valid(pdata->gpio_reset))
I(" DT:gpio_rst value is not valid\n");
#ifdef HX_SHARP_ENABLE_PON
pdata->gpio_pon = of_get_named_gpio(dt, "himax,pon-gpio", 0);
if (!gpio_is_valid(pdata->gpio_pon))
I(" DT:gpio_pon value is not valid\n");
I(" DT:pdata->gpio_pon=%d\n", pdata->gpio_pon);
#endif
pdata->gpio_3v3_en = of_get_named_gpio(dt, "himax,3v3-gpio", 0);
if (!gpio_is_valid(pdata->gpio_3v3_en))
I(" DT:gpio_3v3_en value is not valid\n");
I(" DT:gpio_irq=%d, gpio_rst=%d, gpio_3v3_en=%d\n", pdata->gpio_irq, pdata->gpio_reset, pdata->gpio_3v3_en);
if (of_property_read_u32(dt, "report_type", &data) == 0) {
pdata->protocol_type = data;
I(" DT:protocol_type=%d\n", pdata->protocol_type);
}
himax_vk_parser(dt, pdata);
return 0;
}
EXPORT_SYMBOL(himax_parse_dt);
int himax_bus_read(uint8_t command, uint8_t *data, uint32_t length, uint8_t toRetry)
{
int retry;
struct i2c_client *client = private_ts->client;
struct i2c_msg msg[] = {
{
.addr = client->addr,
.flags = 0,
.len = 1,
.buf = &command,
},
{
.addr = client->addr,
.flags = I2C_M_RD,
.len = length,
.buf = data,
}
};
mutex_lock(&private_ts->rw_lock);
for (retry = 0; retry < toRetry; retry++) {
if (i2c_transfer(client->adapter, msg, 2) == 2)
break;
/*msleep(20);*/
}
if (retry == toRetry) {
E("%s: i2c_read_block retry over %d\n",
__func__, toRetry);
i2c_error_count = toRetry;
mutex_unlock(&private_ts->rw_lock);
return -EIO;
}
mutex_unlock(&private_ts->rw_lock);
return 0;
}
EXPORT_SYMBOL(himax_bus_read);
int himax_bus_write(uint8_t command, uint8_t *data, uint32_t length, uint8_t toRetry)
{
int retry/*, loop_i*/;
uint8_t buf[length + 1];
struct i2c_client *client = private_ts->client;
struct i2c_msg msg[] = {
{
.addr = client->addr,
.flags = 0,
.len = length + 1,
.buf = buf,
}
};
mutex_lock(&private_ts->rw_lock);
buf[0] = command;
memcpy(buf + 1, data, length);
for (retry = 0; retry < toRetry; retry++) {
if (i2c_transfer(client->adapter, msg, 1) == 1)
break;
/*msleep(20);*/
}
if (retry == toRetry) {
E("%s: i2c_write_block retry over %d\n",
__func__, toRetry);
i2c_error_count = toRetry;
mutex_unlock(&private_ts->rw_lock);
return -EIO;
}
mutex_unlock(&private_ts->rw_lock);
return 0;
}
EXPORT_SYMBOL(himax_bus_write);
int himax_bus_write_command(uint8_t command, uint8_t toRetry)
{
return himax_bus_write(command, NULL, 0, toRetry);
}
int himax_bus_master_write(uint8_t *data, uint32_t length, uint8_t toRetry)
{
int retry/*, loop_i*/;
uint8_t buf[length];
struct i2c_client *client = private_ts->client;
struct i2c_msg msg[] = {
{
.addr = client->addr,
.flags = 0,
.len = length,
.buf = buf,
}
};
mutex_lock(&private_ts->rw_lock);
memcpy(buf, data, length);
for (retry = 0; retry < toRetry; retry++) {
if (i2c_transfer(client->adapter, msg, 1) == 1)
break;
/*msleep(20);*/
}
if (retry == toRetry) {
E("%s: i2c_write_block retry over %d\n",
__func__, toRetry);
i2c_error_count = toRetry;
mutex_unlock(&private_ts->rw_lock);
return -EIO;
}
mutex_unlock(&private_ts->rw_lock);
return 0;
}
EXPORT_SYMBOL(himax_bus_master_write);
void himax_int_enable(int enable)
{
int irqnum = 0;
irqnum = private_ts->client->irq;
if (enable == 1 && irq_enable_count == 0) {
enable_irq(irqnum);
irq_enable_count = 1;
private_ts->irq_enabled = 1;
} else if (enable == 0 && irq_enable_count == 1) {
disable_irq_nosync(irqnum);
irq_enable_count = 0;
private_ts->irq_enabled = 0;
}
I("irq_enable_count = %d\n", irq_enable_count);
}
EXPORT_SYMBOL(himax_int_enable);
#ifdef HX_RST_PIN_FUNC
void himax_rst_gpio_set(int pinnum, uint8_t value)
{
gpio_direction_output(pinnum, value);
}
EXPORT_SYMBOL(himax_rst_gpio_set);
#endif
uint8_t himax_int_gpio_read(int pinnum)
{
return gpio_get_value(pinnum);
}
#if defined(CONFIG_HMX_DB)
static int himax_regulator_configure(struct himax_i2c_platform_data *pdata)
{
int retval;
struct i2c_client *client = private_ts->client;
pdata->vcc_dig = regulator_get(&client->dev, "vdd");
if (IS_ERR(pdata->vcc_dig)) {
E("%s: Failed to get regulator vdd\n",
__func__);
retval = PTR_ERR(pdata->vcc_dig);
return retval;
}
pdata->vcc_ana = regulator_get(&client->dev, "avdd");
if (IS_ERR(pdata->vcc_ana)) {
E("%s: Failed to get regulator avdd\n",
__func__);
retval = PTR_ERR(pdata->vcc_ana);
regulator_put(pdata->vcc_dig);
return retval;
}
return 0;
};
static void himax_regulator_deinit(struct himax_i2c_platform_data *pdata)
{
I("%s: entered.\n", __func__);
if (!IS_ERR(pdata->vcc_ana))
regulator_put(pdata->vcc_ana);
if (!IS_ERR(pdata->vcc_dig))
regulator_put(pdata->vcc_dig);
I("%s: regulator put, completed.\n", __func__);
};
static int himax_power_on(struct himax_i2c_platform_data *pdata, bool on)
{
int retval;
if (on) {
retval = regulator_enable(pdata->vcc_dig);
if (retval) {
E("%s: Failed to enable regulator vdd\n",
__func__);
return retval;
}
/*msleep(100);*/
usleep_range(1000, 1001);
retval = regulator_enable(pdata->vcc_ana);
if (retval) {
E("%s: Failed to enable regulator avdd\n",
__func__);
regulator_disable(pdata->vcc_dig);
return retval;
}
} else {
regulator_disable(pdata->vcc_dig);
regulator_disable(pdata->vcc_ana);
}
return 0;
}
int himax_gpio_power_config(struct himax_i2c_platform_data *pdata)
{
int error;
struct i2c_client *client = private_ts->client;
error = himax_regulator_configure(pdata);
if (error) {
E("Failed to intialize hardware\n");
goto err_regulator_not_on;
}
#ifdef HX_RST_PIN_FUNC
if (gpio_is_valid(pdata->gpio_reset)) {
/* configure touchscreen reset out gpio */
error = gpio_request(pdata->gpio_reset, "hmx_reset_gpio");
if (error) {
E("unable to request gpio [%d]\n", pdata->gpio_reset);
goto err_regulator_on;
}
error = gpio_direction_output(pdata->gpio_reset, 0);
if (error) {
E("unable to set direction for gpio [%d]\n",
pdata->gpio_reset);
goto err_gpio_reset_req;
}
}
#endif
error = himax_power_on(pdata, true);
if (error) {
E("Failed to power on hardware\n");
goto err_power_on;
}
if (gpio_is_valid(pdata->gpio_irq)) {
/* configure touchscreen irq gpio */
error = gpio_request(pdata->gpio_irq, "hmx_gpio_irq");
if (error) {
E("unable to request gpio [%d]\n",
pdata->gpio_irq);
goto err_req_irq_gpio;
}
error = gpio_direction_input(pdata->gpio_irq);
if (error) {
E("unable to set direction for gpio [%d]\n",
pdata->gpio_irq);
goto err_set_gpio_irq;
}
client->irq = gpio_to_irq(pdata->gpio_irq);
private_ts->hx_irq = client->irq;
} else {
E("irq gpio not provided\n");
goto err_req_irq_gpio;
}
/*msleep(20);*/
usleep_range(2000, 2001);
#ifdef HX_RST_PIN_FUNC
if (gpio_is_valid(pdata->gpio_reset)) {
error = gpio_direction_output(pdata->gpio_reset, 1);
if (error) {
E("unable to set direction for gpio [%d]\n",
pdata->gpio_reset);
goto err_set_gpio_irq;
}
}
#endif
return 0;
err_set_gpio_irq:
if (gpio_is_valid(pdata->gpio_irq))
gpio_free(pdata->gpio_irq);
err_req_irq_gpio:
himax_power_on(pdata, false);
err_power_on:
#ifdef HX_RST_PIN_FUNC
err_gpio_reset_req:
if (gpio_is_valid(pdata->gpio_reset))
gpio_free(pdata->gpio_reset);
err_regulator_on:
#endif
himax_regulator_deinit(pdata);
err_regulator_not_on:
return error;
}
#else
int himax_gpio_power_config(struct himax_i2c_platform_data *pdata)
{
int error = 0;
struct i2c_client *client = private_ts->client;
#ifdef HX_RST_PIN_FUNC
if (pdata->gpio_reset >= 0) {
error = gpio_request(pdata->gpio_reset, "himax-reset");
if (error < 0) {
E("%s: request reset pin failed\n", __func__);
goto err_gpio_reset_req;
}
error = gpio_direction_output(pdata->gpio_reset, 0);
if (error) {
E("unable to set direction for gpio [%d]\n",
pdata->gpio_reset);
goto err_gpio_reset_dir;
}
}
#endif
#ifdef HX_SHARP_ENABLE_PON
if (gpio_is_valid(pdata->gpio_pon)) {
error = gpio_request(pdata->gpio_pon, "hmx_pon_gpio");
if (error) {
E("unable to request scl gpio [%d]\n", pdata->gpio_pon);
goto err_gpio_pon_req;
}
error = gpio_direction_output(pdata->gpio_pon, 0);
I("gpio_pon LOW [%d]\n", pdata->gpio_pon);
if (error) {
E("unable to set direction for pon gpio [%d]\n", pdata->gpio_pon);
goto err_gpio_pon_dir;
}
}
#endif
if (pdata->gpio_3v3_en >= 0) {
error = gpio_request(pdata->gpio_3v3_en, "himax-3v3_en");
if (error < 0) {
E("%s: request 3v3_en pin failed\n", __func__);
goto err_gpio_3v3_req;
}
gpio_direction_output(pdata->gpio_3v3_en, 1);
I("3v3_en set 1 get pin = %d\n", gpio_get_value(pdata->gpio_3v3_en));
}
if (gpio_is_valid(pdata->gpio_irq)) {
/* configure touchscreen irq gpio */
error = gpio_request(pdata->gpio_irq, "himax_gpio_irq");
if (error) {
E("unable to request gpio [%d]\n", pdata->gpio_irq);
goto err_gpio_irq_req;
}
error = gpio_direction_input(pdata->gpio_irq);
if (error) {
E("unable to set direction for gpio [%d]\n", pdata->gpio_irq);
goto err_gpio_irq_set_input;
}
client->irq = gpio_to_irq(pdata->gpio_irq);
private_ts->hx_irq = client->irq;
} else {
E("irq gpio not provided\n");
goto err_gpio_irq_req;
}
#ifdef HX_SHARP_ENABLE_PON
msleep(20);
#else
usleep_range(2000, 2001);
#endif
#ifdef HX_RST_PIN_FUNC
if (pdata->gpio_reset >= 0) {
error = gpio_direction_output(pdata->gpio_reset, 1);
if (error) {
E("unable to set direction for gpio [%d]\n",
pdata->gpio_reset);
goto err_gpio_reset_set_high;
}
}
#endif
#ifdef HX_SHARP_ENABLE_PON
msleep(800);
if (gpio_is_valid(pdata->gpio_pon)) {
error = gpio_direction_output(pdata->gpio_pon, 1);
I("gpio_pon HIGH [%d]\n", pdata->gpio_pon);
if (error) {
E("gpio_pon unable to set direction for gpio [%d]\n", pdata->gpio_pon);
goto err_gpio_pon_set_high;
}
}
#endif
return error;
#ifdef HX_SHARP_ENABLE_PON
err_gpio_pon_set_high:
#endif
#ifdef HX_RST_PIN_FUNC
err_gpio_reset_set_high:
#endif
err_gpio_irq_set_input:
if (gpio_is_valid(pdata->gpio_irq))
gpio_free(pdata->gpio_irq);
err_gpio_irq_req:
if (pdata->gpio_3v3_en >= 0)
gpio_free(pdata->gpio_3v3_en);
err_gpio_3v3_req:
#ifdef HX_SHARP_ENABLE_PON
err_gpio_pon_dir:
if (gpio_is_valid(pdata->gpio_pon))
gpio_free(pdata->gpio_pon);
err_gpio_pon_req:
#endif
#ifdef HX_RST_PIN_FUNC
err_gpio_reset_dir:
if (pdata->gpio_reset >= 0)
gpio_free(pdata->gpio_reset);
err_gpio_reset_req:
#endif
return error;
}
#endif
void himax_gpio_power_deconfig(struct himax_i2c_platform_data *pdata)
{
if (gpio_is_valid(pdata->gpio_irq))
gpio_free(pdata->gpio_irq);
#ifdef HX_RST_PIN_FUNC
if (gpio_is_valid(pdata->gpio_reset))
gpio_free(pdata->gpio_reset);
#endif
#if defined(CONFIG_HMX_DB)
himax_power_on(pdata, false);
himax_regulator_deinit(pdata);
#else
if (pdata->gpio_3v3_en >= 0)
gpio_free(pdata->gpio_3v3_en);
#ifdef HX_SHARP_ENABLE_PON
if (gpio_is_valid(pdata->gpio_pon))
gpio_free(pdata->gpio_pon);
#endif
#endif
}
static void himax_ts_isr_func(struct himax_ts_data *ts)
{
himax_ts_work(ts);
}
irqreturn_t himax_ts_thread(int irq, void *ptr)
{
himax_ts_isr_func((struct himax_ts_data *)ptr);
return IRQ_HANDLED;
}
static void himax_ts_work_func(struct work_struct *work)
{
struct himax_ts_data *ts = container_of(work, struct himax_ts_data, work);
himax_ts_work(ts);
}
int himax_int_register_trigger(void)
{
int ret = 0;
struct himax_ts_data *ts = private_ts;
struct i2c_client *client = private_ts->client;
if (ic_data->HX_INT_IS_EDGE) {
I("%s edge triiger falling\n ", __func__);
ret = request_threaded_irq(client->irq, NULL, himax_ts_thread, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, client->name, ts);
}
else {
I("%s level trigger low\n ", __func__);
ret = request_threaded_irq(client->irq, NULL, himax_ts_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT, client->name, ts);
}
return ret;
}
int himax_int_en_set(void)
{
int ret = NO_ERR;
ret = himax_int_register_trigger();
return ret;
}
int himax_ts_register_interrupt(void)
{
struct himax_ts_data *ts = private_ts;
struct i2c_client *client = private_ts->client;
int ret = 0;
ts->irq_enabled = 0;
/* Work functon */
if (client->irq && private_ts->hx_irq) {/*INT mode*/
ts->use_irq = 1;
ret = himax_int_register_trigger();
if (ret == 0) {
ts->irq_enabled = 1;
irq_enable_count = 1;
I("%s: irq enabled at gpio: %d\n", __func__, client->irq);
#ifdef HX_SMART_WAKEUP
irq_set_irq_wake(client->irq, 1);
#endif
} else {
ts->use_irq = 0;
E("%s: request_irq failed\n", __func__);
}
} else {
I("%s: client->irq is empty, use polling mode.\n", __func__);
}
if (!ts->use_irq) {/*if use polling mode need to disable HX_ESD_RECOVERY function*/
ts->himax_wq = create_singlethread_workqueue("himax_touch");
INIT_WORK(&ts->work, himax_ts_work_func);
hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL);
ts->timer.function = himax_ts_timer_func;
hrtimer_start(&ts->timer, ktime_set(1, 0), HRTIMER_MODE_REL);
I("%s: polling mode enabled\n", __func__);
}
return ret;
}
int himax_ts_unregister_interrupt(void)
{
struct himax_ts_data *ts = private_ts;
int ret = 0;
I("%s: entered.\n", __func__);
/* Work functon */
if (private_ts->hx_irq && ts->use_irq) {/*INT mode*/
#ifdef HX_SMART_WAKEUP
irq_set_irq_wake(ts->hx_irq, 0);
#endif
free_irq(ts->hx_irq, ts);
I("%s: irq disabled at qpio: %d\n", __func__, private_ts->hx_irq);
}
if (!ts->use_irq) {/*if use polling mode need to disable HX_ESD_RECOVERY function*/
hrtimer_cancel(&ts->timer);
cancel_work_sync(&ts->work);
if (ts->himax_wq != NULL)
destroy_workqueue(ts->himax_wq);
I("%s: polling mode destroyed", __func__);
}
return ret;
}
static int himax_common_suspend(struct device *dev)
{
struct himax_ts_data *ts = dev_get_drvdata(dev);
I("%s: enter\n", __func__);
himax_chip_common_suspend(ts);
return 0;
}
static int himax_common_resume(struct device *dev)
{
struct himax_ts_data *ts = dev_get_drvdata(dev);
I("%s: enter\n", __func__);
himax_chip_common_resume(ts);
return 0;
}
#if defined(CONFIG_FB)
int fb_notifier_callback(struct notifier_block *self,
unsigned long event, void *data)
{
struct fb_event *evdata = data;
int *blank;
struct himax_ts_data *ts =
container_of(self, struct himax_ts_data, fb_notif);
I(" %s\n", __func__);
if (evdata && evdata->data && event == FB_EVENT_BLANK && ts &&
ts->client) {
blank = evdata->data;
switch (*blank) {
case FB_BLANK_UNBLANK:
himax_common_resume(&ts->client->dev);
break;
case FB_BLANK_POWERDOWN:
case FB_BLANK_HSYNC_SUSPEND:
case FB_BLANK_VSYNC_SUSPEND:
case FB_BLANK_NORMAL:
himax_common_suspend(&ts->client->dev);
break;
}
}
return 0;
}
#endif
int himax_chip_common_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
int ret = 0;
struct himax_ts_data *ts;
I("%s:Enter\n", __func__);
/* Check I2C functionality */
if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
E("%s: i2c check functionality error\n", __func__);
ret = -ENODEV;
goto err_check_functionality_failed;
}
ts = kzalloc(sizeof(struct himax_ts_data), GFP_KERNEL);
if (ts == NULL) {
E("%s: allocate himax_ts_data failed\n", __func__);
ret = -ENOMEM;
goto err_alloc_data_failed;
}
i2c_set_clientdata(client, ts);
ts->client = client;
ts->dev = &client->dev;
mutex_init(&ts->rw_lock);
private_ts = ts;
ret = himax_chip_common_init();
err_alloc_data_failed:
err_check_functionality_failed:
return ret;
}
int himax_chip_common_remove(struct i2c_client *client)
{
if (g_hx_chip_inited)
himax_chip_common_deinit();
return 0;
}
static const struct i2c_device_id himax_common_ts_id[] = {
{HIMAX_common_NAME, 0 },
{}
};
static const struct dev_pm_ops himax_common_pm_ops = {
#if (!defined(CONFIG_FB))
.suspend = himax_common_suspend,
.resume = himax_common_resume,
#endif
};
#ifdef CONFIG_OF
static const struct of_device_id himax_match_table[] = {
{.compatible = "himax,hxcommon" },
{},
};
#else
#define himax_match_table NULL
#endif
static struct i2c_driver himax_common_driver = {
.id_table = himax_common_ts_id,
.probe = himax_chip_common_probe,
.remove = himax_chip_common_remove,
.driver = {
.name = HIMAX_common_NAME,
.owner = THIS_MODULE,
.of_match_table = himax_match_table,
#ifdef CONFIG_PM
.pm = &himax_common_pm_ops,
#endif
},
};
static int __init himax_common_init(void)
{
I("Himax common touch panel driver init\n");
D("Himax check double loading\n");
if (g_mmi_refcnt++ > 0) {
I("Himax driver has been loaded! ignoring....\n");
return 0;
}
i2c_add_driver(&himax_common_driver);
return 0;
}
static void __exit himax_common_exit(void)
{
i2c_del_driver(&himax_common_driver);
}
module_init(himax_common_init);
module_exit(himax_common_exit);
MODULE_DESCRIPTION("Himax_common driver");
MODULE_LICENSE("GPL");

View file

@ -0,0 +1,144 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Himax Android Driver Sample Code for QCT platform
*
* Copyright (C) 2019 Himax Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef HIMAX_PLATFORM_H
#define HIMAX_PLATFORM_H
#include "himax_common.h"
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <linux/types.h>
#include <linux/i2c.h>
#include <linux/interrupt.h>
#if defined(CONFIG_HMX_DB)
#include <linux/regulator/consumer.h>
#endif
#define HIMAX_I2C_RETRY_TIMES 3
#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
#define D(x...) pr_debug("[HXTP] " x)
#define I(x...) pr_info("[HXTP] " x)
#define W(x...) pr_warn("[HXTP][WARNING] " x)
#define E(x...) pr_err("[HXTP][ERROR] " x)
#define DIF(x...) \
do { \
if (debug_flag) \
pr_debug("[HXTP][DEBUG] " x) \
} while (0)
#else
#define D(x...)
#define I(x...)
#define W(x...)
#define E(x...)
#define DIF(x...)
#endif
#if defined(CONFIG_HMX_DB)
/* Analog voltage @2.7 V */
#define HX_VTG_MIN_UV 2700000
#define HX_VTG_MAX_UV 3300000
#define HX_ACTIVE_LOAD_UA 15000
#define HX_LPM_LOAD_UA 10
/* Digital voltage @1.8 V */
#define HX_VTG_DIG_MIN_UV 1800000
#define HX_VTG_DIG_MAX_UV 1800000
#define HX_ACTIVE_LOAD_DIG_UA 10000
#define HX_LPM_LOAD_DIG_UA 10
#define HX_I2C_VTG_MIN_UV 1800000
#define HX_I2C_VTG_MAX_UV 1800000
#define HX_I2C_LOAD_UA 10000
#define HX_I2C_LPM_LOAD_UA 10
#endif
#define HIMAX_common_NAME "himax_tp"
#define HIMAX_I2C_ADDR 0x48
#define INPUT_DEV_NAME "himax-touchscreen"
struct himax_i2c_platform_data {
int abs_x_min;
int abs_x_max;
int abs_x_fuzz;
int abs_y_min;
int abs_y_max;
int abs_y_fuzz;
int abs_pressure_min;
int abs_pressure_max;
int abs_pressure_fuzz;
int abs_width_min;
int abs_width_max;
int screenWidth;
int screenHeight;
uint8_t fw_version;
uint8_t tw_id;
uint8_t powerOff3V3;
uint8_t cable_config[2];
uint8_t protocol_type;
int gpio_irq;
int gpio_reset;
int gpio_3v3_en;
int gpio_pon;
int (*power)(int on);
void (*reset)(void);
struct himax_virtual_key *virtual_key;
struct kobject *vk_obj;
struct kobj_attribute *vk2Use;
int hx_config_size;
#if defined(CONFIG_HMX_DB)
bool i2c_pull_up;
bool digital_pwr_regulator;
int reset_gpio;
u32 reset_gpio_flags;
int irq_gpio;
u32 irq_gpio_flags;
struct regulator *vcc_ana; /* For Dragon Board */
struct regulator *vcc_dig; /* For Dragon Board */
struct regulator *vcc_i2c; /* For Dragon Board */
#endif
};
extern int irq_enable_count;
extern int himax_bus_read(uint8_t command, uint8_t *data, uint32_t length, uint8_t toRetry);
extern int himax_bus_write(uint8_t command, uint8_t *data, uint32_t length, uint8_t toRetry);
extern int himax_bus_write_command(uint8_t command, uint8_t toRetry);
extern int himax_bus_master_write(uint8_t *data, uint32_t length, uint8_t toRetry);
extern void himax_int_enable(int enable);
extern int himax_ts_register_interrupt(void);
int himax_ts_unregister_interrupt(void);
extern uint8_t himax_int_gpio_read(int pinnum);
extern int himax_gpio_power_config(struct himax_i2c_platform_data *pdata);
void himax_gpio_power_deconfig(struct himax_i2c_platform_data *pdata);
#if defined(CONFIG_FB)
extern int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data);
#endif
extern void himax_ts_work(struct himax_ts_data *ts);
extern enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer);
extern int himax_chip_common_init(void);
extern void himax_chip_common_deinit(void);
#endif

View file

@ -0,0 +1,143 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Himax Android Driver Sample Code for QCT platform
*
* Copyright (C) 2019 Himax Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef HIMAX_PLATFORM_H
#define HIMAX_PLATFORM_H
#include <linux/delay.h>
#include <linux/fs.h>
#include <linux/gpio.h>
#include <linux/types.h>
#include <linux/spi/spi.h>
#include <linux/interrupt.h>
#if defined(CONFIG_HMX_DB)
#include <linux/regulator/consumer.h>
#endif
#define HIMAX_I2C_RETRY_TIMES 3
#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
#define D(x...) pr_debug("[HXTP] " x)
#define I(x...) pr_info("[HXTP] " x)
#define W(x...) pr_warn("[HXTP][WARNING] " x)
#define E(x...) pr_err("[HXTP][ERROR] " x)
#define DIF(x...) \
do { \
if (debug_flag) \
pr_debug("[HXTP][DEBUG] " x) \
} while (0)
#else
#define D(x...)
#define I(x...)
#define W(x...)
#define E(x...)
#define DIF(x...)
#endif
#if defined(CONFIG_HMX_DB)
/* Analog voltage @2.7 V */
#define HX_VTG_MIN_UV 2700000
#define HX_VTG_MAX_UV 3300000
#define HX_ACTIVE_LOAD_UA 15000
#define HX_LPM_LOAD_UA 10
/* Digital voltage @1.8 V */
#define HX_VTG_DIG_MIN_UV 1800000
#define HX_VTG_DIG_MAX_UV 1800000
#define HX_ACTIVE_LOAD_DIG_UA 10000
#define HX_LPM_LOAD_DIG_UA 10
#define HX_I2C_VTG_MIN_UV 1800000
#define HX_I2C_VTG_MAX_UV 1800000
#define HX_I2C_LOAD_UA 10000
#define HX_I2C_LPM_LOAD_UA 10
#endif
#define HIMAX_common_NAME "himax_tp"
#define HIMAX_I2C_ADDR 0x48
#define INPUT_DEV_NAME "himax-touchscreen"
#define PACKET_MAX_SZ 4096
#define GBUFFER_SZ PACKET_MAX_SZ - 2
struct himax_i2c_platform_data {
int abs_x_min;
int abs_x_max;
int abs_x_fuzz;
int abs_y_min;
int abs_y_max;
int abs_y_fuzz;
int abs_pressure_min;
int abs_pressure_max;
int abs_pressure_fuzz;
int abs_width_min;
int abs_width_max;
int screenWidth;
int screenHeight;
uint8_t fw_version;
uint8_t tw_id;
uint8_t powerOff3V3;
uint8_t cable_config[2];
uint8_t protocol_type;
int gpio_irq;
int gpio_reset;
int gpio_3v3_en;
char panel_supplier[16];
int (*power)(int on);
void (*reset)(void);
struct himax_virtual_key *virtual_key;
struct kobject *vk_obj;
struct kobj_attribute *vk2Use;
int hx_config_size;
#if defined(CONFIG_HMX_DB)
bool i2c_pull_up;
bool digital_pwr_regulator;
int reset_gpio;
u32 reset_gpio_flags;
int irq_gpio;
u32 irq_gpio_flags;
struct regulator *vcc_ana; /* For Dragon Board */
struct regulator *vcc_dig; /* For Dragon Board */
struct regulator *vcc_i2c; /* For Dragon Board */
#endif
};
extern struct himax_ic_data *ic_data;
extern struct himax_ts_data *private_ts;
int himax_chip_common_init(void);
void himax_chip_common_deinit(void);
void himax_ts_work(struct himax_ts_data *ts);
enum hrtimer_restart himax_ts_timer_func(struct hrtimer *timer);
extern int irq_enable_count;
extern int himax_bus_read(uint8_t command, uint8_t *data, uint32_t length, uint8_t toRetry);
extern int himax_bus_write(uint8_t command, uint8_t *data, uint32_t length, uint8_t toRetry);
extern int himax_bus_write_command(uint8_t command, uint8_t toRetry);
extern int himax_bus_master_write(uint8_t *data, uint32_t length, uint8_t toRetry);
extern void himax_int_enable(int enable);
extern int himax_ts_register_interrupt(void);
int himax_ts_unregister_interrupt(void);
extern uint8_t himax_int_gpio_read(int pinnum);
extern int himax_gpio_power_config(struct himax_i2c_platform_data *pdata);
void himax_gpio_power_deconfig(struct himax_i2c_platform_data *pdata);
#if defined(CONFIG_DRM)
extern int drm_notifier_callback(struct notifier_block *self, unsigned long event, void *data);
#elif defined(CONFIG_FB)
extern int fb_notifier_callback(struct notifier_block *self, unsigned long event, void *data);
#endif
#endif

View file

@ -0,0 +1,275 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Himax Android Driver Sample Code for modularize functions
*
* Copyright (C) 2019 Himax Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef __HIMAX_MODULAR_H__
#define __HIMAX_MODULAR_H__
#include "himax_modular_table.h"
static bool (*this_detect_fp)(void);
static void himax_add_chip_dt(bool (*detect_fp)(void))
{
int32_t idx;
struct himax_chip_entry *entry;
this_detect_fp = detect_fp;
idx = himax_get_ksym_idx();
if (idx < 0) {
/*TODO: No entry, handle this error*/
E("%s: no entry exist, please insert ic module first!", __func__);
} else {
entry = (void *)kallsyms_lookup_name(himax_ksym_lookup[idx]);
if (/*!(entry->core_chip_dt)*/isEmpty(idx) == 1) {
entry->core_chip_dt = kcalloc(HX_DRIVER_MAX_IC_NUM,
sizeof(struct himax_chip_detect), GFP_KERNEL);
entry->hx_ic_dt_num = 0;
}
entry->core_chip_dt[entry->hx_ic_dt_num++].fp_chip_detect = detect_fp;
}
}
static void free_chip_dt_table(void)
{
int i, j, idx;
struct himax_chip_entry *entry;
idx = himax_get_ksym_idx();
if (idx >= 0) {
if (isEmpty(idx) != 0) {
I("%s: no chip registered or entry has been clean up, leave safetly.\n",
__func__);
return;
}
entry = get_chip_entry_by_index(idx);
for (i = 0; i < entry->hx_ic_dt_num; i++) {
if (entry->core_chip_dt[i].fp_chip_detect == this_detect_fp) {
if (i == (entry->hx_ic_dt_num - 1)) {
entry->core_chip_dt[i].fp_chip_detect = NULL;
entry->hx_ic_dt_num = 0;
} else {
for (j = i; j < entry->hx_ic_dt_num; j++)
entry->core_chip_dt[i].fp_chip_detect = entry->core_chip_dt[j].fp_chip_detect;
entry->core_chip_dt[j].fp_chip_detect = NULL;
entry->hx_ic_dt_num--;
}
}
}
if (entry->hx_ic_dt_num == 0) {
kfree(entry->core_chip_dt);
entry->core_chip_dt = NULL;
}
}
}
#define setup_symbol(sym) ({kp_##sym = (void *)kallsyms_lookup_name(#sym); kp_##sym; })
#define assert_on_symbol(sym) do { \
if (!setup_symbol(sym)) { \
E("%s: setup %s failed!\n", __func__, #sym); \
ret = -1; \
} \
} while (0)
#if !defined(__HIMAX_HX852xH_MOD__) && !defined(__HIMAX_HX852xG_MOD__)
static struct fw_operation **kp_pfw_op;
static struct ic_operation **kp_pic_op;
static struct driver_operation **kp_pdriver_op;
#endif
static struct himax_chip_detect **kp_g_core_chip_dt;
#if defined(HX_ZERO_FLASH)
static struct zf_operation **kp_pzf_op;
static int *kp_G_POWERONOF;
#endif
#if defined(HX_AUTO_UPDATE_FW) || defined(HX_ZERO_FLASH)
#if defined(HX_EN_DYNAMIC_NAME)
static char **kp_i_CTPM_firmware_name;
#endif
#endif
static unsigned char *kp_IC_CHECKSUM;
#ifdef HX_ESD_RECOVERY
static u8 *kp_HX_ESD_RESET_ACTIVATE;
#endif
#if defined(HX_ZERO_FLASH) && defined(HX_CODE_OVERLAY)
#if defined(CONFIG_TOUCHSCREEN_HIMAX_INCELL)
extern uint8_t *ovl_idx;
static uint8_t **kp_ovl_idx;
#endif
#endif
static unsigned long *kp_FW_VER_MAJ_FLASH_ADDR;
static unsigned long *kp_FW_VER_MIN_FLASH_ADDR;
static unsigned long *kp_CFG_VER_MAJ_FLASH_ADDR;
static unsigned long *kp_CFG_VER_MIN_FLASH_ADDR;
static unsigned long *kp_CID_VER_MAJ_FLASH_ADDR;
static unsigned long *kp_CID_VER_MIN_FLASH_ADDR;
static unsigned long *kp_FW_VER_MAJ_FLASH_LENG;
static unsigned long *kp_FW_VER_MIN_FLASH_LENG;
static unsigned long *kp_CFG_VER_MAJ_FLASH_LENG;
static unsigned long *kp_CFG_VER_MIN_FLASH_LENG;
static unsigned long *kp_CID_VER_MAJ_FLASH_LENG;
static unsigned long *kp_CID_VER_MIN_FLASH_LENG;
#ifdef HX_AUTO_UPDATE_FW
static int *kp_g_i_FW_VER;
static int *kp_g_i_CFG_VER;
static int *kp_g_i_CID_MAJ;
static int *kp_g_i_CID_MIN;
static unsigned char **kp_i_CTPM_FW;
#endif
#ifdef HX_TP_PROC_2T2R
static bool *kp_Is_2T2R;
#endif
#ifdef HX_USB_DETECT_GLOBAL
static void (*kp_himax_cable_detect_func)(bool force_renew);
#endif
#ifdef HX_RST_PIN_FUNC
static void (*kp_himax_rst_gpio_set)(int pinnum, uint8_t value);
#endif
static struct himax_ts_data **kp_private_ts;
static struct himax_core_fp *kp_g_core_fp;
static struct himax_ic_data **kp_ic_data;
#if defined(__HIMAX_HX852xH_MOD__) || defined(__HIMAX_HX852xG_MOD__)
#if defined(__HIMAX_HX852xG_MOD__)
static struct on_driver_operation **kp_on_pdriver_op;
#endif
static void (*kp_himax_mcu_on_cmd_init)(void);
static int (*kp_himax_mcu_on_cmd_struct_init)(void);
static void (*kp_himax_on_parse_assign_cmd)(uint32_t addr, uint8_t *cmd, int len);
#else
static void (*kp_himax_mcu_in_cmd_init)(void);
static int (*kp_himax_mcu_in_cmd_struct_init)(void);
static void (*kp_himax_in_parse_assign_cmd)(uint32_t addr, uint8_t *cmd, int len);
#endif
static int *kp_irq_enable_count;
static int (*kp_himax_bus_read)(uint8_t command, uint8_t *data, uint32_t length, uint8_t toRetry);
static int (*kp_himax_bus_write)(uint8_t command, uint8_t *data, uint32_t length, uint8_t toRetry);
static int (*kp_himax_bus_write_command)(uint8_t command, uint8_t toRetry);
static int (*kp_himax_bus_master_write)(uint8_t *data, uint32_t length, uint8_t toRetry);
static void (*kp_himax_int_enable)(int enable);
static int (*kp_himax_ts_register_interrupt)(void);
static uint8_t (*kp_himax_int_gpio_read)(int pinnum);
static int (*kp_himax_gpio_power_config)(struct himax_i2c_platform_data *pdata);
static int32_t himax_ic_setup_external_symbols(void)
{
int32_t ret = 0;
#if !defined(__HIMAX_HX852xH_MOD__) && !defined(__HIMAX_HX852xG_MOD__)
assert_on_symbol(pfw_op);
assert_on_symbol(pic_op);
assert_on_symbol(pdriver_op);
#endif
assert_on_symbol(g_core_chip_dt);
assert_on_symbol(private_ts);
assert_on_symbol(g_core_fp);
assert_on_symbol(ic_data);
#if defined(__HIMAX_HX852xH_MOD__) || defined(__HIMAX_HX852xG_MOD__)
#if defined(__HIMAX_HX852xG_MOD__)
assert_on_symbol(on_pdriver_op);
#endif
assert_on_symbol(himax_mcu_on_cmd_init);
assert_on_symbol(himax_mcu_on_cmd_struct_init);
assert_on_symbol(himax_on_parse_assign_cmd);
#else
assert_on_symbol(himax_mcu_in_cmd_init);
assert_on_symbol(himax_mcu_in_cmd_struct_init);
assert_on_symbol(himax_in_parse_assign_cmd);
#endif
assert_on_symbol(irq_enable_count);
assert_on_symbol(himax_bus_read);
assert_on_symbol(himax_bus_write);
assert_on_symbol(himax_bus_write_command);
assert_on_symbol(himax_bus_master_write);
assert_on_symbol(himax_int_enable);
assert_on_symbol(himax_ts_register_interrupt);
assert_on_symbol(himax_int_gpio_read);
assert_on_symbol(himax_gpio_power_config);
#if defined(HX_ZERO_FLASH)
assert_on_symbol(pzf_op);
assert_on_symbol(G_POWERONOF);
#endif
#if defined(HX_AUTO_UPDATE_FW) || defined(HX_ZERO_FLASH)
#if defined(HX_EN_DYNAMIC_NAME)
assert_on_symbol(i_CTPM_firmware_name);
#endif
#endif
assert_on_symbol(IC_CHECKSUM);
assert_on_symbol(FW_VER_MAJ_FLASH_ADDR);
assert_on_symbol(FW_VER_MIN_FLASH_ADDR);
assert_on_symbol(CFG_VER_MAJ_FLASH_ADDR);
assert_on_symbol(CFG_VER_MIN_FLASH_ADDR);
assert_on_symbol(CID_VER_MAJ_FLASH_ADDR);
assert_on_symbol(CID_VER_MIN_FLASH_ADDR);
assert_on_symbol(FW_VER_MAJ_FLASH_LENG);
assert_on_symbol(FW_VER_MIN_FLASH_LENG);
assert_on_symbol(CFG_VER_MAJ_FLASH_LENG);
assert_on_symbol(CFG_VER_MIN_FLASH_LENG);
assert_on_symbol(CID_VER_MAJ_FLASH_LENG);
assert_on_symbol(CID_VER_MIN_FLASH_LENG);
#ifdef HX_AUTO_UPDATE_FW
assert_on_symbol(g_i_FW_VER);
assert_on_symbol(g_i_CFG_VER);
assert_on_symbol(g_i_CID_MAJ);
assert_on_symbol(g_i_CID_MIN);
assert_on_symbol(i_CTPM_FW);
#endif
#ifdef HX_TP_PROC_2T2R
assert_on_symbol(Is_2T2R);
#endif
#ifdef HX_USB_DETECT_GLOBAL
assert_on_symbol(himax_cable_detect_func);
#endif
#ifdef HX_RST_PIN_FUNC
assert_on_symbol(himax_rst_gpio_set);
#endif
#ifdef HX_ESD_RECOVERY
assert_on_symbol(HX_ESD_RESET_ACTIVATE);
#endif
#if defined(HX_ZERO_FLASH) && defined(HX_CODE_OVERLAY)
#if defined(CONFIG_TOUCHSCREEN_HIMAX_INCELL)
assert_on_symbol(ovl_idx);
#endif
#endif
return ret;
}
#endif

View file

@ -1,58 +0,0 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Himax Android Driver Sample Code for HX83102 chipset
*
* Copyright (C) 2019 Himax Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "himax_platform.h"
#include "himax_common.h"
#include "himax_ic_core.h"
#include <linux/slab.h>
#define hx83102ab_fw_addr_sorting_mode_en 0x100007FC
#define hx83102ab_fw_addr_selftest_addr_en 0x100007F8
#define hx83102ab_data_adc_cfg_1 0x10007B00
#define hx83102a_data_df_rx 48
#define hx83102a_data_df_tx 24
#define hx83102a_data_df_x_res 2160
#define hx83102a_data_df_y_res 3840
#define hx83102a_data_adc_num 100
#define hx83102b_data_df_x_res 720
#define hx83102b_data_df_y_res 1280
#define hx83102b_data_adc_num 64
#define hx83102d_fw_addr_raw_out_sel 0x800204f4
#define hx83102d_zf_data_adc_cfg_1 0x10007B00
#define hx83102d_zf_data_adc_cfg_2 0x10006A00
#define hx83102d_zf_data_adc_cfg_3 0x10007500
#define hx83102d_zf_data_bor_prevent_info 0x10007268
#define hx83102d_zf_data_notch_info 0x10007300
#define hx83102d_zf_func_info_en 0x10007FD0
#define hx83102d_zf_po_sub_func 0x10005A00
#define hx83102d_zf_data_sram_start_addr 0x20000000
#define hx83102d_data_df_x_res 720
#define hx83102d_data_df_y_res 1280
#define hx83102d_adr_osc_en 0x9000009C
#define hx83102d_adr_osc_pw 0x90000280
#define hx83102d_data_adc_num 48
#define hx83102e_fw_addr_raw_out_sel 0x100072EC
#define hx83102e_ic_adr_tcon_rst 0x80020004
#define hx83102e_data_df_rx 48
#define hx83102e_data_df_tx 30
#define hx83102e_data_df_x_res 1200
#define hx83102e_data_df_y_res 1920
#define hx83102e_data_adc_num 100
#if defined(HX_ESD_RECOVERY)
extern u8 HX_ESD_RESET_ACTIVATE;
#endif

View file

@ -7,10 +7,10 @@ else
HIMAX_MMI_IC_MODULE_PATH := $(KERNEL_MODULES_OUT)
endif
KERNEL_CFLAGS += CONFIG_INPUT_HIMAX_V3_MMI_IC_NAME=hx83102
KERNEL_CFLAGS += CONFIG_INPUT_HIMAX_V2_MMI_IC_NAME_D=hx83102d
include $(CLEAR_VARS)
LOCAL_MODULE := himax_v3_mmi_hx83102.ko
LOCAL_MODULE := himax_v3_mmi_hx83102d.ko
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE_PATH := $(HIMAX_MMI_IC_MODULE_PATH)
LOCAL_REQUIRED_MODULES := himax_v3_mmi.ko

View file

@ -3,15 +3,18 @@ EXTRA_CFLAGS += -Wall
EXTRA_CFLAGS += -I$(TOP)/motorola/kernel/modules/include \
-I$(TOP)/motorola/kernel/modules/drivers/input/touchscreen/himax_v3_mmi \
-I$(TOP)/motorola/kernel/modules/drivers/input/touchscreen/himax_v3_mmi/support_ic \
-I$(TOP)/motorola/kernel/modules/drivers/input/touchscreen/himax_v3_mmi/support_ic/himax_v3_mmi_hx83102
-I$(TOP)/motorola/kernel/modules/drivers/input/touchscreen/himax_v3_mmi/support_ic/himax_v3_mmi_hx83102d
EXTRA_CFLAGS += -DCONFIG_TOUCHSCREEN_HIMAX_DEBUG \
-DCONFIG_TOUCHSCREEN_HIMAX_INSPECT
EXTRA_CFLAGS += -DCONFIG_TOUCHSCREEN_HIMAX_INCELL
EXTRA_CFLAGS += -DCONFIG_HMX_DB
ifneq ($(filter hx83102,$(CONFIG_INPUT_HIMAX_V3_MMI_IC_NAME)),)
EXTRA_CFLAGS += -D__HIMAX_HX83102_MOD__
ifneq ($(filter hx83102d,$(CONFIG_INPUT_HIMAX_V2_MMI_IC_NAME_D)),)
EXTRA_CFLAGS += -D__HIMAX_HX83102D_MOD__
EXTRA_CFLAGS += -DHX_ZERO_FLASH
EXTRA_CFLAGS += -DHX_CODE_OVERLAY
endif
obj-m := himax_v3_mmi_hx83102.o
himax_v3_mmi_hx83102-objs += himax_ic_HX83102.o
obj-m := himax_v3_mmi_hx83102d.o
himax_v3_mmi_hx83102d-objs += himax_ic_HX83102d.o

View file

@ -0,0 +1,65 @@
/* SPDX-License-Identifier: GPL-2.0 */
/* Himax Android Driver Sample Code for HX83102 chipset
*
* Copyright (C) 2019 Himax Corporation.
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#include "himax_platform.h"
#include "himax_common.h"
#include "himax_ic_core.h"
#include <linux/slab.h>
#define hx83102ab_fw_addr_sorting_mode_en 0x100007FC
#define hx83102ab_fw_addr_selftest_addr_en 0x100007F8
#define hx83102ab_data_adc_cfg_1 0x10007B00
#define hx83102a_data_df_rx 48
#define hx83102a_data_df_tx 24
#define hx83102a_data_df_x_res 2160
#define hx83102a_data_df_y_res 3840
#define hx83102b_data_df_x_res 720
#define hx83102b_data_df_y_res 1280
#define hx83102d_fw_addr_raw_out_sel 0x800204f4
#define hx83102d_zf_data_adc_cfg_1 0x10007B00
#define hx83102d_zf_data_adc_cfg_2 0x10006A00
#define hx83102d_zf_data_adc_cfg_3 0x10007500
#define hx83102d_zf_data_bor_prevent_info 0x10007268
#define hx83102d_zf_data_notch_info 0x10007300
#define hx83102d_zf_func_info_en 0x10007FD0
#define hx83102d_zf_po_sub_func 0x10005A00
#define hx83102d_zf_data_sram_start_addr 0x20000000
#define hx83102d_data_df_x_res 720
#define hx83102d_data_df_y_res 1280
#define hx83102d_adr_osc_en 0x9000009C
#define hx83102d_adr_osc_pw 0x90000280
#define hx83102e_fw_addr_raw_out_sel 0x100072EC
#define hx83102e_data_df_rx 48
#define hx83102e_data_df_tx 30
#define hx83102e_data_df_x_res 1200
#define hx83102e_data_df_y_res 1920
#if defined(HX_AUTO_UPDATE_FW) || defined(HX_ZERO_FLASH)
#ifdef HX_EN_DYNAMIC_NAME
#define hx83102_ic_b9_en 0x300B9000
#define hx83102_ic_fw 0x300E8006
#define hx83102b_ic_osc_en 0x900880A0
#define hx83102d_ic_osc_en 0x9000009C
#define hx83102d_ic_osc_pw 0x90000280
#endif
#endif
#ifdef HX_ESD_RECOVERY
extern u8 HX_ESD_RESET_ACTIVATE;
#endif