From 1e0028ae3d1d43a8ca906e7cfd6c89bd15a4ade1 Mon Sep 17 00:00:00 2001 From: Gerard Marull-Paretas Date: Wed, 19 Apr 2023 11:11:38 +0200 Subject: [PATCH] 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 --- drivers/spi/spi_b91.c | 6 +++--- drivers/spi/spi_cc13xx_cc26xx.c | 2 +- drivers/spi/spi_context.h | 2 +- drivers/spi/spi_gd32.c | 2 +- drivers/spi/spi_handlers.c | 2 +- drivers/spi/spi_ll_stm32.c | 2 +- drivers/spi/spi_nrfx_spis.c | 2 +- drivers/spi/spi_oc_simple.c | 4 ++-- drivers/spi/spi_pw.c | 2 +- drivers/spi/spi_sifive.c | 2 +- include/zephyr/drivers/spi.h | 28 ++++++++++++++++++++++++++-- tests/drivers/spi/dt_spec/src/main.c | 3 ++- 12 files changed, 41 insertions(+), 16 deletions(-) diff --git a/drivers/spi/spi_b91.c b/drivers/spi/spi_b91.c index c064b93a2b00ca..bdc580a521f90b 100644 --- a/drivers/spi/spi_b91.c +++ b/drivers/spi/spi_b91.c @@ -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); } diff --git a/drivers/spi/spi_cc13xx_cc26xx.c b/drivers/spi/spi_cc13xx_cc26xx.c index 61b513b1889ac3..151196d7798aeb 100644 --- a/drivers/spi/spi_cc13xx_cc26xx.c +++ b/drivers/spi/spi_cc13xx_cc26xx.c @@ -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; } diff --git a/drivers/spi/spi_context.h b/drivers/spi/spi_context.h index d1d8b9d4a55ece..1aed41173eecc1 100644 --- a/drivers/spi/spi_context.h +++ b/drivers/spi/spi_context.h @@ -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); diff --git a/drivers/spi/spi_gd32.c b/drivers/spi/spi_gd32.c index 622b87bdc1732d..7f9ecaf90fb77a 100644 --- a/drivers/spi/spi_gd32.c +++ b/drivers/spi/spi_gd32.c @@ -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 { /* diff --git a/drivers/spi/spi_handlers.c b/drivers/spi/spi_handlers.c index 338589033e24b1..7793d6b8a3a9ea 100644 --- a/drivers/spi/spi_handlers.c +++ b/drivers/spi/spi_handlers.c @@ -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)); } diff --git a/drivers/spi/spi_ll_stm32.c b/drivers/spi/spi_ll_stm32.c index fc3a9c3913b06f..cf5f28e824e0d1 100644 --- a/drivers/spi/spi_ll_stm32.c +++ b/drivers/spi/spi_ll_stm32.c @@ -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) diff --git a/drivers/spi/spi_nrfx_spis.c b/drivers/spi/spi_nrfx_spis.c index 328870118dad62..27dcc76fbd3dc0 100644 --- a/drivers/spi/spi_nrfx_spis.c +++ b/drivers/spi/spi_nrfx_spis.c @@ -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; } diff --git a/drivers/spi/spi_oc_simple.c b/drivers/spi/spi_oc_simple.c index 13b35d91d822ce..3b8f9c126cfdc7 100644 --- a/drivers/spi/spi_oc_simple.c +++ b/drivers/spi/spi_oc_simple.c @@ -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)); diff --git a/drivers/spi/spi_pw.c b/drivers/spi/spi_pw.c index a729d3687c8c3c..e6f4061c6e225d 100644 --- a/drivers/spi/spi_pw.c +++ b/drivers/spi/spi_pw.c @@ -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; diff --git a/drivers/spi/spi_sifive.c b/drivers/spi/spi_sifive.c index 2206adf9caedd6..c302e67ba80c57 100644 --- a/drivers/spi/spi_sifive.c +++ b/drivers/spi/spi_sifive.c @@ -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; } diff --git a/include/zephyr/drivers/spi.h b/include/zephyr/drivers/spi.h index d915d4ab815b62..cfd9aa6e537a6a 100644 --- a/include/zephyr/drivers/spi.h +++ b/include/zephyr/drivers/spi.h @@ -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; } diff --git a/tests/drivers/spi/dt_spec/src/main.c b/tests/drivers/spi/dt_spec/src/main.c index 450d670f8c6a18..f3affa887a9bc6 100644 --- a/tests/drivers/spi/dt_spec/src/main.c +++ b/tests/drivers/spi/dt_spec/src/main.c @@ -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);