/* drivers/input/touchscreen/ektf3k.c - ELAN EKTF3K FIFO verions of driver
 *
 * Copyright (C) 2011 Elan Microelectronics Corporation.
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 */

#define ELAN_BUFFER_MODE

#include <linux/module.h>
#include <linux/input/mt.h>
#include <linux/interrupt.h>
#include <linux/earlysuspend.h>
#include <linux/platform_device.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/gpio.h>
#include <linux/device.h>
#include <linux/jiffies.h>
#include <linux/miscdevice.h>
#include <linux/debugfs.h>

// for linux 2.6.36.3
#include <linux/cdev.h>
#include <linux/slab.h>
#include <linux/uaccess.h>
#include <asm/ioctl.h>
#include <linux/switch.h>
#include <linux/proc_fs.h>
#include <linux/wakelock.h>

#define PACKET_SIZE		40
#define NEW_PACKET_SIZE 55
#define FINGER_NUM		10
		
#define PWR_STATE_DEEP_SLEEP	0
#define PWR_STATE_NORMAL		1
#define PWR_NORMAL_STATE 8
#define PWR_IDLE_STATE 1
#define PWR_STATE_MASK			BIT(3)

#define CMD_S_PKT			0x52
#define CMD_R_PKT			0x53
#define CMD_W_PKT			0x54

#define HELLO_PKT			0x55
#define NORMAL_PKT			0x63
#define NEW_NOMARL_PKT      0x66
#define TEN_FINGERS_PKT			0x62

#define RPT_LOCK_PKT		0x56
#define RPT_UNLOCK_PKT		0xA6

#define RESET_PKT			0x77
#define CALIB_PKT			0xA8

#define IDX_FINGER			3
#define MAX_FINGER_SIZE          31
#define MAX_FINGER_PRESSURE  255

#define ABS_MT_POSITION         0x2a    /* Group a set of X and Y */
#define ABS_MT_AMPLITUDE        0x2b    /* Group a set of Z and W */

#include <linux/i2c/ektf3k.h>

// For Firmware Update 
#define ELAN_IOCTLID	0xD0
#define IOCTL_I2C_SLAVE	_IOW(ELAN_IOCTLID,  1, int)
#define IOCTL_MAJOR_FW_VER  _IOR(ELAN_IOCTLID, 2, int)
#define IOCTL_MINOR_FW_VER  _IOR(ELAN_IOCTLID, 3, int)
#define IOCTL_RESET  _IOR(ELAN_IOCTLID, 4, int)
#define IOCTL_IAP_MODE_LOCK  _IOR(ELAN_IOCTLID, 5, int)
#define IOCTL_CHECK_RECOVERY_MODE  _IOR(ELAN_IOCTLID, 6, int)
#define IOCTL_FW_VER  _IOR(ELAN_IOCTLID, 7, int)
#define IOCTL_X_RESOLUTION  _IOR(ELAN_IOCTLID, 8, int)
#define IOCTL_Y_RESOLUTION  _IOR(ELAN_IOCTLID, 9, int)
#define IOCTL_FW_ID  _IOR(ELAN_IOCTLID, 10, int)
#define IOCTL_ROUGH_CALIBRATE  _IOR(ELAN_IOCTLID, 11, int)
#define IOCTL_IAP_MODE_UNLOCK  _IOR(ELAN_IOCTLID, 12, int)
#define IOCTL_I2C_INT  _IOR(ELAN_IOCTLID, 13, int)
#define IOCTL_RESUME  _IOR(ELAN_IOCTLID, 14, int)
#define IOCTL_FW_UPDATE _IOR(ELAN_IOCTLID, 22, int) 

#define FIRMWARE_UPDATE_WITH_HEADER 1 

uint16_t checksum_err=0;
static uint8_t RECOVERY=0x00;
int FW_VERSION=0x00;
int X_RESOLUTION=0x00;
int Y_RESOLUTION=0x00;
int FW_ID=0x00;
static int work_lock=0x00;

#define USB_NO_Cable 0
#define USB_DETECT_CABLE 1 
#define USB_SHIFT 0
#define AC_SHIFT 1 
#define USB_Cable ((1 << (USB_SHIFT)) | (USB_DETECT_CABLE))
#define USB_AC_Adapter ((1 << (AC_SHIFT)) | (USB_DETECT_CABLE))
#define USB_CALBE_DETECT_MASK (USB_Cable  | USB_DETECT_CABLE)
static unsigned now_usb_cable_status=0;
static unsigned int gPrint_point = 0; 

#define TOUCH_STRESS_TEST 1
#ifdef TOUCH_STRESS_TEST
#define STRESS_IOC_MAGIC 0xF3
#define STRESS_IOC_MAXNR 4
#define STRESS_POLL_DATA _IOR(STRESS_IOC_MAGIC,2,int )
#define STRESS_IOCTL_START_HEAVY 2
#define STRESS_IOCTL_START_NORMAL 1
#define STRESS_IOCTL_END 0
#define START_NORMAL	(HZ/5)
#define START_HEAVY	(HZ/200)
static int poll_mode=0;
static struct delayed_work elan_poll_data_work;
static struct workqueue_struct *stress_work_queue;
static atomic_t touch_char_available = ATOMIC_INIT(1);
#endif

#define _ENABLE_DBG_LEVEL    
#ifdef _ENABLE_DBG_LEVEL
	#define PROC_FS_NAME	"ektf_dbg"
	#define PROC_FS_MAX_LEN	8
	static struct proc_dir_entry *dbgProcFile;
#endif

struct elan_ktf3k_ts_data {
	struct i2c_client *client;
	struct input_dev *input_dev;
	struct workqueue_struct *elan_wq;
	struct work_struct work;
	int (*power)(int on);
	struct early_suspend early_suspend;
	int intr_gpio;
// Firmware Information
	int fw_ver;
	int fw_id;
	int x_resolution;
	int y_resolution;
// For Firmare Update 
	struct miscdevice firmware;
      struct attribute_group attrs;
	int status;
	struct switch_dev touch_sdev;
	int abs_x_max;
	int abs_y_max;
	int rst_gpio;
	struct wake_lock wakelock;
#ifdef TOUCH_STRESS_TEST
      struct miscdevice  misc_dev;
#endif 
};

static struct elan_ktf3k_ts_data *private_ts = NULL;
static int __fw_packet_handler(struct i2c_client *client, int imediate);
static int elan_ktf3k_ts_rough_calibrate(struct i2c_client *client);
static int elan_ktf3k_ts_hw_reset(struct i2c_client *client);
static int elan_ktf3k_ts_resume(struct i2c_client *client);
#ifdef FIRMWARE_UPDATE_WITH_HEADER
static int firmware_update_header(struct i2c_client *client, const unsigned char *firmware, unsigned int page_number);
#endif
static struct semaphore pSem;
static int mTouchStatus[FINGER_NUM] = {0};

#define FIRMWARE_PAGE_SIZE 132
#define MAX_FIRMWARE_SIZE 32868
#define FIRMWARE_ACK_SIZE 2

/* Debug levels */
#define NO_DEBUG       0
#define DEBUG_ERROR  1
#define DEBUG_INFO     2
#define DEBUG_MESSAGES 5
#define DEBUG_TRACE   10

static int debug = DEBUG_INFO;

#define touch_debug(level, ...) \
	do { \
		if (debug >= (level)) \
			printk("[ektf3k]:" __VA_ARGS__); \
	} while (0)

int elan_iap_open(struct inode *inode, struct file *filp){ 
	touch_debug(DEBUG_INFO, "[ELAN]into elan_iap_open\n");
		if (private_ts == NULL)  touch_debug(DEBUG_ERROR, "private_ts is NULL~~~");
		
	return 0;
}

int elan_iap_release(struct inode *inode, struct file *filp){    
	return 0;
}

static ssize_t elan_iap_write(struct file *filp, const char *buff, size_t count, loff_t *offp){  
    int ret;
    char *tmp;

    if (count > 8192)
        count = 8192;

    tmp = kmalloc(count, GFP_KERNEL);
    
    if (tmp == NULL)
        return -ENOMEM;

    if (copy_from_user(tmp, buff, count)) {
        return -EFAULT;
    }
	
    ret = i2c_master_send(private_ts->client, tmp, count);
    if (ret != count) touch_debug(DEBUG_ERROR, "ELAN i2c_master_send fail, ret=%d \n", ret);
    kfree(tmp);
    return ret;

}

ssize_t elan_iap_read(struct file *filp, char *buff, size_t count, loff_t *offp){    
    char *tmp;
    int ret;  
    long rc;
   
    if (count > 8192)
        count = 8192;

    tmp = kmalloc(count, GFP_KERNEL);

    if (tmp == NULL)
        return -ENOMEM;

    ret = i2c_master_recv(private_ts->client, tmp, count);

    if (ret >= 0)
        rc = copy_to_user(buff, tmp, count);
    
    kfree(tmp);

    return ret;
}

static long elan_iap_ioctl(/*struct inode *inode,*/ struct file *filp,    unsigned int cmd, unsigned long arg){

	int __user *ip = (int __user *)arg;
	touch_debug(DEBUG_INFO, "[ELAN]into elan_iap_ioctl cmd=%u\n", cmd);

	switch (cmd) {        
		case IOCTL_I2C_SLAVE: 
			private_ts->client->addr = (int __user)arg;
			break;   
		case IOCTL_MAJOR_FW_VER:            
			break;        
		case IOCTL_MINOR_FW_VER:            
			break;        
		case IOCTL_RESET:
			return elan_ktf3k_ts_hw_reset(private_ts->client);
		case IOCTL_IAP_MODE_LOCK:
			work_lock=1;
			disable_irq(private_ts->client->irq);
			wake_lock(&private_ts->wakelock);
			break;
		case IOCTL_IAP_MODE_UNLOCK:
			work_lock=0;
			enable_irq(private_ts->client->irq);
			wake_unlock(&private_ts->wakelock);
			break;
		case IOCTL_CHECK_RECOVERY_MODE:
			return RECOVERY;
			break;
		case IOCTL_FW_VER:
			__fw_packet_handler(private_ts->client, work_lock);
			msleep(100);
			return FW_VERSION;
			break;
		case IOCTL_X_RESOLUTION:
			__fw_packet_handler(private_ts->client, work_lock);
			msleep(100);
			return X_RESOLUTION;
			break;
		case IOCTL_Y_RESOLUTION:
			__fw_packet_handler(private_ts->client, work_lock);
			msleep(100);
			return Y_RESOLUTION;
			break;
		case IOCTL_FW_ID:
			__fw_packet_handler(private_ts->client, work_lock);
			msleep(100);
			return FW_ID;
			break;
		case IOCTL_ROUGH_CALIBRATE:
			return elan_ktf3k_ts_rough_calibrate(private_ts->client);
		case IOCTL_I2C_INT:
			put_user(gpio_get_value(private_ts->intr_gpio), ip);
			break;
		case IOCTL_RESUME:
			elan_ktf3k_ts_resume(private_ts->client);
			break;
		default:            
			break;   
	}       
	return 0;
}

struct file_operations elan_touch_fops = {    
        .open =         elan_iap_open,    
        .write =        elan_iap_write,    
        .read = 	elan_iap_read,    
        .release =	elan_iap_release,    
	.unlocked_ioctl=elan_iap_ioctl, 
 };

/* Detect old / new FW */
static int isOldFW(struct i2c_client *client)
{
    struct elan_ktf3k_ts_data *ts = i2c_get_clientdata(client);
        
    touch_debug(DEBUG_MESSAGES, "[elan] GPIO_TP_INT_N=%d\n", ts->intr_gpio);
    if (gpio_get_value(ts->intr_gpio) == 0) {
        // Old FW 
	 touch_debug(DEBUG_INFO,  "[elan]detect intr=>Old FW\n");
	 return 1;
    }
	
    return 0;
}

#ifdef CONFIG_HAS_EARLYSUSPEND
static void elan_ktf3k_ts_early_suspend(struct early_suspend *h);
static void elan_ktf3k_ts_late_resume(struct early_suspend *h);
#endif

static ssize_t elan_ktf3k_gpio_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	int ret = 0;
	struct elan_ktf3k_ts_data *ts = private_ts;

	ret = gpio_get_value(ts->intr_gpio);
	touch_debug(DEBUG_MESSAGES, "GPIO_TP_INT_N=%d\n", ts->intr_gpio);
	sprintf(buf, "GPIO_TP_INT_N=%d\n", ret);
	ret = strlen(buf) + 1;
	return ret;
}

static DEVICE_ATTR(gpio, S_IRUGO, elan_ktf3k_gpio_show, NULL);

static ssize_t elan_ktf3k_vendor_show(struct device *dev,
		struct device_attribute *attr, char *buf)
{
	ssize_t ret = 0;
	struct elan_ktf3k_ts_data *ts = private_ts;

	sprintf(buf, "%s_x%4.4x\n", "ELAN_KTF3K", ts->fw_ver);
	ret = strlen(buf) + 1;
	return ret;
}

static DEVICE_ATTR(vendor, S_IRUGO, elan_ktf3k_vendor_show, NULL);

static ssize_t elan_show_status(struct device *dev, struct device_attribute *devattr, char *buf)
{
	struct i2c_client *client = to_i2c_client(dev);
	struct elan_ktf3k_ts_data *data = i2c_get_clientdata(client);

	return sprintf(buf, "%d\n", data->status);
}

DEVICE_ATTR(elan_touchpanel_status, S_IRUGO, elan_show_status, NULL);

static int check_fw_version(const unsigned char*firmware, unsigned int size, int fw_version){
       int id, version;
	   
       if(size < 2*FIRMWARE_PAGE_SIZE)
           return -1;
	   
	 version = firmware[size - 2*FIRMWARE_PAGE_SIZE + 120] | 
	 	      (firmware[size - 2*FIRMWARE_PAGE_SIZE + 121] << 8); 
	 id = firmware[size - 2*FIRMWARE_PAGE_SIZE + 122] | 
	 	      (firmware[size - 2*FIRMWARE_PAGE_SIZE + 123] << 8);
	 
	 touch_debug(DEBUG_INFO, "The firmware was version 0x%X and id:0x%X\n", version, id);
	 if(id == 0x3021)
	     return fw_version == 0xFFFF ? 1 : version - fw_version; // if the touch firmware was empty, always update firmware
	 else 
	     return 0; // this buffer doesn't contain the touch firmware
	 
}
static ssize_t update_firmware(struct device *dev, struct device_attribute *devattr,const char *buf, size_t count)
{
	 struct i2c_client *client = to_i2c_client(dev);
	 struct elan_ktf3k_ts_data *ts = i2c_get_clientdata(client);
	 struct file *firmware_fp;
	 char file_path[100];
        unsigned int pos = 0;
	 mm_segment_t oldfs;
	 unsigned int page_number;
	 static unsigned char firmware[MAX_FIRMWARE_SIZE];
	 int ret = 0, retry = 0;
	 
	 oldfs=get_fs();
	 set_fs(KERNEL_DS);
	 memset(file_path, 0, 100);
	 sscanf(buf, "%s\n", file_path);
	 touch_debug(DEBUG_INFO, "Update touch firmware with the file path:%s\n", file_path);
	 firmware_fp = filp_open(file_path, O_RDONLY, S_IRUSR |S_IRGRP);
	 if(PTR_ERR(firmware_fp) == -ENOENT){
	     dev_err(&client->dev, "Error to open file %s\n", file_path);
	     return -1;
	 }    
       //start move the firmware file into memory
       firmware_fp->f_pos = 0;
       for(pos = 0, page_number = 0; pos < MAX_FIRMWARE_SIZE; pos += FIRMWARE_PAGE_SIZE, page_number++){
	     if(firmware_fp->f_op->read(firmware_fp, firmware + pos,
		 	FIRMWARE_PAGE_SIZE, &firmware_fp->f_pos) != FIRMWARE_PAGE_SIZE){
	         break;
	     }
	 }
	 filp_close(firmware_fp, NULL);
	 // check the firmware ID and version
	 if(RECOVERY || check_fw_version(firmware, pos, ts->fw_ver) > 0){
	     touch_debug(DEBUG_INFO, "Firmware update start!\n");	
	     do{
	         ret = firmware_update_header(client, firmware, page_number);
	         touch_debug(DEBUG_INFO, "Firmware update finish ret=%d retry=%d !\n", ret, retry++);
	     }while(ret != 0 && retry < 3);
	     if(ret == 0 && RECOVERY) RECOVERY = 0;
	 }else 
	     touch_debug(DEBUG_INFO, "No need to update firmware\n");
	     
	 return count;
}

DEVICE_ATTR(update_fw,  S_IWUSR, NULL, update_firmware);


static struct attribute *elan_attr[] = {
	&dev_attr_elan_touchpanel_status.attr,
	&dev_attr_vendor.attr,
	&dev_attr_gpio.attr,
	&dev_attr_update_fw.attr,
	NULL
};

static struct kobject *android_touch_kobj;

static int elan_ktf3k_touch_sysfs_init(void)
{
	int ret ;

	android_touch_kobj = kobject_create_and_add("android_touch", NULL) ;
	if (android_touch_kobj == NULL) {
		touch_debug(DEBUG_ERROR, "[elan]%s: subsystem_register failed\n", __func__);
		ret = -ENOMEM;
		return ret;
	}
	ret = sysfs_create_file(android_touch_kobj, &dev_attr_gpio.attr);
	if (ret) {
		touch_debug(DEBUG_ERROR, "[elan]%s: sysfs_create_file failed\n", __func__);
		return ret;
	}
	ret = sysfs_create_file(android_touch_kobj, &dev_attr_vendor.attr);
	if (ret) {
		touch_debug(DEBUG_ERROR, "[elan]%s: sysfs_create_group failed\n", __func__);
		return ret;
	}
	return 0 ;
}

static void elan_touch_sysfs_deinit(void)
{
	sysfs_remove_file(android_touch_kobj, &dev_attr_vendor.attr);
	sysfs_remove_file(android_touch_kobj, &dev_attr_gpio.attr);
	kobject_del(android_touch_kobj);
}

static int __elan_ktf3k_ts_poll(struct i2c_client *client)
{
	struct elan_ktf3k_ts_data *ts = i2c_get_clientdata(client);
	int status = 0, retry = 150;

	do {
		status = gpio_get_value(ts->intr_gpio);
		dev_dbg(&client->dev, "%s: status = %d\n", __func__, status);
		retry--;
		msleep(20);
	} while (status == 1 && retry > 0);

	dev_dbg(&client->dev, "[elan]%s: poll interrupt status %s\n",
			__func__, status == 1 ? "high" : "low");
	return (status == 0 ? 0 : -ETIMEDOUT);
}

static int elan_ktf3k_ts_poll(struct i2c_client *client)
{
	return __elan_ktf3k_ts_poll(client);
}

static int elan_ktf3k_ts_get_data(struct i2c_client *client, uint8_t *cmd,
			uint8_t *buf, size_t size)
{
	int rc;

	dev_dbg(&client->dev, "[elan]%s: enter\n", __func__);

	if (buf == NULL)
		return -EINVAL;

      down(&pSem);
      rc = i2c_master_send(client, cmd, 4);
      up(&pSem);
	if(rc != 4){
	    dev_err(&client->dev,
			"[elan]%s: i2c_master_send failed\n", __func__);
	    return -EINVAL;
	}
      down(&pSem);
      rc  = i2c_master_recv(client, buf, size);
      up(&pSem);       
	if(rc != size){
	    dev_err(&client->dev,
			"[elan]%s: i2c_master_read failed\n", __func__);
	    return -EINVAL;
	}
	
	return 0;
}

static int elan_ktf3k_ts_read_command(struct i2c_client *client,
			   u8* cmd, u16 cmd_length, u8 *value, u16 value_length){
       struct i2c_adapter *adapter = client->adapter;
	struct i2c_msg msg[2];
	__le16 le_addr;
	struct elan_ktf3k_ts_data *ts;
	int length = 0;

	ts = i2c_get_clientdata(client);

	msg[0].addr = client->addr;
	msg[0].flags = 0x00;
	msg[0].len = cmd_length;
	msg[0].buf = cmd;

	down(&pSem);
	length = i2c_transfer(adapter, msg, 1);
	up(&pSem);
	
	if (length == 1) // only send on packet
		return value_length;
	else
		return -EIO;
}

static int elan_ktf3k_i2c_read_packet(struct i2c_client *client, 
	u8 *value, u16 value_length){
       struct i2c_adapter *adapter = client->adapter;
	struct i2c_msg msg[1];
	__le16 le_addr;
	struct elan_ktf3k_ts_data *ts;
	int length = 0;

	ts = i2c_get_clientdata(client);

	msg[0].addr = client->addr;
	msg[0].flags = I2C_M_RD;
	msg[0].len = value_length;
	msg[0].buf = (u8 *) value;
	down(&pSem);
	length = i2c_transfer(adapter, msg, 1);
	up(&pSem);
	
	if (length == 1) // only send on packet
		return value_length;
	else
		return -EIO;
}

static int __hello_packet_handler(struct i2c_client *client)
{
	int rc;
	uint8_t buf_recv[4] = { 0 };
	uint8_t buf_recv1[4] = { 0 };

	rc = elan_ktf3k_ts_poll(client);
	if (rc < 0) {
		touch_debug(DEBUG_ERROR, "[elan] %s: IRQ is not low!\n", __func__);
		RECOVERY = 1; 
	}

	rc = i2c_master_recv(client, buf_recv, 4);
	if(rc < 0){
		touch_debug(DEBUG_ERROR, "I2C message no Ack!\n");
             return -EINVAL;
	}
	touch_debug(DEBUG_INFO, "[elan] %s: hello packet %2x:%2X:%2x:%2x\n", __func__, buf_recv[0], buf_recv[1], buf_recv[2], buf_recv[3]);
      if(!(buf_recv[0]==0x55 && buf_recv[1]==0x55 && buf_recv[2]==0x55 && buf_recv[3]==0x55)){
		RECOVERY=0x80;
		return RECOVERY;
	}
	return 0;
}

static int wait_for_IRQ_Low(struct i2c_client *client, int utime){
    struct elan_ktf3k_ts_data *ts = i2c_get_clientdata(client);
    int retry_times = 10;
    do{
        usleep_range(utime,utime + 500);
	  if(gpio_get_value(ts->intr_gpio) == 0)
	      return 0; 
    }while(retry_times-- > 0);
	
    touch_debug("Wait IRQ time out\n");
    return -1;
}

static int __fw_packet_handler(struct i2c_client *client, int immediate)
{
	struct elan_ktf3k_ts_data *ts = i2c_get_clientdata(client);
	int rc;
	int major, minor;
	uint8_t cmd[] = {CMD_R_PKT, 0x00, 0x00, 0x01};
	uint8_t cmd_x[] = {0x53, 0x60, 0x00, 0x00}; /*Get x resolution*/
	uint8_t cmd_y[] = {0x53, 0x63, 0x00, 0x00}; /*Get y resolution*/
	uint8_t cmd_id[] = {0x53, 0xf0, 0x00, 0x01}; /*Get firmware ID*/
	uint8_t buf_recv[4] = {0};
// Firmware version
	rc = elan_ktf3k_ts_read_command(client, cmd, 4, buf_recv, 4);
	if (rc < 0)
		return rc;
	
	if(immediate){
	    wait_for_IRQ_Low(client, 1000);
	    elan_ktf3k_i2c_read_packet(client, buf_recv, 4);
	    major = ((buf_recv[1] & 0x0f) << 4) | ((buf_recv[2] & 0xf0) >> 4);
	    minor = ((buf_recv[2] & 0x0f) << 4) | ((buf_recv[3] & 0xf0) >> 4);
	    ts->fw_ver = major << 8 | minor;
	    FW_VERSION = ts->fw_ver;
	    touch_debug(DEBUG_INFO, "[elan] %s: firmware version: 0x%4.4x\n", __func__, ts->fw_ver);
	}
// X Resolution
	rc = elan_ktf3k_ts_read_command(client, cmd_x, 4, buf_recv, 4);
	if (rc < 0)
		return rc;
	
	if(immediate){
	    wait_for_IRQ_Low(client, 1000);
	    elan_ktf3k_i2c_read_packet(client, buf_recv, 4);
	    minor = ((buf_recv[2])) | ((buf_recv[3] & 0xf0) << 4);
	    ts->x_resolution =minor;
	    X_RESOLUTION = ts->x_resolution;
	    touch_debug(DEBUG_INFO, "[elan] %s: X resolution: 0x%4.4x\n", __func__, ts->x_resolution);
	}
// Y Resolution	
	rc = elan_ktf3k_ts_read_command(client, cmd_y, 4, buf_recv, 4);
	if (rc < 0)
		return rc;
	
	if(immediate){
	    wait_for_IRQ_Low(client, 1000);
	    elan_ktf3k_i2c_read_packet(client, buf_recv, 4);
	    minor = ((buf_recv[2])) | ((buf_recv[3] & 0xf0) << 4);
	    ts->y_resolution =minor;
	    Y_RESOLUTION = ts->y_resolution;
	    touch_debug(DEBUG_INFO, "[elan] %s: Y resolution: 0x%4.4x\n", __func__, ts->y_resolution);
	}
// Firmware ID
	rc = elan_ktf3k_ts_read_command(client, cmd_id, 4, buf_recv, 4);
	if (rc < 0)
		return rc;
	
	if(immediate){
	    wait_for_IRQ_Low(client, 1000);
	    elan_ktf3k_i2c_read_packet(client, buf_recv, 4);
	    major = ((buf_recv[1] & 0x0f) << 4) | ((buf_recv[2] & 0xf0) >> 4);
	    minor = ((buf_recv[2] & 0x0f) << 4) | ((buf_recv[3] & 0xf0) >> 4);
	    ts->fw_id = major << 8 | minor;
	    FW_ID = ts->fw_id;
	    touch_debug(DEBUG_INFO, "[elan] %s: firmware id: 0x%4.4x\n", __func__, ts->fw_id);
	}
	return 0;
}

static inline int elan_ktf3k_ts_parse_xy(uint8_t *data,
			uint16_t *x, uint16_t *y)
{
	*x = *y = 0;

	*x = (data[0] & 0xf0);
	*x <<= 4;
	*x |= data[1];

	*y = (data[0] & 0x0f);
	*y <<= 8;
	*y |= data[2];

	return 0;
}

static int elan_ktf3k_ts_setup(struct i2c_client *client)
{
	int rc, count = 10;
retry:	
        // Reset
        elan_ktf3k_ts_hw_reset(client);
	// Check if old firmware. If not, send the notmal_command to enter normal mode
       if( isOldFW(client) == 0 ){ //if check is new bootcode
           touch_debug(DEBUG_INFO, "The boot code is new!\n");
	}else
	    touch_debug(DEBUG_INFO, "The boot code is old!\n");
	
	rc = __hello_packet_handler(client);
	touch_debug(DEBUG_INFO, "[elan] hello packet's rc = %d\n",rc);
	if (rc < 0){ 
               if (rc == -ETIME && count > 0) {
			count--;
			dev_err(&client->dev, "wait main hello timeout, reset\n");
			goto retry;
		}
		else
			goto hand_shake_failed;

	}

	dev_dbg(&client->dev, "[elan] %s: hello packet got.\n", __func__);
        msleep(200);
	rc = __fw_packet_handler(client, 1);
	if (rc < 0)
		goto hand_shake_failed;
	dev_dbg(&client->dev, "[elan] %s: firmware checking done.\n", __func__);
hand_shake_failed:
	return rc;
}

static int elan_ktf3k_ts_set_power_state(struct i2c_client *client, int state)
{
	uint8_t cmd[] = {CMD_W_PKT, 0x50, 0x00, 0x01};
	int length;

	dev_dbg(&client->dev, "[elan] %s: enter\n", __func__);

	cmd[1] |= (state << 3);

	dev_dbg(&client->dev,
		"[elan] dump cmd: %02x, %02x, %02x, %02x\n",
		cmd[0], cmd[1], cmd[2], cmd[3]);

      down(&pSem);
      length = i2c_master_send(client, cmd, sizeof(cmd));
      up(&pSem);
	if (length != sizeof(cmd)) {
		dev_err(&client->dev,
			"[elan] %s: i2c_master_send failed\n", __func__);
		return -EINVAL;
	}

	return 0;
}

static int elan_ktf3k_ts_rough_calibrate(struct i2c_client *client){
      uint8_t cmd[] = {CMD_W_PKT, 0x29, 0x00, 0x01};
      int length;

	touch_debug(DEBUG_INFO, "[elan] %s: enter\n", __func__);
	touch_debug(DEBUG_INFO,
		"[elan] dump cmd: %02x, %02x, %02x, %02x\n",
		cmd[0], cmd[1], cmd[2], cmd[3]);
	
	down(&pSem);
	length = i2c_master_send(client, cmd, sizeof(cmd));
	up(&pSem);
	if (length != sizeof(cmd)) {
		dev_err(&client->dev,
			"[elan] %s: i2c_master_send failed\n", __func__);
		return -EINVAL;
	}

	return 0;
}

static int elan_ktf3k_ts_get_power_state(struct i2c_client *client)
{
	int rc = 0;
	uint8_t cmd[] = {CMD_R_PKT, 0x50, 0x00, 0x01};
	uint8_t buf[4], power_state;

	rc = elan_ktf3k_ts_get_data(client, cmd, buf, 4);
	if (rc)
		return rc;

	power_state = buf[1];
	touch_debug(DEBUG_INFO, "[elan] dump repsponse: %0x\n", power_state);
	power_state = power_state & 0x0F;
	dev_dbg(&client->dev, "[elan] power state = %s\n",
		power_state == PWR_STATE_DEEP_SLEEP ?
		"Deep Sleep" : "Normal/Idle");

	return power_state;
}

static int elan_ktf3k_ts_hw_reset(struct i2c_client *client)
{
      struct elan_ktf3k_ts_data *ts = i2c_get_clientdata(client);
      touch_debug(DEBUG_INFO, "[ELAN] Start HW reset!\n");
      gpio_direction_output(ts->rst_gpio, 0);
	usleep_range(1000,1500);
	gpio_direction_output(ts->rst_gpio, 1);
	msleep(250);
	return 0;
}


static int elan_ktf3k_ts_set_power_source(struct i2c_client *client, u8 state)
{
	uint8_t cmd[] = {CMD_W_PKT, 0x40, 0x00, 0x01};
	int length = 0;

	dev_dbg(&client->dev, "[elan] %s: enter\n", __func__);
    /*0x52 0x40 0x00 0x01  =>    Battery Mode
       0x52 0x41 0x00 0x01  =>    USB and AC Adapter Mode
      */
	cmd[1] |= state & 0x0F;

	dev_dbg(&client->dev,
		"[elan] dump cmd: %02x, %02x, %02x, %02x\n",
		cmd[0], cmd[1], cmd[2], cmd[3]);
      dev_info(&private_ts->client->dev, "Update power source to %d\n", state);	
      down(&pSem);
      length = i2c_master_send(client, cmd, sizeof(cmd));
      up(&pSem);
	if (length != sizeof(cmd)) {
		dev_err(&client->dev,
			"[elan] %s: i2c_master_send failed\n", __func__);
		return -EINVAL;
	}

	return 0;
}

static int elan_ktf3k_ts_get_power_source(struct i2c_client *client)
{
	int rc = 0;
	uint8_t cmd[] = {CMD_R_PKT, 0x40, 0x00, 0x01};
	uint8_t buf[4] = {0}, power_source;

	//rc = elan_ktf2k_ts_get_data(client, cmd, buf, 4);
	rc = elan_ktf3k_ts_read_command(client, cmd, 4, buf, 4);
	if (rc < 0)
		return rc;

	return 0;
}

static void update_power_source(){
      unsigned power_source = now_usb_cable_status;
      if(private_ts == NULL || work_lock) return;
	// Send power state 1 if USB cable and AC charger was plugged on. 
      elan_ktf3k_ts_set_power_source(private_ts->client, power_source != USB_NO_Cable);
}

void touch_callback(unsigned cable_status){ 
      now_usb_cable_status = cable_status;
      update_power_source();
}

static int elan_ktf3k_ts_recv_data(struct i2c_client *client, uint8_t *buf, int size)
{

	int rc, bytes_to_recv = size;

	if (buf == NULL)
		return -EINVAL;

	memset(buf, 0, bytes_to_recv);
	rc = i2c_master_recv(client, buf, bytes_to_recv);

	if (rc != bytes_to_recv) {
		dev_err(&client->dev,
			"[elan] %s: i2c_master_recv error?! \n", __func__);
		rc = i2c_master_recv(client, buf, bytes_to_recv);
		return -EINVAL;
	}

	return rc;
}

static void elan_ktf3k_ts_report_data(struct i2c_client *client, uint8_t *buf)
{
	struct elan_ktf3k_ts_data *ts = i2c_get_clientdata(client);
	struct input_dev *idev = ts->input_dev;
	uint16_t x, y, touch_size, pressure_size;
	uint16_t fbits=0, checksum=0;
	uint8_t i, num;
	static uint8_t size_index[10] = {35, 35, 36, 36, 37, 37, 38, 38, 39, 39};
	uint16_t active = 0;
	uint8_t idx=IDX_FINGER;

      num = buf[2] & 0xf; 
	for (i=0; i<34;i++)
		checksum +=buf[i];
	
       if ((num < 3) || ((checksum & 0x00ff) == buf[34])) { 
	    fbits = buf[2] & 0x30;	
	    fbits = (fbits << 4) | buf[1]; 
          for(i = 0; i < FINGER_NUM; i++){
              active = fbits & 0x1;
              if(active || mTouchStatus[i]){
		     input_mt_slot(ts->input_dev, i);
                  input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, active);
                  if(active){
                      elan_ktf3k_ts_parse_xy(&buf[idx], &x, &y);
			   x = x > ts->abs_x_max ? 0 : ts->abs_x_max - x;
			   y = y > ts->abs_y_max ? ts->abs_y_max : y; 
		         touch_size = ((i & 0x01) ? buf[size_index[i]] : (buf[size_index[i]] >> 4)) & 0x0F;
			   pressure_size = touch_size << 4; // shift left touch size value to 4 bits for max pressure value 255   
                      input_report_abs(idev, ABS_MT_TOUCH_MAJOR, touch_size);
                      input_report_abs(idev, ABS_MT_PRESSURE, pressure_size);
                      input_report_abs(idev, ABS_MT_POSITION_X, y);
                      input_report_abs(idev, ABS_MT_POSITION_Y, x);
                      if(unlikely(gPrint_point)) touch_debug(DEBUG_INFO, "[elan] finger id=%d X=%d y=%d size=%d pressure=%d\n", i, x, y, touch_size, pressure_size);
		     }
		 }
		 mTouchStatus[i] = active;
              fbits = fbits >> 1;
              idx += 3;
	    }
          input_sync(idev);
	} // checksum
	else {
		checksum_err +=1;
		touch_debug(DEBUG_ERROR, "[elan] Checksum Error %d byte[2]=%X\n", checksum_err, buf[2]);
	}   
     	
	return;
}

static void elan_ktf3k_ts_report_data2(struct i2c_client *client, uint8_t *buf)
{
	struct elan_ktf3k_ts_data *ts = i2c_get_clientdata(client);
	struct input_dev *idev = ts->input_dev;
	uint16_t x, y, touch_size, pressure_size;
	uint16_t fbits=0, checksum=0;
	uint8_t i, num;
	uint16_t active = 0; 
	uint8_t idx=IDX_FINGER;

      num = buf[2] & 0xf;
	for (i=0; i<34;i++)
		checksum +=buf[i];
	
	if ( (num < 3) || ((checksum & 0x00ff) == buf[34])) {   
          fbits = buf[2] & 0x30;	
	    fbits = (fbits << 4) | buf[1]; 
	    //input_report_key(idev, BTN_TOUCH, 1);
          for(i = 0; i < FINGER_NUM; i++){
              active = fbits & 0x1;
              if(active || mTouchStatus[i]){
		     input_mt_slot(ts->input_dev, i);
                  input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, active);
                  if(active){
		         elan_ktf3k_ts_parse_xy(&buf[idx], &x, &y);
                      x = x > ts->abs_x_max ? 0 : ts->abs_x_max - x;
			   y = y > ts->abs_y_max ? ts->abs_y_max : y;
			   touch_size = buf[35 + i];
			   pressure_size = buf[45 + i];	 
			   input_report_abs(idev, ABS_MT_TOUCH_MAJOR, touch_size);
			   input_report_abs(idev, ABS_MT_PRESSURE, pressure_size);
			   input_report_abs(idev, ABS_MT_POSITION_X, y);
			   input_report_abs(idev, ABS_MT_POSITION_Y, x);
			   if(unlikely(gPrint_point)) touch_debug(DEBUG_INFO, "[elan] finger id=%d X=%d y=%d size=%d pressure=%d\n", i, x, y, touch_size, pressure_size);
		     }
		 }
		 mTouchStatus[i] = active;
              fbits = fbits >> 1;
              idx += 3;
	    }
          input_sync(idev);
	} // checksum
	else {
		checksum_err +=1;
		touch_debug(DEBUG_ERROR, "[elan] Checksum Error %d byte[2]=%X\n", checksum_err, buf[2]);
	} 

	return;
}

static void process_resp_message(struct elan_ktf3k_ts_data *ts, const unsigned char *buf,
	                                                      unsigned int size){
      int major, minor;

      if(buf == NULL) return;
      switch(buf[1] & 0xF0){
      case 0x00:// firmware version
          major = ((buf[1] & 0x0f) << 4) | ((buf[2] & 0xf0) >> 4);
          minor = ((buf[2] & 0x0f) << 4) | ((buf[3] & 0xf0) >> 4);
          ts->fw_ver = major << 8 | minor;
          FW_VERSION = ts->fw_ver;
          break;
      case 0x20: // Rough calibrate response
          major = buf[2] & 0x0F;	  	
          touch_debug(DEBUG_INFO, "Get the Rough Calibrate result:%d\n", major);
          break;
      case 0x40: // the power source
          major = buf[1] & 0x0f;
          touch_debug(DEBUG_INFO, "Get the power source:%d\n", major);
      case 0x50: // the power state
          major = buf[1] & 0x0f;
          touch_debug(DEBUG_INFO, "Get the power mode:%d\n", major);
          break;
      case 0xF0: // firmware id
          major = ((buf[1] & 0x0f) << 4) | ((buf[2] & 0xf0) >> 4);
          minor = ((buf[2] & 0x0f) << 4) | ((buf[3] & 0xf0) >> 4);
          ts->fw_id = major << 8 | minor;
          FW_ID = ts->fw_id;
          break;	   
      default: 
          touch_debug(DEBUG_INFO, "[elan] Get unknow packet {0x%02X, 0x%02X, 0x%02X, 0x%02X}\n", buf[0], buf[1], buf[2], buf[3]);	
      }
}

static void elan_ktf3k_ts_work_func(struct work_struct *work)
{
	int rc;
	struct elan_ktf3k_ts_data *ts =
		container_of(work, struct elan_ktf3k_ts_data, work);
	uint8_t buf[NEW_PACKET_SIZE + 4] = { 0 };
	uint8_t buf1[NEW_PACKET_SIZE] = { 0 };
	uint8_t buf2[NEW_PACKET_SIZE] = { 0 };

	if(work_lock!=0) {
		touch_debug(DEBUG_INFO, "Firmware update during touch event handling");
		enable_irq(ts->client->irq);
		return;
	}
	      
#ifndef ELAN_BUFFER_MODE
		rc = elan_ktf3k_ts_recv_data(ts->client, buf, 40);
#else
             down(&pSem);
		rc = elan_ktf3k_ts_recv_data(ts->client, buf, 4); // read the first four bytes
#endif 
		if (rc < 0)
		{
                   up(&pSem);
			enable_irq(ts->client->irq);
			return;
		}
#ifndef ELAN_BUFFER_MODE
		elan_ktf3k_ts_report_data(ts->client, buf);
#else
             switch(buf[0]){
             case NORMAL_PKT:
		    rc = elan_ktf3k_ts_recv_data(ts->client, buf+4, 40); // read the finger report packet.
		    up(&pSem);
		    elan_ktf3k_ts_report_data(ts->client, buf+4);
	           // Second package
	 	    if ((buf[1] == 2) || (buf[1] == 3)) {
		        rc = elan_ktf3k_ts_recv_data(ts->client, buf1,PACKET_SIZE);
                     if (rc < 0){
			      enable_irq(ts->client->irq);
				return;
			  }
			  elan_ktf3k_ts_report_data(ts->client, buf1);
		    }
		
	           // Final package
		    if (buf[1] == 3) {
		        rc = elan_ktf3k_ts_recv_data(ts->client, buf2, PACKET_SIZE);
		        if (rc < 0){
		            enable_irq(ts->client->irq);
                         return;
                     }
                     elan_ktf3k_ts_report_data(ts->client, buf2);
                 }
		    break;
		case NEW_NOMARL_PKT:
		    rc = elan_ktf3k_ts_recv_data(ts->client, buf+4, NEW_PACKET_SIZE); // read the finger report packet.
		    up(&pSem);
		    elan_ktf3k_ts_report_data2(ts->client, buf+4);
	           // Second package
	 	    if ((buf[1] == 2) || (buf[1] == 3)) {
		        rc = elan_ktf3k_ts_recv_data(ts->client, buf1,NEW_PACKET_SIZE);
                     if (rc < 0){
			      enable_irq(ts->client->irq);
				return;
			  }
			  elan_ktf3k_ts_report_data2(ts->client, buf1);
		    }
		
	           // Final package
		    if (buf[1] == 3) {
		        rc = elan_ktf3k_ts_recv_data(ts->client, buf2, NEW_PACKET_SIZE);
		        if (rc < 0){
		            enable_irq(ts->client->irq);
                         return;
                     }
                     elan_ktf3k_ts_report_data2(ts->client, buf2);
                 }
		    break;
             case CMD_S_PKT:
		    up(&pSem);
                 process_resp_message(ts, buf, 4);
		    break;
		default:
		    up(&pSem);	
		    touch_debug(DEBUG_INFO, "[elan] Get unknow packet {0x%02X, 0x%02X, 0x%02X, 0x%02X}\n", buf[0], buf[1], buf[2], buf[3]);
	       }		 
#endif
		enable_irq(ts->client->irq);
}

static irqreturn_t elan_ktf3k_ts_irq_handler(int irq, void *dev_id)
{
	struct elan_ktf3k_ts_data *ts = dev_id;
	struct i2c_client *client = ts->client;

	dev_dbg(&client->dev, "[elan] %s\n", __func__);
	disable_irq_nosync(ts->client->irq);
	queue_work(ts->elan_wq, &ts->work);

	return IRQ_HANDLED;
}

static int elan_ktf3k_ts_register_interrupt(struct i2c_client *client)
{
	struct elan_ktf3k_ts_data *ts = i2c_get_clientdata(client);
	int err = 0;

	err = request_irq(client->irq, elan_ktf3k_ts_irq_handler,
			IRQF_TRIGGER_LOW, client->name, ts);
	if (err)
		dev_err(&client->dev, "[elan] %s: request_irq %d failed\n",
				__func__, client->irq);

	return err;
}


static ssize_t elan_touch_switch_name(struct switch_dev *sdev, char *buf)
{
	return sprintf(buf, "ELAN-%4.4x-%4.4x\n", 
		   private_ts->fw_id, private_ts->fw_ver);
}

static ssize_t elan_touch_switch_state(struct switch_dev *sdev, char *buf)
{ 
      	return sprintf(buf, "%s\n", "0");
}

#ifdef _ENABLE_DBG_LEVEL
static int ektf_proc_read(char *buffer, char **buffer_location, off_t offset, int buffer_length, int *eof, void *data )
{
	int ret;
	
	touch_debug(DEBUG_MESSAGES, "call proc_read\n");
	
	if(offset > 0)  /* we have finished to read, return 0 */
		ret  = 0;
	else 
		ret = sprintf(buffer, "Debug Level: Release Date: %s\n","2011/10/05");

	return ret;
}

static int ektf_proc_write(struct file *file, const char *buffer, unsigned long count, void *data)
{
	char procfs_buffer_size = 0; 
	int i, ret = 0;
	unsigned char procfs_buf[PROC_FS_MAX_LEN+1] = {0};
	unsigned int command;

	procfs_buffer_size = count;
	if(procfs_buffer_size > PROC_FS_MAX_LEN ) 
		procfs_buffer_size = PROC_FS_MAX_LEN+1;
	
	if( copy_from_user(procfs_buf, buffer, procfs_buffer_size) ) 
	{
		touch_debug(DEBUG_ERROR, " proc_write faied at copy_from_user\n");
		return -EFAULT;
	}

	command = 0;
	for(i=0; i<procfs_buffer_size-1; i++)
	{
		if( procfs_buf[i]>='0' && procfs_buf[i]<='9' )
			command |= (procfs_buf[i]-'0');
		else if( procfs_buf[i]>='A' && procfs_buf[i]<='F' )
			command |= (procfs_buf[i]-'A'+10);
		else if( procfs_buf[i]>='a' && procfs_buf[i]<='f' )
			command |= (procfs_buf[i]-'a'+10);
		
		if(i!=procfs_buffer_size-2)
			command <<= 4;
	}

	command = command&0xFFFFFFFF;
      switch(command){
      case 0xF1: 
	  	 gPrint_point = 1; 
	  	 break;
      case 0xF2: 
	  	 gPrint_point = 0; 
	  	 break;
      case 0xFF:
	      	ret = elan_ktf3k_ts_rough_calibrate(private_ts->client);
		break;
	}
	touch_debug(DEBUG_INFO, "Run command: 0x%08X  result:%d\n", command, ret);

	return count; // procfs_buffer_size;
}
#endif // #ifdef _ENABLE_DBG_LEV

#ifdef FIRMWARE_UPDATE_WITH_HEADER
#define FIRMWARE_PAGE_SIZE 132
static unsigned char touch_firmware[] = {
 #include "fw_data.b"
 }; 

#define SIZE_PER_PACKET 4

static int sendI2CPacket(struct i2c_client *client, const unsigned char *buf, unsigned int length){
     int ret, i, retry_times = 10;
     for(i = 0; i < length; i += ret){
            ret  = i2c_master_send(client, buf + i,  length < SIZE_PER_PACKET ? length : SIZE_PER_PACKET);
            if(ret <= 0){
	          retry_times--;
		    ret = 0;
	      }  
	     if(ret < (length < SIZE_PER_PACKET ? length : SIZE_PER_PACKET)){
	          touch_debug("Sending packet broken\n");
	     } 
		 	
	     if(retry_times < 0){
	          touch_debug("Failed sending I2C touch firmware packet.\n");
	          break;
	     }
     }

     return i;
}

static int recvI2CPacket(struct i2c_client *client, unsigned char *buf, unsigned int length){
     int ret, i, retry_times = 10;
     for(i = 0; i < length; i += ret){
            ret  = i2c_master_recv(client, buf + i,  length - i);
            if(ret <= 0){
	          retry_times--;
		    ret = 0;
	      }  
				
	     if(retry_times < 0){
	          touch_debug("Failed sending I2C touch firmware packet.\n");
	          break;
	     }
     }

     return i;
}


static int firmware_update_header(struct i2c_client *client, const unsigned char *firmware, unsigned int pages_number){
    int ret, i, mode;
    int retry_times = 3, write_times; 
    unsigned char packet_data[8] = {0};
    unsigned char isp_cmd[4] = {0x54, 0x00, 0x12, 0x34};
    unsigned char nb_isp_cmd[4] = {0x45, 0x49, 0x41, 0x50};
    unsigned char *cursor; 
    int boot_code = 0;
    struct elan_ktf3k_ts_data *ts = i2c_get_clientdata(client);
	
    if(ts == NULL) 
        return -1;

    touch_debug(DEBUG_INFO, "Start firmware update!\n");
    disable_irq(client->irq);  // Blocking call no need to do extra wait
    wake_lock(&ts->wakelock);
    work_lock = 1;
    elan_ktf3k_ts_hw_reset(client);
    // Step 1: Check boot code version
    boot_code = gpio_get_value(ts->intr_gpio);
    if(boot_code == 0){ // if the boot code is old
        touch_debug(DEBUG_INFO, "The firmware update of old boot code\n");
        if(recvI2CPacket(client, packet_data, 4) < 0) 
	      goto fw_update_failed;

	  touch_debug(DEBUG_INFO, "The received bytes 0x%X 0x%X 0x%X 0x%X\n", packet_data[0], packet_data[1], 
	  	           packet_data[2], packet_data[3]);
        if(packet_data[0] == 0x55 && packet_data[1] == 0x55 && packet_data[2] == 0x80 && packet_data[3] == 0x80)
	      touch_debug(DEBUG_INFO, "In the recovery mode\n");

        if(sendI2CPacket(client, isp_cmd, sizeof(isp_cmd)) < 0) // get into ISP mode
	      goto fw_update_failed;	  
    }else{ // if the boot code is new
        touch_debug(DEBUG_INFO, "The firmware update of new boot code\n");
        if(sendI2CPacket(client, nb_isp_cmd, sizeof(nb_isp_cmd)) < 0) // get into ISP mode
	      goto fw_update_failed;
    }
	
    msleep(100);
    packet_data[0] = 0x10; 
    if(sendI2CPacket(client, packet_data, 1) < 0) // send dummy byte
	      goto fw_update_failed;
	  
    cursor = firmware;
    touch_debug(DEBUG_INFO, "pages_number=%d\n", pages_number);
    for(i = 0; i < pages_number; i++){
        write_times = 0; 
page_write_retry:
	  touch_debug(DEBUG_MESSAGES, "Update page number %d\n", i);

          int sendCount;
          if((sendCount = sendI2CPacket(client, cursor, FIRMWARE_PAGE_SIZE)) != FIRMWARE_PAGE_SIZE){
	      dev_err(&client->dev, "Fail to Update page number %d\n", i);
		goto fw_update_failed;
	  }
          touch_debug(DEBUG_INFO, "sendI2CPacket send %d bytes\n", sendCount);

          int recvCount;
          if((recvCount = recvI2CPacket(client, packet_data, FIRMWARE_ACK_SIZE)) != FIRMWARE_ACK_SIZE){
	      dev_err(&client->dev, "Fail to Update page number %d\n", i);
	      goto fw_update_failed;
	  }

          touch_debug(DEBUG_INFO, "recvI2CPacket recv %d bytes: %x %x\n", recvCount, packet_data[0], packet_data[1]);

	  if(packet_data[0] != 0xaa || packet_data[1] != 0xaa){
	      touch_debug(DEBUG_INFO, "message received: %02X %02X Page %d rewrite\n", packet_data[0], packet_data[1], i);
		if(write_times++ > 3)
		    goto fw_update_failed;
			
		goto page_write_retry;
	  }
		  
	  cursor += FIRMWARE_PAGE_SIZE;
    }
	
    elan_ktf3k_ts_hw_reset(client);
    if(boot_code)
        msleep(2000);
    else		
        msleep(300);
    if(recvI2CPacket(client, packet_data, 4) < 0) 
	      goto fw_update_failed;	
    __fw_packet_handler(ts->client, 1);
    ret = 0;
    goto fw_update_finish;
fw_update_failed:
    ret = -1;
fw_update_finish:  
    work_lock = 0;
    wake_unlock(&ts->wakelock);
    enable_irq(client->irq);	
    touch_debug(DEBUG_INFO, "Finish the touch firmware update!\n");
    return ret; 
}



#endif

#ifdef TOUCH_STRESS_TEST
static void  stress_poll_data(struct work_struct * work)
{
	bool status;
	u8 count[7];
	status = elan_ktf3k_ts_recv_data(private_ts->client, count, 7);
	if(status < 0)
		printk("Read touch sensor data fail\n");

	if(poll_mode ==0)
		msleep(5);

	queue_delayed_work(stress_work_queue, &elan_poll_data_work, poll_mode);
}

int elan_stress_open(struct inode *inode, struct file *filp)
{
	printk("%s\n", __func__);
	if( !atomic_dec_and_test(&touch_char_available)){
		atomic_inc(&touch_char_available);
		return -EBUSY; /* already open */
	}
	return 0;          /* success */
}


int elan_stress_release(struct inode *inode, struct file *filp)
{
	printk("%s\n", __func__);
	atomic_inc(&touch_char_available); /* release the device */
	return 0;          /* success */
}

int elan_stress_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	int err = 1;

	printk("%s\n", __func__, cmd);
	if (_IOC_TYPE(cmd) != STRESS_IOC_MAGIC)
	return -ENOTTY;
	if (_IOC_NR(cmd) > STRESS_IOC_MAXNR)
	return -ENOTTY;
	if (_IOC_DIR(cmd) & _IOC_READ)
	err = !access_ok(VERIFY_WRITE, (void __user *)arg, _IOC_SIZE(cmd));
	else if (_IOC_DIR(cmd) & _IOC_WRITE)
	err =  !access_ok(VERIFY_READ, (void __user *)arg, _IOC_SIZE(cmd));
	if (err) return -EFAULT;
	switch (cmd) {
		case STRESS_POLL_DATA:
			if (arg == STRESS_IOCTL_START_HEAVY){
				printk("touch sensor heavey\n");
			poll_mode = START_HEAVY;
			queue_delayed_work(stress_work_queue, &elan_poll_data_work, poll_mode);
			}
			else if (arg == STRESS_IOCTL_START_NORMAL){
				printk("touch sensor normal\n");
				poll_mode = START_NORMAL;
				queue_delayed_work(stress_work_queue, &elan_poll_data_work, poll_mode);
			}
			else if  (arg == STRESS_IOCTL_END){
			printk("touch sensor end\n");
			cancel_delayed_work_sync(&elan_poll_data_work);
			}
			else
				return -ENOTTY;
			break;
		break;
	default: /* redundant, as cmd was checked against MAXNR */
	    return -ENOTTY;
	}
	return 0;
}

static struct file_operations stress_fops = {
		.owner =    THIS_MODULE,
		.unlocked_ioctl =	elan_stress_ioctl,
		.open =		elan_stress_open,
		.release =	elan_stress_release,
		};
#endif

static int elan_ktf3k_ts_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	int err = 0;
	struct elan_ktf3k_i2c_platform_data *pdata;
	struct elan_ktf3k_ts_data *ts;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		touch_debug(DEBUG_ERROR, "[elan] %s: i2c check functionality error\n", __func__);
		err = -ENODEV;
		goto err_check_functionality_failed;
	}

	ts = kzalloc(sizeof(struct elan_ktf3k_ts_data), GFP_KERNEL);
	if (ts == NULL) {
		touch_debug(DEBUG_INFO, "[elan] %s: allocate elan_ktf3k_ts_data failed\n", __func__);
		err = -ENOMEM;
		goto err_alloc_data_failed;
	}

	ts->elan_wq = create_singlethread_workqueue("elan_wq");
	if (!ts->elan_wq) {
		touch_debug(DEBUG_ERROR, "[elan] %s: create workqueue failed\n", __func__);
		err = -ENOMEM;
		goto err_create_wq_failed;
	}

	INIT_WORK(&ts->work, elan_ktf3k_ts_work_func);
	ts->client = client;
	i2c_set_clientdata(client, ts);
	pdata = client->dev.platform_data;

	if (likely(pdata != NULL)) {
		ts->intr_gpio = pdata->intr_gpio;
		ts->rst_gpio = pdata->rst_gpio;
	}

       sema_init(&pSem, 1);
	err = elan_ktf3k_ts_setup(client);
	if (err < 0) {
		touch_debug(DEBUG_ERROR, "Main code fail\n");
		ts->status = 0;
		RECOVERY = 1;
		err = 0;
		//goto err_detect_failed;
	}
	
	ts->status = 1; // set I2C status is OK;
	wake_lock_init(&ts->wakelock, WAKE_LOCK_SUSPEND, "elan_touch");
	if(err==0x80)
	    touch_debug(DEBUG_INFO, "[ELAN] Touch is in boot mode!\n");

	ts->input_dev = input_allocate_device();
	if (ts->input_dev == NULL) {
		err = -ENOMEM;
		dev_err(&client->dev, "[elan] Failed to allocate input device\n");
		goto err_input_dev_alloc_failed;
	}
	ts->input_dev->name = "elan-touchscreen";  

	//set_bit(BTN_TOUCH, ts->input_dev->keybit);
	ts->abs_x_max =  pdata->abs_x_max;
	ts->abs_y_max = pdata->abs_y_max;
	touch_debug(DEBUG_INFO, "[Elan] Max X=%d, Max Y=%d\n", ts->abs_x_max, ts->abs_y_max);

	input_mt_init_slots(ts->input_dev, FINGER_NUM);
	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_X, pdata->abs_y_min,  pdata->abs_y_max, 0, 0); // for 800 * 1280 
	input_set_abs_params(ts->input_dev, ABS_MT_POSITION_Y, pdata->abs_x_min,  pdata->abs_x_max, 0, 0);// for 800 * 1280 
	input_set_abs_params(ts->input_dev, ABS_MT_TOUCH_MAJOR, 0, MAX_FINGER_SIZE, 0, 0);
	input_set_abs_params(ts->input_dev, ABS_MT_PRESSURE, 0, MAX_FINGER_PRESSURE, 0, 0);

	__set_bit(EV_ABS, ts->input_dev->evbit);
	__set_bit(EV_SYN, ts->input_dev->evbit);
	__set_bit(EV_KEY, ts->input_dev->evbit);
	

	err = input_register_device(ts->input_dev);
	if (err) {
		dev_err(&client->dev,
			"[elan]%s: unable to register %s input device\n",
			__func__, ts->input_dev->name);
		goto err_input_register_device_failed;
	}

	elan_ktf3k_ts_register_interrupt(ts->client);

	if (gpio_get_value(ts->intr_gpio) == 0) {
		touch_debug(DEBUG_INFO, "[elan]%s: handle missed interrupt\n", __func__);
		elan_ktf3k_ts_irq_handler(client->irq, ts);
	}
	
#ifdef FIRMWARE_UPDATE_WITH_HEADER	
      if(RECOVERY || check_fw_version(touch_firmware, sizeof(touch_firmware), ts->fw_ver) > 0)
          firmware_update_header(client, touch_firmware, sizeof(touch_firmware)/FIRMWARE_PAGE_SIZE);
#endif

#ifdef CONFIG_HAS_EARLYSUSPEND
	ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 21;
	ts->early_suspend.suspend = elan_ktf3k_ts_early_suspend;
	ts->early_suspend.resume = elan_ktf3k_ts_late_resume;
	register_early_suspend(&ts->early_suspend);
#endif

	private_ts = ts;

	//elan_ktf2k_touch_sysfs_init();
      ts->attrs.attrs = elan_attr;
	err = sysfs_create_group(&client->dev.kobj, &ts->attrs);
	if (err) {
		dev_err(&client->dev, "Not able to create the sysfs\n");
	}
	
#ifdef _ENABLE_DBG_LEVEL
	dbgProcFile = create_proc_entry(PROC_FS_NAME, 0600, NULL);
	if (dbgProcFile == NULL) 
	{
		remove_proc_entry(PROC_FS_NAME, NULL);
		touch_debug(DEBUG_INFO, " Could not initialize /proc/%s\n", PROC_FS_NAME);
	}
	else
	{
		dbgProcFile->read_proc = ektf_proc_read;
		dbgProcFile->write_proc = ektf_proc_write;
		touch_debug(DEBUG_INFO, " /proc/%s created\n", PROC_FS_NAME);
	}
#endif // #ifdef _ENABLE_DBG_LEVEL

#ifdef TOUCH_STRESS_TEST
      stress_work_queue = create_singlethread_workqueue("i2c_touchsensor_wq");
	if(!stress_work_queue){
		dev_err(&client->dev, "Unable to create stress_work_queue workqueue\n");
	}
      INIT_DELAYED_WORK(&elan_poll_data_work, stress_poll_data);
	ts->misc_dev.minor  = MISC_DYNAMIC_MINOR;
	ts->misc_dev.name = "touchpanel";
	ts->misc_dev.fops = &stress_fops;
	err = misc_register(&ts->misc_dev);
	if (err) {
	    dev_err(&client->dev, "elan stress test: Unable to register %s \\misc device\n", ts->misc_dev.name);
	}
#endif
      /* Register Switch file */
      ts->touch_sdev.name = "touch";
      ts->touch_sdev.print_name = elan_touch_switch_name;
	ts->touch_sdev.print_state = elan_touch_switch_state;
	if(switch_dev_register(&ts->touch_sdev) < 0){
		touch_debug(DEBUG_ERROR, "switch_dev_register for dock failed!\n");
		//goto exit;
	}
	switch_set_state(&ts->touch_sdev, 0);
	   
	touch_debug(DEBUG_INFO, "[elan] Start touchscreen %s in interrupt mode\n",
		ts->input_dev->name);

  ts->firmware.minor = MISC_DYNAMIC_MINOR;
  ts->firmware.name = "elan-iap";
  ts->firmware.fops = &elan_touch_fops;
  ts->firmware.mode = S_IFREG|S_IRWXUGO; 

  if (misc_register(&ts->firmware) < 0)
  	touch_debug(DEBUG_ERROR, "[ELAN]misc_register failed!!");
  else
    touch_debug(DEBUG_INFO, "[ELAN]misc_register finished!!");	

  update_power_source();
  return 0;

err_input_register_device_failed:
	if (ts->input_dev)
		input_free_device(ts->input_dev);

err_input_dev_alloc_failed:
err_detect_failed:
	if (ts->elan_wq)
		destroy_workqueue(ts->elan_wq);

err_create_wq_failed:
	kfree(ts);

err_alloc_data_failed:
err_check_functionality_failed:

	return err;
}

static int elan_ktf3k_ts_remove(struct i2c_client *client)
{
	struct elan_ktf3k_ts_data *ts = i2c_get_clientdata(client);

	elan_touch_sysfs_deinit();

	unregister_early_suspend(&ts->early_suspend);
	free_irq(client->irq, ts);

	if (ts->elan_wq)
		destroy_workqueue(ts->elan_wq);
	input_unregister_device(ts->input_dev);
	wake_lock_destroy(&ts->wakelock);
#ifdef TOUCH_STRESS_TEST
	misc_deregister(&ts->misc_dev);
#endif
	kfree(ts);
#ifdef _ENABLE_DBG_LEVEL
	remove_proc_entry(PROC_FS_NAME, NULL);
#endif
	return 0;
}

void force_release_pos(struct i2c_client *client)
{
        struct elan_ktf3k_ts_data *ts = i2c_get_clientdata(client);
        int i;
        for (i=0; i < FINGER_NUM; i++) {
                if (mTouchStatus[i] == 0) continue;
                input_mt_slot(ts->input_dev, i);
                input_mt_report_slot_state(ts->input_dev, MT_TOOL_FINGER, 0);
                mTouchStatus[i] = 0;
        }

        input_sync(ts->input_dev);
}

static int elan_ktf3k_ts_suspend(struct i2c_client *client, pm_message_t mesg)
{
	struct elan_ktf3k_ts_data *ts = i2c_get_clientdata(client);
	int rc = 0;

	touch_debug(DEBUG_INFO, "[elan] %s: enter\n", __func__);
	disable_irq(client->irq);
	force_release_pos(client);
	rc = cancel_work_sync(&ts->work);
	if (rc)
		enable_irq(client->irq);

	if(work_lock == 0)
	    rc = elan_ktf3k_ts_set_power_state(client, PWR_STATE_DEEP_SLEEP);

	return 0;
}

static int elan_ktf3k_ts_resume(struct i2c_client *client)
{

	int rc = 0, retry = 5;
      struct elan_ktf3k_ts_data *ts = i2c_get_clientdata(client);
      int delay_time;
	touch_debug(DEBUG_INFO, "[elan] %s: enter\n", __func__);
	if(work_lock == 0){
	    do {
		rc = elan_ktf3k_ts_set_power_state(client, PWR_STATE_NORMAL);
		rc = elan_ktf3k_ts_get_power_state(client);
		if (rc != PWR_NORMAL_STATE && rc != PWR_IDLE_STATE)
			touch_debug(DEBUG_ERROR,  "[elan] %s: wake up tp failed! err = %d\n",
				__func__, rc);
		else
			break;
	    } while (--retry);
	}
	//force_release_pos(client);
      enable_irq(client->irq);	
	return 0;
}

#ifdef CONFIG_HAS_EARLYSUSPEND
static void elan_ktf3k_ts_early_suspend(struct early_suspend *h)
{
	struct elan_ktf3k_ts_data *ts;
	ts = container_of(h, struct elan_ktf3k_ts_data, early_suspend);
	elan_ktf3k_ts_suspend(ts->client, PMSG_SUSPEND);
}

static void elan_ktf3k_ts_late_resume(struct early_suspend *h)
{
	struct elan_ktf3k_ts_data *ts;
	ts = container_of(h, struct elan_ktf3k_ts_data, early_suspend);
	elan_ktf3k_ts_resume(ts->client);
}
#endif

static const struct i2c_device_id elan_ktf3k_ts_id[] = {
	{ ELAN_KTF3K_NAME, 0 },
	{ }
};

static struct i2c_driver ektf3k_ts_driver = {
	.probe		= elan_ktf3k_ts_probe,
	.remove		= elan_ktf3k_ts_remove,
#ifndef CONFIG_HAS_EARLYSUSPEND
	.suspend	= elan_ktf3k_ts_suspend,
	.resume		= elan_ktf3k_ts_resume,
#endif
	.id_table	= elan_ktf3k_ts_id,
	.driver		= {
		.name = ELAN_KTF3K_NAME,
	},
};

static int __devinit elan_ktf3k_ts_init(void)
{
	touch_debug(DEBUG_INFO, "[elan] %s\n", __func__);
	return i2c_add_driver(&ektf3k_ts_driver);
}

static void __exit elan_ktf3k_ts_exit(void)
{
	i2c_del_driver(&ektf3k_ts_driver);
	return;
}

module_init(elan_ktf3k_ts_init);
module_exit(elan_ktf3k_ts_exit);

MODULE_DESCRIPTION("ELAN KTF3K Touchscreen Driver");
MODULE_LICENSE("GPL");
