Skip to content

Commit

Permalink
drivers: spi: add spi_cs_is_gpio(_dt) helpers
Browse files Browse the repository at this point in the history
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 <[email protected]>
  • Loading branch information
gmarull authored and carlescufi committed Apr 24, 2023
1 parent 3f2c2d4 commit 1e0028a
Show file tree
Hide file tree
Showing 12 changed files with 41 additions and 16 deletions.
6 changes: 3 additions & 3 deletions drivers/spi/spi_b91.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -397,15 +397,15 @@ 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);
}

/* transceive data */
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);
}

Expand Down
2 changes: 1 addition & 1 deletion drivers/spi/spi_cc13xx_cc26xx.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/spi/spi_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion drivers/spi/spi_gd32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
/*
Expand Down
2 changes: 1 addition & 1 deletion drivers/spi/spi_handlers.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
2 changes: 1 addition & 1 deletion drivers/spi/spi_ll_stm32.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion drivers/spi/spi_nrfx_spis.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
4 changes: 2 additions & 2 deletions drivers/spi/spi_oc_simple.c
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand Down Expand Up @@ -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));
Expand Down
2 changes: 1 addition & 1 deletion drivers/spi/spi_pw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion drivers/spi/spi_sifive.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

Expand Down
28 changes: 26 additions & 2 deletions include/zephyr/drivers/spi.h
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
Expand All @@ -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;
}
Expand All @@ -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;
}
Expand Down
3 changes: 2 additions & 1 deletion tests/drivers/spi/dt_spec/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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, "");

Expand All @@ -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);

0 comments on commit 1e0028a

Please sign in to comment.