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