mtk android tp 调试

msg2133 tp调试

重要函数为:

tpd_local_init(tpd_probe), tpd_suspend, tpd_resume


Msg2133_driver.c:

/* Copyright Statement:
*
* This software/firmware and related documentation ("MediaTek Software") are
* protected under relevant copyright laws. The information contained herein
* is confidential and proprietary to MediaTek Inc. and/or its licensors.
* Without the prior written permission of MediaTek inc. and/or its licensors,
* any reproduction, modification, use or disclosure of MediaTek Software,
* and information contained herein, in whole or in part, shall be strictly prohibited.
*/
/* MediaTek Inc. (C) 2010. All rights reserved.
*
* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY ACKNOWLEDGES
* THAT IT IS RECEIVER'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY THIRD PARTY ALL PROPER LICENSES
* CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK
* SOFTWARE RELEASES MADE TO RECEIVER'S SPECIFICATION OR TO CONFORM TO A PARTICULAR
* STANDARD OR OPEN FORUM. RECEIVER'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK'S ENTIRE AND
* CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER WILL BE,
* AT MEDIATEK'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE AT ISSUE,
* OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY RECEIVER TO
* MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* The following software/firmware and/or related documentation ("MediaTek Software")
* have been modified by MediaTek Inc. All revisions are subject to any receiver's
* applicable license agreements with MediaTek Inc.
*/


#include "tpd.h"
#include <linux/interrupt.h>
#include <cust_eint.h>
#include <linux/i2c.h>
#include <linux/sched.h>
#include <linux/kthread.h>
#include <linux/rtpm_prio.h>
#include <linux/wait.h>
#include <linux/time.h>
#include <linux/delay.h>

#include <linux/dma-mapping.h>
#include <linux/slab.h>

#include "cust_gpio_usage.h"
#include "cust_gpio_usage.h"

#include "Tpd_custom_msg2133.h"

#ifdef MT6575
#include <mach/mt6575_pm_ldo.h>
#include <mach/mt6575_typedefs.h>
#include <mach/mt6575_boot.h>
#endif

#define GPIO_CTP_MSG2133_EN_PIN          125 // GPIO_CTP_EN_PIN
#define GPIO_CTP_MSG2133_EN_PIN_M_GPIO    GPIO_MODE_00

#define GPIO_CTP_MSG2133_EINT_PIN         75 //  GPIO_CTP_EINT_PIN
#define GPIO_CTP_MSG2133_EINT_PIN_M_GPIO   GPIO_CTP_EINT_PIN_M_EINT

extern struct tpd_device *tpd;

struct i2c_client *i2c_client = NULL;
struct task_struct *mthread = NULL;

struct TpdTouchDataT
{
	U8 packet_id;
	U8 x_h_y_h;
	U8 x_l;
	U8 y_l;
	U8 disx_h_disy_h;
	U8 disx_l;
	U8 disy_l;
    U8 checksum;
};
static struct TpdTouchDataT TpdTouchData;

static DECLARE_WAIT_QUEUE_HEAD(waiter);


static void tpd_eint_interrupt_handler(void);


extern void mt65xx_eint_unmask(unsigned int line);
extern void mt65xx_eint_mask(unsigned int line);
extern void mt65xx_eint_set_hw_debounce(kal_uint8 eintno, kal_uint32 ms);
extern kal_uint32 mt65xx_eint_set_sens(kal_uint8 eintno, kal_bool sens);
extern void mt65xx_eint_registration(kal_uint8 eintno, kal_bool Dbounce_En,
									 kal_bool ACT_Polarity, void (EINT_FUNC_PTR)(void),
									 kal_bool auto_umask);


static int __devinit tpd_probe(struct i2c_client *client, const struct i2c_device_id *id);
static int tpd_detect(struct i2c_client *client, int kind, struct i2c_board_info *info);
static int __devexit tpd_remove(struct i2c_client *client);
static int touch_event_handler(void *unused);

static int tpd_flag = 0;
static int point_num = 0;
static int p_point_num = 0;

#ifdef TPD_HAVE_BUTTON
static int tpd_keys_local[TPD_KEY_COUNT] = TPD_KEYS;
static int tpd_keys_dim_local[TPD_KEY_COUNT][4] = TPD_KEYS_DIM;
#endif

//#define TPD_CLOSE_POWER_IN_SLEEP
//#define TP_DEBUG
#define TP_FIRMWARE_UPDATE
#define TP_PROXIMITY_SENSOR
#define TPD_OK 0
// debug macros

#define TPD_LOGI  printk
#define TPD_LOGV printk
#if defined(TP_DEBUG_MSG)
#define pr_tp(format, args...) printk("<MSG>" format, ##args)
#define pr_ch(format, args...)                      \
	printk("<MSG>" "%s <%d>,%s(),cheehwa_print:\n\t"  \
	format,__FILE__,__LINE__,__func__, ##arg)
#else
#define pr_tp(format, args...)  do {} while (0)
#define pr_ch(format, args...)  do {} while (0)
#define pr_k(format, args...)  do {} while (0)
#endif

#ifdef TP_PROXIMITY_SENSOR
char ps_data_state[1] = {0};
enum
{
	DISABLE_CTP_PS,
	ENABLE_CTP_PS,
	RESET_CTP_PS
};
#endif

struct TouchInfoT
{
	int x1, y1;
	int x2, y2;
	int pressure;
	int count;
#ifdef TPD_HAVE_BUTTON 
    int key_id;
    int key_value;
#endif
};

#ifdef TP_FIRMWARE_UPDATE
#define U8 unsigned char
#define S8 signed char
#define U16 unsigned short
#define S16 signed short
#define U32 unsigned int
#define S32 signed int
#define TOUCH_ADDR_MSG21XX   0x4C
#define FW_ADDR_MSG21XX      0xC4
#define FW_UPDATE_ADDR_MSG21XX   0x92
static  char *fw_version;
#define DWIIC_MODE_ISP    0
#define DWIIC_MODE_DBBUS  1
#define   DOWNLOAD_FIRMWARE_BUF_SIZE   59*1024
static U8 *download_firmware_buf = NULL;
static int FwDataCnt=0;
//static int FwVersion;
struct class *firmware_class;
struct device *firmware_cmd_dev;

static int update_switch = 0;
#define ENABLE_DMA      0
#if ENABLE_DMA
static u8 *gpDMABuf_va = NULL;
static u32 gpDMABuf_pa = NULL;
#endif

#endif

struct touch_info
{
	unsigned short y[3];
	unsigned short x[3];
	unsigned short p[3];
	unsigned short count;
};

typedef struct
{
	unsigned short pos_x;
	unsigned short pos_y;
	unsigned short pos_x2;
	unsigned short pos_y2;
	unsigned short temp2;
	unsigned short temp;
	short dst_x;
	short dst_y;
	unsigned char checksum;
} SHORT_TOUCH_STATE;

static const struct i2c_device_id tpd_id[] = {{"msg2133", 0}, {}};
unsigned short myforce[] = {0, TOUCH_ADDR_MSG21XX, I2C_CLIENT_END, I2C_CLIENT_END};
static const unsigned short *const forces[] = { myforce, NULL };
static struct i2c_client_address_data addr_data = { .forces = forces, };

#ifdef TP_FIRMWARE_UPDATE
static void i2c_write(u8 addr, u8 *pbt_buf, int dw_lenth)
{
	int ret;
	i2c_client->addr = addr;
	i2c_client->addr|=I2C_ENEXT_FLAG;
	ret = i2c_master_send(i2c_client, pbt_buf, dw_lenth);
	i2c_client->addr = TOUCH_ADDR_MSG21XX;
	i2c_client->addr|=I2C_ENEXT_FLAG;

	if(ret <= 0)
	{
		printk("i2c_write_interface error line = %d, ret = %d\n", __LINE__, ret);
	}
}

static void i2c_read(u8 addr, u8 *pbt_buf, int dw_lenth)
{
	int ret;
	i2c_client->addr = addr;
	i2c_client->addr|=I2C_ENEXT_FLAG;
	ret = i2c_master_recv(i2c_client, pbt_buf, dw_lenth);
	i2c_client->addr = TOUCH_ADDR_MSG21XX;
    i2c_client->addr|=I2C_ENEXT_FLAG;

	if(ret <= 0)
	{
		printk("i2c_read_interface error line = %d, ret = %d\n", __LINE__, ret);
	}
}

static void i2c_write_update_msg2133(u8 *pbt_buf, int dw_lenth)
{
	int ret;
	i2c_client->addr = FW_UPDATE_ADDR_MSG21XX;
	i2c_client->addr|=I2C_ENEXT_FLAG;
	ret = i2c_master_send(i2c_client, pbt_buf, dw_lenth);
	i2c_client->addr = TOUCH_ADDR_MSG21XX;
	i2c_client->addr|=I2C_ENEXT_FLAG;

	// ret = i2c_smbus_write_i2c_block_data(i2c_client, *pbt_buf, dw_lenth-1, pbt_buf+1);
	if(ret <= 0)
	{
		printk("i2c_write_interface error line = %d, ret = %d\n", __LINE__, ret);
	}
}

static void i2c_write_msg2133(u8 *pbt_buf, int dw_lenth)
{
	int ret;
	i2c_client->timing = 40;
	i2c_client->addr = FW_ADDR_MSG21XX;
	i2c_client->addr|=I2C_ENEXT_FLAG;
	ret = i2c_master_send(i2c_client, pbt_buf, dw_lenth);
	i2c_client->addr = TOUCH_ADDR_MSG21XX;
	i2c_client->addr|=I2C_ENEXT_FLAG;
	i2c_client->timing = 240;

	// ret = i2c_smbus_write_i2c_block_data(i2c_client, *pbt_buf, dw_lenth-1, pbt_buf+1);
	if(ret <= 0)
	{
		printk("i2c_write_interface error line = %d, ret = %d\n", __LINE__, ret);
	}
}
static void i2c_read_update_msg2133(u8 *pbt_buf, int dw_lenth)
{
	int ret;
	i2c_client->addr = FW_UPDATE_ADDR_MSG21XX;
	i2c_client->addr|=I2C_ENEXT_FLAG;
	ret = i2c_master_recv(i2c_client, pbt_buf, dw_lenth);
	i2c_client->addr = TOUCH_ADDR_MSG21XX;
	i2c_client->addr|=I2C_ENEXT_FLAG;
	//  ret=i2c_smbus_read_i2c_block_data(i2c_client, *pbt_buf, dw_lenth-1, pbt_buf+1);

	if(ret <= 0)
	{
		printk("i2c_read_interface error line = %d, ret = %d\n", __LINE__, ret);
	}
}

static void i2c_read_msg2133(u8 *pbt_buf, int dw_lenth)
{
	int ret;
	i2c_client->timing = 40;
	i2c_client->addr = FW_ADDR_MSG21XX;
	i2c_client->addr|=I2C_ENEXT_FLAG;
	ret = i2c_master_recv(i2c_client, pbt_buf, dw_lenth);
	i2c_client->addr = TOUCH_ADDR_MSG21XX;
	i2c_client->addr|=I2C_ENEXT_FLAG;
	i2c_client->timing = 240;
	//  ret=i2c_smbus_read_i2c_block_data(i2c_client, *pbt_buf, dw_lenth-1, pbt_buf+1);

	if(ret <= 0)
	{
		printk("i2c_read_interface error line = %d, ret = %d\n", __LINE__, ret);
	}
}

#if ENABLE_DMA
ssize_t msg2133_dma_read_m_byte(u8 *returnData_va, u32 returnData_pa, U16 len)
{
	char     readData = 0;
	int     ret = 0, read_count = 0, read_length = 0;
	int    i, total_count = len;

	if(len == 0)
	{
		printk("[Error]msg2133_dma_read Read Len should not be zero!! \n");
		return 0;
	}

	//gpDMABuf_va = returnData_va; //mtk
	i2c_client->addr = FW_UPDATE_ADDR_MSG21XX;
	i2c_client->addr |= I2C_DMA_FLAG;
	i2c_client->addr|=I2C_ENEXT_FLAG;
	returnData_va[0] = 0x11;
	ret = i2c_master_send(i2c_client, returnData_pa, 1);

	if(ret < 0)
	{
		printk("[Error]MATV sends command error!! \n");
		i2c_client->addr = TOUCH_ADDR_MSG21XX;
		i2c_client->addr|=I2C_ENEXT_FLAG;
		return 0;
	}

	ret = i2c_master_recv(i2c_client, returnData_pa, len); // mtk
	i2c_client->addr = TOUCH_ADDR_MSG21XX;
	i2c_client->addr|=I2C_ENEXT_FLAG;

	if(ret < 0)
	{
		printk("[Error]msg2133_dma_read reads data error!! \n");
		return 0;
	}

	//for (i = 0; i< total_count; i++)
	//    MATV_LOGD("[MATV]I2C ReadData[%d] = %x\n",i,returnData_va[i]);
	return 1;
}

#define MAX_CMD_LEN 255
ssize_t msg2133_dma_write_m_byte(u8 *Data, U16 len)
{
	char addr_bak;
	u32 phyAddr = 0;
	u8 *buf_dma = NULL;
	u32 old_addr = 0;
	int ret = 0;
	int retry = 3;

	addr_bak = i2c_client->addr;
	i2c_client->addr = FW_UPDATE_ADDR_MSG21XX;
	i2c_client->addr |= I2C_ENEXT_FLAG;
	if (len > MAX_CMD_LEN) {
		//TPD_LOGI("[i2c_master_send_ext] exceed the max write length \n");
		return -1;
	}

	phyAddr = 0;
	buf_dma = dma_alloc_coherent(0, len, &phyAddr, GFP_KERNEL);
	if (NULL == buf_dma) {
		//TPD_LOGI("[i2c_master_send_ext] Not enough memory \n");
		return -1;
	}
	memcpy(buf_dma, Data, len);
	i2c_client->addr |= I2C_DMA_FLAG;
	i2c_client->addr|=I2C_ENEXT_FLAG;

	do {
		ret = i2c_master_send(i2c_client, (u8*)phyAddr, len);
		retry --;
		if (ret != len) {
			//TPD_LOGI("[i2c_master_send_ext] Error sent I2C ret = %d\n", ret);
		}
	}while ((ret != len) && (retry > 0));

	dma_free_coherent(0, len, buf_dma, phyAddr);

	i2c_client->addr = addr_bak;

	return 1;
}

U8 drvISP_DMA_Read(U8 *pDataToRead, U32 pa_addr, U8 n)    //First it needs send 0x11 to notify we want to get flash data back.
{
	//    U8 Read_cmd = 0x11;
	//    unsigned char dbbus_rx_data[2] = {0};
	//    i2c_write_update_msg2133( &Read_cmd, 1);
	msg2133_dma_read_m_byte(pDataToRead, pa_addr, n);
	return 0;
}

#endif

void Get_Chip_Version(void)
{
	unsigned char dbbus_tx_data[3];
	unsigned char dbbus_rx_data[2];
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x1E;
	dbbus_tx_data[2] = 0xCE;
	i2c_write_msg2133(&dbbus_tx_data[0], 3);
	i2c_read_msg2133(&dbbus_rx_data[0], 2);

	if(dbbus_rx_data[1] == 0)
	{
		// it is Catch2
		pr_tp("*** Catch2 ***\n");
		//FwVersion  = 2;// 2 means Catch2
	}
	else
	{
		// it is catch1
		pr_tp("*** Catch1 ***\n");
		//FwVersion  = 1;// 1 means Catch1
	}
}

void dbbusDWIICEnterSerialDebugMode(void)
{
	U8 data[5];
	// Enter the Serial Debug Mode
	data[0] = 0x53;
	data[1] = 0x45;
	data[2] = 0x52;
	data[3] = 0x44;
	data[4] = 0x42;
	i2c_write_msg2133(data, 5);
}

void dbbusDWIICStopMCU(void)
{
	U8 data[1];
	// Stop the MCU
	data[0] = 0x37;
	i2c_write_msg2133(data, 1);
}

void dbbusDWIICIICUseBus(void)
{
	U8 data[1];
	// IIC Use Bus
	data[0] = 0x35;
	i2c_write_msg2133(data, 1);
}

void dbbusDWIICIICReshape(void)
{
	U8 data[1];
	// IIC Re-shape
	data[0] = 0x71;
	i2c_write_msg2133(data, 1);
}

void dbbusDWIICIICNotUseBus(void)
{
	U8 data[1];
	// IIC Not Use Bus
	data[0] = 0x34;
	i2c_write_msg2133(data, 1);
}

void dbbusDWIICNotStopMCU(void)
{
	U8 data[1];
	// Not Stop the MCU
	data[0] = 0x36;
	i2c_write_msg2133(data, 1);
}

void dbbusDWIICExitSerialDebugMode(void)
{
	U8 data[1];
	// Exit the Serial Debug Mode
	data[0] = 0x45;
	i2c_write_msg2133(data, 1);
	// Delay some interval to guard the next transaction
	//udelay ( 200 );        // delay about 0.2ms
}

void drvISP_EntryIspMode(void)
{
	U8 bWriteData[5] =
	{
		0x4D, 0x53, 0x54, 0x41, 0x52
	};
	i2c_write_update_msg2133(bWriteData, 5);
	mdelay(10);           // delay about 1ms
}

U8 drvISP_Read(U8 n, U8 *pDataToRead)    //First it needs send 0x11 to notify we want to get flash data back.
{
	U8 Read_cmd = 0x11;
	U8 i = 0;
	unsigned char dbbus_rx_data[16] = {0};
	i2c_write_update_msg2133(&Read_cmd, 1);
	//if (n == 1)
	{
		i2c_read_update_msg2133(&dbbus_rx_data[0], n + 1);

		for(i = 0; i < n; i++)
		{
			*(pDataToRead + i) = dbbus_rx_data[i + 1];
		}
	}
	//else
	{
		//     i2c_read_update_msg2133(pDataToRead, n);
	}
	return 0;
}

void drvISP_WriteEnable(void)
{
	U8 bWriteData[2] =
	{
		0x10, 0x06
	};
	U8 bWriteData1 = 0x12;
	i2c_write_update_msg2133(bWriteData, 2);
	i2c_write_update_msg2133(&bWriteData1, 1);
}


void drvISP_ExitIspMode(void)
{
	U8 bWriteData = 0x24;
	i2c_write_update_msg2133(&bWriteData, 1);
}

U8 drvISP_ReadStatus(void)
{
	U8 bReadData = 0;
	U8 bWriteData[2] =
	{
		0x10, 0x05
	};
	U8 bWriteData1 = 0x12;
	i2c_write_update_msg2133(bWriteData, 2);
	drvISP_Read(1, &bReadData);
	i2c_write_update_msg2133(&bWriteData1, 1);
	return bReadData;
}


void drvISP_BlockErase(U32 addr)
{
	U8 bWriteData[5] = { 0x00, 0x00, 0x00, 0x00, 0x00 };
	U8 bWriteData1 = 0x12;
	pr_ch("The drvISP_ReadStatus0=%d\n", drvISP_ReadStatus());
	drvISP_WriteEnable();
	pr_ch("The drvISP_ReadStatus1=%d\n", drvISP_ReadStatus());
	//Enable write status register
	bWriteData[0] = 0x10;
	bWriteData[1] = 0x50;
	i2c_write_update_msg2133(bWriteData, 2);
	i2c_write_update_msg2133(&bWriteData1, 1);
	//Write Status
	bWriteData[0] = 0x10;
	bWriteData[1] = 0x01;
	bWriteData[2] = 0x00;
	i2c_write_update_msg2133(bWriteData, 3);
	i2c_write_update_msg2133(&bWriteData1, 1);
	//Write disable
	bWriteData[0] = 0x10;
	bWriteData[1] = 0x04;
	i2c_write_update_msg2133(bWriteData, 2);
	i2c_write_update_msg2133(&bWriteData1, 1);

	while((drvISP_ReadStatus() & 0x01) == 0x01)
	{
		;
	}

	pr_ch("The drvISP_ReadStatus3=%d\n", drvISP_ReadStatus());
	drvISP_WriteEnable();
	pr_ch("The drvISP_ReadStatus4=%d\n", drvISP_ReadStatus());
	bWriteData[0] = 0x10;
	bWriteData[1] = 0xC7;        //Block Erase
	//bWriteData[2] = ((addr >> 16) & 0xFF) ;
	//bWriteData[3] = ((addr >> 8) & 0xFF) ;
	// bWriteData[4] = (addr & 0xFF) ;
	i2c_write_update_msg2133(bWriteData, 2);
	//i2c_write_update_msg2133( &bWriteData, 5);
	i2c_write_update_msg2133(&bWriteData1, 1);

	while((drvISP_ReadStatus() & 0x01) == 0x01)
	{
		;
	}
}

void drvISP_Program(U16 k, U8 *pDataToWrite)
{
	U16 i = 0;
	U16 j = 0;
	//U16 n = 0;
	U8 TX_data[133];
	U8 bWriteData1 = 0x12;
	U32 addr = k * 1024;
#if ENABLE_DMA

	for(j = 0; j < 8; j++)    //128*8 cycle
	{
		TX_data[0] = 0x10;
		TX_data[1] = 0x02;// Page Program CMD
		TX_data[2] = (addr + 128 * j) >> 16;
		TX_data[3] = (addr + 128 * j) >> 8;
		TX_data[4] = (addr + 128 * j);

		for(i = 0; i < 128; i++)
		{
			TX_data[5 + i] = pDataToWrite[j * 128 + i];
		}

		while((drvISP_ReadStatus() & 0x01) == 0x01)
		{
			;    //wait until not in write operation
		}

		drvISP_WriteEnable();
		//        i2c_write_update_msg2133( TX_data, 133);   //write 133 byte per cycle
		msg2133_dma_write_m_byte(TX_data, 133);
		i2c_write_update_msg2133(&bWriteData1, 1);
	}

#else

	for(j = 0; j < 512; j++)    //128*8 cycle
	{
		TX_data[0] = 0x10;
		TX_data[1] = 0x02;// Page Program CMD
		TX_data[2] = (addr + 2 * j) >> 16;
		TX_data[3] = (addr + 2 * j) >> 8;
		TX_data[4] = (addr + 2 * j);

		for(i = 0; i < 2; i++)
		{
			TX_data[5 + i] = pDataToWrite[j * 2 + i];
		}

		while((drvISP_ReadStatus() & 0x01) == 0x01)
		{
			;    //wait until not in write operation
		}

		drvISP_WriteEnable();
		i2c_write_update_msg2133(TX_data, 7);    //write 133 byte per cycle
		i2c_write_update_msg2133(&bWriteData1, 1);
	}

#endif
}


void drvISP_Verify(U16 k, U8 *pDataToVerify)
{
	U16 i = 0, j = 0;
	U8 bWriteData[5] =
	{
		0x10, 0x03, 0, 0, 0
	};
	U8 bWriteData1 = 0x12;
	U32 addr = k * 1024;
	U8 index = 0;
#if ENABLE_DMA
	U8 *RX_data = gpDMABuf_va; //mtk

	for(j = 0; j < 8; j++)    //128*8 cycle
	{
		bWriteData[2] = (U8)((addr + j * 128) >> 16);
		bWriteData[3] = (U8)((addr + j * 128) >> 8);
		bWriteData[4] = (U8)(addr + j * 128);

		while((drvISP_ReadStatus() & 0x01) == 0x01)
		{
			;    //wait until not in write operation
		}

		i2c_write_update_msg2133(bWriteData, 5);     //write read flash addr
		drvISP_DMA_Read(gpDMABuf_va, gpDMABuf_pa, 128); //mtk
		i2c_write_update_msg2133(&bWriteData1, 1);     //cmd end

		for(i = 0; i < 128; i++)    //log out if verify error
		{
			if((RX_data[i] != 0) && index < 10)
			{
				pr_tp("j=%d,RX_data[%d]=0x%x\n", j, i, RX_data[i]);
				index++;
			}

			if(RX_data[i] != pDataToVerify[128 * j + i])
			{
				pr_tp("k=%d,j=%d,i=%d===============Update Firmware Error================", k, j, i);
			}
		}
	}

#else
	U8 RX_data[128];

	for(j = 0; j < 256; j++)    //128*8 cycle
	{
		bWriteData[2] = (U8)((addr + j * 4) >> 16);
		bWriteData[3] = (U8)((addr + j * 4) >> 8);
		bWriteData[4] = (U8)(addr + j * 4);

		while((drvISP_ReadStatus() & 0x01) == 0x01)
		{
			;    //wait until not in write operation
		}

		i2c_write_update_msg2133(bWriteData, 5);     //write read flash addr
		drvISP_Read(4, RX_data);
		i2c_write_update_msg2133(&bWriteData1, 1);     //cmd end

		for(i = 0; i < 4; i++)    //log out if verify error
		{
			if((RX_data[i] != 0) && index < 10)
			{
				pr_tp("j=%d,RX_data[%d]=0x%x\n", j, i, RX_data[i]);
				index++;
			}

			if(RX_data[i] != pDataToVerify[4 * j + i])
			{
				pr_tp("k=%d,j=%d,RX_data[%d]=0x%x===============Update Firmware Error================", k, j, i, RX_data[i]);
			}
		}
	}

#endif
}

static ssize_t firmware_update_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
	return sprintf(buf, "%s\n", fw_version);
}

static ssize_t firmware_update_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
	U8 i;
	U8 dbbus_tx_data[4];
	unsigned char dbbus_rx_data[2] = {0};
	update_switch = 1;
	pr_ch("\n");
	//drvISP_EntryIspMode();
	//drvISP_BlockErase(0x00000);
	//M by cheehwa _HalTscrHWReset();
	mt_set_gpio_mode(GPIO_CTP_MSG2133_EN_PIN, GPIO_CTP_MSG2133_EN_PIN_M_GPIO);
	mt_set_gpio_dir(GPIO_CTP_MSG2133_EN_PIN, GPIO_DIR_OUT);
	mt_set_gpio_out(GPIO_CTP_MSG2133_EN_PIN, GPIO_OUT_ZERO);
	msleep(100);
	mt_set_gpio_mode(GPIO_CTP_MSG2133_EN_PIN, GPIO_CTP_MSG2133_EN_PIN_M_GPIO);
	mt_set_gpio_dir(GPIO_CTP_MSG2133_EN_PIN, GPIO_DIR_OUT);
	mt_set_gpio_out(GPIO_CTP_MSG2133_EN_PIN, GPIO_OUT_ONE);
	mdelay(500);
	//msctpc_LoopDelay ( 100 );        // delay about 100ms*****
	// Enable slave's ISP ECO mode
	dbbusDWIICEnterSerialDebugMode();
	dbbusDWIICStopMCU();
	dbbusDWIICIICUseBus();
	dbbusDWIICIICReshape();
	pr_ch("dbbusDWIICIICReshape\n");
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x08;
	dbbus_tx_data[2] = 0x0c;
	dbbus_tx_data[3] = 0x08;
	// Disable the Watchdog
	i2c_write_msg2133(dbbus_tx_data, 4);
	//Get_Chip_Version();
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x11;
	dbbus_tx_data[2] = 0xE2;
	dbbus_tx_data[3] = 0x00;
	i2c_write_msg2133(dbbus_tx_data, 4);
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x3C;
	dbbus_tx_data[2] = 0x60;
	dbbus_tx_data[3] = 0x55;
	i2c_write_msg2133(dbbus_tx_data, 4);
	pr_ch("update\n");
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x3C;
	dbbus_tx_data[2] = 0x61;
	dbbus_tx_data[3] = 0xAA;
	i2c_write_msg2133(dbbus_tx_data, 4);
	//Stop MCU
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x0F;
	dbbus_tx_data[2] = 0xE6;
	dbbus_tx_data[3] = 0x01;
	i2c_write_msg2133(dbbus_tx_data, 4);
	//Enable SPI Pad
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x1E;
	dbbus_tx_data[2] = 0x02;
	i2c_write_msg2133(dbbus_tx_data, 3);
	i2c_read_msg2133(&dbbus_rx_data[0], 2);
	pr_tp("dbbus_rx_data[0]=0x%x", dbbus_rx_data[0]);
	dbbus_tx_data[3] = (dbbus_rx_data[0] | 0x20);  //Set Bit 5
	i2c_write_msg2133(dbbus_tx_data, 4);
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x1E;
	dbbus_tx_data[2] = 0x25;
	i2c_write_msg2133(dbbus_tx_data, 3);
	dbbus_rx_data[0] = 0;
	dbbus_rx_data[1] = 0;
	i2c_read_msg2133(&dbbus_rx_data[0], 2);
	pr_tp("dbbus_rx_data[0]=0x%x", dbbus_rx_data[0]);
	dbbus_tx_data[3] = dbbus_rx_data[0] & 0xFC;  //Clear Bit 1,0
	i2c_write_msg2133(dbbus_tx_data, 4);
	/*
	//------------
	// ISP Speed Change to 400K
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x11;
	dbbus_tx_data[2] = 0xE2;
	i2c_write_msg2133( dbbus_tx_data, 3);
	i2c_read_msg2133( &dbbus_rx_data[3], 1);
	//pr_tp("dbbus_rx_data[0]=0x%x", dbbus_rx_data[0]);
	dbbus_tx_data[3] = dbbus_tx_data[3]&0xf7;  //Clear Bit3
	i2c_write_msg2133( dbbus_tx_data, 4);
	*/
	//WP overwrite
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x1E;
	dbbus_tx_data[2] = 0x0E;
	dbbus_tx_data[3] = 0x02;
	i2c_write_msg2133(dbbus_tx_data, 4);
	//set pin high
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x1E;
	dbbus_tx_data[2] = 0x10;
	dbbus_tx_data[3] = 0x08;
	i2c_write_msg2133(dbbus_tx_data, 4);
	dbbusDWIICIICNotUseBus();
	dbbusDWIICNotStopMCU();
	dbbusDWIICExitSerialDebugMode();
	///////////////////////////////////////
	// Start to load firmware
	///////////////////////////////////////
	drvISP_EntryIspMode();
	pr_ch("entryisp\n");
	drvISP_BlockErase(0x00000);
	//msleep(1000);
	pr_tp("FwVersion=2");

	for(i = 0; i < 59; i++)    // total  94 KB : 1 byte per R/W
	{

		pr_ch("drvISP_Program\n");
		if (download_firmware_buf == NULL)
			return 0;
		drvISP_Program(i,&download_firmware_buf[i*1024]);
		//pr_ch("drvISP_Verify\n");
		//drvISP_Verify ( i,&download_firmware_buf[i*1024] ); //verify data
	}

	pr_tp("update OK\n");
	drvISP_ExitIspMode();
	FwDataCnt = 0;
	if (download_firmware_buf != NULL)
	{
		kfree(download_firmware_buf);
		download_firmware_buf = NULL;
	}

	mt_set_gpio_mode(GPIO_CTP_MSG2133_EN_PIN, GPIO_CTP_MSG2133_EN_PIN_M_GPIO);
	mt_set_gpio_dir(GPIO_CTP_MSG2133_EN_PIN, GPIO_DIR_OUT);
	mt_set_gpio_out(GPIO_CTP_MSG2133_EN_PIN, GPIO_OUT_ZERO);
	msleep(100);
	mt_set_gpio_mode(GPIO_CTP_MSG2133_EN_PIN, GPIO_CTP_MSG2133_EN_PIN_M_GPIO);
	mt_set_gpio_dir(GPIO_CTP_MSG2133_EN_PIN, GPIO_DIR_OUT);
	mt_set_gpio_out(GPIO_CTP_MSG2133_EN_PIN, GPIO_OUT_ONE);
	msleep(500);
	update_switch = 0;
	return size;
}

static DEVICE_ATTR(update, 0777, firmware_update_show, firmware_update_store);

/*test=================*/
static ssize_t firmware_clear_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
	U16 k = 0, i = 0, j = 0;
	U8 bWriteData[5] =
	{
		0x10, 0x03, 0, 0, 0
	};
	U8 RX_data[256];
	U8 bWriteData1 = 0x12;
	U32 addr = 0;
	pr_ch("\n");

	for(k = 0; k < 94; i++)    // total  94 KB : 1 byte per R/W
	{
		addr = k * 1024;

		for(j = 0; j < 8; j++)    //128*8 cycle
		{
			bWriteData[2] = (U8)((addr + j * 128) >> 16);
			bWriteData[3] = (U8)((addr + j * 128) >> 8);
			bWriteData[4] = (U8)(addr + j * 128);

			while((drvISP_ReadStatus() & 0x01) == 0x01)
			{
				;    //wait until not in write operation
			}

			i2c_write_update_msg2133(bWriteData, 5);     //write read flash addr
			drvISP_Read(128, RX_data);
			i2c_write_update_msg2133(&bWriteData1, 1);    //cmd end

			for(i = 0; i < 128; i++)    //log out if verify error
			{
				if(RX_data[i] != 0xFF)
				{
					pr_tp("k=%d,j=%d,i=%d===============erase not clean================", k, j, i);
				}
			}
		}
	}

	pr_tp("read finish\n");
	return sprintf(buf, "%s\n", fw_version);
}

static ssize_t firmware_clear_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
	U8 dbbus_tx_data[4];
	unsigned char dbbus_rx_data[2] = {0};
	//msctpc_LoopDelay ( 100 );        // delay about 100ms*****
	// Enable slave's ISP ECO mode
	/*
	dbbusDWIICEnterSerialDebugMode();
	dbbusDWIICStopMCU();
	dbbusDWIICIICUseBus();
	dbbusDWIICIICReshape();*/

	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x08;
	dbbus_tx_data[2] = 0x0c;
	dbbus_tx_data[3] = 0x08;
	// Disable the Watchdog
	i2c_write_msg2133(dbbus_tx_data, 4);
	//Get_Chip_Version();
	//FwVersion  = 2;
	//if (FwVersion  == 2)
	{
		dbbus_tx_data[0] = 0x10;
		dbbus_tx_data[1] = 0x11;
		dbbus_tx_data[2] = 0xE2;
		dbbus_tx_data[3] = 0x00;
		i2c_write_msg2133(dbbus_tx_data, 4);
	}
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x3C;
	dbbus_tx_data[2] = 0x60;
	dbbus_tx_data[3] = 0x55;
	i2c_write_msg2133(dbbus_tx_data, 4);
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x3C;
	dbbus_tx_data[2] = 0x61;
	dbbus_tx_data[3] = 0xAA;
	i2c_write_msg2133(dbbus_tx_data, 4);
	//Stop MCU
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x0F;
	dbbus_tx_data[2] = 0xE6;
	dbbus_tx_data[3] = 0x01;
	i2c_write_msg2133(dbbus_tx_data, 4);
	//Enable SPI Pad
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x1E;
	dbbus_tx_data[2] = 0x02;
	i2c_write_msg2133(dbbus_tx_data, 3);
	i2c_read_msg2133(&dbbus_rx_data[0], 2);
	pr_tp("dbbus_rx_data[0]=0x%x", dbbus_rx_data[0]);
	dbbus_tx_data[3] = (dbbus_rx_data[0] | 0x20);  //Set Bit 5
	i2c_write_msg2133(dbbus_tx_data, 4);
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x1E;
	dbbus_tx_data[2] = 0x25;
	i2c_write_msg2133(dbbus_tx_data, 3);
	dbbus_rx_data[0] = 0;
	dbbus_rx_data[1] = 0;
	i2c_read_msg2133(&dbbus_rx_data[0], 2);
	pr_tp("dbbus_rx_data[0]=0x%x", dbbus_rx_data[0]);
	dbbus_tx_data[3] = dbbus_rx_data[0] & 0xFC;  //Clear Bit 1,0
	i2c_write_msg2133(dbbus_tx_data, 4);
	//WP overwrite
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x1E;
	dbbus_tx_data[2] = 0x0E;
	dbbus_tx_data[3] = 0x02;
	i2c_write_msg2133(dbbus_tx_data, 4);
	//set pin high
	dbbus_tx_data[0] = 0x10;
	dbbus_tx_data[1] = 0x1E;
	dbbus_tx_data[2] = 0x10;
	dbbus_tx_data[3] = 0x08;
	i2c_write_msg2133(dbbus_tx_data, 4);
	dbbusDWIICIICNotUseBus();
	dbbusDWIICNotStopMCU();
	dbbusDWIICExitSerialDebugMode();
	///////////////////////////////////////
	// Start to load firmware
	///////////////////////////////////////
	drvISP_EntryIspMode();
	pr_tp("chip erase+\n");
	drvISP_BlockErase(0x00000);
	pr_tp("chip erase-\n");
	drvISP_ExitIspMode();
	return size;
}

static DEVICE_ATTR(clear, 0777, firmware_clear_show, firmware_clear_store);

/*test=================*/
/*Add by Tracy.Lin for update touch panel firmware and get fw version*/

static ssize_t firmware_version_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
	pr_ch("*** firmware_version_show fw_version = %s***\n", fw_version);
	return sprintf(buf, "%s\n", fw_version);
}

static ssize_t firmware_version_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
	unsigned char dbbus_tx_data[3];
	unsigned char dbbus_rx_data[4] ;
	unsigned short major = 0, minor = 0;
	dbbusDWIICEnterSerialDebugMode();
	dbbusDWIICStopMCU();
	dbbusDWIICIICUseBus();
	dbbusDWIICIICReshape();
	fw_version = kzalloc(sizeof(char), GFP_KERNEL);
	pr_ch("\n");
	//Get_Chip_Version();
	dbbus_tx_data[0] = 0x53;
	dbbus_tx_data[1] = 0x00;
	dbbus_tx_data[2] = 0x74;
	i2c_write(TOUCH_ADDR_MSG21XX, &dbbus_tx_data[0], 3);
	i2c_read(TOUCH_ADDR_MSG21XX, &dbbus_rx_data[0], 4);
	major = (dbbus_rx_data[1] << 8) + dbbus_rx_data[0];
	minor = (dbbus_rx_data[3] << 8) + dbbus_rx_data[2];
	pr_tp("***major = %d ***\n", major);
	pr_tp("***minor = %d ***\n", minor);
	sprintf(fw_version, "%03d%03d", major, minor);
	pr_tp("***fw_version = %s ***\n", fw_version);
	return size;
}
static DEVICE_ATTR(version, 0777, firmware_version_show, firmware_version_store);

static ssize_t firmware_data_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
	return FwDataCnt;
}

static ssize_t firmware_data_store(struct device *dev,
struct device_attribute *attr, const char *buf, size_t size)
{
	pr_ch("***FwDataCnt = %d ***\n", FwDataCnt);
	if (download_firmware_buf == NULL) {
		download_firmware_buf = kzalloc(DOWNLOAD_FIRMWARE_BUF_SIZE, GFP_KERNEL);
		if (download_firmware_buf == NULL)
			return NULL;
	}
	if(FwDataCnt<59)
	{
		memcpy(&download_firmware_buf[FwDataCnt*1024], buf, 1024);
	}
	FwDataCnt++;
	return size;
}
static DEVICE_ATTR(data, 0777, firmware_data_show, firmware_data_store);
#endif

#ifdef TP_PROXIMITY_SENSOR
static ssize_t show_proximity_sensor(struct device *dev, struct device_attribute *attr, char *buf)
{
	static char temp=2;
	buf = ps_data_state;
	if(temp!=*buf)
	{
		printk("proximity_sensor_show: buf=%d\n\n", *buf);
		temp=*buf;
	}    return 1;
}

static ssize_t store_proximity_sensor(struct device *dev, struct device_attribute *attr, const char *buf, size_t size)
{
	U8 ps_store_data[4];

	if(buf != NULL && size != 0)
	{
		if(DISABLE_CTP_PS == *buf)
		{
			printk("DISABLE_CTP_PS buf=%d,size=%d\n", *buf, size);
			ps_store_data[0] = 0x52;
			ps_store_data[1] = 0x00;
			ps_store_data[2] = 0x62;
			ps_store_data[3] = 0xa1;
			i2c_write(TOUCH_ADDR_MSG21XX, &ps_store_data[0], 4);
			msleep(2000);
			printk("RESET_CTP_PS buf=%d\n", *buf);
			mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM);
			mt_set_gpio_mode(GPIO_CTP_MSG2133_EN_PIN, GPIO_CTP_MSG2133_EN_PIN_M_GPIO);
			mt_set_gpio_dir(GPIO_CTP_MSG2133_EN_PIN, GPIO_DIR_OUT);
			mt_set_gpio_out(GPIO_CTP_MSG2133_EN_PIN, GPIO_OUT_ZERO);
			msleep(100);
			mt_set_gpio_mode(GPIO_CTP_MSG2133_EN_PIN, GPIO_CTP_MSG2133_EN_PIN_M_GPIO);
			mt_set_gpio_dir(GPIO_CTP_MSG2133_EN_PIN, GPIO_DIR_OUT);
			mt_set_gpio_out(GPIO_CTP_MSG2133_EN_PIN, GPIO_OUT_ONE);
			mdelay(500);
			mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);
		}
		else if(ENABLE_CTP_PS == *buf)
		{
			printk("ENABLE_CTP_PS buf=%d,size=%d\n", *buf, size);
			ps_store_data[0] = 0x52;
			ps_store_data[1] = 0x00;
			ps_store_data[2] = 0x62;
			ps_store_data[3] = 0xa0;
			i2c_write(TOUCH_ADDR_MSG21XX, &ps_store_data[0], 4);
		}
	}

	return size;
}
static DEVICE_ATTR(proximity_sensor, 0777, show_proximity_sensor, store_proximity_sensor);
#endif

static struct i2c_driver tpd_i2c_driver =
{
	.driver = {
        .name = "msg2133",
		.owner = THIS_MODULE,
	},
	.probe = tpd_probe,
	.remove = __devexit_p(tpd_remove),
	.id_table = tpd_id,
	.detect = tpd_detect,
	.address_data = &addr_data,
};


static void tpd_down(int x, int y, int p)
{
	input_report_abs(tpd->dev, ABS_PRESSURE, p);
	input_report_key(tpd->dev, BTN_TOUCH, 1);
	input_report_abs(tpd->dev, ABS_MT_TOUCH_MAJOR, p);
	input_report_abs(tpd->dev, ABS_MT_POSITION_X, x);
	input_report_abs(tpd->dev, ABS_MT_POSITION_Y, y);
	printk("[MSG2133]######tpd_down[%4d %4d %4d] ", x, y, p);
	input_mt_sync(tpd->dev);
	TPD_DOWN_DEBUG_TRACK(x,y);
}

static  int tpd_up(int x, int y)
{
	#ifdef TPD_HAVE_BUTTON
	if (y > TPD_BUTTON_HEIGHT)
	{
		tpd_button(x, y,0);
		return;
	}
	#endif
	input_mt_sync(tpd->dev);
	input_sync(tpd->dev);
	TPD_DOWN_DEBUG_TRACK(x, y);
	return 1;
}
unsigned char tpd_check_sum(unsigned char *pval)
{
	int i, sum = 0;

	for(i = 0; i < 7; i++)
	{
		sum += pval[i];
	}

	return (unsigned char)((-sum) & 0xFF);
}

static bool msg2133_i2c_read(char *pbt_buf, int dw_lenth)
{
	int ret;
	i2c_client->timing = 100;
	i2c_client->addr|=I2C_ENEXT_FLAG;
	ret = i2c_master_recv(i2c_client, pbt_buf, dw_lenth);

	if(ret <= 0)
	{
		pr_tp("msg_i2c_read_interface error\n");
		return false;
	}

	return true;
}

static int i2c_master_recv_ext(struct i2c_client *client, char *buf ,int count)
{
    u32 phyAddr = 0; 
    u8  buf_dma[8] = {0};
    u32 old_addr = 0; 
    int ret = 0; 
    int retry = 3; 
    int i = 0; 
   // u8  *buf_test ;
//	buf_test = &buf_dma[0];

    old_addr = client->addr; 
    client->addr |= I2C_ENEXT_FLAG ;
	
	printk("[MSG2133][i2c_master_recv_ext] client->addr = %x\n", client->addr); 

    do {
        ret = i2c_master_recv(client, buf_dma, count);   
        retry --; 
        if (ret != count) {
            printk("[MSG2133][i2c_master_recv_ext] Error sent I2C ret = %d\n", ret); 
        }
    }while ((ret != count) && (retry > 0)); 
    
    memcpy(buf, buf_dma, count); 
	
    client->addr = old_addr; 

    return ret; 
}

static int tpd_touchinfo(struct TouchInfoT *cinfo, struct TouchInfoT *pinfo)
{
	u32 retval;
    u8 key;
    u8 touchData = 0;
	
	//pinfo->count = cinfo->count;
    memcpy(pinfo, cinfo, sizeof(struct TouchInfoT));
    
    //add for sure addr correct
    //i2c_client->addr = 0x4c;
    retval = i2c_master_recv_ext(i2c_client, (u8 *)&TpdTouchData, sizeof(TpdTouchData));

	if(TpdTouchData.packet_id != 0x52 )
       {
		return 0;
       }
	/*touch*/
	if(TpdTouchData.packet_id == 0x52)
	{
	
		if(TpdTouchData.x_h_y_h == 0xFF 
			&& TpdTouchData.x_l == 0xFF 
			&& TpdTouchData.y_l == 0xFF 
			&& TpdTouchData.disx_h_disy_h == 0xFF 
          )
        {
#ifdef TPD_HAVE_BUTTON
		 {
			U8 *p = &TpdTouchData;
			cinfo->key_value = 0;
			cinfo->key_value = *(p+5);			
			printk("+++++++zym+++++++TPD_HAVE_BUTTON:(%d)\n",cinfo->key_value);
			{
				//tpd_button_msg213x(cinfo->key_value);
				//tpd_button(0,0,cinfo->key_value);
				if(cinfo->key_value == 1)
				{
#ifdef HQ_A25_NANBO_CTP_MSG2133_KEY
                             touchData = KEY_BACK;  
#else  
                             touchData = KEY_MENU;
#endif
				}
				else if(cinfo->key_value == 2)
				{
#ifdef HQ_CTP_MSG21XX_REVERT
					touchData = KEY_BACK;
#elif defined(HQ_A25_NANBO_CTP_MSG2133_KEY)
                                        touchData = KEY_MENU;
#elif defined(HQ_A25P_MUDONG_CTP_MSG2133_KEY)
                                         touchData = KEY_BACK;
#else
					touchData = KEY_HOME;
#endif
				}
				else if(cinfo->key_value == 4)
				{
					touchData = KEY_BACK;
				}
				else if(cinfo->key_value == 8)
				{
					touchData = KEY_SEARCH;
				}
				else
				{
					touchData = 0;
				}
				TPD_LOGV("[MSG2133]+++++++zym+++++++:(%d)\n",touchData);
				if(touchData)
					input_report_key(tpd->dev,touchData,1);
				else
				{
					input_report_key(tpd->dev,KEY_MENU,0);
					input_report_key(tpd->dev,KEY_HOME,0);
					input_report_key(tpd->dev,KEY_BACK,0);
					input_report_key(tpd->dev,KEY_SEARCH,0);
				}
			}
		 }
#endif
			cinfo->count = 0;
        }
		else if(TpdTouchData.disx_h_disy_h == 0
			&& TpdTouchData.disx_l == 0 
			&& TpdTouchData.disy_l == 0)
			cinfo->count = 1;
		else
			cinfo->count = 2;
		
		TPD_LOGV("[MSG2133]cinfo: count=%d\n",cinfo->count);
		if(cinfo->count > 0)
		{
			int tmp_x,tmp_y;
			/*point1*/
			cinfo->x1 = (((TpdTouchData.x_h_y_h&0xF0)<<4) | (TpdTouchData.x_l));
			cinfo->y1 = (((TpdTouchData.x_h_y_h&0x0F)<<8) | (TpdTouchData.y_l));
			TPD_LOGV("[MSG2133]+++zym+++(%3d,%3d)\n",cinfo->x1,cinfo->y1);

			if(cinfo->count >1)
			{	
				/*point2*/
				short disx,disy;
	
				disx = (((TpdTouchData.disx_h_disy_h&0xF0)<<4) | (TpdTouchData.disx_l));
				disy = (((TpdTouchData.disx_h_disy_h&0x0F)<<8) | (TpdTouchData.disy_l));
				disy = (disy<<4);
				disy = disy/16;
				if(disx >= 2048)
					disx -= 4096;
				if(disy >= 2048)
					disy -= 4096;
				cinfo->x2 = cinfo->x1 + disx;
				cinfo->y2 = cinfo->y1 + disy;				

				tmp_x = cinfo->x2;
				tmp_y = cinfo->y2;
				cinfo->y2 = tmp_x * (TPD_RES_Y - 1)/ 2047;
				cinfo->x2 = tmp_y * (TPD_RES_X - 1) / 2047;		
			}
			tmp_x = cinfo->x1;
			tmp_y = cinfo->y1;
			cinfo->y1 = tmp_x * (TPD_RES_Y - 1) / 2047;
			cinfo->x1 = tmp_y * (TPD_RES_X - 1) / 2047;
			
			//add by zym 2012-04-16
			#ifdef HQ_CTP_MSG21XX_REVERT
			#else
			cinfo->x1 = TPD_RES_X -1 - cinfo->x1;
			cinfo->x2 = TPD_RES_X - 1 -cinfo->x2;
			#endif
			TPD_LOGV("[MSG2133]++++++++zym+++++++++p1: (%3d,%3d)(%3d,%3d)\n",cinfo->x1,cinfo->y1,TPD_RES_X,TPD_RES_Y);
	        cinfo->pressure = 1;
	        TPD_LOGV("[MSG2133]pressure: %d\n",cinfo->pressure);
		}
	}
	else
	{
		cinfo->count = 0;
	}

    /*ergate-012 start*/
    /*ergate-012 end*/

	return 1;
}



static int touch_event_handler(void *unused)
{

	int pending = 0;
	struct TouchInfoT cinfo, pinfo;
	struct sched_param param = { .sched_priority = RTPM_PRIO_TPD };
	sched_setscheduler(current, SCHED_RR, ¶m);

    memset(&cinfo, 0, sizeof(struct TouchInfoT));
    memset(&pinfo, 0, sizeof(struct TouchInfoT));
	do
	{
	
		set_current_state(TASK_INTERRUPTIBLE); 
		if(!kthread_should_stop())
		{
			TPD_DEBUG_CHECK_NO_RESPONSE;
			do
			{
				if (pending) 
					wait_event_interruptible_timeout(waiter, tpd_flag != 0, HZ/10);
				else 
					wait_event_interruptible_timeout(waiter,tpd_flag != 0, HZ*2);
				 
			}while(0);
			 
			if (tpd_flag == 0 && !pending) 
				continue; // if timeout for no touch, then re-wait.
			 
			if (tpd_flag != 0 && pending > 0)	
				pending = 0;
			 
			tpd_flag = 0;
			TPD_DEBUG_SET_TIME; 
		}
		set_current_state(TASK_RUNNING);

		if (tpd_touchinfo(&cinfo, &pinfo))
		{
			if(cinfo.count >0)
			{
				tpd_down(cinfo.x1, cinfo.y1, cinfo.pressure);
				if(cinfo.count>1)
             	{            	
					tpd_down(cinfo.x2, cinfo.y2, cinfo.pressure);
				}
				input_sync(tpd->dev);		
				TPD_LOGV("[MSG2133]press  --->\n");
			}
			else if(cinfo.count==0 && pinfo.count!=0)
			{		
     
			    input_mt_sync(tpd->dev);
			    input_sync(tpd->dev);
		
				TPD_LOGV("[MSG2133]release --->\n"); 
			}
		}		   
	}while(!kthread_should_stop());

	return 0;

}

static int tpd_detect(struct i2c_client *client, int kind, struct i2c_board_info *info)
{
	strcpy(info->type, "msg2133");
	return 0;
}

static void tpd_eint_interrupt_handler(void)
{
	tpd_flag = 1;
	wake_up_interruptible(&waiter);
}

static int __devinit tpd_probe(struct i2c_client *client, const struct i2c_device_id *id)
{
	int retval = TPD_OK;
	client->timing = 100;
	i2c_client = client;
	msleep(10);
	hwPowerOn(MT65XX_POWER_LDO_VGP2, VOL_2800, "TP");
	mt_set_gpio_mode(GPIO_CTP_MSG2133_EN_PIN, GPIO_CTP_MSG2133_EN_PIN_M_GPIO);
	mt_set_gpio_dir(GPIO_CTP_MSG2133_EN_PIN, GPIO_DIR_OUT);
	mt_set_gpio_out(GPIO_CTP_MSG2133_EN_PIN, GPIO_OUT_ONE);

    msleep(100);
	mt_set_gpio_mode(GPIO_CTP_MSG2133_EINT_PIN, GPIO_CTP_MSG2133_EINT_PIN_M_GPIO);
	mt_set_gpio_dir(GPIO_CTP_MSG2133_EINT_PIN, GPIO_DIR_IN);
	mt_set_gpio_pull_enable(GPIO_CTP_MSG2133_EINT_PIN, GPIO_PULL_ENABLE);
	mt_set_gpio_pull_select(GPIO_CTP_MSG2133_EINT_PIN, GPIO_PULL_UP);


	mt65xx_eint_set_sens(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_SENSITIVE);
	mt65xx_eint_set_hw_debounce(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_CN);
	mt65xx_eint_registration(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_EN, CUST_EINT_TOUCH_PANEL_POLARITY, tpd_eint_interrupt_handler, 1);
	mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);
	msleep(100);
	tpd_load_status = 1;
	mthread = kthread_run(touch_event_handler, 0, "msg2133");

	if(IS_ERR(mthread))
	{
		retval = PTR_ERR(mthread);
		pr_tp(TPD_DEVICE " failed to create kernel thread: %d\n", retval);
	}
#ifdef TP_FIRMWARE_UPDATE
#if ENABLE_DMA
	gpDMABuf_va = (u8 *)dma_alloc_coherent(NULL, 4096, &gpDMABuf_pa, GFP_KERNEL);

	if(!gpDMABuf_va)
	{
		printk("[MATV][Error] Allocate DMA I2C Buffer failed!\n");
	}

#endif
    firmware_class = class_create(THIS_MODULE, "ms-touchscreen-msg20xx");

	if(IS_ERR(firmware_class))
	{
		pr_err("Failed to create class(firmware)!\n");
	}

	firmware_cmd_dev = device_create(firmware_class,NULL, 0, NULL, "device");

	if(IS_ERR(firmware_cmd_dev))
	{
		pr_err("Failed to create device(firmware_cmd_dev)!\n");
	}

	// version
	if(device_create_file(firmware_cmd_dev, &dev_attr_version) < 0)
	{
		pr_err("Failed to create device file(%s)!\n", dev_attr_version.attr.name);
	}

	// update
	if(device_create_file(firmware_cmd_dev, &dev_attr_update) < 0)
	{
		pr_err("Failed to create device file(%s)!\n", dev_attr_update.attr.name);
	}

	// data
	if(device_create_file(firmware_cmd_dev, &dev_attr_data) < 0)
	{
		pr_err("Failed to create device file(%s)!\n", dev_attr_data.attr.name);
	}

	if(device_create_file(firmware_cmd_dev, &dev_attr_clear) < 0)
	{
		pr_err("Failed to create device file(%s)!\n", dev_attr_clear.attr.name);
	}

#endif
#ifdef TP_PROXIMITY_SENSOR

	if(device_create_file(firmware_cmd_dev, &dev_attr_proximity_sensor) < 0) // /sys/class/mtk-tpd/device/proximity_sensor
	{
		pr_err("Failed to create device file(%s)!\n", dev_attr_proximity_sensor.attr.name);
	}
#endif
	printk("Touch Panel Device Probe %s\n", (retval < TPD_OK) ? "FAIL" : "PASS");
	return 0;
}

static int __devexit tpd_remove(struct i2c_client *client)

{
	printk("TPD removed\n");
#ifdef TP_FIRMWARE_UPDATE
#if ENABLE_DMA

	if(gpDMABuf_va)
	{
		dma_free_coherent(NULL, 4096, gpDMABuf_va, gpDMABuf_pa);
		gpDMABuf_va = NULL;
		gpDMABuf_pa = NULL;
	}

#endif
#endif
	return 0;
}


static int tpd_local_init(void)
{
	printk(" MSG2133 I2C Touchscreen Driver (Built %s @ %s)\n", __DATE__, __TIME__);

	if(i2c_add_driver(&tpd_i2c_driver) != 0)
	{
		printk("unable to add i2c driver.\n");
		return -1;
	}

#ifdef TPD_HAVE_BUTTON
	tpd_button_setting(TPD_KEY_COUNT, tpd_keys_local, tpd_keys_dim_local);// initialize tpd button data
#endif
	pr_tp("end %s, %d\n", __FUNCTION__, __LINE__);
	tpd_type_cap = 1;
	return 0;
}

static int tpd_resume(struct i2c_client *client)
{
	int retval = TPD_OK;
	printk("TPD wake up\n");

	 hwPowerOn(MT65XX_POWER_LDO_VGP2, VOL_2800, "TP");
	 msleep(10);
	mt_set_gpio_mode(GPIO_CTP_MSG2133_EN_PIN, GPIO_CTP_MSG2133_EN_PIN_M_GPIO);
	mt_set_gpio_dir(GPIO_CTP_MSG2133_EN_PIN, GPIO_DIR_OUT);
	mt_set_gpio_out(GPIO_CTP_MSG2133_EN_PIN, GPIO_OUT_ONE);

	msleep(200);
	mt65xx_eint_unmask(CUST_EINT_TOUCH_PANEL_NUM);
	mt65xx_eint_registration(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_EN, CUST_EINT_TOUCH_PANEL_POLARITY, tpd_eint_interrupt_handler, 1);

	return retval;
}

static int tpd_suspend(struct i2c_client *client, pm_message_t message)
{
	int retval = TPD_OK;
	static char data = 0x3;
	printk("TPD enter sleep\n");

	{
		mt65xx_eint_mask(CUST_EINT_TOUCH_PANEL_NUM);
		mt65xx_eint_registration(CUST_EINT_TOUCH_PANEL_NUM, CUST_EINT_TOUCH_PANEL_DEBOUNCE_EN, CUST_EINT_TOUCH_PANEL_POLARITY, NULL, 1);


		mt_set_gpio_mode(GPIO_CTP_MSG2133_EN_PIN, GPIO_CTP_MSG2133_EN_PIN_M_GPIO);
		mt_set_gpio_dir(GPIO_CTP_MSG2133_EN_PIN, GPIO_DIR_OUT);
		mt_set_gpio_out(GPIO_CTP_MSG2133_EN_PIN, GPIO_OUT_ZERO);
	
		hwPowerDown(MT65XX_POWER_LDO_VGP2, "TP");
	
	}
	return retval;
}

int tpd_power_switch( int flag )
{
	return 0;
}

EXPORT_SYMBOL( tpd_power_switch );

static struct tpd_driver_t tpd_device_driver =
{
	.tpd_device_name = "msg2133",
	.tpd_local_init = tpd_local_init,
	.suspend = tpd_suspend,
	.resume = tpd_resume,
#ifdef TPD_HAVE_BUTTON
	.tpd_have_button = 1,
#else
	.tpd_have_button = 0,
#endif
};
/* called when loaded into kernel */
static int __init tpd_driver_init(void)
{
	printk("MediaTek MSG2133 touch panel driver init\n");
	if(tpd_driver_add(&tpd_device_driver) < 0)
	{
		printk("add MSG2133 driver failed\n");
	}

	return 0;
}

/* should never be called */
static void __exit tpd_driver_exit(void)
{
	printk("MediaTek MSG2133 touch panel driver exit\n");
	//input_unregister_device(tpd->dev);
	tpd_driver_remove(&tpd_device_driver);
}

module_init(tpd_driver_init);
module_exit(tpd_driver_exit);


Tpd_custom_msg2133.h:

#ifndef TOUCHPANEL_H
#define TOUCHPANEL_H

#define TPD_RES_X                320
#define TPD_RES_Y                480

#define TPD_HAVE_BUTTON


#define TPD_BUTTON_HEIGHT	480
#define TPD_KEY_COUNT           3
#define TPD_KEYS                {KEY_MENU, KEY_HOME, KEY_BACK}
#define TPD_KEYS_DIM            {{40,505,80,50},{120,505,80,50},{200,505,80,50}}

#endif



你可能感兴趣的:(c,android,struct,download,button,MTK)