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:
parent
3f2c2d4130
commit
1e0028ae3d
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
/*
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue