static int ct36x_ts_suspend(struct i2c_client *client, pm_message_t mesg) { struct ct36x_ts_info *ts; ct36x_debug_2("%s: enter\n", __FUNCTION__); /* ct36x_zx */ if (CT36X_TS_DEBUG) ct36x_debug("ct36x_ts_suspend\n"); ts = (struct ct36x_ts_info *)i2c_get_clientdata(client); disable_irq_nosync(ts->irq); #if (CT36X_TS_ESD_TIMER_INTERVAL) if ( ts->timer_on ) { // Disable ESD timer del_timer(&ts->timer); ts->timer_on = 0; } #endif cancel_work_sync(&ts->event_work); /* ct36x_zx */ #if (CT36X_TS_CHIP_SEL == CT360_CHIP_VER) // step 01 W FF 0F 2B ts->data.buf[0] = 0xFF; ts->data.buf[1] = 0x0F; ts->data.buf[2] = 0x2B; ct36x_ts_reg_write(client, client->addr, ts->data.buf, 3, CT36X_TS_I2C_SPEED); mdelay(3); // step 01 W 00 00 ts->data.buf[0] = 0x00; ts->data.buf[1] = 0x00; ct36x_ts_reg_write(client, client->addr, ts->data.buf, 2, CT36X_TS_I2C_SPEED); mdelay(3); #elif (CT36X_TS_CHIP_SEL == CT36X_CHIP_VER) // step 01 W FF 8F FF ts->data.buf[0] = 0xFF; ts->data.buf[1] = 0x8F; ts->data.buf[2] = 0xFF; ct36x_ts_reg_write(client, client->addr, ts->data.buf, 3, CT36X_TS_I2C_SPEED); mdelay(3); // step 01 W 00 AF ts->data.buf[0] = 0x00; ts->data.buf[1] = 0xAF; ct36x_ts_reg_write(client, client->addr, ts->data.buf, 2, CT36X_TS_I2C_SPEED); mdelay(3); #endif mdelay(600); return 0; }
static int ct36x_ts_get_chip(struct i2c_client *client) { struct ct36x_ts_info *ts = (struct ct36x_ts_info *)i2c_get_clientdata(client); // Write read chip id command ts->data.buf[0] = 0xFF; ts->data.buf[1] = 0xF0; ts->data.buf[2] = 0x00; ct36x_ts_reg_write(client, client->addr, (char *) ts->data.buf, 3, CT36X_TS_I2C_SPEED); // Reset i2c offsets ts->data.buf[0] = 0x00; ct36x_ts_reg_write(client, client->addr, (char *) ts->data.buf, 1, CT36X_TS_I2C_SPEED); // read chip id ct36x_ts_reg_read(client, client->addr, (char *) ts->data.buf, 1, CT36X_TS_I2C_SPEED); return ts->data.buf[0]; }
static int ct36x_ts_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct ct36x_ts_info *ts = NULL; struct device *dev = &client->dev; int err = -1; if (dev == NULL) { printk(KERN_ERR "%s(): dev not registered!\n", __func__); goto ERR_HW_INIT; } /* Check I2C Functionality */ err = i2c_check_functionality(client->adapter, I2C_FUNC_I2C); if ( !err ) { dev_err(dev, "Check I2C Functionality Failed.\n"); goto ERR_I2C_CHK; } ts = (struct ct36x_ts_info *)i2c_get_clientdata(client); if (ts == NULL) { printk(KERN_ERR "%s(): Not registered at I2C!\n", __func__); goto ERR_HW_INIT; } ts->ready = 0; // Device is not ready /* Init Hardware */ err = ct36x_ts_hw_init(ts); if ( err ) { dev_err(dev, "Platform HW Init Failed.\n"); goto ERR_HW_INIT; } /* HW Reset when Firmware request and update. */ ct36x_ts_hw_reset(ts); #if (CT36X_TS_CHIP_SEL == CT360_CHIP_VER) // Set I2C scon to 0x0f2f --> read version ts->data.buf[0] = 0xFF; ts->data.buf[1] = 0x0F; ts->data.buf[2] = 0x2A; #elif (CT36X_TS_CHIP_SEL == CT36X_CHIP_VER) // Set I2C scon to 0x3fff --> read version ts->data.buf[0] = 0xFF; ts->data.buf[1] = 0x3F; ts->data.buf[2] = 0xFF; #endif ct36x_ts_reg_write(client, client->addr, (char *) ts->data.buf, 3, CT36X_TS_I2C_SPEED); mdelay(10); ts->data.buf[0] = 0x00; ct36x_ts_reg_write(client, client->addr, (char *) ts->data.buf, 1, CT36X_TS_I2C_SPEED); mdelay(10); // do read version ct36x_ts_reg_read(client, client->addr, (char *) ts->data.buf, 1, CT36X_TS_I2C_SPEED); mdelay(10); dev_info(dev, "FW Version read: 0x%x \n", ts->data.buf[0]); #if defined(CONFIG_CT360_CHIP_UPDATE_SUPPORT) { char fw_ver_upd = Binary_Data[CT36X_TS_FW_VER_OFFSET]; dev_info(dev, "FW Version write: 0x%x \n", fw_ver_upd); if ( fw_ver_upd != ts->data.buf[0] ) { dev_info(dev, "Running bootloader ... \n"); err = ct36x_ts_bootloader(client); dev_info(dev, "Bootloader done, %s \n", err ? "Failed" : "OK"); } } #else dev_info(dev, "Bootloader support disabled, trying without...\n"); #endif // register early suspend #ifdef CONFIG_HAS_EARLYSUSPEND #if (CT36X_TS_HAS_EARLYSUSPEND) ts->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; ts->early_suspend.suspend = ct36x_early_suspend; ts->early_suspend.resume = ct36x_early_resume; register_early_suspend(&ts->early_suspend); #endif #endif // allocate input device ts->input = input_allocate_device(); if ( !ts->input ) { dev_err(dev, "Unable to allocate input device for device %s.\n", DRIVER_NAME); err = -ENOMEM; goto ERR_INPUT_ALLOC; } __set_bit(EV_ABS, ts->input->evbit); #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) __set_bit(INPUT_PROP_DIRECT, ts->input->propbit); #endif #if (LINUX_VERSION_CODE >= KERNEL_VERSION(3, 0, 0)) input_mt_init_slots(ts->input, CT36X_TS_POINT_NUM); #endif input_set_abs_params(ts->input, ABS_MT_POSITION_X, 0, CT36X_TS_ABS_X_MAX, 0, 0); input_set_abs_params(ts->input, ABS_MT_POSITION_Y, 0, CT36X_TS_ABS_Y_MAX, 0, 0); input_set_abs_params(ts->input, ABS_MT_TOUCH_MAJOR, 0, 255, 0, 0); input_set_abs_params(ts->input, ABS_MT_WIDTH_MAJOR, 0, 255, 0, 0); ts->input->name = DRIVER_NAME; ts->input->id.bustype = BUS_I2C; // register input device err = input_register_device(ts->input); if ( err ) { dev_err(dev, "Unable to register input device for device %s.\n", DRIVER_NAME); goto ERR_INPUT_REGIS; } /* ct36x_zx */ ts->ts_workqueue = create_singlethread_workqueue(CT36X_TS_WQ); if (!ts->ts_workqueue) { err = -ESRCH; printk(KERN_ERR "create_workqueue falled!\n"); goto ERR_TS_WQ; } // work INIT_WORK(&ts->event_work, ct36x_ts_workfunc); // Init irq ts->irq = gpio_to_irq(CT36X_TS_IRQ_PIN); //err = request_irq(ts->irq, ct36x_ts_irq, IRQF_TRIGGER_FALLING | IRQF_ONESHOT, DRIVER_NAME, ts); err = request_irq(ts->irq, ct36x_ts_irq, IRQF_TRIGGER_FALLING, DRIVER_NAME, ts); /* ct36x_zx */ if ( err ) { dev_err(dev, "Unable to request irq.\n"); goto ERR_IRQ_REQEST; } // ESD timer #if (CT36X_TS_ESD_TIMER_INTERVAL) setup_timer(&ts->timer, ct36x_ts_timer, ts); ts->timer.expires = jiffies + HZ * CT36X_TS_ESD_TIMER_INTERVAL; add_timer(&ts->timer); ts->timer_on = 1; dev_info(dev, "ESD timer, %s \n", ts->timer_on ? "On" : "Off"); #endif /* Add another reset and then state we are ready */ ct36x_ts_hw_reset(ts); ts->ready = 1; // Device is ready return 0; ERR_TS_WQ: ERR_IRQ_REQEST: ERR_INPUT_REGIS: input_free_device(ts->input); ERR_INPUT_ALLOC: ERR_I2C_CHK: #ifdef CONFIG_HAS_EARLYSUSPEND #if (CT36X_TS_HAS_EARLYSUSPEND) unregister_early_suspend(&ts->early_suspend); #endif #endif ERR_HW_INIT: ct36x_ts_hw_exit(ts); return err; }
int ct36x_ts_bootloader(struct i2c_client *client) { int i = 0, j = 0; unsigned int ver_chk_cnt = 0; unsigned int flash_addr = 0; unsigned char CheckSum[16]; struct ct36x_ts_info *ts = (struct ct36x_ts_info *)i2c_get_clientdata(client); //------------------------------ // Step1 --> initial BootLoader // Note. 0x7F -> 0x00 -> 0xA5 ; // MCU goto idle //------------------------------ printk("%s() Set mcu to idle \n", __FUNCTION__); ts->data.buf[0] = 0x00; ts->data.buf[1] = 0xA5; ct36x_ts_reg_write(client, 0x7F, ts->data.buf, 2, CT36X_TS_I2C_SPEED); mdelay(10); //------------------------------ // Reset I2C Offset address // Note. 0x7F -> 0x00 //------------------------------ printk("%s() Reset i2c offset address \n", __FUNCTION__); ts->data.buf[0] = 0x00; ct36x_ts_reg_write(client, 0x7F, ts->data.buf, 1, CT36X_TS_I2C_SPEED); mdelay(10); //------------------------------ // Read I2C Bus status //------------------------------ printk("%s() Read i2c bus status \n", __FUNCTION__); ct36x_ts_reg_read(client, 0x7F, ts->data.buf, 1, CT36X_TS_I2C_SPEED); mdelay(10); // Delay 1 ms // if return "AAH" then going next step if (ts->data.buf[0] != 0xAA) { printk("%s() i2c bus status: 0x%x \n", __FUNCTION__, ts->data.buf[0]); return -1; } //------------------------------ printk("%s() Vendor ID check \n", __FUNCTION__); ts->data.buf[0] = 0x00; ts->data.buf[1] = 0x99; // Generate check sum command -->read flash, set addr ts->data.buf[2] = 0x00; // define a flash address for CT365 to generate check sum ts->data.buf[3] = 0x44; // ts->data.buf[4] = 0x08; // Define a data length for CT365 to generate check sum // Write Genertate check sum command to CT36x ct36x_ts_reg_write(client, 0x7F, ts->data.buf, 5, CT36X_TS_I2C_SPEED); mdelay(10); // Delay 10 ms ct36x_ts_reg_read(client, 0x7F, ts->data.buf, 13, CT36X_TS_I2C_SPEED); mdelay(10); // Delay 10 ms // Read check sum and flash data from CT36x if ( (ts->data.buf[5] != 'V') || (ts->data.buf[9] != 'T') ) ver_chk_cnt++; ts->data.buf[0] = 0x00; ts->data.buf[1] = 0x99; // Generate check sum command -->read flash,set addr ts->data.buf[2] = 0x00; // define a flash address for CT365 to generate check sum ts->data.buf[3] = 0xA4; // ts->data.buf[4] = 0x08; // Define a data length for CT365 to generate check sum // Write Genertate check sum command to CT365 ct36x_ts_reg_write(client, 0x7F, ts->data.buf, 5, CT36X_TS_I2C_SPEED); mdelay(10); // Delay 10 ms ct36x_ts_reg_read(client, 0x7F, ts->data.buf, 13, CT36X_TS_I2C_SPEED); mdelay(10); // Delay 10 ms if ((ts->data.buf[5] != 'V') || (ts->data.buf[9] != 'T')) ver_chk_cnt++; if ( ver_chk_cnt >= 2 ) { printk("%s() Invalid Vendor ID \n", __FUNCTION__); return -1; } //----------------------------------------------------- // Step 2 : Erase 32K flash memory via Mass Erase (33H) // 0x7F --> 0x00 --> 0x33 --> 0x00; //----------------------------------------------------- printk("%s() Erase flash \n", __FUNCTION__); for(i = 0; i < 100; i++ ) { ts->data.buf[0] = 0x00; // Offset address ts->data.buf[1] = 0x33; // Mass Erase command ts->data.buf[2] = 0x00; ct36x_ts_reg_write(client, 0x7F, ts->data.buf, 3, CT36X_TS_I2C_SPEED); mdelay(10 + i); // Delay 10 mS //------------------------------ // Reset I2C Offset address // Note. 0x7F -> 0x00 //------------------------------ ts->data.buf[0] = 0x00; ct36x_ts_reg_write(client, 0x7F, ts->data.buf, 1, CT36X_TS_I2C_SPEED); mdelay(10 + i); // Delay 10 mS //------------------------------ // Read I2C Bus status //------------------------------ ct36x_ts_reg_read(client, 0x7F, ts->data.buf, 1, CT36X_TS_I2C_SPEED); mdelay(10); // Delay 1 ms // if return "AAH" then going next step if( ts->data.buf[0] == 0xAA ) break; } if ( i >= 100 ) return -1; //---------------------------------------- // Step3. Host write 128 bytes to CT36x // Step4. Host read checksum to verify ; // Write/Read for 256 times ( 32k Bytes ) //---------------------------------------- printk("%s() flash FW \n", __FUNCTION__); for ( j = 0; j < 256; j++ ) { // 32k/128 = 256 times flash_addr = 128 * j; // 0 ~ 127; 128 ~ 255; for ( i = 0; i < 16; i++ ) { // 128/8 = 16 times for One Row program // Step 3 : write binary data to CT36x ts->data.buf[0] = 0x00; // Offset address ts->data.buf[1] = 0x55; // Flash write command ts->data.buf[2] = (char)(flash_addr >> 8); // Flash address [15:8] ts->data.buf[3] = (char)(flash_addr & 0xFF); // Flash address [7:0] ts->data.buf[4] = 0x08; // Data Length ts->data.buf[6] = Binary_Data[flash_addr + 0]; // Binary data 1 ts->data.buf[7] = Binary_Data[flash_addr + 1]; // Binary data 2 ts->data.buf[8] = Binary_Data[flash_addr + 2]; // Binary data 3 ts->data.buf[9] = Binary_Data[flash_addr + 3]; // Binary data 4 ts->data.buf[10] = Binary_Data[flash_addr + 4]; // Binary data 5 ts->data.buf[11] = Binary_Data[flash_addr + 5]; // Binary data 6 ts->data.buf[12] = Binary_Data[flash_addr + 6]; // Binary data 7 ts->data.buf[13] = Binary_Data[flash_addr + 7]; // Binary data 8 // Calculate a check sum by Host controller. // Checksum = / (FLASH_ADRH+FLASH_ADRL+LENGTH+ // Binary_Data1+Binary_Data2+Binary_Data3+Binary_Data4+ // Binary_Data5+Binary_Data6+Binary_Data7+Binary_Data8) + 1 CheckSum[i] = ~(ts->data.buf[2] + ts->data.buf[3] + ts->data.buf[4] + ts->data.buf[6] + ts->data.buf[7] + ts->data.buf[8] + ts->data.buf[9] + ts->data.buf[10] + ts->data.buf[11] + ts->data.buf[12] + ts->data.buf[13]) + 1; ts->data.buf[5] = CheckSum[i]; // Load check sum to I2C Buffer ct36x_ts_reg_write(client, 0x7F, ts->data.buf, 14, CT36X_TS_I2C_SPEED); // Host write I2C_Buf[0?K12] to CT365. mdelay(1); // 8 Bytes program --> Need 1 ms delay time flash_addr += 8; // Increase Flash Address. 8 bytes for 1 time } mdelay(20); // Each Row command --> Need 20 ms delay time flash_addr = 128 * j; // 0 ~ 127 ; 128 ~ 255 ; // Step4. Verify process printk("%s() Verify FW \n", __FUNCTION__); for ( i = 0; i < 16; i++ ) { // 128/8 = 16 times for One Row program //Step 4 : Force CT365 generate check sum for host to compare data. //Prepare get check sum from CT36x ts->data.buf[0] = 0x00; ts->data.buf[1] = 0x99; // Generate check sum command ts->data.buf[2] = (char)(flash_addr >> 8); // define a flash address for NT1100x to generate check sum ts->data.buf[3] = (char)(flash_addr & 0xFF); // ts->data.buf[4] = 0x08; // Define a data length for CT36x to generate check sum ct36x_ts_reg_write(client, 0x7F, ts->data.buf, 5, CT36X_TS_I2C_SPEED); // Write Genertate check sum command to CT365 mdelay(1); // Delay 1 ms ct36x_ts_reg_read(client, 0x7F, ts->data.buf, 13, CT36X_TS_I2C_SPEED); // Read check sum and flash data from CT365 // Compare host check sum with CT365 check sum(I2C_Buf[4]) if ( ts->data.buf[4] != CheckSum[i] ) { return -1; } flash_addr += 8; // Increase Flash Address. } } return 0; }
int CT360_CTP_BootLoader(struct ct360_ts_data *ts) { int i = 0, j = 0; unsigned int ver_chk_cnt = 0; unsigned int flash_addr = 0; unsigned char CheckSum[16]; //------------------------------ // Step1 --> initial BootLoader // Note. 0x7F -> 0x00 -> 0xA5 ; // MCU goto idle //------------------------------ printk("%s() Set mcu to idle \n", __FUNCTION__); ts->data.buf[0] = 0x00; ts->data.buf[1] = 0xA5; ct36x_ts_reg_write(ts->client, 0x7F, ts->data.buf, 2, CT36X_TS_I2C_SPEED); mdelay(10); //------------------------------ // Reset I2C Offset address // Note. 0x7F -> 0x00 //------------------------------ printk(&"%s() Reset i2c offset address \n", __FUNCTION__); ts->data.buf[0] = 0x00; ct36x_ts_reg_write(ts->client, 0x7F, ts->data.buf, 1, CT36X_TS_I2C_SPEED); mdelay(10); //------------------------------ // Read I2C Bus status //------------------------------ printk("%s() Read i2c bus status \n", __FUNCTION__); ct36x_ts_reg_read(ts->client, 0x7F, ts->data.buf, 1, CT36X_TS_I2C_SPEED); mdelay(10); // Delay 1 ms // if return "AAH" then going next step if (ts->data.buf[0] != 0xAA) { printk("%s() i2c bus status: 0x%x \n", __FUNCTION__, ts->data.buf[0]); return -1; } //------------------------------ // Check incomplete flash erase //------------------------------ printk("%s() Flash erase verify \n", __FUNCTION__); ts->data.buf[0] = 0x00; ts->data.buf[1] = 0x99; // Generate check sum command -->read flash, set addr ts->data.buf[2] = 0x00; // define a flash address for CT36x to generate check sum ts->data.buf[3] = 0x00; // ts->data.buf[4] = 0x08; // Define a data length for CT36x to generate check sum // Write Genertate check sum command to CT36x ct36x_ts_reg_write(ts->client, 0x7F, ts->data.buf, 5, CT36X_TS_I2C_SPEED); mdelay(10); // Delay 10 ms ct36x_ts_reg_read(ts->client, 0x7F, ts->data.buf, 13, CT36X_TS_I2C_SPEED); mdelay(10); // Delay 10 ms CheckSum[0] = ts->data.buf[5]; CheckSum[1] = ts->data.buf[6]; ts->data.buf[0] = 0x00; ts->data.buf[1] = 0x99; // Generate check sum command -->read flash, set addr ts->data.buf[2] = 0x3F; // define a flash address for CT36x to generate check sum ts->data.buf[3] = 0xE0; // ts->data.buf[4] = 0x08; // Define a data length for CT36x to generate check sum // Write Genertate check sum command to CT36x ct36x_ts_reg_write(ts->client, 0x7F, ts->data.buf, 5, CT36X_TS_I2C_SPEED); mdelay(10); // Delay 10 ms ct36x_ts_reg_read(ts->client, 0x7F, ts->data.buf, 13, CT36X_TS_I2C_SPEED); mdelay(10); CheckSum[2] = ts->data.buf[5]; CheckSum[3] = ts->data.buf[6]; if ( (CheckSum[0] ^ CheckSum[2]) == 0xFF && (CheckSum[1] ^ CheckSum[3]) == 0xFF ) goto FLASH_ERASE; //------------------------------ // check valid Vendor ID //------------------------------ printk("%s() Vendor ID Check \n", __FUNCTION__); ts->data.buf[0] = 0x00; ts->data.buf[1] = 0x99; // Generate check sum command -->read flash, set addr ts->data.buf[2] = 0x00; // define a flash address for CT365 to generate check sum ts->data.buf[3] = 0x44; // ts->data.buf[4] = 0x08; // Define a data length for CT365 to generate check sum // Write Genertate check sum command to CT36x ct36x_ts_reg_write(ts->client, 0x7F, ts->data.buf, 5, CT36X_TS_I2C_SPEED); mdelay(30); // Delay 10 ms ct36x_ts_reg_read(ts->client, 0x7F, ts->data.buf, 13, CT36X_TS_I2C_SPEED); mdelay(30); // Delay 10 ms // Read check sum and flash data from CT36x if ( (ts->data.buf[5] != 'V') || (ts->data.buf[9] != 'T') ) ver_chk_cnt++; ts->data.buf[0] = 0x00; ts->data.buf[1] = 0x99; // Generate check sum command -->read flash,set addr ts->data.buf[2] = 0x00; // define a flash address for CT365 to generate check sum ts->data.buf[3] = 0xA4; // ts->data.buf[4] = 0x08; // Define a data length for CT365 to generate check sum // Write Genertate check sum command to CT365 ct36x_ts_reg_write(ts->client, 0x7F, ts->data.buf, 5, CT36X_TS_I2C_SPEED); mdelay(30); // Delay 10 ms ct36x_ts_reg_read(ts->client, 0x7F, ts->data.buf, 13, CT36X_TS_I2C_SPEED); mdelay(30); // Delay 10 ms if ((ts->data.buf[5] != 'V') || (ts->data.buf[9] != 'T')) ver_chk_cnt++; if ( ver_chk_cnt >= 2 ) { printk("%s() Invalid FW Version \n", __FUNCTION__); // return -1; } FLASH_ERASE: //----------------------------------------------------- // Step 2 : Erase 32K flash memory via Mass Erase (33H) // 0x7F --> 0x00 --> 0x33 --> 0x00; //----------------------------------------------------- printk("%s() Erase flash \n", __FUNCTION__); for(i = 0; i < 8; i++ ) { ts->data.buf[0] = 0x00; // Offset address ts->data.buf[1] = 0x33; // Mass Erase command ts->data.buf[2] = 0x00 + (i * 8); ct36x_ts_reg_write(ts->client, 0x7F, ts->data.buf, 3, CT36X_TS_I2C_SPEED); mdelay(120); // Delay 10 mS //------------------------------ // Reset I2C Offset address // Note. 0x7F -> 0x00 //------------------------------ ts->data.buf[0] = 0x00; ct36x_ts_reg_write(ts->client, 0x7F, ts->data.buf, 1, CT36X_TS_I2C_SPEED); mdelay(120); // Delay 10 mS //------------------------------ // Read I2C Bus status //------------------------------ ct36x_ts_reg_read(ts->client, 0x7F, ts->data.buf, 1, CT36X_TS_I2C_SPEED); mdelay(10); // Delay 1 ms // if return "AAH" then going next step if( ts->data.buf[0] != 0xAA ) return -1; } //---------------------------------------- // Step3. Host write 128 bytes to CT36x // Step4. Host read checksum to verify ; // Write/Read for 256 times ( 32k Bytes ) //---------------------------------------- printk("%s() flash FW \n", __FUNCTION__); for ( flash_addr = 0; flash_addr < 0x3FFF; flash_addr+=8 ) { // Step 3 : write binary data to CT36x ts->data.buf[0] = 0x00; // Offset address ts->data.buf[1] = 0x55; // Flash write command ts->data.buf[2] = (char)(flash_addr >> 8); // Flash address [15:8] ts->data.buf[3] = (char)(flash_addr & 0xFF); // Flash address [7:0] ts->data.buf[4] = 0x08; // Data Length if( flash_addr == 160 || flash_addr == 168 ) { ts->data.buf[6] = ~Binary_Data[flash_addr + 0]; // Binary data 1 ts->data.buf[7] = ~Binary_Data[flash_addr + 1]; // Binary data 2 ts->data.buf[8] = ~Binary_Data[flash_addr + 2]; // Binary data 3 ts->data.buf[9] = ~Binary_Data[flash_addr + 3]; // Binary data 4 ts->data.buf[10] = ~Binary_Data[flash_addr + 4]; // Binary data 5 ts->data.buf[11] = ~Binary_Data[flash_addr + 5]; // Binary data 6 ts->data.buf[12] = ~Binary_Data[flash_addr + 6]; // Binary data 7 ts->data.buf[13] = ~Binary_Data[flash_addr + 7]; // Binary data 8 } else { ts->data.buf[6] = Binary_Data[flash_addr + 0]; // Binary data 1 ts->data.buf[7] = Binary_Data[flash_addr + 1]; // Binary data 2 ts->data.buf[8] = Binary_Data[flash_addr + 2]; // Binary data 3 ts->data.buf[9] = Binary_Data[flash_addr + 3]; // Binary data 4 ts->data.buf[10] = Binary_Data[flash_addr + 4]; // Binary data 5 ts->data.buf[11] = Binary_Data[flash_addr + 5]; // Binary data 6 ts->data.buf[12] = Binary_Data[flash_addr + 6]; // Binary data 7 ts->data.buf[13] = Binary_Data[flash_addr + 7]; // Binary data 8 } // Calculate a check sum by Host controller. // Checksum = / (FLASH_ADRH+FLASH_ADRL+LENGTH+ // Binary_Data1+Binary_Data2+Binary_Data3+Binary_Data4+ // Binary_Data5+Binary_Data6+Binary_Data7+Binary_Data8) + 1 CheckSum[0] = ~(ts->data.buf[2] + ts->data.buf[3] + ts->data.buf[4] + ts->data.buf[6] + ts->data.buf[7] + ts->data.buf[8] + ts->data.buf[9] + ts->data.buf[10] + ts->data.buf[11] + ts->data.buf[12] + ts->data.buf[13]) + 1; ts->data.buf[5] = CheckSum[0]; // Load check sum to I2C Buffer ct36x_ts_reg_write(ts->client, 0x7F, ts->data.buf, 14, CT36X_TS_I2C_SPEED); // Host write I2C_Buf[0?K12] to CT365. mdelay(10); // 8 Bytes program --> Need 1 ms delay time // Step4. Verify process //printk("%s(flash_addr:0x%04x) Verify FW \n", __FUNCTION__, flash_addr); //Step 4 : Force CT365 generate check sum for host to compare data. //Prepare get check sum from CT36x ts->data.buf[0] = 0x00; ts->data.buf[1] = 0x99; // Generate check sum command ts->data.buf[2] = (char)(flash_addr >> 8); // define a flash address for NT1100x to generate check sum ts->data.buf[3] = (char)(flash_addr & 0xFF); // ts->data.buf[4] = 0x08; // Define a data length for CT36x to generate check sum ct36x_ts_reg_write(ts->client, 0x7F, ts->data.buf, 5, CT36X_TS_I2C_SPEED); // Write Genertate check sum command to CT365 mdelay(10); // Delay 1 ms ct36x_ts_reg_read(ts->client, 0x7F, ts->data.buf, 13, CT36X_TS_I2C_SPEED); // Read check sum and flash data from CT365 // Compare host check sum with CT365 check sum(I2C_Buf[4]) if ( ts->data.buf[4] != CheckSum[0] ) { return -1; } } return 0; }