diff options
Diffstat (limited to 'drivers/input/touchscreen/wacom/wacom_i2c_flash.c')
-rw-r--r-- | drivers/input/touchscreen/wacom/wacom_i2c_flash.c | 418 |
1 files changed, 277 insertions, 141 deletions
diff --git a/drivers/input/touchscreen/wacom/wacom_i2c_flash.c b/drivers/input/touchscreen/wacom/wacom_i2c_flash.c index c8eb9b1..268afe6 100644 --- a/drivers/input/touchscreen/wacom/wacom_i2c_flash.c +++ b/drivers/input/touchscreen/wacom/wacom_i2c_flash.c @@ -18,9 +18,42 @@ */ #include <linux/wacom_i2c.h> - #include "wacom_i2c_flash.h" +#define ERR_HEX 0x056 +#define RETRY_TRANSFER 5 +unsigned char checksum_data[4]; + +int calc_checksum(unsigned char *flash_data) +{ + unsigned long i; + + if (ums_binary) + return 0; + + for (i = 0; i < 4; i++) + checksum_data[i] = 0; + + for (i = 0x0000; i < 0xC000; i += 4) { + checksum_data[0] ^= flash_data[i]; + checksum_data[1] ^= flash_data[i+1]; + checksum_data[2] ^= flash_data[i+2]; + checksum_data[3] ^= flash_data[i+3]; + } + + printk(KERN_DEBUG + "[E-PEN] %s : %02x, %02x, %02x, %02x\n", + __func__, checksum_data[0], checksum_data[1], + checksum_data[2], checksum_data[3]); + + for (i = 0; i < 4; i++) { + if (checksum_data[i] != Firmware_checksum[i+1]) + return -ERR_HEX; + } + + return 0; +} + int wacom_i2c_flash_chksum(struct wacom_i2c *wac_i2c, unsigned char *flash_data, unsigned long *max_address) { @@ -52,24 +85,23 @@ int wacom_i2c_flash_cmd(struct wacom_i2c *wac_i2c) flashq = 0xE0; len = 1; - ret = wacom_i2c_master_send(wac_i2c->client, &flashq, len, - WACOM_I2C_BOOT); + ret = wacom_i2c_send(wac_i2c, &flashq, len, true); if (ret >= 0) { i = 0; do { - msleep(20); - ret = wacom_i2c_master_recv(wac_i2c->client, &flashq, - len, WACOM_I2C_BOOT); + msleep(1); + ret = wacom_i2c_recv(wac_i2c, + &flashq, len, true); i++; if (i > RETRY) return -1; } while (flashq == 0xff); } else { - msleep(20); + msleep(1); len = 8; - ret = i2c_master_send(wac_i2c->client, buf, len); + ret = wacom_i2c_send(wac_i2c, buf, len, false); if (ret < 0) { printk(KERN_ERR "[E-PEN]: Sending flash command failed\n"); @@ -79,6 +111,8 @@ int wacom_i2c_flash_cmd(struct wacom_i2c *wac_i2c) msleep(270); } + wac_i2c->boot_mode = true; + return 0; } @@ -90,21 +124,20 @@ int wacom_i2c_flash_query(struct wacom_i2c *wac_i2c, u8 query, u8 recvdQuery) flashq = query; len = 1; - ret = wacom_i2c_master_send(wac_i2c->client, &flashq, len, - WACOM_I2C_BOOT); + ret = wacom_i2c_send(wac_i2c, &flashq, len, true); if (ret < 0) { printk(KERN_ERR "[E-PEN]: query unsent:%d\n", ret); return -1; } - /*sleep */ - msleep(20); + /*sleep*/ + msleep(10); i = 0; do { - msleep(20); + msleep(1); flashq = query; - ret = wacom_i2c_master_recv(wac_i2c->client, &flashq, len, - WACOM_I2C_BOOT); + ret = wacom_i2c_recv(wac_i2c, + &flashq, len, true); i++; if (i > RETRY) @@ -118,9 +151,22 @@ int wacom_i2c_flash_query(struct wacom_i2c *wac_i2c, u8 query, u8 recvdQuery) int wacom_i2c_flash_end(struct wacom_i2c *wac_i2c) { - if (wacom_i2c_flash_query(wac_i2c, FLASH_END, FLASH_END) == -1) - return ERR_FAILED_EXIT; - printk(KERN_DEBUG "[E-PEN]: Digitizer activated\n"); + int ret; + + /* 2012/07/04 Evaluation for 0x80 and 0xA0 added by Wacom*/ + do { + ret = wacom_i2c_flash_query(wac_i2c, FLASH_END, FLASH_END); + if (ret == -1) + return ERR_FAILED_EXIT; + } while (ret == 0xA0 || ret != 0x80); + /* 2012/07/04 Evaluation for 0x80 and 0xA0 added by Wacom*/ + + /*2012/07/05 + below added for giving firmware enough time to change to user mode*/ + msleep(1000); + + printk(KERN_DEBUG "[E-PEN] Digitizer activated\n"); + wac_i2c->boot_mode = false; return 0; } @@ -157,6 +203,7 @@ int wacom_i2c_flash_erase(struct wacom_i2c *wac_i2c, u8 cmd_erase, { int len, ret, i, j; u8 buf[3], sum, block, flashq; + unsigned long swtich_slot_time; ret = 0; @@ -173,8 +220,7 @@ int wacom_i2c_flash_erase(struct wacom_i2c *wac_i2c, u8 cmd_erase, buf[2] = sum; len = 3; - ret = wacom_i2c_master_send(wac_i2c->client, buf, len, - WACOM_I2C_BOOT); + ret = wacom_i2c_send(wac_i2c, buf, len, true); if (ret < 0) { printk(KERN_ERR "[E-PEN]: Erase failed\n"); return -1; @@ -187,8 +233,8 @@ int wacom_i2c_flash_erase(struct wacom_i2c *wac_i2c, u8 cmd_erase, do { /*sleep */ msleep(100); - ret = wacom_i2c_master_recv(wac_i2c->client, &flashq, - len, WACOM_I2C_BOOT); + ret = wacom_i2c_recv(wac_i2c, + &flashq, len, true); j++; if (j > RETRY || flashq == 0x84 || flashq == 0x88 @@ -203,12 +249,17 @@ int wacom_i2c_flash_erase(struct wacom_i2c *wac_i2c, u8 cmd_erase, printk(KERN_ERR "[E-PEN]: Error:%x\n", flashq); return -1; } - } while (flashq == 0xff); - printk(KERN_DEBUG "[E-PEN]: Erasing at %d, ", i); + + /* 2012/07/04 Evaluation if 0x06 or not added by Wacom*/ + } while (flashq == 0xff || flashq != 0x06); + /* 2012/07/04 Evaluation if 0x06 or not added by Wacom*/ + + if (printk_timed_ratelimit(&swtich_slot_time, 5000)) + printk(KERN_DEBUG "[E-PEN]: Erasing at %d, ", i); /*sleep */ - msleep(20); + msleep(1); } - printk(KERN_DEBUG "Erasing done\n"); + printk(KERN_DEBUG "[E-PEN] Erasing done\n"); return ret; } @@ -216,9 +267,10 @@ int wacom_i2c_flash_write(struct wacom_i2c *wac_i2c, unsigned long startAddr, u8 size, unsigned long maxAddr) { unsigned long ulAddr; - int ret, len, i, j; + int ret, len, i, j, k; char sum; u8 buf[WRITE_BUFF], bank; + unsigned long swtich_slot_time; ret = len = i = 0; bank = BANK; @@ -240,30 +292,43 @@ int wacom_i2c_flash_write(struct wacom_i2c *wac_i2c, unsigned long startAddr, len = 6; - ret = wacom_i2c_master_send(wac_i2c->client, buf, len, - WACOM_I2C_BOOT); - if (ret < 0) { - printk(KERN_ERR "[E-PEN]: Write process aborted\n"); - return ERR_FAILED_ENTER; + /* 2012/07/18 + * if the returned data is not equal to the length of the bytes + * that is supposed to send/receive, return it as fail + */ + for (k = 0; k < RETRY_TRANSFER; k++) { + ret = wacom_i2c_send(wac_i2c, buf, len, true); + if (ret == len) + break; + if (ret < 0 || k == (RETRY_TRANSFER - 1)) { + printk(KERN_ERR "[E-PEN]: Write process aborted\n"); + return ERR_FAILED_ENTER; + } } + /*2012/07/18*/ - msleep(20); + msleep(10); len = 1; j = 0; do { - ret = wacom_i2c_master_recv(wac_i2c->client, buf, len, - WACOM_I2C_BOOT); + msleep(5); + ret = wacom_i2c_recv(wac_i2c, + buf, len, true); j++; if (j > RETRY || buf[0] == 0x90) { /*0xff:No data 0x90:Checksum error */ - printk(KERN_ERR "[E-PEN]: Error:%x\n", buf[0]); + printk(KERN_ERR "[E-PEN] Error: %x , 0x%lx(%d)\n", + buf[0], ulAddr, __LINE__); return -1; } - msleep(20); - } while (buf[0] == 0xff); - msleep(20); + /* 2012/07/04 Evaluation if 0x06 or not added by Wacom*/ + } while (buf[0] == 0xff || buf[0] != 0x06); + /* 2012/07/04 Evaluation if 0x06 or not added by Wacom*/ + + msleep(1); + sum = 0; for (i = 0; i < BLOCK_SIZE_W; i++) { buf[i] = Binary[ulAddr + i]; @@ -273,22 +338,29 @@ int wacom_i2c_flash_write(struct wacom_i2c *wac_i2c, unsigned long startAddr, buf[BLOCK_SIZE_W] = sum; len = BLOCK_SIZE_W + 1; - ret = wacom_i2c_master_send(wac_i2c->client, buf, len, - WACOM_I2C_BOOT); - if (ret < 0) { - printk(KERN_ERR - "[E-PEN]: Firmware flash aborted while writing\n"); - return ERR_NOT_FLASH; + /* 2012/07/18 + * if the returned data is not equal to the length of the bytes + * that is supposed to send/receive, return it as fail + */ + for (k = 0; k < RETRY_TRANSFER; k++) { + ret = wacom_i2c_send(wac_i2c, buf, len, true); + if (ret == len) + break; + if (ret < 0 || k == (RETRY_TRANSFER - 1)) { + printk(KERN_ERR "[E-PEN]: Write process aborted\n"); + return ERR_FAILED_ENTER; + } } + /*2012/07/18*/ - msleep(100); + msleep(50); len = 1; j = 0; do { - msleep(20); - ret = wacom_i2c_master_recv(wac_i2c->client, buf, len, - WACOM_I2C_BOOT); + msleep(10); + ret = wacom_i2c_recv(wac_i2c, + buf, len, true); j++; if (j > RETRY || buf[0] == 0x82 || buf[0] == 0x90) { @@ -297,12 +369,18 @@ int wacom_i2c_flash_write(struct wacom_i2c *wac_i2c, unsigned long startAddr, 0x82:Write error 0x90:Checksum error */ - printk(KERN_ERR "[E-PEN]: Error:%x\n", buf[0]); + printk(KERN_ERR "[E-PEN] Error: %x , 0x%lx(%d)\n", + buf[0], ulAddr, __LINE__); return -1; } - } while (buf[0] == 0xff); - printk(KERN_DEBUG "[E-PEN]: Written on:0x%lx", ulAddr); - msleep(20); + + /* 2012/07/04 Evaluation if 0x06 or not added by Wacom*/ + } while (buf[0] == 0xff || buf[0] != 0x06); + /* 2012/07/04 Evaluation if 0x06 or not added by Wacom*/ + + if (printk_timed_ratelimit(&swtich_slot_time, 5000)) + printk(KERN_DEBUG "[E-PEN]: Written on:0x%lx", ulAddr); + msleep(1); } printk(KERN_DEBUG "\nWriting done\n"); @@ -313,9 +391,10 @@ int wacom_i2c_flash_verify(struct wacom_i2c *wac_i2c, unsigned long startAddr, u8 size, unsigned long maxAddr) { unsigned long ulAddr; - int ret, len, i, j; + int ret, len, i, j, k; char sum; u8 buf[WRITE_BUFF], bank; + unsigned long swtich_slot_time; ret = len = i = 0; bank = BANK; @@ -338,28 +417,39 @@ int wacom_i2c_flash_verify(struct wacom_i2c *wac_i2c, unsigned long startAddr, j = 0; /*sleep */ - ret = wacom_i2c_master_send(wac_i2c->client, buf, len, - WACOM_I2C_BOOT); - if (ret < 0) { - printk(KERN_ERR "[E-PEN]: Write process aborted\n"); - return ERR_FAILED_ENTER; + /* 2012/07/18 + * if the returned data is not equal to the length of the bytes + * that is supposed to send/receive, return it as fail + */ + for (k = 0; k < RETRY_TRANSFER; k++) { + ret = wacom_i2c_send(wac_i2c, buf, len, true); + if (ret == len) + break; + if (ret < 0 || k == (RETRY_TRANSFER - 1)) { + printk(KERN_ERR "[E-PEN]: Write process aborted\n"); + return ERR_FAILED_ENTER; + } } + /*2012/07/18*/ len = 1; do { - msleep(20); - ret = wacom_i2c_master_recv(wac_i2c->client, buf, len, - WACOM_I2C_BOOT); + msleep(1); + ret = wacom_i2c_recv(wac_i2c, + buf, len, true); j++; if (j > RETRY || buf[0] == 0x90) { /*0xff:No data 0x90:Checksum error */ - printk(KERN_ERR "[E-PEN]: Error:%x\n", buf[0]); + printk(KERN_ERR "[E-PEN] Error: %x , 0x%lx(%d)\n", + buf[0], ulAddr, __LINE__); return -1; } - } while (buf[0] == 0xff); + /* 2012/07/04 Evaluation if 0x06 or not added by Wacom*/ + } while (buf[0] == 0xff || buf[0] != 0x06); + /* 2012/07/04 Evaluation if 0x06 or not added by Wacom*/ - msleep(20); + msleep(1); sum = 0; for (i = 0; i < BLOCK_SIZE_W; i++) { buf[i] = Binary[ulAddr + i]; @@ -369,21 +459,27 @@ int wacom_i2c_flash_verify(struct wacom_i2c *wac_i2c, unsigned long startAddr, buf[BLOCK_SIZE_W] = sum; len = BLOCK_SIZE_W + 1; - ret = wacom_i2c_master_send(wac_i2c->client, buf, len, - WACOM_I2C_BOOT); - if (ret < 0) { - printk(KERN_ERR - "[E-PEN]: Firmware flash aborted while writing\n"); - return ERR_NOT_FLASH; + /* 2012/07/18 + * if the returned data is not equal to the length of the bytes + * that is supposed to send/receive, return it as fail + */ + for (k = 0; k < RETRY_TRANSFER; k++) { + ret = wacom_i2c_send(wac_i2c, buf, len, true); + if (ret == len) + break; + if (ret < 0 || k == (RETRY_TRANSFER - 1)) { + printk(KERN_ERR "[E-PEN]: Write process aborted\n"); + return ERR_FAILED_ENTER; + } } + /*2012/07/18*/ - msleep(20); len = 1; j = 0; do { - msleep(20); - ret = wacom_i2c_master_recv(wac_i2c->client, buf, len, - WACOM_I2C_BOOT); + msleep(2); + ret = wacom_i2c_recv(wac_i2c, + buf, len, true); j++; if (j > RETRY || buf[0] == 0x81 || buf[0] == 0x90) { @@ -392,13 +488,28 @@ int wacom_i2c_flash_verify(struct wacom_i2c *wac_i2c, unsigned long startAddr, 0x82:Write error 0x90:Checksum error */ - printk(KERN_ERR "[E-PEN]: Error:%x", buf[0]); + printk(KERN_ERR "[E-PEN] Error: %x , 0x%lx(%d)\n", + buf[0], ulAddr, __LINE__); return -1; } - } while (buf[0] == 0xff); - printk(KERN_DEBUG "[E-PEN]: Verified:0x%lx", ulAddr); - msleep(20); + + /* 2012/07/04 Evaluation if 0x06 or not added by Wacom*/ + } while (buf[0] == 0xff || buf[0] != 0x06); + /* 2012/07/04 Evaluation if 0x06 or not added by Wacom*/ + + if (printk_timed_ratelimit(&swtich_slot_time, 5000)) + printk(KERN_DEBUG "[E-PEN]: Verified:0x%lx", ulAddr); + msleep(1); + } + +#if defined(CONFIG_MACH_P4NOTE) + if (calc_checksum(Binary)) { + printk(KERN_DEBUG + "[E-PEN] check sum not matched\n"); + return -ERR_HEX; } +#endif + printk("\n[E-PEN]: Verifying done\n"); return 0; @@ -406,97 +517,122 @@ int wacom_i2c_flash_verify(struct wacom_i2c *wac_i2c, unsigned long startAddr, int wacom_i2c_flash(struct wacom_i2c *wac_i2c) { - int ret, blver, mcu; - unsigned long i, maxAddr; - ret = blver = mcu = 0; - i = maxAddr = 0; + bool fw_update_enable = false; + int ret = 0, blver = 0, mcu = 0; + u32 max_addr = 0, cmd_addr = 0; + + if (Binary == NULL) { + printk(KERN_ERR"[E-PEN] Data is NULL. Exit.\n"); + return -1; + } + +#if defined(CONFIG_MACH_P4NOTE) + if (calc_checksum(Binary)) { + printk(KERN_DEBUG + "[E-PEN] check sum not matched\n"); + return -ERR_HEX; + } +#endif wake_lock(&wac_i2c->wakelock); ret = wacom_i2c_flash_cmd(wac_i2c); - msleep(20); + if (ret < 0) + goto fw_update_error; + msleep(10); + ret = wacom_i2c_flash_enter(wac_i2c); printk(KERN_DEBUG "[E-PEN]: flashEnter:%d\n", ret); - - /*sleep */ - msleep(20); + msleep(10); blver = wacom_i2c_flash_BLVer(wac_i2c); printk(KERN_DEBUG "[E-PEN]: blver:%d\n", blver); - - /*sleep */ - msleep(20); + msleep(10); mcu = wacom_i2c_flash_mcuId(wac_i2c); printk(KERN_DEBUG "[E-PEN]: mcu:%x\n", mcu); if (Mpu_type != mcu) { - wacom_i2c_flash_end(wac_i2c); - return -1; + printk(KERN_DEBUG "[E-PEN]: mcu:%x\n", mcu); + ret = -ENXIO; + goto mcu_type_error; } - - /*sleep */ - msleep(20); + msleep(1); switch (mcu) { case MPUVER_W8501: printk(KERN_DEBUG "[E-PEN]: flashing for w8501 started\n"); - maxAddr = MAX_ADDR_W8501; - ret = wacom_i2c_flash_erase(wac_i2c, FLASH_ERASE, - MAX_BLOCK_W8501, END_BLOCK); - if (ret < 0) - return -1; - printk(KERN_DEBUG "[E-PEN]: erased:%d\n", ret); - - msleep(20); - - ret = wacom_i2c_flash_write(wac_i2c, START_ADDR, - NUM_BLOCK_2WRITE, maxAddr); - if (ret < 0) - return -1; - - msleep(20); - - ret = wacom_i2c_flash_verify(wac_i2c, START_ADDR, - NUM_BLOCK_2WRITE, maxAddr); - if (ret < 0) - return -1; - + max_addr = MAX_ADDR_W8501; + cmd_addr = MAX_BLOCK_W8501; + fw_update_enable = true; break; case MPUVER_514: printk(KERN_DEBUG "[E-PEN]: Flashing for 514 started\n"); - maxAddr = MAX_ADDR_514; - ret = wacom_i2c_flash_erase(wac_i2c, FLASH_ERASE, - MAX_BLOCK_514, END_BLOCK); - if (ret < 0) - return -1; - printk(KERN_DEBUG "[E-PEN]: erased:%d\n", ret); - - msleep(20); - - ret = wacom_i2c_flash_write(wac_i2c, START_ADDR, - NUM_BLOCK_2WRITE, maxAddr); - if (ret < 0) - return -1; - - msleep(20); - - ret = wacom_i2c_flash_verify(wac_i2c, START_ADDR, - NUM_BLOCK_2WRITE, maxAddr); - if (ret < 0) - return -1; + max_addr = MAX_ADDR_514; + cmd_addr = MAX_BLOCK_514; + fw_update_enable = true; + break; + case MPUVER_505: + printk(KERN_DEBUG "[E-PEN]: Flashing for 505 started\n"); + max_addr = MAX_ADDR_505; + cmd_addr = MAX_BLOCK_505; + fw_update_enable = true; break; default: printk(KERN_DEBUG "[E-PEN]: default called\n"); break; } - msleep(20); - ret = wacom_i2c_flash_end(wac_i2c); - wake_unlock(&wac_i2c->wakelock); - printk(KERN_DEBUG "[E-PEN]: Firmware successfully updated:%x\n", ret); + if (fw_update_enable) { + bool valid_hex = false; + int cnt = 0; + /*2012/07/04: below modified by Wacom*/ + /*If wacom_i2c_flash_verify returns -ERR_HEX, */ + /*please redo whole process of flashing from */ + /*wacom_i2c_flash_erase */ + do { + ret = wacom_i2c_flash_erase(wac_i2c, FLASH_ERASE, + cmd_addr, END_BLOCK); + if (ret < 0) { + printk(KERN_ERR "[E-PEN] error - erase\n"); + continue; + } + msleep(20); - return 0; + ret = wacom_i2c_flash_write(wac_i2c, START_ADDR, + NUM_BLOCK_2WRITE, max_addr); + if (ret < 0) { + printk(KERN_ERR "[E-PEN] error - writing\n"); + continue; + } + msleep(20); + + ret = wacom_i2c_flash_verify(wac_i2c, START_ADDR, + NUM_BLOCK_2WRITE, max_addr); + + if (ret == -ERR_HEX) + printk(KERN_DEBUG "[E-PEN]: firmware is not valied\n"); + else if (ret < 0) { + printk(KERN_ERR "[E-PEN] error - verifying\n"); + continue; + } else + valid_hex = true; + } while ((!valid_hex) && (cnt < 10)); + /*2012/07/04: Wacom*/ + + printk(KERN_DEBUG "[E-PEN]: Firmware successfully updated\n"); + } + msleep(1); + +mcu_type_error: + wacom_i2c_flash_end(wac_i2c); + if (ret < 0) + printk(KERN_ERR "[E-PEN] error - wacom_i2c_flash_end\n"); + +fw_update_error: + wake_unlock(&wac_i2c->wakelock); + return ret; } + |