/* * Driver for Pixcir I2C touchscreen controllers. * * Copyright (C) 2010-2011 Pixcir, Inc. * * pixcir_i2c_ts.c V3.ss0 from v3.0 support TangoC solution and remove the previous soltutions * * pixcir_i2c_ts.c V3.1 Add bootloader function 7 * Add RESET_TP 9 * Add ENABLE_IRQ 10 * Add DISABLE_IRQ 11 * Add BOOTLOADER_STU 16 * Add ATTB_VALUE 17 * Add Write/Read Interface for APP software * * pixcir_i2c_ts.c V3.2.0A for INT_MODE 0x0A * arrange to pixcir 10 slot * * 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. * * You should have received a copy of the GNU General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #ifdef CONFIG_HAS_EARLYSUSPEND #include #endif #if defined(CONFIG_I2C_SPRD) || defined(CONFIG_I2C_SPRD_V1) #include #endif #include #include #include /*********************************Bee-0928-TOP****************************************/ //#define SYSFS_DEBUG //cg,20130929 //#define PIXCIR_DEBUG //#define PIXCIR_CQ_CALL 0 #ifdef PIXCIR_DEBUG #define PIXCIR_DBG(format, ...) \ printk(KERN_INFO "PIXCIR_TS " format "\n", ## __VA_ARGS__) #define TPD_DEBUG(format, ...) \ printk(KERN_INFO "PIXCIR_TS " format "\n", ## __VA_ARGS__) #else #define PIXCIR_DBG(format, ...) #define TPD_DEBUG(format, ...) #endif #define USE_WAIT_QUEUE 1 #define USE_THREADED_IRQ 0 #define USE_WORK_QUEUE 0 #define TOUCH_VIRTUAL_KEYS //#define TP_X_CHANGE #define TP_XY_CHANGE 0 #define SLAVE_ADDR 0x48 #define BOOTLOADER_ADDR 0x5d #ifndef I2C_MAJOR #define I2C_MAJOR 125 #endif #define I2C_MINORS 256 #define CALIBRATION_FLAG 1 #define BOOTLOADER 7 #define RESET_TP 9 #define ENABLE_IRQ 10 #define DISABLE_IRQ 11 #define BOOTLOADER_STU 16 #define ATTB_VALUE 17 #define MAX_FINGER_NUM 5 #define X_OFFSET 30 #define Y_OFFSET 40 #define TPD_OK 0 #define TPD_REG_BASE 0x00 #define TPD_SOFT_RESET_MODE 0x01 #define TPD_OP_MODE 0x00 #define TPD_LOW_PWR_MODE 0x04 #define TPD_SYSINFO_MODE 0x10 #define GET_HSTMODE(reg) ((reg & 0x70) >> 4) // in op mode or not #define GET_BOOTLOADERMODE(reg) ((reg & 0x10) >> 4) // in bl mode //#define __FIRMWARE_UPDATE__ #define REG_RT_PRIO(x) ((x) | 0x10000000) #define RTPM_PRIO_TPD REG_RT_PRIO(4) #if USE_WAIT_QUEUE static struct task_struct *thread = NULL; static DECLARE_WAIT_QUEUE_HEAD(waiter); static int tpd_flag = 0; #endif struct pixcir_i2c_ts_data { struct i2c_client *client; struct input_dev *input; #if USE_WORK_QUEUE struct work_struct pen_event_work; struct workqueue_struct *ts_workqueue; #endif #ifdef CONFIG_HAS_EARLYSUSPEND struct work_struct resume_work; struct workqueue_struct *ts_resume_workqueue; struct early_suspend early_suspend; #endif struct msg2138_ts_platform_data *platform_data; //const struct pixcir_ts_platform_data *chip; bool exiting; }; static unsigned char bl_cmd[] = { 0x00, 0xFF, 0xA5, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07 }; //exit bl mode struct tpd_operation_data_t { unsigned char hst_mode; unsigned char tt_mode; unsigned char tt_stat; unsigned char x1_M,x1_L; unsigned char y1_M,y1_L; unsigned char z1; unsigned char evnt_id; unsigned char x2_M,x2_L; unsigned char y2_M,y2_L; unsigned char r_0d; unsigned char gest_cnt; unsigned char gest_id; }; struct tpd_bootloader_data_t { unsigned char bl_file; unsigned char bl_status; unsigned char bl_error; unsigned char blver_hi,blver_lo; unsigned char bld_blver_hi,bld_blver_lo; unsigned char ttspver_hi,ttspver_lo; unsigned char appid_hi,appid_lo; unsigned char appver_hi,appver_lo; unsigned char cid_0; unsigned char cid_1; unsigned char cid_2; }; struct tpd_sysinfo_data_t { unsigned char hst_mode; unsigned char mfg_cmd; unsigned char mfg_stat; unsigned char cid[3]; unsigned char tt_undef1; unsigned char uid[8]; unsigned char bl_verh; unsigned char bl_verl; unsigned char tts_verh; unsigned char tts_verl; unsigned char app_idh; unsigned char app_idl; unsigned char app_verh; unsigned char app_verl; unsigned char tt_undef2[6]; unsigned char act_intrvl; unsigned char tch_tmout; unsigned char lp_intrvl; }; struct touch_info { int x1, y1; int x2, y2; int x3, y3; int p1, p2,p3; int count; }; struct i2c_dev { struct list_head list; struct i2c_adapter *adap; struct device *dev; }; static struct i2c_client * msg21xx_i2c_client; static struct pixcir_i2c_ts_data *msg21xx_i2c_ts_data; //static unsigned char status_reg = 0; static int global_irq; static struct i2c_driver pixcir_i2c_ts_driver; static struct class *i2c_dev_class; static int MS_TS_MSG21XX_X_MAX = 0; static int MS_TS_MSG21XX_Y_MAX = 0; static LIST_HEAD( i2c_dev_list); static DEFINE_SPINLOCK( i2c_dev_list_lock); static int suspend_flag; static struct early_suspend pixcir_early_suspend; static ssize_t pixcir_set_calibrate(struct device* cd, struct device_attribute *attr, const char* buf, size_t len); static ssize_t pixcir_show_suspend(struct device* cd,struct device_attribute *attr, char* buf); static ssize_t pixcir_store_suspend(struct device* cd, struct device_attribute *attr,const char* buf, size_t len); static void pixcir_ts_suspend(struct early_suspend *handler); static void pixcir_ts_resume(struct early_suspend *handler); //static struct tpd_operation_data_t g_operation_data; static struct tpd_bootloader_data_t g_bootloader_data; static struct tpd_sysinfo_data_t g_sysinfo_data; #ifdef SYSFS_DEBUG static char *cg_fw_version = NULL; #endif //cg,20130929 #define CTP_ID_MSG21XX 1 #define CTP_ID_MSG21XXA 2 #define FW_ADDR_MSG21XX (0xC4>>1) static int HalTscrCReadI2CSeq(u8 addr, u8* read_data, u16 size) { //according to your platform. int rc; struct i2c_msg msgs[] = { { .addr = addr, .flags = I2C_M_RD, .len = size, .buf = read_data, }, }; rc = i2c_transfer(msg21xx_i2c_client->adapter, msgs, 1); if( rc < 0 ) { printk("HalTscrCReadI2CSeq error %d\n", rc); } return rc; } static int HalTscrCDevWriteI2CSeq(u8 addr, u8* data, u16 size) { //according to your platform. int rc; struct i2c_msg msgs[] = { { .addr = addr, .flags = 0, .len = size, .buf = data, }, }; rc = i2c_transfer(msg21xx_i2c_client->adapter, msgs, 1); if( rc < 0 ) { printk("HalTscrCDevWriteI2CSeq error %d,addr = %d\n", rc,addr); } return rc; } #ifdef __FIRMWARE_UPDATE__ #define FW_ADDR_MSG21XX_TP (0x4C>>1) #define FW_UPDATE_ADDR_MSG21XX (0x92>>1) #define TP_DEBUG printk//(x) //x// #define DBUG printk//(x) //x static char *fw_version = NULL; static u8 temp[94][1024]; u8 Fmr_Loader[1024]; u32 crc_tab[256]; static u8 g_dwiic_info_data[1024]; // Buffer for info data static int FwDataCnt; struct class *firmware_class; struct device *firmware_cmd_dev; static 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; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, data, 5); } static void dbbusDWIICStopMCU(void) { u8 data[1]; // Stop the MCU data[0] = 0x37; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, data, 1); } static void dbbusDWIICIICUseBus(void) { u8 data[1]; // IIC Use Bus data[0] = 0x35; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, data, 1); } static void dbbusDWIICIICReshape(void) { u8 data[1]; // IIC Re-shape data[0] = 0x71; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, data, 1); } static void dbbusDWIICIICNotUseBus(void) { u8 data[1]; // IIC Not Use Bus data[0] = 0x34; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, data, 1); } static void dbbusDWIICNotStopMCU(void) { u8 data[1]; // Not Stop the MCU data[0] = 0x36; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, data, 1); } static void dbbusDWIICExitSerialDebugMode(void) { u8 data[1]; // Exit the Serial Debug Mode data[0] = 0x45; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, data, 1); // Delay some interval to guard the next transaction udelay ( 150);//200 ); // delay about 0.2ms } static void drvISP_EntryIspMode(void) { u8 bWriteData[5] = { 0x4D, 0x53, 0x54, 0x41, 0x52 }; printk("\n******%s come in*******\n",__FUNCTION__); HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, bWriteData, 5); udelay ( 150 );//200 ); // delay about 0.1ms } static 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; unsigned char dbbus_rx_data[2] = {0}; HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, &Read_cmd, 1); //msctpc_LoopDelay ( 1 ); // delay about 100us***** udelay( 800 );//200); if (n == 1) { HalTscrCReadI2CSeq(FW_UPDATE_ADDR_MSG21XX, &dbbus_rx_data[0], 2); *pDataToRead = dbbus_rx_data[0]; TP_DEBUG("dbbus=%d,%d===drvISP_Read=====\n",dbbus_rx_data[0],dbbus_rx_data[1]); } else { HalTscrCReadI2CSeq(FW_UPDATE_ADDR_MSG21XX, pDataToRead, n); } return 0; } static void drvISP_WriteEnable(void) { u8 bWriteData[2] = { 0x10, 0x06 }; u8 bWriteData1 = 0x12; HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, bWriteData, 2); udelay(150);//1.16 HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, &bWriteData1, 1); } static void drvISP_ExitIspMode(void) { u8 bWriteData = 0x24; HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, &bWriteData, 1); udelay( 150 );//200); } static u8 drvISP_ReadStatus(void) { u8 bReadData = 0; u8 bWriteData[2] = { 0x10, 0x05 }; u8 bWriteData1 = 0x12; HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, bWriteData, 2); //msctpc_LoopDelay ( 1 ); // delay about 100us***** udelay(150);//200); drvISP_Read(1, &bReadData); HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, &bWriteData1, 1); return bReadData; } static void drvISP_BlockErase(u32 addr) { u8 bWriteData[5] = { 0x00, 0x00, 0x00, 0x00, 0x00 }; u8 bWriteData1 = 0x12; printk("\n******%s come in*******\n",__FUNCTION__); u32 timeOutCount=0; drvISP_WriteEnable(); //Enable write status register bWriteData[0] = 0x10; bWriteData[1] = 0x50; HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, bWriteData, 2); HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, &bWriteData1, 1); //Write Status bWriteData[0] = 0x10; bWriteData[1] = 0x01; bWriteData[2] = 0x00; HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, bWriteData, 3); HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, &bWriteData1, 1); //Write disable bWriteData[0] = 0x10; bWriteData[1] = 0x04; HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, bWriteData, 2); HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, &bWriteData1, 1); //msctpc_LoopDelay ( 1 ); // delay about 100us***** udelay(150);//200); timeOutCount=0; while ( ( drvISP_ReadStatus() & 0x01 ) == 0x01 ) { timeOutCount++; if ( timeOutCount >= 100000 ) break; /* around 1 sec timeout */ } drvISP_WriteEnable(); bWriteData[0] = 0x10; bWriteData[1] = 0xC7;//0xD8; //Block Erase //bWriteData[2] = ((addr >> 16) & 0xFF) ; //bWriteData[3] = ((addr >> 8) & 0xFF) ; //bWriteData[4] = (addr & 0xFF) ; HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, bWriteData, 2); //HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, &bWriteData, 5); HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, &bWriteData1, 1); //msctpc_LoopDelay ( 1 ); // delay about 100us***** udelay(150);//200); timeOutCount=0; while ( ( drvISP_ReadStatus() & 0x01 ) == 0x01 ) { timeOutCount++; if ( timeOutCount >= 500000 ) break; /* around 5 sec timeout */ } } static 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; u32 timeOutCount=0; 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]; } //msctpc_LoopDelay ( 1 ); // delay about 100us***** udelay(150);//200); timeOutCount=0; while ( ( drvISP_ReadStatus() & 0x01 ) == 0x01 ) { timeOutCount++; if ( timeOutCount >= 100000 ) break; /* around 1 sec timeout */ } drvISP_WriteEnable(); HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, TX_data, 133); //write 133 byte per cycle HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, &bWriteData1, 1); } } static ssize_t firmware_update_show ( struct device *dev, struct device_attribute *attr, char *buf ) { return sprintf ( buf, "%s\n", fw_version ); } /*reset the chip*/ static void _HalTscrHWReset(void) { struct msg2138_ts_platform_data *pdata = msg21xx_i2c_ts_data->platform_data; gpio_direction_output(pdata->reset_gpio_number, 1); gpio_set_value(pdata->reset_gpio_number, 1); gpio_set_value(pdata->reset_gpio_number, 0); mdelay(10); /* Note that the RST must be in LOW 10ms at least */ gpio_set_value(pdata->reset_gpio_number, 1); /* Enable the interrupt service thread/routine for INT after 50ms */ mdelay(50); } static void drvISP_Verify ( u16 k, u8* pDataToVerify ) { u16 i = 0, j = 0; u8 bWriteData[5] ={ 0x10, 0x03, 0, 0, 0 }; u8 RX_data[256]; u8 bWriteData1 = 0x12; u32 addr = k * 1024; u8 index = 0; u32 timeOutCount; 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 ); udelay ( 100 ); // delay about 100us***** timeOutCount = 0; while ( ( drvISP_ReadStatus() & 0x01 ) == 0x01 ) { timeOutCount++; if ( timeOutCount >= 100000 ) break; /* around 1 sec timeout */ } HalTscrCDevWriteI2CSeq ( FW_UPDATE_ADDR_MSG21XX, bWriteData, 5 ); //write read flash addr udelay ( 100 ); // delay about 100us***** drvISP_Read ( 128, RX_data ); HalTscrCDevWriteI2CSeq ( FW_UPDATE_ADDR_MSG21XX, &bWriteData1, 1 ); //cmd end for ( i = 0; i < 128; i++ ) //log out if verify error { if ( ( RX_data[i] != 0 ) && index < 10 ) { //TP_DEBUG("j=%d,RX_data[%d]=0x%x\n",j,i,RX_data[i]); index++; } if ( RX_data[i] != pDataToVerify[128 * j + i] ) { TP_DEBUG ( "k=%d,j=%d,i=%d===============Update Firmware Error================", k, j, i ); } } } } static void drvISP_ChipErase() { u8 bWriteData[5] = { 0x00, 0x00, 0x00, 0x00, 0x00 }; u8 bWriteData1 = 0x12; u32 timeOutCount = 0; drvISP_WriteEnable(); //Enable write status register bWriteData[0] = 0x10; bWriteData[1] = 0x50; HalTscrCDevWriteI2CSeq ( FW_UPDATE_ADDR_MSG21XX, bWriteData, 2 ); HalTscrCDevWriteI2CSeq ( FW_UPDATE_ADDR_MSG21XX, &bWriteData1, 1 ); //Write Status bWriteData[0] = 0x10; bWriteData[1] = 0x01; bWriteData[2] = 0x00; HalTscrCDevWriteI2CSeq ( FW_UPDATE_ADDR_MSG21XX, bWriteData, 3 ); HalTscrCDevWriteI2CSeq ( FW_UPDATE_ADDR_MSG21XX, &bWriteData1, 1 ); //Write disable bWriteData[0] = 0x10; bWriteData[1] = 0x04; HalTscrCDevWriteI2CSeq ( FW_UPDATE_ADDR_MSG21XX, bWriteData, 2 ); HalTscrCDevWriteI2CSeq ( FW_UPDATE_ADDR_MSG21XX, &bWriteData1, 1 ); udelay ( 100 ); // delay about 100us***** timeOutCount = 0; while ( ( drvISP_ReadStatus() & 0x01 ) == 0x01 ) { timeOutCount++; if ( timeOutCount >= 100000 ) break; /* around 1 sec timeout */ } drvISP_WriteEnable(); bWriteData[0] = 0x10; bWriteData[1] = 0xC7; HalTscrCDevWriteI2CSeq ( FW_UPDATE_ADDR_MSG21XX, bWriteData, 2 ); HalTscrCDevWriteI2CSeq ( FW_UPDATE_ADDR_MSG21XX, &bWriteData1, 1 ); udelay ( 100 ); // delay about 100us***** timeOutCount = 0; while ( ( drvISP_ReadStatus() & 0x01 ) == 0x01 ) { timeOutCount++; if ( timeOutCount >= 500000 ) break; /* around 5 sec timeout */ } } /* update the firmware part, used by apk*/ /*show the fw version*/ static ssize_t firmware_update_c2 ( 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}; // set FRO to 50M dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x11; dbbus_tx_data[2] = 0xE2; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 3 ); dbbus_rx_data[0] = 0; dbbus_rx_data[1] = 0; HalTscrCReadI2CSeq ( FW_ADDR_MSG21XX, &dbbus_rx_data[0], 2 ); TP_DEBUG ( "dbbus_rx_data[0]=0x%x", dbbus_rx_data[0] ); dbbus_tx_data[3] = dbbus_rx_data[0] & 0xF7; //Clear Bit 3 HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); // set MCU clock,SPI clock =FRO dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0x22; dbbus_tx_data[3] = 0x00; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0x23; dbbus_tx_data[3] = 0x00; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); // Enable slave's ISP ECO mode dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x08; dbbus_tx_data[2] = 0x0c; dbbus_tx_data[3] = 0x08; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); // Enable SPI Pad dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0x02; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 3 ); HalTscrCReadI2CSeq ( FW_ADDR_MSG21XX, &dbbus_rx_data[0], 2 ); TP_DEBUG ( "dbbus_rx_data[0]=0x%x", dbbus_rx_data[0] ); dbbus_tx_data[3] = ( dbbus_rx_data[0] | 0x20 ); //Set Bit 5 HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, 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; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, 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; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); dbbusDWIICIICNotUseBus(); dbbusDWIICNotStopMCU(); dbbusDWIICExitSerialDebugMode(); drvISP_EntryIspMode(); drvISP_ChipErase(); _HalTscrHWReset(); mdelay ( 300 ); // Program and Verify dbbusDWIICEnterSerialDebugMode(); dbbusDWIICStopMCU(); dbbusDWIICIICUseBus(); dbbusDWIICIICReshape(); // Disable the Watchdog dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x3C; dbbus_tx_data[2] = 0x60; dbbus_tx_data[3] = 0x55; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x3C; dbbus_tx_data[2] = 0x61; dbbus_tx_data[3] = 0xAA; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, 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; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); // set FRO to 50M dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x11; dbbus_tx_data[2] = 0xE2; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 3 ); dbbus_rx_data[0] = 0; dbbus_rx_data[1] = 0; HalTscrCReadI2CSeq ( FW_ADDR_MSG21XX, &dbbus_rx_data[0], 2 ); TP_DEBUG ( "dbbus_rx_data[0]=0x%x", dbbus_rx_data[0] ); dbbus_tx_data[3] = dbbus_rx_data[0] & 0xF7; //Clear Bit 3 HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); // set MCU clock,SPI clock =FRO dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0x22; dbbus_tx_data[3] = 0x00; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0x23; dbbus_tx_data[3] = 0x00; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); // Enable slave's ISP ECO mode dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x08; dbbus_tx_data[2] = 0x0c; dbbus_tx_data[3] = 0x08; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); // Enable SPI Pad dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0x02; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 3 ); HalTscrCReadI2CSeq ( FW_ADDR_MSG21XX, &dbbus_rx_data[0], 2 ); TP_DEBUG ( "dbbus_rx_data[0]=0x%x", dbbus_rx_data[0] ); dbbus_tx_data[3] = ( dbbus_rx_data[0] | 0x20 ); //Set Bit 5 HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, 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; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, 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; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); dbbusDWIICIICNotUseBus(); dbbusDWIICNotStopMCU(); dbbusDWIICExitSerialDebugMode(); /////////////////////////////////////// // Start to load firmware /////////////////////////////////////// drvISP_EntryIspMode(); for ( i = 0; i < 94; i++ ) // total 94 KB : 1 byte per R/W { drvISP_Program ( i, temp[i] ); // program to slave's flash drvISP_Verify ( i, temp[i] ); //verify data } TP_DEBUG ( "update OK\n" ); drvISP_ExitIspMode(); FwDataCnt = 0; return size; } static u32 Reflect ( u32 ref, char ch ) //unsigned int Reflect(unsigned int ref, char ch) { u32 value = 0; u32 i = 0; for ( i = 1; i < ( ch + 1 ); i++ ) { if ( ref & 1 ) { value |= 1 << ( ch - i ); } ref >>= 1; } return value; } u32 Get_CRC ( u32 text, u32 prevCRC, u32 *crc32_table ) { u32 ulCRC = prevCRC; ulCRC = ( ulCRC >> 8 ) ^ crc32_table[ ( ulCRC & 0xFF ) ^ text]; return ulCRC ; } static void Init_CRC32_Table ( u32 *crc32_table ) { u32 magicnumber = 0x04c11db7; u32 i = 0, j; for ( i = 0; i <= 0xFF; i++ ) { crc32_table[i] = Reflect ( i, 8 ) << 24; for ( j = 0; j < 8; j++ ) { crc32_table[i] = ( crc32_table[i] << 1 ) ^ ( crc32_table[i] & ( 0x80000000L ) ? magicnumber : 0 ); } crc32_table[i] = Reflect ( crc32_table[i], 32 ); } } typedef enum { EMEM_ALL = 0, EMEM_MAIN, EMEM_INFO, } EMEM_TYPE_t; static void drvDB_WriteReg8Bit ( u8 bank, u8 addr, u8 data ) { u8 tx_data[4] = {0x10, bank, addr, data}; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, tx_data, 4 ); } static void drvDB_WriteReg ( u8 bank, u8 addr, u16 data ) { u8 tx_data[5] = {0x10, bank, addr, data & 0xFF, data >> 8}; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, tx_data, 5 ); } static unsigned short drvDB_ReadReg ( u8 bank, u8 addr ) { u8 tx_data[3] = {0x10, bank, addr}; u8 rx_data[2] = {0}; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, tx_data, 3 ); HalTscrCReadI2CSeq ( FW_ADDR_MSG21XX, &rx_data[0], 2 ); return ( rx_data[1] << 8 | rx_data[0] ); } static int drvTP_erase_emem_c32 ( void ) { ///////////////////////// //Erase all ///////////////////////// //enter gpio mode drvDB_WriteReg ( 0x16, 0x1E, 0xBEAF ); // before gpio mode, set the control pin as the orginal status drvDB_WriteReg ( 0x16, 0x08, 0x0000 ); drvDB_WriteReg8Bit ( 0x16, 0x0E, 0x10 ); mdelay ( 10 ); //MCR_CLBK_DEBUG_DELAY ( 10, MCU_LOOP_DELAY_COUNT_MS ); // ptrim = 1, h'04[2] drvDB_WriteReg8Bit ( 0x16, 0x08, 0x04 ); drvDB_WriteReg8Bit ( 0x16, 0x0E, 0x10 ); mdelay ( 10 ); //MCR_CLBK_DEBUG_DELAY ( 10, MCU_LOOP_DELAY_COUNT_MS ); // ptm = 6, h'04[12:14] = b'110 drvDB_WriteReg8Bit ( 0x16, 0x09, 0x60 ); drvDB_WriteReg8Bit ( 0x16, 0x0E, 0x10 ); // pmasi = 1, h'04[6] drvDB_WriteReg8Bit ( 0x16, 0x08, 0x44 ); // pce = 1, h'04[11] drvDB_WriteReg8Bit ( 0x16, 0x09, 0x68 ); // perase = 1, h'04[7] drvDB_WriteReg8Bit ( 0x16, 0x08, 0xC4 ); // pnvstr = 1, h'04[5] drvDB_WriteReg8Bit ( 0x16, 0x08, 0xE4 ); // pwe = 1, h'04[9] drvDB_WriteReg8Bit ( 0x16, 0x09, 0x6A ); // trigger gpio load drvDB_WriteReg8Bit ( 0x16, 0x0E, 0x10 ); return ( 1 ); } static ssize_t firmware_update_c32 ( struct device *dev, struct device_attribute *attr, const char *buf, size_t size, EMEM_TYPE_t emem_type ) { u8 dbbus_tx_data[4]; u8 dbbus_rx_data[2] = {0}; // Buffer for slave's firmware u32 i, j; u32 crc_main, crc_main_tp; u32 crc_info, crc_info_tp; u16 reg_data = 0; crc_main = 0xffffffff; crc_info = 0xffffffff; #if 1 ///////////////////////// // Erase all ///////////////////////// drvTP_erase_emem_c32(); mdelay ( 1000 ); //MCR_CLBK_DEBUG_DELAY ( 1000, MCU_LOOP_DELAY_COUNT_MS ); //ResetSlave(); _HalTscrHWReset(); //drvDB_EnterDBBUS(); dbbusDWIICEnterSerialDebugMode(); dbbusDWIICStopMCU(); dbbusDWIICIICUseBus(); dbbusDWIICIICReshape(); mdelay ( 300 ); // Reset Watchdog drvDB_WriteReg8Bit ( 0x3C, 0x60, 0x55 ); drvDB_WriteReg8Bit ( 0x3C, 0x61, 0xAA ); ///////////////////////// // Program ///////////////////////// //polling 0x3CE4 is 0x1C70 do { reg_data = drvDB_ReadReg ( 0x3C, 0xE4 ); } while ( reg_data != 0x1C70 ); drvDB_WriteReg ( 0x3C, 0xE4, 0xE38F ); // for all-blocks //polling 0x3CE4 is 0x2F43 do { reg_data = drvDB_ReadReg ( 0x3C, 0xE4 ); } while ( reg_data != 0x2F43 ); //calculate CRC 32 Init_CRC32_Table ( &crc_tab[0] ); for ( i = 0; i < 33; i++ ) // total 33 KB : 2 byte per R/W { if ( i < 32 ) //emem_main { if ( i == 31 ) { temp[i][1014] = 0x5A; //Fmr_Loader[1014]=0x5A; temp[i][1015] = 0xA5; //Fmr_Loader[1015]=0xA5; for ( j = 0; j < 1016; j++ ) { //crc_main=Get_CRC(Fmr_Loader[j],crc_main,&crc_tab[0]); crc_main = Get_CRC ( temp[i][j], crc_main, &crc_tab[0] ); } } else { for ( j = 0; j < 1024; j++ ) { //crc_main=Get_CRC(Fmr_Loader[j],crc_main,&crc_tab[0]); crc_main = Get_CRC ( temp[i][j], crc_main, &crc_tab[0] ); } } } else // emem_info { for ( j = 0; j < 1024; j++ ) { //crc_info=Get_CRC(Fmr_Loader[j],crc_info,&crc_tab[0]); crc_info = Get_CRC ( temp[i][j], crc_info, &crc_tab[0] ); } } //drvDWIIC_MasterTransmit( DWIIC_MODE_DWIIC_ID, 1024, Fmr_Loader ); HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX_TP, temp[i], 1024 ); // polling 0x3CE4 is 0xD0BC do { reg_data = drvDB_ReadReg ( 0x3C, 0xE4 ); } while ( reg_data != 0xD0BC ); drvDB_WriteReg ( 0x3C, 0xE4, 0x2F43 ); } //write file done drvDB_WriteReg ( 0x3C, 0xE4, 0x1380 ); mdelay ( 10 ); //MCR_CLBK_DEBUG_DELAY ( 10, MCU_LOOP_DELAY_COUNT_MS ); // polling 0x3CE4 is 0x9432 do { reg_data = drvDB_ReadReg ( 0x3C, 0xE4 ); } while ( reg_data != 0x9432 ); crc_main = crc_main ^ 0xffffffff; crc_info = crc_info ^ 0xffffffff; // CRC Main from TP crc_main_tp = drvDB_ReadReg ( 0x3C, 0x80 ); crc_main_tp = ( crc_main_tp << 16 ) | drvDB_ReadReg ( 0x3C, 0x82 ); //CRC Info from TP crc_info_tp = drvDB_ReadReg ( 0x3C, 0xA0 ); crc_info_tp = ( crc_info_tp << 16 ) | drvDB_ReadReg ( 0x3C, 0xA2 ); TP_DEBUG ( "crc_main=0x%x, crc_info=0x%x, crc_main_tp=0x%x, crc_info_tp=0x%x\n", crc_main, crc_info, crc_main_tp, crc_info_tp ); //drvDB_ExitDBBUS(); if ( ( crc_main_tp != crc_main ) || ( crc_info_tp != crc_info ) ) { printk ( "update FAILED\n" ); _HalTscrHWReset(); FwDataCnt = 0; enable_irq(global_irq); return ( 0 ); } printk ( "update OK\n" ); _HalTscrHWReset(); FwDataCnt = 0; enable_irq(global_irq); return size; #endif } static int drvTP_erase_emem_c33 ( EMEM_TYPE_t emem_type ) { // stop mcu drvDB_WriteReg ( 0x0F, 0xE6, 0x0001 ); //disable watch dog drvDB_WriteReg8Bit ( 0x3C, 0x60, 0x55 ); drvDB_WriteReg8Bit ( 0x3C, 0x61, 0xAA ); // set PROGRAM password drvDB_WriteReg8Bit ( 0x16, 0x1A, 0xBA ); drvDB_WriteReg8Bit ( 0x16, 0x1B, 0xAB ); //proto.MstarWriteReg(F1.loopDevice, 0x1618, 0x80); drvDB_WriteReg8Bit ( 0x16, 0x18, 0x80 ); if ( emem_type == EMEM_ALL ) { drvDB_WriteReg8Bit ( 0x16, 0x08, 0x10 ); //mark } drvDB_WriteReg8Bit ( 0x16, 0x18, 0x40 ); mdelay ( 10 ); drvDB_WriteReg8Bit ( 0x16, 0x18, 0x80 ); // erase trigger if ( emem_type == EMEM_MAIN ) { drvDB_WriteReg8Bit ( 0x16, 0x0E, 0x04 ); //erase main } else { drvDB_WriteReg8Bit ( 0x16, 0x0E, 0x08 ); //erase all block } return ( 1 ); } static int drvTP_read_emem_dbbus_c33 ( EMEM_TYPE_t emem_type, u16 addr, size_t size, u8 *p, size_t set_pce_high ) { u32 i; // Set the starting address ( must before enabling burst mode and enter riu mode ) drvDB_WriteReg ( 0x16, 0x00, addr ); // Enable the burst mode ( must before enter riu mode ) drvDB_WriteReg ( 0x16, 0x0C, drvDB_ReadReg ( 0x16, 0x0C ) | 0x0001 ); // Set the RIU password drvDB_WriteReg ( 0x16, 0x1A, 0xABBA ); // Enable the information block if pifren is HIGH if ( emem_type == EMEM_INFO ) { // Clear the PCE drvDB_WriteReg ( 0x16, 0x18, drvDB_ReadReg ( 0x16, 0x18 ) | 0x0080 ); mdelay ( 10 ); // Set the PIFREN to be HIGH drvDB_WriteReg ( 0x16, 0x08, 0x0010 ); } // Set the PCE to be HIGH drvDB_WriteReg ( 0x16, 0x18, drvDB_ReadReg ( 0x16, 0x18 ) | 0x0040 ); mdelay ( 10 ); // Wait pce becomes 1 ( read data ready ) while ( ( drvDB_ReadReg ( 0x16, 0x10 ) & 0x0004 ) != 0x0004 ); for ( i = 0; i < size; i += 4 ) { // Fire the FASTREAD command drvDB_WriteReg ( 0x16, 0x0E, drvDB_ReadReg ( 0x16, 0x0E ) | 0x0001 ); // Wait the operation is done while ( ( drvDB_ReadReg ( 0x16, 0x10 ) & 0x0001 ) != 0x0001 ); p[i + 0] = drvDB_ReadReg ( 0x16, 0x04 ) & 0xFF; p[i + 1] = ( drvDB_ReadReg ( 0x16, 0x04 ) >> 8 ) & 0xFF; p[i + 2] = drvDB_ReadReg ( 0x16, 0x06 ) & 0xFF; p[i + 3] = ( drvDB_ReadReg ( 0x16, 0x06 ) >> 8 ) & 0xFF; } // Disable the burst mode drvDB_WriteReg ( 0x16, 0x0C, drvDB_ReadReg ( 0x16, 0x0C ) & ( ~0x0001 ) ); // Clear the starting address drvDB_WriteReg ( 0x16, 0x00, 0x0000 ); //Always return to main block if ( emem_type == EMEM_INFO ) { // Clear the PCE before change block drvDB_WriteReg ( 0x16, 0x18, drvDB_ReadReg ( 0x16, 0x18 ) | 0x0080 ); mdelay ( 10 ); // Set the PIFREN to be LOW drvDB_WriteReg ( 0x16, 0x08, drvDB_ReadReg ( 0x16, 0x08 ) & ( ~0x0010 ) ); drvDB_WriteReg ( 0x16, 0x18, drvDB_ReadReg ( 0x16, 0x18 ) | 0x0040 ); while ( ( drvDB_ReadReg ( 0x16, 0x10 ) & 0x0004 ) != 0x0004 ); } // Clear the RIU password drvDB_WriteReg ( 0x16, 0x1A, 0x0000 ); if ( set_pce_high ) { // Set the PCE to be HIGH before jumping back to e-flash codes drvDB_WriteReg ( 0x16, 0x18, drvDB_ReadReg ( 0x16, 0x18 ) | 0x0040 ); while ( ( drvDB_ReadReg ( 0x16, 0x10 ) & 0x0004 ) != 0x0004 ); } return ( 1 ); } static int drvTP_read_info_dwiic_c33 ( void ) { u8 dwiic_tx_data[5]; u8 dwiic_rx_data[4]; u16 reg_data=0; mdelay ( 300 ); // Stop Watchdog drvDB_WriteReg8Bit ( 0x3C, 0x60, 0x55 ); drvDB_WriteReg8Bit ( 0x3C, 0x61, 0xAA ); drvDB_WriteReg ( 0x3C, 0xE4, 0xA4AB ); drvDB_WriteReg ( 0x1E, 0x04, 0x7d60 ); // TP SW reset drvDB_WriteReg ( 0x1E, 0x04, 0x829F ); mdelay ( 1 ); dwiic_tx_data[0] = 0x10; dwiic_tx_data[1] = 0x0F; dwiic_tx_data[2] = 0xE6; dwiic_tx_data[3] = 0x00; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dwiic_tx_data, 4 ); mdelay ( 100 ); do{ reg_data = drvDB_ReadReg ( 0x3C, 0xE4 ); } while ( reg_data != 0x5B58 ); dwiic_tx_data[0] = 0x72; dwiic_tx_data[1] = 0x80; dwiic_tx_data[2] = 0x00; dwiic_tx_data[3] = 0x04; dwiic_tx_data[4] = 0x00; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX_TP , dwiic_tx_data, 5 ); mdelay ( 50 ); // recive info data HalTscrCReadI2CSeq ( FW_ADDR_MSG21XX_TP, &g_dwiic_info_data[0], 1024 ); return ( 1 ); } static int drvTP_info_updata_C33 ( u16 start_index, u8 *data, u16 size ) { // size != 0, start_index+size !> 1024 u16 i; for ( i = 0; i < size; i++ ) { g_dwiic_info_data[start_index] = * ( data + i ); start_index++; } return ( 1 ); } static ssize_t firmware_update_c33 ( struct device *dev, struct device_attribute *attr, const char *buf, size_t size, EMEM_TYPE_t emem_type ) { u8 dbbus_tx_data[4]; u8 dbbus_rx_data[2] = {0}; u8 life_counter[2]; u32 i, j; u32 crc_main, crc_main_tp; u32 crc_info, crc_info_tp; int update_pass = 1; u16 reg_data = 0; crc_main = 0xffffffff; crc_info = 0xffffffff; drvTP_read_info_dwiic_c33(); if ( g_dwiic_info_data[0] == 'M' && g_dwiic_info_data[1] == 'S' && g_dwiic_info_data[2] == 'T' && g_dwiic_info_data[3] == 'A' && g_dwiic_info_data[4] == 'R' && g_dwiic_info_data[5] == 'T' && g_dwiic_info_data[6] == 'P' && g_dwiic_info_data[7] == 'C' ) { // updata FW Version //drvTP_info_updata_C33 ( 8, &temp[32][8], 5 ); g_dwiic_info_data[8]=temp[32][8]; g_dwiic_info_data[9]=temp[32][9]; g_dwiic_info_data[10]=temp[32][10]; g_dwiic_info_data[11]=temp[32][11]; // updata life counter life_counter[1] = (( ( (g_dwiic_info_data[13] << 8 ) | g_dwiic_info_data[12]) + 1 ) >> 8 ) & 0xFF; life_counter[0] = ( ( (g_dwiic_info_data[13] << 8 ) | g_dwiic_info_data[12]) + 1 ) & 0xFF; g_dwiic_info_data[12]=life_counter[0]; g_dwiic_info_data[13]=life_counter[1]; //drvTP_info_updata_C33 ( 10, &life_counter[0], 3 ); drvDB_WriteReg ( 0x3C, 0xE4, 0x78C5 ); drvDB_WriteReg ( 0x1E, 0x04, 0x7d60 ); // TP SW reset drvDB_WriteReg ( 0x1E, 0x04, 0x829F ); mdelay ( 50 ); //polling 0x3CE4 is 0x2F43 do { reg_data = drvDB_ReadReg ( 0x3C, 0xE4 ); } while ( reg_data != 0x2F43 ); // transmit lk info data HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX_TP , &g_dwiic_info_data[0], 1024 ); //polling 0x3CE4 is 0xD0BC do { reg_data = drvDB_ReadReg ( 0x3C, 0xE4 ); } while ( reg_data != 0xD0BC ); } //erase main drvTP_erase_emem_c33 ( EMEM_MAIN ); mdelay ( 1000 ); //ResetSlave(); _HalTscrHWReset(); //drvDB_EnterDBBUS(); dbbusDWIICEnterSerialDebugMode(); dbbusDWIICStopMCU(); dbbusDWIICIICUseBus(); dbbusDWIICIICReshape(); mdelay ( 300 ); ///////////////////////// // Program ///////////////////////// //polling 0x3CE4 is 0x1C70 if ( ( emem_type == EMEM_ALL ) || ( emem_type == EMEM_MAIN ) ) { do { reg_data = drvDB_ReadReg ( 0x3C, 0xE4 ); } while ( reg_data != 0x1C70 ); } switch ( emem_type ) { case EMEM_ALL: drvDB_WriteReg ( 0x3C, 0xE4, 0xE38F ); // for all-blocks break; case EMEM_MAIN: drvDB_WriteReg ( 0x3C, 0xE4, 0x7731 ); // for main block break; case EMEM_INFO: drvDB_WriteReg ( 0x3C, 0xE4, 0x7731 ); // for info block drvDB_WriteReg8Bit ( 0x0F, 0xE6, 0x01 ); drvDB_WriteReg8Bit ( 0x3C, 0xE4, 0xC5 ); // drvDB_WriteReg8Bit ( 0x3C, 0xE5, 0x78 ); // drvDB_WriteReg8Bit ( 0x1E, 0x04, 0x9F ); drvDB_WriteReg8Bit ( 0x1E, 0x05, 0x82 ); drvDB_WriteReg8Bit ( 0x0F, 0xE6, 0x00 ); mdelay ( 100 ); break; } // polling 0x3CE4 is 0x2F43 do { reg_data = drvDB_ReadReg ( 0x3C, 0xE4 ); } while ( reg_data != 0x2F43 ); // calculate CRC 32 Init_CRC32_Table ( &crc_tab[0] ); for ( i = 0; i < 33; i++ ) // total 33 KB : 2 byte per R/W { if ( emem_type == EMEM_INFO ) i = 32; if ( i < 32 ) //emem_main { if ( i == 31 ) { temp[i][1014] = 0x5A; //Fmr_Loader[1014]=0x5A; temp[i][1015] = 0xA5; //Fmr_Loader[1015]=0xA5; for ( j = 0; j < 1016; j++ ) { //crc_main=Get_CRC(Fmr_Loader[j],crc_main,&crc_tab[0]); crc_main = Get_CRC ( temp[i][j], crc_main, &crc_tab[0] ); } } else { for ( j = 0; j < 1024; j++ ) { //crc_main=Get_CRC(Fmr_Loader[j],crc_main,&crc_tab[0]); crc_main = Get_CRC ( temp[i][j], crc_main, &crc_tab[0] ); } } } else //emem_info { for ( j = 0; j < 1024; j++ ) { //crc_info=Get_CRC(Fmr_Loader[j],crc_info,&crc_tab[0]); crc_info = Get_CRC ( g_dwiic_info_data[j], crc_info, &crc_tab[0] ); } if ( emem_type == EMEM_MAIN ) break; } //drvDWIIC_MasterTransmit( DWIIC_MODE_DWIIC_ID, 1024, Fmr_Loader ); HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX_TP, temp[i], 1024 ); // polling 0x3CE4 is 0xD0BC do { reg_data = drvDB_ReadReg ( 0x3C, 0xE4 ); } while ( reg_data != 0xD0BC ); drvDB_WriteReg ( 0x3C, 0xE4, 0x2F43 ); } if ( ( emem_type == EMEM_ALL ) || ( emem_type == EMEM_MAIN ) ) { // write file done and check crc drvDB_WriteReg ( 0x3C, 0xE4, 0x1380 ); } mdelay ( 10 ); //MCR_CLBK_DEBUG_DELAY ( 10, MCU_LOOP_DELAY_COUNT_MS ); if ( ( emem_type == EMEM_ALL ) || ( emem_type == EMEM_MAIN ) ) { // polling 0x3CE4 is 0x9432 do { reg_data = drvDB_ReadReg ( 0x3C, 0xE4 ); }while ( reg_data != 0x9432 ); } crc_main = crc_main ^ 0xffffffff; crc_info = crc_info ^ 0xffffffff; if ( ( emem_type == EMEM_ALL ) || ( emem_type == EMEM_MAIN ) ) { // CRC Main from TP crc_main_tp = drvDB_ReadReg ( 0x3C, 0x80 ); crc_main_tp = ( crc_main_tp << 16 ) | drvDB_ReadReg ( 0x3C, 0x82 ); // CRC Info from TP crc_info_tp = drvDB_ReadReg ( 0x3C, 0xA0 ); crc_info_tp = ( crc_info_tp << 16 ) | drvDB_ReadReg ( 0x3C, 0xA2 ); } TP_DEBUG ( "crc_main=0x%x, crc_info=0x%x, crc_main_tp=0x%x, crc_info_tp=0x%x\n", crc_main, crc_info, crc_main_tp, crc_info_tp ); //drvDB_ExitDBBUS(); update_pass = 1; if ( ( emem_type == EMEM_ALL ) || ( emem_type == EMEM_MAIN ) ) { if ( crc_main_tp != crc_main ) update_pass = 0; if ( crc_info_tp != crc_info ) update_pass = 0; } if ( !update_pass ) { printk ( "update FAILED\n" ); _HalTscrHWReset(); FwDataCnt = 0; enable_irq(global_irq); return ( 0 ); } printk ( "update OK\n" ); _HalTscrHWReset(); FwDataCnt = 0; enable_irq(global_irq); return size; } #define _FW_UPDATE_C3_ #ifdef _FW_UPDATE_C3_ 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}; disable_irq(global_irq); _HalTscrHWReset(); // Erase TP Flash first dbbusDWIICEnterSerialDebugMode(); dbbusDWIICStopMCU(); dbbusDWIICIICUseBus(); dbbusDWIICIICReshape(); mdelay ( 300 ); // Disable the Watchdog dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x3C; dbbus_tx_data[2] = 0x60; dbbus_tx_data[3] = 0x55; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x3C; dbbus_tx_data[2] = 0x61; dbbus_tx_data[3] = 0xAA; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, 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; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); ///////////////////////// // Difference between C2 and C3 ///////////////////////// // c2:2133 c32:2133a(2) c33:2138 //check id dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0xCC; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 3 ); HalTscrCReadI2CSeq ( FW_ADDR_MSG21XX, &dbbus_rx_data[0], 2 ); if ( dbbus_rx_data[0] == 2 ) { // check version dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x3C; dbbus_tx_data[2] = 0xEA; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 3 ); HalTscrCReadI2CSeq ( FW_ADDR_MSG21XX, &dbbus_rx_data[0], 2 ); TP_DEBUG ( "dbbus_rx version[0]=0x%x", dbbus_rx_data[0] ); if ( dbbus_rx_data[0] == 3 ){ return firmware_update_c33 ( dev, attr, buf, size, EMEM_MAIN ); } else{ return firmware_update_c32 ( dev, attr, buf, size, EMEM_ALL ); } } else { return firmware_update_c2 ( dev, attr, buf, size ); } } #else 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}; _HalTscrHWReset(); // 1. Erase TP Flash first dbbusDWIICEnterSerialDebugMode(); dbbusDWIICStopMCU(); dbbusDWIICIICUseBus(); dbbusDWIICIICReshape(); mdelay ( 300 ); // Disable the Watchdog dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x3C; dbbus_tx_data[2] = 0x60; dbbus_tx_data[3] = 0x55; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x3C; dbbus_tx_data[2] = 0x61; dbbus_tx_data[3] = 0xAA; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, 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; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); // set FRO to 50M dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x11; dbbus_tx_data[2] = 0xE2; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 3 ); dbbus_rx_data[0] = 0; dbbus_rx_data[1] = 0; HalTscrCReadI2CSeq ( FW_ADDR_MSG21XX, &dbbus_rx_data[0], 2 ); TP_DEBUG ( "dbbus_rx_data[0]=0x%x", dbbus_rx_data[0] ); dbbus_tx_data[3] = dbbus_rx_data[0] & 0xF7; //Clear Bit 3 HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); // set MCU clock,SPI clock =FRO dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0x22; dbbus_tx_data[3] = 0x00; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0x23; dbbus_tx_data[3] = 0x00; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); // Enable slave's ISP ECO mode dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x08; dbbus_tx_data[2] = 0x0c; dbbus_tx_data[3] = 0x08; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); // Enable SPI Pad dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0x02; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 3 ); HalTscrCReadI2CSeq ( FW_ADDR_MSG21XX, &dbbus_rx_data[0], 2 ); TP_DEBUG ( "dbbus_rx_data[0]=0x%x", dbbus_rx_data[0] ); dbbus_tx_data[3] = ( dbbus_rx_data[0] | 0x20 ); //Set Bit 5 HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, 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; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, 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; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); dbbusDWIICIICNotUseBus(); dbbusDWIICNotStopMCU(); dbbusDWIICExitSerialDebugMode(); drvISP_EntryIspMode(); drvISP_ChipErase(); _HalTscrHWReset(); mdelay ( 300 ); // 2.Program and Verify dbbusDWIICEnterSerialDebugMode(); dbbusDWIICStopMCU(); dbbusDWIICIICUseBus(); dbbusDWIICIICReshape(); // Disable the Watchdog dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x3C; dbbus_tx_data[2] = 0x60; dbbus_tx_data[3] = 0x55; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x3C; dbbus_tx_data[2] = 0x61; dbbus_tx_data[3] = 0xAA; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, 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; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); // set FRO to 50M dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x11; dbbus_tx_data[2] = 0xE2; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 3 ); dbbus_rx_data[0] = 0; dbbus_rx_data[1] = 0; HalTscrCReadI2CSeq ( FW_ADDR_MSG21XX, &dbbus_rx_data[0], 2 ); TP_DEBUG ( "dbbus_rx_data[0]=0x%x", dbbus_rx_data[0] ); dbbus_tx_data[3] = dbbus_rx_data[0] & 0xF7; //Clear Bit 3 HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); // set MCU clock,SPI clock =FRO dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0x22; dbbus_tx_data[3] = 0x00; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0x23; dbbus_tx_data[3] = 0x00; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); // Enable slave's ISP ECO mode dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x08; dbbus_tx_data[2] = 0x0c; dbbus_tx_data[3] = 0x08; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); // Enable SPI Pad dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0x02; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 3 ); HalTscrCReadI2CSeq ( FW_ADDR_MSG21XX, &dbbus_rx_data[0], 2 ); TP_DEBUG ( "dbbus_rx_data[0]=0x%x", dbbus_rx_data[0] ); dbbus_tx_data[3] = ( dbbus_rx_data[0] | 0x20 ); //Set Bit 5 HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, 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; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, 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; HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 4 ); dbbusDWIICIICNotUseBus(); dbbusDWIICNotStopMCU(); dbbusDWIICExitSerialDebugMode(); /////////////////////////////////////// // Start to load firmware /////////////////////////////////////// drvISP_EntryIspMode(); for ( i = 0; i < 94; i++ ) // total 94 KB : 1 byte per R/W { drvISP_Program ( i, temp[i] ); // program to slave's flash drvISP_Verify ( i, temp[i] ); //verify data } TP_DEBUG ( "update OK\n" ); drvISP_ExitIspMode(); FwDataCnt = 0; return size; } #endif static DEVICE_ATTR(update, 0664, firmware_update_show, firmware_update_store); #if 0 /*test=================*/ static ssize_t firmware_clear_show(struct device *dev, struct device_attribute *attr, char *buf) { printk(" +++++++ [%s] Enter!++++++\n", __func__); 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; u32 timeOutCount=0; 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); //msctpc_LoopDelay ( 1 ); // delay about 100us***** udelay(150);//200); timeOutCount=0; while ( ( drvISP_ReadStatus() & 0x01 ) == 0x01 ) { timeOutCount++; if ( timeOutCount >= 100000 ) break; /* around 1 sec timeout */ } HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, bWriteData, 5); //write read flash addr //msctpc_LoopDelay ( 1 ); // delay about 100us***** udelay(150);//200); drvISP_Read(128, RX_data); HalTscrCDevWriteI2CSeq(FW_UPDATE_ADDR_MSG21XX, &bWriteData1, 1); //cmd end for (i = 0; i < 128; i++) //log out if verify error { if (RX_data[i] != 0xFF) { //TP_DEBUG(printk("k=%d,j=%d,i=%d===============erase not clean================",k,j,i);) printk("k=%d,j=%d,i=%d erase not clean !!",k,j,i); } } } } TP_DEBUG("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}; printk(" +++++++ [%s] Enter!++++++\n", __func__); //msctpc_LoopDelay ( 100 ); // delay about 100ms***** // Enable slave's ISP ECO mode dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x08; dbbus_tx_data[2] = 0x0c; dbbus_tx_data[3] = 0x08; // Disable the Watchdog HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, dbbus_tx_data, 4); dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x11; dbbus_tx_data[2] = 0xE2; dbbus_tx_data[3] = 0x00; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, dbbus_tx_data, 4); dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x3C; dbbus_tx_data[2] = 0x60; dbbus_tx_data[3] = 0x55; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, dbbus_tx_data, 4); dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x3C; dbbus_tx_data[2] = 0x61; dbbus_tx_data[3] = 0xAA; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, 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; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, dbbus_tx_data, 4); //Enable SPI Pad dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0x02; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, dbbus_tx_data, 3); HalTscrCReadI2CSeq(FW_ADDR_MSG21XX, &dbbus_rx_data[0], 2); TP_DEBUG(printk("dbbus_rx_data[0]=0x%x", dbbus_rx_data[0]);) dbbus_tx_data[3] = (dbbus_rx_data[0] | 0x20); //Set Bit 5 HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, dbbus_tx_data, 4); dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0x25; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, dbbus_tx_data, 3); dbbus_rx_data[0] = 0; dbbus_rx_data[1] = 0; HalTscrCReadI2CSeq(FW_ADDR_MSG21XX, &dbbus_rx_data[0], 2); TP_DEBUG(printk("dbbus_rx_data[0]=0x%x", dbbus_rx_data[0]);) dbbus_tx_data[3] = dbbus_rx_data[0] & 0xFC; //Clear Bit 1,0 HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, 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; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, 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; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, dbbus_tx_data, 4); //set FRO to 50M dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x11; dbbus_tx_data[2] = 0xE2; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, dbbus_tx_data, 3); dbbus_rx_data[0] = 0; dbbus_rx_data[1] = 0; HalTscrCReadI2CSeq(FW_ADDR_MSG21XX, &dbbus_rx_data[0], 2); TP_DEBUG(printk("dbbus_rx_data[0]=0x%x", dbbus_rx_data[0]);) dbbus_tx_data[3] = dbbus_rx_data[0] & 0xF7; //Clear Bit 1,0 HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX, dbbus_tx_data, 4); dbbusDWIICIICNotUseBus(); dbbusDWIICNotStopMCU(); dbbusDWIICExitSerialDebugMode(); /////////////////////////////////////// // Start to load firmware /////////////////////////////////////// drvISP_EntryIspMode(); TP_DEBUG(printk("chip erase+\n");) drvISP_BlockErase(0x00000); TP_DEBUG(printk("chip erase-\n");) drvISP_ExitIspMode(); return size; } static DEVICE_ATTR(clear, 0664, firmware_clear_show, firmware_clear_store); #endif //0 /*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) { TP_DEBUG("*** 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(); */ if(NULL==fw_version) { fw_version = kzalloc(sizeof(char), GFP_KERNEL); } //Get_Chip_Version(); dbbus_tx_data[0] = 0x53; dbbus_tx_data[1] = 0x00; dbbus_tx_data[2] = 0x2a; HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX_TP, &dbbus_tx_data[0], 3); HalTscrCReadI2CSeq(FW_ADDR_MSG21XX_TP, &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]; TP_DEBUG("***major = %d ***\n", major); TP_DEBUG("***minor = %d ***\n", minor); sprintf(fw_version,"%03d%03d", major, minor); //TP_DEBUG(printk("***fw_version = %s ***\n", fw_version);) return size; } static DEVICE_ATTR(version, 0664, 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) { int i; TP_DEBUG("***FwDataCnt = %d ***\n", FwDataCnt); for (i = 0; i < 1024; i++) { memcpy(temp[FwDataCnt], buf, 1024); } FwDataCnt++; return size; } static DEVICE_ATTR(data, 0664, firmware_data_show, firmware_data_store); #endif //__FIRMWARE_UPDATE__ static int pixcir_i2c_txdata(char *txdata, int length) { int ret; struct i2c_msg msg[] = { { .addr = msg21xx_i2c_client->addr, .flags = 0, .len = length, .buf = txdata, }, }; ret = i2c_transfer(msg21xx_i2c_client->adapter, msg, 1); if (ret < 0) pr_err("%s i2c write error: %d\n", __func__, ret); return ret; } static int pixcir_i2c_write_data(unsigned char addr, unsigned char data) { unsigned char buf[2]; buf[0]=addr; buf[1]=data; return pixcir_i2c_txdata(buf, 2); } static bool msg2138_i2c_read(char *pbt_buf, int dw_lenth) { int ret; // pr_ch("The msg_i2c_client->addr=0x%x\n",i2c_client->addr); ret = i2c_master_recv(msg21xx_i2c_client, pbt_buf, dw_lenth); if(ret <= 0) { //pr_tp("msg_i2c_read_interface error\n"); return false; } return true; } static bool msg2138_i2c_write(char *pbt_buf, int dw_lenth) { int ret; // pr_ch("The msg_i2c_client->addr=0x%x\n",i2c_client->addr); ret = i2c_master_send(msg21xx_i2c_client, pbt_buf, dw_lenth); if(ret <= 0) { //pr_tp("msg_i2c_read_interface error\n"); return false; } return true; } static DEVICE_ATTR(calibrate, S_IRUGO | S_IWUSR, NULL, pixcir_set_calibrate); static DEVICE_ATTR(suspend, S_IRUGO | S_IWUSR, pixcir_show_suspend, pixcir_store_suspend); static ssize_t pixcir_set_calibrate(struct device* cd, struct device_attribute *attr, const char* buf, size_t len) { unsigned long on_off = simple_strtoul(buf, NULL, 10); if(on_off==1) { printk("%s: PIXCIR calibrate\n",__func__); pixcir_i2c_write_data(0x3a , 0x03); msleep(5*1000); } return len; } static ssize_t pixcir_show_suspend(struct device* cd, struct device_attribute *attr, char* buf) { ssize_t ret = 0; if(suspend_flag==1) sprintf(buf, "Pixcir Suspend\n"); else sprintf(buf, "Pixcir Resume\n"); ret = strlen(buf) + 1; return ret; } static ssize_t pixcir_store_suspend(struct device* cd, struct device_attribute *attr, const char* buf, size_t len) { unsigned long on_off = simple_strtoul(buf, NULL, 10); suspend_flag = on_off; if(on_off==1) { printk("Pixcir Entry Suspend\n"); pixcir_ts_suspend(NULL); } else { printk("Pixcir Entry Resume\n"); pixcir_ts_resume(NULL); } return len; } static void pixcir_reset(void) { struct msg2138_ts_platform_data *pdata = msg21xx_i2c_ts_data->platform_data; PIXCIR_DBG("%s\n",__func__); gpio_set_value(pdata->reset_gpio_number, 1); msleep(3); gpio_set_value(pdata->reset_gpio_number, 0); msleep(310); gpio_set_value(pdata->reset_gpio_number, 1); msleep(100); } //cg,20130929,start #ifdef SYSFS_DEBUG static void cg_tpfwver_readfwver() { unsigned char dbbus_tx_data[3]; unsigned char dbbus_rx_data[4] ; unsigned short major=0, minor=0; u8 count = 0; int ret = 0; for(count=0;count<5;count++) { pixcir_reset(); msleep(100); if(NULL == cg_fw_version) { cg_fw_version = kzalloc(sizeof(char), GFP_KERNEL); } //Get_Chip_Version(); dbbus_tx_data[0] = 0x53; dbbus_tx_data[1] = 0x00; dbbus_tx_data[2] = 0x2a; ret = HalTscrCDevWriteI2CSeq(FW_ADDR_MSG21XX_TP, &dbbus_tx_data[0], 3); if(ret<0) { printk("*** write fail ret = %d ***\n", ret); continue; } msleep(100); ret = HalTscrCReadI2CSeq(FW_ADDR_MSG21XX_TP, &dbbus_rx_data[0], 4); if(ret<0) { printk("*** read fail ret = %d ***\n", ret); continue; } major =(dbbus_rx_data[1]<<8)+dbbus_rx_data[0]; if(0==major) { printk("*** major fail = %d ***\n", major); continue; } minor =(dbbus_rx_data[3]<<8)+dbbus_rx_data[2]; printk("***major = %d ***\n", major); printk("***minor = %d ***\n", minor); sprintf(cg_fw_version,"%03d%03d", major, minor); printk("***tp_fw_version = %s ***\n", cg_fw_version); break; } printk("*** count = %d ***\n", count); } static ssize_t cg_tpfwver_show(struct device *dev, struct device_attribute *attr, char *buf) { cg_tpfwver_readfwver(); return sprintf(buf, "%s\n", cg_fw_version); } static ssize_t cg_tpfwver_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { return -EPERM; } static DEVICE_ATTR(fwversion, S_IRUGO, cg_tpfwver_show,NULL); #endif //cg,20130929,end static int pixcir_create_sysfs(struct i2c_client *client) { int err; struct device *dev = &(client->dev); PIXCIR_DBG("%s\n", __func__); err = device_create_file(dev, &dev_attr_calibrate); err = device_create_file(dev, &dev_attr_suspend); #ifdef SYSFS_DEBUG err = device_create_file(dev, &dev_attr_fwversion); //cg,20130929 #endif return err; } #ifdef CONFIG_HAS_EARLYSUSPEND static void pixcir_ts_suspend(struct early_suspend *handler) { struct msg2138_ts_platform_data *pdata = msg21xx_i2c_ts_data->platform_data; printk("==%s==\n", __func__); disable_irq_nosync(global_irq); msleep(3); gpio_set_value(pdata->reset_gpio_number, 0); msleep(10); } static void pixcir_ts_resume(struct early_suspend *handler) { //unsigned char rdbuf[27]; //int num = 10; //disable_irq_nosync(global_irq); #if 0 struct pixcir_i2c_ts_data *pixcir_ts = (struct pixcir_i2c_ts_data *)i2c_get_clientdata(msg21xx_i2c_client); queue_work(pixcir_ts->ts_resume_workqueue, &pixcir_ts->resume_work); #endif printk("==%s==start==\n", __func__); pixcir_reset(); enable_irq(global_irq); printk("==%s==end==\n", __func__); } #endif #ifdef TOUCH_VIRTUAL_KEYS /*static ssize_t virtual_keys_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { return sprintf(buf, __stringify(EV_KEY) ":" __stringify(KEY_HOMEPAGE) ":192:1000:64:60" ":" __stringify(EV_KEY) ":" __stringify(KEY_MENU) ":256:1000:64:60" ":" __stringify(EV_KEY) ":" __stringify(KEY_BACK) ":128:1000:64:60" ":" __stringify(EV_KEY) ":" __stringify(KEY_SEARCH) ":64:1000:64:60" "\n"); }*/ static ssize_t virtual_keys_show(struct kobject *kobj, struct kobj_attribute *attr, char *buf) { struct pixcir_i2c_ts_data *data = i2c_get_clientdata(msg21xx_i2c_client); struct msg2138_ts_platform_data *pdata = data->platform_data; return sprintf(buf,"%s:%s:%d:%d:%d:%d:%s:%s:%d:%d:%d:%d:%s:%s:%d:%d:%d:%d\n" ,__stringify(EV_KEY), __stringify(KEY_MENU),pdata ->virtualkeys[0],pdata ->virtualkeys[1],pdata ->virtualkeys[2],pdata ->virtualkeys[3] ,__stringify(EV_KEY), __stringify(KEY_HOMEPAGE),pdata ->virtualkeys[4],pdata ->virtualkeys[5],pdata ->virtualkeys[6],pdata ->virtualkeys[7] ,__stringify(EV_KEY), __stringify(KEY_BACK),pdata ->virtualkeys[8],pdata ->virtualkeys[9],pdata ->virtualkeys[10],pdata ->virtualkeys[11]); } static struct kobj_attribute virtual_keys_attr = { .attr = { .name = "virtualkeys.msg2138_ts", .mode = S_IRUGO, }, .show = &virtual_keys_show, }; static struct attribute *properties_attrs[] = { &virtual_keys_attr.attr, NULL }; static struct attribute_group properties_attr_group = { .attrs = properties_attrs, }; static void pixcir_ts_virtual_keys_init(void) { int ret; struct kobject *properties_kobj; PIXCIR_DBG("%s\n",__func__); properties_kobj = kobject_create_and_add("board_properties", NULL); if (properties_kobj) ret = sysfs_create_group(properties_kobj, &properties_attr_group); if (!properties_kobj || ret) pr_err("failed to create board_properties\n"); } #endif static int getchipType(void) { int curr_ic_type = 0; u8 dbbus_tx_data[4]; unsigned char dbbus_rx_data[2] = {0}; int error = 0; //check id dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x1E; dbbus_tx_data[2] = 0xCC; error = HalTscrCDevWriteI2CSeq ( FW_ADDR_MSG21XX, dbbus_tx_data, 3 ); if (error < 0) { pr_err("[MSG2138A] getchipType() write i2c error %d\n",error); return error; } error = HalTscrCReadI2CSeq ( FW_ADDR_MSG21XX, &dbbus_rx_data[0], 2 ); if (error < 0) { pr_err("[MSG2138A] getchipType() read i2c error %d\n",error); return error; } if ( dbbus_rx_data[0] == 2 ) { curr_ic_type = CTP_ID_MSG21XXA; } else { curr_ic_type = CTP_ID_MSG21XX; } return curr_ic_type; } static void pixcir_ts_hw_init(struct pixcir_i2c_ts_data *tsdata) { struct regulator *g_cg_reg_vdd; struct msg2138_ts_platform_data *pdata = tsdata->platform_data; struct i2c_client *client = tsdata->client; int err= 0; gpio_request(pdata->reset_gpio_number, "gpio_tp_rst"); gpio_request(pdata->irq_gpio_number, "gpio_tp_irq"); gpio_direction_output(pdata->reset_gpio_number,1); gpio_direction_input(pdata->irq_gpio_number); g_cg_reg_vdd = regulator_get(&client->dev, pdata->vdd_name); if (!WARN(IS_ERR(g_cg_reg_vdd), "[MSG2138] pixcir_ts_hw_init regulator: failed to get %s.\n", pdata->vdd_name)) { regulator_set_voltage(g_cg_reg_vdd, 2800000, 2800000); err = regulator_enable(g_cg_reg_vdd); } msleep(100); pixcir_reset(); } /*static int attb_read_val(void) { struct msg2138_ts_platform_data *pdata = msg21xx_i2c_ts_data->platform_data; return gpio_get_value(pdata->irq_gpio_number); }*/ 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 void return_i2c_dev(struct i2c_dev *i2c_dev) { spin_lock(&i2c_dev_list_lock); list_del(&i2c_dev->list); spin_unlock(&i2c_dev_list_lock); kfree(i2c_dev); } static struct i2c_dev *i2c_dev_get_by_minor(unsigned index) { struct i2c_dev *i2c_dev; i2c_dev = NULL; spin_lock(&i2c_dev_list_lock); list_for_each_entry(i2c_dev, &i2c_dev_list, list) { if (i2c_dev->adap->nr == index) goto found; } i2c_dev = NULL; found: spin_unlock(&i2c_dev_list_lock); return i2c_dev; } static struct i2c_dev *get_free_i2c_dev(struct i2c_adapter *adap) { struct i2c_dev *i2c_dev; if (adap->nr >= I2C_MINORS) { printk(KERN_ERR "i2c-dev: Out of device minors (%d)\n", adap->nr); return ERR_PTR(-ENODEV); } i2c_dev = kzalloc(sizeof(*i2c_dev), GFP_KERNEL); if (!i2c_dev) return ERR_PTR(-ENOMEM); i2c_dev->adap = adap; spin_lock(&i2c_dev_list_lock); list_add_tail(&i2c_dev->list, &i2c_dev_list); spin_unlock(&i2c_dev_list_lock); return i2c_dev; } /*********************************Bee-0928-bottom**************************************/ struct point_node_t{ unsigned char active ; unsigned char finger_id; int posx; int posy; }; static struct point_node_t point_slot[MAX_FINGER_NUM*2]; static int keycode; static int sy_rxdata(struct touch_info *cinfo, struct touch_info *pinfo) { //u32 retval; //static unsigned char tt_mode; //pinfo->count = cinfo->count; unsigned char reg_val[8] = {0}; int dst_x=0,dst_y=0; unsigned int temp_checksum; struct TouchScreenInfo_t touchData; //unsigned char touchkeycode = 0; //static int preKeyStatus; //TPD_DEBUG("pinfo->count =%d\n",pinfo->count); cinfo->count = 0; //touch end msg2138_i2c_read(reg_val, 8); //retval = i2c_smbus_read_i2c_block_data(msg21xx_i2c_client, TPD_REG_BASE, 8, (unsigned char *)&g_operation_data); //retval += i2c_smbus_read_i2c_block_data(msg21xx_i2c_client, TPD_REG_BASE + 8, 8, (((unsigned char *)(&g_operation_data)) + 8)); cinfo->x1 = ((reg_val[1] & 0xF0) << 4) | reg_val[2]; cinfo->y1 = ((reg_val[1] & 0x0F) << 8) | reg_val[3]; dst_x = ((reg_val[4] & 0xF0) << 4) | reg_val[5]; dst_y = ((reg_val[4] & 0x0F) << 8) | reg_val[6]; temp_checksum = tpd_check_sum(reg_val); if((temp_checksum==reg_val[7])&&(reg_val[0] == 0x52)) { if ((reg_val[1] == 0xFF) && (reg_val[2] == 0xFF) && (reg_val[3] == 0xFF) && (reg_val[4] == 0xFF) && (reg_val[6] == 0xFF)) { cinfo->x1 = 0; // final X coordinate cinfo->y1 = 0; // final Y coordinate if((reg_val[5]==0x0)||(reg_val[5]==0xFF)) { cinfo->count = 0; //touch end touchData.nTouchKeyCode = 0; //TouchKeyMode touchData.nTouchKeyMode = 0; //TouchKeyMode keycode=0; } else { touchData.nTouchKeyMode = 1; //TouchKeyMode touchData.nTouchKeyCode = reg_val[5]; //TouchKeyCode keycode= reg_val[5]; if(keycode==1) { cinfo->x1 = 256; // final X coordinate cinfo->y1 = 1000; // final Y coordinate } else if(keycode==2) { cinfo->x1 = 192; // final X coordinate cinfo->y1 = 1000; // final Y coordinate } else if (keycode==4) { cinfo->x1 = 128; // final X coordinate cinfo->y1 = 1000; // final Y coordinate } cinfo->count = 1; } } else { touchData.nTouchKeyMode = 0; //Touch on screen... if ((dst_x == 0) && (dst_y == 0)) { cinfo->count = 1; //one touch #if TP_XY_CHANGE xysawp_temp=cinfo->x1; //cinfo->x1=2047-cinfo->y1; cinfo->x1=cinfo->y1; cinfo->y1=xysawp_temp; #endif #ifdef TP_X_CHANGE cinfo->x1 = 2047 - cinfo->x1; #endif cinfo->x1 = (cinfo->x1 * MS_TS_MSG21XX_X_MAX) / 2048; cinfo->y1 = (cinfo->y1 * MS_TS_MSG21XX_Y_MAX) / 2048; } else { cinfo->count = 2; //two touch if (dst_x > 2048) //transform the unsigh value to sign value { dst_x -= 4096; } if (dst_y > 2048) { dst_y -= 4096; } cinfo->x2 = (cinfo->x1 + dst_x); cinfo->y2 = (cinfo->y1 + dst_y); #if TP_XY_CHANGE xysawp_temp=cinfo->x1; //cinfo->x1=2047-cinfo->y1; cinfo->x1=cinfo->y1; cinfo->y1=xysawp_temp; xysawp_temp=cinfo->x2; cinfo->x2=2047-cinfo->y2; cinfo->y2=xysawp_temp; #endif #ifdef TP_X_CHANGE cinfo->x1 = 2047 - cinfo->x1; cinfo->x2 = 2047 - cinfo->x2; #endif cinfo->x1 = (cinfo->x1 * MS_TS_MSG21XX_X_MAX) / 2048; cinfo->y1 = (cinfo->y1 * MS_TS_MSG21XX_Y_MAX) / 2048; cinfo->x2 = (cinfo->x2 * MS_TS_MSG21XX_X_MAX) / 2048; cinfo->y2 = (cinfo->y2 * MS_TS_MSG21XX_Y_MAX) / 2048; } } return 1; } return 1; } static void pixcir_ts_poscheck(struct pixcir_i2c_ts_data *data) { struct pixcir_i2c_ts_data *tsdata = data; struct touch_info cinfo, pinfo; int *p; unsigned char touch; unsigned char rdbuf[27]; int i; //static int lastkey=0; // printk("===%s===\n",__func__); rdbuf[0]=0; //pixcir_i2c_rxdata(rdbuf, 27); //touch = rdbuf[0]&0x07; sy_rxdata(&cinfo, &pinfo); touch = cinfo.count; //button = rdbuf[1]; //p=&rdbuf[2]; p=(int*)&cinfo; // printk("===touch:%d===",touch); for (i=0; i>3); point_slot[i].active = 1; point_slot[i].finger_id = i; point_slot[i].posx = *(p+i*2); point_slot[i].posy = *(p+i*2+1); } if(touch) { //input_report_key(tsdata->input, BTN_TOUCH, 1); //input_report_abs(tsdata->input, ABS_MT_TOUCH_MAJOR, 15); for (i=0; i(MS_TS_MSG21XX_X_MAX -2)) { point_slot[i].posx = (MS_TS_MSG21XX_X_MAX -2); } input_report_abs(tsdata->input, ABS_MT_POSITION_X, point_slot[i].posx); input_report_abs(tsdata->input, ABS_MT_POSITION_Y, point_slot[i].posy); //input_report_abs(tsdata->input, ABS_MT_TOUCH_MAJOR, 15); //input_report_abs(tsdata->input, ABS_MT_WIDTH_MAJOR, 1); input_report_key(tsdata->input, BTN_TOUCH, 1); input_mt_sync(tsdata->input); PIXCIR_DBG("%s: slot=%d,x%d=%d,y%d=%d\n",__func__, i, i/2,point_slot[i].posx, i/2, point_slot[i].posy); } } } } else { PIXCIR_DBG("%s: release\n",__func__); #if 0 //input_report_key(tsdata->input, BTN_TOUCH, 0); input_report_abs(tsdata->input, ABS_MT_TOUCH_MAJOR, 0); input_report_abs(tsdata->input, ABS_MT_WIDTH_MAJOR, 0); input_mt_sync(tsdata->input); #endif input_report_key(tsdata->input, BTN_TOUCH, 0); input_mt_sync(tsdata->input); } PIXCIR_DBG("%s: keycode =%x\n",__func__,keycode); /* if(lastkey!=keycode) { for(i=0;i<3;i++) { input_report_key(tsdata->input, keymap[i], (keycode)&(1<input); for (i=0; iexiting) { pixcir_ts_poscheck(tsdata); #endif //cg,20140402 #if 0 if (attb_read_val()) { PIXCIR_DBG("%s: release\n",__func__); //input_report_key(tsdata->input, BTN_TOUCH, 0); input_report_abs(tsdata->input, ABS_MT_TOUCH_MAJOR, 0); input_sync(tsdata->input); break; } #endif // msleep(10); // } enable_irq(irq); return IRQ_HANDLED; } #ifdef CONFIG_PM_SLEEP static int pixcir_i2c_ts_suspend(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); unsigned char wrbuf[2] = { 0 }; int ret; wrbuf[0] = 0x33; wrbuf[1] = 0x03; //enter into freeze mode; /************************************************************** wrbuf[1]: 0x00: Active mode 0x01: Sleep mode 0xA4: Sleep mode automatically switch 0x03: Freeze mode More details see application note 710 power manangement section ****************************************************************/ ret = i2c_master_send(client, wrbuf, 2); if(ret!=2) { dev_err(&client->dev, "%s: i2c_master_send failed(), ret=%d\n", __func__, ret); } if (device_may_wakeup(&client->dev)) enable_irq_wake(client->irq); return 0; } static int pixcir_i2c_ts_resume(struct device *dev) { struct i2c_client *client = to_i2c_client(dev); ///if suspend enter into freeze mode please reset TP #if 1 pixcir_reset(); #else unsigned char wrbuf[2] = { 0 }; int ret; wrbuf[0] = 0x33; wrbuf[1] = 0; ret = i2c_master_send(client, wrbuf, 2); if(ret!=2) { dev_err(&client->dev, "%s: i2c_master_send failed(), ret=%d\n", __func__, ret); } #endif if (device_may_wakeup(&client->dev)) disable_irq_wake(client->irq); return 0; } #endif static SIMPLE_DEV_PM_OPS(pixcir_dev_pm_ops, pixcir_i2c_ts_suspend, pixcir_i2c_ts_resume); static int tpd_get_bl_info (int show) { int retval = TPD_OK; retval = i2c_smbus_read_i2c_block_data(msg21xx_i2c_client, TPD_REG_BASE, 8, (unsigned char *)&g_bootloader_data); retval += i2c_smbus_read_i2c_block_data(msg21xx_i2c_client, TPD_REG_BASE + 8, 8, (((unsigned char *)&g_bootloader_data) + 8)); TPD_DEBUG("ret=%d,first=0x%02x\n",retval,(unsigned char )(*((unsigned char *)&g_bootloader_data))); if (show) { TPD_DEBUG("BL: bl_file = %02X, bl_status = %02X, bl_error = %02X, blver = %02X%02X, bld_blver = %02X%02X\n", \ g_bootloader_data.bl_file, \ g_bootloader_data.bl_status, \ g_bootloader_data.bl_error, \ g_bootloader_data.blver_hi, g_bootloader_data.blver_lo, \ g_bootloader_data.bld_blver_hi, g_bootloader_data.bld_blver_lo); TPD_DEBUG("BL: ttspver = 0x%02X%02X, appid=0x%02X%02X, appver=0x%02X%02X\n", \ g_bootloader_data.ttspver_hi, g_bootloader_data.ttspver_lo, \ g_bootloader_data.appid_hi, g_bootloader_data.appid_lo, \ g_bootloader_data.appver_hi, g_bootloader_data.appver_lo); TPD_DEBUG("BL: cid = 0x%02X%02X%02X\n", \ g_bootloader_data.cid_0, \ g_bootloader_data.cid_1, \ g_bootloader_data.cid_2); } /*ergate-001*/ //mdelay(100); return retval; } static int sy_init(void) { int retval = TPD_OK; int tries = 0; unsigned char host_reg; host_reg = TPD_SOFT_RESET_MODE; // printk("==sy_init==0=="); retval = i2c_smbus_write_i2c_block_data(msg21xx_i2c_client,TPD_REG_BASE,sizeof(host_reg),&host_reg); // printk("==sy_init==1==retval:%d==",retval); if(retval < TPD_OK) return retval; do{ mdelay(100); retval = tpd_get_bl_info(1); }while(!(retval < TPD_OK) && !GET_BOOTLOADERMODE(g_bootloader_data.bl_status)&& !(g_bootloader_data.bl_file == TPD_OP_MODE + TPD_LOW_PWR_MODE) && tries++ < 10); if(g_bootloader_data.bl_status != (unsigned char )0x11) { if(!(retval < 0)) { host_reg = TPD_OP_MODE; retval = i2c_smbus_write_i2c_block_data(msg21xx_i2c_client,TPD_REG_BASE,sizeof(host_reg),&host_reg); mdelay(100); } if(!(retval < 0)) { TPD_DEBUG("Switch to sysinfo mode \n"); host_reg = TPD_SYSINFO_MODE; retval = i2c_smbus_write_i2c_block_data(msg21xx_i2c_client,TPD_REG_BASE,sizeof(host_reg),&host_reg); mdelay(100); if(!(retval < TPD_OK)) { retval = i2c_smbus_read_i2c_block_data(msg21xx_i2c_client,TPD_REG_BASE, 8, (unsigned char *)&g_sysinfo_data); retval += i2c_smbus_read_i2c_block_data(msg21xx_i2c_client,TPD_REG_BASE + 8, 8, (((unsigned char *)(&g_sysinfo_data)) + 8)); retval += i2c_smbus_read_i2c_block_data(msg21xx_i2c_client,TPD_REG_BASE + 16, 8, (((unsigned char *)(&g_sysinfo_data)) + 16)); retval += i2c_smbus_read_i2c_block_data (msg21xx_i2c_client,TPD_REG_BASE + 24, 8, (((unsigned char *)(&g_sysinfo_data)) + 24)); TPD_DEBUG("SI: hst_mode = 0x%02X, mfg_cmd = 0x%02X, mfg_stat = 0x%02X\n", \ g_sysinfo_data.hst_mode, \ g_sysinfo_data.mfg_cmd, \ g_sysinfo_data.mfg_stat); TPD_DEBUG("SI: bl_ver = 0x%02X%02X\n", \ g_sysinfo_data.bl_verh, \ g_sysinfo_data.bl_verl); TPD_DEBUG("SI: act_int = 0x%02X, tch_tmout = 0x%02X, lp_int = 0x%02X\n", \ g_sysinfo_data.act_intrvl, \ g_sysinfo_data.tch_tmout, \ g_sysinfo_data.lp_intrvl); TPD_DEBUG("SI: tver = %02X%02X, a_id = %02X%02X, aver = %02X%02X\n", \ g_sysinfo_data.tts_verh, \ g_sysinfo_data.tts_verl, \ g_sysinfo_data.app_idh, \ g_sysinfo_data.app_idl, \ g_sysinfo_data.app_verh, \ g_sysinfo_data.app_verl); TPD_DEBUG("SI: c_id = %02X%02X%02X\n", \ g_sysinfo_data.cid[0], \ g_sysinfo_data.cid[1], \ g_sysinfo_data.cid[2]); } TPD_DEBUG("Switch back to operational mode \n"); if (!(retval < TPD_OK)) { host_reg = TPD_OP_MODE; retval = i2c_smbus_write_i2c_block_data(msg21xx_i2c_client, TPD_REG_BASE, sizeof(host_reg), &host_reg); mdelay(100); } } } else { //update_support = 1; TPD_DEBUG("Switch back to operational mode \n"); if (!(retval < TPD_OK)) { unsigned char op_cmds[] = {0x00, 0x00, 0xFF, 0xA5, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07}; //retval = i2c_master_send_ext(i2c_client, op_cmds, sizeof(op_cmds)); retval = i2c_master_send(msg21xx_i2c_client,op_cmds, sizeof(op_cmds)); mdelay(100); } } if(retval > TPD_OK) retval = TPD_OK; return retval; } //#define ITO_TEST #ifdef ITO_TEST static void ito_test_create_entry(void); #endif #ifdef CONFIG_OF static struct msg2138_ts_platform_data *pixcir_ts_parse_dt(struct device *dev) { struct msg2138_ts_platform_data *pdata = NULL; struct device_node *np = dev->of_node; int ret; pdata = kzalloc(sizeof(*pdata), GFP_KERNEL); if (!pdata) { dev_err(dev, "Could not allocate struct msg2138_ts_platform_data"); return NULL; } pdata->reset_gpio_number = of_get_gpio(np, 0); if(pdata->reset_gpio_number < 0){ dev_err(dev, "fail to get reset_gpio_number\n"); goto fail; } pdata->irq_gpio_number = of_get_gpio(np, 1); if(pdata->irq_gpio_number < 0){ dev_err(dev, "fail to get irq_gpio_number\n"); goto fail; } ret = of_property_read_string(np, "vdd_name", &pdata->vdd_name); if(ret){ dev_err(dev, "fail to get vdd_name\n"); goto fail; } ret = of_property_read_u32_array(np, "virtualkeys", &pdata->virtualkeys,12); if(ret){ dev_err(dev, "fail to get virtualkeys\n"); goto fail; } ret = of_property_read_u32(np, "TP_MAX_X", &pdata->TP_MAX_X); if(ret){ dev_err(dev, "fail to get TP_MAX_X\n"); goto fail; } ret = of_property_read_u32(np, "TP_MAX_Y", &pdata->TP_MAX_Y); if(ret){ dev_err(dev, "fail to get TP_MAX_Y\n"); goto fail; } return pdata; fail: kfree(pdata); return NULL; } #endif static int pixcir_i2c_ts_probe(struct i2c_client *client,const struct i2c_device_id *id) { struct msg2138_ts_platform_data *pdata = client->dev.platform_data; struct pixcir_i2c_ts_data *tsdata = NULL; struct input_dev *input = NULL; struct device *dev = NULL; struct i2c_dev *i2c_dev = NULL; int i, error; printk("msg2138 probe in! \n"); #ifdef CONFIG_OF struct device_node *np = client->dev.of_node; if (np && !pdata){ pdata = pixcir_ts_parse_dt(&client->dev); if(pdata){ client->dev.platform_data = pdata; } else{ error = -ENOMEM; goto exit_alloc_platform_data_failed; } } #endif tsdata = kzalloc(sizeof(*tsdata), GFP_KERNEL); if (!tsdata) { error = -ENOMEM; dev_err(&client->dev, "Failed to allocate tsdata!\n"); goto exit_alloc_tsdata_failed; } msg21xx_i2c_client = client; tsdata->client = client; msg21xx_i2c_ts_data = tsdata; tsdata->platform_data = pdata; MS_TS_MSG21XX_X_MAX = pdata->TP_MAX_X; MS_TS_MSG21XX_Y_MAX = pdata->TP_MAX_Y; //client->addr = 0x26; pixcir_ts_hw_init(tsdata); client->irq = gpio_to_irq(pdata->irq_gpio_number); i2c_set_clientdata(client, tsdata); #if defined(CONFIG_I2C_SPRD) || defined(CONFIG_I2C_SPRD_V1) sprd_i2c_ctl_chg_clk(client->adapter->nr, 400000); #endif error = getchipType(); if (error < 0) { pr_err("[MSG2138A] read chip id failed\n"); error = -ENODEV; goto exit_chip_check_failed; } else { printk("[MSG2138A] the chip id is %d\n",error); } for(i=0; idev, "Failed to allocate input device!\n"); error = -ENOMEM; goto exit_input_alloc_failed; } #ifdef TOUCH_VIRTUAL_KEYS pixcir_ts_virtual_keys_init(); #endif tsdata->input = input; global_irq = client->irq; input->name = MSG2138_TS_NAME; input->id.bustype = BUS_I2C; input->dev.parent = &client->dev; __set_bit(EV_KEY, input->evbit); __set_bit(EV_ABS, input->evbit); __set_bit(EV_SYN, input->evbit); //__set_bit(BTN_TOUCH, input->keybit); __set_bit(ABS_MT_TOUCH_MAJOR, input->absbit); __set_bit(ABS_MT_POSITION_X, input->absbit); __set_bit(ABS_MT_POSITION_Y, input->absbit); __set_bit(ABS_MT_WIDTH_MAJOR, input->absbit); __set_bit(KEY_MENU, input->keybit); __set_bit(KEY_BACK, input->keybit); __set_bit(KEY_HOME, input->keybit); __set_bit(KEY_SEARCH, input->keybit); input_set_abs_params(input, ABS_MT_POSITION_X, 0, pdata->TP_MAX_X, 0, 0); input_set_abs_params(input, ABS_MT_POSITION_Y, 0, pdata->TP_MAX_Y, 0, 0); input_set_abs_params(input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(input, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); input_set_drvdata(input, tsdata); error = request_irq(client->irq, pixcir_ts_isr, IRQF_TRIGGER_FALLING, client->name, tsdata); if (error) { dev_err(&client->dev, "Unable to request touchscreen IRQ.\n"); goto exit_requst_irq_failed; } disable_irq_nosync(client->irq); error = input_register_device(input); if (error) goto exit_input_register_failed; device_init_wakeup(&client->dev, 1); /*********************************Bee-0928-TOP****************************************/ i2c_dev = get_free_i2c_dev(client->adapter); if (IS_ERR(i2c_dev)) { error = PTR_ERR(i2c_dev); goto exit_get_i2c_dev_failed; } dev = device_create(i2c_dev_class, &client->adapter->dev, MKDEV(I2C_MAJOR, client->adapter->nr), NULL, "pixcir_i2c_ts%d", 0); if (IS_ERR(dev)) { error = PTR_ERR(dev); goto exit_device_create_failed; } /*********************************Bee-0928-BOTTOM****************************************/ #ifdef CONFIG_HAS_EARLYSUSPEND pixcir_early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; pixcir_early_suspend.suspend = pixcir_ts_suspend; pixcir_early_suspend.resume = pixcir_ts_resume; register_early_suspend(&pixcir_early_suspend); #endif /********* frameware upgrade *********/ #ifdef __FIRMWARE_UPDATE__ 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); // clear // 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); dev_set_drvdata(firmware_cmd_dev, NULL); #endif //__FIRMWARE_UPDATE__ #ifdef ITO_TEST ito_test_create_entry(); #endif #if 0 error = pixcir_create_sysfs(client); if (error) { dev_err(&client->dev, "insmod successfully!\n"); goto exit_create_sysfs_failed; }; #endif #ifdef SYSFS_DEBUG cg_tpfwver_readfwver(); #endif //cg,20130929 #if USE_WAIT_QUEUE thread = kthread_run(touch_event_handler, 0, "pixcir-wait-queue"); if (IS_ERR(thread)) { error = PTR_ERR(thread); dev_err(&client->dev, "failed to create kernel thread\n"); goto exit_kthread_run_failed; } #endif enable_irq(client->irq); //tp_cg_flag=2; printk("[MSG2138A]pixcir_i2c probe success\n"); return 0; exit_kthread_run_failed: exit_create_sysfs_failed: exit_device_create_failed: exit_get_i2c_dev_failed: input_unregister_device(input); exit_input_register_failed: free_irq(client->irq, tsdata); exit_requst_irq_failed: input_free_device(input); exit_input_alloc_failed: exit_chip_check_failed: gpio_free(pdata->irq_gpio_number); gpio_free(pdata->reset_gpio_number); kfree(tsdata); exit_alloc_tsdata_failed: pdata = NULL; client = NULL; exit_alloc_platform_data_failed: return error; } static int pixcir_i2c_ts_remove(struct i2c_client *client) { int error; struct i2c_dev *i2c_dev; struct pixcir_i2c_ts_data *tsdata = i2c_get_clientdata(client); device_init_wakeup(&client->dev, 0); tsdata->exiting = true; mb(); free_irq(client->irq, tsdata); /*********************************Bee-0928-TOP****************************************/ i2c_dev = get_free_i2c_dev(client->adapter); if (IS_ERR(i2c_dev)) { error = PTR_ERR(i2c_dev); return error; } return_i2c_dev(i2c_dev); device_destroy(i2c_dev_class, MKDEV(I2C_MAJOR, client->adapter->nr)); /*********************************Bee-0928-BOTTOM****************************************/ unregister_early_suspend(&pixcir_early_suspend); input_unregister_device(tsdata->input); kfree(tsdata); return 0; } /*************************************Bee-0928****************************************/ /* pixcir_open */ /*************************************Bee-0928****************************************/ static int pixcir_open(struct inode *inode, struct file *file) { int subminor; struct i2c_client *client; struct i2c_adapter *adapter; struct i2c_dev *i2c_dev; int ret = 0; PIXCIR_DBG("enter pixcir_open function\n"); subminor = iminor(inode); // lock_kernel(); i2c_dev = i2c_dev_get_by_minor(subminor); if (!i2c_dev) { //printk("error i2c_dev\n"); return -ENODEV; } adapter = i2c_get_adapter(i2c_dev->adap->nr); if (!adapter) { return -ENODEV; } client = kzalloc(sizeof(*client), GFP_KERNEL); if (!client) { i2c_put_adapter(adapter); ret = -ENOMEM; } snprintf(client->name, I2C_NAME_SIZE, "pixcir_i2c_ts%d", adapter->nr); client->driver = &pixcir_i2c_ts_driver; client->adapter = adapter; file->private_data = client; return 0; } /*************************************Bee-0928****************************************/ /* pixcir_ioctl */ /*************************************Bee-0928****************************************/ static long pixcir_ioctl(struct file *file, unsigned int cmd, unsigned long arg) { //struct i2c_client *client = (struct i2c_client *) file->private_data; PIXCIR_DBG("pixcir_ioctl(),cmd = %d,arg = %ld\n", cmd, arg); #if 0 switch (cmd) { case CALIBRATION_FLAG: //CALIBRATION_FLAG = 1 client->addr = SLAVE_ADDR; status_reg = CALIBRATION_FLAG; break; case BOOTLOADER: //BOOTLOADER = 7 client->addr = BOOTLOADER_ADDR; status_reg = BOOTLOADER; pixcir_reset(); mdelay(5); break; case RESET_TP: //RESET_TP = 9 pixcir_reset(); break; case ENABLE_IRQ: //ENABLE_IRQ = 10 status_reg = 0; enable_irq(global_irq); break; case DISABLE_IRQ: //DISABLE_IRQ = 11 disable_irq_nosync(global_irq); break; case BOOTLOADER_STU: //BOOTLOADER_STU = 12 client->addr = BOOTLOADER_ADDR; status_reg = BOOTLOADER_STU; pixcir_reset(); mdelay(5); case ATTB_VALUE: //ATTB_VALUE = 13 client->addr = SLAVE_ADDR; status_reg = ATTB_VALUE; break; default: client->addr = SLAVE_ADDR; status_reg = 0; break; } #endif return 0; } /***********************************Bee-0928****************************************/ /* pixcir_read */ /***********************************Bee-0928****************************************/ static ssize_t pixcir_read (struct file *file, char __user *buf, size_t count,loff_t *offset) { //struct i2c_client *client = (struct i2c_client *)file->private_data; //unsigned char *tmp, bootloader_stu[4], attb_value[1]; int ret = 0; #if 0 switch(status_reg) { case BOOTLOADER_STU: i2c_master_recv(client, bootloader_stu, sizeof(bootloader_stu)); if (ret!=sizeof(bootloader_stu)) { dev_err(&client->dev, "%s: BOOTLOADER_STU: i2c_master_recv() failed, ret=%d\n", __func__, ret); return -EFAULT; } ret = copy_to_user(buf, bootloader_stu, sizeof(bootloader_stu)); if(ret) { dev_err(&client->dev, "%s: BOOTLOADER_STU: copy_to_user() failed.\n", __func__); return -EFAULT; }else { ret = 4; } break; case ATTB_VALUE: attb_value[0] = attb_read_val(); if(copy_to_user(buf, attb_value, sizeof(attb_value))) { dev_err(&client->dev, "%s: ATTB_VALUE: copy_to_user() failed.\n", __func__); return -EFAULT; }else { ret = 1; } break; default: tmp = kmalloc(count,GFP_KERNEL); if (tmp==NULL) return -ENOMEM; ret = i2c_master_recv(client, tmp, count); if (ret != count) { dev_err(&client->dev, "%s: default: i2c_master_recv() failed, ret=%d\n", __func__, ret); return -EFAULT; } if(copy_to_user(buf, tmp, count)) { dev_err(&client->dev, "%s: default: copy_to_user() failed.\n", __func__); kfree(tmp); return -EFAULT; } kfree(tmp); break; } #endif return ret; } /***********************************Bee-0928****************************************/ /* pixcir_write */ /***********************************Bee-0928****************************************/ static ssize_t pixcir_write(struct file *file,const char __user *buf,size_t count, loff_t *ppos) { //struct i2c_client *client; //unsigned char *tmp, bootload_data[143]; int ret=0; #if 0 client = file->private_data; switch(status_reg) { case CALIBRATION_FLAG: //CALIBRATION_FLAG=1 tmp = kmalloc(count,GFP_KERNEL); if (tmp==NULL) return -ENOMEM; if (copy_from_user(tmp,buf,count)) { dev_err(&client->dev, "%s: CALIBRATION_FLAG: copy_from_user() failed.\n", __func__); kfree(tmp); return -EFAULT; } ret = i2c_master_send(client,tmp,count); if (ret!=count ) { dev_err(&client->dev, "%s: CALIBRATION: i2c_master_send() failed, ret=%d\n", __func__, ret); kfree(tmp); return -EFAULT; } while(!attb_read_val()) { msleep(100); i++; if(i>99) break; //10s no high aatb break } //waiting to finish the calibration.(pixcir application_note_710_v3 p43) kfree(tmp); break; case BOOTLOADER: memset(bootload_data, 0, sizeof(bootload_data)); if (copy_from_user(bootload_data, buf, count)) { dev_err(&client->dev, "%s: BOOTLOADER: copy_from_user() failed.\n", __func__); return -EFAULT; } ret = i2c_master_send(client, bootload_data, count); if(ret!=count) { dev_err(&client->dev, "%s: BOOTLOADER: i2c_master_send() failed, ret = %d\n", __func__, ret); return -EFAULT; } break; default: tmp = kmalloc(count,GFP_KERNEL); if (tmp==NULL) return -ENOMEM; if (copy_from_user(tmp,buf,count)) { dev_err(&client->dev, "%s: default: copy_from_user() failed.\n", __func__); kfree(tmp); return -EFAULT; } ret = i2c_master_send(client,tmp,count); if (ret!=count ) { dev_err(&client->dev, "%s: default: i2c_master_send() failed, ret=%d\n", __func__, ret); kfree(tmp); return -EFAULT; } kfree(tmp); break; } #endif return ret; } /***********************************Bee-0928****************************************/ /* pixcir_release */ /***********************************Bee-0928****************************************/ static int pixcir_release(struct inode *inode, struct file *file) { struct i2c_client *client = file->private_data; PIXCIR_DBG("enter pixcir_release funtion\n"); i2c_put_adapter(client->adapter); kfree(client); file->private_data = NULL; return 0; } /*********************************Bee-0928-TOP****************************************/ static const struct file_operations pixcir_i2c_ts_fops = { .owner = THIS_MODULE, .read = pixcir_read, .write = pixcir_write, .open = pixcir_open, .unlocked_ioctl = pixcir_ioctl, .release = pixcir_release, }; /*********************************Bee-0928-BOTTOM****************************************/ static const struct i2c_device_id pixcir_i2c_ts_id[] = { { MSG2138_TS_NAME, MSG2138_TS_ADDR },//0 { } }; MODULE_DEVICE_TABLE(i2c, pixcir_i2c_ts_id); #if 0 static unsigned short force[] = {0,0x4c,I2C_CLIENT_END,I2C_CLIENT_END}; static const unsigned short * const forces[] = { force, NULL }; static struct i2c_client_address_data addr_data = { .forces = forces, }; #endif static const struct of_device_id msg2138_of_match[] = { { .compatible = "Mstar,msg2138_ts", }, { } }; MODULE_DEVICE_TABLE(of, msg2138_of_match); static struct i2c_driver pixcir_i2c_ts_driver = { .driver = { .owner = THIS_MODULE, .name = MSG2138_TS_NAME, .of_match_table = msg2138_of_match, }, .probe = pixcir_i2c_ts_probe, .remove = pixcir_i2c_ts_remove, .id_table = pixcir_i2c_ts_id, }; static int __init pixcir_i2c_ts_init(void) { int ret; /*if (0 != tp_cg_flag) { return -ENODEV; }*/ /*********************************Bee-0928-TOP****************************************/ TPD_DEBUG("msg2138 init111!\n"); ret = register_chrdev(I2C_MAJOR,"pixcir_i2c_ts",&pixcir_i2c_ts_fops); if (ret) { //printk(KERN_ERR "%s:register chrdev failed\n",__FILE__); return ret; } TPD_DEBUG("msg2138 init222!\n"); i2c_dev_class = class_create(THIS_MODULE, "pixcir_i2c_dev"); if (IS_ERR(i2c_dev_class)) { ret = PTR_ERR(i2c_dev_class); class_destroy(i2c_dev_class); } /********************************Bee-0928-BOTTOM******************************************/ return i2c_add_driver(&pixcir_i2c_ts_driver); } static void pixcir_i2c_ts_exit(void) { i2c_del_driver(&pixcir_i2c_ts_driver); /********************************Bee-0928-TOP******************************************/ class_destroy(i2c_dev_class); unregister_chrdev(I2C_MAJOR,"pixcir_i2c_ts"); /********************************Bee-0928-BOTTOM******************************************/ } module_init(pixcir_i2c_ts_init); module_exit(pixcir_i2c_ts_exit); #ifdef ITO_TEST #include "./ito_test/open_test_ANA1_8861A_lianchuang.h" #include "./ito_test/open_test_ANA2_8861A_lianchuang.h" #include "./ito_test/open_test_ANA1_B_8861A_lianchuang.h" #include "./ito_test/open_test_ANA2_B_8861A_lianchuang.h" #include "./ito_test/open_test_ANA3_8861A_lianchuang.h" /////////////////////////////////////////////////////////////////////////// u8 bItoTestDebug = 0; #define ITO_TEST_DEBUG(format, ...) \ { \ if(bItoTestDebug) \ { \ printk(KERN_ERR "ito_test ***" format "\n", ## __VA_ARGS__); \ mdelay(5); \ } \ } #define ITO_TEST_DEBUG_MUST(format, ...) printk(KERN_ERR "ito_test ***" format "\n", ## __VA_ARGS__);mdelay(5) s16 s16_raw_data_1[48] = {0}; s16 s16_raw_data_2[48] = {0}; s16 s16_raw_data_3[48] = {0}; u8 ito_test_keynum = 0; u8 ito_test_dummynum = 0; u8 ito_test_trianglenum = 0; u8 ito_test_2r = 0; u8 g_LTP = 1; uint16_t *open_1 = NULL; uint16_t *open_1B = NULL; uint16_t *open_2 = NULL; uint16_t *open_2B = NULL; uint16_t *open_3 = NULL; u8 *MAP1 = NULL; u8 *MAP2=NULL; u8 *MAP3=NULL; u8 *MAP40_1 = NULL; u8 *MAP40_2 = NULL; u8 *MAP40_3 = NULL; u8 *MAP40_4 = NULL; u8 *MAP41_1 = NULL; u8 *MAP41_2 = NULL; u8 *MAP41_3 = NULL; u8 *MAP41_4 = NULL; #define ITO_TEST_ADDR_TP (0x4C>>1) #define ITO_TEST_ADDR_REG (0xC4>>1) #define REG_INTR_FIQ_MASK 0x04 #define FIQ_E_FRAME_READY_MASK ( 1 << 8 ) #define MAX_CHNL_NUM (48) #define BIT0 (1<<0) #define BIT1 (1<<1) #define BIT5 (1<<5) #define BIT11 (1<<11) #define BIT15 (1<<15) static int ito_test_i2c_read(u8 addr, u8* read_data, u16 size) { int rc; u8 addr_before = msg21xx_i2c_client->addr; msg21xx_i2c_client->addr = addr; #ifdef DMA_IIC if(size>8&&NULL!=I2CDMABuf_va) { int i = 0; msg21xx_i2c_client->ext_flag = msg21xx_i2c_client->ext_flag | I2C_DMA_FLAG ; rc = i2c_master_recv(msg21xx_i2c_client, (unsigned char *)I2CDMABuf_pa, size); for(i = 0; i < size; i++) { read_data[i] = I2CDMABuf_va[i]; } } else { rc = i2c_master_recv(msg21xx_i2c_client, read_data, size); } msg21xx_i2c_client->ext_flag = msg21xx_i2c_client->ext_flag & (~I2C_DMA_FLAG); #else rc = i2c_master_recv(msg21xx_i2c_client, read_data, size); #endif msg21xx_i2c_client->addr = addr_before; if( rc < 0 ) { ITO_TEST_DEBUG_MUST("ito_test_i2c_read error %d,addr=%d\n", rc,addr); } return rc; } static int ito_test_i2c_write(u8 addr, u8* data, u16 size) { int rc; u8 addr_before = msg21xx_i2c_client->addr; msg21xx_i2c_client->addr = addr; #ifdef DMA_IIC if(size>8&&NULL!=I2CDMABuf_va) { int i = 0; for(i=0;iext_flag = msg21xx_i2c_client->ext_flag | I2C_DMA_FLAG ; rc = i2c_master_send(msg21xx_i2c_client, (unsigned char *)I2CDMABuf_pa, size); } else { rc = i2c_master_send(msg21xx_i2c_client, data, size); } msg21xx_i2c_client->ext_flag = msg21xx_i2c_client->ext_flag & (~I2C_DMA_FLAG); #else rc = i2c_master_send(msg21xx_i2c_client, data, size); #endif msg21xx_i2c_client->addr = addr_before; if( rc < 0 ) { ITO_TEST_DEBUG_MUST("ito_test_i2c_write error %d,addr = %d,data[0]=%d\n", rc, addr,data[0]); } return rc; } static void ito_test_reset(void) { struct msg2138_ts_platform_data *pdata = msg21xx_i2c_ts_data->platform_data; gpio_direction_output(pdata->reset_gpio_number, 1); gpio_set_value(pdata->reset_gpio_number, 1); gpio_set_value(pdata->reset_gpio_number, 0); mdelay(100); ITO_TEST_DEBUG("reset tp\n"); gpio_set_value(pdata->reset_gpio_number, 1); mdelay(200); } static void ito_test_disable_irq(void) { disable_irq_nosync(global_irq); } static void ito_test_enable_irq(void) { enable_irq(global_irq); } static void ito_test_set_iic_rate(u32 iicRate) { #ifdef CONFIG_I2C_SPRD sprd_i2c_ctl_chg_clk(msg21xx_i2c_client->adapter->nr, iicRate); mdelay(100); #endif #if MTK msg21xx_i2c_client->timing = iicRate/1000; #endif } static void ito_test_WriteReg( u8 bank, u8 addr, u16 data ) { u8 tx_data[5] = {0x10, bank, addr, data & 0xFF, data >> 8}; ito_test_i2c_write( ITO_TEST_ADDR_REG, &tx_data[0], 5 ); } static void ito_test_WriteReg8Bit( u8 bank, u8 addr, u8 data ) { u8 tx_data[4] = {0x10, bank, addr, data}; ito_test_i2c_write ( ITO_TEST_ADDR_REG, &tx_data[0], 4 ); } static unsigned short ito_test_ReadReg( u8 bank, u8 addr ) { u8 tx_data[3] = {0x10, bank, addr}; u8 rx_data[2] = {0}; ito_test_i2c_write( ITO_TEST_ADDR_REG, &tx_data[0], 3 ); ito_test_i2c_read ( ITO_TEST_ADDR_REG, &rx_data[0], 2 ); return ( rx_data[1] << 8 | rx_data[0] ); } static u32 ito_test_get_TpType(void) { u8 tx_data[3] = {0}; u8 rx_data[4] = {0}; u32 Major = 0, Minor = 0; ITO_TEST_DEBUG("GetTpType\n"); tx_data[0] = 0x53; tx_data[1] = 0x00; tx_data[2] = 0x2A; ito_test_i2c_write(ITO_TEST_ADDR_TP, &tx_data[0], 3); mdelay(50); ito_test_i2c_read(ITO_TEST_ADDR_TP, &rx_data[0], 4); Major = (rx_data[1]<<8) + rx_data[0]; Minor = (rx_data[3]<<8) + rx_data[2]; ITO_TEST_DEBUG("***TpTypeMajor = %d ***\n", Major); ITO_TEST_DEBUG("***TpTypeMinor = %d ***\n", Minor); return Major; } #define TP_OF_LIANCHUANG (2) static u32 ito_test_choose_TpType(void) { u32 tpType = 0; u8 i = 0; open_1 = NULL; open_1B = NULL; open_2 = NULL; open_2B = NULL; open_3 = NULL; MAP1 = NULL; MAP2 = NULL; MAP3 = NULL; MAP40_1 = NULL; MAP40_2 = NULL; MAP40_3 = NULL; MAP40_4 = NULL; MAP41_1 = NULL; MAP41_2 = NULL; MAP41_3 = NULL; MAP41_4 = NULL; ito_test_keynum = 0; ito_test_dummynum = 0; ito_test_trianglenum = 0; ito_test_2r = 0; for(i=0;i<10;i++) { tpType = ito_test_get_TpType(); ITO_TEST_DEBUG("tpType=%d;i=%d;\n",tpType,i); if(TP_OF_LIANCHUANG==tpType) { break; } else if(i<5) { mdelay(100); } else { ito_test_reset(); } } if(TP_OF_LIANCHUANG==tpType) { open_1 = open_1_lianchuang; open_1B = open_1B_lianchuang; open_2 = open_2_lianchuang; open_2B = open_2B_lianchuang; open_3 = open_3_lianchuang; MAP1 = MAP1_lianchuang; MAP2 = MAP2_lianchuang; MAP3 = MAP3_lianchuang; MAP40_1 = MAP40_1_lianchuang; MAP40_2 = MAP40_2_lianchuang; MAP40_3 = MAP40_3_lianchuang; MAP40_4 = MAP40_4_lianchuang; MAP41_1 = MAP41_1_lianchuang; MAP41_2 = MAP41_2_lianchuang; MAP41_3 = MAP41_3_lianchuang; MAP41_4 = MAP41_4_lianchuang; ito_test_keynum = NUM_KEY_LIANCHUANG; ito_test_dummynum = NUM_DUMMY_LIANCHUANG; ito_test_trianglenum = NUM_SENSOR_LIANCHUANG; ito_test_2r = ENABLE_2R_LIANCHUANG; } else { tpType = 0; } return tpType; } static void ito_test_EnterSerialDebugMode(void) { u8 data[5]; data[0] = 0x53; data[1] = 0x45; data[2] = 0x52; data[3] = 0x44; data[4] = 0x42; ito_test_i2c_write(ITO_TEST_ADDR_REG, &data[0], 5); data[0] = 0x37; ito_test_i2c_write(ITO_TEST_ADDR_REG, &data[0], 1); data[0] = 0x35; ito_test_i2c_write(ITO_TEST_ADDR_REG, &data[0], 1); data[0] = 0x71; ito_test_i2c_write(ITO_TEST_ADDR_REG, &data[0], 1); } static uint16_t ito_test_get_num( void ) { uint16_t num_of_sensor,i; uint16_t RegValue1,RegValue2; num_of_sensor = 0; RegValue1 = ito_test_ReadReg( 0x11, 0x4A); ITO_TEST_DEBUG("ito_test_get_num,RegValue1=%d\n",RegValue1); if ( ( RegValue1 & BIT1) == BIT1 ) { RegValue1 = ito_test_ReadReg( 0x12, 0x0A); RegValue1 = RegValue1 & 0x0F; RegValue2 = ito_test_ReadReg( 0x12, 0x16); RegValue2 = (( RegValue2 >> 1 ) & 0x0F) + 1; num_of_sensor = RegValue1 * RegValue2; } else { for(i=0;i<4;i++) { num_of_sensor+=(ito_test_ReadReg( 0x12, 0x0A)>>(4*i))&0x0F; } } ITO_TEST_DEBUG("ito_test_get_num,num_of_sensor=%d\n",num_of_sensor); return num_of_sensor; } static void ito_test_polling( void ) { uint16_t reg_int = 0x0000; uint8_t dbbus_tx_data[5]; uint8_t dbbus_rx_data[4]; uint16_t reg_value; reg_int = 0; ito_test_WriteReg( 0x13, 0x0C, BIT15 ); ito_test_WriteReg( 0x12, 0x14, (ito_test_ReadReg(0x12,0x14) | BIT0) ); ITO_TEST_DEBUG("polling start\n"); while( ( reg_int & BIT0 ) == 0x0000 ) { dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x3D; dbbus_tx_data[2] = 0x18; ito_test_i2c_write(ITO_TEST_ADDR_REG, dbbus_tx_data, 3); ito_test_i2c_read(ITO_TEST_ADDR_REG, dbbus_rx_data, 2); reg_int = dbbus_rx_data[1]; } ITO_TEST_DEBUG("polling end\n"); reg_value = ito_test_ReadReg( 0x3D, 0x18 ); ito_test_WriteReg( 0x3D, 0x18, reg_value & (~BIT0) ); } static uint16_t ito_test_get_data_out( int16_t* s16_raw_data ) { uint8_t i,dbbus_tx_data[8]; uint16_t raw_data[48]={0}; uint16_t num_of_sensor; uint16_t reg_int; uint8_t dbbus_rx_data[96]={0}; num_of_sensor = ito_test_get_num(); if(num_of_sensor*2>96) { ITO_TEST_DEBUG("danger,num_of_sensor=%d\n",num_of_sensor); return num_of_sensor; } reg_int = ito_test_ReadReg( 0x3d, REG_INTR_FIQ_MASK<<1 ); ito_test_WriteReg( 0x3d, REG_INTR_FIQ_MASK<<1, (reg_int & (uint16_t)(~FIQ_E_FRAME_READY_MASK) ) ); ito_test_polling(); dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x13; dbbus_tx_data[2] = 0x40; ito_test_i2c_write(ITO_TEST_ADDR_REG, dbbus_tx_data, 3); mdelay(20); ito_test_i2c_read(ITO_TEST_ADDR_REG, &dbbus_rx_data[0], (num_of_sensor * 2)); mdelay(100); for(i=0;i> 8 ) & 0xFF; } ito_test_i2c_write(ITO_TEST_ADDR_REG, dbbus_tx_data, 3+0x3F*2); dbbus_tx_data[2] = 0x7A * 2; for( i = 0x7A; i <= 0x7D ; i++ ) { dbbus_tx_data[3+2*(i-0x7A)] = 0; dbbus_tx_data[4+2*(i-0x7A)] = 0; } ito_test_i2c_write(ITO_TEST_ADDR_REG, dbbus_tx_data, 3+8); dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x12; dbbus_tx_data[2] = 5 * 2; dbbus_tx_data[3] = Type1[128+5] & 0xFF; dbbus_tx_data[4] = ( Type1[128+5] >> 8 ) & 0xFF; ito_test_i2c_write(ITO_TEST_ADDR_REG, dbbus_tx_data, 5); dbbus_tx_data[2] = 0x0B * 2; dbbus_tx_data[3] = Type1[128+0x0B] & 0xFF; dbbus_tx_data[4] = ( Type1[128+0x0B] >> 8 ) & 0xFF; ito_test_i2c_write(ITO_TEST_ADDR_REG, dbbus_tx_data, 5); dbbus_tx_data[2] = 0x12 * 2; dbbus_tx_data[3] = Type1[128+0x12] & 0xFF; dbbus_tx_data[4] = ( Type1[128+0x12] >> 8 ) & 0xFF; ito_test_i2c_write(ITO_TEST_ADDR_REG, dbbus_tx_data, 5); dbbus_tx_data[2] = 0x15 * 2; dbbus_tx_data[3] = Type1[128+0x15] & 0xFF; dbbus_tx_data[4] = ( Type1[128+0x15] >> 8 ) & 0xFF; ito_test_i2c_write(ITO_TEST_ADDR_REG, dbbus_tx_data, 5); } static void ito_test_set_v( uint8_t Enable, uint8_t Prs) { uint16_t u16RegValue; u16RegValue = ito_test_ReadReg( 0x12, 0x08); u16RegValue = u16RegValue & 0xF1; if ( Prs == 0 ) { ito_test_WriteReg( 0x12, 0x08, u16RegValue| 0x0C); } else if ( Prs == 1 ) { ito_test_WriteReg( 0x12, 0x08, u16RegValue| 0x0E); } else { ito_test_WriteReg( 0x12, 0x08, u16RegValue| 0x02); } if ( Enable ) { u16RegValue = ito_test_ReadReg( 0x11, 0x06); ito_test_WriteReg( 0x11, 0x06, u16RegValue| 0x03); } else { u16RegValue = ito_test_ReadReg( 0x11, 0x06); u16RegValue = u16RegValue & 0xFC; ito_test_WriteReg( 0x11, 0x06, u16RegValue); } } static void ito_test_set_c( uint8_t Csub_Step ) { uint8_t i; uint8_t dbbus_tx_data[MAX_CHNL_NUM+3]; uint8_t HighLevel_Csub = false; uint8_t Csub_new; dbbus_tx_data[0] = 0x10; dbbus_tx_data[1] = 0x11; dbbus_tx_data[2] = 0x84; for( i = 0; i < MAX_CHNL_NUM; i++ ) { Csub_new = Csub_Step; HighLevel_Csub = false; if( Csub_new > 0x1F ) { Csub_new = Csub_new - 0x14; HighLevel_Csub = true; } dbbus_tx_data[3+i] = Csub_new & 0x1F; if( HighLevel_Csub == true ) { dbbus_tx_data[3+i] |= BIT5; } } ito_test_i2c_write(ITO_TEST_ADDR_REG, dbbus_tx_data, MAX_CHNL_NUM+3); dbbus_tx_data[2] = 0xB4; ito_test_i2c_write(ITO_TEST_ADDR_REG, dbbus_tx_data, MAX_CHNL_NUM+3); } static void ito_test_sw( void ) { ito_test_WriteReg( 0x11, 0x00, 0xFFFF ); ito_test_WriteReg( 0x11, 0x00, 0x0000 ); mdelay( 50 ); } static void ito_test_first( uint8_t item_id , int16_t* s16_raw_data) { uint8_t result = 0,loop; uint8_t dbbus_tx_data[9]; uint8_t i,j; int16_t s16_raw_data_tmp[48]={0}; uint8_t num_of_sensor, num_of_sensor2,total_sensor; uint16_t u16RegValue; uint8_t *pMapping=NULL; num_of_sensor = 0; num_of_sensor2 = 0; ITO_TEST_DEBUG("ito_test_first item_id=%d\n",item_id); ito_test_WriteReg( 0x0F, 0xE6, 0x01 ); ito_test_WriteReg( 0x1E, 0x24, 0x0500 ); ito_test_WriteReg( 0x1E, 0x2A, 0x0000 ); ito_test_WriteReg( 0x1E, 0xE6, 0x6E00 ); ito_test_WriteReg( 0x1E, 0xE8, 0x0071 ); if ( item_id == 40 ) { pMapping = &MAP1[0]; if ( ito_test_2r ) { total_sensor = ito_test_trianglenum/2; } else { total_sensor = ito_test_trianglenum/2 + ito_test_keynum + ito_test_dummynum; } } else if( item_id == 41 ) { pMapping = &MAP2[0]; if ( ito_test_2r ) { total_sensor = ito_test_trianglenum/2; } else { total_sensor = ito_test_trianglenum/2 + ito_test_keynum + ito_test_dummynum; } } else if( item_id == 42 ) { pMapping = &MAP3[0]; total_sensor = ito_test_trianglenum + ito_test_keynum+ ito_test_dummynum; } loop = 1; if ( item_id != 42 ) { if(total_sensor>11) { loop = 2; } } ITO_TEST_DEBUG("loop=%d\n",loop); for ( i = 0; i < loop; i++ ) { if ( i == 0 ) { ito_test_send_data_in( item_id - 36 ); } else { if ( item_id == 40 ) ito_test_send_data_in( 9 ); else ito_test_send_data_in( 10 ); } ito_test_set_v(1,0); u16RegValue = ito_test_ReadReg( 0x11, 0x0E); ito_test_WriteReg( 0x11, 0x0E, u16RegValue | BIT11 ); if ( g_LTP == 1 ) ito_test_set_c( 32 ); else ito_test_set_c( 0 ); ito_test_sw(); if ( i == 0 ) { num_of_sensor=ito_test_get_data_out( s16_raw_data_tmp ); ITO_TEST_DEBUG("num_of_sensor=%d;\n",num_of_sensor); } else { num_of_sensor2=ito_test_get_data_out( &s16_raw_data_tmp[num_of_sensor] ); ITO_TEST_DEBUG("num_of_sensor=%d;num_of_sensor2=%d\n",num_of_sensor,num_of_sensor2); } } for ( j = 0; j < total_sensor ; j ++ ) { if ( g_LTP == 1 ) s16_raw_data[pMapping[j]] = s16_raw_data_tmp[j] + 4096; else s16_raw_data[pMapping[j]] = s16_raw_data_tmp[j]; } return; } typedef enum { ITO_TEST_OK = 0, ITO_TEST_FAIL, ITO_TEST_GET_TP_TYPE_ERROR, } ITO_TEST_RET; ITO_TEST_RET ito_test_second (u8 item_id) { u8 i = 0; s32 s16_raw_data_jg_tmp1 = 0; s32 s16_raw_data_jg_tmp2 = 0; s32 jg_tmp1_avg_Th_max =0; s32 jg_tmp1_avg_Th_min =0; s32 jg_tmp2_avg_Th_max =0; s32 jg_tmp2_avg_Th_min =0; u8 Th_Tri = 25; u8 Th_bor = 25; if ( item_id == 40 ) { for (i=0; i<(ito_test_trianglenum/2)-2; i++) { s16_raw_data_jg_tmp1 += s16_raw_data_1[MAP40_1[i]]; } for (i=0; i<2; i++) { s16_raw_data_jg_tmp2 += s16_raw_data_1[MAP40_2[i]]; } } else if( item_id == 41 ) { for (i=0; i<(ito_test_trianglenum/2)-2; i++) { s16_raw_data_jg_tmp1 += s16_raw_data_2[MAP41_1[i]]; } for (i=0; i<2; i++) { s16_raw_data_jg_tmp2 += s16_raw_data_2[MAP41_2[i]]; } } jg_tmp1_avg_Th_max = (s16_raw_data_jg_tmp1 / ((ito_test_trianglenum/2)-2)) * ( 100 + Th_Tri) / 100 ; jg_tmp1_avg_Th_min = (s16_raw_data_jg_tmp1 / ((ito_test_trianglenum/2)-2)) * ( 100 - Th_Tri) / 100 ; jg_tmp2_avg_Th_max = (s16_raw_data_jg_tmp2 / 2) * ( 100 + Th_bor) / 100 ; jg_tmp2_avg_Th_min = (s16_raw_data_jg_tmp2 / 2 ) * ( 100 - Th_bor) / 100 ; ITO_TEST_DEBUG("item_id=%d;sum1=%d;max1=%d;min1=%d;sum2=%d;max2=%d;min2=%d\n",item_id,s16_raw_data_jg_tmp1,jg_tmp1_avg_Th_max,jg_tmp1_avg_Th_min,s16_raw_data_jg_tmp2,jg_tmp2_avg_Th_max,jg_tmp2_avg_Th_min); if ( item_id == 40 ) { for (i=0; i<(ito_test_trianglenum/2)-2; i++) { if (s16_raw_data_1[MAP40_1[i]] > jg_tmp1_avg_Th_max || s16_raw_data_1[MAP40_1[i]] < jg_tmp1_avg_Th_min) return ITO_TEST_FAIL; } for (i=0; i<(ito_test_trianglenum/2)-3; i++) { if (s16_raw_data_1[MAP40_1[i]] > s16_raw_data_1[MAP40_1[i+1]] ) return ITO_TEST_FAIL; } for (i=0; i<2; i++) { if (s16_raw_data_1[MAP40_2[i]] > jg_tmp2_avg_Th_max || s16_raw_data_1[MAP40_2[i]] < jg_tmp2_avg_Th_min) return ITO_TEST_FAIL; } } if ( item_id == 41 ) { for (i=0; i<(ito_test_trianglenum/2)-2; i++) { if (s16_raw_data_2[MAP41_1[i]] > jg_tmp1_avg_Th_max || s16_raw_data_2[MAP41_1[i]] < jg_tmp1_avg_Th_min) return ITO_TEST_FAIL; } for (i=0; i<(ito_test_trianglenum/2)-3; i++) { if (s16_raw_data_2[MAP41_1[i]] < s16_raw_data_2[MAP41_1[i+1]] ) return ITO_TEST_FAIL; } for (i=0; i<2; i++) { if (s16_raw_data_2[MAP41_2[i]] > jg_tmp2_avg_Th_max || s16_raw_data_2[MAP41_2[i]] < jg_tmp2_avg_Th_min) return ITO_TEST_FAIL; } } return ITO_TEST_OK; } ITO_TEST_RET ito_test_second_2r (u8 item_id) { u8 i = 0; s32 s16_raw_data_jg_tmp1 = 0; s32 s16_raw_data_jg_tmp2 = 0; s32 s16_raw_data_jg_tmp3 = 0; s32 s16_raw_data_jg_tmp4 = 0; s32 jg_tmp1_avg_Th_max =0; s32 jg_tmp1_avg_Th_min =0; s32 jg_tmp2_avg_Th_max =0; s32 jg_tmp2_avg_Th_min =0; s32 jg_tmp3_avg_Th_max =0; s32 jg_tmp3_avg_Th_min =0; s32 jg_tmp4_avg_Th_max =0; s32 jg_tmp4_avg_Th_min =0; u8 Th_Tri = 25; // non-border threshold u8 Th_bor = 25; // border threshold if ( item_id == 40 ) { for (i=0; i<(ito_test_trianglenum/4)-2; i++) { s16_raw_data_jg_tmp1 += s16_raw_data_1[MAP40_1[i]]; //first region: non-border } for (i=0; i<2; i++) { s16_raw_data_jg_tmp2 += s16_raw_data_1[MAP40_2[i]]; //first region: border } for (i=0; i<(ito_test_trianglenum/4)-2; i++) { s16_raw_data_jg_tmp3 += s16_raw_data_1[MAP40_3[i]]; //second region: non-border } for (i=0; i<2; i++) { s16_raw_data_jg_tmp4 += s16_raw_data_1[MAP40_4[i]]; //second region: border } } else if( item_id == 41 ) { for (i=0; i<(ito_test_trianglenum/4)-2; i++) { s16_raw_data_jg_tmp1 += s16_raw_data_2[MAP41_1[i]]; //first region: non-border } for (i=0; i<2; i++) { s16_raw_data_jg_tmp2 += s16_raw_data_2[MAP41_2[i]]; //first region: border } for (i=0; i<(ito_test_trianglenum/4)-2; i++) { s16_raw_data_jg_tmp3 += s16_raw_data_2[MAP41_3[i]]; //second region: non-border } for (i=0; i<2; i++) { s16_raw_data_jg_tmp4 += s16_raw_data_2[MAP41_4[i]]; //second region: border } } jg_tmp1_avg_Th_max = (s16_raw_data_jg_tmp1 / ((ito_test_trianglenum/4)-2)) * ( 100 + Th_Tri) / 100 ; jg_tmp1_avg_Th_min = (s16_raw_data_jg_tmp1 / ((ito_test_trianglenum/4)-2)) * ( 100 - Th_Tri) / 100 ; jg_tmp2_avg_Th_max = (s16_raw_data_jg_tmp2 / 2) * ( 100 + Th_bor) / 100 ; jg_tmp2_avg_Th_min = (s16_raw_data_jg_tmp2 / 2) * ( 100 - Th_bor) / 100 ; jg_tmp3_avg_Th_max = (s16_raw_data_jg_tmp3 / ((ito_test_trianglenum/4)-2)) * ( 100 + Th_Tri) / 100 ; jg_tmp3_avg_Th_min = (s16_raw_data_jg_tmp3 / ((ito_test_trianglenum/4)-2)) * ( 100 - Th_Tri) / 100 ; jg_tmp4_avg_Th_max = (s16_raw_data_jg_tmp4 / 2) * ( 100 + Th_bor) / 100 ; jg_tmp4_avg_Th_min = (s16_raw_data_jg_tmp4 / 2) * ( 100 - Th_bor) / 100 ; ITO_TEST_DEBUG("item_id=%d;sum1=%d;max1=%d;min1=%d;sum2=%d;max2=%d;min2=%d;sum3=%d;max3=%d;min3=%d;sum4=%d;max4=%d;min4=%d;\n",item_id,s16_raw_data_jg_tmp1,jg_tmp1_avg_Th_max,jg_tmp1_avg_Th_min,s16_raw_data_jg_tmp2,jg_tmp2_avg_Th_max,jg_tmp2_avg_Th_min,s16_raw_data_jg_tmp3,jg_tmp3_avg_Th_max,jg_tmp3_avg_Th_min,s16_raw_data_jg_tmp4,jg_tmp4_avg_Th_max,jg_tmp4_avg_Th_min); if ( item_id == 40 ) { for (i=0; i<(ito_test_trianglenum/4)-2; i++) { if (s16_raw_data_1[MAP40_1[i]] > jg_tmp1_avg_Th_max || s16_raw_data_1[MAP40_1[i]] < jg_tmp1_avg_Th_min) return ITO_TEST_FAIL; } for (i=0; i<2; i++) { if (s16_raw_data_1[MAP40_2[i]] > jg_tmp2_avg_Th_max || s16_raw_data_1[MAP40_2[i]] < jg_tmp2_avg_Th_min) return ITO_TEST_FAIL; } for (i=0; i<(ito_test_trianglenum/4)-2; i++) { if (s16_raw_data_1[MAP40_3[i]] > jg_tmp3_avg_Th_max || s16_raw_data_1[MAP40_3[i]] < jg_tmp3_avg_Th_min) return ITO_TEST_FAIL; } for (i=0; i<2; i++) { if (s16_raw_data_1[MAP40_4[i]] > jg_tmp4_avg_Th_max || s16_raw_data_1[MAP40_4[i]] < jg_tmp4_avg_Th_min) return ITO_TEST_FAIL; } } if ( item_id == 41 ) { for (i=0; i<(ito_test_trianglenum/4)-2; i++) { if (s16_raw_data_2[MAP41_1[i]] > jg_tmp1_avg_Th_max || s16_raw_data_2[MAP41_1[i]] < jg_tmp1_avg_Th_min) return ITO_TEST_FAIL; } for (i=0; i<2; i++) { if (s16_raw_data_2[MAP41_2[i]] > jg_tmp2_avg_Th_max || s16_raw_data_2[MAP41_2[i]] < jg_tmp2_avg_Th_min) return ITO_TEST_FAIL; } for (i=0; i<(ito_test_trianglenum/4)-2; i++) { if (s16_raw_data_2[MAP41_3[i]] > jg_tmp3_avg_Th_max || s16_raw_data_2[MAP41_3[i]] < jg_tmp3_avg_Th_min) return ITO_TEST_FAIL; } for (i=0; i<2; i++) { if (s16_raw_data_2[MAP41_4[i]] > jg_tmp4_avg_Th_max || s16_raw_data_2[MAP41_4[i]] < jg_tmp4_avg_Th_min) return ITO_TEST_FAIL; } } return ITO_TEST_OK; } static ITO_TEST_RET ito_test_interface(void) { ITO_TEST_RET ret = ITO_TEST_OK; uint16_t i = 0; #ifdef DMA_IIC _msg_dma_alloc(); #endif ito_test_set_iic_rate(50000); ITO_TEST_DEBUG("start\n"); ito_test_disable_irq(); ito_test_reset(); if(!ito_test_choose_TpType()) { ITO_TEST_DEBUG("choose tpType fail\n"); ret = ITO_TEST_GET_TP_TYPE_ERROR; goto ITO_TEST_END; } ito_test_EnterSerialDebugMode(); mdelay(100); ITO_TEST_DEBUG("EnterSerialDebugMode\n"); ito_test_WriteReg8Bit ( 0x0F, 0xE6, 0x01 ); ito_test_WriteReg ( 0x3C, 0x60, 0xAA55 ); ITO_TEST_DEBUG("stop mcu and disable watchdog V.005\n"); mdelay(50); for(i = 0;i < 48;i++) { s16_raw_data_1[i] = 0; s16_raw_data_2[i] = 0; s16_raw_data_3[i] = 0; } ito_test_first(40, s16_raw_data_1); ITO_TEST_DEBUG("40 get s16_raw_data_1\n"); if(ito_test_2r) { ret=ito_test_second_2r(40); } else { ret=ito_test_second(40); } if(ITO_TEST_FAIL==ret) { goto ITO_TEST_END; } ito_test_first(41, s16_raw_data_2); ITO_TEST_DEBUG("41 get s16_raw_data_2\n"); if(ito_test_2r) { ret=ito_test_second_2r(41); } else { ret=ito_test_second(41); } if(ITO_TEST_FAIL==ret) { goto ITO_TEST_END; } ito_test_first(42, s16_raw_data_3); ITO_TEST_DEBUG("42 get s16_raw_data_3\n"); ITO_TEST_END: #ifdef DMA_IIC _msg_dma_free(); #endif ito_test_set_iic_rate(100000); ito_test_reset(); ito_test_enable_irq(); ITO_TEST_DEBUG("end\n"); return ret; } #include #define ITO_TEST_AUTHORITY 0777 static struct proc_dir_entry *msg_ito_test = NULL; static struct proc_dir_entry *debug = NULL; static struct proc_dir_entry *debug_on_off = NULL; #define PROC_MSG_ITO_TESE "msg-ito-test" #define PROC_ITO_TEST_DEBUG "debug" #define PROC_ITO_TEST_DEBUG_ON_OFF "debug-on-off" ITO_TEST_RET g_ito_test_ret = ITO_TEST_OK; static int ito_test_proc_read_debug(char *page, char **start, off_t off, int count, int *eof, void *data) { int cnt= 0; g_ito_test_ret = ito_test_interface(); if(ITO_TEST_OK==g_ito_test_ret) { ITO_TEST_DEBUG_MUST("ITO_TEST_OK"); } else if(ITO_TEST_FAIL==g_ito_test_ret) { ITO_TEST_DEBUG_MUST("ITO_TEST_FAIL"); } else if(ITO_TEST_GET_TP_TYPE_ERROR==g_ito_test_ret) { ITO_TEST_DEBUG_MUST("ITO_TEST_GET_TP_TYPE_ERROR"); } *eof = 1; return cnt; } static int ito_test_proc_write_debug(struct file *file, const char *buffer, unsigned long count, void *data) { u16 i = 0; mdelay(5); ITO_TEST_DEBUG_MUST("ito_test_ret = %d",g_ito_test_ret); mdelay(5); for(i=0;i<48;i++) { ITO_TEST_DEBUG_MUST("data_1[%d]=%d;\n",i,s16_raw_data_1[i]); } mdelay(5); for(i=0;i<48;i++) { ITO_TEST_DEBUG_MUST("data_2[%d]=%d;\n",i,s16_raw_data_2[i]); } mdelay(5); for(i=0;i<48;i++) { ITO_TEST_DEBUG_MUST("data_3[%d]=%d;\n",i,s16_raw_data_3[i]); } mdelay(5); return count; } static int ito_test_proc_read_debug_on_off(char *page, char **start, off_t off, int count, int *eof, void *data) { int cnt= 0; bItoTestDebug = 1; ITO_TEST_DEBUG_MUST("on debug bItoTestDebug = %d",bItoTestDebug); *eof = 1; return cnt; } static int ito_test_proc_write_debug_on_off(struct file *file, const char *buffer, unsigned long count, void *data) { bItoTestDebug = 0; ITO_TEST_DEBUG_MUST("off debug bItoTestDebug = %d",bItoTestDebug); return count; } static void ito_test_create_entry(void) { static const struct file_operations debug_ops = { .owner = THIS_MODULE, .read = ito_test_proc_read_debug, .write = ito_test_proc_write_debug, }; static const struct file_operations debug_on_off_ops = { .owner = THIS_MODULE, .read = ito_test_proc_read_debug_on_off, .write = ito_test_proc_write_debug_on_off, }; msg_ito_test = proc_mkdir(PROC_MSG_ITO_TESE, NULL); debug = proc_create(PROC_ITO_TEST_DEBUG,ITO_TEST_AUTHORITY,msg_ito_test,&debug_ops); debug_on_off = proc_create(PROC_ITO_TEST_DEBUG_ON_OFF,ITO_TEST_AUTHORITY,msg_ito_test,&debug_on_off_ops); if (NULL==debug) { ITO_TEST_DEBUG_MUST("create_proc_entry ITO TEST DEBUG failed\n"); } else { ITO_TEST_DEBUG_MUST("create_proc_entry ITO TEST DEBUG OK\n"); } if (NULL==debug_on_off) { ITO_TEST_DEBUG_MUST("create_proc_entry ITO TEST ON OFF failed\n"); } else { ITO_TEST_DEBUG_MUST("create_proc_entry ITO TEST ON OFF OK\n"); } } #endif MODULE_AUTHOR("Jianchun Bian "); MODULE_DESCRIPTION("Pixcir I2C Touchscreen Driver"); MODULE_LICENSE("GPL");