cyttsp6_ts.h
/*
* cyttsp5_ts.h
* Parade TrueTouch(TM) Standard Product V5 Core Module.
*
* Copyright (C) 2017 Hwtc Co,.Ltd
*
*/
#ifndef _CYTTSP6_REGS_H
#define _CYTTSP6_REGS_H
#include "type.h"
#define IS_BOOTLOADER(hst_mode, reset_detect) \
((hst_mode) & 0x01 || (reset_detect) != 0)
#define IS_BOOTLOADER_IDLE(hst_mode, reset_detect) \
((hst_mode) & 0x01 && (reset_detect) & 0x01)
/* helpers */
#define GET_NUM_TOUCH_RECORDS(x) ((x) & 0x1F)
#define IS_LARGE_AREA(x) ((x) & 0x20)
#define IS_BAD_PKT(x) ((x) & 0x20)
#define IS_BOOTLOADER(hst_mode, reset_detect) \
((hst_mode) & 0x01 || (reset_detect) != 0)
#define IS_BOOTLOADER_IDLE(hst_mode, reset_detect) \
((hst_mode) & 0x01 && (reset_detect) & 0x01)
#define GET_HSTMODE(reg) ((reg & 0x70) >> 4)
#define GET_TOGGLE(reg) ((reg & 0x80) >> 7)
#define IS_LITTLEENDIAN(reg) ((reg & 0x01) == 1)
#define GET_PANELID(reg) (reg & 0x07)
#define HI_BYTE(x) (u8)(((x) >> 8) & 0xFF)
#define LO_BYTE(x) (u8)((x) & 0xFF)
#define IS_DEEP_SLEEP_CONFIGURED(x) ((x) == 0 || (x) == 0xFF)
#define IS_TMO(t) ((t) == 0)
#define IS_GEST_EXTD(gest_id) (((u8)gest_id) >> 7)
#define CY_BL_MAX_STATUS_SIZE 32
/* Communication bus values */
#define CY_DEFAULT_ADAP_MAX_XFER 512
#define CY_ADAP_MIN_XFER 64
/* DEVICE REGISTERS */
/* OP MODE REGISTERS */
#define CY_REG_BASE 0x00
/* DRIVER STATES */
enum cyttsp6_mode {
CY_MODE_UNKNOWN = 0,
CY_MODE_BOOTLOADER = (1 << 0),
CY_MODE_OPERATIONAL = (1 << 1),
CY_MODE_SYSINFO = (1 << 2),
CY_MODE_CAT = (1 << 3),
CY_MODE_STARTUP = (1 << 4),
CY_MODE_LOADER = (1 << 5),
CY_MODE_CHANGE_MODE = (1 << 6),
CY_MODE_CHANGED = (1 << 7),
CY_MODE_CMD_COMPLETE = (1 << 8),
};
enum cyttsp6_core_platform_flags {
CY_CORE_FLAG_NONE = 0,
CY_CORE_FLAG_WAKE_ON_GESTURE = (1 << 0),
CY_CORE_FLAG_POWEROFF_ON_SLEEP = (1 << 1),
CY_CORE_FLAG_BOOTLOADER_FAST_EXIT = (1 << 2),
/* choose SCAN_TYPE or TOUCH_MODE RAM ID to alter scan type */
CY_CORE_FLAG_SCAN_MODE_USES_RAM_ID_SCAN_TYPE = (1 << 3),
};
enum cyttsp6_int_state {
CY_INT_NONE,
CY_INT_IGNORE = (1 << 0),
CY_INT_MODE_CHANGE = (1 << 1),
CY_INT_EXEC_CMD = (1 << 2),
CY_INT_AWAKE = (1 << 3),
};
/* DRIVER STATES */
//enum cyttsp6_mode {
// CY_MODE_UNKNOWN = 0,
// CY_MODE_BOOTLOADER = (1 << 0),
// CY_MODE_OPERATIONAL = (1 << 1),
// CY_MODE_SYSINFO = (1 << 2),
// CY_MODE_CAT = (1 << 3),
// CY_MODE_STARTUP = (1 << 4),
// CY_MODE_LOADER = (1 << 5),
// CY_MODE_CHANGE_MODE = (1 << 6),
// CY_MODE_CHANGED = (1 << 7),
// CY_MODE_CMD_COMPLETE = (1 << 8),
//};
enum cyttsp6_hst_mode_bits {
CY_HST_TOGGLE = (1 << 7),
CY_HST_MODE_CHANGE = (1 << 3),
CY_HST_DEVICE_MODE = (7 << 4),
CY_HST_OPERATE = (0 << 4),
CY_HST_SYSINFO = (1 << 4),
CY_HST_CAT = (2 << 4),
CY_HST_LOWPOW = (1 << 2),
CY_HST_SLEEP = (1 << 1),
CY_HST_RESET = (1 << 0),
};
enum cyttsp_cmd_bits {
CY_CMD_COMPLETE = (1 << 6),
};
struct cyttsp6_core_platform_data {
int irq_gpio;
int rst_gpio;
int err_gpio;
int level_irq_udelay;
int max_xfer_len;
UINT32 flags;
UINT8 easy_wakeup_gesture;
};
struct device {
UINT8 member_a;
};
struct wait_queue {
bool wake_up;
};
struct cyttsp6_core_data {
//char core_id[20];
struct device *dev;
struct wait_queue wait_q;
enum cyttsp6_mode mode;
int int_status; // u
int cmd_toggle;
int phys_num;
int irq;
int f_flag;
void *exclusive_dev;
int exclusive_waits;
bool irq_enabled;
bool irq_wake;
bool wake_initiated_by_device;
bool invalid_touch_app;
bool bl_fast_exit;
int max_xfer;
int apa_mc_en;
int glove_en;
int stylus_en;
int proximity_en;
UINT8 default_scantype;
UINT8 easy_wakeup_gesture;
unsigned int active_refresh_cycle_ms;
UINT8 heartbeat_count;
UINT8 wr_buf[CY_DEFAULT_ADAP_MAX_XFER];
#ifdef VERBOSE_DEBUG
UINT8 pr_buf[CY_MAX_PRBUF_SIZE];
UINT8 rep_stat_counter;
#endif
UINT8 xy_mode[128]; /* operational mode and status regs */
UINT8 *xy_data; /* operational touch regs */
};
// log
#define TP_Debug 1
//#define dev_err(dev, format, arg...) Print(format, ##arg)
#ifdef DEBUG
#define dev_dbg(dev, format, arg...) print(format, ##arg)
#ifdef VERBOSE_DEBUG
#define dev_vdbg(dev, format, arg...) print(format, ##arg);
#else
#define dev_vdbg(dev, format, arg...)
#endif
#else
#define dev_dbg(dev, format, arg...)
#define dev_vdbg(dev, format, arg...)
#endif
#define kmalloc(size, flag) malloc(size)
#define kfree(p) free(p)
#define ENOMEM 12 /* Out of memory */
#define EINVAL 13
#define EIO 14
#define ETIME 15
extern UINT16 TPTimerOutCount;
//extern UINT8 I2CTimerOutCount;
/* Timeout in ms. */
#define CY_COMMAND_COMPLETE_TIMEOUT 1000
#define CY_CALIBRATE_COMPLETE_TIMEOUT 10000
#define CY_WATCHDOG_TIMEOUT 1000
#define CY_CORE_REQUEST_EXCLUSIVE_TIMEOUT 1000
#define CY_PROXIMITY_REQUEST_EXCLUSIVE_TIMEOUT 2000
#define CY_DA_REQUEST_EXCLUSIVE_TIMEOUT 1000
#define CY_LDR_REQUEST_EXCLUSIVE_TIMEOUT 10000
#define CY_CORE_SLEEP_REQUEST_EXCLUSIVE_TIMEOUT 10000
#define CY_CORE_WAIT_SYSINFO_MODE_TIMEOUT 4000
#define CY_CORE_MODE_CHANGE_TIMEOUT 2000
#define CY_CORE_RESET_AND_WAIT_TIMEOUT 1000
#define CY_CORE_WAKEUP_TIMEOUT 500
#define CY_LDR_CMD_TIMEOUT 1000
#define CY_LDR_CMD_INIT_TIMEOUT 20000
#define CY_CORE_CMD_WAIT_FOR_EVENT_TIMEOUT 50
/* TMA400 HOST SYNC BYTE */
#define CY_CMD_LDR_HOST_SYNC 0xFF
#define CY_START_OF_PACKET 0x01
#define CY_END_OF_PACKET 0x17
/* CMD */
enum cyttsp6_cmd_bl {
CY_CMD_LDR_VERIFY_CHKSUM = 0x31,
CY_CMD_LDR_ERASE_ROW = 0x34,
CY_CMD_LDR_SEND_DATA = 0x37,
CY_CMD_LDR_ENTER,
CY_CMD_LDR_PROG_ROW,
CY_CMD_LDR_VERIFY_ROW,
CY_CMD_LDR_EXIT,
CY_CMD_LDR_FAST_EXIT,
CY_CMD_LDR_INIT = 0x48,
};
//需要根据实际情况调整
#define CY_CMD_OFS 2
#define CY_REP_HDR_SIZE 19
#define CY_TCH_REC_SIZE 10
#define CY_REP_OFS 9
#define CY_TT_STAT_OFS 27
#define CY_MAX_TCHS 2//最多5个手指
extern struct cyttsp6_core_data g_cd;
int cyttsp6_startup(struct cyttsp6_core_data *cd);
void cyttsp6_irq(struct cyttsp6_core_data *cd);
int cyttsp6_watchdog_work(struct cyttsp6_core_data *cd);
#endif //_CYTTSP6_REGS_H
cyttsp6_ts.c
/*
* cyttsp5_ts.c
* Parade TrueTouch(TM) Standard Product V5 Core Module.
*
* Copyright (C) 2017 Hwtc Co,.Ltd
*
*/
#include "includes.h"
//#include <malloc.h>
#include <string.h>
UINT16 TPTimerOutCount = 0;//计数
//UINT8 I2CTimerOutCount = 0;//超时标志
struct cyttsp6_core_data g_cd;
static u8 ldr_exit[] = {
CY_CMD_LDR_HOST_SYNC, CY_START_OF_PACKET, CY_CMD_LDR_EXIT, 0x00, 0x00,
0x4F, 0x6D, CY_END_OF_PACKET
};
static u8 ldr_fast_exit[] = {
CY_CMD_LDR_HOST_SYNC, CY_START_OF_PACKET, CY_CMD_LDR_FAST_EXIT,
0x00, 0x00, 0xC3, 0x68, CY_END_OF_PACKET
};
static void wake_up(struct wait_queue *wq)
{
wq->wake_up = 1;
}
// if (pwa->wake_up) \
// { \
// TPCountTimerOut = 0; \
// goto __exit; \
// } \
// __exit: \
// if(TPCountTimerOutFlag == 1) \
// { \
// break; \
// } \
#define wait_event_timeout(wq, condition, timeout) \
{ \
struct wait_queue *pwa = (struct wait_queue *)wq; \
TPTimerOutCount = timeout; \
while ( !(condition)) \
{ \
if(TPTimerOutCount == 0) \
{ \
break; \
} \
} \
pwa->wake_up = 0; \
}
/******************************************************************************
** Function : cyttsp6_adap_readyttsp6_adap_write
** Description : TP I2C读写操作
*******************************************************************************/
static int cyttsp6_adap_read(struct cyttsp6_core_data *cd, u16 addr,
void *buf, int size)
{
// return cd->bus_ops->read(cd->dev, addr, buf, size, cd->max_xfer);
return HALAPI_IIC1_Read(0x48, (UINT8)addr, buf , size);
}
static int cyttsp6_adap_write(struct cyttsp6_core_data *cd, u16 addr,
void *buf, int size)
{
// return cd->bus_ops->write(cd->dev, addr, cd->wr_buf, buf, size,
// cd->max_xfer);
// while(1)
// {
// HALAPI_IIC1_Write(0x48, addr, buf , size);
// }
return HALAPI_IIC1_Write(0x48, (UINT8)addr, buf , size);
}
static int _exit_bootloader(struct cyttsp6_core_data *cd)
{
//const u8 *exit_cmd;
u8 *exit_cmd;
int exit_cmd_size;
int rc;
cd->int_status &= ~CY_INT_IGNORE;
cd->int_status |= CY_INT_MODE_CHANGE;
//if ((cd->f_flag & CY_CORE_FLAG_BOOTLOADER_FAST_EXIT)&& cd->bl_fast_exit)
if(0)
{
// dev_vdbg(cd->dev, "%s: Issuing ldr_fast_exit\n", __func__);
exit_cmd = ldr_fast_exit;
exit_cmd_size = sizeof(ldr_fast_exit);
} else {
// dev_vdbg(cd->dev, "%s: Issuing ldr_exit\n", __func__);
exit_cmd = ldr_exit;
exit_cmd_size = sizeof(ldr_exit);
}
rc = cyttsp6_adap_write(cd, CY_REG_BASE, exit_cmd, exit_cmd_size);
if (rc == 0)
{
DebugUart_Printf(TP_Debug,"_exit_bootloader:cyttsp6_adap_write err\r\n");
}
return rc;
}
static int cyttsp6_wait_sysinfo_mode(struct cyttsp6_core_data *cd)
{
long t;
//dev_vdbg(cd->dev, "%s: wait sysinfo...\n", __func__);
DebugUart_Printf(TP_Debug,"wait sysinfo...\r\n");
wait_event_timeout(&cd->wait_q, cd->mode == CY_MODE_SYSINFO, CY_CORE_WAIT_SYSINFO_MODE_TIMEOUT);
t = TPTimerOutCount;
TPTimerOutCount = 0;//停止计时器
//TPTimerOutCount = 0//超时退出
// t = wait_event_timeout(NULL, cd->mode == CY_MODE_SYSINFO,
if (IS_TMO(t)) {
DebugUart_Printf(TP_Debug,"tmo waiting exit bl cd->mode=%d\r\n",cd->mode);
//dev_err(cd->dev, "%s: tmo waiting exit bl cd->mode=%d\n",__func__, cd->mode);
cd->int_status &= ~CY_INT_MODE_CHANGE;
return -ETIME;
}
return 0;
}
static int set_mode(struct cyttsp6_core_data *cd, int new_mode)
{
u8 new_dev_mode;
u8 mode;
long t;
int rc;
switch (new_mode) {
case CY_MODE_OPERATIONAL:
new_dev_mode = CY_HST_OPERATE;
break;
case CY_MODE_SYSINFO:
new_dev_mode = CY_HST_SYSINFO;
break;
case CY_MODE_CAT:
new_dev_mode = CY_HST_CAT;
break;
default:
//dev_err(cd->dev, "%s: invalid mode: %02X(%d)\n",__func__, new_mode, new_mode);
DebugUart_Printf(TP_Debug,"set_mode:invalid mode: %2x(%d)\r\n",new_mode, new_mode);
return -EINVAL;
}
/* change mode */
// dev_dbg(cd->dev, "%s: have exclusive=%p new_dev_mode=%02X new_mode=%s\n",
// __func__, cd->exclusive_dev,
// new_dev_mode, mode2str(new_mode));
rc = cyttsp6_adap_read(cd, CY_REG_BASE, &mode, sizeof(mode));
if (rc < 0) {
//dev_err(cd->dev, "%s: Fail read mode r=%d\n", __func__, rc);
DebugUart_Printf(TP_Debug,"set_mode:Fail read mode r=%d\r\n",rc);
goto exit;
}
/* Clear device mode bits and set to new mode */
mode &= ~CY_HST_DEVICE_MODE;
mode |= new_dev_mode | CY_HST_MODE_CHANGE;
cd->int_status |= CY_INT_MODE_CHANGE;
rc = cyttsp6_adap_write(cd, CY_REG_BASE, &mode, sizeof(mode));
if (rc < 0) {
//dev_err(cd->dev, "%s: Fail write mode change r=%d\n",__func__, rc);
DebugUart_Printf(TP_Debug,"Fail write mode change rc=%d\r\n",rc);
goto exit;
}
/* wait for mode change done interrupt */
wait_event_timeout(&cd->wait_q,(cd->int_status & CY_INT_MODE_CHANGE) == 0,CY_CORE_MODE_CHANGE_TIMEOUT);
t = TPTimerOutCount;
TPTimerOutCount = 0;//停止计时器
//t = 1;
// dev_dbg(cd->dev, "%s: back from wait t=%ld cd->mode=%s\n",
// __func__, t, mode2str(cd->mode));
if (IS_TMO(t)) {
//dev_err(cd->dev, "%s: tmo waiting mode change\n", __func__);
DebugUart_Printf(TP_Debug,"tmo waiting mode change\r\n",rc);
cd->int_status &= ~CY_INT_MODE_CHANGE;
rc = -EINVAL;
}
exit:
return rc;
}
static void cyttsp6_parse_mode(struct device *dev, u8 mode,
enum cyttsp6_mode *cur_mode)
{
switch (mode & CY_HST_DEVICE_MODE)
{
case CY_HST_OPERATE:
*cur_mode = CY_MODE_OPERATIONAL;
// dev_vdbg(dev, "%s: operational\n", __func__);
break;
case CY_HST_CAT:
*cur_mode = CY_MODE_CAT;
// dev_vdbg(dev, "%s: CaT\n", __func__);
break;
case CY_HST_SYSINFO:
*cur_mode = CY_MODE_SYSINFO;
// dev_vdbg(dev, "%s: sysinfo\n", __func__);
break;
default:
*cur_mode = CY_MODE_UNKNOWN;
//dev_err(dev, "%s: unknown HST mode 0x%02X\n", __func__, mode);
DebugUart_Printf(TP_Debug,"cyttsp6_parse_mode:unknown HST mode 0x%2x\r\n",mode);
break;
}
}
//static char *mode2str(int mode)
//{
// switch (mode) {
// case CY_MODE_UNKNOWN:
// return "unknown";
// case CY_MODE_BOOTLOADER:
// return "bootloader";
// case CY_MODE_OPERATIONAL:
// return "operational";
// case CY_MODE_SYSINFO:
// return "sysinfo";
// case CY_MODE_CAT:
// return "cat";
// case CY_MODE_STARTUP:
// return "startup";
// case CY_MODE_LOADER:
// return "loader";
// case CY_MODE_CHANGE_MODE:
// return "change_mode";
// case CY_MODE_CHANGED:
// return "changed";
// case CY_MODE_CMD_COMPLETE:
// return "cmd_complete";
// default:
// return "mode_failure";
// }
//}
static int cyttsp6_handshake_(struct cyttsp6_core_data *cd, u8 mode)
{
u8 cmd = mode ^ CY_HST_TOGGLE;
int rc;
if (mode & CY_HST_MODE_CHANGE) {
//dev_err(cd->dev, "%s: Host mode change bit set, NO handshake\n",__func__);
DebugUart_Printf(TP_Debug,"cyttsp6_handshake_:Host mode change bit set, NO handshake\r\n");
return 0;
}
rc = cyttsp6_adap_write(cd, CY_REG_BASE, &cmd, sizeof(cmd));
if (rc < 0)
//dev_err(cd->dev, "%s: bus write fail on handshake (ret=%d)\n",__func__, rc);
DebugUart_Printf(TP_Debug,"cyttsp6_handshake_:bus write fail on handshake (ret=%d)\r\n",rc);
return rc;
}
static int cyttsp6_load_status_and_touch_regs_(struct cyttsp6_core_data *cd,bool optimize)
{
// struct device *dev = cd->dev;
int first_read_len;
int second_read_off;
int num_read_rec;
u8 num_cur_rec;
//u8 hst_mode;
u8 rep_len;
// u8 rep_stat;
u8 tt_stat;
int rc;
#ifdef VERBOSE_DEBUG
u8 rep_stat_counter;
#endif
u8 i = 0;
first_read_len = CY_REP_HDR_SIZE; //si->si_ofs.rep_hdr_size;
/* Read one touch record additionally */
if (optimize)
first_read_len += CY_TCH_REC_SIZE; //si->si_ofs.tch_rec_size;
rc = cyttsp6_adap_read(cd, CY_REP_OFS /*si->si_ofs.rep_ofs*/,
&cd->xy_mode[CY_REP_OFS/*si->si_ofs.rep_ofs*/], first_read_len);
if (rc < 0) {
//dev_err(dev, "%s: reading touch record failed r=%d\n",__func__, rc);
DebugUart_Printf(TP_Debug,"cyttsp6_load_status_and_touch_regs_:reading touch record failed rc=%d\r\n",rc);
return rc;
}
//DebugUart_Printf(1,"3\r\n");
//#ifdef VERBOSE_DEBUG
// /* print xy data */
// cyttsp6_pr_buf(dev, cd->pr_buf, si->xy_mode,
// si->si_ofs.mode_size, "xy_mode");
//#endif
// hst_mode = cd->xy_mode[CY_REG_BASE];
rep_len = cd->xy_mode[CY_REP_OFS/*si->si_ofs.rep_ofs*/];
// rep_stat = cd->xy_mode[CY_REP_OFS + 1 /*si->si_ofs.rep_ofs + 1*/];
tt_stat = cd->xy_mode[CY_TT_STAT_OFS /*si->si_ofs.tt_stat_ofs*/];
// dev_vdbg(dev, "%s: %s%02X %s%d %s%02X %s%02X\n", __func__,
// "hst_mode=", hst_mode, "rep_len=", rep_len,
// "rep_stat=", rep_stat, "tt_stat=", tt_stat);
//#ifdef VERBOSE_DEBUG
// cd->rep_stat_counter = ((cd->rep_stat_counter + 1) & 0x3);
// rep_stat_counter = rep_stat >> 6;
// if (cd->rep_stat_counter != rep_stat_counter) {
// dev_vdbg(dev, "Possibly missed a touch record expected:%d device:%d\n",
// cd->rep_stat_counter, rep_stat_counter);
// cd->rep_stat_counter = rep_stat_counter;
// }
//#endif
num_cur_rec = GET_NUM_TOUCH_RECORDS(tt_stat);
//dev_vdbg(dev, "%s: num_cur_rec=%d\n", __func__, num_cur_rec);
if (rep_len == 0 && num_cur_rec > 0)
{
//dev_err(dev, "%s: report length error rep_len=%d num_rec=%d\n",__func__, rep_len, num_cur_rec);
DebugUart_Printf(TP_Debug,"cyttsp6_load_status_and_touch_regs_:report length error rep_len=%d num_rec=%d\r\n",rep_len, num_cur_rec);
return -EIO;
}
if (num_cur_rec > CY_MAX_TCHS /*si->si_ofs.max_tchs*/)
{
//dev_err(dev, "%s: %s (n=%d c=%zu)\n", __func__,"too many tch; set to max tch",num_cur_rec, CY_MAX_TCHS /*si->si_ofs.max_tchs*/);
//DebugUart_Printf(TP_Debug,"cyttsp6_load_status_and_touch_regs_:n=%d\r\n",num_cur_rec);
num_cur_rec = CY_MAX_TCHS /*si->si_ofs.max_tchs*/;
}
num_read_rec = num_cur_rec;
//DebugUart_Printf(TP_Debug,"num_read_rec=%d\r\n",num_read_rec);
second_read_off = CY_TT_STAT_OFS + 1; //si->si_ofs.tt_stat_ofs + 1;
if (optimize)
{
num_read_rec--;
second_read_off += CY_TCH_REC_SIZE; //si->si_ofs.tch_rec_size;
}
if (num_read_rec < 0)
{
//DebugUart_Printf(1,"4\r\n");
goto exit_print;
}
//DebugUart_Printf(1,"5\r\n");
rc = cyttsp6_adap_read(cd, second_read_off,&cd->xy_mode[second_read_off],num_read_rec * CY_TCH_REC_SIZE /*si->si_ofs.tch_rec_size*/);
if (rc < 0) {
//dev_err(dev, "%s: read fail on touch regs r=%d\n",__func__, rc);
DebugUart_Printf(TP_Debug,"cyttsp6_load_status_and_touch_regs_:read fail on touch regs rc=%d\r\n",rc);
return rc;
}
//DebugUart_Printf(TP_Debug,"TouchInfoNum:num_read_rec=%d\r\n",num_read_rec);
//将数据传送出去
if(I2C_SendBuf[I2CSendFillNum].NewDataFlg == 1)
{
DebugUart_Printf(TP_Debug,"Touch Buf FIFO:%d\r\n",I2CSendFillNum);
}
else
{
I2C_SendBuf[I2CSendFillNum].buf[0] = num_read_rec;//TouchNum
for(i=0; i<num_read_rec; i++)
{
I2C_SendBuf[I2CSendFillNum].buf[1+i*7] = cd->xy_mode[28+i*10];
I2C_SendBuf[I2CSendFillNum].buf[2+i*7] = cd->xy_mode[29+i*10];//X
I2C_SendBuf[I2CSendFillNum].buf[3+i*7] = cd->xy_mode[30+i*10];
I2C_SendBuf[I2CSendFillNum].buf[4+i*7] = cd->xy_mode[31+i*10];//Y
I2C_SendBuf[I2CSendFillNum].buf[5+i*7] = cd->xy_mode[32+i*10];//P
I2C_SendBuf[I2CSendFillNum].buf[6+i*7] = cd->xy_mode[33+i*10];//T
I2C_SendBuf[I2CSendFillNum].buf[7+i*7] = cd->xy_mode[36+i*10];//MAJ
}
I2C_SendBuf[I2CSendFillNum].len = 7*num_read_rec + 1;
I2C_SendBuf[I2CSendFillNum].NewDataFlg = 1;
DebugUart_Printf(1,"TouchNum=%d,",I2C_SendBuf[I2CSendFillNum].buf[0]);
for(i=0; i<I2C_SendBuf[I2CSendFillNum].buf[0]; i++)
{
//DebugUart_Printf(1,"X=%d,",((UINT16)I2C_SendBuf[I2CSendFillNum].buf[1+i*7]<<8|I2C_SendBuf[I2CSendFillNum].buf[2+i*7]));
//DebugUart_Printf(1,"Y=%d,",((UINT16)I2C_SendBuf[I2CSendFillNum].buf[3+i*7]<<8|I2C_SendBuf[I2CSendFillNum].buf[4+i*7]));
//DebugUart_Printf(1,"P=%d,",I2C_SendBuf[I2CSendFillNum].buf[5+i*7]);
DebugUart_Printf(1,"T=0x%2x,",I2C_SendBuf[I2CSendFillNum].buf[6+i*7]);
//DebugUart_Printf(1,"M=%d,",I2C_SendBuf[I2CSendFillNum].buf[7+i*7]);
}
DebugUart_Printf(1,"\r\n");
I2CSendFillNum ++;
if(I2CSendFillNum == I2C_SendMax)
{
I2CSendFillNum = 0;
}
}
exit_print:
/* print xy data */
// cyttsp6_pr_buf(dev, cd->pr_buf, si->xy_data,
// num_cur_rec * si->si_ofs.tch_rec_size, "xy_data");
//DebugUart_Printf(1,"6\r\n");
return 0;
}
/******************************************************************************
** Function : cyttsp6_startup
** Description : TP初始化操作
*******************************************************************************/
int cyttsp6_startup(struct cyttsp6_core_data *cd)
{
// struct device *dev = cd->dev;
int rc;
cd->xy_data = &cd->xy_mode[28];
//#if 0
// rc = cyttsp6_wait_bl_heartbeat(cd);
// if (rc) {
// dev_err(dev, "%s: Error on waiting bl heartbeat r=%d\n",
// __func__, rc);
// return rc;
// }
//#endif
/* exit bl into sysinfo mode */
rc = _exit_bootloader(cd);
if (rc < 0) {
//dev_err(dev, "%s: Fail exit bootloader rc=%d\n",__func__, rc);
DebugUart_Printf(TP_Debug,"cyttsp6_startup:Fail exit bootloader rc=%d\r\n",rc);
return rc;
}
rc = cyttsp6_wait_sysinfo_mode(cd);
if (rc < 0) {
//dev_err(dev, "%s: Fail switch to sysinfo mode, r=%d\n",__func__, rc);
DebugUart_Printf(TP_Debug,"cyttsp6_startup:Fail switch to sysinfo mode, rc=%d\r\n",rc);
goto exit_lock;
}
rc = set_mode(cd, CY_MODE_OPERATIONAL);
if (rc < 0) {
//dev_err(dev, "%s: Fail set mode to Operational mode, r=%d\n",__func__, rc);
DebugUart_Printf(TP_Debug,"cyttsp6_startup:Fail set mode to Operational mode, rc=%d\r\n",rc);
goto exit_lock;
}
DebugUart_Printf(TP_Debug,"cyttsp6_startup InitOk\r\n");
exit_lock:
return rc;
}
/******************************************************************************
** Function : cyttsp6_irq
** Description : INT中断处理函数
*******************************************************************************/
void cyttsp6_irq(struct cyttsp6_core_data *cd)
{
struct device *dev = cd->dev;
enum cyttsp6_mode cur_mode;
u8 cmd_ofs = CY_CMD_OFS;//cd->sysinfo.si_ofs.cmd_ofs;
bool command_complete = 0;
u8 mode[3];
int rc;
rc = cyttsp6_adap_read(cd, CY_REG_BASE, mode, sizeof(mode));
if (rc == 0)
{
DebugUart_Printf(TP_Debug,"cyttsp6_irq:cyttsp6_adap_read err\r\n");
goto cyttsp6_irq_exit;
}
if (IS_BOOTLOADER(mode[0], mode[1]))
{
DebugUart_Printf(TP_Debug,"cyttsp6_irq:IS_BOOTLOADER\r\n");
cur_mode = CY_MODE_BOOTLOADER;
/* switch to bootloader */
if (cd->mode != CY_MODE_BOOTLOADER)
{
}
/* catch operation->bl glitch */
if ((cd->mode != CY_MODE_BOOTLOADER) && (cd->mode != CY_MODE_UNKNOWN))
{
/* Incase startup_state, do not let startup_() */
cd->mode = CY_MODE_UNKNOWN;
DebugUart_Printf(TP_Debug,"cyttsp6_irq:CY_MODE_UNKNOWN\r\n");
goto cyttsp6_irq_exit;
}
/* Recover if stuck in bootloader idle mode */
if (cd->mode == CY_MODE_BOOTLOADER)
{
if (IS_BOOTLOADER_IDLE(mode[0], mode[1]))
{
if (cd->heartbeat_count > 3)
{
cd->heartbeat_count = 0;
/* exit bl into sysinfo mode */
rc = _exit_bootloader(cd);
if (rc == 0)
{
DebugUart_Printf(TP_Debug,"cyttsp6_startup:_exit_bootloader err\r\n");
}
goto cyttsp6_irq_exit;
}
cd->heartbeat_count++;
}
}
cd->mode = cur_mode;
/* Signal bootloader heartbeat heard */
wake_up(&cd->wait_q);
goto cyttsp6_irq_exit;
}
cyttsp6_parse_mode(dev, mode[0], &cur_mode);
/* Check whether this IRQ should be ignored (internal) */
if (cd->int_status & CY_INT_IGNORE)
{
}
/* Check for wake up interrupt */
if (cd->int_status & CY_INT_AWAKE)
{
cd->int_status &= ~CY_INT_AWAKE;
wake_up(&cd->wait_q);
//DebugUart_Printf(1,"cyttsp6_irq_handshake1\r\n");
goto cyttsp6_irq_handshake;
}
/* Expecting mode change interrupt */
if ((cd->int_status & CY_INT_MODE_CHANGE) && ((mode[0] & CY_HST_MODE_CHANGE) == 0))
{
cd->int_status &= ~CY_INT_MODE_CHANGE;
cd->mode = cur_mode;
wake_up(&cd->wait_q);
//DebugUart_Printf(1,"cyttsp6_irq_handshake2\r\n");
goto cyttsp6_irq_handshake;
}
/* compare current core mode to current device mode */
if (((mode[0] & CY_HST_MODE_CHANGE) == 0) && cd->mode != cur_mode)
{
DebugUart_Printf(TP_Debug,"cyttsp6_irq:%d %d->%d int:%s\r\n",cd->mode,cur_mode, cd->int_status);
goto cyttsp6_irq_exit;
}
/* Expecting command complete interrupt */
if ((cd->int_status & CY_INT_EXEC_CMD)
&& mode[cmd_ofs] & CY_CMD_COMPLETE)
{
command_complete = 1;
cd->int_status &= ~CY_INT_EXEC_CMD;
wake_up(&cd->wait_q);
/*
* It is possible to receive a single interrupt for
* command complete and touch/button status report.
* Continue processing for a possible status report.
*/
}
if (!cd->xy_mode)
{
//DebugUart_Printf(1,"cyttsp6_irq_handshake3\r\n");
goto cyttsp6_irq_handshake;
}
/* Copy the mode registers */
memcpy(cd->xy_mode, mode, sizeof(mode));
/* This should be status report, read status and touch regs */
if (cd->mode == CY_MODE_OPERATIONAL)
{
//DebugUart_Printf(1,"2\r\n");
rc = cyttsp6_load_status_and_touch_regs_(cd, command_complete);
if (rc < 0)
DebugUart_Printf(TP_Debug,"cyttsp6_irq:fail read mode/touch regs rc=%d\r\n",rc);
}
cyttsp6_irq_handshake:
/* handshake the event */
rc = cyttsp6_handshake_(cd, mode[0]);
if (rc < 0)
DebugUart_Printf(TP_Debug,"cyttsp6_irq:Fail handshake mode=0x%2x rc=%d\r\n",mode[0], rc);
/*
* a non-zero udelay period is required for using
* IRQF_TRIGGER_LOW in order to delay until the
* device completes isr deassert
*/
//DebugUart_Printf(1,"cyttsp6_handshake_\r\n");
// udelay(cd->cpdata->level_irq_udelay);
cyttsp6_irq_exit:
//DebugUart_Printf(1,"cyttsp6_irq_exit\r\n");
return;
}
int cyttsp6_watchdog_work(struct cyttsp6_core_data *cd)
{
u8 mode[2];
int rc;
rc = cyttsp6_adap_read(cd,CY_REG_BASE,&mode,sizeof(mode));
if(rc == 0)
{
DebugUart_Printf(1,"cyttsp6_adap_read I2C Err\r\n");
return 0;
}
if(IS_BOOTLOADER(mode[0], mode[1]))
{
DebugUart_Printf(1,"Device found in bootloader mode\r\n");
return 0;
}
return 1;
}