summaryrefslogtreecommitdiff
path: root/drivers/input/touchscreen/msg2138.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/msg2138.c')
-rw-r--r--drivers/input/touchscreen/msg2138.c4581
1 files changed, 4581 insertions, 0 deletions
diff --git a/drivers/input/touchscreen/msg2138.c b/drivers/input/touchscreen/msg2138.c
new file mode 100644
index 00000000..efa1e76d
--- /dev/null
+++ b/drivers/input/touchscreen/msg2138.c
@@ -0,0 +1,4581 @@
+/*
+ * 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 <linux/i2c.h>
+#include <linux/input.h>
+#include <linux/gpio.h>
+#include <linux/earlysuspend.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/miscdevice.h>
+#include <linux/firmware.h>
+#include <linux/platform_device.h>
+
+#include <linux/slab.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/mm.h>
+#include <linux/device.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/sysctl.h>
+#include <linux/input/mt.h>
+#include <asm/uaccess.h>
+
+#include <linux/sched.h>
+#include <linux/kthread.h>
+#include <linux/completion.h>
+#include <linux/err.h>
+
+#include <linux/regulator/consumer.h>
+#include <linux/i2c/msg2138.h>
+#include <soc/sprd/regulator.h>
+#include <linux/fs.h>
+#include <soc/sprd/board.h>
+#ifdef CONFIG_HAS_EARLYSUSPEND
+#include <linux/earlysuspend.h>
+#endif
+#if defined(CONFIG_I2C_SPRD) || defined(CONFIG_I2C_SPRD_V1)
+#include <soc/sprd/i2c-sprd.h>
+#endif
+
+#include <linux/of_device.h>
+#include <linux/of_address.h>
+#include <linux/of_gpio.h>
+
+/*********************************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<touch; i++) {
+ //pix_id = (*(p+4));
+ //slot_id = ((pix_id & 7)<<1) | ((pix_id & 8)>>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<touch; i++) {
+ if (point_slot[i].active == 1) {
+ if(point_slot[i].posy<0) {
+ } else {
+ if(point_slot[i].posx<0) {
+ point_slot[i].posx = 0;
+ } else if (point_slot[i].posx>(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<<i));
+ }
+ lastkey=keycode;
+ }*/
+ input_sync(tsdata->input);
+ for (i=0; i<MAX_FINGER_NUM*2; i++) {
+ if (point_slot[i].active == 0) {
+ point_slot[i].posx = 0;
+ point_slot[i].posy = 0;
+ }
+ point_slot[i].active = 0;
+ }
+}
+
+#if USE_WAIT_QUEUE
+static int touch_event_handler(void *unused)
+{
+ struct sched_param param = { .sched_priority = 5 };
+
+ struct pixcir_i2c_ts_data *tsdata = i2c_get_clientdata(msg21xx_i2c_client);
+ sched_setscheduler(current, SCHED_RR, &param);
+
+ do {
+ set_current_state(TASK_INTERRUPTIBLE);
+ wait_event_interruptible(waiter, (0 != tpd_flag));
+ tpd_flag = 0;
+ set_current_state(TASK_RUNNING);
+
+ pixcir_ts_poscheck(tsdata);
+
+ } while (!kthread_should_stop());
+
+ return 0;
+}
+#endif
+
+static irqreturn_t pixcir_ts_isr(int irq, void *dev_id)
+{
+#if USE_WAIT_QUEUE
+ tpd_flag = 1;
+ wake_up_interruptible(&waiter);
+ return IRQ_HANDLED;
+#endif
+
+#if 0
+ struct pixcir_i2c_ts_data *tsdata = dev_id;
+
+ disable_irq_nosync(irq);
+
+ // while (!tsdata->exiting) {
+ 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; i<MAX_FINGER_NUM*2; i++) {
+ point_slot[i].active = 0;
+ }
+ sy_init();
+ msleep(200);
+
+ input = input_allocate_device();
+ if (!input) {
+ dev_err(&client->dev, "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;i<size;i++)
+ {
+ I2CDMABuf_va[i]=data[i];
+ }
+ msg21xx_i2c_client->ext_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<num_of_sensor * 2;i++)
+ {
+ ITO_TEST_DEBUG("dbbus_rx_data[%d]=%d\n",i,dbbus_rx_data[i]);
+ }
+
+ 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 ) );
+
+
+ for( i = 0; i < num_of_sensor; i++ )
+ {
+ raw_data[i] = ( dbbus_rx_data[ 2 * i + 1] << 8 ) | ( dbbus_rx_data[2 * i] );
+ s16_raw_data[i] = ( int16_t )raw_data[i];
+ }
+
+ return(num_of_sensor);
+}
+
+
+static void ito_test_send_data_in( uint8_t step )
+{
+ uint16_t i;
+ uint8_t dbbus_tx_data[512];
+ uint16_t *Type1=NULL;
+
+ ITO_TEST_DEBUG("ito_test_send_data_in step=%d\n",step);
+ if( step == 4 )
+ {
+ Type1 = &open_1[0];
+ }
+ else if( step == 5 )
+ {
+ Type1 = &open_2[0];
+ }
+ else if( step == 6 )
+ {
+ Type1 = &open_3[0];
+ }
+ else if( step == 9 )
+ {
+ Type1 = &open_1B[0];
+ }
+ else if( step == 10 )
+ {
+ Type1 = &open_2B[0];
+ }
+
+ dbbus_tx_data[0] = 0x10;
+ dbbus_tx_data[1] = 0x11;
+ dbbus_tx_data[2] = 0x00;
+ for( i = 0; i <= 0x3E ; i++ )
+ {
+ dbbus_tx_data[3+2*i] = Type1[i] & 0xFF;
+ dbbus_tx_data[4+2*i] = ( Type1[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 <linux/proc_fs.h>
+#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 <jcbian@pixcir.com.cn>");
+MODULE_DESCRIPTION("Pixcir I2C Touchscreen Driver");
+MODULE_LICENSE("GPL");