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