summaryrefslogtreecommitdiff
path: root/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts
diff options
context:
space:
mode:
Diffstat (limited to 'ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts')
-rwxr-xr-xANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/Kconfig16
-rwxr-xr-xANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/Makefile32
-rwxr-xr-xANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/wmt_ts.c833
-rwxr-xr-xANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/wmt_ts.h149
-rwxr-xr-xANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/zet6221_downloader.c1209
-rwxr-xr-xANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/zet6221_i2c.c2786
-rwxr-xr-xANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/zet6221_ts.h6
7 files changed, 5031 insertions, 0 deletions
diff --git a/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/Kconfig b/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/Kconfig
new file mode 100755
index 00000000..3bf6dcc3
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/Kconfig
@@ -0,0 +1,16 @@
+#
+# ZET6221 capacity touch screen driver configuration
+#
+config TOUCHSCREEN_ZET6221
+ tristate "ZEITEC ZET6221 I2C Capacitive Touchscreen Input Driver Support"
+ depends on ARCH_WMT
+ default y
+ 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_zet6221
+
diff --git a/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/Makefile b/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/Makefile
new file mode 100755
index 00000000..102fb212
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/Makefile
@@ -0,0 +1,32 @@
+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
+endif
+
+EXTRA_CFLAGS += $(DEBFLAGS)
+
+
+MY_MODULE_NAME=s_wmt_ts_zet6221
+
+obj-m := $(MY_MODULE_NAME).o
+$(MY_MODULE_NAME)-objs := zet6221_i2c.o wmt_ts.o zet6221_downloader.o
+
+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 modules.builtin
+
+clean:
+ rm -rf *.o *~ core .depend .*.cmd *.ko *.mod.c .tmp_versions *.order *.symvers modules.builtin \ No newline at end of file
diff --git a/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/wmt_ts.c b/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/wmt_ts.c
new file mode 100755
index 00000000..bfc65e7f
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/wmt_ts.c
@@ -0,0 +1,833 @@
+#include <linux/unistd.h>
+#include <linux/time.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+//#include <asm/semaphore.h>
+#include <linux/proc_fs.h>
+#include <linux/completion.h>
+#include <linux/delay.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/suspend.h>
+#include <linux/input.h>
+#include <linux/types.h>
+#include <linux/platform_device.h>
+#include <mach/hardware.h>
+#include <linux/i2c.h>
+#include <linux/irq.h>
+#include <linux/firmware.h>
+
+#include <asm/uaccess.h>
+#include <linux/fs.h>
+#include <linux/syscalls.h>
+
+#include "wmt_ts.h"
+#include "zet6221_ts.h"
+
+/////////////////////////////////////////////////////////////////
+
+// commands for ui
+#define TS_IOC_MAGIC 't'
+
+#define TS_IOCTL_CAL_START _IO(TS_IOC_MAGIC, 1)
+#define TS_IOCTL_CAL_DONE _IOW(TS_IOC_MAGIC, 2, int*)
+#define TS_IOCTL_GET_RAWDATA _IOR(TS_IOC_MAGIC, 3, int*)
+#define TS_IOCTL_CAL_QUIT _IOW(TS_IOC_MAGIC, 4, int*)
+#define TS_IOCTL_AUTO_CALIBRATION _IOW(TS_IOC_MAGIC, 5, int*)
+#define TS_IOC_MAXNR 5
+
+#define TP_INFOR_ARRAY_SIZE (sizeof(l_tpinfor)/sizeof(l_tpinfor[1]))
+//
+#define TS_MAJOR 11
+#define TS_DRIVER_NAME "wmtts_touch"
+#define TS_NAME "wmtts"
+#define WMTTS_PROC_NAME "wmtts_config"
+
+#define EXT_GPIO0 0
+#define EXT_GPIO1 1
+#define EXT_GPIO2 2
+#define EXT_GPIO3 3
+#define EXT_GPIO4 4
+#define EXT_GPIO5 5
+#define EXT_GPIO6 6
+#define EXT_GPIO7 7
+
+
+
+typedef struct {
+ int a1;
+ int b1;
+ int c1;
+ int a2;
+ int b2;
+ int c2;
+ int delta;
+}CALIBRATION_PARAMETER, *PCALIBRATION_PARAMETER;
+
+
+static int irq_gpio;
+static int rst_gpio;
+static int panelres_x;
+static int panelres_y;
+static int s_download_option;
+static int s_high_Impendence_mode;
+static int lcd_exchg = 0;
+
+
+static DECLARE_WAIT_QUEUE_HEAD(queue);
+static DECLARE_WAIT_QUEUE_HEAD(ts_penup_wait_queue);
+
+extern struct wmtts_device zet6221_tsdev;
+static struct wmtts_device* l_tsdev = &zet6221_tsdev;
+struct proc_dir_entry* l_tsproc = NULL;
+static struct i2c_client *l_client=NULL;
+static int l_penup = 1; // 1-pen up,0-pen down
+int earlysus_en = 0;
+
+struct tp_infor
+{
+ //enum tp_type type;
+ char name[64];
+ //unsigned int i2caddr;
+ unsigned int xaxis; //0: x,1: x swap with y
+ unsigned int xdir; // 1: positive,-1: revert
+ unsigned int ydir; // 1: positive,-1: revert
+ unsigned int max_finger_num;
+};
+
+static int l_tpindex = -1;
+static struct tp_infor l_tpinfor[1];
+
+/////////////////////////////////////////////////////
+// function declare
+/////////////////////////////////////////////////////
+extern int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+extern int wmt_setsyspara(char *varname, unsigned char *varval);
+static int ts_writeproc( struct file *file,
+ const char *buffer,
+ unsigned long count,
+ void *data );
+static int ts_readproc(char *page, char **start, off_t off,
+ int count, int *eof, void *data);
+///////////////////////////////////////////////////////////////////////
+
+void wmt_ts_get_firmwname(char* firmname)
+{
+ int offset = 0;
+ offset = strlen(l_tsdev->ts_id);
+ switch(ic_model){
+ case ZET6223:
+ l_tpinfor[l_tpindex].name[offset] = '2';
+ l_tpinfor[l_tpindex].name[offset+1] = '3';
+ break;
+ case ZET6231:
+ l_tpinfor[l_tpindex].name[offset] = '3';
+ l_tpinfor[l_tpindex].name[offset+1] = '1';
+ break;
+ case ZET6251:
+ l_tpinfor[l_tpindex].name[offset] = '5';
+ l_tpinfor[l_tpindex].name[offset+1] = '1';
+ break;
+ case ZET6221:
+ default:
+ l_tpinfor[l_tpindex].name[offset] = '2';
+ l_tpinfor[l_tpindex].name[offset+1] = '1';
+ break;
+ }
+ sprintf(firmname,"%s_fw.bin",l_tpinfor[l_tpindex].name);
+}
+
+unsigned int wmt_ts_get_xaxis(void)
+{
+ return l_tpinfor[l_tpindex].xaxis;
+}
+
+unsigned int wmt_ts_get_xdir(void)
+{
+ return l_tpinfor[l_tpindex].xdir;
+}
+
+unsigned int wmt_ts_get_ydir(void)
+{
+ return l_tpinfor[l_tpindex].ydir;
+}
+
+unsigned int wmt_ts_get_maxfingernum(void)
+{
+ return l_tpinfor[l_tpindex].max_finger_num;
+}
+
+
+int wmt_ts_load_firmware(char* firmwarename, unsigned char** firmdata, int* fwlen)
+{
+ const struct firmware *fw_entry;
+ if(request_firmware(&fw_entry, firmwarename, &l_client->dev)!=0) {
+ printk(KERN_ERR "cat't request firmware\n");
+ return -1;
+ }
+ if (fw_entry->size <= 0) {
+ printk(KERN_ERR "load firmware error\n");
+ release_firmware(fw_entry);
+ return -1;
+ }
+
+ //*firmdata = kzalloc(fw_entry->size + 1, GFP_KERNEL);
+ memcpy(*firmdata, fw_entry->data, fw_entry->size);
+ *fwlen = fw_entry->size;
+ release_firmware(fw_entry);
+
+ return 0;
+}
+
+
+
+ int wmt_ts_get_gpionum(void)
+{
+ return irq_gpio;
+}
+
+int wmt_ts_get_resetgpnum(void)
+{
+ return rst_gpio;
+}
+
+int wmt_ts_get_lcdexchg(void)
+{
+ return lcd_exchg;
+}
+
+int wmt_ts_get_resolvX(void)
+{
+ return panelres_x;
+}
+
+int wmt_ts_get_resolvY(void)
+{
+ return panelres_y;
+}
+
+//up:1-pen up,0-pen down
+void wmt_ts_set_penup(int up)
+{
+ l_penup = up;
+}
+
+//
+int wmt_ts_wait_penup(void)
+{
+ int ret = wait_event_interruptible(
+ ts_penup_wait_queue,
+ (1==l_penup));
+ return ret;
+}
+
+// return:1-pen up,0-pen dwon
+int wmt_ts_ispenup(void)
+{
+ return l_penup;
+}
+
+
+void wmt_ts_wakeup_penup(void)
+{
+ wake_up(&ts_penup_wait_queue);
+}
+
+int wmt_is_tsirq_enable(void)
+{
+ int val = 0;
+ int num = irq_gpio;
+
+ if(num > 11)
+ 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
+ val = REG32_VAL(__GPIO_BASE+0x0308) & (1<<((num-8)*8+7));
+
+ return val?1:0;
+
+}
+
+int wmt_is_tsint(void)
+{
+ int num = irq_gpio;
+
+ if (num > 11)
+ {
+ return 0;
+ }
+ return (REG32_VAL(__GPIO_BASE+0x0360) & (1<<num)) ? 1: 0;
+}
+
+void wmt_clr_int(void)
+{
+ int num = irq_gpio;
+
+ if (num > 11)
+ {
+ return;
+ }
+ REG32_VAL(__GPIO_BASE+0x0360) = 1<<num;
+}
+
+void wmt_tsreset_init(void)
+{
+ int num = rst_gpio;
+
+ REG32_VAL(__GPIO_BASE+0x0040) |= (1<<num);//&= ~(1<<num); //enable gpio
+ REG32_VAL(__GPIO_BASE+0x00C0) &= ~(1<<num); // out low
+ REG32_VAL(__GPIO_BASE+0x0080) |= (1<<num); //output enable
+ msleep(10);
+ REG32_VAL(__GPIO_BASE+0x00C0) |= (1<<num); // out high
+}
+
+// enable:0-disable,1-enable
+void wmt_enable_rst_pull(int enable)
+{
+ if (enable)
+ {
+ REG32_VAL(__GPIO_BASE+0x0480) |= (1<<rst_gpio); //enable pull up/down
+ } else {
+ REG32_VAL(__GPIO_BASE+0x0480) &= ~(1<<rst_gpio); //disable pull up/down
+ }
+}
+
+// up:0-pull down,1-pull up
+void wmt_set_rst_pull(int up)
+{
+ if (up)
+ {
+ REG32_VAL(__GPIO_BASE+0x04c0) |= (1<<rst_gpio); //pull up
+ } else {
+ REG32_VAL(__GPIO_BASE+0x04c0) &= ~(1<<rst_gpio); //pull down
+ }
+}
+
+// high:0-low level,1-high level
+void wmt_rst_output(int high)
+{
+ REG32_VAL(__GPIO_BASE+0x0040) |= (1<<rst_gpio); //enable gpio
+ if (high)
+ {
+ REG32_VAL(__GPIO_BASE+0x00C0) |= (1<<rst_gpio); // high
+ } else {
+ REG32_VAL(__GPIO_BASE+0x00C0) &= ~(1<<rst_gpio); // low
+ }
+ REG32_VAL(__GPIO_BASE+0x0080) |= (1<<rst_gpio); //set output
+}
+
+void wmt_rst_input(void)
+{
+ REG32_VAL(__GPIO_BASE+0x0040) |= (1<<rst_gpio); //enable gpio
+ REG32_VAL(__GPIO_BASE+0x0080) &= ~(1<<rst_gpio); //set input
+}
+
+void wmt_set_intasgp(void)
+{
+ REG32_VAL(__GPIO_BASE+0x0040) |= (1<<irq_gpio); //enable gpio
+}
+
+// val:1--high,0-low
+void wmt_intgp_out(int val)
+{
+ if (val)
+ {
+ REG32_VAL(__GPIO_BASE+0x00C0) |= (1<<irq_gpio); // high
+ } else {
+ REG32_VAL(__GPIO_BASE+0x00C0) &= ~(1<<irq_gpio); // low
+ }
+ REG32_VAL(__GPIO_BASE+0x0080) |= (1<<irq_gpio); //set output
+}
+
+void wmt_ts_set_irqinput(void)
+{
+ int num = irq_gpio;
+
+ REG32_VAL(__GPIO_BASE+0x0040) |= (1<<num); //enable gpio
+ REG32_VAL(__GPIO_BASE+0x0080) &= ~(1<<num); //set input
+}
+
+unsigned int wmt_ts_irqinval(void)
+{
+ return REG32_VAL(__GPIO_BASE+0x0000)&(1<<irq_gpio);
+}
+
+int wmt_set_gpirq(int type)
+{
+ int shift;
+ int offset;
+ unsigned long reg;
+ int num = irq_gpio;
+
+ if(num >11)
+ 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{// [8,11]
+ shift = num-8;
+ offset = 0x0308;
+ }
+
+ 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;
+}
+
+int wmt_enable_gpirq(void)
+{
+ int num = irq_gpio;
+
+ if(num > 11)
+ 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
+ REG32_VAL(__GPIO_BASE+0x0308) |= 1<<((num-8)*8+7); //enable interrupt
+
+ return 0;
+}
+
+int wmt_disable_gpirq(void)
+{
+ int num = irq_gpio;
+
+ if(num > 11)
+ 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
+ REG32_VAL(__GPIO_BASE+0x0308) &= ~(1<<((num-8)*8+7)); //enable interrupt
+
+ return 0;
+}
+
+
+int wmt_get_tsirqnum(void)
+{
+ return IRQ_GPIO;
+}
+
+static void wmt_ts_platform_release(struct device *device)
+{
+ return;
+}
+
+static struct platform_device wmt_ts_plt_device = {
+ .name = TS_DRIVER_NAME,
+ .id = 0,
+ .dev = {
+ .release = wmt_ts_platform_release,
+ },
+// .num_resources = ARRAY_SIZE(wm9715_ts_resources),
+// .resource = wm9715_ts_resources,
+};
+
+static int wmt_ts_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ dbg("ts suspend....\n");
+ return l_tsdev->suspend(pdev, state);
+}
+static int wmt_ts_resume(struct platform_device *pdev)
+{
+ dbg("ts resume....\n");
+ return l_tsdev->resume(pdev);
+}
+
+static int wmt_ts_probe(struct platform_device *pdev)
+{
+ l_tsproc= create_proc_entry(WMTTS_PROC_NAME, 0666, NULL/*&proc_root*/);
+ if (l_tsproc != NULL)
+ {
+ l_tsproc->read_proc = ts_readproc;
+ l_tsproc->write_proc = ts_writeproc;
+ }
+
+ if (l_tsdev->probe != NULL)
+ return l_tsdev->probe(pdev);
+ else
+ return 0;
+}
+
+static int wmt_ts_remove(struct platform_device *pdev)
+{
+ if (l_tsproc != NULL)
+ {
+ remove_proc_entry(WMTTS_PROC_NAME, NULL);
+ l_tsproc = NULL;
+ }
+
+ if (l_tsdev->remove != NULL)
+ return l_tsdev->remove(pdev);
+ else
+ return 0;
+}
+
+static struct platform_driver wmt_ts_plt_driver = {
+ .driver = {
+ .name = TS_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ },
+ .probe = wmt_ts_probe,
+ .remove = wmt_ts_remove,
+ .suspend = wmt_ts_suspend,
+ .resume = wmt_ts_resume,
+};
+
+static int ts_writeproc( struct file *file,
+ const char *buffer,
+ unsigned long count,
+ void *data )
+{
+ int calibrate = 0;
+ int val = 0;
+
+ if (sscanf(buffer, "calibrate=%d\n", &calibrate))
+ {
+ if (1 == calibrate)
+ {
+ if((l_tsdev->capacitance_calibrate != NULL) &&
+ (0 == l_tsdev->capacitance_calibrate()))
+ {
+ printk(KERN_ALERT "%s calibration successfully!\n", l_tsdev->ts_id);
+ } else {
+ printk(KERN_ALERT "%s calibration failed!\n", l_tsdev->ts_id);
+ }
+ }
+ } else if (sscanf(buffer, "reset=%d\n", &val))
+ {
+
+ }
+ return count;
+}
+
+static int ts_readproc(char *page, char **start, off_t off,
+ int count, int *eof, void *data)
+{
+ int len = 0;
+
+ len = sprintf(page,
+ "echo calibrate=1 > /proc/wmtts_config to calibrate ts.\n");
+ return len;
+}
+
+
+int is_high_impendence_mode(void)
+{
+ return s_high_Impendence_mode;
+}
+
+int get_download_option(void)
+{
+ return s_download_option;
+}
+
+
+static int wmt_check_touch_env(void)
+{
+ int ret = 0;
+ int len = 96, i = 0;
+ char retval[200] = {0},*p=NULL,*s=NULL;
+ int Enable=0;
+ int val,val1;
+
+ // Get u-boot parameter
+ ret = wmt_getsyspara("wmt.io.touch", retval, &len);
+ if(ret){
+ errlog("Read wmt.io.touch Failed.\n");
+ return -EIO;
+ }
+ memset(l_tpinfor,0,sizeof(l_tpinfor[0]));
+
+ p = retval;
+ sscanf(p,"%d:", &Enable);
+ p = strchr(p,':');p++;
+ s = strchr(p,':');
+ strncpy(l_tpinfor[0].name,p, (s-p));
+ p = s+1;
+ dbg("ts_name=%s\n", l_tpinfor[0].name);
+
+ ret = sscanf(p,"%d:%d:%d:%d:%d:%d:%d:%d:%d:%d",
+ &irq_gpio,&panelres_x,&panelres_y,&rst_gpio,
+ &(l_tpinfor[0].xaxis),&(l_tpinfor[0].xdir),&(l_tpinfor[0].ydir),
+ &(l_tpinfor[0].max_finger_num),&s_high_Impendence_mode,&s_download_option);
+
+ if (ret < 8)
+ {
+ dbg("Wrong format ts u-boot param(%d)!\nwmt.io.touch=%s\n",ret,retval);
+ return -ENODEV;
+ }
+
+ //check touch enable
+ if(Enable == 0){
+ errlog("Touch Screen Is Disabled.\n");
+ return -ENODEV;
+ }
+
+
+ /*p = strchr(retval,':');
+ p++;
+ if(strncmp(p, l_tsdev->ts_id,strlen(l_tsdev->ts_id))){//check touch ID
+ //errlog(" %s!=====\n", l_tsdev->ts_id);
+ return -ENODEV;
+ }*/
+
+ //sscanf(p,"%s:", );
+ if (strstr(l_tpinfor[0].name, l_tsdev->ts_id) == NULL)
+ {
+ errlog("Can't find %s%s!\n", l_tsdev->ts_id,"xx");
+ return -ENODEV;
+ }
+ l_tpindex = 0;
+
+/*
+ p = strchr(p,':');
+ p++;
+ sscanf(p,"%d:%d:%d:%d",&irq_gpio,&panelres_x,&panelres_y,&rst_gpio);
+
+ */
+ klog("p.x = %d, p.y = %d, gpio=%d, resetgpio=%d,xaxis=%d,xdir=%d,ydri=%d,maxfingernum=%d,high_Impendence_mode=%d,s_download_option=%d\n",
+ panelres_x, panelres_y, irq_gpio, rst_gpio,
+ l_tpinfor[0].xaxis,l_tpinfor[0].xdir,l_tpinfor[0].ydir,
+ l_tpinfor[0].max_finger_num,s_high_Impendence_mode,s_download_option);
+
+ // parse touch key param
+ memset(retval,0,sizeof(retval));
+ ret = wmt_getsyspara("wmt.io.tskeyindex", retval, &len);
+ if(ret){
+ dbg("no touch key!\n");
+ //return -EIO;
+ } else {
+ p = retval;
+ // the number of touch key
+ sscanf(retval,"%d:", &val);
+ dbg("tskey num:%d\n",val);
+ p = strchr(p,':');
+ p++;
+ // touch key range
+ for (i=0;i<val;i++)
+ {
+ sscanf(p,"%d:",&val1);
+ p = strchr(p,':');
+ p++;
+ zet6221_set_tskey(i, val1);
+ dbg("key%d:(%d)\n",i,val1);
+ };
+ }
+
+ memset(retval,0,sizeof(retval));
+ ret = wmt_getsyspara("wmt.touch.earlysus", retval, &len);
+ if(!ret) {
+ p = retval;
+ sscanf(p, "%d", &earlysus_en);
+ }
+
+
+ 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])
+ lcd_exchg = 1;
+ }
+
+/* memset(retval,0,sizeof(retval));
+ ret = wmt_getsyspara("wmt.io.ts.2dcal", retval, &len);
+ if(ret){
+ errlog("Read env wmt.io.ts.2dcal Failed.\n ");
+ //return -EIO;
+ }
+ i = 0;
+ while(i < sizeof(retval)){
+ if(retval[i]==' ' || retval[i]==',' || retval[i]==':')
+ retval[i] = '\0';
+ i++;
+ }
+
+ i = 0;
+ p = retval;
+ while(i<7 && p < (retval + sizeof(retval))){
+ if(*p == '\0')
+ p++;
+ else{
+ sscanf(p,"%d",&nBuff[i]);
+ //printk("%d\n",nBuff[i]);
+ p=p+strlen(p);
+ i++;
+ }
+ }
+ //sscanf(retval,"%d %d %d %d %d %d %d %d",&nBuff[0],&nBuff[1],&nBuff[2],&nBuff[3],&nBuff[4],&nBuff[5],&nBuff[6]);
+ dbg("Tsc calibrate init data: [%d %d %d %d %d %d %d]\n",nBuff[0],nBuff[1],nBuff[2],nBuff[3],nBuff[4],nBuff[5],nBuff[6]);
+
+ g_CalcParam.a1 = nBuff[0];
+ g_CalcParam.b1 = nBuff[1];
+ g_CalcParam.c1 = nBuff[2];
+ g_CalcParam.a2 = nBuff[3];
+ g_CalcParam.b2 = nBuff[4];
+ g_CalcParam.c2 = nBuff[5];
+ g_CalcParam.delta = nBuff[6];
+
+ if(g_CalcParam.delta == 0)
+ g_CalcParam.delta =1;//avoid divide by zero
+*/
+ return 0;
+}
+
+struct i2c_board_info ts_i2c_board_info = {
+ .type = WMT_TS_I2C_NAME,
+ .flags = 0x00,
+ .addr = WMT_TS_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_bi = &ts_i2c_board_info;
+ adapter = i2c_get_adapter(1);/*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;
+ }
+}
+
+struct i2c_client* ts_get_i2c_client(void)
+{
+ return l_client;
+}
+
+static int __init wmt_ts_init(void)
+{
+ int ret = 0;
+
+ if(wmt_check_touch_env())
+ return -ENODEV;
+
+ //ts_i2c_board_info.addr = l_tpinfor[l_tpindex].i2caddr;
+ if (ts_i2c_register_device()<0)
+ {
+ dbg("Error to run ts_i2c_register_device()!\n");
+ return -1;
+ }
+
+ if (l_tsdev->init() < 0){
+ dbg("Errors to init %s ts IC!!!\n", l_tsdev->ts_id);
+ ret = -1;
+ goto err_init;
+ }
+
+ // register device and driver of platform
+ ret = platform_device_register(&wmt_ts_plt_device);
+ if(ret){
+ errlog("wmt ts plat device register failed!\n");
+ return ret;
+ }
+ ret = platform_driver_register(&wmt_ts_plt_driver);
+ if(ret){
+ errlog("can not register platform_driver_register\n");
+ platform_device_unregister(&wmt_ts_plt_device);
+ return ret;
+ }
+
+ klog("%s driver init ok!\n",l_tsdev->ts_id);
+ return 0;
+err_init:
+ ts_i2c_unregister_device();
+ return ret;
+}
+
+static void __exit wmt_ts_exit(void)
+{
+ dbg("%s\n",__FUNCTION__);
+
+ l_tsdev->exit();
+ platform_driver_unregister(&wmt_ts_plt_driver);
+ platform_device_unregister(&wmt_ts_plt_device);
+ ts_i2c_unregister_device();
+}
+
+
+module_init(wmt_ts_init);
+module_exit(wmt_ts_exit);
+
+MODULE_LICENSE("GPL");
+
diff --git a/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/wmt_ts.h b/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/wmt_ts.h
new file mode 100755
index 00000000..cab70586
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/wmt_ts.h
@@ -0,0 +1,149 @@
+
+#ifndef WMT_TSH_201010191758
+#define WMT_TSH_201010191758
+
+#include <linux/platform_device.h>
+#include <linux/types.h>
+#include <linux/device.h>
+#include <linux/suspend.h>
+#include <linux/i2c.h>
+
+
+//#define DEBUG_WMT_TS
+#ifdef DEBUG_WMT_TS
+#undef dbg
+#define dbg(fmt, args...) printk(KERN_ALERT "[%s]: " fmt, __FUNCTION__ , ## args)
+
+//#define dbg(fmt, args...) if (kpadall_isrundbg()) printk(KERN_ALERT "[%s]: " fmt, __FUNCTION__, ## args)
+
+#else
+#define dbg(fmt, args...)
+#endif
+
+#undef errlog
+#undef klog
+#define errlog(fmt, args...) printk("[%s]: " fmt, __FUNCTION__, ## args)
+#define klog(fmt, args...) printk("[%s]: " fmt, __FUNCTION__, ## args)
+
+#define WMT_TS_I2C_NAME "zet6221-ts"
+#define WMT_TS_I2C_ADDR 0x76
+
+
+#ifndef dim
+#define dim(x) (sizeof(x) / sizeof(x[0]))
+#endif
+
+extern int earlysus_en;
+
+//////////////////////////////data type///////////////////////////
+typedef struct {
+ short pressure;
+ short x;
+ short y;
+ //short millisecs;
+} TS_EVENT;
+
+struct wmtts_device
+{
+ //data
+ char* driver_name;
+ char* ts_id;
+ //function
+ int (*init)(void);
+ int (*probe)(struct platform_device *platdev);
+ int (*remove)(struct platform_device *pdev);
+ void (*exit)(void);
+ int (*suspend)(struct platform_device *pdev, pm_message_t state);
+ int (*resume)(struct platform_device *pdev);
+ int (*capacitance_calibrate)(void);
+ int (*wait_penup)(struct wmtts_device*tsdev); // waiting untill penup
+ int penup; // 0--pendown;1--penup
+
+};
+
+enum {
+ ZET6221 = 0,
+ ZET6231,
+ ZET6223,
+ ZET6251,
+};
+extern u8 ic_model;
+extern unsigned char* flash_buffer;
+extern int l_fwlen;
+
+
+//////////////////////////function interface/////////////////////////
+extern int wmt_ts_get_gpionum(void);
+extern int wmt_ts_iscalibrating(void);
+extern int wmt_ts_get_resolvX(void);
+extern int wmt_ts_get_resolvY(void);
+extern int wmt_set_gpirq(int type);
+extern int wmt_get_tsirqnum(void);
+extern int wmt_disable_gpirq(void);
+extern int wmt_enable_gpirq(void);
+extern int wmt_is_tsirq_enable(void);
+extern int wmt_is_tsint(void);
+extern void wmt_clr_int(void);
+extern void wmt_tsreset_init(void);
+extern int wmt_ts_get_resetgpnum(void);
+extern int wmt_ts_get_lcdexchg(void);
+extern void wmt_enable_rst_pull(int enable);
+extern void wmt_set_rst_pull(int up);
+extern void wmt_rst_output(int high);
+extern void wmt_rst_input(void);
+extern void wmt_set_intasgp(void);
+extern void wmt_intgp_out(int val);
+extern void wmt_ts_set_irqinput(void);
+extern unsigned int wmt_ts_irqinval(void);
+extern void wmt_ts_set_penup(int up);
+extern int wmt_ts_wait_penup(void);
+extern void wmt_ts_wakeup_penup(void);
+extern struct i2c_client* ts_get_i2c_client(void);
+extern int wmt_ts_ispenup(void);
+extern unsigned int wmt_ts_get_maxfingernum(void);
+extern unsigned int wmt_ts_get_ictype(void);
+extern unsigned int wmt_ts_get_xaxis(void);
+extern unsigned int wmt_ts_get_xdir(void);
+extern unsigned int wmt_ts_get_ydir(void);
+// short
+extern unsigned int wmt_ts_get_touchheight(void);
+// long
+extern unsigned int wmt_ts_get_touchwidth(void);
+extern void wmt_ts_get_firmwname(char* firmname);
+extern int wmt_ts_load_firmware(char* firmwarename, unsigned char** firmdata, int* fwlen);
+
+
+
+
+extern void TouchPanelCalibrateAPoint(
+ int UncalX, //@PARM The uncalibrated X coordinate
+ int UncalY, //@PARM The uncalibrated Y coordinate
+ int *pCalX, //@PARM The calibrated X coordinate
+ int *pCalY //@PARM The calibrated Y coordinate
+ );
+
+//filepath:the path of firmware file;
+//firmdata:store the data from firmware file;
+//maxlen: the max len of firmdata;
+//return:the length of firmware data,negative-parsing error.
+//extern
+u8 zet6221_ts_sfr(struct i2c_client *client);
+int wmt_getsyspara(char *varname, unsigned char *varval, int *varlen);
+
+
+#define HIGH_IMPENDENCE_MODE 0
+#define NOT_HIGH_IMPENDENCE_MODE 1
+
+extern int is_high_impendence_mode(void);
+
+
+#define FORCE_DOWNLOAD 1
+#define FORCE_CANCEL_DOWNLOAD 2
+extern int get_download_option(void);
+
+
+
+#endif
+
+
+
diff --git a/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/zet6221_downloader.c b/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/zet6221_downloader.c
new file mode 100755
index 00000000..ac51aa21
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/zet6221_downloader.c
@@ -0,0 +1,1209 @@
+#include <linux/kernel.h>
+#include <linux/i2c.h>
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/slab.h>
+//#include "zet6221_fw.h"
+
+#include "wmt_ts.h"
+
+#define ZET6221_DOWNLOADER_NAME "zet6221_downloader"
+#define FEATURE_FW_CHECK_SUM 1
+//#define High_Impendence_Mode
+
+#define TS_INT_GPIO S3C64XX_GPN(9) /*s3c6410*/
+#define TS_RST_GPIO S3C64XX_GPN(10) /*s3c6410*/
+#define RSTPIN_ENABLE
+
+#define GPIO_LOW 0
+#define GPIO_HIGH 1
+
+//static u8 fw_version0;
+//static u8 fw_version1;
+
+//#define debug_mode 1
+//#define DPRINTK(fmt,args...) do { if (debug_mode) printk(KERN_EMERG "[%s][%d] "fmt"\n", __FUNCTION__, __LINE__, ##args);} while(0)
+
+static unsigned char zeitec_zet6221_page[131] __initdata;
+static unsigned char zeitec_zet6221_page_in[131] __initdata;
+unsigned char* flash_buffer = NULL;
+int l_fwlen = 0;
+
+//static u16 fb[8] = {0x3EEA,0x3EED,0x3EF0,0x3EF3,0x3EF6,0x3EF9,0x3EFC,0x3EFF};
+static u16 fb[8] = {0x3DF1,0x3DF4,0x3DF7,0x3DFA,0x3EF6,0x3EF9,0x3EFC,0x3EFF};
+static u16 fb21[8] = {0x3DF1,0x3DF4,0x3DF7,0x3DFA,0x3EF6,0x3EF9,0x3EFC,0x3EFF};
+static u16 fb23[8] = {0x7BFC,0x7BFD,0x7BFE,0x7BFF,0x7C04,0x7C05,0x7C06,0x7C07};
+u8 ic_model = 0;
+
+extern int zet6221_i2c_write_tsdata(struct i2c_client *client, u8 *data, u8 length);
+extern int zet6221_i2c_read_tsdata(struct i2c_client *client, u8 *data, u8 length);
+extern u8 pc[];
+
+
+
+
+/************************load firmwre data from file************************/
+int zet6221_load_fw(void)
+{
+ char fwname[256] = {0};
+ int ret = -1;
+ wmt_ts_get_firmwname(fwname);
+ ret = wmt_ts_load_firmware(fwname, &flash_buffer, &l_fwlen);
+ if(!ret) {
+ printk("Success load fw_file: %s, length %d\n", fwname, l_fwlen);
+ printk("%x,%x,%x,%x\n", flash_buffer[0], flash_buffer[1], flash_buffer[2], flash_buffer[3]);
+ printk("%x,%x,%x,%x\n", flash_buffer[l_fwlen-4], flash_buffer[l_fwlen-3], flash_buffer[l_fwlen-2], flash_buffer[l_fwlen-1]);
+ }
+ return ret;
+}
+
+/***********************free firmware memory*******************************/
+int zet6221_free_fwmem(void)
+{
+ if (l_fwlen > 0 && flash_buffer != NULL )
+ {
+ kfree(flash_buffer);
+ flash_buffer = NULL;
+ l_fwlen = 0;
+ }
+ return 0;
+}
+//#define I2C_CTPM_ADDRESS (0x76)
+
+/***********************************************************************
+[function]:
+ callback: write data to ctpm by i2c interface,implemented by special user;
+[parameters]:
+ client[in] :i2c client structure;
+ bt_ctpm_addr[in] :the address of the ctpm;
+ pbt_buf[in] :data buffer;
+ dw_lenth[in] :the length of the data buffer;
+[return]:
+ 1 :success;
+ 0 :fail;
+************************************************************************/
+int i2c_write_interface(struct i2c_client *client, u8 bt_ctpm_addr, u8* pbt_buf, u16 dw_lenth)
+{
+ struct i2c_msg msg;
+ msg.addr = bt_ctpm_addr;
+ msg.flags = 0;
+ msg.len = dw_lenth;
+ msg.buf = pbt_buf;
+ return i2c_transfer(client->adapter,&msg, 1);
+}
+
+/***********************************************************************
+[function]:
+ callback: read data from ctpm by i2c interface,implemented by special user;
+[parameters]:
+ client[in] :i2c client structure;
+ bt_ctpm_addr[in] :the address of the ctpm;
+ pbt_buf[out] :data buffer;
+ dw_lenth[in] :the length of the data buffer;
+[return]:
+ 1 :success;
+ 0 :fail;
+************************************************************************/
+int i2c_read_interface(struct i2c_client *client, u8 bt_ctpm_addr, u8* pbt_buf, u16 dw_lenth)
+{
+ struct i2c_msg msg;
+ msg.addr = bt_ctpm_addr;
+ msg.flags = I2C_M_RD;
+ msg.len = dw_lenth;
+ msg.buf = pbt_buf;
+ return i2c_transfer(client->adapter,&msg, 1);
+}
+
+/***********************************************************************
+ [function]:
+ callback: check version;
+ [parameters]:
+ void
+
+ [return]:
+ 0: different 1: same;
+************************************************************************/
+u8 zet6221_ts_version(void)
+{
+ int i;
+
+ if(pc == NULL){
+ errlog(" pc is NULL\n");
+ return 0;
+ }
+ if( flash_buffer == NULL ){
+ errlog("flash_buffer \n");
+ return 0;
+ }
+
+#if 1
+ dbg("pc: ");
+ for(i=0;i<8;i++){
+ dbg("%02x ",pc[i]);
+ }
+ dbg("\n");
+
+ dbg("src: ");
+ for(i=0;i<8;i++){
+ dbg("%02x ", flash_buffer[fb[i]]);
+ }
+ dbg("\n");
+#endif
+
+ mdelay(20);
+
+ for(i=0;i<8;i++)
+ if(pc[i]!= flash_buffer[fb[i]])
+ return 0;
+ return 1;
+}
+
+
+/***********************************************************************
+ [function]:
+ callback: send password 1K (ZET6223)
+ [parameters]:
+ client[in]: struct i2c_client — represent an I2C slave device;
+
+ [return]:
+ 1;
+************************************************************************/
+u8 zet6221_ts_sndpwd_1k(struct i2c_client *client)
+{
+ u8 ts_sndpwd_cmd[3] = {0x20,0xB9,0xA3};
+
+ int ret;
+
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, ts_sndpwd_cmd, 3);
+#else
+ ret=zet6221_i2c_write_tsdata(client, ts_sndpwd_cmd, 3);
+#endif
+
+
+ return 1;
+}
+
+
+/***********************************************************************
+ [function]:
+ callback: send password;
+ [parameters]:
+ client[in]: struct i2c_client ???represent an I2C slave device;
+
+ [return]:
+ 1;
+************************************************************************/
+u8 zet6221_ts_sndpwd(struct i2c_client *client)
+{
+ u8 ts_sndpwd_cmd[3] = {0x20,0xC5,0x9D};
+
+ int ret;
+
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, ts_sndpwd_cmd, 3);
+#else
+ ret=zet6221_i2c_write_tsdata(client, ts_sndpwd_cmd, 3);
+#endif
+
+ return 1;
+}
+
+u8 zet622x_ts_option(struct i2c_client *client)
+{
+ u8 ts_cmd[1] = {0x27};
+ u8 ts_cmd_erase[1] = {0x28};
+ u8 ts_in_data[16] = {0};
+ u8 ts_out_data[18] = {0};
+ int ret;
+ u16 model;
+ int i;
+ u8 high_impendence_data = 0;
+ const u8 HIGH_IMPENDENCE_MODE_DATA = 0xf1;
+ const u8 NOT_HIGH_IMPENDENCE_MODE_DATA = 0xf2;
+
+
+ dbg("zet622x_ts_option++\n");
+
+ wmt_rst_output(0);
+ msleep(10);
+ //send password
+ zet6221_ts_sndpwd(client);
+ msleep(100);
+
+
+
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, ts_cmd, dim(ts_cmd));
+#else
+ ret=zet6221_i2c_write_tsdata(client, ts_cmd, dim(ts_cmd));
+#endif
+ msleep(2);
+
+
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_read_interface(client, I2C_CTPM_ADDRESS, ts_in_data, dim(ts_in_data));
+#else
+ ret=zet6221_i2c_read_tsdata(client, ts_in_data, dim(ts_in_data));
+#endif
+ //msleep(2);
+
+ dbg("command %02x recv:\n",ts_cmd[0]);
+ for(i=0;i<16;i++)
+ {
+ dbg("%02x ",ts_in_data[i]);
+ }
+ dbg("\n");
+ // zet6231 recv: ff ff fc 30 ff 80 31 62 ff ff ff ff ff ff ff ff
+
+ model = 0x0;
+ model = ts_in_data[7];
+ model = (model << 8) | ts_in_data[6];
+
+ switch(model) {
+ case 0xFFFF:
+ ret = 1;
+ ic_model = ZET6221;
+ for(i=0;i<8;i++)
+ {
+ fb[i]=fb21[i];
+ }
+
+ if( is_high_impendence_mode() == HIGH_IMPENDENCE_MODE ){
+ high_impendence_data = HIGH_IMPENDENCE_MODE_DATA;
+ }else if( is_high_impendence_mode() == NOT_HIGH_IMPENDENCE_MODE ) {
+ high_impendence_data = NOT_HIGH_IMPENDENCE_MODE_DATA;
+ }
+
+ //#if defined(High_Impendence_Mode)
+ if(ts_in_data[2] != high_impendence_data)
+ {
+
+ if(zet6221_ts_sfr(client)==0)
+ {
+ return 0;
+ }
+
+ #if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, ts_cmd_erase, dim(ts_cmd_erase));
+ #else
+ ret=zet6221_i2c_write_tsdata(client, ts_cmd_erase, dim(ts_cmd_erase));
+ #endif
+
+ msleep(100);
+ dbg("erase ret=%d \n",ret);
+
+
+ for(i=2;i<18;i++)
+ {
+ ts_out_data[i]=ts_in_data[i-2];
+ }
+ ts_out_data[0] = 0x21;
+ ts_out_data[1] = 0xc5;
+ ts_out_data[4] = high_impendence_data;
+
+ #if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, ts_out_data, 18);
+ #else
+ ret=zet6221_i2c_write_tsdata(client, ts_out_data, 18);
+ #endif
+
+ msleep(100);
+ dbg("write out data, ret=%d\n",ret);
+
+
+
+ #if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, ts_cmd, 1);
+ #else
+ ret=zet6221_i2c_write_tsdata(client, ts_cmd, 1);
+ #endif
+
+ msleep(2);
+
+ dbg("send %02x\n",ts_cmd[0]);
+
+
+ #if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_read_interface(client, I2C_CTPM_ADDRESS, ts_in_data, 16);
+ #else
+ ret=zet6221_i2c_read_tsdata(client, ts_in_data, 16);
+ #endif
+ //msleep(2);
+ dbg("command %02x recv:\n",ts_cmd[0]);
+ for(i=0;i<16;i++)
+ {
+ dbg("%02x ",ts_in_data[i]);
+ }
+ dbg("\n");
+
+ }
+
+ //#endif
+
+
+
+ break;
+ case 0x6223:
+ ret = 1;
+ ic_model = ZET6223;
+ for(i=0;i<8;i++)
+ {
+ fb[i]=fb23[i];
+ }
+ break;
+ case 0x6231:
+ ret = 1;
+ ic_model = ZET6231;
+ for(i=0;i<8;i++)
+ {
+ fb[i]=fb23[i];
+ }
+ break;
+ case 0x6251:
+ ic_model = ZET6251;
+ for(i=0;i<8;i++)
+ {
+ fb[i] = fb23[i];
+ }
+ break;
+ default:
+ errlog("Notice: can't detect the TP IC,use ZET6231 default\n");
+ ret = 1;
+ ic_model = ZET6231;
+ for(i=0;i<8;i++)
+ {
+ fb[i]=fb23[i];
+ }
+ break;
+
+ }
+
+ wmt_rst_output(1);
+ msleep(10);
+
+ dbg("zet622x_ts_option-- ret:%d\n",ret);
+ return ret;
+}
+/***********************************************************************
+ [function]:
+ callback: set/check sfr information;
+ [parameters]:
+ client[in]: struct i2c_client ???represent an I2C slave device;
+
+ [return]:
+ 1;
+************************************************************************/
+u8 zet6221_ts_sfr(struct i2c_client *client)
+{
+ u8 ts_cmd[1] = {0x2C};
+ u8 ts_in_data[16] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ u8 ts_cmd17[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ //u8 ts_sfr_data[16] = {0x18,0x76,0x27,0x27,0xFF,0x03,0x8E,0x14,0x00,0x38,0x82,0xEC,0x00,0x00,0x7d,0x03};
+ int ret;
+ int i;
+
+ dbg("zet6221_ts_sfr++");
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, ts_cmd, 1);
+#else
+ ret=zet6221_i2c_write_tsdata(client, ts_cmd, 1);
+#endif
+ msleep(10);
+ dbg("sfr cmd : 0x%02x \n",ts_cmd[0]);
+
+
+
+ dbg("sfr rcv : \n");
+
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_read_interface(client, I2C_CTPM_ADDRESS, ts_in_data, 16);
+#else
+ ret=zet6221_i2c_read_tsdata(client, ts_in_data, 16);
+#endif
+ msleep(10);
+
+ if(ts_in_data[14]!=0x3D && ts_in_data[14]!=0x7D)
+ {
+ return 0;
+ }
+
+ for(i=0;i<16;i++)
+ {
+ ts_cmd17[i+1]=ts_in_data[i];
+ dbg("[%d]%02x\n",i,ts_in_data[i]);
+ }
+
+ dbg("\n");
+
+ // need to check 0x3D to open write function
+ if(ts_in_data[14]!=0x3D)
+ {
+ ts_cmd17[15]=0x3D;
+
+ ts_cmd17[0]=0x2B;
+
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, ts_cmd17, 17);
+#else
+ ret=zet6221_i2c_write_tsdata(client, ts_cmd17, 17);
+#endif
+
+ if(ret<0)
+ {
+ errlog("enable sfr(0x3D) failed!\n");
+ return 0;
+ }
+
+ }
+ dbg("zet6221_ts_sfr--");
+ return 1;
+}
+
+/***********************************************************************
+ [function]:
+ callback: mass erase flash;
+ [parameters]:
+ client[in]: struct i2c_client ???represent an I2C slave device;
+
+ [return]:
+ 1;
+************************************************************************/
+u8 zet6221_ts_masserase(struct i2c_client *client)
+{
+ u8 ts_cmd[1] = {0x24};
+
+ int ret;
+
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, ts_cmd, 1);
+#else
+ ret=zet6221_i2c_write_tsdata(client, ts_cmd, 1);
+#endif
+
+ return 1;
+}
+
+/***********************************************************************
+ [function]:
+ callback: erase flash by page;
+ [parameters]:
+ client[in]: struct i2c_client ???represent an I2C slave device;
+
+ [return]:
+ 1;
+************************************************************************/
+u8 zet6221_ts_pageerase(struct i2c_client *client,int npage)
+{
+ u8 ts_cmd[3] = {0x23,0x00,0x00};
+ u8 len = 0;
+ int ret;
+
+ switch(ic_model)
+ {
+ case ZET6221:
+ ts_cmd[1]=npage;
+ len=2;
+ break;
+ case ZET6231:
+ case ZET6223:
+ case ZET6251:
+ ts_cmd[1]=npage & 0xff;
+ ts_cmd[2]=npage >> 8;
+ len=3;
+ break;
+ default:
+ ts_cmd[1]=npage & 0xff;
+ ts_cmd[2]=npage >> 8;
+ len=3;
+ break;
+ }
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, ts_cmd, len);
+#else
+ ret=zet6221_i2c_write_tsdata(client, ts_cmd, len);
+#endif
+ msleep(2);
+
+ return 1;
+}
+
+/***********************************************************************
+ [function]:
+ callback: reset mcu;
+ [parameters]:
+ client[in]: struct i2c_client ???represent an I2C slave device;
+
+ [return]:
+ 1;
+************************************************************************/
+u8 zet6221_ts_resetmcu(struct i2c_client *client)
+{
+ u8 ts_cmd[1] = {0x29};
+
+ int ret;
+
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, ts_cmd, 1);
+#else
+ ret=zet6221_i2c_write_tsdata(client, ts_cmd, 1);
+#endif
+
+ return 1;
+}
+
+
+#define CMD_PROG_CHECK_SUM (0x36)
+#define CMD_PROG_GET_CHECK_SUM (0x37)
+///***********************************************************************
+/// [function]: zet622x_cmd_read_check_sum
+/// [parameters]: client, page_id, buf
+/// [return]: int
+///************************************************************************
+int zet622x_cmd_read_check_sum(struct i2c_client *client, int page_id, u8 * buf)
+{
+ int ret;
+ int cmd_len = 3;
+
+ buf[0]= CMD_PROG_CHECK_SUM;
+ buf[1]= (u8)(page_id) & 0xff;
+ buf[2]= (u8)(page_id >> 8);
+ ret=zet6221_i2c_write_tsdata(client, buf, cmd_len);
+ if(ret<=0)
+ {
+ printk("[ZET]: Read check sum fail");
+ return ret;
+ }
+
+ buf[0]= CMD_PROG_GET_CHECK_SUM;
+ cmd_len = 1;
+ ret=zet6221_i2c_write_tsdata(client, buf, cmd_len);
+ if(ret<=0)
+ {
+ printk("[ZET]: Read check sum fail");
+ return ret;
+ }
+
+ cmd_len = 1;
+ ret = zet6221_i2c_read_tsdata(client, buf, cmd_len);
+ if(ret<=0)
+ {
+ printk("[ZET]: Read check sum fail");
+ return ret;
+ }
+ return 1;
+}
+
+
+/***********************************************************************
+ [function]:
+ callback: start HW function;
+ [parameters]:
+ client[in]: struct i2c_client ???represent an I2C slave device;
+
+ [return]:
+ 1;
+************************************************************************/
+u8 zet6221_ts_hwcmd(struct i2c_client *client)
+{
+ u8 ts_cmd[1] = {0xB9};
+
+ int ret;
+
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, ts_cmd, 1);
+#else
+ ret=zet6221_i2c_write_tsdata(client, ts_cmd, 1);
+#endif
+
+ return 1;
+}
+
+/***********************************************************************
+update FW
+************************************************************************/
+int __init zet6221_downloader( struct i2c_client *client )
+{
+ int BufLen=0;
+ int BufPage=0;
+ int BufIndex=0;
+ int ret;
+ int i;
+
+ int nowBufLen=0;
+ int nowBufPage=0;
+ int nowBufIndex=0;
+ int retryCount=0;
+ int retryTimes = 0;
+
+ int i2cLength=0;
+ int bufOffset=0;
+
+ dbg("zet6221_downloader++\n");
+
+begin_download:
+
+#if defined(RSTPIN_ENABLE)
+ //reset mcu
+ //gpio_direction_output(TS_RST_GPIO, GPIO_LOW);
+ wmt_rst_output(0);
+ msleep(5);
+#else
+ zet6221_ts_hwcmd(client);
+ msleep(200);
+#endif
+ //send password
+ //send password
+ ret = zet6221_ts_sndpwd(client);
+ dbg("zet6221_ts_sndpwd ret=%d\n",ret);
+ msleep(100);
+
+/*****compare version*******/
+
+ //0~3
+ memset(zeitec_zet6221_page_in,0x00,131);
+ switch(ic_model)
+ {
+ case ZET6221:
+ zeitec_zet6221_page_in[0]=0x25;
+ zeitec_zet6221_page_in[1]=(fb[0] >> 7);//(fb[0]/128);
+
+ i2cLength=2;
+ break;
+ case ZET6231:
+ case ZET6223:
+ case ZET6251:
+ default:
+ zeitec_zet6221_page_in[0]=0x25;
+ zeitec_zet6221_page_in[1]=(fb[0] >> 7) & 0xff; //(fb[0]/128);
+ zeitec_zet6221_page_in[2]=(fb[0] >> 7) >> 8; //(fb[0]/128);
+
+ i2cLength=3;
+ break;
+ }
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, zeitec_zet6221_page_in, i2cLength);
+#else
+ ret=zet6221_i2c_write_tsdata(client, zeitec_zet6221_page_in, i2cLength);
+ dbg("write_ret =%d, i2caddr=0x%x\n", ret, client->addr);
+#endif
+ msleep(2);
+
+ zeitec_zet6221_page_in[0]=0x0;
+ zeitec_zet6221_page_in[1]=0x0;
+ zeitec_zet6221_page_in[2]=0x0;
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_read_interface(client, I2C_CTPM_ADDRESS, zeitec_zet6221_page_in, 128);
+#else
+ ret=zet6221_i2c_read_tsdata(client, zeitec_zet6221_page_in, 128);
+ dbg("read_ret =%d, i2caddr=0x%x\n", ret, client->addr);
+#endif
+
+ //printk("page=%d ",(fb[0] >> 7)); //(fb[0]/128));
+ for(i=0;i<4;i++)
+ {
+ pc[i]=zeitec_zet6221_page_in[(fb[i] & 0x7f)]; //[(fb[i]%128)];
+ dbg("offset[%d]=%d ",i,(fb[i] & 0x7f)); //(fb[i]%128));
+ }
+ dbg("\n");
+
+
+ // 4~7
+ memset(zeitec_zet6221_page_in,0x00,131);
+ switch(ic_model)
+ {
+ case ZET6221:
+ zeitec_zet6221_page_in[0]=0x25;
+ zeitec_zet6221_page_in[1]=(fb[4] >> 7);//(fb[4]/128);
+
+ i2cLength=2;
+ break;
+ case ZET6231:
+ case ZET6223:
+ case ZET6251:
+ zeitec_zet6221_page_in[0]=0x25;
+ zeitec_zet6221_page_in[1]=(fb[4] >> 7) & 0xff; //(fb[4]/128);
+ zeitec_zet6221_page_in[2]=(fb[4] >> 7) >> 8; //(fb[4]/128);
+
+ i2cLength=3;
+ break;
+ }
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, zeitec_zet6221_page_in, i2cLength);
+#else
+ ret=zet6221_i2c_write_tsdata(client, zeitec_zet6221_page_in, i2cLength);
+ dbg("write_ret =%d, i2caddr=0x%x\n", ret, client->addr);
+#endif
+
+ zeitec_zet6221_page_in[0]=0x0;
+ zeitec_zet6221_page_in[1]=0x0;
+ zeitec_zet6221_page_in[2]=0x0;
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_read_interface(client, I2C_CTPM_ADDRESS, zeitec_zet6221_page_in, 128);
+#else
+ ret=zet6221_i2c_read_tsdata(client, zeitec_zet6221_page_in, 128);
+ dbg("read_ret =%d, i2caddr=0x%x\n", ret, client->addr);
+#endif
+
+ //printk("page=%d ",(fb[4] >> 7)); //(fb[4]/128));
+ for(i=4;i<8;i++)
+ {
+ pc[i]=zeitec_zet6221_page_in[(fb[i] & 0x7f)]; //[(fb[i]%128)];
+ dbg("offset[%d]=%d ",i,(fb[i] & 0x7f)); //(fb[i]%128));
+ }
+ dbg("\n");
+
+#if 1 // need to check
+ //page 127
+ memset(zeitec_zet6221_page_in,0x00,130);
+ zeitec_zet6221_page_in[0]=0x25;
+ zeitec_zet6221_page_in[1]=127;
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, zeitec_zet6221_page_in, 2);
+#else
+ ret=zet6221_i2c_write_tsdata(client, zeitec_zet6221_page_in, 2);
+#endif
+
+ zeitec_zet6221_page_in[0]=0x0;
+ zeitec_zet6221_page_in[1]=0x0;
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_read_interface(client, I2C_CTPM_ADDRESS, zeitec_zet6221_page_in, 128);
+#else
+ ret=zet6221_i2c_read_tsdata(client, zeitec_zet6221_page_in, 128);
+#endif
+
+ for(i=0;i<128;i++)
+ {
+ // 0x3F80 = 16256 = 128x127, means skipped the first 127 page (0-126) ,use the page 127.
+ if(0x3F80+i < l_fwlen/*sizeof(flash_buffer)/sizeof(char)*/) //l_fwlen: the bytes of data read from firmware file
+ {
+ if(zeitec_zet6221_page_in[i]!=flash_buffer[0x3F80+i])
+ {
+ errlog("page 127 [%d] doesn't match! continue to download! retry times:%d\n",i,retryTimes);
+ if( retryTimes++ >= 20){ // retry 20 times ,quit
+ errlog("May be I2C comunication is error\n");
+ goto exit_download;
+ }
+ goto proc_sfr;
+ }
+ }
+ }
+
+#endif
+
+ if( get_download_option() == FORCE_DOWNLOAD ){
+ errlog("FORCE_DOWNLOAD\n");
+ goto proc_sfr;
+ }
+ if( get_download_option() == FORCE_CANCEL_DOWNLOAD ){
+ errlog("FORCE_CANCEL_DOWNLOAD\n");
+ goto exit_download;
+ }
+ if(zet6221_ts_version()!=0){
+ klog("tp version is the same,no need to download\n");
+ goto exit_download;
+ }
+
+
+
+/*****compare version*******/
+proc_sfr:
+ //sfr
+ if(zet6221_ts_sfr(client)==0)
+ {
+
+#if 1
+
+#if defined(RSTPIN_ENABLE)
+
+ //gpio_direction_output(TS_RST_GPIO, GPIO_HIGH);
+ wmt_rst_output(1);
+ msleep(20);
+
+ //gpio_direction_output(TS_RST_GPIO, GPIO_LOW);
+ wmt_rst_output(0);
+ msleep(20);
+
+ //gpio_direction_output(TS_RST_GPIO, GPIO_HIGH);
+ wmt_rst_output(1);
+#else
+ zet6221_ts_resetmcu(client);
+#endif
+ msleep(20);
+ errlog("zet6221_ts_sfr error, download again\n");
+ goto begin_download;
+
+#endif
+
+ }
+ msleep(20);
+
+ /// Fix the bug that page#504~#512 failed to write
+ if(ic_model == ZET6223)
+ {
+ zet6221_ts_sndpwd_1k(client);
+ }
+
+ //erase
+ if(BufLen==0)
+ {
+ //mass erase
+ dbg( "mass erase\n");
+ zet6221_ts_masserase(client);
+ msleep(200);
+
+ BufLen=l_fwlen;/*sizeof(flash_buffer)/sizeof(char)*/;
+ }else
+ {
+ zet6221_ts_pageerase(client,BufPage);
+ msleep(200);
+ }
+
+
+ while(BufLen>0)
+ {
+download_page:
+
+ memset(zeitec_zet6221_page,0x00,131);
+
+ klog( "Start: write page%d\n",BufPage);
+ nowBufIndex=BufIndex;
+ nowBufLen=BufLen;
+ nowBufPage=BufPage;
+
+ switch(ic_model)
+ {
+ case ZET6221:
+ bufOffset = 2;
+ i2cLength=130;
+
+ zeitec_zet6221_page[0]=0x22;
+ zeitec_zet6221_page[1]=BufPage;
+ break;
+ case ZET6231:
+ case ZET6223:
+ case ZET6251:
+ default:
+ bufOffset = 3;
+ i2cLength=131;
+
+ zeitec_zet6221_page[0]=0x22;
+ zeitec_zet6221_page[1]=BufPage & 0xff;
+ zeitec_zet6221_page[2]=BufPage >> 8;
+ break;
+ }
+ if(BufLen>128)
+ {
+ for(i=0;i<128;i++)
+ {
+ zeitec_zet6221_page[i+bufOffset]=flash_buffer[BufIndex];
+ BufIndex+=1;
+ }
+ zeitec_zet6221_page[0]=0x22;
+ zeitec_zet6221_page[1]=BufPage;
+ BufLen-=128;
+ }
+ else
+ {
+ for(i=0;i<BufLen;i++)
+ {
+ zeitec_zet6221_page[i+bufOffset]=flash_buffer[BufIndex];
+ BufIndex+=1;
+ }
+ zeitec_zet6221_page[0]=0x22;
+ zeitec_zet6221_page[1]=BufPage;
+ BufLen=0;
+ }
+
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, zeitec_zet6221_page, i2cLength);
+#else
+ ret=zet6221_i2c_write_tsdata(client, zeitec_zet6221_page, i2cLength);
+#endif
+ //msleep(200);
+ msleep(2);
+
+#if 1
+
+ memset(zeitec_zet6221_page_in,0x00,131);
+ switch(ic_model)
+ {
+ case ZET6221:
+ zeitec_zet6221_page_in[0]=0x25;
+ zeitec_zet6221_page_in[1]=BufPage;
+
+ i2cLength=2;
+ break;
+ case ZET6231:
+ case ZET6223:
+ case ZET6251:
+ default:
+ zeitec_zet6221_page_in[0]=0x25;
+ zeitec_zet6221_page_in[1]=BufPage & 0xff;
+ zeitec_zet6221_page_in[2]=BufPage >> 8;
+
+ i2cLength=3;
+ break;
+ }
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_write_interface(client, I2C_CTPM_ADDRESS, zeitec_zet6221_page_in, i2cLength);
+#else
+ ret=zet6221_i2c_write_tsdata(client, zeitec_zet6221_page_in, i2cLength);
+#endif
+ msleep(2);
+
+ zeitec_zet6221_page_in[0]=0x0;
+ zeitec_zet6221_page_in[1]=0x0;
+ zeitec_zet6221_page_in[2]=0x0;
+#if defined(I2C_CTPM_ADDRESS)
+ ret=i2c_read_interface(client, I2C_CTPM_ADDRESS, zeitec_zet6221_page_in, 128);
+#else
+ ret=zet6221_i2c_read_tsdata(client, zeitec_zet6221_page_in, 128);
+#endif
+
+ for(i=0;i<128;i++)
+ {
+ if(i < nowBufLen)
+ {
+ if(zeitec_zet6221_page[i+bufOffset]!=zeitec_zet6221_page_in[i])
+ {
+ BufIndex=nowBufIndex;
+ BufLen=nowBufLen;
+ BufPage=nowBufPage;
+
+ if(retryCount < 5)
+ {
+ retryCount++;
+ goto download_page;
+ }else
+ {
+ //BufIndex=0;
+ //BufLen=0;
+ //BufPage=0;
+ retryCount=0;
+
+#if defined(RSTPIN_ENABLE)
+ //gpio_direction_output(TS_RST_GPIO, GPIO_HIGH);
+ wmt_rst_output(1);
+ msleep(20);
+
+ //gpio_direction_output(TS_RST_GPIO, GPIO_LOW);
+ wmt_rst_output(0);
+ msleep(20);
+
+ //gpio_direction_output(TS_RST_GPIO, GPIO_HIGH);
+ wmt_rst_output(1);
+#else
+ zet6221_ts_resetmcu(client);
+#endif
+ msleep(20);
+ goto begin_download;
+ }
+
+ }
+ }
+ }
+
+#endif
+ retryCount=0;
+ BufPage+=1;
+ }
+
+exit_download:
+
+#if defined(RSTPIN_ENABLE)
+ //gpio_direction_output(TS_RST_GPIO, GPIO_HIGH);
+ wmt_rst_output(1);
+ msleep(100);
+#endif
+
+ zet6221_ts_resetmcu(client);
+ msleep(100);
+
+ dbg("zet6221_downloader--\n");
+ return 1;
+
+
+}
+
+int zet622x_resume_downloader(struct i2c_client *client)
+{
+ int ret = 0;
+
+ int BufLen=0;
+ int BufPage=0;
+ int BufIndex=0;
+ int bufOffset = 0;
+
+ int nowBufLen=0;
+ int nowBufPage=0;
+ int nowBufIndex=0;
+
+ int i2cLength = 0;
+
+ int i = 0;
+
+ u8 bPageBuf[256];
+
+#ifdef FEATURE_FW_CHECK_SUM
+ u8 get_check_sum = 0;
+ u8 check_sum = 0;
+ int retry_count = 0;
+ u8 tmp_data[16];
+#endif ///< for FEATURE_FW_CHECK_SUM
+
+
+ ///-------------------------------------------------------------///
+ /// 1. Set RST=LOW
+ ///-------------------------------------------------------------///
+ wmt_rst_output(0);
+ msleep(20);
+ //printk("RST = LOW\n");
+
+ ///-------------------------------------------------------------///
+ /// Send password
+ ///-------------------------------------------------------------///
+ ret = zet6221_ts_sndpwd(client);
+ if(ret<=0)
+ {
+ return ret;
+ }
+
+ //printk("AAA\n");
+ BufLen=l_fwlen;/*sizeof(flash_buffer)/sizeof(char)*/;
+ //printk("BBB%d\n",BufLen);
+
+ while(BufLen>0)
+ {
+ /// memset(zeitec_zet622x_page, 0x00, 131);
+ nowBufIndex=BufIndex;
+ nowBufLen=BufLen;
+ nowBufPage=BufPage;
+
+ switch(ic_model)
+ {
+ case ZET6251:
+ bufOffset = 3;
+ i2cLength=131;
+
+ bPageBuf[0]=0x22;
+ bPageBuf[1]=BufPage & 0xff;
+ bPageBuf[2]=BufPage >> 8;
+ break;
+ }
+
+ if(BufLen>128)
+ {
+ for(i=0;i<128;i++)
+ {
+ bPageBuf[i + bufOffset] = flash_buffer[BufIndex];
+ BufIndex += 1;
+ }
+
+ BufLen = BufLen - 128;
+ }
+ else
+ {
+ for(i=0;i<BufLen;i++)
+ {
+ bPageBuf[i+bufOffset]=flash_buffer[BufIndex];
+ BufIndex+=1;
+ }
+
+ BufLen=0;
+ }
+
+#ifdef FEATURE_FW_CHECK_SUM
+LABEL_RETRY_DOWNLOAD_PAGE:
+#endif ///< for FEATURE_FW_CHECK_SUM
+
+ ret=zet6221_i2c_write_tsdata(client, bPageBuf, i2cLength);
+
+ if(ic_model!= ZET6251)
+ {
+ msleep(50);
+ }
+
+#ifdef FEATURE_FW_CHECK_SUM
+ ///---------------------------------///
+ /// Get check sum
+ ///---------------------------------///
+ for(i=0;i<128;i++)
+ {
+ if(i == 0)
+ {
+ check_sum = bPageBuf[i + bufOffset];
+ }
+ else
+ {
+ check_sum = check_sum ^ bPageBuf[i + bufOffset];
+ }
+ }
+
+ ///---------------------------------///
+ /// Read check sum
+ ///---------------------------------///
+ memset(tmp_data, 0, 16);
+ ret = zet622x_cmd_read_check_sum(client, BufPage, &tmp_data[0]);
+ if(ret<=0)
+ {
+ return ret;
+ }
+ get_check_sum = tmp_data[0];
+
+ //printk("[ZET]: page=%3d ,Check sum : %x ,get check sum : %x\n", BufPage, check_sum, get_check_sum);
+ if(check_sum != get_check_sum)
+ {
+
+ if(retry_count < 5)
+ {
+ retry_count++;
+ goto LABEL_RETRY_DOWNLOAD_PAGE;
+ }
+ else
+ {
+ retry_count = 0;
+ wmt_rst_output(1);
+ msleep(20);
+ wmt_rst_output(0);
+ msleep(20);
+ wmt_rst_output(1);
+ msleep(20);
+ printk("[ZET] zet622x_resume_downloader fail\n");
+ return ret;
+ }
+
+ }
+ retry_count = 0;
+#endif ///< for FEATURE_FW_CHECK_SUM
+
+ BufPage+=1;
+ }
+
+ printk("[ZET] zet622x_resume_downloader OK\n");
+ //printk("RST = HIGH\n");
+
+ ///-------------------------------------------------------------///
+ /// reset_mcu command
+ ///-------------------------------------------------------------///
+ zet6221_ts_resetmcu(client);
+ msleep(10);
+
+ ///-------------------------------------------------------------///
+ /// SET RST=HIGH
+ ///-------------------------------------------------------------///
+ wmt_rst_output(1);
+ msleep(20);
+
+ ///-------------------------------------------------------------///
+ /// RST toggle
+ ///-------------------------------------------------------------///
+ wmt_rst_output(0);
+ msleep(2);
+
+ wmt_rst_output(1);
+ msleep(2);
+
+ return ret;
+}
+
diff --git a/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/zet6221_i2c.c b/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/zet6221_i2c.c
new file mode 100755
index 00000000..31818510
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/zet6221_i2c.c
@@ -0,0 +1,2786 @@
+/* drivers/input/touchscreen/zet6221_i2c.c
+ * 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.
+ * ZEITEC Semiconductor Co., Ltd
+ * Tel: +886-3-579-0045
+ * Fax: +886-3-579-9960
+ * http://www.zeitecsemi.com
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/input.h>
+#include <linux/platform_device.h>
+#include <linux/jiffies.h>
+#include <linux/io.h>
+#include <linux/kthread.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/delay.h>
+#include <linux/wakelock.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#include <linux/slab.h>
+#include <linux/irq.h>
+#include <linux/errno.h>
+#include <linux/fs.h>
+#include <linux/file.h>
+#include <asm/uaccess.h>
+
+#include <linux/input/mt.h>
+#include "wmt_ts.h"
+#include <linux/power/wmt_battery.h>
+#include "../../../video/backlight/wmt_bl.h"
+
+
+//fw update.
+//#include "zet6221_fw.h"
+
+/* -------------- global variable definition -----------*/
+#define _MACH_MSM_TOUCH_H_
+
+#define ZET_TS_ID_NAME "zet6221-ts"
+
+#define MJ5_TS_NAME "touch_zet6221"
+
+//#define TS_INT_GPIO S3C64XX_GPN(9) /*s3c6410*/
+//#define TS1_INT_GPIO AT91_PIN_PB17 /*AT91SAM9G45 external*/
+//#define TS1_INT_GPIO AT91_PIN_PA27 /*AT91SAM9G45 internal*/
+//#define TS_RST_GPIO S3C64XX_GPN(10)
+
+//#define MT_TYPE_B
+
+#define TS_RST_GPIO
+#define X_MAX 800 //1024
+#define Y_MAX 480 //576
+#define FINGER_NUMBER 5
+#define KEY_NUMBER 3 //0
+//#define P_MAX 1
+#define P_MAX 255 //modify 2013-1-1
+#define D_POLLING_TIME 25000
+#define U_POLLING_TIME 25000
+#define S_POLLING_TIME 100
+#define REPORT_POLLING_TIME 3
+#define RETRY_DOWNLOAD_TIMES 2
+
+#define MAX_KEY_NUMBER 8
+#define MAX_FINGER_NUMBER 16
+#define TRUE 1
+#define FALSE 0
+
+//#define debug_mode 1
+//#define DPRINTK(fmt,args...) do { if (debug_mode) printk(KERN_EMERG "[%s][%d] "fmt"\n", __FUNCTION__, __LINE__, ##args);} while(0)
+
+//#define TRANSLATE_ENABLE 1
+#define TOPRIGHT 0
+#define TOPLEFT 1
+#define BOTTOMRIGHT 2
+#define BOTTOMLEFT 3
+#define ORIGIN BOTTOMRIGHT
+
+#define TIME_CHECK_CHARGE 3000
+
+#define I2C_MAJOR 126
+#define I2C_MINORS 256
+
+
+///=============================================================================================///
+/// IOCTL control Definition
+///=============================================================================================///
+#define ZET_IOCTL_CMD_FLASH_READ (20)
+#define ZET_IOCTL_CMD_FLASH_WRITE (21)
+#define ZET_IOCTL_CMD_RST (22)
+#define ZET_IOCTL_CMD_RST_HIGH (23)
+#define ZET_IOCTL_CMD_RST_LOW (24)
+
+#define ZET_IOCTL_CMD_DYNAMIC (25)
+
+#define ZET_IOCTL_CMD_FW_FILE_PATH_GET (26)
+#define ZET_IOCTL_CMD_FW_FILE_PATH_SET (27)
+
+#define ZET_IOCTL_CMD_MDEV (28)
+#define ZET_IOCTL_CMD_MDEV_GET (29)
+
+#define ZET_IOCTL_CMD_TRAN_TYPE_PATH_GET (30)
+#define ZET_IOCTL_CMD_TRAN_TYPE_PATH_SET (31)
+
+#define ZET_IOCTL_CMD_IDEV (32)
+#define ZET_IOCTL_CMD_IDEV_GET (33)
+
+#define ZET_IOCTL_CMD_MBASE (34)
+#define ZET_IOCTL_CMD_MBASE_GET (35)
+
+#define ZET_IOCTL_CMD_INFO_SET (36)
+#define ZET_IOCTL_CMD_INFO_GET (37)
+
+#define ZET_IOCTL_CMD_TRACE_X_SET (38)
+#define ZET_IOCTL_CMD_TRACE_X_GET (39)
+
+#define ZET_IOCTL_CMD_TRACE_Y_SET (40)
+#define ZET_IOCTL_CMD_TRACE_Y_GET (41)
+
+#define ZET_IOCTL_CMD_IBASE (42)
+#define ZET_IOCTL_CMD_IBASE_GET (43)
+
+#define ZET_IOCTL_CMD_DRIVER_VER_GET (44)
+#define ZET_IOCTL_CMD_MBASE_EXTERN_GET (45)
+
+#define IOCTL_MAX_BUF_SIZE (1024)
+
+///----------------------------------------------------///
+/// IOCTL ACTION
+///----------------------------------------------------///
+#define IOCTL_ACTION_NONE (0)
+#define IOCTL_ACTION_FLASH_DUMP (1<<0)
+
+static int ioctl_action = IOCTL_ACTION_NONE;
+
+///=============================================================================================///
+/// Transfer type
+///=============================================================================================///
+#define TRAN_TYPE_DYNAMIC (0x00)
+#define TRAN_TYPE_MUTUAL_SCAN_BASE (0x01)
+#define TRAN_TYPE_MUTUAL_SCAN_DEV (0x02)
+#define TRAN_TYPE_INIT_SCAN_BASE (0x03)
+#define TRAN_TYPE_INIT_SCAN_DEV (0x04)
+#define TRAN_TYPE_KEY_MUTUAL_SCAN_BASE (0x05)
+#define TRAN_TYPE_KEY_MUTUAL_SCAN_DEV (0x06)
+#define TRAN_TYPE_KEY_DATA (0x07)
+#define TRAN_TYPE_MTK_TYPE (0x0A)
+#define TRAN_TYPE_FOCAL_TYPE (0x0B)
+
+///=============================================================================================///
+/// TP Trace
+///=============================================================================================///
+#define TP_DEFAULT_ROW (10)
+#define TP_DEFAULT_COL (15)
+
+#define DRIVER_VERSION "$Revision: 44 $"
+//static char const *revision="$Revision: 44 $";
+
+///=============================================================================================///
+/// Macro Definition
+///=============================================================================================///
+#define MAX_FLASH_BUF_SIZE (0x10000)
+
+///---------------------------------------------------------------------------------///
+/// 18. IOCTRL Debug
+///---------------------------------------------------------------------------------///
+#define FEATURE_IDEV_OUT_ENABLE
+#define FEATURE_MBASE_OUT_ENABLE
+#define FEATURE_MDEV_OUT_ENABLE
+#define FEATURE_INFO_OUT_EANBLE
+#define FEATURE_IBASE_OUT_ENABLE
+
+
+
+///-------------------------------------///
+/// firmware save / load
+///-------------------------------------///
+u32 data_offset = 0;
+struct inode *inode = NULL;
+mm_segment_t old_fs;
+
+char driver_version[128];
+
+//#define FW_FILE_NAME "/vendor/modules/zet62xx.bin"
+char fw_file_name[128];
+///-------------------------------------///
+/// Transmit Type Mode Path parameters
+///-------------------------------------///
+/// External SD-Card could be
+/// "/mnt/sdcard/"
+/// "/mnt/extsd/"
+///-------------------------------------///
+
+// It should be the path where adb tools can push files in
+#define TRAN_MODE_FILE_PATH "/data/local/tmp/"
+char tran_type_mode_file_name[128];
+u8 *tran_data = NULL;
+
+///-------------------------------------///
+/// Mutual Dev Mode parameters
+///-------------------------------------///
+/// External SD-Card could be
+/// "/mnt/sdcard/zetmdev"
+/// "/mnt/extsd/zetmdev"
+///-------------------------------------///
+#ifdef FEATURE_MDEV_OUT_ENABLE
+ #define MDEV_FILE_NAME "zetmdev"
+ #define MDEV_MAX_FILE_ID (10)
+ #define MDEV_MAX_DATA_SIZE (2048)
+///-------------------------------------///
+/// mutual dev variables
+///-------------------------------------///
+ u8 *mdev_data = NULL;
+ int mdev_file_id = 0;
+#endif ///< FEATURE_MDEV_OUT_ENABLE
+
+///-------------------------------------///
+/// Initial Base Mode parameters
+///-------------------------------------///
+/// External SD-Card could be
+/// "/mnt/sdcard/zetibase"
+/// "/mnt/extsd/zetibase"
+///-------------------------------------///
+#ifdef FEATURE_IBASE_OUT_ENABLE
+ #define IBASE_FILE_NAME "zetibase"
+ #define IBASE_MAX_FILE_ID (10)
+ #define IBASE_MAX_DATA_SIZE (512)
+
+///-------------------------------------///
+/// initial base variables
+///-------------------------------------///
+ u8 *ibase_data = NULL;
+ int ibase_file_id = 0;
+#endif ///< FEATURE_IBASE_OUT_ENABLE
+
+///-------------------------------------///
+/// Initial Dev Mode parameters
+///-------------------------------------///
+/// External SD-Card could be
+/// "/mnt/sdcard/zetidev"
+/// "/mnt/extsd/zetidev"
+///-------------------------------------///
+#ifdef FEATURE_IDEV_OUT_ENABLE
+ #define IDEV_FILE_NAME "zetidev"
+ #define IDEV_MAX_FILE_ID (10)
+ #define IDEV_MAX_DATA_SIZE (512)
+
+///-------------------------------------///
+/// initial dev variables
+///-------------------------------------///
+ u8 *idev_data = NULL;
+ int idev_file_id = 0;
+#endif ///< FEATURE_IDEV_OUT_ENABLE
+
+///-------------------------------------///
+/// Mutual Base Mode parameters
+///-------------------------------------///
+/// External SD-Card could be
+/// "/mnt/sdcard/zetmbase"
+/// "/mnt/extsd/zetmbase"
+///-------------------------------------///
+#ifdef FEATURE_MBASE_OUT_ENABLE
+ #define MBASE_FILE_NAME "zetmbase"
+ #define MBASE_MAX_FILE_ID (10)
+ #define MBASE_MAX_DATA_SIZE (2048)
+
+///-------------------------------------///
+/// mutual base variables
+///-------------------------------------///
+ u8 *mbase_data = NULL;
+ int mbase_file_id = 0;
+#endif ///< FEATURE_MBASE_OUT_ENABLE
+
+///-------------------------------------///
+/// infomation variables
+///-------------------------------------///
+#ifdef FEATURE_INFO_OUT_EANBLE
+ #define INFO_MAX_DATA_SIZE (64)
+ #define INFO_DATA_SIZE (17)
+ #define ZET6221_INFO (0x00)
+ #define ZET6231_INFO (0x0B)
+ #define ZET6223_INFO (0x0D)
+ #define ZET6251_INFO (0x0C)
+ #define UNKNOW_INFO (0xFF)
+ u8 *info_data = NULL;
+#endif ///< FEATURE_INFO_OUT_EANBLE
+///-------------------------------------///
+/// Default transfer type
+///-------------------------------------///
+u8 transfer_type = TRAN_TYPE_DYNAMIC;
+
+///-------------------------------------///
+/// Default TP TRACE
+///-------------------------------------///
+int row = TP_DEFAULT_ROW;
+int col = TP_DEFAULT_COL;
+
+struct msm_ts_platform_data {
+ unsigned int x_max;
+ unsigned int y_max;
+ unsigned int pressure_max;
+};
+
+struct zet6221_tsdrv {
+ struct i2c_client *i2c_ts;
+ struct work_struct work1;
+ struct input_dev *input;
+ struct timer_list polling_timer;
+ struct delayed_work work; // for polling
+ struct workqueue_struct *queue;
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ struct early_suspend early_suspend;
+#endif
+ unsigned int gpio; /* GPIO used for interrupt of TS1*/
+ unsigned int irq;
+ unsigned int x_max;
+ unsigned int y_max;
+ unsigned int pressure_max;
+};
+
+struct i2c_dev
+{
+ struct list_head list;
+ struct i2c_adapter *adap;
+ struct device *dev;
+};
+
+static struct i2c_dev *zet_i2c_dev;
+static struct class *i2c_dev_class;
+static LIST_HEAD (i2c_dev_list);
+static DEFINE_SPINLOCK(i2c_dev_list_lock);
+
+struct zet6221_tsdrv * l_ts = NULL;
+static int l_suspend = 0; // 1:suspend, 0:normal state
+
+//static int resetCount = 0; //albert++ 20120807
+
+
+//static u16 polling_time = S_POLLING_TIME;
+
+static int l_powermode = -1;
+static struct mutex i2c_mutex;
+static struct wake_lock downloadWakeLock;
+
+
+//static int __devinit zet6221_ts_probe(struct i2c_client *client, const struct i2c_device_id *id);
+//static int __devexit zet6221_ts_remove(struct i2c_client *dev);
+extern int register_bl_notifier(struct notifier_block *nb);
+
+extern int unregister_bl_notifier(struct notifier_block *nb);
+
+extern int zet6221_downloader( struct i2c_client *client/*, unsigned short ver, unsigned char * data */);
+extern int zet622x_resume_downloader(struct i2c_client *client);
+extern u8 zet6221_ts_version(void);
+extern u8 zet6221_ts_get_report_mode_t(struct i2c_client *client);
+extern u8 zet622x_ts_option(struct i2c_client *client);
+extern int zet6221_load_fw(void);
+extern int zet6221_free_fwmem(void);
+
+void zet6221_ts_charger_mode_disable(void);
+void zet6221_ts_charger_mode(void);
+static int zet_fw_size(void);
+static void zet_fw_save(char *file_name);
+static void zet_fw_load(char *file_name);
+static void zet_fw_init(void);
+#ifdef FEATURE_MDEV_OUT_ENABLE
+static void zet_mdev_save(char *file_name);
+#endif ///< FEATURE_MDEV_OUT_ENABLE
+#ifdef FEATURE_IDEV_OUT_ENABLE
+static void zet_idev_save(char *file_name);
+#endif ///< FEATURE_IDEV_OUT_ENABLE
+#ifdef FEATURE_IBASE_OUT_ENABLE
+static void zet_ibase_save(char *file_name);
+#endif ///< FEATURE_IBASE_OUT_ENABLE
+#ifdef FEATURE_MBASE_OUT_ENABLE
+static void zet_mbase_save(char *file_name);
+#endif ///< FEATURE_MBASE_OUT_ENABLE
+static void zet_information_save(char *file_name);
+
+static struct task_struct *resume_download_task;
+
+
+
+//static int filterCount = 0;
+//static u32 filterX[MAX_FINGER_NUMBER][2], filterY[MAX_FINGER_NUMBER][2];
+
+//static u8 key_menu_pressed = 0x1;
+//static u8 key_back_pressed = 0x1;
+//static u8 key_search_pressed = 0x1;
+
+static u16 ResolutionX=X_MAX;
+static u16 ResolutionY=Y_MAX;
+static u16 FingerNum=0;
+static u16 KeyNum=0;
+static int bufLength=0;
+static u8 xyExchange=0;
+static u16 inChargerMode = 0;
+static struct i2c_client *this_client;
+struct workqueue_struct *ts_wq = NULL;
+static int l_tskey[4][2] = {
+ {KEY_BACK,0},
+ {KEY_MENU,0},
+ {KEY_HOME,0},
+ {KEY_SEARCH,0},
+};
+
+u8 pc[8];
+// {IC Model, FW Version, FW version,Codebase Type=0x08, Customer ID, Project ID, Config Board No, Config Serial No}
+
+//Touch Screen
+/*static const struct i2c_device_id zet6221_ts_idtable[] = {
+ { ZET_TS_ID_NAME, 0 },
+ { }
+};
+
+static struct i2c_driver zet6221_ts_driver = {
+ .driver = {
+ .owner = THIS_MODULE,
+ .name = ZET_TS_ID_NAME,
+ },
+ .probe = zet6221_ts_probe,
+ .remove = __devexit_p(zet6221_ts_remove),
+ .id_table = zet6221_ts_idtable,
+};
+*/
+
+void zet6221_set_tskey(int index,int key)
+{
+ l_tskey[index][0] = key;
+}
+
+
+void check_charger(void)
+{
+ mutex_lock(&i2c_mutex);
+ if (!wmt_charger_is_dc_plugin())
+ {
+ klog("disable_mode\n");
+ zet6221_ts_charger_mode_disable();
+ } else {
+ klog("charge mode\n");
+ zet6221_ts_charger_mode();
+ }
+ mutex_unlock(&i2c_mutex);
+ l_powermode = wmt_charger_is_dc_plugin();
+}
+
+
+void check_charger_polling(void)
+{
+ if(l_suspend == 1)
+ {
+ return;
+ }
+
+ if (wmt_charger_is_dc_plugin() != l_powermode)
+ {
+ check_charger();
+ }
+
+ ///-------------------------------------------------------------------///
+ /// IOCTL Action
+ ///-------------------------------------------------------------------///
+ if(ioctl_action & IOCTL_ACTION_FLASH_DUMP)
+ {
+ printk("[ZET]: IOCTL_ACTION: Dump flash\n");
+ zet_fw_save(fw_file_name);
+ ioctl_action &= ~IOCTL_ACTION_FLASH_DUMP;
+ }
+
+ return;
+}
+
+
+
+//extern unsigned int wmt_bat_is_batterypower(void);
+/***********************************************************************
+ [function]:
+ callback: Timer Function if there is no interrupt fuction;
+ [parameters]:
+ arg[in]: arguments;
+ [return]:
+ NULL;
+************************************************************************/
+
+static void polling_timer_func(struct work_struct *work)
+{
+ struct zet6221_tsdrv *ts = l_ts;
+ //schedule_work(&ts->work1);
+ //queue_work(ts_wq,&ts->work1);
+ //dbg("check mode!\n");
+/*
+ if (wmt_bat_is_batterypower() != l_powermode)
+ {
+ mutex_lock(&i2c_mutex);
+ if (wmt_bat_is_batterypower())
+ {
+ klog("disable_mode\n");
+ zet6221_ts_charger_mode_disable();
+ } else {
+ klog("charge mode\n");
+ zet6221_ts_charger_mode();
+ }
+ mutex_unlock(&i2c_mutex);
+ l_powermode = wmt_bat_is_batterypower();
+ }
+*/
+
+ check_charger_polling();
+ queue_delayed_work(ts->queue, &ts->work, msecs_to_jiffies(TIME_CHECK_CHARGE));
+
+
+ //mod_timer(&ts->polling_timer,jiffies + msecs_to_jiffies(TIME_CHECK_CHARGE));
+}
+
+
+
+///**********************************************************************
+/// [function]: zet622x_i2c_get_free_dev
+/// [parameters]: adap
+/// [return]: void
+///**********************************************************************
+static struct i2c_dev *zet622x_i2c_get_free_dev(struct i2c_adapter *adap)
+{
+ struct i2c_dev *i2c_dev;
+
+ if (adap->nr >= I2C_MINORS)
+ {
+ printk("[ZET] : i2c-dev:out of device minors (%d) \n",adap->nr);
+ return ERR_PTR (-ENODEV);
+ }
+
+ i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL);
+ if (!i2c_dev)
+ {
+ return ERR_PTR(-ENOMEM);
+ }
+ i2c_dev->adap = adap;
+
+ spin_lock(&i2c_dev_list_lock);
+ list_add_tail(&i2c_dev->list, &i2c_dev_list);
+ spin_unlock(&i2c_dev_list_lock);
+
+ return i2c_dev;
+}
+
+///**********************************************************************
+/// [function]: zet622x_i2c_dev_get_by_minor
+/// [parameters]: index
+/// [return]: i2c_dev
+///**********************************************************************
+static struct i2c_dev *zet622x_i2c_dev_get_by_minor(unsigned index)
+{
+ struct i2c_dev *i2c_dev;
+ spin_lock(&i2c_dev_list_lock);
+
+ list_for_each_entry(i2c_dev, &i2c_dev_list, list)
+ {
+ printk(" [ZET] : line = %d ,i2c_dev->adapt->nr = %d,index = %d.\n",__LINE__,i2c_dev->adap->nr,index);
+ if(i2c_dev->adap->nr == index)
+ {
+ goto LABEL_FOUND;
+ }
+ }
+ i2c_dev = NULL;
+
+LABEL_FOUND:
+ spin_unlock(&i2c_dev_list_lock);
+
+ return i2c_dev ;
+}
+
+
+
+//extern int wmt_i2c_xfer_continue_if_4(struct i2c_msg *msg, unsigned int num,int bus_id);
+/***********************************************************************
+ [function]:
+ callback: read data by i2c interface;
+ [parameters]:
+ client[in]: struct i2c_client �represent an I2C slave device;
+ data [out]: data buffer to read;
+ length[in]: data length to read;
+ [return]:
+ Returns negative errno, else the number of messages executed;
+************************************************************************/
+int zet6221_i2c_read_tsdata(struct i2c_client *client, u8 *data, u8 length)
+{
+ struct i2c_msg msg;
+ msg.addr = client->addr;
+ msg.flags = I2C_M_RD;
+ msg.len = length;
+ msg.buf = data;
+ return i2c_transfer(client->adapter,&msg, 1);
+
+ /*int rc = 0;
+
+ memset(data, 0, length);
+ rc = i2c_master_recv(client, data, length);
+ if (rc <= 0)
+ {
+ errlog("error!\n");
+ return -EINVAL;
+ } else if (rc != length)
+ {
+ dbg("want:%d,real:%d\n", length, rc);
+ }
+ return rc;*/
+}
+
+/***********************************************************************
+ [function]:
+ callback: write data by i2c interface;
+ [parameters]:
+ client[in]: struct i2c_client �represent an I2C slave device;
+ data [out]: data buffer to write;
+ length[in]: data length to write;
+ [return]:
+ Returns negative errno, else the number of messages executed;
+************************************************************************/
+int zet6221_i2c_write_tsdata(struct i2c_client *client, u8 *data, u8 length)
+{
+ struct i2c_msg msg;
+ msg.addr = client->addr;
+ msg.flags = 0;
+ msg.len = length;
+ msg.buf = data;
+ return i2c_transfer(client->adapter,&msg, 1);
+
+ /*int ret = i2c_master_recv(client, data, length);
+ if (ret <= 0)
+ {
+ errlog("error!\n");
+ }
+ return ret;
+ */
+}
+
+/***********************************************************************
+ [function]:
+ callback: coordinate traslating;
+ [parameters]:
+ px[out]: value of X axis;
+ py[out]: value of Y axis;
+ p [in]: pressed of released status of fingers;
+ [return]:
+ NULL;
+************************************************************************/
+void touch_coordinate_traslating(u32 *px, u32 *py, u8 p)
+{
+ int i;
+ u8 pressure;
+
+ #if ORIGIN == TOPRIGHT
+ for(i=0;i<MAX_FINGER_NUMBER;i++){
+ pressure = (p >> (MAX_FINGER_NUMBER-i-1)) & 0x1;
+ if(pressure)
+ {
+ px[i] = X_MAX - px[i];
+ }
+ }
+ #elif ORIGIN == BOTTOMRIGHT
+ for(i=0;i<MAX_FINGER_NUMBER;i++){
+ pressure = (p >> (MAX_FINGER_NUMBER-i-1)) & 0x1;
+ if(pressure)
+ {
+ px[i] = X_MAX - px[i];
+ py[i] = Y_MAX - py[i];
+ }
+ }
+ #elif ORIGIN == BOTTOMLEFT
+ for(i=0;i<MAX_FINGER_NUMBER;i++){
+ pressure = (p >> (MAX_FINGER_NUMBER-i-1)) & 0x1;
+ if(pressure)
+ {
+ py[i] = Y_MAX - py[i];
+ }
+ }
+ #endif
+}
+
+/***********************************************************************
+ [function]:
+ callback: reset function;
+ [parameters]:
+ void;
+ [return]:
+ void;
+************************************************************************/
+void ctp_reset(void)
+{
+#if defined(TS_RST_GPIO)
+ //reset mcu
+ /* gpio_direction_output(TS_RST_GPIO, 1);
+ msleep(1);
+ gpio_direction_output(TS_RST_GPIO, 0);
+ msleep(10);
+ gpio_direction_output(TS_RST_GPIO, 1);
+ msleep(20);*/
+ wmt_rst_output(1);
+ msleep(1);
+ wmt_rst_output(0);
+ msleep(10);
+ wmt_rst_output(1);
+ msleep(5);
+ dbg("has done\n");
+#else
+ u8 ts_reset_cmd[1] = {0xb0};
+ zet6221_i2c_write_tsdata(this_client, ts_reset_cmd, 1);
+#endif
+
+}
+
+
+///**********************************************************************
+/// [function]: zet622x_ts_parse_mutual_dev
+/// [parameters]: client
+/// [return]: u8
+///**********************************************************************
+#ifdef FEATURE_MDEV_OUT_ENABLE
+u8 zet622x_ts_parse_mutual_dev(struct i2c_client *client)
+{
+ int mdev_packet_size = (row+2) * (col + 2);
+ int ret = 0;
+ int idx = 0;
+ int len = mdev_packet_size;
+ char mdev_file_name_out[128];
+
+ int step_size = col + 2;
+
+ while(len > 0)
+ {
+ if(len < step_size)
+ {
+ step_size = len;
+ }
+
+ ret = zet6221_i2c_read_tsdata(client, &tran_data[idx], step_size);
+ len -= step_size;
+ idx += step_size;
+ }
+
+ sprintf(mdev_file_name_out, "%s%s%02d.bin", tran_type_mode_file_name, MDEV_FILE_NAME, mdev_file_id);
+ zet_mdev_save(mdev_file_name_out);
+ mdev_file_id = (mdev_file_id +1)% (MDEV_MAX_FILE_ID);
+ return ret;
+}
+#endif ///< FEATURE_MDEV_OUT_ENABLE
+
+///**********************************************************************
+/// [function]: zet622x_ts_parse_initial_base
+/// [parameters]: client
+/// [return]: u8
+///**********************************************************************
+#ifdef FEATURE_IBASE_OUT_ENABLE
+u8 zet622x_ts_parse_initial_base(struct i2c_client *client)
+{
+ int ibase_packet_size = (row + col) * 2;
+ int ret = 0;
+ int idx = 0;
+ int len = ibase_packet_size;
+ char ibase_file_name_out[128];
+
+ int step_size = ibase_packet_size;
+
+ while(len > 0)
+ {
+ ret = zet6221_i2c_read_tsdata(client, &tran_data[idx], step_size);
+ len -= step_size;
+ }
+ sprintf(ibase_file_name_out, "%s%s%02d.bin", tran_type_mode_file_name, IBASE_FILE_NAME, ibase_file_id);
+ zet_ibase_save(ibase_file_name_out);
+ ibase_file_id = (ibase_file_id +1)% (IBASE_MAX_FILE_ID);
+ return ret;
+}
+#endif ///< FEATURE_IBASE_OUT_ENABLE
+
+///**********************************************************************
+/// [function]: zet622x_ts_parse_initial_dev
+/// [parameters]: client
+/// [return]: u8
+///**********************************************************************
+#ifdef FEATURE_IDEV_OUT_ENABLE
+u8 zet622x_ts_parse_initial_dev(struct i2c_client *client)
+{
+ int idev_packet_size = (row + col);
+ int ret = 0;
+ int idx = 0;
+ int len = idev_packet_size;
+ char idev_file_name_out[128];
+
+ int step_size = idev_packet_size;
+
+ while(len > 0)
+ {
+ ret = zet6221_i2c_read_tsdata(client, &tran_data[idx], step_size);
+ len -= step_size;
+ }
+ sprintf(idev_file_name_out, "%s%s%02d.bin", tran_type_mode_file_name, IDEV_FILE_NAME, idev_file_id);
+ zet_idev_save(idev_file_name_out);
+ idev_file_id = (idev_file_id +1)% (IDEV_MAX_FILE_ID);
+ return ret;
+}
+#endif ///< FEATURE_IDEV_OUT_ENABLE
+
+///**********************************************************************
+/// [function]: zet622x_ts_parse_mutual_base
+/// [parameters]: client
+/// [return]: u8
+///**********************************************************************
+#ifdef FEATURE_MBASE_OUT_ENABLE
+u8 zet622x_ts_parse_mutual_base(struct i2c_client *client)
+{
+ int mbase_packet_size = (row * col * 2);
+ int ret = 0;
+ int idx = 0;
+ int len = mbase_packet_size;
+ char mbase_file_name_out[128];
+
+ int step_size = col*2;
+
+ while(len > 0)
+ {
+ if(len < step_size)
+ {
+ step_size = len;
+ }
+
+ ret = zet6221_i2c_read_tsdata(client, &tran_data[idx], step_size);
+ len -= step_size;
+ idx += step_size;
+ }
+ sprintf(mbase_file_name_out, "%s%s%02d.bin",tran_type_mode_file_name, MBASE_FILE_NAME, mbase_file_id);
+ zet_mbase_save(mbase_file_name_out);
+ mbase_file_id = (mbase_file_id +1)% (MBASE_MAX_FILE_ID);
+ return ret;
+}
+#endif ///< FEATURE_MBASE_OUT_ENABLE
+
+/***********************************************************************
+ [function]:
+ callback: read finger information from TP;
+ [parameters]:
+ client[in]: struct i2c_client �represent an I2C slave device;
+ x[out]: values of X axis;
+ y[out]: values of Y axis;
+ z[out]: values of Z axis;
+ pr[out]: pressed of released status of fingers;
+ ky[out]: pressed of released status of keys;
+ [return]:
+ Packet ID;
+************************************************************************/
+u8 zet6221_ts_get_xy_from_panel(struct i2c_client *client, u32 *x, u32 *y, u32 *z, u32 *pr, u32 *ky)
+{
+ u8 ts_data[70];
+ int ret;
+ int i;
+
+ memset(ts_data,0,70);
+
+ ret=zet6221_i2c_read_tsdata(client, ts_data, bufLength);
+
+ *pr = ts_data[1];
+ *pr = (*pr << 8) | ts_data[2];
+
+ for(i=0;i<FingerNum;i++)
+ {
+ x[i]=(u8)((ts_data[3+4*i])>>4)*256 + (u8)ts_data[(3+4*i)+1];
+ y[i]=(u8)((ts_data[3+4*i]) & 0x0f)*256 + (u8)ts_data[(3+4*i)+2];
+ z[i]=(u8)((ts_data[(3+4*i)+3]) & 0x0f);
+ }
+
+ //if key enable
+ if(KeyNum > 0)
+ *ky = ts_data[3+4*FingerNum];
+
+ return ts_data[0];
+}
+
+/***********************************************************************
+ [function]:
+ callback: get dynamic report information;
+ [parameters]:
+ client[in]: struct i2c_client �represent an I2C slave device;
+
+ [return]:
+ 1;
+************************************************************************/
+u8 zet6221_ts_get_report_mode(struct i2c_client *client)
+{
+ u8 ts_report_cmd[1] = {0xb2};
+ //u8 ts_reset_cmd[1] = {0xb0};
+ u8 ts_in_data[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+ int ret;
+ int i;
+ int count=0;
+
+ ret=zet6221_i2c_write_tsdata(client, ts_report_cmd, 1);
+
+ if (ret > 0)
+ {
+ while(1)
+ {
+ msleep(1);
+
+ //if (gpio_get_value(TS_INT_GPIO) == 0)
+ if (wmt_ts_irqinval() == 0)
+ {
+ dbg( "int low\n");
+ ret=zet6221_i2c_read_tsdata(client, ts_in_data, 17);
+
+ if(ret > 0)
+ {
+
+ for(i=0;i<8;i++)
+ {
+ pc[i]=ts_in_data[i] & 0xff;
+ }
+
+ if(pc[3] != 0x08)
+ {
+ errlog("=============== zet6221_ts_get_report_mode report error ===============\n");
+ return 0;
+ }
+
+ xyExchange = (ts_in_data[16] & 0x8) >> 3;
+ if(xyExchange == 1)
+ {
+ ResolutionY= ts_in_data[9] & 0xff;
+ ResolutionY= (ResolutionY << 8)|(ts_in_data[8] & 0xff);
+ ResolutionX= ts_in_data[11] & 0xff;
+ ResolutionX= (ResolutionX << 8) | (ts_in_data[10] & 0xff);
+ }
+ else
+ {
+ ResolutionX = ts_in_data[9] & 0xff;
+ ResolutionX = (ResolutionX << 8)|(ts_in_data[8] & 0xff);
+ ResolutionY = ts_in_data[11] & 0xff;
+ ResolutionY = (ResolutionY << 8) | (ts_in_data[10] & 0xff);
+ }
+
+ FingerNum = (ts_in_data[15] & 0x7f);
+ KeyNum = (ts_in_data[15] & 0x80);
+
+ if(KeyNum==0)
+ bufLength = 3+4*FingerNum;
+ else
+ bufLength = 3+4*FingerNum+1;
+
+ //DPRINTK( "bufLength=%d\n",bufLength);
+
+ break;
+
+ }else
+ {
+ errlog ("=============== zet6221_ts_get_report_mode read error ===============\n");
+ return 0;
+ }
+
+ }else
+ {
+ //DPRINTK( "int high\n");
+ if(count++ > 30)
+ {
+ errlog ("=============== zet6221_ts_get_report_mode time out ===============\n");
+ return 0;
+ }
+
+ }
+ }
+
+ }
+ return 1;
+}
+
+#if 0
+static int zet6221_is_ts(struct i2c_client *client)
+{
+ /*u8 ts_in_data[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+ ctp_reset();
+ if (zet6221_i2c_read_tsdata(client, ts_in_data, 17) <= 0)
+ {
+ return 0;
+ }
+ return 1;*/
+ return 1;
+}
+#endif
+
+/***********************************************************************
+ [function]:
+ callback: get dynamic report information with timer delay;
+ [parameters]:
+ client[in]: struct i2c_client represent an I2C slave device;
+
+ [return]:
+ 1;
+************************************************************************/
+
+u8 zet6221_ts_get_report_mode_t(struct i2c_client *client)
+{
+ u8 ts_report_cmd[1] = {0xb2};
+ u8 ts_in_data[17] = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+
+ int ret;
+ int i;
+
+ ret=zet6221_i2c_write_tsdata(client, ts_report_cmd, 1);
+ msleep(10);
+
+ dbg("ret=%d,i2c_addr=0x%x\n", ret, client->addr);
+ if (ret > 0)
+ {
+ //mdelay(10);
+ //msleep(10);
+ dbg("=============== zet6221_ts_get_report_mode_t ===============\n");
+ ret=zet6221_i2c_read_tsdata(client, ts_in_data, 17);
+
+ if(ret > 0)
+ {
+
+ for(i=0;i<8;i++)
+ {
+ pc[i]=ts_in_data[i] & 0xff;
+ }
+
+ if(pc[3] != 0x08)
+ {
+ errlog("=============== zet6221_ts_get_report_mode_t report error ===============\n");
+ return 0;
+ }
+
+ xyExchange = (ts_in_data[16] & 0x8) >> 3;
+ if(xyExchange == 1)
+ {
+ ResolutionY= ts_in_data[9] & 0xff;
+ ResolutionY= (ResolutionY << 8)|(ts_in_data[8] & 0xff);
+ ResolutionX= ts_in_data[11] & 0xff;
+ ResolutionX= (ResolutionX << 8) | (ts_in_data[10] & 0xff);
+ }
+ else
+ {
+ ResolutionX = ts_in_data[9] & 0xff;
+ ResolutionX = (ResolutionX << 8)|(ts_in_data[8] & 0xff);
+ ResolutionY = ts_in_data[11] & 0xff;
+ ResolutionY = (ResolutionY << 8) | (ts_in_data[10] & 0xff);
+ }
+
+ FingerNum = (ts_in_data[15] & 0x7f);
+ KeyNum = (ts_in_data[15] & 0x80);
+ inChargerMode = (ts_in_data[16] & 0x2) >> 1;
+
+ if(KeyNum==0)
+ bufLength = 3+4*FingerNum;
+ else
+ bufLength = 3+4*FingerNum+1;
+
+ }else
+ {
+ errlog ("=============== zet6221_ts_get_report_mode_t READ ERROR ===============\n");
+ return 0;
+ }
+
+ }else
+ {
+ errlog("=============== zet6221_ts_get_report_mode_t WRITE ERROR ===============\n");
+ return 0;
+ }
+ return 1;
+}
+
+/***********************************************************************
+ [function]:
+ callback: interrupt function;
+ [parameters]:
+ irq[in]: irq value;
+ dev_id[in]: dev_id;
+
+ [return]:
+ NULL;
+************************************************************************/
+static irqreturn_t zet6221_ts_interrupt(int irq, void *dev_id)
+{
+ struct zet6221_tsdrv *ts_drv = dev_id;
+ int j = 0;
+ if (wmt_is_tsint())
+ {
+ wmt_clr_int();
+ if (wmt_is_tsirq_enable() && l_suspend == 0)
+ {
+ wmt_disable_gpirq();
+ dbg("begin..\n");
+ //if (!work_pending(&l_tsdata.pen_event_work))
+ if (wmt_ts_irqinval() == 0)
+ {
+ queue_work(ts_wq, &ts_drv->work1);
+ } else {
+ if(KeyNum > 0)
+ {
+ //if (0 == ky)
+ {
+ for (j=0;j<4;j++)
+ {
+ if (l_tskey[j][1] != 0)
+ {
+ l_tskey[j][1] = 0;
+ }
+ }
+ dbg("finish one key report!\n");
+ }
+ }
+ wmt_enable_gpirq();
+ }
+ }
+ return IRQ_HANDLED;
+ }
+
+ return IRQ_NONE;
+
+ /*//polling_time = D_POLLING_TIME;
+
+ if (gpio_get_value(TS_INT_GPIO) == 0)
+ {
+ // IRQ is triggered by FALLING code here
+ struct zet6221_tsdrv *ts_drv = dev_id;
+ schedule_work(&ts_drv->work1);
+ //DPRINTK("TS1_INT_GPIO falling\n");
+ }else
+ {
+ //DPRINTK("TS1_INT_GPIO raising\n");
+ }
+
+ return IRQ_HANDLED;*/
+}
+
+/***********************************************************************
+ [function]:
+ callback: touch information handler;
+ [parameters]:
+ _work[in]: struct work_struct;
+
+ [return]:
+ NULL;
+************************************************************************/
+static void zet6221_ts_work(struct work_struct *_work)
+{
+ u32 x[MAX_FINGER_NUMBER], y[MAX_FINGER_NUMBER], z[MAX_FINGER_NUMBER], pr, ky, points;
+ u32 px,py,pz;
+ u8 ret;
+ u8 pressure;
+ int i,j;
+ int tx,ty;
+ int xmax,ymax;
+ int realnum = 0;
+ struct zet6221_tsdrv *ts =
+ container_of(_work, struct zet6221_tsdrv, work1);
+
+ struct i2c_client *tsclient1 = ts->i2c_ts;
+
+ if(l_suspend == 1)
+ {
+ return;
+ }
+
+ if (bufLength == 0)
+ {
+ wmt_enable_gpirq();
+ return;
+ }
+ /*if(resetCount == 1)
+ {
+ resetCount = 0;
+ wmt_enable_gpirq();
+ return;
+ }*/
+
+ //if (gpio_get_value(TS_INT_GPIO) != 0)
+ if (wmt_ts_irqinval() != 0)
+ {
+ /* do not read when IRQ is triggered by RASING*/
+ //DPRINTK("INT HIGH\n");
+ dbg("INT HIGH....\n");
+ wmt_enable_gpirq();
+ return;
+ }
+
+ ///-------------------------------------------///
+ /// Transfer Type : Mutual Dev Mode
+ ///-------------------------------------------///
+#ifdef FEATURE_MDEV_OUT_ENABLE
+ if(transfer_type == TRAN_TYPE_MUTUAL_SCAN_DEV)
+ {
+ zet622x_ts_parse_mutual_dev(tsclient1);
+ wmt_enable_gpirq();
+ return;
+ }
+#endif ///< FEATURE_MDEV_OUT_ENABLE
+
+ ///-------------------------------------------///
+ /// Transfer Type : Initial Base Mode
+ ///-------------------------------------------///
+#ifdef FEATURE_IBASE_OUT_ENABLE
+ if(transfer_type == TRAN_TYPE_INIT_SCAN_BASE)
+ {
+ zet622x_ts_parse_initial_base(tsclient1);
+ wmt_enable_gpirq();
+ return;
+ }
+#endif ///< FEATURE_IBASE_OUT_ENABLE
+
+ ///-------------------------------------------///
+ /// Transfer Type : Initial Dev Mode
+ ///-------------------------------------------///
+#ifdef FEATURE_IDEV_OUT_ENABLE
+ if(transfer_type == TRAN_TYPE_INIT_SCAN_DEV)
+ {
+ zet622x_ts_parse_initial_dev(tsclient1);
+ wmt_enable_gpirq();
+ return;
+ }
+#endif ///< TRAN_TYPE_INIT_SCAN_DEV
+
+ ///-------------------------------------------///
+ /// Transfer Type : Mutual Base Mode
+ ///-------------------------------------------///
+#ifdef FEATURE_MBASE_OUT_ENABLE
+ if(transfer_type == TRAN_TYPE_MUTUAL_SCAN_BASE)
+ {
+ zet622x_ts_parse_mutual_base(tsclient1);
+ wmt_enable_gpirq();
+ return;
+ }
+#endif ///< FEATURE_MBASE_OUT_ENABLE
+
+ mutex_lock(&i2c_mutex);
+ ret = zet6221_ts_get_xy_from_panel(tsclient1, x, y, z, &pr, &ky);
+ mutex_unlock(&i2c_mutex);
+
+ if(ret == 0x3C)
+ {
+
+ dbg( "x1= %d, y1= %d x2= %d, y2= %d [PR] = %d [KY] = %d\n", x[0], y[0], x[1], y[1], pr, ky);
+
+ points = pr;
+
+ #if defined(TRANSLATE_ENABLE)
+ touch_coordinate_traslating(x, y, points);
+ #endif
+ realnum = 0;
+
+ for(i=0;i<FingerNum;i++){
+ pressure = (points >> (MAX_FINGER_NUMBER-i-1)) & 0x1;
+ dbg( "valid=%d pressure[%d]= %d x= %d y= %d\n",points , i, pressure,x[i],y[i]);
+
+ if(pressure)
+ {
+ px = x[i];
+ py = y[i];
+ pz = z[i];
+
+ dbg("raw%d(%d,%d) xaxis:%d ResolutionX:%d ResolutionY:%d\n", i, px, py,wmt_ts_get_xaxis(),ResolutionX,ResolutionY);
+
+ //input_report_abs(ts->input, ABS_MT_TRACKING_ID, i);
+ //input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, P_MAX);
+ //input_report_abs(ts->input, ABS_MT_POSITION_X, x[i]);
+ //input_report_abs(ts->input, ABS_MT_POSITION_Y, y[i]);
+ if (wmt_ts_get_xaxis() == 0)
+ {
+ tx = px;
+ ty = py;
+ xmax = ResolutionX;
+ ymax = ResolutionY;
+ } else {
+ tx = py;
+ ty = px;
+ xmax = ResolutionY;
+ ymax = ResolutionX;
+ }
+ if (wmt_ts_get_xdir() == -1)
+ {
+ tx = xmax - tx;
+ }
+ if (wmt_ts_get_ydir() == -1)
+ {
+ ty = ymax - ty;
+ }
+ //tx = ResolutionY - py;
+ //ty = px;
+ dbg("rpt%d(%d,%d)\n", i, tx, ty);
+ //add for cross finger 2013-1-10
+ #ifdef MT_TYPE_B
+ input_mt_slot(ts->input, i);
+ input_mt_report_slot_state(ts->input, MT_TOOL_FINGER,true);
+ #endif
+ input_report_abs(ts->input, ABS_MT_TRACKING_ID, i);
+ //input_report_key(ts->input, BTN_TOUCH, 1);
+ //input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, pz);
+ //*******************************
+
+ if (wmt_ts_get_lcdexchg()) {
+ int tmp;
+ tmp = tx;
+ tx = ty;
+ ty = ResolutionY - tmp;
+ }
+
+ input_report_abs(ts->input, ABS_MT_POSITION_X, tx /*px*/);
+ input_report_abs(ts->input, ABS_MT_POSITION_Y, ty /*py*/);
+
+ #ifndef MT_TYPE_B
+ input_mt_sync(ts->input);
+ #endif
+ realnum++;
+ if (wmt_ts_ispenup())
+ {
+ wmt_ts_set_penup(0);
+ }
+
+ }else
+ {
+ //input_report_abs(ts->input, ABS_MT_TRACKING_ID, i);
+ //input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, 0);
+ //input_mt_sync(ts->input);
+ #ifdef MT_TYPE_B
+ input_mt_slot(ts->input, i);
+ input_mt_report_slot_state(ts->input, MT_TOOL_FINGER,false);
+ input_report_abs(ts->input, ABS_MT_TRACKING_ID, -1);
+ #endif //add cross finger 2013-1-10
+ dbg("p%d not pen down\n",i);
+ }
+ }
+
+ #ifdef MT_TYPE_B
+ input_mt_report_pointer_emulation(ts->input, true);
+ #endif //add finger cross 2013-1-10
+ //printk("<<<realnum %d\n", realnum);
+ if (realnum != 0)
+ {
+ input_sync(ts->input);
+ dbg("report one point group\n");
+ } else if (!wmt_ts_ispenup())
+ {//********here no finger press 2013-1-10
+ //add 2013-1-10 cross finger issue!
+ #ifdef MT_TYPE_B
+ for(i=0;i<FingerNum;i++){
+ input_mt_slot(ts->input, i);
+ input_mt_report_slot_state(ts->input, MT_TOOL_FINGER,false);
+ input_report_abs(ts->input, ABS_MT_TRACKING_ID, -1);
+ }
+ input_mt_report_pointer_emulation(ts->input, true);
+ #else
+ //input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, 0);
+ //input_mt_sync(ts->input);
+ //input_report_abs(ts->input, ABS_MT_TRACKING_ID, -1);
+ //input_report_key(ts->input, BTN_TOUCH, 0);
+ #endif
+ //**********************************
+ input_mt_sync(ts->input);
+ input_sync(ts->input);
+ dbg("real pen up!\n");
+ wmt_ts_set_penup(1);
+ }
+
+ if(KeyNum > 0)
+ {
+ //for(i=0;i<MAX_KEY_NUMBER;i++)
+ if (0 == ky)
+ {
+ for (j=0;j<4;j++)
+ {
+ if (l_tskey[j][1] != 0)
+ {
+ l_tskey[j][1] = 0;
+ }
+ }
+ dbg("finish one key report!\n");
+ } else {
+ for(i=0;i<4;i++)
+ {
+ pressure = ky & ( 0x01 << i );
+ if (pressure)
+ {
+ dbg("key%d\n", i);
+ if (0 == l_tskey[i][1])
+ {
+ l_tskey[i][1] = 1; // key down
+ input_report_key(ts->input, l_tskey[i][0], 1);
+ input_report_key(ts->input, l_tskey[i][0], 0);
+ input_sync(ts->input);
+ dbg("report key_%d\n", l_tskey[i][0]);
+ break;
+ }
+ }
+
+ }
+ }
+ }
+
+ dbg("normal end...\n");
+ }else {
+ dbg("do nothing!\n");
+ if(KeyNum > 0)
+ {
+ //if (0 == ky)
+ {
+ for (j=0;j<4;j++)
+ {
+ if (l_tskey[j][1] != 0)
+ {
+ l_tskey[j][1] = 0;
+ }
+ }
+ dbg("finish one key report!\n");
+ }
+ }
+ }
+ wmt_enable_gpirq();
+
+}
+
+/***********************************************************************
+ [function]:
+ callback: charger mode enable;
+ [parameters]:
+ void
+
+ [return]:
+ void
+************************************************************************/
+void zet6221_ts_charger_mode()
+{
+ //struct zet6221_tsdrv *zet6221_ts;
+ u8 ts_write_charge_cmd[1] = {0xb5};
+ int ret=0;
+ ret=zet6221_i2c_write_tsdata(this_client, ts_write_charge_cmd, 1);
+}
+EXPORT_SYMBOL_GPL(zet6221_ts_charger_mode);
+
+/***********************************************************************
+ [function]:
+ callback: charger mode disable;
+ [parameters]:
+ void
+
+ [return]:
+ void
+************************************************************************/
+void zet6221_ts_charger_mode_disable(void)
+{
+ //struct zet6221_tsdrv *zet6221_ts;
+ u8 ts_write_cmd[1] = {0xb6};
+ int ret=0;
+ ret=zet6221_i2c_write_tsdata(this_client, ts_write_cmd, 1);
+}
+EXPORT_SYMBOL_GPL(zet6221_ts_charger_mode_disable);
+
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+static void ts_early_suspend(struct early_suspend *handler)
+{
+ //Sleep Mode
+/* u8 ts_sleep_cmd[1] = {0xb1};
+ int ret=0;
+ ret=zet6221_i2c_write_tsdata(this_client, ts_sleep_cmd, 1);
+ return;
+ */
+ wmt_disable_gpirq();
+ l_suspend = 1;
+ //del_timer(&l_ts->polling_timer);
+
+}
+
+static void ts_late_resume(struct early_suspend *handler)
+{
+ resetCount = 1;
+ //if (l_suspend != 0)
+ {
+ //wmt_disable_gpirq();
+ //ctp_reset();
+ //wmt_set_gpirq(IRQ_TYPE_EDGE_FALLING);
+ wmt_enable_gpirq();
+ l_suspend = 0;
+ }
+ //l_powermode = -1;
+ //mod_timer(&l_ts->polling_timer,jiffies + msecs_to_jiffies(TIME_CHECK_CHARGE));
+
+}
+#endif
+static int zet_ts_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ wmt_disable_gpirq();
+ l_suspend = 1;
+ return 0;
+}
+
+
+/***********************************************************************
+ [function]:
+ resume_download_thread
+ [parameters]:
+ arg
+
+ [return]:
+ int;
+************************************************************************/
+int resume_download_thread(void *arg)
+{
+ char fw_name[64];
+ wake_lock(&downloadWakeLock);
+ sprintf(fw_name, "%szet62xx.bin", tran_type_mode_file_name);
+ zet_fw_load(fw_name);
+ //printk("Thread : Enter\n");
+// if((iRomType == ROM_TYPE_SRAM) ||
+// (iRomType == ROM_TYPE_OTP)) //SRAM,OTP
+ // {
+ zet622x_resume_downloader(this_client);
+ check_charger();
+ l_suspend = 0;
+ //printk("zet622x download OK\n");
+ // }
+ //printk("Thread : Leave\n");
+ wake_unlock(&downloadWakeLock);
+ return 0;
+}
+
+static int zet_ts_resume(struct platform_device *pdev)
+{
+ wmt_disable_gpirq();
+ ctp_reset();
+
+ if(ic_model == ZET6251) {
+ //upload bin to flash_buffer, just for debug
+ resume_download_task = kthread_create(resume_download_thread, NULL , "resume_download");
+ if(IS_ERR(resume_download_task)) {
+ errlog("cread thread failed\n");
+ }
+ wake_up_process(resume_download_task);
+ } else {
+ check_charger();
+ l_suspend = 0;
+ }
+
+ wmt_set_gpirq(IRQ_TYPE_EDGE_FALLING);
+ if (!earlysus_en)
+ wmt_enable_gpirq();
+
+ ///--------------------------------------///
+ /// Set transfer type to dynamic mode
+ ///--------------------------------------///
+ transfer_type = TRAN_TYPE_DYNAMIC;
+
+ return 0;
+}
+
+
+///**********************************************************************
+/// [function]: zet622x_ts_set_transfer_type
+/// [parameters]: void
+/// [return]: void
+///**********************************************************************
+int zet622x_ts_set_transfer_type(u8 bTransType)
+{
+ u8 ts_cmd[10] = {0xC1, 0x02, TRAN_TYPE_DYNAMIC, 0x55, 0xAA, 0x00, 0x00, 0x00, 0x00, 0x00};
+ int ret = 0;
+ ts_cmd[2] = bTransType;
+ ret = zet6221_i2c_write_tsdata(this_client, ts_cmd, 10);
+ return ret;
+}
+
+
+///**********************************************************************
+/// [function]: zet622x_ts_set_transfer_type
+/// [parameters]: void
+/// [return]: void
+///**********************************************************************
+#ifdef FEATURE_INFO_OUT_EANBLE
+int zet622x_ts_set_info_type(void)
+{
+ int ret = 1;
+ char info_file_name_out[128];
+
+ /// ic type
+ switch(ic_model)
+ {
+ case ZET6221:
+ tran_data[0] = ZET6221_INFO;
+ break;
+ case ZET6223:
+ tran_data[0] = ZET6223_INFO;
+ break;
+ case ZET6231:
+ tran_data[0] = ZET6231_INFO;
+ break;
+ case ZET6251:
+ tran_data[0] = ZET6251_INFO;
+ break;
+ default:
+ tran_data[0] = UNKNOW_INFO;
+ break;
+ }
+
+ /// resolution
+ if(xyExchange== 1)
+ {
+ tran_data[16] = 0x8;
+ tran_data[9] = ((ResolutionY >> 8)&0xFF);
+ tran_data[8] = (ResolutionY &0xFF);
+ tran_data[11] = ((ResolutionX >> 8)&0xFF);
+ tran_data[10] = (ResolutionX &0xFF);
+ }
+ else
+ {
+ tran_data[16] = 0x00;
+ tran_data[9] = ((ResolutionX >> 8)&0xFF);
+ tran_data[8] = (ResolutionX &0xFF);
+ tran_data[11] = ((ResolutionY >> 8)&0xFF);
+ tran_data[10] = (ResolutionY &0xFF);
+ }
+
+ /// trace X
+ tran_data[13] = TP_DEFAULT_COL; ///< trace x
+ /// trace Y
+ tran_data[14] = TP_DEFAULT_ROW; ///< trace y
+
+ if(KeyNum > 0)
+ {
+ tran_data[15] = (0x80 | FingerNum);
+ }
+ else
+ {
+ tran_data[15] = FingerNum;
+ }
+
+ sprintf(info_file_name_out, "%sinfo.bin",tran_type_mode_file_name);
+ zet_information_save(info_file_name_out);
+
+ printk("[ZET] : ic:%d, traceX:%d, traceY:%d\n", tran_data[0],tran_data[13],tran_data[14]);
+ return ret;
+}
+#endif ///< FEATURE_INFO_OUT_EANBLE
+
+///***********************************************************************
+/// [function]: zet_mdev_save
+/// [parameters]: char *
+/// [return]: void
+///************************************************************************
+static void zet_mdev_save(char *file_name)
+{
+ struct file *fp;
+ int data_total_len = (row+2) * (col + 2);
+
+ ///-------------------------------------------------------///
+ /// create the file that stores the mutual dev data
+ ///-------------------------------------------------------///
+ fp = filp_open(file_name, O_RDWR | O_CREAT, 0644);
+ if(IS_ERR(fp))
+ {
+ printk("[ZET] : Failed to open %s\n", file_name);
+ return;
+ }
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ vfs_write(fp, tran_data, data_total_len, &(fp->f_pos));
+ memcpy(mdev_data, tran_data, data_total_len);
+ set_fs(old_fs);
+ filp_close(fp, 0);
+
+ return;
+}
+
+///***********************************************************************
+/// [function]: zet_idev_save
+/// [parameters]: char *
+/// [return]: void
+///************************************************************************
+#ifdef FEATURE_IDEV_OUT_ENABLE
+static void zet_idev_save(char *file_name)
+{
+ struct file *fp;
+ int data_total_len = (row + col);
+
+ ///-------------------------------------------------------///
+ /// create the file that stores the initial dev data
+ ///-------------------------------------------------------///
+ fp = filp_open(file_name, O_RDWR | O_CREAT, 0644);
+ if(IS_ERR(fp))
+ {
+ printk("[ZET] : Failed to open %s\n", file_name);
+ return;
+ }
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ vfs_write(fp, tran_data, data_total_len, &(fp->f_pos));
+ memcpy(idev_data, tran_data, data_total_len);
+ set_fs(old_fs);
+ filp_close(fp, 0);
+
+ return;
+}
+#endif ///< FEATURE_IDEV_OUT_ENABLE
+
+///***********************************************************************
+/// [function]: zet_ibase_save
+/// [parameters]: char *
+/// [return]: void
+///************************************************************************
+#ifdef FEATURE_IBASE_OUT_ENABLE
+static void zet_ibase_save(char *file_name)
+{
+ struct file *fp;
+ int data_total_len = (row + col) * 2;
+
+ ///-------------------------------------------------------///
+ /// create the file that stores the initial base data
+ ///-------------------------------------------------------///
+ fp = filp_open(file_name, O_RDWR | O_CREAT, 0644);
+ if(IS_ERR(fp))
+ {
+ printk("[ZET] : Failed to open %s\n", file_name);
+ return;
+ }
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ vfs_write(fp, tran_data, data_total_len, &(fp->f_pos));
+ memcpy(ibase_data, tran_data, data_total_len);
+ set_fs(old_fs);
+ filp_close(fp, 0);
+
+ return;
+}
+#endif ///< FEATURE_IBASE_OUT_ENABLE
+
+///***********************************************************************
+/// [function]: zet_mbase_save
+/// [parameters]: char *
+/// [return]: void
+///************************************************************************
+#ifdef FEATURE_MBASE_OUT_ENABLE
+static void zet_mbase_save(char *file_name)
+{
+ struct file *fp;
+ int data_total_len = (row * col * 2);
+
+ ///-------------------------------------------------------///
+ /// create the file that stores the mutual base data
+ ///-------------------------------------------------------///
+ fp = filp_open(file_name, O_RDWR | O_CREAT, 0644);
+ if(IS_ERR(fp))
+ {
+ printk("[ZET] : Failed to open %s\n", file_name);
+ return;
+ }
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ vfs_write(fp, tran_data, data_total_len, &(fp->f_pos));
+ memcpy(mbase_data, tran_data, data_total_len);
+ set_fs(old_fs);
+ filp_close(fp, 0);
+
+ return;
+}
+#endif ///< FEATURE_MBASE_OUT_ENABLE
+
+///***********************************************************************
+/// [function]: zet_information_save
+/// [parameters]: char *
+/// [return]: void
+///************************************************************************
+#ifdef FEATURE_INFO_OUT_EANBLE
+static void zet_information_save(char *file_name)
+{
+ struct file *fp;
+ int data_total_len = INFO_DATA_SIZE;
+
+ ///-------------------------------------------------------///
+ /// create the file that stores the mutual base data
+ ///-------------------------------------------------------///
+ fp = filp_open(file_name, O_RDWR | O_CREAT, 0644);
+ if(IS_ERR(fp))
+ {
+ printk("[ZET] : Failed to open %s\n", file_name);
+ return;
+ }
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ vfs_write(fp, tran_data, data_total_len, &(fp->f_pos));
+ memcpy(info_data, tran_data, data_total_len);
+ set_fs(old_fs);
+ filp_close(fp, 0);
+
+ return;
+}
+#endif ///< FEATURE_INFO_OUT_EANBLE
+
+///************************************************************************
+/// [function]: zet_dv_set_file_name
+/// [parameters]: void
+/// [return]: void
+///************************************************************************
+static void zet_dv_set_file_name(char *file_name)
+{
+ strcpy(driver_version, file_name);
+}
+
+///************************************************************************
+/// [function]: zet_fw_set_file_name
+/// [parameters]: void
+/// [return]: void
+///************************************************************************
+static void zet_fw_set_file_name(void)//char *file_name)
+{
+ char fwname[256] = {0};
+ wmt_ts_get_firmwname(fwname);
+ sprintf(fw_file_name,"/system/etc/firmware/%s",fwname);
+ //strcpy(fw_file_name, file_name);
+}
+
+///************************************************************************
+/// [function]: zet_mdev_set_file_name
+/// [parameters]: void
+/// [return]: void
+///************************************************************************
+static void zet_tran_type_set_file_name(char *file_name)
+{
+ strcpy(tran_type_mode_file_name, file_name);
+}
+
+
+///***********************************************************************
+/// [function]: zet_fw_size
+/// [parameters]: void
+/// [return]: void
+///************************************************************************
+static int zet_fw_size(void)
+{
+ int flash_total_len = 0x8000;
+
+ switch(ic_model)
+ {
+ case ZET6221:
+ flash_total_len = 0x4000;
+ break;
+ case ZET6223:
+ flash_total_len = 0x10000;
+ break;
+ case ZET6231:
+ case ZET6251:
+ default:
+ flash_total_len = 0x8000;
+ break;
+ }
+
+ return flash_total_len;
+}
+
+
+///***********************************************************************
+/// [function]: zet_fw_save
+/// [parameters]: file name
+/// [return]: void
+///************************************************************************
+static void zet_fw_save(char *file_name)
+{
+ struct file *fp;
+ int flash_total_len = 0;
+
+ fp = filp_open(file_name, O_RDWR | O_CREAT, 0644);
+ if(IS_ERR(fp))
+ {
+ printk("[ZET] : Failed to open %s\n", file_name);
+ return;
+ }
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ flash_total_len = zet_fw_size();
+ printk("[ZET] : flash_total_len = 0x%04x\n",flash_total_len );
+
+ vfs_write(fp, flash_buffer, flash_total_len, &(fp->f_pos));
+
+ set_fs(old_fs);
+
+ filp_close(fp, 0);
+
+
+ return;
+}
+
+///***********************************************************************
+/// [function]: zet_fw_load
+/// [parameters]: file name
+/// [return]: void
+///************************************************************************
+static void zet_fw_load(char *file_name)
+{
+ int file_length = 0;
+ struct file *fp;
+ loff_t *pos;
+
+ //printk("[ZET]: find %s\n", file_name);
+ fp = filp_open(file_name, O_RDONLY, 0644);
+ if(IS_ERR(fp))
+ {
+ //printk("[ZET]: No firmware file detected\n");
+ return;
+ }
+
+ ///----------------------------///
+ /// Load from file
+ ///----------------------------///
+ printk("[ZET]: Load from %s\n", file_name);
+
+ old_fs = get_fs();
+ set_fs(KERNEL_DS);
+
+ /// Get file size
+ inode = fp->f_dentry->d_inode;
+ file_length = (int)inode->i_size;
+ //l_fwlen = file_length;
+
+ pos = &(fp->f_pos);
+
+ vfs_read(fp, &flash_buffer[0], file_length, pos);
+
+ //file_length
+ set_fs(old_fs);
+ filp_close(fp, 0);
+
+
+}
+
+///************************************************************************
+/// [function]: zet_fw_init
+/// [parameters]: void
+/// [return]: void
+///************************************************************************
+static void zet_fw_init(void)
+{
+ //int i;
+
+ if(flash_buffer == NULL)
+ {
+ flash_buffer = kmalloc(MAX_FLASH_BUF_SIZE, GFP_KERNEL);
+ }
+
+ ///---------------------------------------------///
+ /// Init the mutual dev buffer
+ ///---------------------------------------------///
+ if(mdev_data== NULL)
+ {
+ mdev_data = kmalloc(MDEV_MAX_DATA_SIZE, GFP_KERNEL);
+ }
+ if(idev_data== NULL)
+ {
+ idev_data = kmalloc(IDEV_MAX_DATA_SIZE, GFP_KERNEL);
+ }
+
+ if(mbase_data== NULL)
+ {
+ mbase_data = kmalloc(MBASE_MAX_DATA_SIZE, GFP_KERNEL);
+ }
+ if(ibase_data== NULL)
+ {
+ ibase_data = kmalloc(IBASE_MAX_DATA_SIZE, GFP_KERNEL);
+ }
+
+ if(tran_data == NULL)
+ {
+ tran_data = kmalloc(MBASE_MAX_DATA_SIZE, GFP_KERNEL);
+ }
+
+ if(info_data == NULL)
+ {
+ info_data = kmalloc(INFO_MAX_DATA_SIZE, GFP_KERNEL);
+ }
+
+ /*printk("[ZET]: Load from header\n");
+
+ if(ic_model == ZET6221)
+ {
+ for(i = 0 ; i < sizeof(zeitec_zet6221_firmware) ; i++)
+ {
+ flash_buffer[i] = zeitec_zet6221_firmware[i];
+ }
+ }
+ else if(ic_model == ZET6223)
+ {
+ for(i = 0 ; i < sizeof(zeitec_zet6223_firmware) ; i++)
+ {
+ flash_buffer[i] = zeitec_zet6223_firmware[i];
+ }
+ }
+ else if(ic_model == ZET6231)
+ {
+ for(i = 0 ; i < sizeof(zeitec_zet6231_firmware) ; i++)
+ {
+ flash_buffer[i] = zeitec_zet6231_firmware[i];
+ }
+ }
+ else if(ic_model == ZET6251)
+ {
+ for(i = 0 ; i < sizeof(zeitec_zet6251_firmware) ; i++)
+ {
+ flash_buffer[i] = zeitec_zet6251_firmware[i];
+ }
+ }
+
+ /// Load firmware from bin file
+ zet_fw_load(fw_file_name);*/
+}
+
+///************************************************************************
+/// [function]: zet_fw_exit
+/// [parameters]: void
+/// [return]: void
+///************************************************************************
+static void zet_fw_exit(void)
+{
+ ///---------------------------------------------///
+ /// free mdev_data
+ ///---------------------------------------------///
+ if(mdev_data!=NULL)
+ {
+ kfree(mdev_data);
+ mdev_data = NULL;
+ }
+
+ if(idev_data!=NULL)
+ {
+ kfree(idev_data);
+ idev_data = NULL;
+ }
+
+ if(mbase_data!=NULL)
+ {
+ kfree(mbase_data);
+ mbase_data = NULL;
+ }
+
+ if(ibase_data!=NULL)
+ {
+ kfree(ibase_data);
+ ibase_data = NULL;
+ }
+
+ if(tran_data != NULL)
+ {
+ kfree(tran_data);
+ tran_data = NULL;
+ }
+
+ if(info_data != NULL)
+ {
+ kfree(info_data);
+ info_data = NULL;
+ }
+
+
+ ///---------------------------------------------///
+ /// free flash buffer
+ ///---------------------------------------------///
+ if(flash_buffer!=NULL)
+ {
+ kfree(flash_buffer);
+ flash_buffer = NULL;
+}
+
+}
+
+///************************************************************************
+/// [function]: zet_fops_open
+/// [parameters]: file
+/// [return]: int
+///************************************************************************
+static int zet_fops_open(struct inode *inode, struct file *file)
+{
+ int subminor;
+ int ret = 0;
+ struct i2c_client *client;
+ struct i2c_adapter *adapter;
+ struct i2c_dev *i2c_dev;
+
+ subminor = iminor(inode);
+ printk("[ZET] : ZET_FOPS_OPEN , subminor=%d\n",subminor);
+
+ i2c_dev = zet622x_i2c_dev_get_by_minor(subminor);
+ if (!i2c_dev)
+ {
+ printk("error i2c_dev\n");
+ return -ENODEV;
+ }
+
+ adapter = i2c_get_adapter(i2c_dev->adap->nr);
+ if(!adapter)
+ {
+ return -ENODEV;
+ }
+
+ client = kzalloc(sizeof(*client), GFP_KERNEL);
+
+ if(!client)
+ {
+ i2c_put_adapter(adapter);
+ ret = -ENOMEM;
+ }
+ snprintf(client->name, I2C_NAME_SIZE, "pctp_i2c_ts%d", adapter->nr);
+ //client->driver = &zet622x_i2c_driver;
+ client->driver = this_client->driver;
+ client->adapter = adapter;
+ file->private_data = client;
+
+ return 0;
+}
+
+
+///************************************************************************
+/// [function]: zet_fops_release
+/// [parameters]: inode, file
+/// [return]: int
+///************************************************************************
+static int zet_fops_release (struct inode *inode, struct file *file)
+{
+ struct i2c_client *client = file->private_data;
+
+ printk("[ZET] : zet_fops_release -> line : %d\n",__LINE__ );
+
+ i2c_put_adapter(client->adapter);
+ kfree(client);
+ file->private_data = NULL;
+ return 0;
+}
+
+///************************************************************************
+/// [function]: zet_fops_read
+/// [parameters]: file, buf, count, ppos
+/// [return]: size_t
+///************************************************************************
+static ssize_t zet_fops_read(struct file *file, char __user *buf, size_t count,
+ loff_t *ppos)
+{
+ int i;
+ int iCnt = 0;
+ char str[256];
+ int len = 0;
+
+ printk("[ZET] : zet_fops_read -> line : %d\n",__LINE__ );
+
+ ///-------------------------------///
+ /// Print message
+ ///-------------------------------///
+ sprintf(str, "Please check \"%s\"\n", fw_file_name);
+ len = strlen(str);
+
+ ///-------------------------------///
+ /// if read out
+ ///-------------------------------///
+ if(data_offset >= len)
+ {
+ return 0;
+ }
+
+ for(i = 0 ; i < count-1 ; i++)
+ {
+ buf[i] = str[data_offset];
+ buf[i+1] = 0;
+ iCnt++;
+ data_offset++;
+ if(data_offset >= len)
+ {
+ break;
+ }
+ }
+
+ ///-------------------------------///
+ /// Save file
+ ///-------------------------------///
+ if(data_offset == len)
+ {
+ zet_fw_save(fw_file_name);
+ }
+ return iCnt;
+}
+
+///************************************************************************
+/// [function]: zet_fops_write
+/// [parameters]: file, buf, count, ppos
+/// [return]: size_t
+///************************************************************************
+static ssize_t zet_fops_write(struct file *file, const char __user *buf,
+ size_t count, loff_t *ppos)
+{
+ printk("[ZET]: zet_fops_write -> %s\n", buf);
+ data_offset = 0;
+ return count;
+}
+
+///************************************************************************
+/// [function]: ioctl
+/// [parameters]: file , cmd , arg
+/// [return]: long
+///************************************************************************
+static long zet_fops_ioctl(struct file *file, unsigned int cmd, unsigned long arg )
+{
+ u8 __user * user_buf = (u8 __user *) arg;
+
+ u8 buf[IOCTL_MAX_BUF_SIZE];
+ int data_size;
+
+ if(copy_from_user(buf, user_buf, IOCTL_MAX_BUF_SIZE))
+ {
+ printk("[ZET]: zet_ioctl: copy_from_user fail\n");
+ return 0;
+ }
+
+ printk("[ZET]: zet_ioctl -> cmd = %d, %02x, %02x\n", cmd, buf[0], buf[1]);
+
+ if(cmd == ZET_IOCTL_CMD_FLASH_READ)
+ {
+ printk("[ZET]: zet_ioctl -> ZET_IOCTL_CMD_FLASH_DUMP cmd = %d, file=%s\n", cmd, (char *)buf);
+ ioctl_action |= IOCTL_ACTION_FLASH_DUMP;
+ }
+ else if(cmd == ZET_IOCTL_CMD_FLASH_WRITE)
+ {
+ printk("[ZET]: zet_ioctl -> ZET_IOCTL_CMD_FLASH_WRITE cmd = %d\n", cmd);
+ { //upload bin to flash_buffer
+ char fw_name[64];
+ sprintf(fw_name, "%szet62xx.bin", tran_type_mode_file_name);
+ zet_fw_load(fw_name);
+ }
+ zet622x_resume_downloader(this_client);
+ }
+ else if(cmd == ZET_IOCTL_CMD_RST)
+ {
+ printk("[ZET]: zet_ioctl -> ZET_IOCTL_CMD_RST cmd = %d\n", cmd);
+ //ctp_reset();
+ wmt_rst_output(1);
+
+ wmt_rst_output(0);
+ msleep(20);
+ wmt_rst_output(1);
+
+ transfer_type = TRAN_TYPE_DYNAMIC;
+ }
+ else if(cmd == ZET_IOCTL_CMD_RST_HIGH)
+ {
+ wmt_rst_output(1);
+ }
+ else if(cmd == ZET_IOCTL_CMD_RST_LOW)
+ {
+ wmt_rst_output(0);
+ }
+ else if(cmd == ZET_IOCTL_CMD_MDEV)
+ {
+ ///---------------------------------------------------///
+ /// set mutual dev mode
+ ///---------------------------------------------------///
+ zet622x_ts_set_transfer_type(TRAN_TYPE_MUTUAL_SCAN_DEV);
+ transfer_type = TRAN_TYPE_MUTUAL_SCAN_DEV;
+
+ }
+ else if(cmd == ZET_IOCTL_CMD_IBASE)
+ {
+ ///---------------------------------------------------///
+ /// set initial base mode
+ ///---------------------------------------------------///
+ zet622x_ts_set_transfer_type(TRAN_TYPE_INIT_SCAN_BASE);
+ transfer_type = TRAN_TYPE_INIT_SCAN_BASE;
+
+ }
+#ifdef FEATURE_IDEV_OUT_ENABLE
+ else if(cmd == ZET_IOCTL_CMD_IDEV)
+ {
+ ///---------------------------------------------------///
+ /// set initial dev mode
+ ///---------------------------------------------------///
+ zet622x_ts_set_transfer_type(TRAN_TYPE_INIT_SCAN_DEV);
+ transfer_type = TRAN_TYPE_INIT_SCAN_DEV;
+
+ }
+#endif ///< FEATURE_IDEV_OUT_ENABLE
+#ifdef FEATURE_MBASE_OUT_ENABLE
+ else if(cmd == ZET_IOCTL_CMD_MBASE)
+ {
+ ///---------------------------------------------------///
+ /// set Mutual Base mode
+ ///---------------------------------------------------///
+ zet622x_ts_set_transfer_type(TRAN_TYPE_MUTUAL_SCAN_BASE);
+ transfer_type = TRAN_TYPE_MUTUAL_SCAN_BASE;
+
+ }
+#endif ///< FEATURE_MBASE_OUT_ENABLE
+ else if(cmd == ZET_IOCTL_CMD_DYNAMIC)
+ {
+ zet622x_ts_set_transfer_type(TRAN_TYPE_DYNAMIC);
+ transfer_type = TRAN_TYPE_DYNAMIC;
+ }
+ else if(cmd == ZET_IOCTL_CMD_FW_FILE_PATH_GET)
+ {
+ memset(buf, 0x00, 64);
+ strcpy(buf, fw_file_name);
+ printk("[ZET]: zet_ioctl: Get FW_FILE_NAME = %s\n", buf);
+ }
+ else if(cmd == ZET_IOCTL_CMD_FW_FILE_PATH_SET)
+ {
+ strcpy(fw_file_name, buf);
+ printk("[ZET]: zet_ioctl: set FW_FILE_NAME = %s\n", buf);
+
+ }
+ else if(cmd == ZET_IOCTL_CMD_MDEV_GET)
+ {
+ data_size = (row+2)*(col+2);
+ memcpy(buf, mdev_data, data_size);
+ printk("[ZET]: zet_ioctl: Get MDEV data size=%d\n", data_size);
+ }
+ else if(cmd == ZET_IOCTL_CMD_TRAN_TYPE_PATH_SET)
+ {
+ strcpy(tran_type_mode_file_name, buf);
+ printk("[ZET]: zet_ioctl: Set ZET_IOCTL_CMD_TRAN_TYPE_PATH_ = %s\n", buf);
+ }
+ else if(cmd == ZET_IOCTL_CMD_TRAN_TYPE_PATH_GET)
+ {
+ memset(buf, 0x00, 64);
+ strcpy(buf, tran_type_mode_file_name);
+ printk("[ZET]: zet_ioctl: Get ZET_IOCTL_CMD_TRAN_TYPE_PATH = %s\n", buf);
+ }
+ else if(cmd == ZET_IOCTL_CMD_IDEV_GET)
+ {
+ data_size = (row + col);
+ memcpy(buf, idev_data, data_size);
+ printk("[ZET]: zet_ioctl: Get IDEV data size=%d\n", data_size);
+ }
+ else if(cmd == ZET_IOCTL_CMD_IBASE_GET)
+ {
+ data_size = (row + col)*2;
+ memcpy(buf, ibase_data, data_size);
+ printk("[ZET]: zet_ioctl: Get IBASE data size=%d\n", data_size);
+ }
+ else if(cmd == ZET_IOCTL_CMD_MBASE_GET)
+ {
+ data_size = (row*col*2);
+ if(data_size > IOCTL_MAX_BUF_SIZE)
+ {
+ data_size = IOCTL_MAX_BUF_SIZE;
+ }
+ memcpy(buf, mbase_data, data_size);
+ printk("[ZET]: zet_ioctl: Get MBASE data size=%d\n", data_size);
+ }
+ else if(cmd == ZET_IOCTL_CMD_INFO_SET)
+ {
+ printk("[ZET]: zet_ioctl: ZET_IOCTL_CMD_INFO_SET\n");
+ zet622x_ts_set_info_type();
+ }
+ else if(cmd == ZET_IOCTL_CMD_INFO_GET)
+ {
+ data_size = INFO_DATA_SIZE;
+ memcpy(buf, info_data, data_size);
+ printk("[ZET]: zet_ioctl: Get INFO data size=%d,IC: %x,X:%d,Y:%d\n", data_size, info_data[0], info_data[13], info_data[14]);
+ }
+ else if(cmd == ZET_IOCTL_CMD_TRACE_X_SET)
+ {
+ printk("[ZET]: zet_ioctl: ZET_IOCTL_CMD_TRACE_X_SET\n");
+ }
+ else if(cmd == ZET_IOCTL_CMD_TRACE_X_GET)
+ {
+ printk("[ZET]: zet_ioctl: Get TRACEX data\n");
+ }
+ else if(cmd == ZET_IOCTL_CMD_TRACE_Y_SET)
+ {
+ printk("[ZET]: zet_ioctl: ZET_IOCTL_CMD_TRACE_Y_SET\n");
+ }
+ else if(cmd == ZET_IOCTL_CMD_TRACE_Y_GET)
+ {
+ printk("[ZET]: zet_ioctl: Get TRACEY data \n");
+ }
+ else if(cmd == ZET_IOCTL_CMD_DRIVER_VER_GET)
+ {
+ memset(buf, 0x00, 64);
+ strcpy(buf, driver_version);
+ printk("[ZET]: zet_ioctl: Get DRIVER_VERSION = %s\n", buf);
+ printk("[ZET]: zet_ioctl: Get SVN = %s\n", DRIVER_VERSION);
+ }
+ else if(cmd == ZET_IOCTL_CMD_MBASE_EXTERN_GET)
+ {
+ data_size = (row*col*2) - IOCTL_MAX_BUF_SIZE;
+ if(data_size < 1)
+ {
+ data_size = 1;
+ }
+ memcpy(buf, (mbase_data+IOCTL_MAX_BUF_SIZE), data_size);
+ printk("[ZET]: zet_ioctl: Get MBASE extern data size=%d\n", data_size);
+ }
+
+ if(copy_to_user(user_buf, buf, IOCTL_MAX_BUF_SIZE))
+ {
+ printk("[ZET]: zet_ioctl: copy_to_user fail\n");
+ return 0;
+ }
+
+ return 0;
+}
+
+///************************************************************************
+/// file_operations
+///************************************************************************
+static const struct file_operations zet622x_ts_fops =
+{
+ .owner = THIS_MODULE,
+ .open = zet_fops_open,
+ .read = zet_fops_read,
+ .write = zet_fops_write,
+ .unlocked_ioctl = zet_fops_ioctl,
+ .compat_ioctl = zet_fops_ioctl,
+ .release = zet_fops_release,
+};
+
+static int zet6221_ts_probe(struct i2c_client *client/*, const struct i2c_device_id *id*/)
+{
+ int result = -1;
+ int count = 0;
+ int download_count = 0;
+ int download_ok = 0;
+ struct input_dev *input_dev;
+ struct device *dev;
+
+
+ struct zet6221_tsdrv *zet6221_ts;
+
+ dbg( "[TS] zet6221_ts_probe \n");
+
+ zet6221_ts = kzalloc(sizeof(struct zet6221_tsdrv), GFP_KERNEL);
+ l_ts = zet6221_ts;
+ zet6221_ts->i2c_ts = client;
+ //zet6221_ts->gpio = TS_INT_GPIO; /*s3c6410*/
+ //zet6221_ts->gpio = TS1_INT_GPIO;
+
+ this_client = client;
+
+ i2c_set_clientdata(client, zet6221_ts);
+
+ //client->driver = &zet6221_ts_driver;
+ ts_wq = create_singlethread_workqueue("zet6221ts_wq");
+ if (!ts_wq)
+ {
+ errlog("Failed to create workqueue!\n");
+ goto err_create_wq;
+ }
+
+ INIT_WORK(&zet6221_ts->work1, zet6221_ts_work);
+
+ input_dev = input_allocate_device();
+ if (!input_dev || !zet6221_ts) {
+ result = -ENOMEM;
+ goto fail_alloc_mem;
+ }
+
+ //i2c_set_clientdata(client, zet6221_ts);
+
+ input_dev->name = MJ5_TS_NAME;
+ input_dev->phys = "zet6221_touch/input0";
+ input_dev->id.bustype = BUS_HOST;
+ input_dev->id.vendor = 0x0001;
+ input_dev->id.product = 0x0002;
+ input_dev->id.version = 0x0100;
+//bootloader
+ zet622x_ts_option(client);
+ msleep(100);
+
+ download_count = 0;
+ download_ok = 0;
+ zet_fw_init();
+ do{
+ if (zet6221_load_fw())
+ {
+ errlog("Can't load the firmware of zet62xx!\n");
+ } else {
+ zet6221_downloader(client);
+ //ctp_reset(); //cancel it? need to check
+ }
+ udelay(100);
+
+ count=0;
+ do{
+ ctp_reset();
+
+ if(zet6221_ts_get_report_mode_t(client)==0) //get IC info by delay
+ {
+ ResolutionX = X_MAX;
+ ResolutionY = Y_MAX;
+ FingerNum = FINGER_NUMBER;
+ KeyNum = KEY_NUMBER;
+ if(KeyNum==0)
+ bufLength = 3+4*FingerNum;
+ else
+ bufLength = 3+4*FingerNum+1;
+ errlog("[warning] zet6221_ts_get_report_mode_t report error!!use default value\n");
+ }else
+ {
+ if(zet6221_ts_version()==1) // zet6221_ts_version() depends on zet6221_downloader()
+ // cancel download firmware, need to comment it.
+ {
+ dbg("get report mode ok!\n");
+ download_ok = 1;
+ }
+ }
+ count++;
+ }while(count<REPORT_POLLING_TIME && download_ok != 1 );
+ download_count++;
+ }while( download_count < RETRY_DOWNLOAD_TIMES && download_ok != 1 );
+
+ errlog( "ResolutionX=%d ResolutionY=%d FingerNum=%d KeyNum=%d\n",ResolutionX,ResolutionY,FingerNum,KeyNum);
+
+ input_dev->evbit[0] = BIT_MASK(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
+ if (wmt_ts_get_lcdexchg()) {
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, ResolutionX, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, ResolutionY, 0, 0);
+ } else {
+ input_set_abs_params(input_dev, ABS_MT_POSITION_X, 0, ResolutionY, 0, 0);
+ input_set_abs_params(input_dev, ABS_MT_POSITION_Y, 0, ResolutionX, 0, 0);
+ }
+
+ set_bit(KEY_BACK, input_dev->keybit);
+ set_bit(KEY_HOME, input_dev->keybit);
+ set_bit(KEY_MENU, input_dev->keybit);
+
+ //*******************************add 2013-1-10
+ set_bit(ABS_MT_TRACKING_ID, input_dev->absbit);
+ //set_bit(ABS_MT_TOUCH_MAJOR, input_dev->absbit);
+ input_set_abs_params(input_dev,ABS_MT_TRACKING_ID, 0, FingerNum, 0, 0);
+ //input_set_abs_params(input_dev, ABS_MT_TOUCH_MAJOR, 0, P_MAX, 0, 0);
+ //set_bit(BTN_TOUCH, input_dev->keybit);
+
+ #ifdef MT_TYPE_B
+ input_mt_init_slots(input_dev, FingerNum);
+ #endif
+ //set_bit(KEY_SEARCH, input_dev->keybit);
+
+ //input_dev->evbit[0] = BIT(EV_SYN) | BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ //input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+
+ result = input_register_device(input_dev);
+ if (result)
+ goto fail_ip_reg;
+
+ zet6221_ts->input = input_dev;
+
+ input_set_drvdata(zet6221_ts->input, zet6221_ts);
+ mutex_init(&i2c_mutex);
+ wake_lock_init(&downloadWakeLock, WAKE_LOCK_SUSPEND, "resume_download");
+ zet6221_ts->queue = create_singlethread_workqueue("ts_check_charge_queue");
+ INIT_DELAYED_WORK(&zet6221_ts->work, polling_timer_func);
+
+ //setup_timer(&zet6221_ts->polling_timer, polling_timer_func, (unsigned long)zet6221_ts);
+ //mod_timer(&zet6221_ts->polling_timer,jiffies + msecs_to_jiffies(TIME_CHECK_CHARGE));
+
+
+ //s3c6410
+ //result = gpio_request(zet6221_ts->gpio, "GPN");
+ wmt_set_gpirq(IRQ_TYPE_EDGE_FALLING);
+ wmt_disable_gpirq();
+ /*result = gpio_request(zet6221_ts->gpio, "GPN");
+ if (result)
+ goto gpio_request_fail;
+ */
+
+ zet6221_ts->irq = wmt_get_tsirqnum();//gpio_to_irq(zet6221_ts->gpio);
+ dbg( "[TS] zet6221_ts_probe.gpid_to_irq [zet6221_ts->irq=%d]\n",zet6221_ts->irq);
+
+ result = request_irq(zet6221_ts->irq, zet6221_ts_interrupt,IRQF_SHARED /*IRQF_TRIGGER_FALLING*/,
+ ZET_TS_ID_NAME, zet6221_ts);
+ if (result)
+ {
+ errlog("Can't alloc ts irq=%d\n", zet6221_ts->irq);
+ goto request_irq_fail;
+ }
+
+
+ ///-----------------------------------------------///
+ /// Set the default firmware bin file name & mutual dev file name
+ ///-----------------------------------------------///
+ zet_dv_set_file_name(DRIVER_VERSION);
+ zet_fw_set_file_name();//FW_FILE_NAME);
+ zet_tran_type_set_file_name(TRAN_MODE_FILE_PATH);
+
+ ///---------------------------------///
+ /// Set file operations
+ ///---------------------------------///
+ result = register_chrdev(I2C_MAJOR, "zet_i2c_ts", &zet622x_ts_fops);
+ if(result)
+ {
+ printk(KERN_ERR "%s:register chrdev failed\n",__FILE__);
+ goto fail_register_chrdev;
+ }
+ ///---------------------------------///
+ /// Create device class
+ ///---------------------------------///
+ i2c_dev_class = class_create(THIS_MODULE,"zet_i2c_dev");
+ if(IS_ERR(i2c_dev_class))
+ {
+ result = PTR_ERR(i2c_dev_class);
+ goto fail_create_class;
+ }
+ ///--------------------------------------------///
+ /// Get a free i2c dev
+ ///--------------------------------------------///
+ zet_i2c_dev = zet622x_i2c_get_free_dev(client->adapter);
+ if(IS_ERR(zet_i2c_dev))
+ {
+ result = PTR_ERR(zet_i2c_dev);
+ goto fail_get_free_dev;
+ }
+ dev = device_create(i2c_dev_class, &client->adapter->dev,
+ MKDEV(I2C_MAJOR,client->adapter->nr), NULL, "zet62xx_ts%d", client->adapter->nr);
+ if(IS_ERR(dev))
+ {
+ result = PTR_ERR(dev);
+ goto fail_create_device;
+ }
+
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ zet6221_ts->early_suspend.suspend = ts_early_suspend,
+ zet6221_ts->early_suspend.resume = ts_late_resume,
+ zet6221_ts->early_suspend.level = EARLY_SUSPEND_LEVEL_DISABLE_FB + 1;//,EARLY_SUSPEND_LEVEL_DISABLE_FB + 2;
+ register_early_suspend(&zet6221_ts->early_suspend);
+#endif
+ //disable_irq(zet6221_ts->irq);
+ ctp_reset();
+ wmt_enable_gpirq();
+ queue_delayed_work(zet6221_ts->queue, &zet6221_ts->work, msecs_to_jiffies(TIME_CHECK_CHARGE));
+ //mod_timer(&zet6221_ts->polling_timer,jiffies + msecs_to_jiffies(TIME_CHECK_CHARGE));
+ dbg("ok\n");
+ return 0;
+
+fail_create_device:
+ kfree(zet_i2c_dev);
+fail_get_free_dev:
+ class_destroy(i2c_dev_class);
+fail_create_class:
+ unregister_chrdev(I2C_MAJOR, "zet_i2c_ts");
+fail_register_chrdev:
+ free_irq(zet6221_ts->irq, zet6221_ts);
+request_irq_fail:
+ destroy_workqueue(zet6221_ts->queue);
+ cancel_delayed_work_sync(&zet6221_ts->work);
+ //gpio_free(zet6221_ts->gpio);
+//gpio_request_fail:
+ free_irq(zet6221_ts->irq, zet6221_ts);
+ wake_lock_destroy(&downloadWakeLock);
+ input_unregister_device(input_dev);
+ input_dev = NULL;
+fail_ip_reg:
+fail_alloc_mem:
+ input_free_device(input_dev);
+ destroy_workqueue(ts_wq);
+ cancel_work_sync(&zet6221_ts->work1);
+ zet_fw_exit();
+err_create_wq:
+ kfree(zet6221_ts);
+ return result;
+}
+
+static int zet6221_ts_remove(void /*struct i2c_client *dev*/)
+{
+ struct zet6221_tsdrv *zet6221_ts = l_ts;//i2c_get_clientdata(dev);
+
+ //del_timer(&zet6221_ts->polling_timer);
+#ifdef CONFIG_HAS_EARLYSUSPEND
+ unregister_early_suspend(&zet6221_ts->early_suspend);
+#endif
+ wmt_disable_gpirq();
+ device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR,this_client->adapter->nr));
+ kfree(zet_i2c_dev);
+ class_destroy(i2c_dev_class);
+ unregister_chrdev(I2C_MAJOR, "zet_i2c_ts");
+ free_irq(zet6221_ts->irq, zet6221_ts);
+ //gpio_free(zet6221_ts->gpio);
+ //del_timer_sync(&zet6221_ts->polling_timer);
+ destroy_workqueue(zet6221_ts->queue);
+ cancel_delayed_work_sync(&zet6221_ts->work);
+ input_unregister_device(zet6221_ts->input);
+ wake_lock_destroy(&downloadWakeLock);
+ cancel_work_sync(&zet6221_ts->work1);
+ destroy_workqueue(ts_wq);
+ zet_fw_exit();
+ kfree(zet6221_ts);
+
+ return 0;
+}
+
+static int wmt_wakeup_bl_notify(struct notifier_block *nb, unsigned long event,
+ void *dummy)
+{
+ //printk("get notify\n");
+ switch (event) {
+ case BL_CLOSE:
+ l_suspend = 1;
+ //printk("\nclose backlight\n\n");
+ //printk("disable irq\n\n");
+ wmt_disable_gpirq();
+ break;
+ case BL_OPEN:
+ l_suspend = 0;
+ //printk("\nopen backlight\n\n");
+ //printk("enable irq\n\n");
+ wmt_enable_gpirq();
+ break;
+ }
+
+ return NOTIFY_OK;
+}
+
+static struct notifier_block wmt_bl_notify = {
+ .notifier_call = wmt_wakeup_bl_notify,
+};
+
+static int zet6221_ts_init(void)
+{
+ //u8 ts_data[70];
+ //int ret;
+
+ /*ctp_reset();
+ memset(ts_data,0,70);
+ ret=zet6221_i2c_read_tsdata(ts_get_i2c_client(), ts_data, 8);
+ if (ret <= 0)
+ {
+ dbg("Can't find zet6221!\n");
+ return -1;
+ }
+ if (!zet6221_is_ts(ts_get_i2c_client()))
+ {
+ dbg("isn't zet6221!\n");
+ return -1;
+ }*/
+ if (zet6221_ts_probe(ts_get_i2c_client()))
+ {
+ return -1;
+ }
+ if (earlysus_en)
+ register_bl_notifier(&wmt_bl_notify);
+ //i2c_add_driver(&zet6221_ts_driver);
+ return 0;
+}
+//module_init(zet6221_ts_init);
+
+static void zet6221_ts_exit(void)
+{
+ zet6221_ts_remove();
+ if (earlysus_en)
+ unregister_bl_notifier(&wmt_bl_notify);
+ //i2c_del_driver(&zet6221_ts_driver);
+}
+//module_exit(zet6221_ts_exit);
+
+void zet6221_set_ts_mode(u8 mode)
+{
+ dbg( "[Touch Screen]ts mode = %d \n", mode);
+}
+//EXPORT_SYMBOL_GPL(zet6221_set_ts_mode);
+
+struct wmtts_device zet6221_tsdev = {
+ .driver_name = WMT_TS_I2C_NAME,
+ .ts_id = "ZET62",
+ .init = zet6221_ts_init,
+ .exit = zet6221_ts_exit,
+ .suspend = zet_ts_suspend,
+ .resume = zet_ts_resume,
+};
+
+
+MODULE_DESCRIPTION("ZET6221 I2C Touch Screen driver");
+MODULE_LICENSE("GPL v2");
diff --git a/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/zet6221_ts.h b/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/zet6221_ts.h
new file mode 100755
index 00000000..671bb29d
--- /dev/null
+++ b/ANDROID_3.4.5/drivers/input/touchscreen/zet6221_ts/zet6221_ts.h
@@ -0,0 +1,6 @@
+#ifndef ZET6221_TSH_201010191758
+#define ZET6221_TSH_201010191758
+
+extern void zet6221_set_tskey(int index,int key);
+
+#endif