/* * Copyright (c) 2020 Henrik Brix Andersen * * SPDX-License-Identifier: Apache-2.0 */ #include #include #include #include #include #include LOG_MODULE_REGISTER(board, CONFIG_LOG_DEFAULT_LEVEL); #include "board.h" #define DAPLINK_QSPI_MUX_NODE DT_NODELABEL(daplink_qspi_mux) #if DT_NODE_HAS_STATUS(DAPLINK_QSPI_MUX_NODE, okay) int board_daplink_qspi_mux_select(enum board_daplink_qspi_mux_mode mode) { const struct device *gpio; gpio_flags_t flags; int err; switch (mode) { case BOARD_DAPLINK_QSPI_MUX_MODE_XIP: flags = GPIO_OUTPUT_LOW; break; case BOARD_DAPLINK_QSPI_MUX_MODE_NORMAL: flags = GPIO_OUTPUT_HIGH; break; default: __ASSERT(0, "invalid mode"); return -EINVAL; } gpio = device_get_binding(DT_GPIO_LABEL(DAPLINK_QSPI_MUX_NODE, mux_gpios)); if (!gpio) { LOG_ERR("DAPLink QSPI MUX GPIO device '%s' not found", DT_GPIO_LABEL(DAPLINK_QSPI_MUX_NODE, mux_gpios)); return -EINVAL; } err = gpio_config(gpio, DT_GPIO_PIN(DAPLINK_QSPI_MUX_NODE, mux_gpios), DT_GPIO_FLAGS(DAPLINK_QSPI_MUX_NODE, mux_gpios) | flags); if (err) { LOG_ERR("failed to configure DAPLink QSPI MUX GPIO (err %d)", err); return err; } return 0; } bool board_daplink_is_fitted(void) { /* * The DAPLINK_fitted_n signal is routed to an IRQ line. It is used as a * level-detect non-interrupt signal to determine if the DAPLink shield * is fitted. */ return !NVIC_GetPendingIRQ(DT_IRQN(DAPLINK_QSPI_MUX_NODE)); } static int board_init(const struct device *dev) { ARG_UNUSED(dev); /* * Automatically select normal mode unless the DAPLink shield is fitted * in which case the CPU will have the off-board QSPI NOR flash * memory-mapped at 0x0. */ if (!board_daplink_is_fitted()) { board_daplink_qspi_mux_select( BOARD_DAPLINK_QSPI_MUX_MODE_NORMAL); } return 0; } SYS_INIT(board_init, POST_KERNEL, CONFIG_BOARD_INIT_PRIORITY); #endif /* DT_NODE_HAS_STATUS(DAPLINK_QSPI_MUX_NODE, okay) */