diff options
Diffstat (limited to 'drivers/input/touchscreen/wacom/w9002_flash.c')
-rw-r--r-- | drivers/input/touchscreen/wacom/w9002_flash.c | 1253 |
1 files changed, 0 insertions, 1253 deletions
diff --git a/drivers/input/touchscreen/wacom/w9002_flash.c b/drivers/input/touchscreen/wacom/w9002_flash.c deleted file mode 100644 index e2fe54d..0000000 --- a/drivers/input/touchscreen/wacom/w9002_flash.c +++ /dev/null @@ -1,1253 +0,0 @@ -/* - * w9002_flash.c - Wacom Digitizer Controller Flash Driver - * - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - * 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 program; if not, write to the Free Software - * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - -#include <linux/wacom_i2c.h> -#include "w9002_flash.h" - -static int wacom_i2c_flash_chksum(struct wacom_i2c *wac_i2c, - unsigned char *flash_data, - unsigned long *max_address) -{ - unsigned long i; - unsigned long chksum = 0; - - for (i = 0x0000; i <= *max_address; i++) - chksum += flash_data[i]; - - chksum &= 0xFFFF; - - return (int)chksum; -} - -static int wacom_flash_cmd(struct wacom_i2c *wac_i2c) -{ - int rv, len, i; - u8 buf[10]; - bool i2c_mode = WACOM_I2C_MODE_BOOT; - -#if defined(CONFIG_MACH_KONA) - buf[0] = 0x0d; - buf[1] = FLASH_START0; - buf[2] = FLASH_START1; - buf[3] = FLASH_START2; - buf[4] = FLASH_START3; - buf[5] = FLASH_START4; - buf[6] = FLASH_START5; - buf[7] = 0x0d; - - len = 8; - rv = wacom_i2c_send(wac_i2c, buf, len, i2c_mode); -#else - - for (i = 0; i < 2; ++i) { - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x32; - buf[len++] = CMD_SET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, i2c_mode); - if (rv < 0) { - printk(KERN_DEBUG "epen:fail change to normal:%d\n", - rv); - - i2c_mode = WACOM_I2C_MODE_NORMAL; - continue; - } - - len = 0; - buf[len++] = 5; - buf[len++] = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 2; - buf[len++] = 2; - - rv = wacom_i2c_send(wac_i2c, buf, len, i2c_mode); - if (rv < 0) { - printk(KERN_DEBUG "epen:fail change to normal:%d\n", - rv); - i2c_mode = WACOM_I2C_MODE_NORMAL; - continue; - } - } -#endif - if (rv < 0) { - printk(KERN_ERR - "Sending flash command failed\n"); - return -1; - } - - printk(KERN_DEBUG "epen:flash cmd sent:%d\n", rv); - msleep(500); - - return 0; -} - -static bool flash_query(struct wacom_i2c *wac_i2c) -{ - int rv, ECH; - u8 buf[4]; - u16 len; - unsigned char command[CMD_SIZE]; - unsigned char response[RSP_SIZE]; - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x37; - buf[len++] = CMD_SET_FEATURE; - - printk(KERN_DEBUG "epen: %s\n", __func__); - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 1 rv:%d\n", rv); - return false; - } - - command[0] = 5; - command[1] = 0; - command[2] = 5; - command[3] = 0; - command[4] = BOOT_CMD_REPORT_ID; - command[5] = BOOT_QUERY; - command[6] = ECH = 7; - - rv = wacom_i2c_send(wac_i2c, command, 7, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 2 rv:%d\n", rv); - return false; - } - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x38; - buf[len++] = CMD_GET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 3 rv:%d\n", rv); - return false; - } - - len = 0; - buf[len++] = 5; - buf[len++] = 0; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 4 rv:%d\n", rv); - return false; - } - - usleep_range(10000, 10000); - - rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, - WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 5 rv:%d\n", rv); - return false; - } - - if ((response[3] != QUERY_CMD) || (response[4] != ECH)) { - printk(KERN_DEBUG "epen: res3:%d res4:%d\n", response[3], - response[4]); - return false; - } - if (response[5] != QUERY_RSP) { - printk(KERN_DEBUG "epen: res5:%d\n", response[5]); - return false; - } - - return true; -} - -static bool flash_blver(struct wacom_i2c *wac_i2c, int *blver) -{ - int rv, ECH; - u8 buf[4]; - u16 len; - unsigned char command[CMD_SIZE]; - unsigned char response[RSP_SIZE]; - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x37; - buf[len++] = CMD_SET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 1 rv:%d\n", rv); - return false; - } - - command[0] = 5; - command[1] = 0; - command[2] = 5; - command[3] = 0; - command[4] = BOOT_CMD_REPORT_ID; - command[5] = BOOT_BLVER; - command[6] = ECH = 7; - - rv = wacom_i2c_send(wac_i2c, command, 7, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 2 rv:%d\n", rv); - return false; - } - - usleep_range(10000, 10000); - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x38; - buf[len++] = CMD_GET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 3 rv:%d\n", rv); - return false; - } - - len = 0; - buf[len++] = 5; - buf[len++] = 0; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 4 rv:%d\n", rv); - return false; - } - - usleep_range(10000, 10000); - - rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, - WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 5 rv:%d\n", rv); - return false; - } - - if ((response[3] != BOOT_CMD) || (response[4] != ECH)) - return false; - - *blver = (int)response[5]; - - return true; -} - -static bool flash_mputype(struct wacom_i2c *wac_i2c, int *pMpuType) -{ - int rv, ECH; - u8 buf[4]; - u16 len; - unsigned char command[CMD_SIZE]; - unsigned char response[RSP_SIZE]; - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x37; - buf[len++] = CMD_SET_FEATURE; /* Command-MSB, SET_REPORT */ - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 1 rv:%d\n", rv); - return false; - } - - command[0] = 5; - command[1] = 0; - command[2] = 5; - command[3] = 0; - command[4] = BOOT_CMD_REPORT_ID; - command[5] = BOOT_MPU; - command[6] = ECH = 7; - - rv = wacom_i2c_send(wac_i2c, command, 7, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 2 rv:%d\n", rv); - return false; - } - - usleep_range(10000, 10000); - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x38; - buf[len++] = CMD_GET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 3 rv:%d\n", rv); - return false; - } - - len = 0; - buf[len++] = 5; - buf[len++] = 0; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 4 rv:%d\n", rv); - return false; - } - - usleep_range(1000, 1000); - - rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, - WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 5 rv:%d\n", rv); - return false; - } - - if ((response[3] != MPU_CMD) || (response[4] != ECH)) - return false; - - *pMpuType = (int)response[5]; - - return true; -} - -static bool flash_security_unlock(struct wacom_i2c *wac_i2c, int *status) -{ - int rv, ECH; - u8 buf[4]; - u16 len; - unsigned char command[CMD_SIZE]; - unsigned char response[RSP_SIZE]; - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x37; - buf[len++] = CMD_SET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 1 rv:%d\n", rv); - return false; - } - - command[0] = 5; - command[1] = 0; - command[2] = 5; - command[3] = 0; - command[4] = BOOT_CMD_REPORT_ID; - command[5] = BOOT_SECURITY_UNLOCK; - command[6] = ECH = 7; - - rv = wacom_i2c_send(wac_i2c, command, 7, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 2 rv:%d\n", rv); - return false; - } - - usleep_range(10000, 10000); - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x38; - buf[len++] = CMD_GET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 3 rv:%d\n", rv); - return 0; - } - - len = 0; - buf[len++] = 5; - buf[len++] = 0; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 4 rv:%d\n", rv); - return false; - } - - usleep_range(1000, 1000); - - rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, - WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 5 rv:%d\n", rv); - return false; - } - - if ((response[3] != SEC_CMD) || (response[4] != ECH)) - return false; - - *status = (int)response[5]; - - return true; -} - -static bool flash_end(struct wacom_i2c *wac_i2c) -{ - int rv, ECH; - u8 buf[4]; - u16 len; - unsigned char command[CMD_SIZE]; - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x37; - buf[len++] = CMD_SET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 1 rv:%d\n", rv); - return false; - } - - command[0] = 5; - command[1] = 0; - command[2] = 5; - command[3] = 0; - command[4] = BOOT_CMD_REPORT_ID; - command[5] = BOOT_EXIT; - command[6] = ECH = 7; - - rv = wacom_i2c_send(wac_i2c, command, 7, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 2 rv:%d\n", rv); - return false; - } - - return true; -} - -static int GetBLVersion(struct wacom_i2c *wac_i2c, int *pBLVer) -{ - int rv; - int retry = 0; - - wacom_flash_cmd(wac_i2c); - do { - msleep(100); - rv = flash_query(wac_i2c); - retry++; - } while (rv < 0 && retry < 10); - - if (rv < 0) - return EXIT_FAIL_GET_BOOT_LOADER_VERSION; - - rv = flash_blver(wac_i2c, pBLVer); - if (rv) - return EXIT_OK; - else - return EXIT_FAIL_GET_BOOT_LOADER_VERSION; -} - -static int GetMpuType(struct wacom_i2c *wac_i2c, int *pMpuType) -{ - int rv; - - if (!flash_query(wac_i2c)) { - if (!wacom_flash_cmd(wac_i2c)) { - return EXIT_FAIL_ENTER_FLASH_MODE; - } else { - msleep(100); - if (!flash_query(wac_i2c)) - return EXIT_FAIL_FLASH_QUERY; - } - } - - rv = flash_mputype(wac_i2c, pMpuType); - if (rv) - return EXIT_OK; - else - return EXIT_FAIL_GET_MPU_TYPE; -} - -static int SetSecurityUnlock(struct wacom_i2c *wac_i2c, int *pStatus) -{ - int rv; - - if (!flash_query(wac_i2c)) { - if (!wacom_flash_cmd(wac_i2c)) { - return EXIT_FAIL_ENTER_FLASH_MODE; - } else { - msleep(100); - if (!flash_query(wac_i2c)) - return EXIT_FAIL_FLASH_QUERY; - } - } - - rv = flash_security_unlock(wac_i2c, pStatus); - if (rv) - return EXIT_OK; - else - return EXIT_FAIL; -} - -static bool flash_erase(struct wacom_i2c *wac_i2c, bool bAllUserArea, - int *eraseBlock, int num) -{ - int rv, ECH; - unsigned char sum; - unsigned char buf[72]; - unsigned char cmd_chksum; - u16 len; - int i, j; - unsigned char command[CMD_SIZE]; - unsigned char response[RSP_SIZE]; - - for (i = 0; i < num; i++) { - /*msleep(500);*/ -retry: - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x37; - buf[len++] = CMD_SET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: failing 1:%d\n", i); - return false; - } - - command[0] = 5; - command[1] = 0; - command[2] = 7; - command[3] = 0; - command[4] = BOOT_CMD_REPORT_ID; - command[5] = BOOT_ERASE_FLASH; - command[6] = ECH = i; - command[7] = *eraseBlock; - eraseBlock++; - - sum = 0; - for (j = 0; j < 8; j++) - sum += command[j]; - cmd_chksum = ~sum + 1; - command[8] = cmd_chksum; - - rv = wacom_i2c_send(wac_i2c, command, 9, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: failing 2:%d\n", i); - return false; - } - - switch (i) { - case 0: - msleep(3000); - break; - - case 1: - msleep(3000); - break; - - case 2: - msleep(5000); - break; - - case 3: - msleep(500); - break; - - default: - msleep(5000); - break; - } - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x38; - buf[len++] = CMD_GET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: failing 3:%d\n", i); - return false; - } - - len = 0; - buf[len++] = 5; - buf[len++] = 0; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: failing 4:%d\n", i); - return false; - } - - rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, - WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: failing 5:%d\n", i); - return false; - } - - if ((response[3] != ERS_CMD) || (response[4] != ECH)) { - printk(KERN_DEBUG "epen: failing 6:%d\n", i); - return false; - } - - if (response[5] == 0x80) { - printk(KERN_DEBUG "epen: retry\n"); - goto retry; - } - if (response[5] != ACK) { - printk(KERN_DEBUG "epen: failing 7:%d res5:%d\n", i, - response[5]); - return false; - } - } - return true; -} - -static bool is_flash_marking(struct wacom_i2c *wac_i2c, - size_t data_size, bool *bMarking, int iMpuID) -{ - const int MAX_CMD_SIZE = (12 + FLASH_BLOCK_SIZE + 2); - int rv, ECH; - unsigned char flash_data[FLASH_BLOCK_SIZE]; - unsigned char buf[300]; - unsigned char sum; - int len; - unsigned int i, j; - unsigned char response[RSP_SIZE]; - unsigned char command[MAX_CMD_SIZE]; - - *bMarking = false; - - printk(KERN_DEBUG "epen: started\n"); - for (i = 0; i < FLASH_BLOCK_SIZE; i++) - flash_data[i] = 0xFF; - - flash_data[56] = 0x00; - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x37; - buf[len++] = CMD_SET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 1 rv:%d\n", rv); - return false; - } - - command[0] = 5; - command[1] = 0; - command[2] = 76; - command[3] = 0; - command[4] = BOOT_CMD_REPORT_ID; - command[5] = BOOT_VERIFY_FLASH; - command[6] = ECH = 1; - command[7] = 0xC0; - command[8] = 0x1F; - command[9] = 0x01; - command[10] = 0x00; - command[11] = 8; - - sum = 0; - for (j = 0; j < 12; j++) - sum += command[j]; - - command[MAX_CMD_SIZE - 2] = ~sum + 1; - - sum = 0; - printk(KERN_DEBUG "epen: start writing command\n"); - for (i = 12; i < (FLASH_BLOCK_SIZE + 12); i++) { - command[i] = flash_data[i - 12]; - sum += flash_data[i - 12]; - } - command[MAX_CMD_SIZE - 1] = ~sum + 1; - - printk(KERN_DEBUG "epen: sending command\n"); - rv = wacom_i2c_send(wac_i2c, command, MAX_CMD_SIZE, - WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 2 rv:%d\n", rv); - return false; - } - - usleep_range(10000, 10000); - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x38; - buf[len++] = CMD_GET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 3 rv:%d\n", rv); - return false; - } - - len = 0; - buf[len++] = 5; - buf[len++] = 0; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 4 rv:%d\n", rv); - return false; - } - - rv = wacom_i2c_recv(wac_i2c, response, RSP_SIZE, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 5 rv:%d\n", rv); - return false; - } - - printk(KERN_DEBUG "epen: checking response\n"); - if ((response[3] != MARK_CMD) || - (response[4] != ECH) || (response[5] != ACK)) { - printk(KERN_DEBUG "epen: fails res3:%d res4:%d res5:%d\n", - response[3], response[4], response[5]); - return false; - } - - *bMarking = true; - return true; -} - -static bool flash_write_block(struct wacom_i2c *wac_i2c, char *flash_data, - unsigned long ulAddress, u8 *pcommand_id) -{ - const int MAX_COM_SIZE = (12 + FLASH_BLOCK_SIZE + 2); - int len, ECH; - unsigned char buf[300]; - int rv; - unsigned char sum; - unsigned char command[MAX_COM_SIZE]; - unsigned char response[RSP_SIZE]; - unsigned int i; - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x37; - buf[len++] = CMD_SET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) - return false; - - command[0] = 5; - command[1] = 0; - command[2] = 76; - command[3] = 0; - command[4] = BOOT_CMD_REPORT_ID; - command[5] = BOOT_WRITE_FLASH; - command[6] = ECH = ++(*pcommand_id); - command[7] = ulAddress & 0x000000ff; - command[8] = (ulAddress & 0x0000ff00) >> 8; - command[9] = (ulAddress & 0x00ff0000) >> 16; - command[10] = (ulAddress & 0xff000000) >> 24; - command[11] = 8; - sum = 0; - for (i = 0; i < 12; i++) - sum += command[i]; - command[MAX_COM_SIZE - 2] = ~sum + 1; - - sum = 0; - for (i = 12; i < (FLASH_BLOCK_SIZE + 12); i++) { - command[i] = flash_data[ulAddress + (i - 12)]; - sum += flash_data[ulAddress + (i - 12)]; - } - command[MAX_COM_SIZE - 1] = ~sum + 1; - - rv = wacom_i2c_send(wac_i2c, command, BOOT_CMD_SIZE, - WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 1 rv:%d\n", rv); - return false; - } - - usleep_range(10000, 10000); - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x38; - buf[len++] = CMD_GET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 2 rv:%d\n", rv); - return false; - } - - len = 0; - buf[len++] = 5; - buf[len++] = 0; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 3 rv:%d\n", rv); - return false; - } - - rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, - WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 4 rv:%d\n", rv); - return false; - } - - if ((response[3] != WRITE_CMD) || - (response[4] != ECH) || response[5] != ACK) - return false; - - return true; - -} - -static bool flash_write(struct wacom_i2c *wac_i2c, - unsigned char *flash_data, size_t data_size, - unsigned long start_address, unsigned long *max_address, - int mpuType) -{ - unsigned long ulAddress; - int i; - bool rv; - unsigned long pageNo = 0; - u8 command_id = 0; - - printk(KERN_DEBUG "epen: flash_write start\n"); - - for (ulAddress = start_address; ulAddress < *max_address; - ulAddress += FLASH_BLOCK_SIZE) { - unsigned int j; - bool bWrite = false; - - /* Wacom 2012/10/04: skip if all each data locating on - from ulAddr to ulAddr+Block_SIZE_W are 0xff */ - for (i = 0; i < FLASH_BLOCK_SIZE; i++) { - if (flash_data[ulAddress + i] != 0xFF) - break; - } - if (i == (FLASH_BLOCK_SIZE)) { - /*printk(KERN_DEBUG"epen:BLOCK PASSED\n"); */ - continue; - } - /* Wacom 2012/10/04 */ - - for (j = 0; j < FLASH_BLOCK_SIZE; j++) { - if (flash_data[ulAddress + j] == 0xFF) - continue; - else { - bWrite = true; - break; - } - } - - if (!bWrite) { - pageNo++; - continue; - } - - rv = flash_write_block(wac_i2c, flash_data, ulAddress, - &command_id); - if (!rv) - return false; - - pageNo++; - } - - return true; -} - -static bool flash_verify(struct wacom_i2c *wac_i2c, - unsigned char *flash_data, size_t data_size, - unsigned long start_address, - unsigned long *max_address, int mpuType) -{ - int ECH; - unsigned long ulAddress; - int rv; - unsigned long pageNo = 0; - u8 command_id = 0; - printk(KERN_DEBUG "epen: verify starts\n"); - for (ulAddress = start_address; ulAddress < *max_address; - ulAddress += FLASH_BLOCK_SIZE) { - const int MAX_CMD_SIZE = 12 + FLASH_BLOCK_SIZE + 2; - unsigned char buf[300]; - unsigned char sum; - int len; - unsigned int i, j; - unsigned char command[MAX_CMD_SIZE]; - unsigned char response[RSP_SIZE]; - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x37; - buf[len++] = CMD_SET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 1 rv:%d\n", rv); - return false; - } - - command[0] = 5; - command[1] = 0; - command[2] = 76; - command[3] = 0; - command[4] = BOOT_CMD_REPORT_ID; - command[5] = BOOT_VERIFY_FLASH; - command[6] = ECH = ++command_id; - command[7] = ulAddress & 0x000000ff; - command[8] = (ulAddress & 0x0000ff00) >> 8; - command[9] = (ulAddress & 0x00ff0000) >> 16; - command[10] = (ulAddress & 0xff000000) >> 24; - command[11] = 8; - - sum = 0; - for (j = 0; j < 12; j++) - sum += command[j]; - command[MAX_CMD_SIZE - 2] = ~sum + 1; - - sum = 0; - for (i = 12; i < (FLASH_BLOCK_SIZE + 12); i++) { - command[i] = flash_data[ulAddress + (i - 12)]; - sum += flash_data[ulAddress + (i - 12)]; - } - command[MAX_CMD_SIZE - 1] = ~sum + 1; - - rv = wacom_i2c_send(wac_i2c, command, BOOT_CMD_SIZE, - WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 2 rv:%d\n", rv); - return false; - } - - if (ulAddress <= 0x0ffff) - ndelay(250000); - else if (ulAddress >= 0x10000 && ulAddress <= 0x20000) - ndelay(350000); - else - usleep_range(10000, 10000); - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x38; - buf[len++] = CMD_GET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 3 rv:%d\n", rv); - return false; - } - - len = 0; - buf[len++] = 5; - buf[len++] = 0; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 4 rv:%d\n", rv); - return false; - } - - rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, - WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 5 rv:%d\n", rv); - return false; - } - - if ((response[3] != VERIFY_CMD) || - (response[4] != ECH) || (response[5] != ACK)) { - printk(KERN_DEBUG "epen: res3:%d res4:%d res5:%d\n", - response[3], response[4], response[5]); - return false; - } - pageNo++; - } - - return true; -} - -static bool flash_marking(struct wacom_i2c *wac_i2c, - size_t data_size, bool bMarking, int iMpuID) -{ - const int MAX_CMD_SIZE = 12 + FLASH_BLOCK_SIZE + 2; - int rv, ECH; - unsigned char flash_data[FLASH_BLOCK_SIZE]; - unsigned char buf[300]; - unsigned char response[RSP_SIZE]; - unsigned char sum; - int len; - unsigned int i, j; - unsigned char command[MAX_CMD_SIZE]; - - for (i = 0; i < FLASH_BLOCK_SIZE; i++) - flash_data[i] = 0xFF; - - if (bMarking) - flash_data[56] = 0x00; - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x37; - buf[len++] = CMD_SET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 1 rv:%d\n", rv); - return false; - } - - command[0] = 5; - command[1] = 0; - command[2] = 76; - command[3] = 0; - command[4] = BOOT_CMD_REPORT_ID; - command[5] = BOOT_WRITE_FLASH; - command[6] = ECH = 1; - command[7] = 0xC0; - command[8] = 0x1F; - command[9] = 0x01; - command[10] = 0x00; - command[11] = 8; - - sum = 0; - for (j = 0; j < 12; j++) - sum += command[j]; - command[MAX_CMD_SIZE - 2] = ~sum + 1; - - sum = 0; - for (i = 12; i < (FLASH_BLOCK_SIZE + 12); i++) { - command[i] = flash_data[i - 12]; - sum += flash_data[i - 12]; - } - command[MAX_CMD_SIZE - 1] = ~sum + 1; - - rv = wacom_i2c_send(wac_i2c, command, BOOT_CMD_SIZE, - WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 2 rv:%d\n", rv); - return false; - } - - usleep_range(10000, 10000); - - len = 0; - buf[len++] = 4; - buf[len++] = 0; - buf[len++] = 0x38; - buf[len++] = CMD_GET_FEATURE; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 3 rv:%d\n", rv); - return false; - } - - len = 0; - buf[len++] = 5; - buf[len++] = 0; - - rv = wacom_i2c_send(wac_i2c, buf, len, WACOM_I2C_MODE_BOOT); - if (rv < 0) { - printk(KERN_DEBUG "epen: 4 rv:%d\n", rv); - return false; - } - - printk(KERN_DEBUG "epen: confirming marking\n"); - rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, - WACOM_I2C_MODE_BOOT); - if (rv < 0) - return false; - - if ((response[3] != 1) || (response[4] != ECH)\ - || (response[5] != ACK)) { - printk(KERN_DEBUG "epen: failing res3:%d res4:%d res5:%d\n", - response[3], response[4], response[5]); - return false; - } - - return true; -} - -int wacom_i2c_flash(struct wacom_i2c *wac_i2c) -{ - unsigned long max_address = 0; - unsigned long start_address = 0x4000; - int eraseBlock[50], eraseBlockNum; - bool bRet; - int iChecksum; - int iBLVer, iMpuType, iStatus; - bool bMarking; - int iRet; - unsigned long ulMaxRange; - - if (Binary == NULL) { - printk(KERN_ERR"[E-PEN] Data is NULL. Exit.\n"); - return -1; - } - -#ifdef WACOM_HAVE_FWE_PIN - if (wac_i2c->have_fwe_pin) { - wac_i2c->wac_pdata->compulsory_flash_mode(true); - /*Reset */ - wac_i2c->wac_pdata->reset_platform_hw(); - msleep(200); - printk(KERN_DEBUG "epen: Set FWE\n"); - } -#endif - wake_lock(&wac_i2c->wakelock); - - printk(KERN_DEBUG "epen:start getting the boot loader version\n"); - /*Obtain boot loader version */ - iRet = GetBLVersion(wac_i2c, &iBLVer); - if (iRet != EXIT_OK) { - printk(KERN_DEBUG "epen:failed to get Boot Loader version\n"); - goto fw_update_error; - } - - printk(KERN_DEBUG "epen: start getting the MPU version\n"); - /*Obtain MPU type: this can be manually done in user space */ - iRet = GetMpuType(wac_i2c, &iMpuType); - if (iRet != EXIT_OK) { - printk(KERN_DEBUG "epen: failed to get MPU type\n"); - goto fw_update_error; - } - - /*Set start and end address and block numbers */ - eraseBlockNum = 0; - start_address = 0x4000; - max_address = 0x12FFF; - eraseBlock[eraseBlockNum++] = 2; - eraseBlock[eraseBlockNum++] = 1; - eraseBlock[eraseBlockNum++] = 0; - eraseBlock[eraseBlockNum++] = 3; - - printk(KERN_DEBUG "epen: obtaining the checksum\n"); - /*Calculate checksum */ - iChecksum = wacom_i2c_flash_chksum(wac_i2c, Binary, &max_address); - printk(KERN_DEBUG "epen: Checksum is :%d\n", iChecksum); - - bRet = true; - - printk(KERN_DEBUG "epen: setting the security unlock\n"); - /*Unlock security */ - iRet = SetSecurityUnlock(wac_i2c, &iStatus); - if (iRet != EXIT_OK) { - printk(KERN_DEBUG "epen: failed to set security unlock\n"); - goto fw_update_error; - } - - /*Set adress range */ - ulMaxRange = max_address; - ulMaxRange -= start_address; - ulMaxRange >>= 6; - if (max_address > (ulMaxRange << 6)) - ulMaxRange++; - - printk(KERN_DEBUG "epen: connecting to Wacom Digitizer\n"); - printk(KERN_DEBUG "epen: erasing the current firmware\n"); - /*Erase the old program */ - bRet = flash_erase(wac_i2c, true, eraseBlock, eraseBlockNum); - if (!bRet) { - printk(KERN_DEBUG "epen: failed to erase the user program\n"); - iRet = EXIT_FAIL_ERASE; - goto fw_update_error; - } - printk(KERN_DEBUG "epen: erasing done\n"); - - max_address = 0x11FC0; - - printk(KERN_DEBUG "epen: writing new firmware\n"); - /*Write the new program */ - bRet = - flash_write(wac_i2c, Binary, DATA_SIZE, start_address, &max_address, - iMpuType); - if (!bRet) { - printk(KERN_DEBUG "epen: failed to write firmware\n"); - iRet = EXIT_FAIL_WRITE_FIRMWARE; - goto fw_update_error; - } - - printk(KERN_DEBUG "epen: start marking\n"); - /*Set mark in writing process */ - bRet = flash_marking(wac_i2c, DATA_SIZE, true, iMpuType); - if (!bRet) { - printk(KERN_DEBUG "epen: failed to mark firmware\n"); - iRet = EXIT_FAIL_WRITE_FIRMWARE; - goto fw_update_error; - } - - /*Set the address for verify */ - start_address = 0x4000; - max_address = 0x11FBF; - - printk(KERN_DEBUG "epen: start the verification\n"); - /*Verify the written program */ - bRet = - flash_verify(wac_i2c, Binary, DATA_SIZE, start_address, - &max_address, iMpuType); - if (!bRet) { - printk(KERN_DEBUG "epen: failed to verify the firmware\n"); - iRet = EXIT_FAIL_VERIFY_FIRMWARE; - goto fw_update_error; - } - - printk(KERN_DEBUG "epen: checking the mark\n"); - /*Set mark */ - bRet = is_flash_marking(wac_i2c, DATA_SIZE, &bMarking, iMpuType); - if (!bRet) { - printk(KERN_DEBUG "epen: marking firmwrae failed\n"); - iRet = EXIT_FAIL_WRITING_MARK_NOT_SET; - goto fw_update_error; - } - - /*Enable */ - printk(KERN_DEBUG "epen: closing the boot mode\n"); - bRet = flash_end(wac_i2c); - if (!bRet) { - printk(KERN_DEBUG "epen: closing boot mode failed\n"); - iRet = EXIT_FAIL_WRITING_MARK_NOT_SET; - goto fw_update_error; - } - iRet = EXIT_OK; - printk(KERN_DEBUG "epen: write and verify completed\n"); - -fw_update_error: - wake_unlock(&wac_i2c->wakelock); - -#ifdef WACOM_HAVE_FWE_PIN - if (wac_i2c->have_fwe_pin) { - wac_i2c->wac_pdata->compulsory_flash_mode(false); - /*Reset */ - wac_i2c->wac_pdata->reset_platform_hw(); - msleep(200); - } -#endif - return iRet; -} |