diff options
author | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
---|---|---|
committer | Srikant Patnaik | 2015-01-11 12:28:04 +0530 |
commit | 871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch) | |
tree | 8718f573808810c2a1e8cb8fb6ac469093ca2784 /drivers/input/touchscreen/aw5306_ts | |
parent | 9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff) | |
download | FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.gz FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.tar.bz2 FOSSEE-netbook-kernel-source-871480933a1c28f8a9fed4c4d34d06c439a7a422.zip |
Moved, renamed, and deleted files
The original directory structure was scattered and unorganized.
Changes are basically to make it look like kernel structure.
Diffstat (limited to 'drivers/input/touchscreen/aw5306_ts')
-rwxr-xr-x | drivers/input/touchscreen/aw5306_ts/AW5306_Base.b | bin | 0 -> 41612 bytes | |||
-rwxr-xr-x | drivers/input/touchscreen/aw5306_ts/AW5306_Clb.b | bin | 0 -> 32804 bytes | |||
-rwxr-xr-x | drivers/input/touchscreen/aw5306_ts/AW5306_Drv.b | bin | 0 -> 114476 bytes | |||
-rwxr-xr-x | drivers/input/touchscreen/aw5306_ts/AW5306_Drv.h | 158 | ||||
-rwxr-xr-x | drivers/input/touchscreen/aw5306_ts/AW5306_Reg.h | 187 | ||||
-rwxr-xr-x | drivers/input/touchscreen/aw5306_ts/AW5306_ts.c | 1614 | ||||
-rwxr-xr-x | drivers/input/touchscreen/aw5306_ts/AW5306_userpara.c | 196 | ||||
-rwxr-xr-x | drivers/input/touchscreen/aw5306_ts/AW5306_userpara.h | 99 | ||||
-rwxr-xr-x | drivers/input/touchscreen/aw5306_ts/Kconfig | 11 | ||||
-rwxr-xr-x | drivers/input/touchscreen/aw5306_ts/Makefile | 35 | ||||
-rwxr-xr-x | drivers/input/touchscreen/aw5306_ts/irq_gpio.c | 149 | ||||
-rwxr-xr-x | drivers/input/touchscreen/aw5306_ts/irq_gpio.h | 13 |
12 files changed, 2462 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/aw5306_ts/AW5306_Base.b b/drivers/input/touchscreen/aw5306_ts/AW5306_Base.b Binary files differnew file mode 100755 index 00000000..e3e6c22a --- /dev/null +++ b/drivers/input/touchscreen/aw5306_ts/AW5306_Base.b diff --git a/drivers/input/touchscreen/aw5306_ts/AW5306_Clb.b b/drivers/input/touchscreen/aw5306_ts/AW5306_Clb.b Binary files differnew file mode 100755 index 00000000..40e49326 --- /dev/null +++ b/drivers/input/touchscreen/aw5306_ts/AW5306_Clb.b diff --git a/drivers/input/touchscreen/aw5306_ts/AW5306_Drv.b b/drivers/input/touchscreen/aw5306_ts/AW5306_Drv.b Binary files differnew file mode 100755 index 00000000..03f070a1 --- /dev/null +++ b/drivers/input/touchscreen/aw5306_ts/AW5306_Drv.b diff --git a/drivers/input/touchscreen/aw5306_ts/AW5306_Drv.h b/drivers/input/touchscreen/aw5306_ts/AW5306_Drv.h new file mode 100755 index 00000000..47042361 --- /dev/null +++ b/drivers/input/touchscreen/aw5306_ts/AW5306_Drv.h @@ -0,0 +1,158 @@ +/************************************************************************** +* AW5306_Drv.h +* +* AW5306 Driver code version 1.0 +* +* Create Date : 2012/06/25 +* +* Modify Date : +* +* Create by : wuhaijun +* +**************************************************************************/ + +#ifndef AW5306_DRV_H + +#define AW5306_DRV_H + +#define Release_Ver 219 + + +#define MAX_POINT 5 + +#define NUM_TX 21 // TX number of TOUCH IC +#define NUM_RX 12 // RX number of TOUCH IC + +//#define NEWBASE_PROCESS //new base process need test!!! + +#define ABS(X) ((X > 0) ? (X) : (-X)) + + +typedef enum{ + RawDataMode = 0, + DeltaMode, + MonitorMode +}enumWorkMode; + +typedef enum{ + BASE_INITIAL, + BASE_FAST_TRACE, + BASE_STABLE, + TEMP_DRIFT +} CompensateMode; + +typedef struct { + unsigned short Base[NUM_TX][NUM_RX]; + unsigned short ChipBase[NUM_TX][NUM_RX]; + signed char Flag[NUM_TX][NUM_RX]; + signed char BaseCnt[NUM_TX][NUM_RX]; + unsigned char CompensateFlag; + unsigned char TraceTempIncCnt; + unsigned char TraceTempDecCnt; + unsigned char CompensateStateFrameCnt; + short LastMaxDiff; + CompensateMode CompensateState; + unsigned int InitialFrameCnt; + unsigned char PosBigAreaTouchFlag; + unsigned char NegBigAreaTouchFlag; + unsigned char BigAreaFirstFlag; + unsigned char BigAreaChangeFlag; + unsigned short BigTouchFrame; + unsigned short FrameCnt; + unsigned char LongStableCnt; + unsigned char PosPeakCnt; + unsigned char NegPeakCnt; + unsigned char PeakCheckFrameCnt; + unsigned char BaseFrozen; + unsigned char PosPeakCompensateCnt[MAX_POINT]; + unsigned char NegPeakCompensateCnt[MAX_POINT]; +}STRUCTBASE; + +typedef struct { + unsigned char Peak[MAX_POINT][2]; + unsigned char LastPeak[MAX_POINT][2]; + unsigned char NegPeak[MAX_POINT][2]; + unsigned char CurrentPointNum; + unsigned char CurrentNegPointNum; + unsigned char LastPointNum; +}STRUCTPEAK; + +typedef struct { + unsigned short X,Y; // X,Y coordinate + unsigned char PointID; // Assigned point ID + unsigned char Event; // Event of current point +}STRUCTPOINT; + +typedef struct { + STRUCTPOINT PointInfo[MAX_POINT]; + STRUCTPOINT RptPoint[MAX_POINT]; + unsigned char PointNum; + unsigned char LastPointNum; + unsigned char NegPointNum; + unsigned char FilterPointCnt; + unsigned char FirstLiftUpFlag; + unsigned char TouchStatus; + unsigned char PointHoldCnt[MAX_POINT]; + unsigned char PointPressCnt[MAX_POINT]; + +}STRUCTFRAME; + +typedef struct { + unsigned char fileflag[14]; + unsigned char TXOFFSET[(NUM_TX+1)/2]; + unsigned char RXOFFSET[(NUM_RX+1)/2]; + unsigned char TXCAC[NUM_TX]; + unsigned char RXCAC[NUM_RX]; + unsigned char TXGAIN[NUM_TX]; + short SOFTOFFSET[NUM_TX][NUM_RX]; +}STRUCTCALI; + +#define NOISE_LISTENING 0 +#define NOISE_SCAN 1 +#define NOISE_FREQ_JUMP 2 +#define NOISE_SEEK_FAIL 3 + +#define NOISE_FRM_NORMAL 0 +#define NOISE_FRM_PRE_MEASURE 1 +#define NOISE_FRM_MEASURE 2 + +typedef struct { + unsigned char AllFrmCnt; // Frame counter to generate noise meaure frame indicator + unsigned char NoiseFrmCnt; // Frame counter for noise level checking + unsigned char IdleFrmCnt; // No touch frame counter + unsigned char State; // Noise checking state: LISTENING, SCAN, JUMP + unsigned char FrmState; // Frame type indicator: PRE_MEAUSRE, MEAUSRE, NORMAL + short NoiseNormal; // Noise in working freq + short NoiseScan; // Noise in scan freq + short Better_NoiseScan; //pfx:smaller Noise in Scan freq + unsigned char Better_ScanFreqID; //pfx:the Scan Freq for the smaller Noise + unsigned char ScanFreqID; // Scan freq ID + unsigned char WorkFreqID; // Current freq ID + short NoiseTh1; // Diff threshold for noise too high judgement + char JumpTh; // frame number threshold for freq jumping + char FailedFreqList [32]; // Searched freq indicator for freq scanning +}STRUCTNOISE; + + +void AW5306_TP_Init(void); +void AW5306_TP_Reinit(void); +void AW5306_Sleep(void); +char AW5306_TouchProcess(void); +void AW5306_ChargeMode(char mode); +unsigned char AW5306_GetPointNum(void); +unsigned char AW5306_GetPeakNum(void); +char AW5306_GetPoint(int *x,int *y, int *id, int *event,char Index); +void AW5306_GetBase(unsigned short *data, char x,char y); +void AW5306_GetDiff(short *data, char x,char y); +char AW5306_GetPeak(unsigned char *x,unsigned char *y,unsigned char Index); +char AW5306_GetNegPeak(unsigned char *x,unsigned char *y,unsigned char Index); +char AW5306_GetCalcPoint(unsigned short *x,unsigned short *y,unsigned char Index); +char AW5306_CLB(void); +void AW5306_CLB_GetCfg(void); +void AW5306_CLB_WriteCfg(void); +void TP_Force_Calibration(void); +void FreqScan(unsigned char BaseFreq); + + + +#endif diff --git a/drivers/input/touchscreen/aw5306_ts/AW5306_Reg.h b/drivers/input/touchscreen/aw5306_ts/AW5306_Reg.h new file mode 100755 index 00000000..2bbbeb00 --- /dev/null +++ b/drivers/input/touchscreen/aw5306_ts/AW5306_Reg.h @@ -0,0 +1,187 @@ +/************************************************************************** +* AW5306_Reg.h +* +* AW5306 Driver code version 1.0 +* +* Create Date : 2012/06/25 +* +* Modify Date : +* +* Create by : wuhaijun +* +**************************************************************************/ + +#ifndef AW5306_REG_H + +#define AW5306_REG_H + +#define SA_PAGE 0x00 +#define SA_IDRST 0x01 +#define SA_CTRL 0x02 +#define SA_SCANMD 0x03 +#define SA_IER 0x04 +#define SA_RX_NUM 0x05 +#define SA_RX_START 0x06 +#define SA_TX_NUM 0x07 +#define SA_TX_INDEX0 0x08 +#define SA_TX_INDEX1 0x09 +#define SA_TX_INDEX2 0x0A +#define SA_TX_INDEX3 0x0B +#define SA_TX_INDEX4 0x0C +#define SA_TX_INDEX5 0x0D +#define SA_TX_INDEX6 0x0E +#define SA_TX_INDEX7 0x0F +#define SA_TX_INDEX8 0x10 +#define SA_TX_INDEX9 0x11 +#define SA_TX_INDEX10 0x12 +#define SA_TX_INDEX11 0x13 +#define SA_TX_INDEX12 0x14 +#define SA_TX_INDEX13 0x15 +#define SA_TX_INDEX14 0x16 +#define SA_TX_INDEX15 0x17 +#define SA_TX_INDEX16 0x18 +#define SA_TX_INDEX17 0x19 +#define SA_TX_INDEX18 0x1A +#define SA_TX_INDEX19 0x1B +#define SA_TX_INDEX20 0x1C +#define SA_TXCAC0 0x1D +#define SA_TXCAC1 0x1E +#define SA_TXCAC2 0x1F +#define SA_TXCAC3 0x20 +#define SA_TXCAC4 0x21 +#define SA_TXCAC5 0x22 +#define SA_TXCAC6 0x23 +#define SA_TXCAC7 0x24 +#define SA_TXCAC8 0x25 +#define SA_TXCAC9 0x26 +#define SA_TXCAC10 0x27 +#define SA_TXCAC11 0x28 +#define SA_TXCAC12 0x29 +#define SA_TXCAC13 0x2A +#define SA_TXCAC14 0x2B +#define SA_TXCAC15 0x2C +#define SA_TXCAC16 0x2D +#define SA_TXCAC17 0x2E +#define SA_TXCAC18 0x2F +#define SA_TXCAC19 0x30 +#define SA_TXCAC20 0x31 +#define SA_TXOFFSET0 0x32 +#define SA_TXOFFSET1 0x33 +#define SA_TXOFFSET2 0x34 +#define SA_TXOFFSET3 0x35 +#define SA_TXOFFSET4 0x36 +#define SA_TXOFFSET5 0x37 +#define SA_TXOFFSET6 0x38 +#define SA_TXOFFSET7 0x39 +#define SA_TXOFFSET8 0x3A +#define SA_TXOFFSET9 0x3B +#define SA_TXOFFSET10 0x3C +#define SA_RXCAC0 0x3E +#define SA_RXCAC1 0x3F +#define SA_RXCAC2 0x40 +#define SA_RXCAC3 0x41 +#define SA_RXCAC4 0x42 +#define SA_RXCAC5 0x43 +#define SA_RXCAC6 0x44 +#define SA_RXCAC7 0x45 +#define SA_RXCAC8 0x46 +#define SA_RXCAC9 0x47 +#define SA_RXCAC10 0x48 +#define SA_RXCAC11 0x49 +#define SA_RXOFFSET0 0x4A +#define SA_RXOFFSET1 0x4B +#define SA_RXOFFSET2 0x4C +#define SA_RXOFFSET3 0x4D +#define SA_RXOFFSET4 0x4E +#define SA_RXOFFSET5 0x4F +#define SA_DRV_VLT 0x51 +#define SA_SCANFREQ1 0x52 +#define SA_SCANFREQ2 0x53 +#define SA_SCANFREQ3 0x54 +#define SA_TXADCGAIN0 0x55 +#define SA_TXADCGAIN1 0x56 +#define SA_TXADCGAIN2 0x57 +#define SA_TXADCGAIN3 0x58 +#define SA_TXADCGAIN4 0x59 +#define SA_TXADCGAIN5 0x5A +#define SA_TXADCGAIN6 0x5B +#define SA_TXADCGAIN7 0x5C +#define SA_TXADCGAIN8 0x5D +#define SA_TXADCGAIN9 0x5E +#define SA_TXADCGAIN10 0x5F +#define SA_TXADCGAIN11 0x60 +#define SA_TXADCGAIN12 0x61 +#define SA_TXADCGAIN13 0x62 +#define SA_TXADCGAIN14 0x63 +#define SA_TXADCGAIN15 0x64 +#define SA_TXADCGAIN16 0x65 +#define SA_TXADCGAIN17 0x66 +#define SA_TXADCGAIN18 0x67 +#define SA_TXADCGAIN19 0x68 +#define SA_TXADCGAIN20 0x69 +#define SA_WAITTIME 0x6A +#define SA_TCLKDLY 0x6B +#define SA_FINEADJ 0x6C +#define SA_TXCLKFREQ 0x6D +#define SA_SCANTIM 0x6E +#define SA_READSEL 0x70 +#define SA_ISR 0x71 +#define SA_STATE1 0x72 +#define SA_POSCNT 0x73 +#define SA_NEGCNT 0x74 +#define SA_VLDNUM 0x75 +#define SA_ADDRH 0x7D +#define SA_ADDRL 0x7E +#define SA_RAWDATA 0x7F +//////////////////////// +// Page 2 +//////////////////////// +#define SA_SINETABE1 0x03 +#define SA_SINETABE2 0x04 +#define SA_DATAOFFSET 0x05 +#define SA_TRACECTRL1 0x10 +#define SA_TRACECTRL2 0x11 +#define SA_TRACECTRL3 0x12 +#define SA_TRACEST 0x13 +#define SA_RPTNEGTH 0x14 +#define SA_RPTPOSTH 0x15 +#define SA_TRACESTEP 0x16 +#define SA_TRCLVLLO 0x17 +#define SA_TRCLVLPOSHI 0x18 +#define SA_TRCLVLNEGHI 0x19 +#define SA_TRACEINTERVAL 0x1A +#define SA_RXSTABLETH 0x1B +#define SA_POSLEVELTH 0x1C +#define SA_POSNUMTH 0x1D +#define SA_NEGLEVELTH 0x1E +#define SA_NEGNUMTH 0x1F +#define SA_BIGPOINTTH 0x20 +#define SA_BIGPOSTIMTH 0x21 +#define SA_BIGNEGTIMTH 0x22 +#define SA_NEGTIMTH 0x23 +#define SA_TRACEHIGHTIM 0x24 +#define SA_INITPNTTH 0x25 +#define SA_TCHCLRTIMSET 0x26 +#define SA_INITLVTH 0x27 +#define SA_MAXCHKTH 0x28 +#define SA_MINCHKTH 0x29 +#define SA_INITFORCEQUIT 0x2A +#define SA_CHAMPCFG 0x30 +#define SA_ADCCFG 0x31 +#define SA_IBCFG1 0x32 +#define SA_IBCFG2 0x33 +#define SA_LDOCFG 0x34 +#define SA_OSCCFG1 0x35 +#define SA_OSCCFG2 0x36 +#define SA_OSCCFG3 0x37 +#define SA_EN_CLK_QNTZ1 0x38 +#define SA_EN_CLK_QNTZ2 0x39 +#define SA_CPFREQ 0x3A +#define SA_ATEST1 0x3B +#define SA_ATEST2 0x3C +#define SA_RAMTST 0x60 +#define SA_TESTCFG 0x61 +#define SA_TSTDATAH 0x62 +#define SA_TSTDATAL 0x63 +#endif + diff --git a/drivers/input/touchscreen/aw5306_ts/AW5306_ts.c b/drivers/input/touchscreen/aw5306_ts/AW5306_ts.c new file mode 100755 index 00000000..f623c646 --- /dev/null +++ b/drivers/input/touchscreen/aw5306_ts/AW5306_ts.c @@ -0,0 +1,1614 @@ +/* + * drivers/input/touchscreen/aw5306/aw5306.c + * + * FocalTech aw5306 TouchScreen driver. + * + * Copyright (c) 2010 Focal tech Ltd. + * + * 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. + * + * + * note: only support mulititouch Wenfs 2010-10-01 + */ +#include <linux/module.h> +#include <linux/kernel.h> +#include <linux/i2c.h> +#include <linux/input.h> +#ifdef CONFIG_HAS_EARLYSUSPEND +#include <linux/earlysuspend.h> +#endif +#include <linux/interrupt.h> +#include <linux/delay.h> +#include <mach/hardware.h> +#include <linux/platform_device.h> +#include <linux/suspend.h> +#include <linux/wait.h> +#include <asm/uaccess.h> +#include <linux/irq.h> +#include <linux/gpio.h> +#include <mach/wmt_iomux.h> +#include <linux/slab.h> +#include "AW5306_Drv.h" +#include "AW5306_userpara.h" +#include "irq_gpio.h" + +#define CONFIG_AW5306_MULTITOUCH (1) +#define DEV_AW5306 "touch_aw5306" +#define TS_I2C_NAME "aw5306-ts" +#define AW5306_I2C_ADDR 0x38 +#define AW5306_I2C_BUS 0x01 + +//#define DEBUG_EN + +#undef dbg +#ifdef DEBUG_EN + #define dbg(fmt,args...) printk("DBG:%s_%d:"fmt,__FUNCTION__,__LINE__,##args) +#else + #define dbg(fmt,args...) +#endif + +#undef dbg_err +#define dbg_err(fmt,args...) printk("ERR:%s_%d:"fmt,__FUNCTION__,__LINE__,##args) + + + +struct ts_event { + int x[5]; + int y[5]; + int pressure; + int touch_ID[5]; + int touch_point; + int pre_point; +}; + +struct AW5306_ts_data { + const char *name; + struct input_dev *input_dev; + struct ts_event event; + struct work_struct pen_event_work; + struct workqueue_struct *ts_workqueue; + struct kobject *kobj; +#ifdef CONFIG_HAS_EARLYSUSPEND + struct early_suspend early_suspend; +#endif + struct timer_list touch_timer; + + int irq; + int irqgpio; + int rstgpio; + + int reslx; + int resly; + int nt; + int nb; + int xch; + int ych; + int swap; + int dbg; + int lcd_exchg; +}; + + +struct AW5306_ts_data *pContext=NULL; +static struct i2c_client *l_client=NULL; +static unsigned char suspend_flag=0; //0: sleep out; 1: sleep in +static short tp_idlecnt = 0; +static char tp_SlowMode = 0; +//static struct class *i2c_dev_class; + +extern char AW5306_CLB(void); +extern void AW5306_CLB_GetCfg(void); +extern STRUCTCALI AW_Cali; +extern AW5306_UCF AWTPCfg; +extern STRUCTBASE AW_Base; +extern short Diff[NUM_TX][NUM_RX]; +extern short adbDiff[NUM_TX][NUM_RX]; +extern short AWDeltaData[32]; + +char AW_CALI_FILENAME[50] = {0,}; +char AW_UCF_FILENAME[50] = {0,}; + +extern int wmt_setsyspara(char *varname, unsigned char *varval); +extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen); + + +void __aeabi_unwind_cpp_pr0(void) +{ +} + +void __aeabi_unwind_cpp_pr1(void) +{ +} + + +int AW_nvram_read(char *filename, char *buf, ssize_t len, int offset) +{ + struct file *fd; + //ssize_t ret; + int retLen = -1; + + mm_segment_t old_fs = get_fs(); + set_fs(KERNEL_DS); + + fd = filp_open(filename, O_RDONLY, 0); + + if(IS_ERR(fd)) { + printk("[AW5306][nvram_read] : failed to open!!\n"); + return -1; + } + + do{ + if ((fd->f_op == NULL) || (fd->f_op->read == NULL)) + { + printk("[AW5306][nvram_read] : file can not be read!!\n"); + break; + } + + if (fd->f_pos != offset) { + if (fd->f_op->llseek) { + if(fd->f_op->llseek(fd, offset, 0) != offset) { + printk("[AW5306][nvram_read] : failed to seek!!\n"); + break; + } + } else { + fd->f_pos = offset; + } + } + + retLen = fd->f_op->read(fd, + buf, + len, + &fd->f_pos); + + }while(false); + + filp_close(fd, NULL); + + set_fs(old_fs); + + + return retLen; +} + +int AW_nvram_write(char *filename, char *buf, ssize_t len, int offset) +{ + struct file *fd; + //ssize_t ret; + int retLen = -1; + + mm_segment_t old_fs = get_fs(); + set_fs(KERNEL_DS); + + fd = filp_open(filename, O_WRONLY|O_CREAT, 0666); + + if(IS_ERR(fd)) { + printk("[AW5306][nvram_write] : failed to open!!\n"); + return -1; + } + + do{ + if ((fd->f_op == NULL) || (fd->f_op->write == NULL)) + { + printk("[AW5306][nvram_write] : file can not be write!!\n"); + break; + } /* End of if */ + + if (fd->f_pos != offset) { + if (fd->f_op->llseek) { + if(fd->f_op->llseek(fd, offset, 0) != offset) { + printk("[AW5306][nvram_write] : failed to seek!!\n"); + break; + } + } else { + fd->f_pos = offset; + } + } + + retLen = fd->f_op->write(fd, + buf, + len, + &fd->f_pos); + + }while(false); + + filp_close(fd, NULL); + + set_fs(old_fs); + + return retLen; +} + + +int AW_I2C_WriteByte(u8 addr, u8 para) +{ + int ret; + u8 buf[3]; + struct i2c_msg msg[] = { + { + .addr = l_client->addr, + .flags = 0, + .len = 2, + .buf = buf, + }, + }; + buf[0] = addr; + buf[1] = para; + ret = i2c_transfer(l_client->adapter, msg, 1); + return ret; +} + + +unsigned char AW_I2C_ReadByte(u8 addr) +{ + int ret; + u8 buf[2] = {0}; + struct i2c_msg msgs[] = { + { + .addr = l_client->addr, + .flags = 0, + .len = 1, + .buf = buf, + }, + { + .addr = l_client->addr, + .flags = I2C_M_RD, + .len = 1, + .buf = buf, + }, + }; + buf[0] = addr; + //msleep(1); + ret = i2c_transfer(l_client->adapter, msgs, 2); + return buf[0]; +} + +unsigned char AW_I2C_ReadXByte( unsigned char *buf, unsigned char addr, unsigned short len) +{ + int ret,i; + u8 rdbuf[512] = {0}; + struct i2c_msg msgs[] = { + { + .addr = l_client->addr, + .flags = 0, + .len = 1, + .buf = rdbuf, + }, + { + .addr = l_client->addr, + .flags = I2C_M_RD, + .len = len, + .buf = rdbuf, + }, + }; + rdbuf[0] = addr; + //msleep(1); + ret = i2c_transfer(l_client->adapter, msgs, 2); + if (ret < 0) + pr_err("msg %s i2c read error: %d\n", __func__, ret); + for(i = 0; i < len; i++) + { + buf[i] = rdbuf[i]; + } + return ret; +} + +unsigned char AW_I2C_WriteXByte( unsigned char *buf, unsigned char addr, unsigned short len) +{ + int ret,i; + u8 wdbuf[512] = {0}; + + struct i2c_msg msgs[] = { + { + .addr = l_client->addr, + .flags = 0, + .len = len+1, + .buf = wdbuf, + } + }; + + wdbuf[0] = addr; + for(i = 0; i < len; i++) + { + wdbuf[i+1] = buf[i]; + } + //msleep(1); + ret = i2c_transfer(l_client->adapter, msgs, 1); + if (ret < 0) + pr_err("msg %s i2c read error: %d\n", __func__, ret); + return ret; +} + + +void AW_Sleep(unsigned int msec) +{ + msleep(msec); +} + +static ssize_t AW5306_get_Cali(struct device* cd,struct device_attribute *attr, char* buf); +static ssize_t AW5306_set_Cali(struct device* cd,struct device_attribute *attr, const char *buf, size_t count); +static ssize_t AW5306_get_reg(struct device* cd,struct device_attribute *attr, char* buf); +static ssize_t AW5306_write_reg(struct device* cd,struct device_attribute *attr, const char *buf, size_t count); +static ssize_t AW5306_get_Base(struct device* cd,struct device_attribute *attr, char* buf); +static ssize_t AW5306_get_Diff(struct device* cd,struct device_attribute *attr, char* buf); +static ssize_t AW5306_get_adbBase(struct device* cd,struct device_attribute *attr, char* buf); +static ssize_t AW5306_get_adbDiff(struct device* cd,struct device_attribute *attr, char* buf); +static ssize_t AW5306_get_FreqScan(struct device* cd,struct device_attribute *attr, char* buf); +static ssize_t AW5306_Set_FreqScan(struct device* cd, struct device_attribute *attr,const char* buf, size_t len); +static ssize_t AW5306_GetUcf(struct device* cd,struct device_attribute *attr, char* buf); + + + +static DEVICE_ATTR(cali, S_IRUGO | S_IWUGO, AW5306_get_Cali, AW5306_set_Cali); +static DEVICE_ATTR(readreg, S_IRUGO | S_IWUGO, AW5306_get_reg, AW5306_write_reg); +static DEVICE_ATTR(base, S_IRUGO | S_IWUSR, AW5306_get_Base, NULL); +static DEVICE_ATTR(diff, S_IRUGO | S_IWUSR, AW5306_get_Diff, NULL); +static DEVICE_ATTR(adbbase, S_IRUGO | S_IWUSR, AW5306_get_adbBase, NULL); +static DEVICE_ATTR(adbdiff, S_IRUGO | S_IWUSR, AW5306_get_adbDiff, NULL); +static DEVICE_ATTR(freqscan, S_IRUGO | S_IWUGO, AW5306_get_FreqScan, AW5306_Set_FreqScan); +static DEVICE_ATTR(getucf, S_IRUGO | S_IWUSR, AW5306_GetUcf, NULL); + + +static ssize_t AW5306_get_Cali(struct device* cd,struct device_attribute *attr, char* buf) +{ + unsigned char i,j; + ssize_t len = 0; + + len += snprintf(buf+len, PAGE_SIZE-len,"AWINIC RELEASE CODE VER = %d\n", Release_Ver); + + len += snprintf(buf+len, PAGE_SIZE-len,"*****AW5306 Calibrate data*****\n"); + len += snprintf(buf+len, PAGE_SIZE-len,"TXOFFSET:"); + + for(i=0;i<11;i++) + { + len += snprintf(buf+len, PAGE_SIZE-len, "0x%02X ", AW_Cali.TXOFFSET[i]); + } + + len += snprintf(buf+len, PAGE_SIZE-len, "\n"); + len += snprintf(buf+len, PAGE_SIZE-len, "RXOFFSET:"); + + for(i=0;i<6;i++) + { + len += snprintf(buf+len, PAGE_SIZE-len, "0x%02X ", AW_Cali.RXOFFSET[i]); + } + + len += snprintf(buf+len, PAGE_SIZE-len, "\n"); + len += snprintf(buf+len, PAGE_SIZE-len, "TXCAC:"); + + for(i=0;i<21;i++) + { + len += snprintf(buf+len, PAGE_SIZE-len, "0x%02X ", AW_Cali.TXCAC[i]); + } + + len += snprintf(buf+len, PAGE_SIZE-len, "\n"); + len += snprintf(buf+len, PAGE_SIZE-len, "RXCAC:"); + + for(i=0;i<12;i++) + { + len += snprintf(buf+len, PAGE_SIZE-len, "0x%02X ", AW_Cali.RXCAC[i]); + } + + len += snprintf(buf+len, PAGE_SIZE-len, "\n"); + len += snprintf(buf+len, PAGE_SIZE-len, "TXGAIN:"); + + for(i=0;i<21;i++) + { + len += snprintf(buf+len, PAGE_SIZE-len, "0x%02X ", AW_Cali.TXGAIN[i]); + } + + len += snprintf(buf+len, PAGE_SIZE-len, "\n"); + + for(i=0;i<AWTPCfg.TX_LOCAL;i++) + { + for(j=0;j<AWTPCfg.RX_LOCAL;j++) + { + len += snprintf(buf+len, PAGE_SIZE-len, "%4d ", AW_Cali.SOFTOFFSET[i][j]); + } + len += snprintf(buf+len, PAGE_SIZE-len, "\n"); + } + return len; + +} + +static ssize_t AW5306_set_Cali(struct device* cd,struct device_attribute *attr, const char* buf, size_t count) +{ + struct AW5306_ts_data *data = i2c_get_clientdata(l_client); + + unsigned long on_off = simple_strtoul(buf, NULL, 10); + + if(on_off == 1) + { + #ifdef INTMODE + wmt_disable_gpirq(data ->irqgpio); + AW5306_Sleep(); + suspend_flag = 1; + AW_Sleep(50); + + TP_Force_Calibration(); + + AW5306_TP_Reinit(); + wmt_enable_gpirq(data->irqgpio); + suspend_flag = 0; + + #else + suspend_flag = 1; + AW_Sleep(50); + + TP_Force_Calibration(); + + AW5306_TP_Reinit(); + tp_idlecnt = 0; + tp_SlowMode = 0; + suspend_flag = 0; + data->touch_timer.expires = jiffies + HZ/AWTPCfg.FAST_FRAME; + add_timer(&data->touch_timer); + #endif + } + + return count; +} + + +static ssize_t AW5306_get_adbBase(struct device* cd,struct device_attribute *attr, char* buf) +{ + unsigned char i,j; + ssize_t len = 0; + + len += snprintf(buf+len, PAGE_SIZE-len, "base: \n"); + for(i=0;i< AWTPCfg.TX_LOCAL;i++) + { + for(j=0;j<AWTPCfg.RX_LOCAL;j++) + { + len += snprintf(buf+len, PAGE_SIZE-len, "%4d, ",AW_Base.Base[i][j]+AW_Cali.SOFTOFFSET[i][j]); + } + len += snprintf(buf+len, PAGE_SIZE-len, "\n"); + } + + return len; +} + +static ssize_t AW5306_get_Base(struct device* cd,struct device_attribute *attr, char* buf) +{ + unsigned char i,j; + ssize_t len = 0; + + *(buf+len) = AWTPCfg.TX_LOCAL; + len++; + *(buf+len) = AWTPCfg.RX_LOCAL; + len++; + + for(i=0;i< AWTPCfg.TX_LOCAL;i++) + { + for(j=0;j<AWTPCfg.RX_LOCAL;j++) + { + *(buf+len) = (char)(((AW_Base.Base[i][j]+AW_Cali.SOFTOFFSET[i][j]) & 0xFF00)>>8); + len++; + *(buf+len) = (char)((AW_Base.Base[i][j]+AW_Cali.SOFTOFFSET[i][j]) & 0x00FF); + len++; + } + } + return len; + +} + +static ssize_t AW5306_get_adbDiff(struct device* cd,struct device_attribute *attr, char* buf) +{ + unsigned char i,j; + ssize_t len = 0; + + len += snprintf(buf+len, PAGE_SIZE-len, "Diff: \n"); + for(i=0;i< AWTPCfg.TX_LOCAL;i++) + { + for(j=0;j<AWTPCfg.RX_LOCAL;j++) + { + len += snprintf(buf+len, PAGE_SIZE-len, "%4d, ",adbDiff[i][j]); + } + len += snprintf(buf+len, PAGE_SIZE-len, "\n"); + } + + return len; +} + +static ssize_t AW5306_get_Diff(struct device* cd,struct device_attribute *attr, char* buf) +{ + unsigned char i,j; + ssize_t len = 0; + + *(buf+len) = AWTPCfg.TX_LOCAL; + len++; + *(buf+len) = AWTPCfg.RX_LOCAL; + len++; + + for(i=0;i< AWTPCfg.TX_LOCAL;i++) + { + for(j=0;j<AWTPCfg.RX_LOCAL;j++) + { + *(buf+len) = (char)((adbDiff[i][j] & 0xFF00)>>8); + len++; + *(buf+len) = (char)(adbDiff[i][j] & 0x00FF); + len++; + } + } + return len; +} + +static ssize_t AW5306_get_FreqScan(struct device* cd,struct device_attribute *attr, char* buf) +{ + unsigned char i; + ssize_t len = 0; + + for(i=0;i< 32;i++) + { + //*(buf+len) = (char)((AWDeltaData[i] & 0xFF00)>>8); + //len++; + //*(buf+len) = (char)(AWDeltaData[i] & 0x00FF); + //len++; + len += snprintf(buf+len, PAGE_SIZE-len, "%4d, ",AWDeltaData[i]); + } + + len += snprintf(buf+len, PAGE_SIZE-len, "\n"); + return len; +} + +static ssize_t AW5306_Set_FreqScan(struct device* cd, struct device_attribute *attr, + const char* buf, size_t len) +{ + struct AW5306_ts_data *data = i2c_get_clientdata(l_client); + unsigned long Basefreq = simple_strtoul(buf, NULL, 10); + + if(Basefreq < 16) + { + #ifdef INTMODE + wmt_disable_gpirq(data ->irqgpio); + AW5306_Sleep(); + suspend_flag = 1; + AW_Sleep(50); + + FreqScan(Basefreq); + + AW5306_TP_Reinit(); + wmt_enable_gpirq(data ->irqgpio); + suspend_flag = 0; + #else + suspend_flag = 1; + AW_Sleep(50); + + FreqScan(Basefreq); + + AW5306_TP_Reinit(); + tp_idlecnt = 0; + tp_SlowMode = 0; + suspend_flag = 0; + data->touch_timer.expires = jiffies + HZ/AWTPCfg.FAST_FRAME; + add_timer(&data->touch_timer); + #endif + } + + return len; +} + +static ssize_t AW5306_get_reg(struct device* cd,struct device_attribute *attr, char* buf) +{ + struct AW5306_ts_data *data = i2c_get_clientdata(l_client); + u8 reg_val[128]; + ssize_t len = 0; + u8 i; + + if(suspend_flag != 1) + { +#ifdef INTMODE + wmt_disable_gpirq(data ->irqgpio); + AW5306_Sleep(); + suspend_flag = 1; + AW_Sleep(50); + + AW_I2C_ReadXByte(reg_val,0,127); + + AW5306_TP_Reinit(); + wmt_enable_gpirq(data->irqgpio); + suspend_flag = 0; +#else + suspend_flag = 1; + + AW_Sleep(50); + + AW_I2C_ReadXByte(reg_val,0,127); + + AW5306_TP_Reinit(); + tp_idlecnt = 0; + tp_SlowMode = 0; + suspend_flag = 0; + data->touch_timer.expires = jiffies + HZ/AWTPCfg.FAST_FRAME; + add_timer(&data->touch_timer); +#endif + } + else + { + AW_I2C_ReadXByte(reg_val,0,127); + } + for(i=0;i<0x7F;i++) + { + len += snprintf(buf+len, PAGE_SIZE-len, "reg%02X = 0x%02X, ", i,reg_val[i]); + } + + return len; + +} + +static ssize_t AW5306_write_reg(struct device* cd,struct device_attribute *attr, const char *buf, size_t count) +{ + struct AW5306_ts_data *data = i2c_get_clientdata(l_client); + int databuf[2]; + + if(2 == sscanf(buf, "%d %d", &databuf[0], &databuf[1])) + { + if(suspend_flag != 1) + { + #ifdef INTMODE + wmt_disable_gpirq(data ->irqgpio); + AW5306_Sleep(); + suspend_flag = 1; + AW_Sleep(50); + + AW_I2C_WriteByte((u8)databuf[0],(u8)databuf[1]); + + AW5306_TP_Reinit(); + //ctp_enable_irq(); + wmt_enable_gpirq(data->irqgpio); + suspend_flag = 0; + #else + suspend_flag = 1; + AW_Sleep(50); + + AW_I2C_WriteByte((u8)databuf[0],(u8)databuf[1]); + + AW5306_TP_Reinit(); + tp_idlecnt = 0; + tp_SlowMode = 0; + suspend_flag = 0; + data->touch_timer.expires = jiffies + HZ/AWTPCfg.FAST_FRAME; + add_timer(&data->touch_timer); + #endif + } + else + { + AW_I2C_WriteByte((u8)databuf[0],(u8)databuf[1]); + } + } + else + { + printk("invalid content: '%s', length = %d\n", buf, count); + } + return count; +} + +static ssize_t AW5306_GetUcf(struct device* cd,struct device_attribute *attr, char* buf) +{ + ssize_t len = 0; + + len += snprintf(buf+len, PAGE_SIZE-len,"*****AW5306 UCF DATA*****\n"); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.TX_LOCAL,AWTPCfg.RX_LOCAL); + len += snprintf(buf+len, PAGE_SIZE-len,"(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d}\n", + AWTPCfg.TX_ORDER[0],AWTPCfg.TX_ORDER[1],AWTPCfg.TX_ORDER[2],AWTPCfg.TX_ORDER[3],AWTPCfg.TX_ORDER[4], + AWTPCfg.TX_ORDER[5],AWTPCfg.TX_ORDER[6],AWTPCfg.TX_ORDER[7],AWTPCfg.TX_ORDER[8],AWTPCfg.TX_ORDER[9], + AWTPCfg.TX_ORDER[10],AWTPCfg.TX_ORDER[11],AWTPCfg.TX_ORDER[12],AWTPCfg.TX_ORDER[13],AWTPCfg.TX_ORDER[14], + AWTPCfg.TX_ORDER[15],AWTPCfg.TX_ORDER[16],AWTPCfg.TX_ORDER[17],AWTPCfg.TX_ORDER[19],AWTPCfg.TX_ORDER[19], + AWTPCfg.TX_ORDER[20]); + len += snprintf(buf+len, PAGE_SIZE-len,"{%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d},\n", + AWTPCfg.RX_ORDER[0],AWTPCfg.RX_ORDER[1],AWTPCfg.RX_ORDER[2],AWTPCfg.RX_ORDER[3], + AWTPCfg.RX_ORDER[4],AWTPCfg.RX_ORDER[5],AWTPCfg.RX_ORDER[6],AWTPCfg.RX_ORDER[7], + AWTPCfg.RX_ORDER[8],AWTPCfg.RX_ORDER[9],AWTPCfg.RX_ORDER[10],AWTPCfg.RX_ORDER[11]); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.RX_START,AWTPCfg.HAVE_KEY_LINE); + len += snprintf(buf+len, PAGE_SIZE-len,"{%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d},\n", + AWTPCfg.KeyLineValid[0],AWTPCfg.KeyLineValid[1],AWTPCfg.KeyLineValid[2],AWTPCfg.KeyLineValid[3], + AWTPCfg.KeyLineValid[4],AWTPCfg.KeyLineValid[5],AWTPCfg.KeyLineValid[6],AWTPCfg.KeyLineValid[7], + AWTPCfg.KeyLineValid[8],AWTPCfg.KeyLineValid[9],AWTPCfg.KeyLineValid[10],AWTPCfg.KeyLineValid[11]); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.MAPPING_MAX_X,AWTPCfg.MAPPING_MAX_Y); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.GainClbDeltaMax,AWTPCfg.GainClbDeltaMin); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.KeyLineDeltaMax,AWTPCfg.KeyLineDeltaMin); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.OffsetClbExpectedMax,AWTPCfg.OffsetClbExpectedMin); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.RawDataDeviation,AWTPCfg.CacMultiCoef); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.RawDataCheckMin,AWTPCfg.RawDataCheckMax); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,%d,\n",AWTPCfg.FLYING_TH,AWTPCfg.MOVING_TH,AWTPCfg.MOVING_ACCELER); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.PEAK_TH,AWTPCfg.GROUP_TH); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,%d,\n",AWTPCfg.BIGAREA_TH,AWTPCfg.BIGAREA_CNT,AWTPCfg.BIGAREA_FRESHCNT); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,%d,\n",AWTPCfg.CACULATE_COEF,AWTPCfg.FIRST_CALI,AWTPCfg.RAWDATA_DUMP_SWITCH); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,0x%x,\n",AWTPCfg.MULTI_SCANFREQ,AWTPCfg.BASE_FREQ,AWTPCfg.FREQ_OFFSET); + len += snprintf(buf+len, PAGE_SIZE-len,"0x%x,0x%x,0x%x,\n",AWTPCfg.WAIT_TIME,AWTPCfg.CHAMP_CFG,AWTPCfg.POSLEVEL_TH); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,\n",AWTPCfg.ESD_PROTECT); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,%d,%d,%d,\n",AWTPCfg.MARGIN_COMPENSATE,AWTPCfg.MARGIN_COMP_DATA_UP, + AWTPCfg.MARGIN_COMP_DATA_DOWN,AWTPCfg.MARGIN_COMP_DATA_LEFT,AWTPCfg.MARGIN_COMP_DATA_RIGHT); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,%d,%d,\n",AWTPCfg.POINT_RELEASEHOLD,AWTPCfg.MARGIN_RELEASEHOLD, + AWTPCfg.POINT_PRESSHOLD,AWTPCfg.KEY_PRESSHOLD); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,%d,\n",AWTPCfg.PEAK_ROW_COMPENSATE,AWTPCfg.PEAK_COL_COMPENSATE, + AWTPCfg.PEAK_COMPENSATE_COEF); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.LCD_NOISE_PROCESS,AWTPCfg.LCD_NOISETH); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.FALSE_PEAK_PROCESS,AWTPCfg.FALSE_PEAK_TH); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.STABLE_DELTA_X,AWTPCfg.STABLE_DELTA_Y); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,%d,\n",AWTPCfg.DEBUG_LEVEL,AWTPCfg.FAST_FRAME,AWTPCfg.SLOW_FRAME); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.GAIN_CLB_SEPERATE,AWTPCfg.MARGIN_PREFILTER); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.BIGAREA_HOLDPOINT,AWTPCfg.CHARGE_NOISE); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.FREQ_JUMP,AWTPCfg.PEAK_VALID_CHECK); + len += snprintf(buf+len, PAGE_SIZE-len,"%d,%d,\n",AWTPCfg.WATER_REMOVE,AWTPCfg.INT_MODE); + + return len; + +} + + +static int AW5306_create_sysfs(struct i2c_client *client) +{ + int err; + struct device *dev = &(client->dev); + + //TS_DBG("%s", __func__); + + err = device_create_file(dev, &dev_attr_cali); + err = device_create_file(dev, &dev_attr_readreg); + err = device_create_file(dev, &dev_attr_base); + err = device_create_file(dev, &dev_attr_diff); + err = device_create_file(dev, &dev_attr_adbbase); + err = device_create_file(dev, &dev_attr_adbdiff); + err = device_create_file(dev, &dev_attr_freqscan); + err = device_create_file(dev, &dev_attr_getucf); + return err; +} + +static void AW5306_ts_release(void) +{ + struct AW5306_ts_data *data = pContext; +#ifdef CONFIG_AW5306_MULTITOUCH + #ifdef TOUCH_KEY_SUPPORT + if(1 == key_tp){ + if(key_val == 1){ + input_report_key(data->input_dev, KEY_MENU, 0); + input_sync(data->input_dev); + } + else if(key_val == 2){ + input_report_key(data->input_dev, KEY_BACK, 0); + input_sync(data->input_dev); + // printk("===KEY 2 upupupupupu===++=\n"); + } + else if(key_val == 3){ + input_report_key(data->input_dev, KEY_SEARCH, 0); + input_sync(data->input_dev); + // printk("===KEY 3 upupupupupu===++=\n"); + } + else if(key_val == 4){ + input_report_key(data->input_dev, KEY_HOMEPAGE, 0); + input_sync(data->input_dev); + // printk("===KEY 4 upupupupupu===++=\n"); + } + else if(key_val == 5){ + input_report_key(data->input_dev, KEY_VOLUMEDOWN, 0); + input_sync(data->input_dev); + // printk("===KEY 5 upupupupupu===++=\n"); + } + else if(key_val == 6){ + input_report_key(data->input_dev, KEY_VOLUMEUP, 0); + input_sync(data->input_dev); + // printk("===KEY 6 upupupupupu===++=\n"); + } +// input_report_key(data->input_dev, key_val, 0); + //printk("Release Key = %d\n",key_val); + //printk("Release Keyi+++++++++++++++++++++++++++++\n"); + } else{ + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 0); + } + #else + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 0); + #endif + +#else + input_report_abs(data->input_dev, ABS_PRESSURE, 0); + input_report_key(data->input_dev, BTN_TOUCH, 0); +#endif + + input_mt_sync(data->input_dev); + input_sync(data->input_dev); + return; + +} + + +static void Point_adjust(int *x, int *y) +{ + struct AW5306_ts_data *AW5306_ts = pContext; + int temp; + + if (AW5306_ts->swap) { + temp = *x; + *x = *y; + *y = temp; + } + if (AW5306_ts->xch) + *x = AW5306_ts->reslx - *x; + if (AW5306_ts->ych) + *y = AW5306_ts->resly - *y; + + if (AW5306_ts->lcd_exchg) { + int tmp; + tmp = *x; + *x = *y; + *y = AW5306_ts->reslx - tmp; + } +} + + +static int AW5306_read_data(void) +{ + struct AW5306_ts_data *data = pContext; + struct ts_event *event = &data->event; + int Pevent; + int i = 0; + + AW5306_TouchProcess(); + + //memset(event, 0, sizeof(struct ts_event)); + event->touch_point = AW5306_GetPointNum(); + + for(i=0;i<event->touch_point;i++) + { + AW5306_GetPoint(&event->x[i],&event->y[i],&event->touch_ID[i],&Pevent,i); + //swap(event->x[i], event->y[i]); + Point_adjust(&event->x[i], &event->y[i]); +// printk("key%d = %d,%d,%d \n",i,event->x[i],event->y[i],event->touch_ID[i] ); + } + + if (event->touch_point == 0) + { + if(tp_idlecnt <= AWTPCfg.FAST_FRAME*5) + { + tp_idlecnt++; + } + if(tp_idlecnt > AWTPCfg.FAST_FRAME*5) + { + tp_SlowMode = 1; + } + + if (event->pre_point != 0) + { + AW5306_ts_release(); + event->pre_point = 0; + } + return 1; + } + else + { + tp_SlowMode = 0; + tp_idlecnt = 0; + event->pre_point = event->touch_point; + event->pressure = 200; + dbg("%s: 1:%d %d 2:%d %d \n", __func__, + event->x[0], event->y[0], event->x[1], event->y[1]); + + return 0; + } +} + +static void AW5306_report_multitouch(void) +{ + struct AW5306_ts_data *data = pContext; + struct ts_event *event = &data->event; + +#ifdef TOUCH_KEY_SUPPORT + if(1 == key_tp){ + return; + } +#endif + + switch(event->touch_point) { + case 5: + input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID[4]); + //input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure); + input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x[4]); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y[4]); + //input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1); + input_mt_sync(data->input_dev); + // printk("=++==x5 = %d,y5 = %d ====\n",event->x[4],event->y[4]); + case 4: + input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID[3]); + //input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure); + input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x[3]); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y[3]); + //input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1); + input_mt_sync(data->input_dev); + // printk("===x4 = %d,y4 = %d ====\n",event->x[3],event->y[3]); + case 3: + input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID[2]); + //input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure); + input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x[2]); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y[2]); + //input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1); + input_mt_sync(data->input_dev); + // printk("===x3 = %d,y3 = %d ====\n",event->x[2],event->y[2]); + case 2: + input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID[1]); + //input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure); + input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x[1]); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y[1]); + //input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1); + input_mt_sync(data->input_dev); + // printk("===x2 = %d,y2 = %d ====\n",event->x[1],event->y[1]); + case 1: + input_report_abs(data->input_dev, ABS_MT_TRACKING_ID, event->touch_ID[0]); + //input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, event->pressure); + input_report_abs(data->input_dev, ABS_MT_POSITION_X, event->x[0]); + input_report_abs(data->input_dev, ABS_MT_POSITION_Y, event->y[0]); + //input_report_abs(data->input_dev, ABS_MT_WIDTH_MAJOR, 1); + input_mt_sync(data->input_dev); + // printk("===x1 = %d,y1 = %d ====\n",event->x[0],event->y[0]); + break; + default: +// print_point_info("==touch_point default =\n"); + break; + } + + input_sync(data->input_dev); + dbg("%s: 1:%d %d 2:%d %d \n", __func__, + event->x[0], event->y[0], event->x[1], event->y[1]); + return; +} + +#ifdef TOUCH_KEY_SUPPORT +static void AW5306_report_touchkey(void) +{ + struct AW5306_ts_data *data = pContext; + struct ts_event *event = &data->event; + //printk("x=%d===Y=%d\n",event->x[0],event->y[0]); + +#ifdef TOUCH_KEY_FOR_ANGDA + if((1==event->touch_point)&&(event->x1 > TOUCH_KEY_X_LIMIT)){ + key_tp = 1; + if(event->x1 < 40){ + key_val = 1; + input_report_key(data->input_dev, key_val, 1); + input_sync(data->input_dev); + // print_point_info("===KEY 1====\n"); + }else if(event->y1 < 90){ + key_val = 2; + input_report_key(data->input_dev, key_val, 1); + input_sync(data->input_dev); + // print_point_info("===KEY 2 ====\n"); + }else{ + key_val = 3; + input_report_key(data->input_dev, key_val, 1); + input_sync(data->input_dev); + // print_point_info("===KEY 3====\n"); + } + } else{ + key_tp = 0; + } +#endif +#ifdef TOUCH_KEY_FOR_EVB13 + if((1==event->touch_point)&&((event->y[0] > 510)&&(event->y[0]<530))) + { + if(key_tp != 1) + { + input_report_abs(data->input_dev, ABS_MT_TOUCH_MAJOR, 0); + input_sync(data->input_dev); + } + else + { + //printk("===KEY touch ++++++++++====++=\n"); + + if(event->x[0] < 90){ + key_val = 1; + input_report_key(data->input_dev, KEY_MENU, 1); + input_sync(data->input_dev); + // printk("===KEY 1===++=\n"); + }else if((event->x[0] < 230)&&(event->x[0]>185)){ + key_val = 2; + input_report_key(data->input_dev, KEY_BACK, 1); + input_sync(data->input_dev); + // printk("===KEY 2 ====\n"); + }else if((event->x[0] < 355)&&(event->x[0]>305)){ + key_val = 3; + input_report_key(data->input_dev, KEY_SEARCH, 1); + input_sync(data->input_dev); + // print_point_info("===KEY 3====\n"); + }else if ((event->x[0] < 497)&&(event->x[0]>445)) { + key_val = 4; + input_report_key(data->input_dev, KEY_HOMEPAGE, 1); + input_sync(data->input_dev); + // print_point_info("===KEY 4====\n"); + }else if ((event->x[0] < 615)&&(event->x[0]>570)) { + key_val = 5; + input_report_key(data->input_dev, KEY_VOLUMEDOWN, 1); + input_sync(data->input_dev); + // print_point_info("===KEY 5====\n"); + }else if ((event->x[0] < 750)&&(event->x[0]>705)) { + key_val = 6; + input_report_key(data->input_dev, KEY_VOLUMEUP, 1); + input_sync(data->input_dev); + // print_point_info("===KEY 6====\n"); + } + } + key_tp = 1; + } + else + { + key_tp = 0; + } +#endif + +#ifdef TOUCH_KEY_LIGHT_SUPPORT + AW5306_lighting(); +#endif + return; +} +#endif + + +static void AW5306_report_value(void) +{ + AW5306_report_multitouch(); +#ifdef TOUCH_KEY_SUPPORT + AW5306_report_touchkey(); +#endif + return; +} /*end AW5306_report_value*/ + + +#ifdef INTMODE +static void AW5306_ts_pen_irq_work(struct work_struct *work) +{ + int ret = -1; + + ret = AW5306_read_data(); + if (ret == 0) + AW5306_report_value(); + + wmt_enable_gpirq(pContext->irqgpio); + + return; +} +#else +static void AW5306_ts_pen_irq_work(struct work_struct *work) +{ + int ret = -1; + + if(suspend_flag != 1) + { + ret = AW5306_read_data(); + if (ret == 0) { + AW5306_report_value(); + } + } + else + { + AW5306_Sleep(); + } +} + +#endif + + + +static irqreturn_t aw5306_interrupt(int irq, void *dev) +{ + struct AW5306_ts_data *AW5306_ts= dev; + +//printk("I\n"); + if (wmt_is_tsint(AW5306_ts->irqgpio)) + { + wmt_clr_int(AW5306_ts->irqgpio); + if (wmt_is_tsirq_enable(AW5306_ts->irqgpio)) + { + wmt_disable_gpirq(AW5306_ts->irqgpio); + #ifdef CONFIG_HAS_EARLYSUSPEND + if(!AW5306_ts->earlysus) queue_work(AW5306_ts->ts_workqueue , &AW5306_ts->pen_event_work); + #else + queue_work(AW5306_ts->ts_workqueue , &AW5306_ts->pen_event_work); + #endif + + } + return IRQ_HANDLED; + } + return IRQ_NONE; +} +/* +static void aw5306_reset(struct AW5306_ts_data *aw5306) +{ + gpio_set_value(aw5306->rstgpio, 0); + mdelay(5); + gpio_set_value(aw5306->rstgpio, 1); + mdelay(5); + gpio_set_value(aw5306->rstgpio, 0); + mdelay(5); + + return; +} +*/ + +void AW5306_tpd_polling(unsigned long data) + { + struct AW5306_ts_data *AW5306_ts = i2c_get_clientdata(l_client); + +#ifdef INTMODE + if (!work_pending(&AW5306_ts->pen_event_work)) { + queue_work(AW5306_ts->ts_workqueue, &AW5306_ts->pen_event_work); + } +#else + + if (!work_pending(&AW5306_ts->pen_event_work)) { + queue_work(AW5306_ts->ts_workqueue, &AW5306_ts->pen_event_work); + } + if(suspend_flag != 1) + { + #ifdef AUTO_RUDUCEFRAME + if(tp_SlowMode) + { + AW5306_ts->touch_timer.expires = jiffies + HZ/AWTPCfg.SLOW_FRAME; + } + else + { + AW5306_ts->touch_timer.expires = jiffies + HZ/AWTPCfg.FAST_FRAME; + } + #else + AW5306_ts->touch_timer.expires = jiffies + HZ/AWTPCfg.FAST_FRAME; + #endif + add_timer(&AW5306_ts->touch_timer); + } +#endif + } + +#ifdef CONFIG_HAS_EARLYSUSPEND +static void aw5306_early_suspend(struct early_suspend *handler) +{ +#ifdef INTMODE + if(suspend_flag != 1) + { + wmt_disable_gpirq(AW5306_ts->irqgpio); + AW5306_Sleep(); + suspend_flag = 1; + } +#else + if(suspend_flag != 1) + { + printk("AW5306 SLEEP!!!"); + suspend_flag = 1; + } +#endif + + return; +} + +static void aw5306_late_resume(struct early_suspend *handler) +{ + struct AW5306_ts_data *AW5306_ts= container_of(handler, struct AW5306_ts_data , early_suspend); +#ifdef INTMODE + if(suspend_flag != 0) + { + gpio_direction_output(AW5306_ts->rstgpio, 0); + AW5306_User_Cfg1(); + AW5306_TP_Reinit(); + wmt_enable_gpirq(AW5306_ts->irqgpio); + suspend_flag = 0; + } +#else + if(suspend_flag != 0) + { + gpio_direction_output(AW5306_ts->rstgpio, 0); + AW5306_User_Cfg1(); + AW5306_TP_Reinit(); + tp_idlecnt = 0; + tp_SlowMode = 0; + suspend_flag = 0; + printk("AW5306 WAKE UP!!!"); + AW5306_ts->touch_timer.expires = jiffies + HZ/AWTPCfg.FAST_FRAME; + add_timer(&AW5306_ts->touch_timer); + } +#endif + + return; +} +#endif //CONFIG_HAS_EARLYSUSPEND + +#ifdef CONFIG_PM +static int aw5306_suspend(struct platform_device *pdev, pm_message_t state) +{ +#ifdef INTMODE + if(suspend_flag != 1) + { + wmt_disable_gpirq(pContext->irqgpio); + AW5306_Sleep(); + suspend_flag = 1; + } +#else + if(suspend_flag != 1) + { + printk("AW5306 SLEEP!!!"); + suspend_flag = 1; + } +#endif + return 0; + +} + +static int aw5306_resume(struct platform_device *pdev) +{ + struct AW5306_ts_data *AW5306_ts= dev_get_drvdata(&pdev->dev); + +#ifdef INTMODE + if(suspend_flag != 0) + { + gpio_direction_output(AW5306_ts->rstgpio, 0); + AW5306_User_Cfg1(); + AW5306_TP_Reinit(); + suspend_flag = 0; + printk("AW5306 WAKE UP_intmode!!!"); + wmt_enable_gpirq(AW5306_ts->irqgpio); + } +#else + if(suspend_flag != 0) + { + gpio_direction_output(AW5306_ts->rstgpio, 0); + AW5306_User_Cfg1(); + AW5306_TP_Reinit(); + tp_idlecnt = 0; + tp_SlowMode = 0; + suspend_flag = 0; + printk("AW5306 WAKE UP!!!"); + AW5306_ts->touch_timer.expires = jiffies + HZ/AWTPCfg.FAST_FRAME; + add_timer(&AW5306_ts->touch_timer); + } +#endif + + return 0; +} + +#else +#define aw5306_suspend NULL +#define aw5306_resume NULL +#endif + +static int aw5306_probe(struct platform_device *pdev) +{ + int err = 0; + struct AW5306_ts_data *AW5306_ts = platform_get_drvdata( pdev); + u8 reg_value; + + //aw5306_reset(AW5306_ts); + + reg_value = AW_I2C_ReadByte(0x01); + if(reg_value != 0xA8) + { + //l_client->addr = 0x39; + dbg_err("AW5306_ts_probe: CHIP ID NOT CORRECT\n"); + return -ENODEV; + } + + i2c_set_clientdata(l_client, AW5306_ts); + + INIT_WORK(&AW5306_ts->pen_event_work, AW5306_ts_pen_irq_work); + AW5306_ts->ts_workqueue = create_singlethread_workqueue(AW5306_ts->name); + if (!AW5306_ts->ts_workqueue ) { + err = -ESRCH; + goto exit_create_singlethread; + } + + AW5306_ts->input_dev = input_allocate_device(); + if (!AW5306_ts->input_dev) { + err = -ENOMEM; + dbg_err("failed to allocate input device\n"); + goto exit_input_dev_alloc_failed; + } + + AW5306_ts->input_dev->name = AW5306_ts->name; + AW5306_ts->input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + set_bit(INPUT_PROP_DIRECT, AW5306_ts->input_dev->propbit); + + if (AW5306_ts->lcd_exchg) { + input_set_abs_params(AW5306_ts->input_dev, + ABS_MT_POSITION_X, 0, AW5306_ts->resly, 0, 0); + input_set_abs_params(AW5306_ts->input_dev, + ABS_MT_POSITION_Y, 0, AW5306_ts->reslx, 0, 0); + } else { + input_set_abs_params(AW5306_ts->input_dev, + ABS_MT_POSITION_X, 0, AW5306_ts->reslx, 0, 0); + input_set_abs_params(AW5306_ts->input_dev, + ABS_MT_POSITION_Y, 0, AW5306_ts->resly, 0, 0); + } + input_set_abs_params(AW5306_ts->input_dev, + ABS_MT_TRACKING_ID, 0, 4, 0, 0); + + err = input_register_device(AW5306_ts->input_dev); + if (err) { + dbg_err("aw5306_ts_probe: failed to register input device.\n"); + goto exit_input_register_device_failed; + } + +#ifdef CONFIG_HAS_EARLYSUSPEND + AW5306_ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; + AW5306_ts->early_suspend.suspend = aw5306_early_suspend; + AW5306_ts->early_suspend.resume = aw5306_late_resume; + register_early_suspend(&AW5306_ts->early_suspend); +#endif + + AW5306_create_sysfs(l_client); + memcpy(AW_CALI_FILENAME,"/data/tpcali",12); + //memcpy(AW_UCF_FILENAME,"/data/AWTPucf",13); + printk("ucf file: %s\n", AW_UCF_FILENAME); + + AW5306_TP_Init(); + + AW5306_ts->touch_timer.function = AW5306_tpd_polling; + AW5306_ts->touch_timer.data = 0; + init_timer(&AW5306_ts->touch_timer); + AW5306_ts->touch_timer.expires = jiffies + HZ*10; + add_timer(&AW5306_ts->touch_timer); + +#ifdef INTMODE + + if(request_irq(AW5306_ts->irq, aw5306_interrupt, IRQF_SHARED, AW5306_ts->name, AW5306_ts) < 0){ + dbg_err("Could not allocate irq for ts_aw5306 !\n"); + err = -1; + goto exit_register_irq; + } + + wmt_set_gpirq(AW5306_ts->irqgpio, IRQ_TYPE_EDGE_FALLING); + wmt_enable_gpirq(AW5306_ts->irqgpio); + +#endif + + + + + return 0; + +exit_register_irq: +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&AW5306_ts->early_suspend); +#endif +exit_input_register_device_failed: + input_free_device(AW5306_ts->input_dev); +exit_input_dev_alloc_failed: +//exit_create_group: + cancel_work_sync(&AW5306_ts->pen_event_work); + destroy_workqueue(AW5306_ts->ts_workqueue ); +exit_create_singlethread: + return err; +} + +static int aw5306_remove(struct platform_device *pdev) +{ + struct AW5306_ts_data *AW5306_ts= platform_get_drvdata( pdev); + + del_timer(&AW5306_ts->touch_timer); + + +#ifdef INTMODE + wmt_disable_gpirq(AW5306_ts->irqgpio); + free_irq(AW5306_ts->irq, AW5306_ts); +#endif + + +#ifdef CONFIG_HAS_EARLYSUSPEND + unregister_early_suspend(&AW5306_ts->early_suspend); +#endif + input_unregister_device(AW5306_ts->input_dev); + input_free_device(AW5306_ts->input_dev); + + cancel_work_sync(&AW5306_ts->pen_event_work); + flush_workqueue(AW5306_ts->ts_workqueue); + destroy_workqueue(AW5306_ts->ts_workqueue); + + dbg("remove...\n"); + return 0; +} + +static void aw5306_release(struct device *device) +{ + return; +} + +static struct platform_device aw5306_device = { + .name = DEV_AW5306, + .id = 0, + .dev = {.release = aw5306_release}, +}; + +static struct platform_driver aw5306_driver = { + .driver = { + .name = DEV_AW5306, + .owner = THIS_MODULE, + }, + .probe = aw5306_probe, + .remove = aw5306_remove, + .suspend = aw5306_suspend, + .resume = aw5306_resume, +}; + +static int check_touch_env(struct AW5306_ts_data *AW5306_ts) +{ + int ret = 0; + int len = 96; + int Enable; + char retval[96] = {0}; + char ucfname[20] = {0}; + char *p=NULL, *s=NULL; + + // Get u-boot parameter + ret = wmt_getsyspara("wmt.io.touch", retval, &len); + if(ret){ + //printk("MST FT5x0x:Read wmt.io.touch Failed.\n"); + return -EIO; + } + sscanf(retval,"%d:",&Enable); + //check touch enable + if(Enable == 0){ + //printk("FT5x0x Touch Screen Is Disabled.\n"); + return -ENODEV; + } + + p = strchr(retval,':'); + p++; + if(strncmp(p,"aw5306",6)) return -ENODEV; + AW5306_ts->name = DEV_AW5306; + s = strchr(p, ':'); + p = p + 7; + if (s <= p) + return -ENODEV; + strncpy(ucfname, p, s-p); + sprintf(AW_UCF_FILENAME, "/lib/firmware/%s", ucfname); + + s++; + sscanf(s,"%d:%d:%d:%d:%d:%d:%d:%d", &AW5306_ts->irqgpio, &AW5306_ts->reslx, &AW5306_ts->resly, &AW5306_ts->rstgpio, &AW5306_ts->swap, &AW5306_ts->xch, &AW5306_ts->ych, &AW5306_ts->nt); + + AW5306_ts->irq = IRQ_GPIO; + + printk("%s irqgpio=%d, reslx=%d, resly=%d, rstgpio=%d, swap=%d, xch=%d, ych=%d, nt=%d\n", AW5306_ts->name, AW5306_ts->irqgpio, AW5306_ts->reslx, AW5306_ts->resly, AW5306_ts->rstgpio, AW5306_ts->swap, AW5306_ts->xch, AW5306_ts->ych, AW5306_ts->nt); + + memset(retval,0,sizeof(retval)); + ret = wmt_getsyspara("wmt.display.fb0", retval, &len); + if (!ret) { + int tmp[6]; + p = retval; + sscanf(p, "%d:[%d:%d:%d:%d:%d", &tmp[0], &tmp[1], &tmp[2], &tmp[3], &tmp[4], &tmp[5]); + if (tmp[4] > tmp[5]) + AW5306_ts->lcd_exchg = 1; + } + + return 0; +} + +struct i2c_board_info ts_i2c_board_info = { + .type = TS_I2C_NAME, + .flags = 0x00, + .addr = AW5306_I2C_ADDR, + .platform_data = NULL, + .archdata = NULL, + .irq = -1, +}; + +static int ts_i2c_register_device (void) +{ + struct i2c_board_info *ts_i2c_bi; + struct i2c_adapter *adapter = NULL; + //struct i2c_client *client = NULL; + + //ts_i2c_board_info.addr = AW5306_I2C_ADDR; + ts_i2c_bi = &ts_i2c_board_info; + adapter = i2c_get_adapter(AW5306_I2C_BUS);/*in bus 1*/ + + if (NULL == adapter) { + printk("can not get i2c adapter, client address error\n"); + return -1; + } + l_client = i2c_new_device(adapter, ts_i2c_bi); + if (l_client == NULL) { + printk("allocate i2c client failed\n"); + return -1; + } + i2c_put_adapter(adapter); + return 0; +} + +static void ts_i2c_unregister_device(void) +{ + if (l_client != NULL) + { + i2c_unregister_device(l_client); + l_client = NULL; + } +} + +static int __init aw5306_init(void) +{ + int ret = -ENOMEM; + struct AW5306_ts_data *AW5306_ts=NULL; + + if (ts_i2c_register_device()<0) + { + dbg("Error to run ts_i2c_register_device()!\n"); + return -1; + } + + AW5306_ts = kzalloc(sizeof(struct AW5306_ts_data), GFP_KERNEL); + if(!AW5306_ts){ + dbg_err("mem alloc failed.\n"); + return -ENOMEM; + } + + pContext = AW5306_ts; + ret = check_touch_env(AW5306_ts); + if(ret < 0) + goto exit_free_mem; + + ret = gpio_request(AW5306_ts->irqgpio, "ts_irq"); + if (ret < 0) { + printk("gpio(%d) touchscreen irq request fail\n", AW5306_ts->irqgpio); + goto exit_free_mem; + } + //wmt_gpio_setpull(AW5306_ts->irqgpio, WMT_GPIO_PULL_UP); + gpio_direction_input(AW5306_ts->irqgpio); + + ret = gpio_request(AW5306_ts->rstgpio, "ts_rst"); + if (ret < 0) { + printk("gpio(%d) touchscreen reset request fail\n", AW5306_ts->rstgpio); + goto exit_free_irqgpio; + } + gpio_direction_output(AW5306_ts->rstgpio, 0); + + + ret = platform_device_register(&aw5306_device); + if(ret){ + dbg_err("register platform drivver failed!\n"); + goto exit_free_gpio; + } + platform_set_drvdata(&aw5306_device, AW5306_ts); + + ret = platform_driver_register(&aw5306_driver); + if(ret){ + dbg_err("register platform device failed!\n"); + goto exit_unregister_pdev; + } + +/* + i2c_dev_class = class_create(THIS_MODULE,"aw_i2c_dev"); + if (IS_ERR(i2c_dev_class)) { + ret = PTR_ERR(i2c_dev_class); + class_destroy(i2c_dev_class); + } +*/ + + + return ret; + +exit_unregister_pdev: + platform_device_unregister(&aw5306_device); +exit_free_gpio: + gpio_free(AW5306_ts->rstgpio); +exit_free_irqgpio: + gpio_free(AW5306_ts->irqgpio); +exit_free_mem: + kfree(AW5306_ts); + pContext = NULL; + return ret; +} + +static void aw5306_exit(void) +{ + if(!pContext) return; + + platform_driver_unregister(&aw5306_driver); + platform_device_unregister(&aw5306_device); + gpio_free(pContext->rstgpio); + gpio_free(pContext->irqgpio); + kfree(pContext); + ts_i2c_unregister_device(); + return; +} + +late_initcall(aw5306_init); +module_exit(aw5306_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("FocalTech.Touch"); diff --git a/drivers/input/touchscreen/aw5306_ts/AW5306_userpara.c b/drivers/input/touchscreen/aw5306_ts/AW5306_userpara.c new file mode 100755 index 00000000..99f65f87 --- /dev/null +++ b/drivers/input/touchscreen/aw5306_ts/AW5306_userpara.c @@ -0,0 +1,196 @@ +#include "AW5306_Reg.h" +#include "AW5306_Drv.h" +#include <linux/kernel.h> +#include <linux/string.h> +#include "AW5306_userpara.h" + +#define POS_PRECISION 64 + +extern AW5306_UCF AWTPCfg; +extern STRUCTCALI AW_Cali; +extern char AW5306_WorkMode; +extern STRUCTNOISE AW_Noise; + +extern void AW5306_CLB_WriteCfg(void); +extern int AW_I2C_WriteByte(unsigned char addr, unsigned char data); +extern unsigned char AW_I2C_ReadByte(unsigned char addr); +extern unsigned char AW_I2C_ReadXByte( unsigned char *buf, unsigned char addr, unsigned short len); +extern unsigned char AW5306_RAWDATACHK(void); + +const STRUCTCALI Default_Cali1 = +{ + "AWINIC TP CALI", + //{0x33,0x23,0x22,0x22,0x22,0x22,0x22,0x02,0x22,0x22}, //TXOFFSET + {0x32,0x32,0x23,0x32,0x33,0x33,0x33,0x03,0x22,0x22}, //TXOFFSET + //{0x9A,0xA9,0xAA,0xA9,0x9B,0x00}, //RXOFFSET + {0x35,0x44,0x55,0x54,0x34,0x00}, //RXOFFSET + //{0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c,0x3c},//TXCAC + {0x2C,0x2B,0x2B,0x2A,0x2A,0x2C,0x2C,0x2C,0x2C,0x2C,0x2D,0x2D,0x2D,0x2D,0x31,0x2C,0x2C,0x2C,0x2C,0x2C},//TXCAC + //{0x3d,0x3c,0x3c,0x3c,0x3e,0x3a,0x3a,0x3e,0x3c,0x3b,0x3c,0x3c},//RXCAC + {0x84,0x84,0x82,0x82,0x80,0x86,0x86,0x80,0x8C,0x82,0x84,0x84},//RXCAC + //{0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x0e,0x2e,0x2e,0x0e,0x0e,0x0e,0x0e,0x0e},//TXGAIN + {0x88,0x88,0x88,0x88,0x88,0x68,0x68,0x68,0x68,0x68,0x48,0x48,0x48,0x48,0x28,0x08,0x08,0x08,0x08,0x08},//TXGAIN +}; + +const AW5306_UCF Default_UCF = +{ + 15, //TX_NUM + 10, //RX_NUM + {17,16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1,0,0,0}, //TX_ORDER + {9,8,7,6,5,4,3,2,1,0,0,0}, //RX_ORDER + 0, //RX_START + 0, //HAVE_KEY_LINE + {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}, //KeyLineValid + + 600, //MAPPING_MAX_X + 1024, //MAPPING_MAX_Y + + 350, //GainClbDeltaMin + 450, //GainClbDeltaMax + 550, //KeyLineDeltaMin + 650, //KeyLineDeltaMax + 8300, //OffsetClbExpectedMin + 8500, //OffsetClbExpectedMax + 300, //RawDataDeviation + 8, //CacMultiCoef + + 7000, //RawDataCheckMin + 10000, //RawDataCheckMax + + 200, //FLYING_TH + 100, //MOVING_TH + 50, //MOVING_ACCELER + + 70, //PEAK_TH + 80, //GROUP_TH + 90, //BIGAREA_TH + 25, //BIGAREA_CNT + 20, //BIGAREA_FRESHCNT + + 1, //CACULATE_COEF + + 1, //FIRST_CALI + 0, //RAWDATA_DUMP_SWITCH + + 1, //MULTI_SCANFREQ + 5, //BASE_FREQ + 0x83, //FREQ_OFFSET + 0x00, //WAIT_TIME + 0x2b, //CHAMP_CFG + 0x10, //POSLEVEL_TH + + 1, //ESD_PROTECT + + 0, //MARGIN_COMPENSATE + 0, //MARGIN_COMP_DATA_UP + 0, //MARGIN_COMP_DATA_DOWN + 0, //MARGIN_COMP_DATA_LEFT + 0, //MARGIN_COMP_DATA_RIGHT + + 1, //POINT_RELEASEHOLD + 0, //MARGIN_RELEASEHOLD + 0, //POINT_PRESSHOLD + 1, //KEY_PRESSHOLD + + 0, //PEAK_ROW_COMPENSATE + 1, //PEAK_COL_COMPENSATE + 3, //PEAK_COMPENSATE_COEF + + 0, //LCD_NOISE_PROCESS + 50, //LCD_NOISETH + + 0, //FALSE_PEAK_PROCESS + 100, //FALSE_PEAK_TH + + 6, //STABLE_DELTA_X + 6, //STABLE_DELTA_Y + + 0, //DEBUG_LEVEL + + 50, //FAST_FRAME + 20, //SLOW_FRAME + + 0, //GAIN_CLB_SEPERATE + 5, //MARGIN_PREFILTER + 0, //BIGAREA_HOLDPOINT + 50, //CHARGE_NOISE + 0, //FREQ_JUMP + 0, //PEAK_VALID_CHECK + 1, //WATER_REMOVE + +#ifdef INTMODE + 1 //INT_MODE +#else + 0 //POLL_MODE +#endif +}; + +void AW5306_User_Cfg1(void) +{ + unsigned char i; + + + for(i=0;i<AWTPCfg.TX_LOCAL;i++) + { + AW_I2C_WriteByte(SA_TX_INDEX0+i,AWTPCfg.TX_ORDER[i]); //TX REVERT + } + + AW_I2C_WriteByte(SA_TX_NUM,AWTPCfg.TX_LOCAL); + AW_I2C_WriteByte(SA_RX_NUM,AWTPCfg.RX_LOCAL); + + if(1 == AWTPCfg.MULTI_SCANFREQ) + { + AW_I2C_WriteByte(SA_SCANFREQ1,AWTPCfg.BASE_FREQ); + AW_I2C_WriteByte(SA_SCANFREQ2,AWTPCfg.BASE_FREQ); + AW_I2C_WriteByte(SA_SCANFREQ3,AWTPCfg.BASE_FREQ); + } + else + { + AW_I2C_WriteByte(SA_SCANFREQ1,AWTPCfg.BASE_FREQ); //3-5 + } + + + AW_I2C_WriteByte(SA_WAITTIME,AWTPCfg.WAIT_TIME); + AW_I2C_WriteByte(SA_RX_START,AWTPCfg.RX_START); + AW_I2C_WriteByte(SA_SCANTIM,4); // set to 32 TX cycles mode + + AW_I2C_WriteByte(SA_PAGE,1); + AW_I2C_WriteByte(SA_CHAMPCFG,AWTPCfg.CHAMP_CFG); // + AW_I2C_WriteByte(SA_OSCCFG1,AWTPCfg.FREQ_OFFSET); // + AW_I2C_WriteByte(SA_OSCCFG2,0x10); //TRIM register + AW_I2C_WriteByte(SA_POSLEVELTH,AWTPCfg.POSLEVEL_TH); + + AW_I2C_WriteByte(SA_CPFREQ,0x00); //for AW256 + AW_I2C_WriteByte(SA_PAGE,0); + + AW5306_CLB_WriteCfg(); + //printk("AW5306 user config finished TXCAC0 = %x",AW_Cali.TXCAC[0] ); +} + +void AW5306_User_Init(void) +{ + unsigned char ret; + + ret = 0; + + AW5306_WorkMode = DeltaMode; //DeltaMode: chip output delta data RawDataMode: chip output rawdata + + memcpy(&AWTPCfg,&Default_UCF,sizeof(AW5306_UCF)); + memcpy(&AW_Cali,&Default_Cali1,sizeof(STRUCTCALI)); //load default cali value + + + //AW_I2C_WriteByte(SA_PAGE,0); + //AW_I2C_WriteByte(SA_IDRST,0x55); + + AW5306_User_Cfg1(); + + AW_Noise.FrmState = NOISE_FRM_NORMAL; + AW_Noise.WorkFreqID = 16; + AW_Noise.ScanFreqID = AW_Noise.WorkFreqID; + AW_Noise.State = NOISE_LISTENING; + AW_Noise.NoiseTh1 = 60; + AW_Noise.JumpTh = 5; + AW_Noise.Better_NoiseScan = 1000; + //ret = AW5306_RAWDATACHK(); + +} diff --git a/drivers/input/touchscreen/aw5306_ts/AW5306_userpara.h b/drivers/input/touchscreen/aw5306_ts/AW5306_userpara.h new file mode 100755 index 00000000..15d5c180 --- /dev/null +++ b/drivers/input/touchscreen/aw5306_ts/AW5306_userpara.h @@ -0,0 +1,99 @@ +#ifndef AW5306_USERPARA_H + +#define AW5306_USERPARA_H + +#define INTMODE + +typedef struct { + unsigned char TX_LOCAL; // 15 //TX number of TP + unsigned char RX_LOCAL; // 10 //RX number of TP + unsigned char TX_ORDER[22]; // TX ORDER + unsigned char RX_ORDER[12]; // RX mapping in inverted order + unsigned char RX_START; //RX START LINE + unsigned char HAVE_KEY_LINE; // 0: no KEY line, 1: have key line on TX line TX_LOCAL-1 + unsigned char KeyLineValid[16]; + + unsigned short MAPPING_MAX_X; // 320 + unsigned short MAPPING_MAX_Y; // 460 + + unsigned short GainClbDeltaMin; // Expected minimum delta for GAIN calibration + unsigned short GainClbDeltaMax; // Expected maximum delta for GAIN calibration + unsigned short KeyLineDeltaMin; + unsigned short KeyLineDeltaMax; + unsigned short OffsetClbExpectedMin; // Expected minimum data for OFFSET calibration + unsigned short OffsetClbExpectedMax; // Expected minimum data for OFFSET calibration + unsigned short RawDataDeviation; // Maximum deviation in a frame + unsigned short CacMultiCoef; + + unsigned short RawDataCheckMin; + unsigned short RawDataCheckMax; + + unsigned short FLYING_TH; + unsigned short MOVING_TH; + unsigned short MOVING_ACCELER; + + unsigned char PEAK_TH; + unsigned char GROUP_TH; + unsigned char BIGAREA_TH; + unsigned char BIGAREA_CNT; + unsigned char BIGAREA_FRESHCNT; + + unsigned char CACULATE_COEF; + + unsigned char FIRST_CALI; + unsigned char RAWDATA_DUMP_SWITCH; + unsigned char MULTI_SCANFREQ; + unsigned char BASE_FREQ; + unsigned char FREQ_OFFSET; + unsigned char WAIT_TIME; + unsigned char CHAMP_CFG; + unsigned char POSLEVEL_TH; + + unsigned char ESD_PROTECT; + + unsigned char MARGIN_COMPENSATE; + unsigned char MARGIN_COMP_DATA_UP; + unsigned char MARGIN_COMP_DATA_DOWN; + unsigned char MARGIN_COMP_DATA_LEFT; + unsigned char MARGIN_COMP_DATA_RIGHT; + + unsigned char POINT_RELEASEHOLD; + unsigned char MARGIN_RELEASEHOLD; + unsigned char POINT_PRESSHOLD; + unsigned char KEY_PRESSHOLD; + + unsigned char PEAK_ROW_COMPENSATE; + unsigned char PEAK_COL_COMPENSATE; + unsigned char PEAK_COMPENSATE_COEF; + + unsigned char LCD_NOISE_PROCESS; + unsigned char LCD_NOISETH; + + unsigned char FALSE_PEAK_PROCESS; + unsigned char FALSE_PEAK_TH; + + unsigned char STABLE_DELTA_X; + unsigned char STABLE_DELTA_Y; + + unsigned char DEBUG_LEVEL; + + unsigned char FAST_FRAME; + unsigned char SLOW_FRAME; + + unsigned char GAIN_CLB_SEPERATE; + + unsigned char MARGIN_PREFILTER; + + unsigned char BIGAREA_HOLDPOINT; + unsigned char CHARGE_NOISE; + unsigned char FREQ_JUMP; + unsigned char PEAK_VALID_CHECK; + unsigned char WATER_REMOVE; + unsigned char INT_MODE; + +}AW5306_UCF; + +void AW5306_User_Init(void); +void AW5306_User_Cfg1(void); + +#endif diff --git a/drivers/input/touchscreen/aw5306_ts/Kconfig b/drivers/input/touchscreen/aw5306_ts/Kconfig new file mode 100755 index 00000000..32029915 --- /dev/null +++ b/drivers/input/touchscreen/aw5306_ts/Kconfig @@ -0,0 +1,11 @@ +config TOUCHSCREEN_AW5306
+ tristate "AW5306 Capacity Touchscreen Device Support"
+ default y
+ depends on ARCH_WMT
+ ---help---
+ Say Y here if you have an WMT based board with touchscreen
+ attached to it.
+ If unsure, say N.
+ To compile this driver as a module, choose M here: the
+ module will be called s_wmt_ts_aw5306.
+
diff --git a/drivers/input/touchscreen/aw5306_ts/Makefile b/drivers/input/touchscreen/aw5306_ts/Makefile new file mode 100755 index 00000000..2a79cbe6 --- /dev/null +++ b/drivers/input/touchscreen/aw5306_ts/Makefile @@ -0,0 +1,35 @@ +KERNELDIR=../../../../
+CROSS = arm_1103_le-
+CC= $(CROSS)gcc
+LD= $(CROSS)ld
+STRIP = $(CROSS)strip
+
+DEBUG = n
+
+# Add your debugging flag (or not) to EXTRA_CFLAGS
+ifeq ($(DEBUG),y)
+# DEBFLAGS = -O -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+DEBFLAGS = -O0 -g -DSCULL_DEBUG # "-O" is needed to expand inlines
+
+else
+ DEBFLAGS = -O2 -Wall
+ #DEBFLAGS = -O2 -Wall -L./libAW5306.a
+endif
+
+EXTRA_CFLAGS += $(DEBFLAGS)
+
+
+MY_MODULE_NAME=s_wmt_ts_aw5306
+
+#obj-$(CONFIG_TOUCHSCREEN_FT5X0X) := $(MY_MODULE_NAME).o
+obj-m := $(MY_MODULE_NAME).o
+$(MY_MODULE_NAME)-objs := AW5306_ts.o irq_gpio.o AW5306_userpara.o AW5306_Base.b AW5306_Clb.b AW5306_Drv.b
+
+default:
+ $(MAKE) -C $(KERNELDIR) SUBDIRS=$(PWD) modules
+ $(STRIP) --strip-debug $(MY_MODULE_NAME).ko
+# @rm -rf *.o *~ core .depend .*.cmd *.mod.c .tmp_versions *.order *.symvers
+
+clean:
+ @rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order *.symvers modules.builtin
+
diff --git a/drivers/input/touchscreen/aw5306_ts/irq_gpio.c b/drivers/input/touchscreen/aw5306_ts/irq_gpio.c new file mode 100755 index 00000000..8bdf9f20 --- /dev/null +++ b/drivers/input/touchscreen/aw5306_ts/irq_gpio.c @@ -0,0 +1,149 @@ +#include <linux/interrupt.h> +#include <linux/irq.h> +#include <linux/delay.h> +#include <mach/hardware.h> +#include "irq_gpio.h" + +int wmt_enable_gpirq(int num) +{ + if(num > 15) + return -1; + + if(num < 4) + REG32_VAL(__GPIO_BASE+0x0300) |= 1<<(num*8+7); //enable interrupt + else if(num >= 4 && num < 8) + REG32_VAL(__GPIO_BASE+0x0304) |= 1<<((num-4)*8+7); //enable interrupt + else if(num >= 8 && num < 12) + REG32_VAL(__GPIO_BASE+0x0308) |= 1<<((num-8)*8+7); //enable interrupt + else + REG32_VAL(__GPIO_BASE+0x030C) |= 1<<((num-12)*8+7); //enable interrupt + + return 0; +} + +int wmt_disable_gpirq(int num) +{ + if(num > 15) + return -1; + + if(num<4) + REG32_VAL(__GPIO_BASE+0x0300) &= ~(1<<(num*8+7)); //enable interrupt + else if(num >= 4 && num < 8) + REG32_VAL(__GPIO_BASE+0x0304) &= ~(1<<((num-4)*8+7)); //enable interrupt + else if(num >= 8 && num < 12) + REG32_VAL(__GPIO_BASE+0x0308) &= ~(1<<((num-8)*8+7)); //enable interrupt + else + REG32_VAL(__GPIO_BASE+0x030C) &= ~(1<<((num-12)*8+7)); //enable interrupt + + return 0; +} + +int wmt_is_tsirq_enable(int num) +{ + int val = 0; + + if(num > 15) + return 0; + + if(num<4) + val = REG32_VAL(__GPIO_BASE+0x0300) & (1<<(num*8+7)); + else if(num >= 4 && num < 8) + val = REG32_VAL(__GPIO_BASE+0x0304) & (1<<((num-4)*8+7)); + else if(num >= 8 && num < 12) + val = REG32_VAL(__GPIO_BASE+0x0308) & (1<<((num-8)*8+7)); + else + val = REG32_VAL(__GPIO_BASE+0x030C) & (1<<((num-12)*8+7)); + + return val?1:0; + +} + +int wmt_is_tsint(int num) +{ + if (num > 15) + { + return 0; + } + return (REG32_VAL(__GPIO_BASE+0x0360) & (1<<num)) ? 1: 0; +} + +void wmt_clr_int(int num) +{ + if (num > 15) + { + return; + } + REG32_VAL(__GPIO_BASE+0x0360) = 1<<num; +} + +int wmt_set_gpirq(int num, int type) +{ + int shift; + int offset; + unsigned long reg; + + if(num >15) + return -1; + //if (num > 9) + //GPIO_PIN_SHARING_SEL_4BYTE_VAL &= ~BIT4; // gpio10,11 as gpio + + REG32_VAL(__GPIO_BASE+0x0040) &= ~(1<<num);//|=(1<<num);// //enable gpio + REG32_VAL(__GPIO_BASE+0x0080) &= ~(1<<num); //set input + REG32_VAL(__GPIO_BASE+0x04c0) |= (1<<num); //pull down + REG32_VAL(__GPIO_BASE+0x0480) &= ~(1<<num); //enable pull up/down + + //set gpio irq triger type + if(num < 4){//[0,3] + shift = num; + offset = 0x0300; + }else if(num >= 4 && num < 8){//[4,7] + shift = num-4; + offset = 0x0304; + }else if(num >= 8 && num < 12){//[8,11] + shift = num-8; + offset = 0x0308; + }else{// [12,15] + shift = num-12; + offset = 0x030C; + } + + reg = REG32_VAL(__GPIO_BASE + offset); + + switch(type){ + case IRQ_TYPE_LEVEL_LOW: + reg &= ~(1<<(shift*8+2)); + reg &= ~(1<<(shift*8+1)); + reg &= ~(1<<(shift*8)); + break; + case IRQ_TYPE_LEVEL_HIGH: + reg &= ~(1<<(shift*8+2)); + reg &= ~(1<<(shift*8+1)); + reg |= (1<<(shift*8)); + break; + case IRQ_TYPE_EDGE_FALLING: + reg &= ~(1<<(shift*8+2)); + reg |= (1<<(shift*8+1)); + reg &= ~(1<<(shift*8)); + break; + case IRQ_TYPE_EDGE_RISING: + reg &= ~(1<<(shift*8+2)); + reg |= (1<<(shift*8+1)); + reg |= (1<<(shift*8)); + break; + default://both edge + reg |= (1<<(shift*8+2)); + reg &= ~(1<<(shift*8+1)); + reg &= ~(1<<(shift*8)); + break; + + } + //reg |= 1<<(shift*8+7);//enable interrupt + reg &= ~(1<<(shift*8+7)); //disable int + + REG32_VAL(__GPIO_BASE + offset) = reg; + REG32_VAL(__GPIO_BASE+0x0360) = 1<<num; //clear interrupt status + msleep(5); + return 0; +} + + diff --git a/drivers/input/touchscreen/aw5306_ts/irq_gpio.h b/drivers/input/touchscreen/aw5306_ts/irq_gpio.h new file mode 100755 index 00000000..0232bd04 --- /dev/null +++ b/drivers/input/touchscreen/aw5306_ts/irq_gpio.h @@ -0,0 +1,13 @@ +#ifndef _LINUX_IRQ_GPIO_H +#define _LINUX_IRQ_GPIO_H + + +extern int wmt_enable_gpirq(int num); +extern int wmt_disable_gpirq(int num); +extern int wmt_is_tsirq_enable(int num); +extern int wmt_is_tsint(int num); +extern void wmt_clr_int(int num); +extern int wmt_set_gpirq(int num, int type); + + +#endif |