int flash_query(struct wacom_i2c *wac_i2c) { u8 command[CMD_SIZE]; u8 response[RSP_SIZE]; int ret, ECH; int len = 0; command[len++] = 4; /* Command Register-LSB */ command[len++] = 0; /* Command Register-MSB */ command[len++] = 0x37; /* Command-LSB, ReportType:Feature(11) ReportID:7 */ command[len++] = CMD_SET_FEATURE; /* Command-MSB, SET_REPORT */ command[len++] = 5; /* Data Register-LSB */ command[len++] = 0; /* Data-Register-MSB */ command[len++] = 5; /* Length Field-LSB */ command[len++] = 0; /* Length Field-MSB */ command[len++] = BOOT_CMD_REPORT_ID; /* Report:ReportID */ command[len++] = BOOT_QUERY; /* Report:Boot Query command */ command[len++] = ECH = 7; /* Report:echo */ ret = wacom_i2c_send(wac_i2c, command, len, WACOM_I2C_MODE_BOOT); if (ret < 0) { printk(KERN_DEBUG"epen:%s 2 ret:%d \n", __func__, ret); return -EXIT_FAIL_SEND_QUERY_COMMAND; } len = 0; command[len++] = 4; /* Command Register-LSB */ command[len++] = 0; /* Command Register-MSB */ command[len++] = 0x38; /* Command-LSB, ReportType:Feature(11) ReportID:8 */ command[len++] = CMD_GET_FEATURE; /* Command-MSB, GET_REPORT */ command[len++] = 5; /* Data Register-LSB */ command[len++] = 0; /* Data Register-MSB */ ret = wacom_i2c_send(wac_i2c, command, len, WACOM_I2C_MODE_BOOT); if (ret < 0) { printk(KERN_DEBUG"epen:%s 2 ret:%d \n", __func__, ret); return -EXIT_FAIL_SEND_QUERY_COMMAND; } msleep(10); ret = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, WACOM_I2C_MODE_BOOT); if (ret < 0) { printk(KERN_DEBUG"epen:%s 5 ret:%d \n", __func__, ret); return -EXIT_FAIL_SEND_QUERY_COMMAND; } if ((response[3] != QUERY_CMD) || (response[4] != ECH)) { printk(KERN_DEBUG"epen:%s res3:%x res4:%x \n", __func__, response[3], response[4]); return -EXIT_FAIL_SEND_QUERY_COMMAND; } if (response[5] != QUERY_RSP) { printk(KERN_DEBUG"epen:%s res5:%x \n", __func__, response[5]); return -EXIT_FAIL_SEND_QUERY_COMMAND; } return 0; }
int wacom_i2c_test(struct wacom_i2c *wac_i2c) { int ret, i; char buf, test[10]; buf = COM_QUERY; ret = wacom_i2c_send(wac_i2c, &buf, sizeof(buf), false); if (ret > 0) printk(KERN_INFO "[E-PEN] buf:%d, sent:%d\n", buf, ret); else { printk(KERN_ERR "[E-PEN] Digitizer is not active\n"); return -1; } ret = wacom_i2c_recv(wac_i2c, test, sizeof(test), false); if (ret >= 0) { for (i = 0; i < 8; i++) printk(KERN_INFO "[E-PEN] %d\n", test[i]); } else { printk(KERN_ERR "[E-PEN] Digitizer does not reply\n"); return -1; } return 0; }
static void wacom_open_test(struct wacom_i2c *wac_i2c) { u8 cmd = 0; u8 buf[2] = {0,}; int ret = 0, cnt = 30; cmd = WACOM_I2C_STOP; ret = wacom_i2c_send(wac_i2c, &cmd, 1, false); if (ret <= 0) { printk(KERN_ERR "[E-PEN] failed to send stop command\n"); return ; } cmd = WACOM_I2C_GRID_CHECK; ret = wacom_i2c_send(wac_i2c, &cmd, 1, false); if (ret <= 0) { printk(KERN_ERR "[E-PEN] failed to send stop command\n"); goto grid_check_error; } cmd = WACOM_STATUS; do { msleep(50); if (1 == wacom_i2c_send(wac_i2c, &cmd, 1, false)) { if (2 == wacom_i2c_recv(wac_i2c, buf, 2, false)) { switch (buf[0]) { /* * status value * 0 : data is not ready * 1 : PASS * 2 : Fail (coil function error) * 3 : Fail (All coil function error) */ case 1: case 2: case 3: cnt = 0; break; default: break; } } } } while (cnt--); wac_i2c->connection_check = (1 == buf[0]); printk(KERN_DEBUG "[E-PEN] epen_connection : %s %d\n", (1 == buf[0]) ? "Pass" : "Fail", buf[1]); grid_check_error: cmd = WACOM_I2C_STOP; wacom_i2c_send(wac_i2c, &cmd, 1, false); cmd = WACOM_I2C_START; wacom_i2c_send(wac_i2c, &cmd, 1, false); }
int wacom_i2c_test(struct wacom_i2c *wac_i2c) { int ret, i; char buf, test[10]; buf = COM_QUERY; ret = wacom_i2c_send(wac_i2c, &buf, sizeof(buf), false); if (ret > 0) dev_info(&wac_i2c->client->dev, "%s: buf:%d, sent:%d\n", __func__, buf, ret); else { dev_err(&wac_i2c->client->dev, "%s: Digitizer is not active\n", __func__); return -1; } ret = wacom_i2c_recv(wac_i2c, test, sizeof(test), false); if (ret >= 0) { for (i = 0; i < 8; i++) dev_info(&wac_i2c->client->dev, "%s: %d\n", __func__, test[i]); } else { dev_err(&wac_i2c->client->dev, "%s: Digitizer does not reply\n", __func__); return -1; } return 0; }
static bool flash_blver(struct wacom_i2c *wac_i2c, int *blver) { u8 command[CMD_SIZE]; u8 response[RSP_SIZE]; int ret, ECH; int len = 0; command[len++] = 4; /* Command Register-LSB */ command[len++] = 0; /* Command Register-MSB */ command[len++] = 0x37; /* Command-LSB, ReportType:Feature(11) ReportID:7 */ command[len++] = CMD_SET_FEATURE; /* Command-MSB, SET_REPORT */ command[len++] = 5; /* Data Register-LSB */ command[len++] = 0; /* Data-Register-MSB */ command[len++] = 5; /* Length Field-LSB */ command[len++] = 0; /* Length Field-MSB */ command[len++] = BOOT_CMD_REPORT_ID; /* Report:ReportID */ command[len++] = BOOT_BLVER; /* Report:Boot Version command */ command[len++] = ECH = 7; /* Report:echo */ ret = wacom_i2c_send(wac_i2c, command, len, WACOM_I2C_MODE_BOOT); if (ret < 0) { printk(KERN_DEBUG"epen:%s 2 ret:%d \n", __func__, ret); return false; } len = 0; command[len++] = 4; /* Command Register-LSB */ command[len++] = 0; /* Command Register-MSB */ command[len++] = 0x38; /* Command-LSB, ReportType:Feature(11) ReportID:8 */ command[len++] = CMD_GET_FEATURE; /* Command-MSB, GET_REPORT */ command[len++] = 5; /* Data Register-LSB */ command[len++] = 0; /* Data Register-MSB */ ret = wacom_i2c_send(wac_i2c, command, len, WACOM_I2C_MODE_BOOT); if (ret < 0) { printk(KERN_DEBUG"epen:%s 4 ret:%d \n", __func__, ret); return false; } msleep(10); ret = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, WACOM_I2C_MODE_BOOT); if (ret < 0) { printk(KERN_DEBUG"epen:%s 5 ret:%d \n", __func__, ret); return false; } if ((response[3] != BOOT_CMD) || (response[4] != ECH)) { printk(KERN_DEBUG"epen:%s res[3]:%x res[4]:%x \n", __func__, response[3], response[4]); return false; } *blver = (int)response[5]; return true; }
int wacom_checksum(struct wacom_i2c *wac_i2c) { int ret = 0, retry = 10; int i = 0; u8 buf[5] = {0, }; buf[0] = COM_CHECKSUM; while (retry--) { ret = wacom_i2c_send(wac_i2c, &buf[0], 1, false); if (ret < 0) { printk(KERN_DEBUG "[E-PEN] i2c fail, retry, %d\n", __LINE__); continue; } msleep(200); ret = wacom_i2c_recv(wac_i2c, buf, 5, false); if (ret < 0) { printk(KERN_DEBUG "[E-PEN] i2c fail, retry, %d\n", __LINE__); continue; } else if (buf[0] == 0x1f) break; printk(KERN_DEBUG "[E-PEN] checksum retry\n"); } if (ret >= 0) { printk(KERN_DEBUG "[E-PEN] received checksum %x, %x, %x, %x, %x\n", buf[0], buf[1], buf[2], buf[3], buf[4]); } for (i = 0; i < 5; ++i) { if (buf[i] != Firmware_checksum[i]) { printk(KERN_DEBUG "[E-PEN] checksum fail %dth %x %x\n", i, buf[i], Firmware_checksum[i]); break; } } wac_i2c->checksum_result = (5 == i); #ifdef WACOM_CONNECTION_CHECK if (!wac_i2c->connection_check) wacom_open_test(wac_i2c); #endif return ret; }
int wacom_checksum(struct wacom_i2c *wac_i2c) { int ret = 0, retry = 10; int i = 0; u8 buf[5] = {0, }; buf[0] = COM_CHECKSUM; while (retry--) { ret = wacom_i2c_send(wac_i2c, &buf[0], 1, false); if (ret < 0) { dev_err(&wac_i2c->client->dev, "%s: i2c fail, retry, %d\n", __func__, __LINE__); continue; } msleep(200); ret = wacom_i2c_recv(wac_i2c, buf, 5, false); if (ret < 0) { dev_err(&wac_i2c->client->dev, "%s: i2c fail, retry, %d\n", __func__, __LINE__); continue; } else if (buf[0] == 0x1f) break; dev_info(&wac_i2c->client->dev, "%s: checksum retry\n", __func__); } if (ret >= 0) { dev_info(&wac_i2c->client->dev, "%s: received checksum %x, %x, %x, %x, %x\n", __func__, buf[0], buf[1], buf[2], buf[3], buf[4]); } for (i = 0; i < 5; ++i) { if (buf[i] != Firmware_checksum[i]) { dev_info(&wac_i2c->client->dev, "%s: checksum fail %dth %x %x\n", __func__, i, buf[i], Firmware_checksum[i]); break; } } wac_i2c->checksum_result = (5 == i); return ret; }
int wacom_checksum(struct wacom_i2c *wac_i2c) { int ret = 0, retry = 10; int i = 0; u8 buf[5] = {0, }; buf[0] = COM_CHECKSUM; while (retry--) { ret = wacom_i2c_send(wac_i2c, &buf[0], 1, false); if (ret < 0) { printk(KERN_DEBUG "epen:i2c fail, retry, %d\n", __LINE__); continue; } msleep(200); ret = wacom_i2c_recv(wac_i2c, buf, 5, false); if (ret < 0) { printk(KERN_DEBUG "epen:i2c fail, retry, %d\n", __LINE__); continue; } else if (buf[0] == 0x1f) break; printk(KERN_DEBUG "epen:checksum retry\n"); } if (ret >= 0) { printk(KERN_DEBUG "epen:received checksum %x, %x, %x, %x, %x\n", buf[0], buf[1], buf[2], buf[3], buf[4]); } for (i = 0; i < 5; ++i) { if (buf[i] != fw_chksum[i]) { printk(KERN_DEBUG "epen:checksum fail %dth %x %x\n", i, buf[i], fw_chksum[i]); break; } } wac_i2c->checksum_result = (5 == i); return ret; }
static void wacom_i2c_resume_work(struct work_struct *work) { struct wacom_i2c *wac_i2c = container_of(work, struct wacom_i2c, resume_work.work); u8 irq_state = 0; int ret = 0; irq_state = wac_i2c->wac_pdata->get_irq_state(); wacom_enable_irq(wac_i2c, true); if (unlikely(irq_state)) { printk(KERN_DEBUG"epen:irq was enabled\n"); ret = wacom_i2c_recv(wac_i2c, wac_i2c->wac_feature->data, COM_COORD_NUM, false); if (ret < 0) { printk(KERN_ERR "epen:%s failed to read i2c.L%d\n", __func__, __LINE__); } } printk(KERN_DEBUG "epen:%s\n", __func__); }
bool flash_devcieType(struct wacom_i2c *wac_i2c) { int rv; u8 buf[4]; u16 len; len = 0; buf[len++] = 4; buf[len++] = 0; buf[len++] = 0x32; buf[len++] = CMD_GET_FEATURE; rv = wacom_i2c_send(wac_i2c, buf, len, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } len = 0; buf[len++] = 5; buf[len++] = 0; rv = wacom_i2c_send(wac_i2c, buf, len, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } rv = wacom_i2c_recv(wac_i2c, buf, 4, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } return true; }
int wacom_i2c_query(struct wacom_i2c *wac_i2c) { struct wacom_g5_platform_data *pdata = wac_i2c->pdata; struct wacom_features *wac_feature = wac_i2c->wac_feature; u8 data[COM_QUERY_BUFFER] = {0, }; u8 *query = data + COM_QUERY_POS; int read_size = COM_QUERY_BUFFER; u8 buf = COM_QUERY; int ret; int i; int max_x, max_y, pressure; for (i = 0; i < COM_QUERY_RETRY; i++) { if (unlikely(pdata->use_query_cmd)) { ret = wacom_i2c_send(wac_i2c, &buf, 1, false); if (ret < 0) { printk(KERN_ERR"epen:I2C send failed(%d)\n", ret); msleep(50); continue; } read_size = COM_QUERY_NUM; query = data; msleep(50); } ret = wacom_i2c_recv(wac_i2c, data, read_size, false); if (ret < 0) { printk(KERN_ERR"epen:I2C recv failed(%d)\n", ret); continue; } printk(KERN_INFO "epen:%s: %dth ret of wacom query=%d\n", __func__, i, ret); if (read_size != ret) { printk(KERN_ERR"epen:read size error %d of %d\n", ret, read_size); continue; } if (0x0f == query[EPEN_REG_HEADER]) { wac_feature->fw_version = ((u16) query[EPEN_REG_FWVER1] << 8) + (u16) query[EPEN_REG_FWVER2]; break; } printk(KERN_ERR "epen:%X, %X, %X, %X, %X, %X, %X, fw=0x%x\n", query[0], query[1], query[2], query[3], query[4], query[5], query[6], wac_feature->fw_version); } printk(KERN_NOTICE "epen:%X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X, %X\n", query[0], query[1], query[2], query[3], query[4], query[5], query[6], query[7], query[8], query[9], query[10], query[11], query[12], query[13]); if (i == COM_QUERY_RETRY || ret < 0) { printk(KERN_ERR"epen:%s:failed to read query\n", __func__); wac_feature->fw_version = 0; wac_i2c->query_status = false; return ret; } wac_i2c->query_status = true; max_x = ((u16) query[EPEN_REG_X1] << 8) + (u16) query[EPEN_REG_X2]; max_y = ((u16) query[EPEN_REG_Y1] << 8) + (u16) query[EPEN_REG_Y2]; pressure = ((u16) query[EPEN_REG_PRESSURE1] << 8) + (u16) query[EPEN_REG_PRESSURE2]; printk(KERN_NOTICE"epen:q max_x=%d max_y=%d, max_pressure=%d\n", max_x, max_y, pressure); printk(KERN_NOTICE"epen:p max_x=%d max_y=%d, max_pressure=%d\n", pdata->max_x, pdata->max_y, pdata->max_pressure); printk(KERN_NOTICE "epen:fw_version=0x%X (d7:0x%X,d8:0x%X)\n", wac_feature->fw_version, query[EPEN_REG_FWVER1], query[EPEN_REG_FWVER2]); printk(KERN_NOTICE "epen:mpu %#x, bl %#x, tx %d, ty %d, h %d\n", query[EPEN_REG_MPUVER], query[EPEN_REG_BLVER], query[EPEN_REG_TILT_X], query[EPEN_REG_TILT_Y], query[EPEN_REG_HEIGHT]); return ret; }
bool flash_marking(struct wacom_i2c *wac_i2c, 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, false); 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 = 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]; } /* Report:data checksum */ command[MAX_CMD_SIZE - 1] = ~sum + 1; rv = wacom_i2c_send(wac_i2c, command, BOOT_CMD_SIZE, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } usleep(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, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } len = 0; buf[len++] = 5; buf[len++] = 0; rv = wacom_i2c_send(wac_i2c, buf, len, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } pr_info("wacom: %s confirming marking\n", __func__); rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } if ((response[3] != 1) || (response[4] != ECH) || (response[5] != ACK)) { pr_err( "wacom: %s failing res3:%d res4:%d res5:%d\n", __func__, response[3], response[4], response[5]); return false; } return true; }
static ssize_t epen_connection_show(struct device *dev, struct device_attribute *attr, char *buff) { struct wacom_i2c *wac_i2c = dev_get_drvdata(dev); u8 cmd = 0; u8 buf[2] = {0,}; int ret = 0, cnt = 10; disable_irq(wac_i2c->client->irq); cmd = WACOM_I2C_STOP; ret = wacom_i2c_send(wac_i2c, &cmd, 1, false); if (ret <= 0) { dev_err(&wac_i2c->client->dev, "%s: failed to send stop command\n", __func__); goto grid_check_error; } cmd = WACOM_I2C_GRID_CHECK; ret = wacom_i2c_send(wac_i2c, &cmd, 1, false); if (ret <= 0) { dev_err(&wac_i2c->client->dev, "%s: failed to send stop command\n", __func__); goto grid_check_error; } cmd = WACOM_STATUS; do { msleep(50); if (1 == wacom_i2c_send(wac_i2c, &cmd, 1, false)) { if (2 == wacom_i2c_recv(wac_i2c, buf, 2, false)) { switch (buf[0]) { /* * status value * 0 : data is not ready * 1 : PASS * 2 : Fail (coil function error) * 3 : Fail (All coil function error) */ case 1: case 2: case 3: cnt = 0; break; default: break; } } } } while (cnt--); dev_info(&wac_i2c->client->dev, "%s : status: %x, error code: %x\n", __func__, buf[0], buf[1]); grid_check_error: cmd = WACOM_I2C_STOP; ret = wacom_i2c_send(wac_i2c, &cmd, 1, false); if (ret <= 0) dev_err(&wac_i2c->client->dev, "%s: failed to send stop command\n", __func__); cmd = WACOM_I2C_START; wacom_i2c_send(wac_i2c, &cmd, 1, false); if (ret <= 0) dev_err(&wac_i2c->client->dev, "%s: failed to send stop command\n", __func__); enable_irq(wac_i2c->client->irq); if ((buf[0] == 0x1) && (buf[1] == 0)) return sprintf(buff, "%s\n", "OK"); else return sprintf(buff, "%s\n", "NG"); }
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; bool 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 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; }
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; pr_info("wacom: %s sending SET_FEATURE:%d\n", __func__, i); rv = wacom_i2c_send(wac_i2c, buf, len, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } pr_info("wacom: %s setting a command:%d\n", __func__, i); 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, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } msleep(5000); len = 0; buf[len++] = 4; buf[len++] = 0; buf[len++] = 0x38; buf[len++] = CMD_GET_FEATURE; pr_info("wacom: %s sending GET_FEATURE :%d\n", __func__, i); rv = wacom_i2c_send(wac_i2c, buf, len, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } len = 0; buf[len++] = 5; buf[len++] = 0; rv = wacom_i2c_send(wac_i2c, buf, len, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } if ((response[3] != ERS_CMD) || (response[4] != ECH)) { pr_err("wacom: %s failing 5:%d\n", __func__, i); return false; } if (response[5] == 0x80) { pr_err("wacom: %s retry\n", __func__); goto retry; } if (response[5] != ACK) { pr_err("wacom: %s failing 6:%d res5:%d\n", __func__, i, response[5]); return false; } pr_info("wacom: %s %d\n", __func__, i); } return true; }
int wacom_i2c_query(struct wacom_i2c *wac_i2c) { struct wacom_features *wac_feature = wac_i2c->wac_feature; int ret; u8 buf; u8 data[9] = {0, }; int i = 0; int query_limit = 10; buf = COM_QUERY; for (i = 0; i < query_limit; i++) { ret = wacom_i2c_send(wac_i2c, &buf, 1, false); if (ret < 0) { printk(KERN_ERR"[E-PEN] I2C send failed(%d)\n", ret); continue; } msleep(100); ret = wacom_i2c_recv(wac_i2c, data, COM_QUERY_NUM, false); if (ret < 0) { printk(KERN_ERR"[E-PEN] I2C recv failed(%d)\n", ret); continue; } printk(KERN_INFO "[E-PEN] %s: %dth ret of wacom query=%d\n", __func__, i, ret); if (COM_QUERY_NUM == ret) { if (0x0f == data[0]) { wac_feature->fw_version = ((u16) data[7] << 8) + (u16) data[8]; break; } else { printk(KERN_NOTICE "[E-PEN] %X, %X, %X, %X, %X, %X, %X, fw=0x%x\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6], wac_feature->fw_version); } } } #if defined(CONFIG_MACH_Q1_BD)\ || defined(CONFIG_MACH_P4NOTE)\ || defined(CONFIG_MACH_T0) wac_feature->x_max = (u16) WACOM_MAX_COORD_X; wac_feature->y_max = (u16) WACOM_MAX_COORD_Y; #else wac_feature->x_max = ((u16) data[1] << 8) + (u16) data[2]; wac_feature->y_max = ((u16) data[3] << 8) + (u16) data[4]; #endif wac_feature->pressure_max = (u16) data[6] + ((u16) data[5] << 8); #if defined(COOR_WORK_AROUND) if (i == 10 || ret < 0) { printk(KERN_NOTICE "[E-PEN] COOR_WORK_AROUND is applied\n"); printk(KERN_NOTICE "[E-PEN] %X, %X, %X, %X, %X, %X, %X, %X, %X\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]); wac_feature->x_max = (u16) WACOM_MAX_COORD_X; wac_feature->y_max = (u16) WACOM_MAX_COORD_Y; wac_feature->pressure_max = (u16) WACOM_MAX_PRESSURE; #ifdef CONFIG_MACH_T0 wac_feature->fw_version = 0; #else wac_feature->fw_version = 0xFF; #endif } #endif printk(KERN_NOTICE "[E-PEN] x_max=0x%X\n", wac_feature->x_max); printk(KERN_NOTICE "[E-PEN] y_max=0x%X\n", wac_feature->y_max); printk(KERN_NOTICE "[E-PEN] pressure_max=0x%X\n", wac_feature->pressure_max); printk(KERN_NOTICE "[E-PEN] fw_version=0x%X (d7:0x%X,d8:0x%X)\n", wac_feature->fw_version, data[7], data[8]); printk(KERN_NOTICE "[E-PEN] %X, %X, %X, %X, %X, %X, %X, %X, %X\n", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]); if ((i == 10) && (ret < 0)) { printk(KERN_DEBUG"[E-PEN] %s, failed\n", __func__); wac_i2c->query_status = false; return ret; } wac_i2c->query_status = true; #if defined(CONFIG_MACH_P4NOTE) wacom_checksum(wac_i2c); #endif return 0; }
static bool flash_erase(struct wacom_i2c *wac_i2c, 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: if (epen_debug) printk(KERN_DEBUG"epen:erase count %d\n", 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) { 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; } #ifdef CONFIG_EPEN_WACOM_G9PL switch (i) { case 0: case 1: msleep(3000); break; case 2: msleep(5000); break; case 3: msleep(500); break; default: msleep(5000); break; } #else msleep(300); #endif 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 void wacom_open_test(struct wacom_i2c *wac_i2c) { u8 cmd = 0; u8 buf[2] = {0,}; int ret = 0, retry = 10; cmd = WACOM_I2C_STOP; ret = wacom_i2c_send(wac_i2c, &cmd, 1, false); if (ret <= 0) { printk(KERN_ERR "epen:failed to send stop command\n"); return ; } usleep_range(500, 500); cmd = WACOM_I2C_GRID_CHECK; ret = wacom_i2c_send(wac_i2c, &cmd, 1, false); if (ret <= 0) { printk(KERN_ERR "epen:failed to send stop command\n"); goto grid_check_error; } msleep(150); cmd = WACOM_STATUS; do { printk(KERN_DEBUG"epen:read status, retry %d\n", retry); ret = wacom_i2c_send(wac_i2c, &cmd, 1, false); if (ret != 1) { printk(KERN_DEBUG"epen:failed to send cmd(ret:%d)\n", ret); continue; } usleep_range(500, 500); ret = wacom_i2c_recv(wac_i2c, buf, 2, false); if (ret != 2) { printk(KERN_DEBUG"epen:failed to recv data(ret:%d)\n", ret); continue; } /* * status value * 0 : data is not ready * 1 : PASS * 2 : Fail (coil function error) * 3 : Fail (All coil function error) */ if (buf[0] == 1) { printk(KERN_DEBUG"epen:Pass\n"); break; } printk(KERN_DEBUG"epen:buf[0]:%d, buf[1]:%d\n", buf[0], buf[1]); msleep(50); } while (retry--); wac_i2c->connection_check = (1 == buf[0]); printk(KERN_DEBUG "epen:epen_connection : %s buf[1]:%d\n", (1 == buf[0]) ? "Pass" : "Fail", buf[1]); grid_check_error: cmd = WACOM_I2C_STOP; wacom_i2c_send(wac_i2c, &cmd, 1, false); cmd = WACOM_I2C_START; wacom_i2c_send(wac_i2c, &cmd, 1, false); }
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, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); 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, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } usleep(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, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } len = 0; buf[len++] = 5; buf[len++] = 0; rv = wacom_i2c_send(wac_i2c, buf, len, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } if ((response[3] != SEC_CMD) || (response[4] != ECH)) return false; *status = (int)response[5]; return true; }
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; pr_info( "wacom: %s started buf[3]:%d len:%d\n", __func__, buf[3], len); rv = wacom_i2c_send(wac_i2c, buf, len, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); 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, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } usleep(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, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } len = 0; buf[len++] = 5; buf[len++] = 0; rv = wacom_i2c_send(wac_i2c, buf, len, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } if ((response[3] != QUERY_CMD) || (response[4] != ECH)) { pr_err("wacom: %s res3:%d res4:%d\n", __func__, response[3], response[4]); return false; } if (response[5] != QUERY_RSP) { pr_err("wacom: %s res5:%d\n", __func__, response[5]); return false; } return true; }
bool flash_verify(struct wacom_i2c *wac_i2c, unsigned char *flash_data, unsigned long start_address, unsigned long *max_address, int mpuType) { int ECH; unsigned long ulAddress; bool rv; unsigned long pageNo = 0; u8 command_id = 0; pr_info("wacom: %s verify starts\n", __func__); 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, false); 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_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, false); if (rv < 0) return false; usleep(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, false); if (rv < 0) return false; len = 0; buf[len++] = 5; buf[len++] = 0; rv = wacom_i2c_send(wac_i2c, buf, len, false); if (rv < 0) return false; rv = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, false); if (rv < 0) return false; if ((response[3] != VERIFY_CMD) || (response[4] != ECH) || (response[5] != ACK)) { pr_err( "wacom: %s res3:%d res4:%d res5:%d\n", __func__, response[3], response[4], response[5]); return false; } pageNo++; } return true; }
bool is_flash_marking(struct wacom_i2c *wac_i2c, 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; pr_info("wacom: %s started\n", __func__); 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, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); 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; pr_info("wacom: %s start writing command\n", __func__); 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; pr_info("wacom: %s sending command\n", __func__); rv = wacom_i2c_send(wac_i2c, command, MAX_CMD_SIZE, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } usleep(10000); len = 0; buf[len++] = 4; buf[len++] = 0; buf[len++] = 0x38; buf[len++] = CMD_GET_FEATURE; pr_info("wacom: %s sending GET_FEATURE 1\n", __func__); rv = wacom_i2c_send(wac_i2c, buf, len, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } len = 0; buf[len++] = 5; buf[len++] = 0; pr_info("wacom: %s sending GET_FEATURE 2\n", __func__); rv = wacom_i2c_send(wac_i2c, buf, len, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } pr_info("wacom: %s receiving GET_FEATURE\n", __func__); rv = wacom_i2c_recv(wac_i2c, response, RSP_SIZE, false); if (rv < 0) { pr_err("wacom: %s(%d) %d\n", __func__, rv, __LINE__); return false; } pr_info("wacom: %s checking response\n", __func__); if ((response[3] != MARK_CMD) || (response[4] != ECH) || (response[5] != ACK)) { pr_err("wacom: %s fails res3:%d res4:%d res5:%d\n", __func__, response[3], response[4], response[5]); return false; } *bMarking = true; return true; }
static bool flash_write(struct wacom_i2c *wac_i2c, unsigned char *flash_data, unsigned long start_address, unsigned long *max_address) { bool bRet = false; u8 command_id = 0; u8 command[BOOT_RSP_SIZE]; u8 response[BOOT_RSP_SIZE]; int ret, i, j, len, ECH = 0, ECH_len = 0; int ECH_ARRAY[3]; unsigned long ulAddress; j = 0; for (ulAddress = start_address; ulAddress < *max_address; ulAddress += FLASH_BLOCK_SIZE) { for (i = 0; i < FLASH_BLOCK_SIZE; i++) { if (flash_data[ulAddress + i] != 0xFF) break; } if (i == (FLASH_BLOCK_SIZE)) continue; /* for debug */ //printk(KERN_DEBUG"epen:write data %#x\n", (unsigned int)ulAddress); bRet = flash_write_block(wac_i2c, flash_data, ulAddress, &command_id, &ECH); if (!bRet) return false; if (ECH_len == 3) ECH_len = 0; ECH_ARRAY[ECH_len++] = ECH; if (ECH_len == 3) { for (j = 0; j < 3; j++) { do { len = 0; command[len++] = 4; command[len++] = 0; command[len++] = 0x38; command[len++] = CMD_GET_FEATURE; command[len++] = 5; command[len++] = 0; ret = wacom_i2c_send(wac_i2c, command, len, WACOM_I2C_MODE_BOOT); if (ret < 0) { printk(KERN_DEBUG"epen:%s failing 2:%d \n", __func__, i); return false; } ret = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, WACOM_I2C_MODE_BOOT); if (ret < 0) { printk(KERN_DEBUG"epen:%s failing 3:%d \n", __func__, i); return false; } if ((response[3] != 0x01 || response[4] != ECH_ARRAY[j]) || (response[5] != 0xff && response[5] != 0x00)) return false; //printk(KERN_DEBUG"epen:addr: %x res:%x \n", ulAddress, response[5]); } while (response[3] == 0x01 && response[4] == ECH_ARRAY[j] && response[5] == 0xff); } } } return true; }
static bool erase_codemem(struct wacom_i2c *wac_i2c, int *eraseBlock, int num) { u8 command[CMD_SIZE]; u8 response[BOOT_RSP_SIZE]; unsigned char sum = 0; unsigned char cmd_chksum; int ret, ECH; int len = 0; int i, j; for (i = 0; i < num; i++) { len = 0; command[len++] = 4; /* Command Register-LSB */ command[len++] = 0; /* Command Register-MSB */ command[len++] = 0x37; /* Command-LSB, ReportType:Feature(11) ReportID:7 */ command[len++] = CMD_SET_FEATURE; /* Command-MSB, SET_REPORT */ command[len++] = 5; /* Data Register-LSB */ command[len++] = 0; /* Data-Register-MSB */ command[len++] = 7; /* Length Field-LSB */ command[len++] = 0; /* Length Field-MSB */ command[len++] = BOOT_CMD_REPORT_ID; /* Report:ReportID */ command[len++] = BOOT_ERASE_FLASH; /* Report:erase command */ command[len++] = ECH = i; /* Report:echo */ command[len++] = *eraseBlock; /* Report:erased block No. */ eraseBlock++; sum = 0; for (j = 4; j < 12; j++) sum += command[j]; cmd_chksum = ~sum + 1; /* Report:check sum */ command[len++] = cmd_chksum; ret = wacom_i2c_send(wac_i2c, command, len, WACOM_I2C_MODE_BOOT); if (ret < 0) { printk(KERN_DEBUG"epen:%s failing 1:%d \n", __func__, i); return false; } do { len = 0; command[len++] = 4; command[len++] = 0; command[len++] = 0x38; command[len++] = CMD_GET_FEATURE; command[len++] = 5; command[len++] = 0; ret = wacom_i2c_send(wac_i2c, command, len, WACOM_I2C_MODE_BOOT); if (ret < 0) { printk(KERN_DEBUG"epen:%s failing 2:%d \n", __func__, i); return false; } ret = wacom_i2c_recv(wac_i2c, response, BOOT_RSP_SIZE, WACOM_I2C_MODE_BOOT); if (ret < 0) { printk(KERN_DEBUG"epen:%s failing 3:%d \n", __func__, i); return false; } if ((response[3] != 0x00 || response[4] != ECH) || (response[5] != 0xff && response[5] != 0x00)) return false; } while (response[3] == 0x00 && response[4] == ECH && response[5] == 0xff); } 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_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; } #ifdef CONFIG_EPEN_WACOM_G9PL usleep_range(10000, 10000); #endif 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_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; }
int wacom_i2c_query(struct wacom_i2c *wac_i2c) { struct wacom_features *wac_feature = wac_i2c->wac_feature; int ret; u8 buf; u8 data[COM_QUERY_NUM] = {0, }; int i = 0; const int query_limit = 3; buf = COM_QUERY; dev_info(&wac_i2c->client->dev, "%s: start\n", __func__); for (i = 0; i < query_limit; i++) { ret = wacom_i2c_send(wac_i2c, &buf, 1, false); if (ret < 0) { dev_err(&wac_i2c->client->dev, "%s: I2C send failed(%d)\n", __func__, ret); continue; } msleep(100); ret = wacom_i2c_recv(wac_i2c, data, COM_QUERY_NUM, false); if (ret < 0) { dev_err(&wac_i2c->client->dev, "%s: I2C recv failed(%d)\n", __func__, ret); continue; } dev_info(&wac_i2c->client->dev, "%s: %dth ret of wacom query=%d\n", __func__, i, ret); if (COM_QUERY_NUM != ret) { dev_info(&wac_i2c->client->dev, "%s: epen:failed to read i2c(%d)\n", __func__, ret); continue; } if (0x0f == data[0]) { wac_feature->fw_ic_version = ((u16) data[7] << 8) + (u16) data[8]; break; } else { dev_info(&wac_i2c->client->dev, "%s: %X, %X, %X, %X, %X, %X, %X, fw=0x%x\n", __func__, data[0], data[1], data[2], data[3], data[4], data[5], data[6], wac_feature->fw_ic_version); } } wac_feature->x_max = wac_i2c->wac_pdata->max_x; wac_feature->y_max = wac_i2c->wac_pdata->max_y; wac_feature->pressure_max = (u16) data[6] + ((u16) data[5] << 8); #if defined(COOR_WORK_AROUND) if (i == 10 || ret < 0) { dev_info(&wac_i2c->client->dev, "%s: COOR_WORK_AROUND is applied\n", __func__); dev_info(&wac_i2c->client->dev, "%s: %X, %X, %X, %X, %X, %X, %X, %X, %X\n", __func__, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]); wac_feature->x_max = (u16) wac_i2c->wac_pdata->max_x; wac_feature->y_max = (u16) wac_i2c->wac_pdata->max_y; wac_feature->pressure_max = (u16) wac_i2c->wac_pdata->max_pressure; wac_feature->fw_ic_version = 0; } #endif dev_info(&wac_i2c->client->dev, "%s: x_max=0x%X, y_max=0x%X\n, pressure_max=0x%X", __func__, wac_feature->x_max, wac_feature->y_max, wac_feature->pressure_max); dev_info(&wac_i2c->client->dev, "%s: fw_version=0x%X (d7:0x%X,d8:0x%X)\n", __func__, wac_feature->fw_version, data[7], data[8]); dev_info(&wac_i2c->client->dev, "%s: %X, %X, %X, %X, %X, %X, %X, %X, %X\n", __func__, data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8]); if ((i == query_limit) && (ret < 0)) { dev_info(&wac_i2c->client->dev, "%s: failed\n", __func__); wac_i2c->query_status = false; return ret; } wac_i2c->query_status = true; return wac_feature->fw_ic_version; }
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; } #ifdef CONFIG_EPEN_WACOM_G9PL usleep_range(10000, 10000); #else usleep_range(1000, 1000); #endif 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; }