aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/input/touchscreen/wacom/wacom_i2c_flash.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/input/touchscreen/wacom/wacom_i2c_flash.c')
-rw-r--r--drivers/input/touchscreen/wacom/wacom_i2c_flash.c418
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;
}
+