summaryrefslogtreecommitdiff
path: root/util
diff options
context:
space:
mode:
Diffstat (limited to 'util')
-rw-r--r--util/build.mk1
-rw-r--r--util/iteflash.c675
2 files changed, 425 insertions, 251 deletions
diff --git a/util/build.mk b/util/build.mk
index ad9f5656c2..f61a11d628 100644
--- a/util/build.mk
+++ b/util/build.mk
@@ -25,6 +25,7 @@ endif
comm-objs=$(util-lock-objs:%=lock/%) comm-host.o comm-dev.o
comm-objs+=comm-lpc.o comm-i2c.o misc_util.o
+iteflash-objs = iteflash.o usb_if.o
ectool-objs=ectool.o ectool_keyscan.o ec_flash.o ec_panicinfo.o $(comm-objs)
ectool_servo-objs=$(ectool-objs) comm-servo-spi.o
ec_sb_firmware_update-objs=ec_sb_firmware_update.o $(comm-objs) misc_util.o
diff --git a/util/iteflash.c b/util/iteflash.c
index 800cddab08..6308f5c142 100644
--- a/util/iteflash.c
+++ b/util/iteflash.c
@@ -6,6 +6,7 @@
*/
#include <errno.h>
+#include <ftdi.h>
#include <getopt.h>
#include <signal.h>
#include <stdint.h>
@@ -15,15 +16,24 @@
#include <time.h>
#include <unistd.h>
-#pragma GCC diagnostic ignored "-Wstrict-prototypes"
-#include <ftdi.h>
-#pragma GCC diagnostic pop
+#include "usb_if.h"
-/* default USB device : Servo v2 */
+/* Default FTDI device : Servo v2. */
#define SERVO_USB_VID 0x18d1
#define SERVO_USB_PID 0x5002
#define SERVO_INTERFACE INTERFACE_B
+/* Default CCD device: Cr50. */
+#define CR50_USB_VID 0x18d1
+#define CR50_USB_PID 0x5014
+
+/* Cr50 exposed properties of the USB I2C endpoint. */
+#define CR50_I2C_SUBCLASS 82
+#define CR50_I2C_PROTOCOL 1
+
+#define CROS_CMD_ADDR 0x78
+#define CROS_CMD_ITE_SYNC 0
+
/* DBGR I2C addresses */
#define I2C_CMD_ADDR 0x5A
#define I2C_DATA_ADDR 0x35
@@ -41,8 +51,9 @@
/* Embedded flash page size */
#define PAGE_SIZE 256
-/* Embedded flash block write size */
-#define BLOCK_WRITE_SIZE 65536
+/* Embedded flash block write size for different programming modes. */
+#define FTDI_BLOCK_WRITE_SIZE 65536
+#define CCD_BLOCK_WRITE_SIZE 56
/* Embedded flash number of pages in a sector erase */
#define SECTOR_ERASE_PAGES 4
@@ -88,11 +99,32 @@ static int debug;
enum {
FLAG_UNPROTECT = 0x01,
FLAG_ERASE = 0x02,
+ FLAG_CCD_MODE = 0x04
+};
+
+enum interface_type {
+ FTDI_IF,
+ CCD_IF
+};
+
+struct common_hnd {
+ enum interface_type iftype;
+ union {
+ struct ftdi_context *ftdi_hnd;
+ struct usb_endpoint uep;
+ };
};
/* number of bytes to send consecutively before checking for ACKs */
#define TX_BUFFER_LIMIT 32
+/* For backwards compatibility let FTDI value be the default. */
+static int block_write_size_ = FTDI_BLOCK_WRITE_SIZE;
+static int block_write_size(void)
+{
+ return block_write_size_;
+}
+
static int i2c_add_send_byte(struct ftdi_context *ftdi, uint8_t *buf,
uint8_t *ptr, uint8_t *tbuf, int tcnt)
{
@@ -217,13 +249,88 @@ static int i2c_add_recv_bytes(struct ftdi_context *ftdi, uint8_t *buf,
return ret;
}
-static int i2c_byte_transfer(struct ftdi_context *ftdi, uint8_t addr,
+#define USB_I2C_HEADER_SIZE 4
+static int ccd_i2c_byte_transfer(struct usb_endpoint *uep, uint8_t addr,
+ uint8_t *data, int write, int numbytes)
+{
+ uint8_t usb_buffer[USB_I2C_HEADER_SIZE + numbytes +
+ (((!write * numbytes) > 0x7f) ? 2 : 0)];
+ size_t response_size;
+ size_t extra = 0;
+
+ /* Do nothing if user wants to quit. */
+ if (exit_requested)
+ return -1;
+
+ /* Build a message following format described in ./include/usb_i2c.h. */
+ usb_buffer[0] = 0; /* Hardcode port 0, may need to change this. */
+ usb_buffer[1] = addr;
+ if (write) {
+ usb_buffer[2] = numbytes;
+ usb_buffer[3] = 0;
+ memcpy(usb_buffer + USB_I2C_HEADER_SIZE, data, numbytes);
+ } else {
+ usb_buffer[2] = 0;
+ if (numbytes < 0x80) {
+ usb_buffer[3] = numbytes;
+ } else {
+ usb_buffer[3] = (numbytes & 0x7f) | 0x80;
+ usb_buffer[4] = numbytes >> 7;
+ usb_buffer[5] = 0;
+ extra = 2;
+ }
+ }
+
+ response_size = 0;
+ usb_trx(uep, usb_buffer,
+ write ? sizeof(usb_buffer) : USB_I2C_HEADER_SIZE + extra,
+ usb_buffer, sizeof(usb_buffer), 1, &response_size);
+
+ if (response_size < (USB_I2C_HEADER_SIZE + (write ? 0 : numbytes))) {
+ fprintf(stderr, "%s: got too few bytes (%zd) in response\n",
+ __func__, response_size);
+ return -1;
+ }
+
+ if (usb_buffer[0]) {
+ uint32_t rv;
+
+ /*
+ * Error is reported as a 16 bit value in little endian byte
+ * order.
+ */
+ rv = usb_buffer[1];
+ rv = (rv << 8) + usb_buffer[0];
+
+ fprintf(stderr, "%s: usb i2c error %d\n",
+ __func__,
+ (((uint16_t)usb_buffer[1]) << 8) + usb_buffer[0]);
+
+ return -rv;
+ }
+
+ if (!write)
+ memcpy(data, usb_buffer + USB_I2C_HEADER_SIZE, numbytes);
+
+ return 0;
+}
+
+static int i2c_byte_transfer(struct common_hnd *chnd, uint8_t addr,
uint8_t *data, int write, int numbytes)
{
- int ret = 0, rets;
+ int ret, rets;
static uint8_t buf[FTDI_CMD_BUF_SIZE];
- uint8_t *b = buf;
+ uint8_t *b;
uint8_t slave_addr;
+ struct ftdi_context *ftdi;
+
+ if (chnd->iftype == CCD_IF)
+ return ccd_i2c_byte_transfer(&chnd->uep, addr,
+ data, write, numbytes);
+
+ ret = 0;
+ b = buf;
+ ftdi = chnd->ftdi_hnd;
/* START condition */
/* SCL & SDA high */
@@ -268,35 +375,35 @@ exit_xfer:
return ret;
}
-static int i2c_write_byte(struct ftdi_context *ftdi, uint8_t cmd, uint8_t data)
+static int i2c_write_byte(struct common_hnd *chnd, uint8_t cmd, uint8_t data)
{
int ret;
- ret = i2c_byte_transfer(ftdi, I2C_CMD_ADDR, &cmd, 1, 1);
+ ret = i2c_byte_transfer(chnd, I2C_CMD_ADDR, &cmd, 1, 1);
if (ret < 0)
return -EIO;
- ret = i2c_byte_transfer(ftdi, I2C_DATA_ADDR, &data, 1, 1);
+ ret = i2c_byte_transfer(chnd, I2C_DATA_ADDR, &data, 1, 1);
if (ret < 0)
return -EIO;
return 0;
}
-static int i2c_read_byte(struct ftdi_context *ftdi, uint8_t cmd, uint8_t *data)
+static int i2c_read_byte(struct common_hnd *chnd, uint8_t cmd, uint8_t *data)
{
int ret;
- ret = i2c_byte_transfer(ftdi, I2C_CMD_ADDR, &cmd, 1, 1);
+ ret = i2c_byte_transfer(chnd, I2C_CMD_ADDR, &cmd, 1, 1);
if (ret < 0)
return -EIO;
- ret = i2c_byte_transfer(ftdi, I2C_DATA_ADDR, data, 0, 1);
+ ret = i2c_byte_transfer(chnd, I2C_DATA_ADDR, data, 0, 1);
if (ret < 0)
return -EIO;
return 0;
}
-static int check_chipid(struct ftdi_context *ftdi)
+static int check_chipid(struct common_hnd *chnd)
{
int ret;
uint8_t ver = 0xff;
@@ -326,13 +433,13 @@ static int check_chipid(struct ftdi_context *ftdi)
* 8:512KB
*/
- ret = i2c_read_byte(ftdi, 0x00, (uint8_t *)&id + 1);
+ ret = i2c_read_byte(chnd, 0x00, (uint8_t *)&id + 1);
if (ret < 0)
return ret;
- ret = i2c_read_byte(ftdi, 0x01, (uint8_t *)&id);
+ ret = i2c_read_byte(chnd, 0x01, (uint8_t *)&id);
if (ret < 0)
return ret;
- ret = i2c_read_byte(ftdi, 0x02, &ver);
+ ret = i2c_read_byte(chnd, 0x02, &ver);
if (ret < 0)
return ret;
if ((id & 0xff00) != (CHIP_ID & 0xff00)) {
@@ -354,18 +461,18 @@ static int check_chipid(struct ftdi_context *ftdi)
}
/* DBGR Reset*/
-static int dbgr_reset(struct ftdi_context *ftdi, unsigned char val)
+static int dbgr_reset(struct common_hnd *chnd, unsigned char val)
{
int ret = 0;
/* Reset CPU only, and we keep power state until flashing is done. */
- ret |= i2c_write_byte(ftdi, 0x2f, 0x20);
- ret |= i2c_write_byte(ftdi, 0x2e, 0x06);
+ ret |= i2c_write_byte(chnd, 0x2f, 0x20);
+ ret |= i2c_write_byte(chnd, 0x2e, 0x06);
/* Enable the Reset Status by val */
- ret |= i2c_write_byte(ftdi, 0x30, val);
+ ret |= i2c_write_byte(chnd, 0x30, val);
- ret |= i2c_write_byte(ftdi, 0x27, 0x80);
+ ret |= i2c_write_byte(chnd, 0x27, 0x80);
if (ret < 0)
printf("DBGR RESET FAILED\n");
@@ -373,15 +480,15 @@ static int dbgr_reset(struct ftdi_context *ftdi, unsigned char val)
}
/* Enter follow mode and FSCE# high level */
-static int spi_flash_follow_mode(struct ftdi_context *ftdi, char *desc)
+static int spi_flash_follow_mode(struct common_hnd *chnd, char *desc)
{
int ret = 0;
- ret |= i2c_write_byte(ftdi, 0x07, 0x7f);
- ret |= i2c_write_byte(ftdi, 0x06, 0xff);
- ret |= i2c_write_byte(ftdi, 0x05, 0xfe);
- ret |= i2c_write_byte(ftdi, 0x04, 0x00);
- ret |= i2c_write_byte(ftdi, 0x08, 0x00);
+ ret |= i2c_write_byte(chnd, 0x07, 0x7f);
+ ret |= i2c_write_byte(chnd, 0x06, 0xff);
+ ret |= i2c_write_byte(chnd, 0x05, 0xfe);
+ ret |= i2c_write_byte(chnd, 0x04, 0x00);
+ ret |= i2c_write_byte(chnd, 0x08, 0x00);
ret = (ret ? -EIO : 0);
if (ret < 0)
@@ -392,12 +499,12 @@ static int spi_flash_follow_mode(struct ftdi_context *ftdi, char *desc)
}
/* Exit follow mode */
-static int spi_flash_follow_mode_exit(struct ftdi_context *ftdi, char *desc)
+static int spi_flash_follow_mode_exit(struct common_hnd *chnd, char *desc)
{
int ret = 0;
- ret |= i2c_write_byte(ftdi, 0x07, 0x00);
- ret |= i2c_write_byte(ftdi, 0x06, 0x00);
+ ret |= i2c_write_byte(chnd, 0x07, 0x00);
+ ret |= i2c_write_byte(chnd, 0x06, 0x00);
ret = (ret ? -EIO : 0);
if (ret < 0)
@@ -408,16 +515,15 @@ static int spi_flash_follow_mode_exit(struct ftdi_context *ftdi, char *desc)
}
/* SPI Flash generic command, short version */
-static int spi_flash_command_short(struct ftdi_context *ftdi,
- uint8_t cmd,
- char *desc)
+static int spi_flash_command_short(struct common_hnd *chnd,
+ uint8_t cmd, char *desc)
{
int ret = 0;
- ret |= i2c_write_byte(ftdi, 0x05, 0xfe);
- ret |= i2c_write_byte(ftdi, 0x08, 0x00);
- ret |= i2c_write_byte(ftdi, 0x05, 0xfd);
- ret |= i2c_write_byte(ftdi, 0x08, cmd);
+ ret |= i2c_write_byte(chnd, 0x05, 0xfe);
+ ret |= i2c_write_byte(chnd, 0x08, 0x00);
+ ret |= i2c_write_byte(chnd, 0x05, 0xfd);
+ ret |= i2c_write_byte(chnd, 0x08, cmd);
ret = (ret ? -EIO : 0);
if (ret < 0)
@@ -427,15 +533,14 @@ static int spi_flash_command_short(struct ftdi_context *ftdi,
}
/* SPI Flash set erase page */
-static int spi_flash_set_erase_page(struct ftdi_context *ftdi,
- int page,
- char *desc)
+static int spi_flash_set_erase_page(struct common_hnd *chnd,
+ int page, char *desc)
{
int ret = 0;
- ret |= i2c_write_byte(ftdi, 0x08, page >> 8);
- ret |= i2c_write_byte(ftdi, 0x08, page & 0xff);
- ret |= i2c_write_byte(ftdi, 0x08, 0);
+ ret |= i2c_write_byte(chnd, 0x08, page >> 8);
+ ret |= i2c_write_byte(chnd, 0x08, page & 0xff);
+ ret |= i2c_write_byte(chnd, 0x08, 0);
ret = (ret ? -EIO : 0);
if (ret < 0)
@@ -445,19 +550,19 @@ static int spi_flash_set_erase_page(struct ftdi_context *ftdi,
}
/* Poll SPI Flash Read Status register until BUSY is reset */
-static int spi_poll_busy(struct ftdi_context *ftdi, char *desc)
+static int spi_poll_busy(struct common_hnd *chnd, char *desc)
{
uint8_t reg = 0xff;
int ret = -EIO;
- if (spi_flash_command_short(ftdi, SPI_CMD_READ_STATUS,
+ if (spi_flash_command_short(chnd, SPI_CMD_READ_STATUS,
"read status for busy bit") < 0) {
fprintf(stderr, "Flash %s wait busy cleared FAILED\n", desc);
goto failed_read_status;
}
while (1) {
- if (i2c_byte_transfer(ftdi, I2C_DATA_ADDR, &reg, 0, 1) < 0) {
+ if (i2c_byte_transfer(chnd, I2C_DATA_ADDR, &reg, 0, 1) < 0) {
fprintf(stderr, "Flash polling busy cleared FAILED\n");
break;
}
@@ -472,19 +577,19 @@ failed_read_status:
return ret;
}
-static int spi_check_write_enable(struct ftdi_context *ftdi, char *desc)
+static int spi_check_write_enable(struct common_hnd *chnd, char *desc)
{
uint8_t reg = 0xff;
int ret = -EIO;
- if (spi_flash_command_short(ftdi, SPI_CMD_READ_STATUS,
+ if (spi_flash_command_short(chnd, SPI_CMD_READ_STATUS,
"read status for write enable bit") < 0) {
fprintf(stderr, "Flash %s wait WE FAILED\n", desc);
goto failed_read_status;
}
while (1) {
- if (i2c_byte_transfer(ftdi, I2C_DATA_ADDR, &reg, 0, 1) < 0) {
+ if (i2c_byte_transfer(chnd, I2C_DATA_ADDR, &reg, 0, 1) < 0) {
fprintf(stderr, "Flash polling WE FAILED\n");
break;
}
@@ -553,86 +658,129 @@ static int config_i2c(struct ftdi_context *ftdi)
#define SPECIAL_BUFFER_SIZE \
(((SPECIAL_LEN_USEC * SPECIAL_FREQ * 2 / USEC) + 7) & ~7)
-static int send_special_waveform(struct ftdi_context *ftdi)
+static int ccd_trigger_special_waveform(struct usb_endpoint *uep)
+{
+ uint8_t response[20];
+ size_t rsize;
+ uint8_t req[] = {
+ 0, /* Port 0. Might be necessary to modify. */
+ CROS_CMD_ADDR, /* Chrome OS dedicated address. */
+ 1, /* Will send a single byte command. */
+ 0, /* No need to read back anything. */
+ CROS_CMD_ITE_SYNC
+ };
+
+ usb_trx(uep, req, sizeof(req), response, sizeof(response), 1, &rsize);
+
+ if (rsize < USB_I2C_HEADER_SIZE)
+ return -1;
+
+ if (response[0])
+ return -response[0];
+
+ return 0;
+}
+
+static int ftdi_send_special_waveform(struct ftdi_context *ftdi, uint64_t *wave)
{
int ret;
int i;
- uint64_t *wave;
uint8_t release_lines[] = {SET_BITS_LOW, 0, 0};
- wave = malloc(SPECIAL_BUFFER_SIZE);
+ /* Reset the FTDI into a known state */
+ ret = ftdi_set_bitmode(ftdi, 0xFF, BITMODE_RESET);
+ if (ret) {
+ fprintf(stderr, "failed to reset FTDI\n");
+ return ret;
+ }
- printf("Waiting for the EC power-on sequence ...");
- fflush(stdout);
+ /*
+ * set the clock divider, so we output a new bitbang value every
+ * 2.5us.
+ */
+ ret = ftdi_set_baudrate(ftdi, 160000);
+ if (ret) {
+ fprintf(stderr, "failed to set bitbang clock\n");
+ return ret;
+ }
- do {
- /* Reset the FTDI into a known state */
- ret = ftdi_set_bitmode(ftdi, 0xFF, BITMODE_RESET);
- if (ret != 0) {
- fprintf(stderr, "failed to reset FTDI\n");
- break;
- }
+ /* Enable asynchronous bit-bang mode */
+ ret = ftdi_set_bitmode(ftdi, 0xFF, BITMODE_BITBANG);
+ if (ret) {
+ fprintf(stderr, "failed to set bitbang mode\n");
+ return ret;
+ }
- /*
- * set the clock divider,
- * so we output a new bitbang value every 2.5us.
- */
- ret = ftdi_set_baudrate(ftdi, 160000);
- if (ret != 0) {
- fprintf(stderr, "failed to set bitbang clock\n");
- break;
- }
+ /* do usb special waveform */
+ wave[0] = 0x0;
+ ftdi_write_data(ftdi, (uint8_t *)wave, 1);
+ usleep(5000);
- /* Enable asynchronous bit-bang mode */
- ret = ftdi_set_bitmode(ftdi, 0xFF, BITMODE_BITBANG);
- if (ret != 0) {
- fprintf(stderr, "failed to set bitbang mode\n");
- break;
- }
+ /* program each special tick */
+ for (i = 0; i < TICK_COUNT; ) {
+ wave[i++] = SPECIAL_PATTERN_SDA_L_SCL_L;
+ wave[i++] = SPECIAL_PATTERN_SDA_H_SCL_L;
+ wave[i++] = SPECIAL_PATTERN_SDA_L_SCL_L;
+ }
+ wave[19] = SPECIAL_PATTERN_SDA_H_SCL_H;
- /* do usb special waveform */
- wave[0] = 0x0;
- ftdi_write_data(ftdi, (uint8_t *)wave, 1);
- usleep(5000);
+ /* fill the buffer with the waveform pattern */
+ for (i = TICK_COUNT; i < SPECIAL_BUFFER_SIZE / sizeof(uint64_t); i++)
+ wave[i] = SPECIAL_PATTERN;
- /* program each special tick */
- for (i = 0; i < TICK_COUNT; ) {
- wave[i++] = SPECIAL_PATTERN_SDA_L_SCL_L;
- wave[i++] = SPECIAL_PATTERN_SDA_H_SCL_L;
- wave[i++] = SPECIAL_PATTERN_SDA_L_SCL_L;
- }
- wave[19] = SPECIAL_PATTERN_SDA_H_SCL_H;
+ ret = ftdi_write_data(ftdi, (uint8_t *)wave, SPECIAL_BUFFER_SIZE);
+ if (ret < 0)
+ fprintf(stderr, "Cannot output special waveform\n");
+
+ /* clean everything to go back to regular I2C communication */
+ ftdi_usb_purge_buffers(ftdi);
+ ftdi_set_bitmode(ftdi, 0xff, BITMODE_RESET);
+ config_i2c(ftdi);
+ ftdi_write_data(ftdi, release_lines, sizeof(release_lines));
+
+ return ret;
+}
+
+static int send_special_waveform(struct common_hnd *chnd)
+{
+ int ret;
+ uint64_t *wave;
+ int iterations;
+
+ if (chnd->iftype == FTDI_IF)
+ wave = malloc(SPECIAL_BUFFER_SIZE);
+ else
+ wave = NULL;
+
+ printf("Waiting for the EC power-on sequence ...");
+ fflush(stdout);
- /* fill the buffer with the waveform pattern */
- for (i = TICK_COUNT; i < SPECIAL_BUFFER_SIZE / sizeof(uint64_t);
- i++)
- wave[i] = SPECIAL_PATTERN;
+ iterations = 0;
- ret = ftdi_write_data(ftdi, (uint8_t *)wave,
- SPECIAL_BUFFER_SIZE);
- if (ret < 0)
- fprintf(stderr, "Cannot output special waveform\n");
+ do {
+ if (chnd->iftype == FTDI_IF)
+ ret = ftdi_send_special_waveform(chnd->ftdi_hnd, wave);
+ else
+ ret = ccd_trigger_special_waveform(&chnd->uep);
- /* clean everything to go back to regular I2C communication */
- ftdi_usb_purge_buffers(ftdi);
- ftdi_set_bitmode(ftdi, 0xff, BITMODE_RESET);
- config_i2c(ftdi);
- ftdi_write_data(ftdi, release_lines, sizeof(release_lines));
+ if (ret)
+ break;
/* wait for PLL stable for 5ms (plus remaining USB transfers) */
usleep(10 * MSEC);
/* If we can talk to chip, then we can break the retry loop */
- ret = check_chipid(ftdi);
+ ret = check_chipid(chnd);
- } while (ret != 0);
+ } while (ret && (iterations++ < 50));
if (ret)
printf(" Failed!\n");
else
printf(" Done.\n");
- free(wave);
+ if (wave)
+ free(wave);
return ret;
}
@@ -645,7 +793,7 @@ static void draw_spinner(uint32_t remaining, uint32_t size)
windex %= sizeof(wheel);
}
-int command_read_pages(struct ftdi_context *ftdi, uint32_t address,
+int command_read_pages(struct common_hnd *chnd, uint32_t address,
uint32_t size, uint8_t *buffer)
{
int res = -EIO;
@@ -653,7 +801,7 @@ int command_read_pages(struct ftdi_context *ftdi, uint32_t address,
int cnt;
uint16_t page;
- if (spi_flash_follow_mode(ftdi, "fast read") < 0)
+ if (spi_flash_follow_mode(chnd, "fast read") < 0)
goto failed_read;
while (remaining) {
@@ -665,21 +813,21 @@ int command_read_pages(struct ftdi_context *ftdi, uint32_t address,
draw_spinner(remaining, size);
/* Fast Read command */
- if (spi_flash_command_short(ftdi, SPI_CMD_FAST_READ,
+ if (spi_flash_command_short(chnd, SPI_CMD_FAST_READ,
"fast read") < 0)
goto failed_read;
- res = i2c_write_byte(ftdi, 0x08, page >> 8);
- res += i2c_write_byte(ftdi, 0x08, page & 0xff);
- res += i2c_write_byte(ftdi, 0x08, 0x00);
- res += i2c_write_byte(ftdi, 0x08, 0x00);
+ res = i2c_write_byte(chnd, 0x08, page >> 8);
+ res += i2c_write_byte(chnd, 0x08, page & 0xff);
+ res += i2c_write_byte(chnd, 0x08, 0x00);
+ res += i2c_write_byte(chnd, 0x08, 0x00);
if (res < 0) {
fprintf(stderr, "page address set failed\n");
goto failed_read;
}
/* read page data */
- res = i2c_byte_transfer(ftdi, I2C_CMD_ADDR, &cmd, 1, 1);
- res = i2c_byte_transfer(ftdi, I2C_BLOCK_ADDR, buffer, 0, cnt);
+ res = i2c_byte_transfer(chnd, I2C_CMD_ADDR, &cmd, 1, 1);
+ res = i2c_byte_transfer(chnd, I2C_BLOCK_ADDR, buffer, 0, cnt);
if (res < 0) {
fprintf(stderr, "page data read failed\n");
goto failed_read;
@@ -692,13 +840,13 @@ int command_read_pages(struct ftdi_context *ftdi, uint32_t address,
/* No error so far */
res = size;
failed_read:
- if (spi_flash_follow_mode_exit(ftdi, "fast read") < 0)
+ if (spi_flash_follow_mode_exit(chnd, "fast read") < 0)
res = -EIO;
return res;
}
-int command_write_pages(struct ftdi_context *ftdi, uint32_t address,
+int command_write_pages(struct common_hnd *chnd, uint32_t address,
uint32_t size, uint8_t *buffer)
{
int res = -EIO;
@@ -707,12 +855,12 @@ int command_write_pages(struct ftdi_context *ftdi, uint32_t address,
uint8_t addr_H, addr_M, addr_L;
uint8_t cmd;
- if (spi_flash_follow_mode(ftdi, "AAI write") < 0)
+ if (spi_flash_follow_mode(chnd, "AAI write") < 0)
goto failed_write;
while (remaining) {
- cnt = (remaining > BLOCK_WRITE_SIZE) ?
- BLOCK_WRITE_SIZE : remaining;
+ cnt = (remaining > block_write_size()) ?
+ block_write_size() : remaining;
addr_H = (address >> 16) & 0xFF;
addr_M = (address >> 8) & 0xFF;
addr_L = (address) & 0xFF;
@@ -720,23 +868,23 @@ int command_write_pages(struct ftdi_context *ftdi, uint32_t address,
draw_spinner(remaining, size);
/* Write enable */
- if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_ENABLE,
+ if (spi_flash_command_short(chnd, SPI_CMD_WRITE_ENABLE,
"write enable for AAI write") < 0)
goto failed_write;
/* Check write enable bit */
- if (spi_check_write_enable(ftdi, "AAI write") < 0)
+ if (spi_check_write_enable(chnd, "AAI write") < 0)
goto failed_write;
/* Setup write */
- if (spi_flash_command_short(ftdi, SPI_CMD_WORD_PROGRAM,
+ if (spi_flash_command_short(chnd, SPI_CMD_WORD_PROGRAM,
"AAI write") < 0)
goto failed_write;
/* Set eflash page address */
- res = i2c_byte_transfer(ftdi, I2C_DATA_ADDR, &addr_H, 1, 1);
- res |= i2c_byte_transfer(ftdi, I2C_DATA_ADDR, &addr_M, 1, 1);
- res |= i2c_byte_transfer(ftdi, I2C_DATA_ADDR, &addr_L, 1, 1);
+ res = i2c_byte_transfer(chnd, I2C_DATA_ADDR, &addr_H, 1, 1);
+ res |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, &addr_M, 1, 1);
+ res |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, &addr_L, 1, 1);
if (res < 0) {
fprintf(stderr, "Flash write set page FAILED (%d)\n",
res);
@@ -744,12 +892,12 @@ int command_write_pages(struct ftdi_context *ftdi, uint32_t address,
}
/* Wait until not busy */
- if (spi_poll_busy(ftdi, "AAI write") < 0)
+ if (spi_poll_busy(chnd, "AAI write") < 0)
goto failed_write;
- /* Write up to BLOCK_WRITE_SIZE data */
- res = i2c_write_byte(ftdi, 0x10, 0x20);
- res = i2c_byte_transfer(ftdi, I2C_BLOCK_ADDR, buffer, 1, cnt);
+ /* Write up to block_write_size() data */
+ res = i2c_write_byte(chnd, 0x10, 0x20);
+ res = i2c_byte_transfer(chnd, I2C_BLOCK_ADDR, buffer, 1, cnt);
buffer += cnt;
if (res < 0) {
@@ -758,8 +906,8 @@ int command_write_pages(struct ftdi_context *ftdi, uint32_t address,
}
cmd = 0xff;
- res = i2c_byte_transfer(ftdi, I2C_DATA_ADDR, &cmd, 1, 1);
- res |= i2c_write_byte(ftdi, 0x10, 0x00);
+ res = i2c_byte_transfer(chnd, I2C_DATA_ADDR, &cmd, 1, 1);
+ res |= i2c_write_byte(chnd, 0x10, 0x00);
if (res < 0) {
fprintf(stderr, "Flash end data write FAILED (%d)\n",
res);
@@ -767,12 +915,12 @@ int command_write_pages(struct ftdi_context *ftdi, uint32_t address,
}
/* Write disable */
- if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_DISABLE,
+ if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE,
"write disable for AAI write") < 0)
goto failed_write;
/* Wait until available */
- if (spi_poll_busy(ftdi, "write disable for AAI write") < 0)
+ if (spi_poll_busy(chnd, "write disable for AAI write") < 0)
goto failed_write;
address += cnt;
@@ -782,11 +930,11 @@ int command_write_pages(struct ftdi_context *ftdi, uint32_t address,
/* No error so far */
res = size;
failed_write:
- if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_DISABLE,
+ if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE,
"write disable exit AAI write") < 0)
res = -EIO;
- if (spi_flash_follow_mode_exit(ftdi, "AAI write") < 0)
+ if (spi_flash_follow_mode_exit(chnd, "AAI write") < 0)
res = -EIO;
return res;
@@ -797,11 +945,10 @@ failed_write:
* Write another program flow to match the
* original ITE 8903 Download board.
*/
-int command_write_pages2(struct ftdi_context *ftdi, uint32_t address,
- uint32_t size, uint8_t *buffer)
+int command_write_pages2(struct common_hnd *chnd, uint32_t address,
+ uint32_t size, uint8_t *buffer)
{
int res = 0;
- uint32_t remaining = size;
uint8_t BA, A1, A0, data;
/*
@@ -809,33 +956,33 @@ int command_write_pages2(struct ftdi_context *ftdi, uint32_t address,
* The code will merge to the original function
*/
- res |= i2c_write_byte(ftdi, 0x07, 0x7f);
- res |= i2c_write_byte(ftdi, 0x06, 0xff);
- res |= i2c_write_byte(ftdi, 0x04, 0xFF);
+ res |= i2c_write_byte(chnd, 0x07, 0x7f);
+ res |= i2c_write_byte(chnd, 0x06, 0xff);
+ res |= i2c_write_byte(chnd, 0x04, 0xFF);
/* SMB_SPI_Flash_Enable_Write_Status */
- if (spi_flash_command_short(ftdi, SPI_CMD_EWSR,
+ if (spi_flash_command_short(chnd, SPI_CMD_EWSR,
"Enable Write Status Register") < 0) {
res = -EIO;
goto failed_write;
}
/* SMB_SPI_Flash_Write_Status_Reg */
- res |= i2c_write_byte(ftdi, 0x05, 0xfe);
- res |= i2c_write_byte(ftdi, 0x08, 0x00);
- res |= i2c_write_byte(ftdi, 0x05, 0xfd);
- res |= i2c_write_byte(ftdi, 0x08, 0x01);
- res |= i2c_write_byte(ftdi, 0x08, 0x00);
+ res |= i2c_write_byte(chnd, 0x05, 0xfe);
+ res |= i2c_write_byte(chnd, 0x08, 0x00);
+ res |= i2c_write_byte(chnd, 0x05, 0xfd);
+ res |= i2c_write_byte(chnd, 0x08, 0x01);
+ res |= i2c_write_byte(chnd, 0x08, 0x00);
/* SMB_SPI_Flash_Write_Enable */
- if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_ENABLE,
+ if (spi_flash_command_short(chnd, SPI_CMD_WRITE_ENABLE,
"SPI Command Write Enable") < 0) {
res = -EIO;
goto failed_write;
}
/* SMB_SST_SPI_Flash_AAI2_Program */
- if (spi_flash_command_short(ftdi, SPI_CMD_WORD_PROGRAM,
+ if (spi_flash_command_short(chnd, SPI_CMD_WORD_PROGRAM,
"SPI AAI2 Program") < 0) {
res = -EIO;
goto failed_write;
@@ -845,32 +992,30 @@ int command_write_pages2(struct ftdi_context *ftdi, uint32_t address,
A1 = address>>8;
A0 = 0;
- res = i2c_byte_transfer(ftdi, I2C_DATA_ADDR, &BA, 1, 1);
- res |= i2c_byte_transfer(ftdi, I2C_DATA_ADDR, &A1, 1, 1);
- res |= i2c_byte_transfer(ftdi, I2C_DATA_ADDR, &A0, 1, 1);
- res |= i2c_byte_transfer(ftdi, I2C_DATA_ADDR, buffer++, 1, 1);
- res |= i2c_byte_transfer(ftdi, I2C_DATA_ADDR, buffer++, 1, 1);
+ res = i2c_byte_transfer(chnd, I2C_DATA_ADDR, &BA, 1, 1);
+ res |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, &A1, 1, 1);
+ res |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, &A0, 1, 1);
+ res |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, buffer++, 1, 1);
+ res |= i2c_byte_transfer(chnd, I2C_DATA_ADDR, buffer++, 1, 1);
/* Wait until not busy */
- if (spi_poll_busy(ftdi, "AAI write") < 0)
+ if (spi_poll_busy(chnd, "AAI write") < 0)
goto failed_write;
- res = i2c_write_byte(ftdi, 0x10, 0x20);
- res = i2c_byte_transfer(ftdi, I2C_BLOCK_ADDR,
- buffer, 1, BLOCK_WRITE_SIZE-2);
- remaining = size - BLOCK_WRITE_SIZE;
+ res = i2c_write_byte(chnd, 0x10, 0x20);
+ res = i2c_byte_transfer(chnd, I2C_BLOCK_ADDR,
+ buffer, 1, block_write_size()-2);
- draw_spinner(remaining, size);
/* No error so far */
res = size;
data = 0xff;
- res = i2c_byte_transfer(ftdi, I2C_DATA_ADDR, &data, 1, 1);
- res = i2c_write_byte(ftdi, 0x10, 0x00);
+ res = i2c_byte_transfer(chnd, I2C_DATA_ADDR, &data, 1, 1);
+ res = i2c_write_byte(chnd, 0x10, 0x00);
failed_write:
- if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_DISABLE,
+ if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE,
"write disable exit AAI write") < 0)
res = -EIO;
@@ -878,13 +1023,13 @@ failed_write:
}
-int command_write_unprotect(struct ftdi_context *ftdi)
+int command_write_unprotect(struct common_hnd *chnd)
{
/* TODO(http://crosbug.com/p/23576): implement me */
return 0;
}
-int command_erase(struct ftdi_context *ftdi, uint32_t len, uint32_t off)
+int command_erase(struct common_hnd *chnd, uint32_t len, uint32_t off)
{
int res = -EIO;
int page = 0;
@@ -897,40 +1042,40 @@ int command_erase(struct ftdi_context *ftdi, uint32_t len, uint32_t off)
return -EINVAL;
}
- if (spi_flash_follow_mode(ftdi, "erase") < 0)
+ if (spi_flash_follow_mode(chnd, "erase") < 0)
goto failed_erase;
while (remaining) {
draw_spinner(remaining, len);
- if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_ENABLE,
+ if (spi_flash_command_short(chnd, SPI_CMD_WRITE_ENABLE,
"write enable for erase") < 0)
goto failed_erase;
- if (spi_check_write_enable(ftdi, "erase") < 0)
+ if (spi_check_write_enable(chnd, "erase") < 0)
goto failed_erase;
/* do chip erase */
if (remaining == flash_size) {
- if (spi_flash_command_short(ftdi, SPI_CMD_CHIP_ERASE,
+ if (spi_flash_command_short(chnd, SPI_CMD_CHIP_ERASE,
"chip erase") < 0)
goto failed_erase;
goto wait_busy_cleared;
}
/* do sector erase */
- if (spi_flash_command_short(ftdi, SPI_CMD_SECTOR_ERASE,
+ if (spi_flash_command_short(chnd, SPI_CMD_SECTOR_ERASE,
"sector erase") < 0)
goto failed_erase;
- if (spi_flash_set_erase_page(ftdi, page, "sector erase") < 0)
+ if (spi_flash_set_erase_page(chnd, page, "sector erase") < 0)
goto failed_erase;
wait_busy_cleared:
- if (spi_poll_busy(ftdi, "erase") < 0)
+ if (spi_poll_busy(chnd, "erase") < 0)
goto failed_erase;
- if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_DISABLE,
+ if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE,
"write disable for erase") < 0)
goto failed_erase;
@@ -946,11 +1091,11 @@ wait_busy_cleared:
printf("\n\rErasing Done.\n");
res = 0;
failed_erase:
- if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_DISABLE,
+ if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE,
"write disable exit erase") < 0)
res = -EIO;
- if (spi_flash_follow_mode_exit(ftdi, "erase") < 0)
+ if (spi_flash_follow_mode_exit(chnd, "erase") < 0)
res = -EIO;
return res;
@@ -963,8 +1108,8 @@ failed_erase:
* reset issue while flash.
* Add such function to prevent the reset issue.
*/
-int command_erase2(struct ftdi_context *ftdi, uint32_t len,
- uint32_t off, uint32_t reset)
+int command_erase2(struct common_hnd *chnd, uint32_t len,
+ uint32_t off, uint32_t reset)
{
int res = -EIO;
int page = 0;
@@ -984,32 +1129,32 @@ int command_erase2(struct ftdi_context *ftdi, uint32_t len,
return -EINVAL;
}
- if (spi_flash_follow_mode(ftdi, "erase") < 0)
+ if (spi_flash_follow_mode(chnd, "erase") < 0)
goto failed_erase;
while (remaining) {
draw_spinner(remaining, len);
- if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_ENABLE,
+ if (spi_flash_command_short(chnd, SPI_CMD_WRITE_ENABLE,
"write enable for erase") < 0)
goto failed_erase;
- if (spi_check_write_enable(ftdi, "erase") < 0)
+ if (spi_check_write_enable(chnd, "erase") < 0)
goto failed_erase;
/* do sector erase */
- if (spi_flash_command_short(ftdi, SPI_CMD_SECTOR_ERASE,
+ if (spi_flash_command_short(chnd, SPI_CMD_SECTOR_ERASE,
"sector erase") < 0)
goto failed_erase;
- if (spi_flash_set_erase_page(ftdi, page, "sector erase") < 0)
+ if (spi_flash_set_erase_page(chnd, page, "sector erase") < 0)
goto failed_erase;
- if (spi_poll_busy(ftdi, "erase") < 0)
+ if (spi_poll_busy(chnd, "erase") < 0)
goto failed_erase;
- if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_DISABLE,
+ if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE,
"write disable for erase") < 0)
goto failed_erase;
@@ -1027,18 +1172,18 @@ int command_erase2(struct ftdi_context *ftdi, uint32_t len,
printf("\n\rErasing Done.\n");
res = 0;
failed_erase:
- if (spi_flash_command_short(ftdi, SPI_CMD_WRITE_DISABLE,
+ if (spi_flash_command_short(chnd, SPI_CMD_WRITE_DISABLE,
"write disable exit erase") < 0)
res = -EIO;
- if (spi_flash_follow_mode_exit(ftdi, "erase") < 0)
+ if (spi_flash_follow_mode_exit(chnd, "erase") < 0)
res = -EIO;
return res;
}
/* Return zero on success, a negative error value on failures. */
-int read_flash(struct ftdi_context *ftdi, const char *filename,
+int read_flash(struct common_hnd *chnd, const char *filename,
uint32_t offset, uint32_t size)
{
int res;
@@ -1060,7 +1205,7 @@ int read_flash(struct ftdi_context *ftdi, const char *filename,
if (!size)
size = flash_size;
printf("Reading %d bytes at 0x%08x\n", size, offset);
- res = command_read_pages(ftdi, offset, size, buffer);
+ res = command_read_pages(chnd, offset, size, buffer);
if (res > 0) {
if (fwrite(buffer, res, 1, hnd) != 1)
fprintf(stderr, "Cannot write %s\n", filename);
@@ -1073,7 +1218,7 @@ int read_flash(struct ftdi_context *ftdi, const char *filename,
}
/* Return zero on success, a negative error value on failures. */
-int write_flash(struct ftdi_context *ftdi, const char *filename,
+int write_flash(struct common_hnd *chnd, const char *filename,
uint32_t offset)
{
int res, written;
@@ -1101,7 +1246,7 @@ int write_flash(struct ftdi_context *ftdi, const char *filename,
fclose(hnd);
printf("Writing %d bytes at 0x%08x\n", res, offset);
- written = command_write_pages(ftdi, offset, res, buffer);
+ written = command_write_pages(chnd, offset, res, buffer);
if (written != res) {
fprintf(stderr, "Error writing to flash\n");
free(buffer);
@@ -1120,7 +1265,7 @@ int write_flash(struct ftdi_context *ftdi, const char *filename,
* The original flow may not work on the DX chip.
*
*/
-int write_flash2(struct ftdi_context *ftdi, const char *filename,
+int write_flash2(struct common_hnd *chnd, const char *filename,
uint32_t offset)
{
int res, written;
@@ -1152,16 +1297,16 @@ int write_flash2(struct ftdi_context *ftdi, const char *filename,
offset = 0;
printf("Writing %d bytes at 0x%08x.......\n", res, offset);
while (res) {
- cnt = (res > BLOCK_WRITE_SIZE) ?
- BLOCK_WRITE_SIZE : res;
- written = command_write_pages2(ftdi, offset, cnt,
+ cnt = (res > block_write_size()) ?
+ block_write_size() : res;
+ written = command_write_pages2(chnd, offset, cnt,
&buffer[offset]);
if (written == -EIO)
goto failed_write;
res -= cnt;
offset += cnt;
- draw_spinner(res, size);
+ draw_spinner(res, res + offset);
}
if (written != res) {
@@ -1178,7 +1323,7 @@ failed_write:
/* Return zero on success, a negative error value on failures. */
-int verify_flash(struct ftdi_context *ftdi, const char *filename,
+int verify_flash(struct common_hnd *chnd, const char *filename,
uint32_t offset)
{
int res;
@@ -1210,7 +1355,7 @@ int verify_flash(struct ftdi_context *ftdi, const char *filename,
}
printf("Verify %d bytes at 0x%08x\n", file_size, offset);
- res = command_read_pages(ftdi, offset, flash_size, buffer2);
+ res = command_read_pages(chnd, offset, flash_size, buffer2);
draw_spinner(flash_size-res, flash_size);
res = memcmp(buffer, buffer2, file_size);
printf("\n\rVerify %s\n", res ? "Failed!" : "Done.");
@@ -1253,35 +1398,37 @@ open_failed:
}
static const struct option longopts[] = {
+ {"ccd", 0, 0, 'c'},
{"debug", 0, 0, 'd'},
- {"product", 1, 0, 'p'},
- {"vendor", 1, 0, 'v'},
- {"interface", 1, 0, 'i'},
- {"serial", 1, 0, 's'},
- {"read", 1, 0, 'r'},
- {"write", 1, 0, 'w'},
{"erase", 0, 0, 'e'},
{"help", 0, 0, 'h'},
+ {"interface", 1, 0, 'i'},
+ {"product", 1, 0, 'p'},
+ {"read", 1, 0, 'r'},
+ {"serial", 1, 0, 's'},
{"unprotect", 0, 0, 'u'},
+ {"vendor", 1, 0, 'v'},
+ {"write", 1, 0, 'w'},
{NULL, 0, 0, 0}
};
void display_usage(char *program)
{
- fprintf(stderr, "Usage: %s [-d] [-v <VID>] [-p <PID>] [-i <1|2>] "
+ fprintf(stderr, "Usage: %s [-c] [-d] [-v <VID>] [-p <PID>] [-i <1|2>] "
"[-s <serial>] [-u] [-e] [-r <file>] [-w <file>]\n", program);
+ fprintf(stderr, "--c[cd] : use CCD interface instead of FTDI, make "
+ "sure this option is included before -p and or -v\n");
fprintf(stderr, "--d[ebug] : output debug traces\n");
- fprintf(stderr, "--v[endor] <0x1234> : USB vendor ID\n");
- fprintf(stderr, "--p[roduct] <0x1234> : USB product ID\n");
- fprintf(stderr, "--s[erial] <serialname> : USB serial string\n");
- fprintf(stderr, "--i[interface] <1> : FTDI interface: A=1, B=2, ...\n");
- fprintf(stderr, "--u[nprotect] : remove flash write protect\n");
fprintf(stderr, "--e[rase] : erase all the flash content\n");
+ fprintf(stderr, "--i[interface] <1> : FTDI interface: A=1, B=2, ...\n");
+ fprintf(stderr, "--p[roduct] <0x1234> : USB product ID\n");
fprintf(stderr, "--r[ead] <file> : read the flash content and "
"write it into <file>\n");
+ fprintf(stderr, "--s[erial] <serialname> : USB serial string\n");
+ fprintf(stderr, "--u[nprotect] : remove flash write protect\n");
+ fprintf(stderr, "--v[endor] <0x1234> : USB vendor ID\n");
fprintf(stderr, "--w[rite] <file> : read <file> and "
"write it to flash\n");
-
exit(2);
}
@@ -1290,24 +1437,18 @@ int parse_parameters(int argc, char **argv)
int opt, idx;
int flags = 0;
- while ((opt = getopt_long(argc, argv, "dv:p:i:s:ehr:w:u?",
+ while ((opt = getopt_long(argc, argv, "?cdehi:p:r:s:uv:w:",
longopts, &idx)) != -1) {
switch (opt) {
+ case 'c':
+ flags |= FLAG_CCD_MODE;
+ usb_vid = CR50_USB_VID;
+ usb_pid = CR50_USB_PID;
+ block_write_size_ = CCD_BLOCK_WRITE_SIZE;
+ break;
case 'd':
debug = 1;
break;
- case 'v':
- usb_vid = strtol(optarg, NULL, 16);
- break;
- case 'p':
- usb_pid = strtol(optarg, NULL, 16);
- break;
- case 'i':
- usb_interface = atoi(optarg);
- break;
- case 's':
- usb_serial = optarg;
- break;
case 'e':
flags |= FLAG_ERASE;
break;
@@ -1315,15 +1456,27 @@ int parse_parameters(int argc, char **argv)
case '?':
display_usage(argv[0]);
break;
+ case 'i':
+ usb_interface = atoi(optarg);
+ break;
+ case 'p':
+ usb_pid = strtol(optarg, NULL, 16);
+ break;
case 'r':
input_filename = optarg;
break;
- case 'w':
- output_filename = optarg;
+ case 's':
+ usb_serial = optarg;
break;
case 'u':
flags |= FLAG_UNPROTECT;
break;
+ case 'v':
+ usb_vid = strtol(optarg, NULL, 16);
+ break;
+ case 'w':
+ output_filename = optarg;
+ break;
}
}
return flags;
@@ -1350,37 +1503,51 @@ static void register_sigaction(void)
int main(int argc, char **argv)
{
- void *hnd;
+ struct common_hnd chnd;
int ret = 1;
int flags;
/* Parse command line options */
flags = parse_parameters(argc, argv);
- /* Open the USB device */
- hnd = open_ftdi_device(usb_vid, usb_pid, usb_interface, usb_serial);
- if (hnd == NULL)
- return 1;
+ /* Open the communications channel. */
+ memset(&chnd, 0, sizeof(chnd));
+ if (flags & FLAG_CCD_MODE) {
+ usb_findit(usb_vid, usb_pid, CR50_I2C_SUBCLASS,
+ CR50_I2C_PROTOCOL, &chnd.uep);
+ chnd.iftype = CCD_IF;
+ printf("Using CCD device%s\n",
+ usb_serial ? ", ignoring serial number" : "");
+ } else {
+ chnd.ftdi_hnd = open_ftdi_device(usb_vid, usb_pid,
+ usb_interface, usb_serial);
+ if (chnd.ftdi_hnd == NULL)
+ return 1;
+ chnd.iftype = FTDI_IF;
+ }
/* Register signal handler after opening USB handle. */
register_sigaction();
/* Trigger embedded monitor detection */
- if (send_special_waveform(hnd) < 0)
+ if (send_special_waveform(&chnd) < 0)
goto terminate;
- if (config_i2c(hnd) < 0)
- goto terminate;
+ if (chnd.iftype == FTDI_IF) {
+ if (config_i2c(chnd.ftdi_hnd) < 0)
+ goto terminate;
- if (check_chipid(hnd) < 0)
- goto terminate;
+ if (check_chipid(&chnd) < 0)
+ goto terminate;
+ }
if (flags & FLAG_UNPROTECT)
- command_write_unprotect(hnd);
+ command_write_unprotect(&chnd);
if (input_filename) {
- dbgr_reset(hnd, RSTS_VCCDO_PW_ON);
- ret = read_flash(hnd, input_filename, 0, flash_size);
+ dbgr_reset(&chnd, RSTS_VCCDO_PW_ON);
+ ret = read_flash(&chnd, input_filename, 0, flash_size);
+
if (ret)
goto terminate;
}
@@ -1394,18 +1561,22 @@ int main(int argc, char **argv)
* Erase first sector to prevent watchdog reset
* from happening
*/
- command_erase2(hnd, flash_size, 0, 1);
+ command_erase2(&chnd, flash_size, 0, 1);
/* Call DBGR Rest to clear the EC lock status */
- dbgr_reset(hnd, RSTS_VCCDO_PW_ON|RSTS_HGRST|RSTS_GRST);
- if (config_i2c(hnd) < 0)
+
+ dbgr_reset(&chnd,
+ RSTS_VCCDO_PW_ON|RSTS_HGRST|RSTS_GRST);
+ if (!(flags & FLAG_CCD_MODE) &&
+ (config_i2c(chnd.ftdi_hnd) < 0))
goto terminate;
/* Do Normal Erase Function */
- command_erase2(hnd, flash_size, 0, 0);
+ command_erase2(&chnd, flash_size, 0, 0);
} else {
- command_erase(hnd, flash_size, 0);
+ command_erase(&chnd, flash_size, 0);
/* Call DBGR Rest to clear the EC lock status */
- dbgr_reset(hnd, RSTS_VCCDO_PW_ON|RSTS_HGRST|RSTS_GRST);
+ dbgr_reset(&chnd,
+ RSTS_VCCDO_PW_ON|RSTS_HGRST|RSTS_GRST);
}
}
@@ -1413,14 +1584,14 @@ int main(int argc, char **argv)
if (output_filename) {
if (is8320dx)
- ret = write_flash2(hnd, output_filename, 0);
+ ret = write_flash2(&chnd, output_filename, 0);
else
- ret = write_flash(hnd, output_filename, 0);
+ ret = write_flash(&chnd, output_filename, 0);
if (ret)
goto terminate;
- ret = verify_flash(hnd, output_filename, 0);
+ ret = verify_flash(&chnd, output_filename, 0);
if (ret)
goto terminate;
}
@@ -1432,9 +1603,11 @@ terminate:
/*
* Enable EC Host Global Reset to reset EC resource and EC domain
*/
- dbgr_reset(hnd, RSTS_VCCDO_PW_ON|RSTS_HGRST|RSTS_GRST);
+ dbgr_reset(&chnd, RSTS_VCCDO_PW_ON|RSTS_HGRST|RSTS_GRST);
/* Close the FTDI USB handle */
- ftdi_usb_close(hnd);
- ftdi_free(hnd);
+ if (chnd.iftype == FTDI_IF) {
+ ftdi_usb_close(chnd.ftdi_hnd);
+ ftdi_free(chnd.ftdi_hnd);
+ }
return ret;
}