summaryrefslogtreecommitdiff
path: root/drivers/input/touchscreen/aw5306_ts
diff options
context:
space:
mode:
authorSrikant Patnaik2015-01-11 12:28:04 +0530
committerSrikant Patnaik2015-01-11 12:28:04 +0530
commit871480933a1c28f8a9fed4c4d34d06c439a7a422 (patch)
tree8718f573808810c2a1e8cb8fb6ac469093ca2784 /drivers/input/touchscreen/aw5306_ts
parent9d40ac5867b9aefe0722bc1f110b965ff294d30d (diff)
downloadFOSSEE-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-xdrivers/input/touchscreen/aw5306_ts/AW5306_Base.bbin0 -> 41612 bytes
-rwxr-xr-xdrivers/input/touchscreen/aw5306_ts/AW5306_Clb.bbin0 -> 32804 bytes
-rwxr-xr-xdrivers/input/touchscreen/aw5306_ts/AW5306_Drv.bbin0 -> 114476 bytes
-rwxr-xr-xdrivers/input/touchscreen/aw5306_ts/AW5306_Drv.h158
-rwxr-xr-xdrivers/input/touchscreen/aw5306_ts/AW5306_Reg.h187
-rwxr-xr-xdrivers/input/touchscreen/aw5306_ts/AW5306_ts.c1614
-rwxr-xr-xdrivers/input/touchscreen/aw5306_ts/AW5306_userpara.c196
-rwxr-xr-xdrivers/input/touchscreen/aw5306_ts/AW5306_userpara.h99
-rwxr-xr-xdrivers/input/touchscreen/aw5306_ts/Kconfig11
-rwxr-xr-xdrivers/input/touchscreen/aw5306_ts/Makefile35
-rwxr-xr-xdrivers/input/touchscreen/aw5306_ts/irq_gpio.c149
-rwxr-xr-xdrivers/input/touchscreen/aw5306_ts/irq_gpio.h13
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
new file mode 100755
index 00000000..e3e6c22a
--- /dev/null
+++ b/drivers/input/touchscreen/aw5306_ts/AW5306_Base.b
Binary files differ
diff --git a/drivers/input/touchscreen/aw5306_ts/AW5306_Clb.b b/drivers/input/touchscreen/aw5306_ts/AW5306_Clb.b
new file mode 100755
index 00000000..40e49326
--- /dev/null
+++ b/drivers/input/touchscreen/aw5306_ts/AW5306_Clb.b
Binary files differ
diff --git a/drivers/input/touchscreen/aw5306_ts/AW5306_Drv.b b/drivers/input/touchscreen/aw5306_ts/AW5306_Drv.b
new file mode 100755
index 00000000..03f070a1
--- /dev/null
+++ b/drivers/input/touchscreen/aw5306_ts/AW5306_Drv.b
Binary files differ
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