blob: 1093f6cbf8e4cff63dd7d934cba9e7353c9217af [file] [log] [blame]
/* Himax Android Driver Sample Code for HMX852xES chipset
*
* Copyright (C) 2014 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 HIMAX852xES_H
#define HIMAX852xES_H
#include <asm/segment.h>
#include <asm/uaccess.h>
#include <asm/atomic.h>
#include <linux/delay.h>
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/interrupt.h>
#include <linux/module.h>
#include <linux/async.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/input/mt.h>
#include <linux/firmware.h>
#include <linux/types.h>
#include <linux/fs.h>
#include <linux/buffer_head.h>
#include <linux/wakelock.h>
#include <linux/seq_file.h>
#include <linux/proc_fs.h>
#include "himax_platform.h"
#include <linux/asusevtlog.h>
#ifdef CONFIG_FB
#include <linux/notifier.h>
#include <linux/fb.h>
#endif
#ifdef CONFIG_OF
#include <linux/of_gpio.h>
#endif
#define HIMAX_DRIVER_VER "0.1.8.0"
#define HIMAX852xes_NAME "Himax852xes"
#define HIMAX852xes_FINGER_SUPPORT_NUM 10
#define HIMAX_I2C_ADDR 0x48
#define INPUT_DEV_NAME "HX852XES"
#define FLASH_DUMP_FILE "/data/user/Flash_Dump.bin"
#define DIAG_COORDINATE_FILE "/sdcard/Coordinate_Dump.csv"
#define D(x...) pr_notice("[HXTP] " x)
#define I(x...) pr_info("[HXTP] " x)
#define W(x...) pr_warning("[HXTP][WARNING] " x)
#define E(x...) pr_err("[HXTP][ERROR] " x)
#define DIF(x...) \
if (debug_flag) \
printk("[HXTP][DEBUG] " x) \
} while(0)
#ifdef CONFIG_TOUCHSCREEN_HIMAX_DEBUG
#define HX_TP_PROC_DIAG
#define HX_TP_PROC_RESET
#define HX_TP_PROC_REGISTER
#define HX_TP_PROC_DEBUG
#define HX_TP_PROC_FLASH_DUMP
#define HX_TP_PROC_SELF_TEST
#define HX_TP_PROC_HITOUCH
#define HX_TP_PROC_2T2R //if enable, Need to check "HX_2T2R_Addr"
//and "HX_2T2R_en_setting" with project FW eng.
#endif
//===========Himax Option function=============
#define HX_RST_PIN_FUNC
//#define HX_LOADIN_CONFIG
#define HX_AUTO_UPDATE_FW
//#define HX_AUTO_UPDATE_CONFIG //if enable HX_AUTO_UPDATE_CONFIG, need to disable HX_LOADIN_CONFIG
#define HX_SMART_WAKEUP
#define HX_PALM_REPORT
#define HX_CHECK_CRC_AP
#define HX_TIME_TELLING
//#define HX_ESD_WORKAROUND
//#define HX_CHIP_STATUS_MONITOR //for ESD 2nd solution,default off
#define HX_85XX_A_SERIES_PWON 1
#define HX_85XX_B_SERIES_PWON 2
#define HX_85XX_C_SERIES_PWON 3
#define HX_85XX_D_SERIES_PWON 4
#define HX_85XX_E_SERIES_PWON 5
#define HX_85XX_ES_SERIES_PWON 6
#define HX_TP_BIN_CHECKSUM_SW 1
#define HX_TP_BIN_CHECKSUM_HW 2
#define HX_TP_BIN_CHECKSUM_CRC 3
#define HX_KEY_MAX_COUNT 4
#define DEFAULT_RETRY_CNT 10
#define HX_VKEY_0 KEY_BACK
#define HX_VKEY_1 KEY_HOME
#define HX_VKEY_2 KEY_RESERVED
#define HX_VKEY_3 KEY_RESERVED
#define HX_KEY_ARRAY {HX_VKEY_0, HX_VKEY_1, HX_VKEY_2, HX_VKEY_3}
#define SHIFTBITS 5
#define FLASH_SIZE 32768
struct himax_virtual_key {
int index;
int keycode;
int x_range_min;
int x_range_max;
int y_range_min;
int y_range_max;
};
struct himax_config {
uint8_t default_cfg;
uint8_t sensor_id;
uint8_t fw_ver_main;
uint8_t fw_ver_minor;
uint16_t length;
uint32_t tw_x_min;
uint32_t tw_x_max;
uint32_t tw_y_min;
uint32_t tw_y_max;
uint32_t pl_x_min;
uint32_t pl_x_max;
uint32_t pl_y_min;
uint32_t pl_y_max;
uint8_t c1[11];
uint8_t c2[11];
uint8_t c3[11];
uint8_t c4[11];
uint8_t c5[11];
uint8_t c6[11];
uint8_t c7[11];
uint8_t c8[11];
uint8_t c9[11];
uint8_t c10[11];
uint8_t c11[11];
uint8_t c12[11];
uint8_t c13[11];
uint8_t c14[11];
uint8_t c15[11];
uint8_t c16[11];
uint8_t c17[11];
uint8_t c18[17];
uint8_t c19[15];
uint8_t c20[5];
uint8_t c21[11];
uint8_t c22[4];
uint8_t c23[3];
uint8_t c24[3];
uint8_t c25[4];
uint8_t c26[2];
uint8_t c27[2];
uint8_t c28[2];
uint8_t c29[2];
uint8_t c30[2];
uint8_t c31[2];
uint8_t c32[2];
uint8_t c33[2];
uint8_t c34[2];
uint8_t c35[3];
uint8_t c36[5];
uint8_t c37[5];
uint8_t c38[9];
uint8_t c39[14];
uint8_t c40[159];
uint8_t c41[99];
};
struct himax_ts_data {
bool suspended;
bool resumed;
atomic_t suspend_mode;
uint8_t x_channel;
uint8_t y_channel;
uint8_t useScreenRes;
uint8_t diag_command;
uint8_t vendor_fw_ver_H;
uint8_t vendor_fw_ver_L;
uint8_t vendor_config_ver;
uint8_t vendor_sensor_id;
uint8_t protocol_type;
uint8_t first_pressed;
uint8_t coord_data_size;
uint8_t area_data_size;
uint8_t raw_data_frame_size;
uint8_t raw_data_nframes;
uint8_t nFinger_support;
uint8_t irq_enabled;
uint8_t diag_self[50];
uint16_t finger_pressed;
uint16_t last_slot;
uint16_t pre_finger_mask;
uint32_t debug_log_level;
uint32_t widthFactor;
uint32_t heightFactor;
uint32_t tw_x_min;
uint32_t tw_x_max;
uint32_t tw_y_min;
uint32_t tw_y_max;
uint32_t pl_x_min;
uint32_t pl_x_max;
uint32_t pl_y_min;
uint32_t pl_y_max;
int use_irq;
int (*power)(int on);
int pre_finger_data[10][2];
struct device *dev;
struct workqueue_struct *himax_wq;
struct work_struct work;
struct input_dev *input_dev;
struct hrtimer timer;
struct i2c_client *client;
struct himax_i2c_platform_data *pdata;
struct himax_virtual_key *button;
struct wake_lock ts_flash_wake_lock;
#ifdef CONFIG_FB
struct notifier_block fb_notif;
struct workqueue_struct *himax_att_wq;
struct delayed_work work_att;
#endif
#ifdef HX_CHIP_STATUS_MONITOR
struct workqueue_struct *himax_chip_monitor_wq;
struct delayed_work himax_chip_monitor;
#endif
#ifdef HX_TP_PROC_FLASH_DUMP
struct workqueue_struct *flash_wq;
struct work_struct flash_work;
#endif
#ifdef HX_RST_PIN_FUNC
int rst_gpio;
#endif
#ifdef HX_SMART_WAKEUP
uint8_t SMWP_enable;
struct wake_lock ts_SMWP_wake_lock;
#endif
#ifdef HX_TIME_TELLING
int sleepmode;
int timetellmode;
struct workqueue_struct *himax_sleepmode_wq;
struct work_struct sleepmode_work;
#endif
const struct firmware *fw;
u8 *fw_data_start;
uint32_t fw_size;
};
static struct himax_ts_data *private_ts;
#define HX_CMD_NOP 0x00
#define HX_CMD_SETMICROOFF 0x35
#define HX_CMD_SETROMRDY 0x36
#define HX_CMD_TSSLPIN 0x80
#define HX_CMD_TSSLPOUT 0x81
#define HX_CMD_TSSOFF 0x82
#define HX_CMD_TSSON 0x83
#define HX_CMD_ROE 0x85
#define HX_CMD_RAE 0x86
#define HX_CMD_RLE 0x87
#define HX_CMD_CLRES 0x88
#define HX_CMD_TSSWRESET 0x9E
#define HX_CMD_SETDEEPSTB 0xD7
#define HX_CMD_SET_CACHE_FUN 0xDD
#define HX_CMD_SETIDLE 0xF2
#define HX_CMD_SETIDLEDELAY 0xF3
#define HX_CMD_SELFTEST_BUFFER 0x8D
#define HX_CMD_MANUALMODE 0x42
#define HX_CMD_FLASH_ENABLE 0x43
#define HX_CMD_FLASH_SET_ADDRESS 0x44
#define HX_CMD_FLASH_WRITE_REGISTER 0x45
#define HX_CMD_FLASH_SET_COMMAND 0x47
#define HX_CMD_FLASH_WRITE_BUFFER 0x48
#define HX_CMD_FLASH_PAGE_ERASE 0x4D
#define HX_CMD_FLASH_SECTOR_ERASE 0x4E
#define HX_CMD_CB 0xCB
#define HX_CMD_EA 0xEA
#define HX_CMD_4A 0x4A
#define HX_CMD_4F 0x4F
#define HX_CMD_B9 0xB9
#define HX_CMD_76 0x76
#define HX_VER_FW_MAJ 0x33
#define HX_VER_FW_MIN 0x32
#define HX_VER_FW_CFG 0x39
enum input_protocol_type {
PROTOCOL_TYPE_A = 0x00,
PROTOCOL_TYPE_B = 0x01,
};
//1uA
static unsigned char E_IrefTable_1[16][2] = { {0x20,0x0F},{0x20,0x1F},{0x20,0x2F},{0x20,0x3F},
{0x20,0x4F},{0x20,0x5F},{0x20,0x6F},{0x20,0x7F},
{0x20,0x8F},{0x20,0x9F},{0x20,0xAF},{0x20,0xBF},
{0x20,0xCF},{0x20,0xDF},{0x20,0xEF},{0x20,0xFF}};
//2uA
static unsigned char E_IrefTable_2[16][2] = { {0xA0,0x0E},{0xA0,0x1E},{0xA0,0x2E},{0xA0,0x3E},
{0xA0,0x4E},{0xA0,0x5E},{0xA0,0x6E},{0xA0,0x7E},
{0xA0,0x8E},{0xA0,0x9E},{0xA0,0xAE},{0xA0,0xBE},
{0xA0,0xCE},{0xA0,0xDE},{0xA0,0xEE},{0xA0,0xFE}};
//3uA
static unsigned char E_IrefTable_3[16][2] = { {0x20,0x0E},{0x20,0x1E},{0x20,0x2E},{0x20,0x3E},
{0x20,0x4E},{0x20,0x5E},{0x20,0x6E},{0x20,0x7E},
{0x20,0x8E},{0x20,0x9E},{0x20,0xAE},{0x20,0xBE},
{0x20,0xCE},{0x20,0xDE},{0x20,0xEE},{0x20,0xFE}};
//4uA
static unsigned char E_IrefTable_4[16][2] = { {0xA0,0x0D},{0xA0,0x1D},{0xA0,0x2D},{0xA0,0x3D},
{0xA0,0x4D},{0xA0,0x5D},{0xA0,0x6D},{0xA0,0x7D},
{0xA0,0x8D},{0xA0,0x9D},{0xA0,0xAD},{0xA0,0xBD},
{0xA0,0xCD},{0xA0,0xDD},{0xA0,0xED},{0xA0,0xFD}};
//5uA
static unsigned char E_IrefTable_5[16][2] = { {0x20,0x0D},{0x20,0x1D},{0x20,0x2D},{0x20,0x3D},
{0x20,0x4D},{0x20,0x5D},{0x20,0x6D},{0x20,0x7D},
{0x20,0x8D},{0x20,0x9D},{0x20,0xAD},{0x20,0xBD},
{0x20,0xCD},{0x20,0xDD},{0x20,0xED},{0x20,0xFD}};
//6uA
static unsigned char E_IrefTable_6[16][2] = { {0xA0,0x0C},{0xA0,0x1C},{0xA0,0x2C},{0xA0,0x3C},
{0xA0,0x4C},{0xA0,0x5C},{0xA0,0x6C},{0xA0,0x7C},
{0xA0,0x8C},{0xA0,0x9C},{0xA0,0xAC},{0xA0,0xBC},
{0xA0,0xCC},{0xA0,0xDC},{0xA0,0xEC},{0xA0,0xFC}};
//7uA
static unsigned char E_IrefTable_7[16][2] = { {0x20,0x0C},{0x20,0x1C},{0x20,0x2C},{0x20,0x3C},
{0x20,0x4C},{0x20,0x5C},{0x20,0x6C},{0x20,0x7C},
{0x20,0x8C},{0x20,0x9C},{0x20,0xAC},{0x20,0xBC},
{0x20,0xCC},{0x20,0xDC},{0x20,0xEC},{0x20,0xFC}};
static u8 HW_RESET_ACTIVATE = 1;
#if defined(CONFIG_TOUCHSCREEN_HIMAX_DEBUG)
static uint8_t HX_PROC_SEND_FLAG;
#ifdef HX_TP_PROC_DIAG
#define HIMAX_PROC_TOUCH_FOLDER "himax_touch"
static struct proc_dir_entry *himax_touch_proc_dir = NULL;
#define HIMAX_PROC_DIAG_FILE "diag"
static struct proc_dir_entry *himax_proc_diag_file = NULL;
static int touch_monitor_stop_flag = 0;
static int touch_monitor_stop_limit = 5;
static uint8_t x_channel = 0;
static uint8_t y_channel = 0;
static uint8_t *diag_mutual = NULL;
static int diag_command = 0;
static uint8_t diag_coor[128];// = {0xFF};
static uint8_t diag_self[100] = {0};
static uint8_t *getMutualBuffer(void);
static uint8_t *getSelfBuffer(void);
static uint8_t getDiagCommand(void);
static uint8_t getXChannel(void);
static uint8_t getYChannel(void);
static void setMutualBuffer(void);
static void setXChannel(uint8_t x);
static void setYChannel(uint8_t y);
static uint8_t coordinate_dump_enable = 0;
struct file *coordinate_fn;
#ifdef HX_TP_PROC_2T2R
static bool Is_2T2R = false;
static int HX_2T2R_Addr = 0x96;//Need to check with project FW eng.
static int HX_2T2R_en_setting = 0x02;//Need to check with project FW eng.
static uint8_t x_channel_2 = 0;
static uint8_t y_channel_2 = 0;
static uint8_t *diag_mutual_2 = NULL;
static int HX_RX_NUM_2 = 0;
static int HX_TX_NUM_2 = 0;
static uint8_t *getMutualBuffer_2(void);
static uint8_t getXChannel_2(void);
static uint8_t getYChannel_2(void);
static void setMutualBuffer_2(void);
static void setXChannel_2(uint8_t x);
static void setYChannel_2(uint8_t y);
#endif
#endif
#ifdef HX_TP_PROC_REGISTER
static uint8_t register_command = 0;
static uint8_t multi_register_command = 0;
static uint8_t multi_register[8] = {0x00};
static uint8_t multi_cfg_bank[8] = {0x00};
static uint8_t multi_value[1024] = {0x00};
static bool config_bank_reg = false;
#endif
#ifdef HX_TP_PROC_DEBUG
static uint8_t IC_STATUS_CHECK = 0xAA;
static bool fw_update_complete = false;
static int handshaking_result = 0;
static unsigned char debug_level_cmd = 0;
static unsigned char upgrade_fw[32*1024];
#endif
#ifdef HX_TP_PROC_FLASH_DUMP
static uint8_t *flash_buffer = NULL;
static uint8_t flash_command = 0;
static uint8_t flash_read_step = 0;
static uint8_t flash_progress = 0;
static uint8_t flash_dump_complete = 0;
static uint8_t flash_dump_fail = 0;
static uint8_t sys_operation = 0;
static uint8_t flash_dump_sector = 0;
static uint8_t flash_dump_page = 0;
static bool flash_dump_going = false;
static uint8_t getFlashCommand(void);
static uint8_t getFlashDumpComplete(void);
static uint8_t getFlashDumpFail(void);
static uint8_t getFlashDumpProgress(void);
static uint8_t getFlashReadStep(void);
static uint8_t getSysOperation(void);
static uint8_t getFlashDumpSector(void);
static uint8_t getFlashDumpPage(void);
static bool getFlashDumpGoing(void);
static void setFlashBuffer(void);
static void setFlashCommand(uint8_t command);
static void setFlashReadStep(uint8_t step);
static void setFlashDumpComplete(uint8_t complete);
static void setFlashDumpFail(uint8_t fail);
static void setFlashDumpProgress(uint8_t progress);
static void setSysOperation(uint8_t operation);
static void setFlashDumpSector(uint8_t sector);
static void setFlashDumpPage(uint8_t page);
static void setFlashDumpGoing(bool going);
#endif
#ifdef HX_TP_PROC_HITOUCH
static int hitouch_command = 0;
static bool hitouch_is_connect = false;
#endif
#endif
#ifdef HX_ESD_WORKAROUND
static u8 ESD_RESET_ACTIVATE = 1;
static u8 ESD_COUNTER = 0;
//static int ESD_COUNTER_SETTING = 3;
static u8 ESD_R36_FAIL = 0;
#endif
#ifdef HX_RST_PIN_FUNC
void himax_HW_reset(uint8_t loadconfig,uint8_t int_off);
#endif
#ifdef HX_SMART_WAKEUP
static bool FAKE_POWER_KEY_SEND = false;
#endif
#ifdef HX_AUTO_UPDATE_CONFIG
static int CFB_START_ADDR = 0;
static int CFB_LENGTH = 0;
static int CFB_INFO_LENGTH = 0;
#endif
#ifdef HX_AUTO_UPDATE_FW
#define FW_UPDATE_MANUAL_MODE 2
#define HMX_FW_NAME "HX852XES.bin"
#define ASUS_FW_NAME "/asusfw/touch/HX852XES.bin"
static uint8_t ASUS_FW_MAJ = 0x19;
static uint8_t IC_checksum[4];
static bool fw_update_result = false;
static bool fw_update_processing= false;
static int i_update_FW(bool manual);
#endif
#ifdef HX_CHIP_STATUS_MONITOR
static int HX_CHIP_POLLING_COUNT;
static int HX_POLLING_TIMER =5;//unit:sec
static int HX_POLLING_TIMES =2;//ex:5(timer)x2(times)=10sec(polling time)
static int HX_ON_HAND_SHAKING =0;//
#endif
#ifdef HX_TIME_TELLING
#define TOUCH_ACTIVE 0
#define TOUCH_SLEEP 1
#define TOUCH_IDLE 2
static int DisableTouch_flag = 0;
static int touch_mode;
void himax_timetelling_detection(int supplymode);
#endif
extern int irq_enable_count;
#endif