drivers: spi: add spi_cs_is_gpio(_dt) helpers

Add spi_cs_is_gpio(_dt) helpers to check whether SPI CS is controlled by
GPIO or not. This both improves code readability and isolates SPI
internals.

Signed-off-by: Gerard Marull-Paretas <gerard.marull@nordicsemi.no>
This commit is contained in:
Gerard Marull-Paretas 2023-04-19 11:11:38 +02:00 committed by Carles Cufí
parent 3f2c2d4130
commit 1e0028ae3d
12 changed files with 41 additions and 16 deletions

View file

@ -74,7 +74,7 @@ static bool spi_b91_config_cs(const struct device *dev,
const struct spi_b91_cfg *b91_config = SPI_CFG(dev);
/* software flow control */
if (config->cs.gpio.port != NULL) {
if (spi_cs_is_gpio(config)) {
/* disable all hardware CS pins */
spi_b91_hw_cs_disable(b91_config);
return true;
@ -397,7 +397,7 @@ static int spi_b91_transceive(const struct device *dev,
spi_context_buffers_setup(&data->ctx, tx_bufs, rx_bufs, 1);
/* if cs is defined: software cs control, set active true */
if (config->cs.gpio.port != NULL) {
if (spi_cs_is_gpio(config)) {
spi_context_cs_control(&data->ctx, true);
}
@ -405,7 +405,7 @@ static int spi_b91_transceive(const struct device *dev,
spi_b91_txrx(dev, txrx_len);
/* if cs is defined: software cs control, set active false */
if (config->cs.gpio.port != NULL) {
if (spi_cs_is_gpio(config)) {
spi_context_cs_control(&data->ctx, false);
}

View file

@ -75,7 +75,7 @@ static int spi_cc13xx_cc26xx_configure(const struct device *dev,
return -EINVAL;
}
if (config->operation & SPI_CS_ACTIVE_HIGH && config->cs.gpio.port == NULL) {
if (config->operation & SPI_CS_ACTIVE_HIGH && !spi_cs_is_gpio(config)) {
LOG_ERR("Active high CS requires emulation through a GPIO line.");
return -EINVAL;
}

View file

@ -236,7 +236,7 @@ static inline int spi_context_cs_configure_all(struct spi_context *ctx)
static inline void _spi_context_cs_control(struct spi_context *ctx,
bool on, bool force_off)
{
if (ctx->config && ctx->config->cs.gpio.port) {
if (ctx->config && spi_cs_is_gpio(ctx->config)) {
if (on) {
gpio_pin_set_dt(&ctx->config->cs.gpio, 1);
k_busy_wait(ctx->config->cs.delay);

View file

@ -147,7 +147,7 @@ static int spi_gd32_configure(const struct device *dev,
/* Reset to hardware NSS mode. */
SPI_CTL0(cfg->reg) &= ~SPI_CTL0_SWNSSEN;
if (config->cs.gpio.port != NULL) {
if (spi_cs_is_gpio(config)) {
SPI_CTL0(cfg->reg) |= SPI_CTL0_SWNSSEN;
} else {
/*

View file

@ -104,7 +104,7 @@ static inline int z_vrfy_spi_transceive(const struct device *dev,
}
memcpy(&config_copy, config, sizeof(*config));
if (config_copy.cs.gpio.port != NULL) {
if (spi_cs_is_gpio(&config_copy)) {
Z_OOPS(Z_SYSCALL_OBJ(config_copy.cs.gpio.port,
K_OBJ_DRIVER_GPIO));
}

View file

@ -541,7 +541,7 @@ static int spi_stm32_configure(const struct device *dev,
LL_SPI_DisableCRC(spi);
if (config->cs.gpio.port != NULL || !IS_ENABLED(CONFIG_SPI_STM32_USE_HW_SS)) {
if (spi_cs_is_gpio(config) || !IS_ENABLED(CONFIG_SPI_STM32_USE_HW_SS)) {
#if DT_HAS_COMPAT_STATUS_OKAY(st_stm32h7_spi)
if (SPI_OP_MODE_GET(config->operation) == SPI_OP_MODE_MASTER) {
if (LL_SPI_GetNSSPolarity(spi) == LL_SPI_NSS_POLARITY_LOW)

View file

@ -91,7 +91,7 @@ static int configure(const struct device *dev,
return -EINVAL;
}
if (spi_cfg->cs.gpio.port != NULL) {
if (spi_cs_is_gpio(spi_cfg)) {
LOG_ERR("CS control via GPIO is not supported");
return -EINVAL;
}

View file

@ -109,7 +109,7 @@ int spi_oc_simple_transceive(const struct device *dev,
spi_oc_simple_configure(info, spi, config);
/* Set chip select */
if (config->cs.gpio.port != NULL) {
if (spi_cs_is_gpio(config)) {
spi_context_cs_control(&spi->ctx, true);
} else {
sys_write8(1 << config->slave, SPI_OC_SIMPLE_SPSS(info));
@ -147,7 +147,7 @@ int spi_oc_simple_transceive(const struct device *dev,
}
/* Clear chip-select */
if (config->cs.gpio.port != NULL) {
if (spi_cs_is_gpio(config)) {
spi_context_cs_control(&spi->ctx, false);
} else {
sys_write8(0 << config->slave, SPI_OC_SIMPLE_SPSS(info));

View file

@ -549,7 +549,7 @@ static int spi_pw_configure(const struct device *dev,
/* At this point, it's mandatory to set this on the context! */
spi->ctx.config = config;
if (spi->ctx.config->cs.gpio.port == NULL) {
if (!spi_cs_is_gpio(spi->ctx.config)) {
if (spi->cs_mode == CS_GPIO_MODE) {
LOG_DBG("cs gpio is NULL, switch to hw mode");
spi->cs_mode = CS_HW_MODE;

View file

@ -216,7 +216,7 @@ static int spi_sifive_transceive(const struct device *dev,
* If the chip select configuration is not present, we'll ask the
* SPI peripheral itself to control the CS line
*/
if (config->cs.gpio.port == NULL) {
if (!spi_cs_is_gpio(config)) {
hw_cs_control = true;
}

View file

@ -486,6 +486,30 @@ __subsystem struct spi_driver_api {
spi_api_release release;
};
/**
* @brief Check if SPI CS is controlled using a GPIO.
*
* @param config SPI configuration.
* @return true If CS is controlled using a GPIO.
* @return false If CS is controlled by hardware or any other means.
*/
static inline bool spi_cs_is_gpio(const struct spi_config *config)
{
return config->cs.gpio.port != NULL;
}
/**
* @brief Check if SPI CS in @ref spi_dt_spec is controlled using a GPIO.
*
* @param spec SPI specification from devicetree.
* @return true If CS is controlled using a GPIO.
* @return false If CS is controlled by hardware or any other means.
*/
static inline bool spi_cs_is_gpio_dt(const struct spi_dt_spec *spec)
{
return spi_cs_is_gpio(&spec->config);
}
/**
* @brief Validate that SPI bus is ready.
*
@ -502,7 +526,7 @@ static inline bool spi_is_ready(const struct spi_dt_spec *spec)
return false;
}
/* Validate CS gpio port is ready, if it is used */
if (spec->config.cs.gpio.port != NULL &&
if (spi_cs_is_gpio_dt(spec) &&
!device_is_ready(spec->config.cs.gpio.port)) {
return false;
}
@ -524,7 +548,7 @@ static inline bool spi_is_ready_dt(const struct spi_dt_spec *spec)
return false;
}
/* Validate CS gpio port is ready, if it is used */
if (spec->config.cs.gpio.port != NULL &&
if (spi_cs_is_gpio_dt(spec) &&
!device_is_ready(spec->config.cs.gpio.port)) {
return false;
}

View file

@ -22,6 +22,7 @@ ZTEST(spi_dt_spec, test_dt_spec)
LOG_DBG("spi_cs.config.cs.gpio.pin = %u", spi_cs.config.cs.gpio.pin);
zassert_equal(spi_cs.bus, DEVICE_DT_GET(DT_NODELABEL(test_spi_cs)), "");
zassert_true(spi_cs_is_gpio_dt(&spi_cs), "");
zassert_equal(spi_cs.config.cs.gpio.port, DEVICE_DT_GET(DT_NODELABEL(test_gpio)), "");
zassert_equal(spi_cs.config.cs.gpio.pin, 0x10, "");
@ -32,7 +33,7 @@ ZTEST(spi_dt_spec, test_dt_spec)
LOG_DBG("spi_no_cs.config.cs.gpio.port = %p", spi_no_cs.config.cs.gpio.port);
zassert_equal(spi_no_cs.bus, DEVICE_DT_GET(DT_NODELABEL(test_spi_no_cs)), "");
zassert_is_null(spi_no_cs.config.cs.gpio.port, "");
zassert_false(spi_cs_is_gpio_dt(&spi_no_cs), "");
}
ZTEST_SUITE(spi_dt_spec, NULL, NULL, NULL, NULL, NULL);