diff options
-rw-r--r-- | util/build.mk | 1 | ||||
-rw-r--r-- | util/iteflash.c | 675 |
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, ®, 0, 1) < 0) { + if (i2c_byte_transfer(chnd, I2C_DATA_ADDR, ®, 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, ®, 0, 1) < 0) { + if (i2c_byte_transfer(chnd, I2C_DATA_ADDR, ®, 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; } |