diff options
Diffstat (limited to 'chip/npcx/flash.c')
-rw-r--r-- | chip/npcx/flash.c | 832 |
1 files changed, 0 insertions, 832 deletions
diff --git a/chip/npcx/flash.c b/chip/npcx/flash.c deleted file mode 100644 index 507b83714c..0000000000 --- a/chip/npcx/flash.c +++ /dev/null @@ -1,832 +0,0 @@ -/* Copyright 2014 The Chromium OS Authors. All rights reserved. - * Use of this source code is governed by a BSD-style license that can be - * found in the LICENSE file. - */ - -/* Flash memory module for Chrome EC */ - -#include "flash.h" -#include "host_command.h" -#include "registers.h" -#include "spi_flash_reg.h" -#include "switch.h" -#include "system.h" -#include "timer.h" -#include "util.h" -#include "task.h" -#include "watchdog.h" -#include "console.h" -#include "hwtimer_chip.h" - -static int all_protected; /* Has all-flash protection been requested? */ -static int addr_prot_start; -static int addr_prot_length; -static uint8_t flag_prot_inconsistent; - -/* SR regs aren't readable when UMA lock is on, so save a copy */ -static uint8_t saved_sr1; -static uint8_t saved_sr2; - -#ifdef CONFIG_EXTERNAL_STORAGE -#define TRISTATE_FLASH(x) -#else -#define TRISTATE_FLASH(x) flash_tristate(x) -#endif - -/* Ensure only one task is accessing flash at a time. */ -static struct mutex flash_lock; - -/*****************************************************************************/ -/* flash internal functions */ -#if !defined(NPCX_INT_FLASH_SUPPORT) -static void flash_pinmux(int enable) -{ - /* Select pin-mux for FIU*/ - UPDATE_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_NO_F_SPI, !enable); - - /* CS0/1 pinmux */ - if (enable) { -#if (FIU_CHIP_SELECT == 1) - SET_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_F_SPI_CS1_1); -#elif (FIU_CHIP_SELECT == 2) - SET_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_F_SPI_CS1_2); -#endif - } else { - CLEAR_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_F_SPI_CS1_1); - CLEAR_BIT(NPCX_DEVALT(0), NPCX_DEVALT0_F_SPI_CS1_2); - } -} -#endif - -static void flash_execute_cmd(uint8_t code, uint8_t cts) -{ - /* - * Flash mutex must be held while executing UMA commands after - * task_start(). - */ - ASSERT(!task_start_called() || flash_lock.lock); - - /* set UMA_CODE */ - NPCX_UMA_CODE = code; - /* execute UMA flash transaction */ - NPCX_UMA_CTS = cts; - while (IS_BIT_SET(NPCX_UMA_CTS, NPCX_UMA_CTS_EXEC_DONE)) - ; -} - -static void flash_cs_level(int level) -{ - /* Set chip select to high/low level */ - UPDATE_BIT(NPCX_UMA_ECTS, NPCX_UMA_ECTS_SW_CS1, level); -} - -static int flash_wait_ready(void) -{ - uint8_t mask = SPI_FLASH_SR1_BUSY; - const timestamp_t start = get_time(); - const uint32_t timeout_us = 10 * SECOND; - const timestamp_t deadline = { - .val = start.val + timeout_us, - }; - - /* Chip Select down. */ - flash_cs_level(0); - /* Command for Read status register */ - flash_execute_cmd(CMD_READ_STATUS_REG, MASK_CMD_ONLY); - do { - /* Read status register */ - NPCX_UMA_CTS = MASK_RD_1BYTE; - while (IS_BIT_SET(NPCX_UMA_CTS, NPCX_UMA_CTS_EXEC_DONE)) - ; - /* Busy bit is clear */ - if ((NPCX_UMA_DB0 & mask) == 0) - break; - usleep(10); - } while (!timestamp_expired(deadline, NULL)); /* Wait for Busy clear */ - - /* Chip Select high. */ - flash_cs_level(1); - - if (timestamp_expired(deadline, NULL)) - return EC_ERROR_TIMEOUT; - - return EC_SUCCESS; -} - -static int flash_write_enable(void) -{ - uint8_t mask = SPI_FLASH_SR1_WEL; - int rv; - /* Wait for previous operation to complete */ - rv = flash_wait_ready(); - if (rv) - return rv; - - /* Write enable command */ - flash_execute_cmd(CMD_WRITE_EN, MASK_CMD_ONLY); - - /* Wait for flash is not busy */ - rv = flash_wait_ready(); - if (rv) - return rv; - - if (NPCX_UMA_DB0 & mask) - return EC_SUCCESS; - else - return EC_ERROR_BUSY; -} - -static void flash_set_address(uint32_t dest_addr) -{ - uint8_t *addr = (uint8_t *)&dest_addr; - /* Write address */ - NPCX_UMA_AB2 = addr[2]; - NPCX_UMA_AB1 = addr[1]; - NPCX_UMA_AB0 = addr[0]; -} - -static uint8_t flash_get_status1(void) -{ - uint8_t ret; - - if (all_protected) - return saved_sr1; - - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - /* Read status register1 */ - flash_execute_cmd(CMD_READ_STATUS_REG, MASK_CMD_RD_1BYTE); - /* Enable tri-state */ - TRISTATE_FLASH(1); - - ret = NPCX_UMA_DB0; - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); - - return ret; -} - -static uint8_t flash_get_status2(void) -{ - uint8_t ret; - - if (all_protected) - return saved_sr2; - - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - /* Read status register2 */ - flash_execute_cmd(CMD_READ_STATUS_REG2, MASK_CMD_RD_1BYTE); - /* Enable tri-state */ - TRISTATE_FLASH(1); - - ret = NPCX_UMA_DB0; - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); - - return ret; -} - -#ifdef NPCX_INT_FLASH_SUPPORT -static int is_int_flash_protected(void) -{ - return IS_BIT_SET(NPCX_DEV_CTL4, NPCX_DEV_CTL4_WP_IF); -} - -static void flash_protect_int_flash(int enable) -{ - /* - * Please notice the type of WP_IF bit is R/W1S. Once it's set, - * only rebooting EC can clear it. - */ - if (enable && !is_int_flash_protected()) - SET_BIT(NPCX_DEV_CTL4, NPCX_DEV_CTL4_WP_IF); -} -#endif - -#ifdef CONFIG_HOSTCMD_FLASH_SPI_INFO - -void flash_get_mfr_dev_id(uint8_t *dest) -{ - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - /* Read manufacturer and device ID. Send cmd=0x90 + 24-bit address=0 */ - flash_set_address(0); - flash_execute_cmd(CMD_READ_MAN_DEV_ID, - MASK_CMD_RD_2BYTE | MASK(A_SIZE)); - /* Enable tri-state */ - TRISTATE_FLASH(1); - - dest[0] = NPCX_UMA_DB0; - dest[1] = NPCX_UMA_DB1; - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); -} - -#endif /* CONFIG_HOSTCMD_FLASH_SPI_INFO */ - -void flash_get_jedec_id(uint8_t *dest) -{ - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - /* Read manufacturer and device ID */ - flash_execute_cmd(CMD_READ_ID, MASK_CMD_RD_3BYTE); - /* Enable tri-state */ - TRISTATE_FLASH(1); - - dest[0] = NPCX_UMA_DB0; - dest[1] = NPCX_UMA_DB1; - dest[2] = NPCX_UMA_DB2; - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); -} - -static void flash_uma_lock(int enable) -{ - if (enable && !all_protected) { - /* - * Store SR1 / SR2 for later use since we're about to lock - * out all access (including read access) to these regs. - */ - saved_sr1 = flash_get_status1(); - saved_sr2 = flash_get_status2(); - } - - all_protected = enable; - UPDATE_BIT(NPCX_UMA_ECTS, NPCX_UMA_ECTS_UMA_LOCK, enable); -} - -static int flash_set_status_for_prot(int reg1, int reg2) -{ - /* - * Writing SR regs will fail if our UMA lock is enabled. If WP - * is deasserted then remove the lock and allow the write. - */ - if (all_protected) { -#ifdef NPCX_INT_FLASH_SUPPORT - if (is_int_flash_protected()) - return EC_ERROR_ACCESS_DENIED; -#endif - - if (crec_flash_get_protect() & EC_FLASH_PROTECT_GPIO_ASSERTED) - return EC_ERROR_ACCESS_DENIED; - flash_uma_lock(0); - } - - /* - * If WP# is active and ec doesn't protect the status registers of - * internal spi-flash, protect it now before setting them. - */ -#ifdef NPCX_INT_FLASH_SUPPORT -#ifdef CONFIG_WP_ACTIVE_HIGH - flash_protect_int_flash(gpio_get_level(GPIO_WP)); -#else - flash_protect_int_flash(!gpio_get_level(GPIO_WP_L)); -#endif /*_CONFIG_WP_ACTIVE_HIGH_*/ -#endif - - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - /* Enable write */ - flash_write_enable(); - - NPCX_UMA_DB0 = reg1; - NPCX_UMA_DB1 = reg2; - - /* Write status register 1/2 */ - flash_execute_cmd(CMD_WRITE_STATUS_REG, MASK_CMD_WR_2BYTE); - /* Enable tri-state */ - TRISTATE_FLASH(1); - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); - - spi_flash_reg_to_protect(reg1, reg2, - &addr_prot_start, &addr_prot_length); - - return EC_SUCCESS; -} - -static int flash_check_prot_range(unsigned int offset, unsigned int bytes) -{ - /* Invalid value */ - if (offset + bytes > CONFIG_FLASH_SIZE_BYTES) - return EC_ERROR_INVAL; - /* Check if ranges overlap */ - if (MAX(addr_prot_start, offset) < MIN(addr_prot_start + - addr_prot_length, offset + bytes)) - return EC_ERROR_ACCESS_DENIED; - - return EC_SUCCESS; -} - -static int flash_check_prot_reg(unsigned int offset, unsigned int bytes) -{ - unsigned int start; - unsigned int len; - uint8_t sr1, sr2; - int rv = EC_SUCCESS; - - /* - * If WP# is active and ec doesn't protect the status registers of - * internal spi-flash, protect it now. - */ -#ifdef NPCX_INT_FLASH_SUPPORT -#ifdef CONFIG_WP_ACTIVE_HIGH - flash_protect_int_flash(gpio_get_level(GPIO_WP)); -#else - flash_protect_int_flash(!gpio_get_level(GPIO_WP_L)); -#endif /* CONFIG_WP_ACTIVE_HIGH */ -#endif - - sr1 = flash_get_status1(); - sr2 = flash_get_status2(); - - /* Invalid value */ - if (offset + bytes > CONFIG_FLASH_SIZE_BYTES) - return EC_ERROR_INVAL; - - /* Compute current protect range */ - rv = spi_flash_reg_to_protect(sr1, sr2, &start, &len); - if (rv) - return rv; - - /* Check if ranges overlap */ - if (MAX(start, offset) < MIN(start + len, offset + bytes)) - return EC_ERROR_ACCESS_DENIED; - - return EC_SUCCESS; - -} - -static int flash_write_prot_reg(unsigned int offset, unsigned int bytes, - int hw_protect) -{ - int rv; - uint8_t sr1 = flash_get_status1(); - uint8_t sr2 = flash_get_status2(); - - /* Invalid values */ - if (offset + bytes > CONFIG_FLASH_SIZE_BYTES) - return EC_ERROR_INVAL; - - /* Compute desired protect range */ - rv = spi_flash_protect_to_reg(offset, bytes, &sr1, &sr2); - if (rv) - return rv; - - if (hw_protect) - sr1 |= SPI_FLASH_SR1_SRP0; - - return flash_set_status_for_prot(sr1, sr2); -} - -static void flash_burst_write(unsigned int dest_addr, unsigned int bytes, - const char *data) -{ - unsigned int i; - /* Chip Select down */ - flash_cs_level(0); - /* Set write address */ - flash_set_address(dest_addr); - /* Start programming */ - flash_execute_cmd(CMD_FLASH_PROGRAM, MASK_CMD_WR_ADR); - for (i = 0; i < bytes; i++) { - flash_execute_cmd(*data, MASK_CMD_WR_ONLY); - data++; - } - /* Chip Select up */ - flash_cs_level(1); -} - -static int flash_program_bytes(uint32_t offset, uint32_t bytes, - const uint8_t *data) -{ - int write_size; - int rv; - - while (bytes > 0) { - /* Write length can not go beyond the end of the flash page */ - write_size = MIN(bytes, CONFIG_FLASH_WRITE_IDEAL_SIZE - - (offset & (CONFIG_FLASH_WRITE_IDEAL_SIZE - 1))); - - /* Enable write */ - rv = flash_write_enable(); - if (rv) - return rv; - - /* Burst UMA transaction */ - flash_burst_write(offset, write_size, data); - - /* Wait write completed */ - rv = flash_wait_ready(); - if (rv) - return rv; - - data += write_size; - offset += write_size; - bytes -= write_size; - } - - return rv; -} - -/*****************************************************************************/ - -int crec_flash_physical_read(int offset, int size, char *data) -{ - int dest_addr = offset; - uint32_t idx; - - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - /* Chip Select down. */ - flash_cs_level(0); - - /* Set read address */ - flash_set_address(dest_addr); - /* Start fast read - 1110 1001 - EXEC, WR, CMD, ADDR */ - flash_execute_cmd(CMD_FAST_READ, MASK_CMD_ADR_WR); - - /* Burst read transaction */ - for (idx = 0; idx < size; idx++) { - /* 1101 0101 - EXEC, RD, NO CMD, NO ADDR, 4 bytes */ - NPCX_UMA_CTS = MASK_RD_1BYTE; - /* wait for UMA to complete */ - while (IS_BIT_SET(NPCX_UMA_CTS, EXEC_DONE)) - ; - /* Get read transaction results*/ - data[idx] = NPCX_UMA_DB0; - } - - /* Chip Select up */ - flash_cs_level(1); - /* Enable tri-state */ - TRISTATE_FLASH(1); - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); - - return EC_SUCCESS; -} - -int crec_flash_physical_write(int offset, int size, const char *data) -{ - int dest_addr = offset; - int write_len; - int rv; - - /* Fail if offset, size, and data aren't at least word-aligned */ - if ((offset | size - | (uint32_t)(uintptr_t)data) & (CONFIG_FLASH_WRITE_SIZE - 1)) - return EC_ERROR_INVAL; - - /* check protection */ - if (all_protected) - return EC_ERROR_ACCESS_DENIED; - - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - - while (size > 0) { - /* First write multiples of 256, then (size % 256) last */ - write_len = ((size % CONFIG_FLASH_WRITE_IDEAL_SIZE) == size) ? - size : CONFIG_FLASH_WRITE_IDEAL_SIZE; - - /* check protection */ - if (flash_check_prot_range(dest_addr, write_len)) { - rv = EC_ERROR_ACCESS_DENIED; - break; - } - - rv = flash_program_bytes(dest_addr, write_len, data); - if (rv) - break; - - data += write_len; - dest_addr += write_len; - size -= write_len; - } - - /* Enable tri-state */ - TRISTATE_FLASH(1); - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); - - return rv; -} - -int crec_flash_physical_erase(int offset, int size) -{ - int rv = EC_SUCCESS; - /* check protection */ - if (all_protected) - return EC_ERROR_ACCESS_DENIED; - - /* Lock physical flash operations */ - crec_flash_lock_mapped_storage(1); - - /* Disable tri-state */ - TRISTATE_FLASH(0); - - /* Alignment has been checked in upper layer */ - for (; size > 0; size -= CONFIG_FLASH_ERASE_SIZE, - offset += CONFIG_FLASH_ERASE_SIZE) { - /* check protection */ - if (flash_check_prot_range(offset, CONFIG_FLASH_ERASE_SIZE)) { - rv = EC_ERROR_ACCESS_DENIED; - break; - } - - /* - * Reload the watchdog timer, so that erasing many flash pages - * doesn't cause a watchdog reset. May not need this now that - * we're using msleep() below. - */ - watchdog_reload(); - - /* Enable write */ - rv = flash_write_enable(); - if (rv) - break; - - /* Set erase address */ - flash_set_address(offset); - /* Start erase */ - flash_execute_cmd(NPCX_ERASE_COMMAND, MASK_CMD_ADR); - - /* Wait erase completed */ - rv = flash_wait_ready(); - if (rv) - break; - } - - /* Enable tri-state */ - TRISTATE_FLASH(1); - - /* Unlock physical flash operations */ - crec_flash_lock_mapped_storage(0); - - return rv; -} - -int crec_flash_physical_get_protect(int bank) -{ - uint32_t addr = bank * CONFIG_FLASH_BANK_SIZE; - - return flash_check_prot_reg(addr, CONFIG_FLASH_BANK_SIZE); -} - -uint32_t crec_flash_physical_get_protect_flags(void) -{ - uint32_t flags = 0; - - /* Check if WP region is protected in status register */ - if (flash_check_prot_reg(WP_BANK_OFFSET*CONFIG_FLASH_BANK_SIZE, - WP_BANK_COUNT*CONFIG_FLASH_BANK_SIZE)) - flags |= EC_FLASH_PROTECT_RO_AT_BOOT; - - /* - * TODO: If status register protects a range, but SRP0 is not set, - * flags should indicate EC_FLASH_PROTECT_ERROR_INCONSISTENT. - */ - if (flag_prot_inconsistent) - flags |= EC_FLASH_PROTECT_ERROR_INCONSISTENT; - - /* Read all-protected state from our shadow copy */ - if (all_protected) - flags |= EC_FLASH_PROTECT_ALL_NOW; - - return flags; -} - -int crec_flash_physical_protect_now(int all) -{ - if (all) { - /* - * Set UMA_LOCK bit for locking all UMA transaction. - * But we still can read directly from flash mapping address - */ - flash_uma_lock(1); - } else { - /* TODO: Implement RO "now" protection */ - } - - return EC_SUCCESS; -} - - -int crec_flash_physical_protect_at_boot(uint32_t new_flags) -{ - int ret; - - if ((new_flags & (EC_FLASH_PROTECT_RO_AT_BOOT | - EC_FLASH_PROTECT_ALL_AT_BOOT)) == 0) { - /* Clear protection bits in status register */ - return flash_set_status_for_prot(0, 0); - } - - ret = flash_write_prot_reg(CONFIG_WP_STORAGE_OFF, - CONFIG_WP_STORAGE_SIZE, - 1); - - /* - * Set UMA_LOCK bit for locking all UMA transaction. - * But we still can read directly from flash mapping address - */ - if (new_flags & EC_FLASH_PROTECT_ALL_AT_BOOT) - flash_uma_lock(1); - - return ret; -} - -uint32_t crec_flash_physical_get_valid_flags(void) -{ - return EC_FLASH_PROTECT_RO_AT_BOOT | - EC_FLASH_PROTECT_RO_NOW | - EC_FLASH_PROTECT_ALL_NOW; -} - -uint32_t crec_flash_physical_get_writable_flags(uint32_t cur_flags) -{ - uint32_t ret = 0; - - /* If RO protection isn't enabled, its at-boot state can be changed. */ - if (!(cur_flags & EC_FLASH_PROTECT_RO_NOW)) - ret |= EC_FLASH_PROTECT_RO_AT_BOOT; - - /* - * If entire flash isn't protected at this boot, it can be enabled if - * the WP GPIO is asserted. - */ - if (!(cur_flags & EC_FLASH_PROTECT_ALL_NOW) && - (cur_flags & EC_FLASH_PROTECT_GPIO_ASSERTED)) - ret |= EC_FLASH_PROTECT_ALL_NOW; - - return ret; -} - -/*****************************************************************************/ -/* High-level APIs */ - -int crec_flash_pre_init(void) -{ - /* - * Protect status registers of internal spi-flash if WP# is active - * during ec initialization. - */ -#ifdef NPCX_INT_FLASH_SUPPORT -#ifdef CONFIG_WP_ACTIVE_HIGH - flash_protect_int_flash(gpio_get_level(GPIO_WP)); -#else - flash_protect_int_flash(!gpio_get_level(GPIO_WP_L)); -#endif /*CONFIG_WP_ACTIVE_HIGH */ -#endif - -#if !defined(NPCX_INT_FLASH_SUPPORT) - /* Enable FIU interface */ - flash_pinmux(1); -#endif - -#if defined(CONFIG_EXTERNAL_STORAGE) && !defined(NPCX_INT_FLASH_SUPPORT) - /* Disable tristate all the time */ - CLEAR_BIT(NPCX_DEVCNT, NPCX_DEVCNT_F_SPI_TRIS); -#endif - - /* Initialize UMA to unlocked */ - flash_uma_lock(0); - return EC_SUCCESS; -} - -void crec_flash_lock_mapped_storage(int lock) -{ - if (lock) - mutex_lock(&flash_lock); - else - mutex_unlock(&flash_lock); -} - -/*****************************************************************************/ -/* Host commands */ - -#if defined(CONFIG_HOSTCMD_FLASH_SPI_INFO) && !defined(BOARD_NPCX_EVB) -/* NPCX EVB uses implementation from spi_flash.c */ - -static enum ec_status flash_command_spi_info(struct host_cmd_handler_args *args) -{ - struct ec_response_flash_spi_info *r = args->response; - - flash_get_jedec_id(r->jedec); - r->reserved0 = 0; - flash_get_mfr_dev_id(r->mfr_dev_id); - r->sr1 = flash_get_status1(); - r->sr2 = flash_get_status2(); - - args->response_size = sizeof(*r); - return EC_RES_SUCCESS; -} -DECLARE_HOST_COMMAND(EC_CMD_FLASH_SPI_INFO, - flash_command_spi_info, - EC_VER_MASK(0)); - -#endif - -#ifdef CONFIG_CMD_FLASH_TRISTATE -#ifdef NPCX_INT_FLASH_SUPPORT -#error "Flash tristate is not relevant when internal flash is used." -#endif -static void flash_tristate(int enable) -{ - /* Enable/Disable FIU pins to tri-state */ - UPDATE_BIT(NPCX_DEVCNT, NPCX_DEVCNT_F_SPI_TRIS, enable); -} - -static int flash_spi_sel_lock(int enable) -{ - /* - * F_SPI_QUAD, F_SPI_CS1_1/2, F_SPI_TRIS become read-only - * if this bit is set - */ - UPDATE_BIT(NPCX_DEV_CTL4, NPCX_DEV_CTL4_F_SPI_SLLK, enable); - return IS_BIT_SET(NPCX_DEV_CTL4, NPCX_DEV_CTL4_F_SPI_SLLK); -} - -/*****************************************************************************/ -/* Console commands */ - -static int command_flash_spi_sel_lock(int argc, char **argv) -{ - int ena; - - if (argc > 1) { - if (!parse_bool(argv[1], &ena)) - return EC_ERROR_PARAM1; - ena = flash_spi_sel_lock(ena); - ccprintf("Enabled: %d\n", ena); - } - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(flash_spi_lock, command_flash_spi_sel_lock, - "[on | off]", - "Lock spi flash interface selection"); - -static int command_flash_tristate(int argc, char **argv) -{ - int ena; - - if (argc > 1) { - if (!parse_bool(argv[1], &ena)) - return EC_ERROR_PARAM1; - flash_tristate(ena); - ccprintf("Enabled: %d\n", ena); - } - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(flash_tristate, command_flash_tristate, - "[on | off]", - "Tristate spi flash pins"); -#endif /* CONFIG_CMD_FLASH_TRISTATE */ - -static int command_flash_chip(int argc, char **argv) -{ - uint8_t jedec_id[3]; - - ccprintf("Status 1: 0x%02x, Status 2: 0x%02x\n", flash_get_status1(), - flash_get_status2()); - - flash_get_jedec_id(jedec_id); - ccprintf("Manufacturer: 0x%02x, DID: 0x%02x%02x\n", jedec_id[0], - jedec_id[1], jedec_id[2]); - - return EC_SUCCESS; -} -DECLARE_CONSOLE_COMMAND(flashchip, command_flash_chip, - NULL, - "Print flash chip info"); |