Skip to content

Commit

Permalink
drivers: spi: esp32: Continue configuration if SPI clock already running
Browse files Browse the repository at this point in the history
When clock_control_on returns -EALREADY we can continue with SPI
configuration because clock is already running.

Signed-off-by: Tomáš Juřena <[email protected]>
  • Loading branch information
jurenat committed May 30, 2024
1 parent 518a712 commit 856f706
Showing 1 changed file with 55 additions and 75 deletions.
130 changes: 55 additions & 75 deletions drivers/spi/spi_esp32_spim.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,7 @@ static bool spi_esp32_transfer_ongoing(struct spi_esp32_data *data)
return spi_context_tx_on(&data->ctx) || spi_context_rx_on(&data->ctx);
}

static inline void spi_esp32_complete(const struct device *dev,
struct spi_esp32_data *data,
static inline void spi_esp32_complete(const struct device *dev, struct spi_esp32_data *data,
spi_dev_t *spi, int status)
{
#ifdef CONFIG_SPI_ESP32_INTERRUPT
Expand All @@ -57,7 +56,6 @@ static inline void spi_esp32_complete(const struct device *dev,
#ifdef CONFIG_SPI_ESP32_INTERRUPT
spi_context_complete(&data->ctx, dev, status);
#endif

}

static int IRAM_ATTR spi_esp32_transfer(const struct device *dev)
Expand Down Expand Up @@ -226,11 +224,8 @@ static int spi_esp32_init(const struct device *dev)
}

#ifdef CONFIG_SPI_ESP32_INTERRUPT
data->irq_line = esp_intr_alloc(cfg->irq_source,
0,
(ISR_HANDLER)spi_esp32_isr,
(void *)dev,
NULL);
data->irq_line =
esp_intr_alloc(cfg->irq_source, 0, (ISR_HANDLER)spi_esp32_isr, (void *)dev, NULL);
#endif

err = spi_context_cs_configure_all(&data->ctx);
Expand Down Expand Up @@ -270,8 +265,7 @@ static inline uint8_t spi_esp32_get_line_mode(uint16_t operation)
return 1;
}

static int IRAM_ATTR spi_esp32_configure(const struct device *dev,
const struct spi_config *spi_cfg)
static int IRAM_ATTR spi_esp32_configure(const struct device *dev, const struct spi_config *spi_cfg)
{
const struct spi_esp32_config *cfg = dev->config;
struct spi_esp32_data *data = dev->data;
Expand All @@ -280,6 +274,7 @@ static int IRAM_ATTR spi_esp32_configure(const struct device *dev,
spi_hal_dev_config_t *hal_dev = &data->dev_config;
spi_dev_t *hw = hal->hw;
int freq;
int res;

if (spi_context_configured(ctx, spi_cfg)) {
return 0;
Expand All @@ -291,7 +286,8 @@ static int IRAM_ATTR spi_esp32_configure(const struct device *dev,
}

/* enables SPI peripheral */
if (clock_control_on(cfg->clock_dev, cfg->clock_subsys)) {
res = clock_control_on(cfg->clock_dev, cfg->clock_subsys);
if (res != 0 && res != -EALREADY) {
LOG_ERR("Could not enable SPI clock");
return -EIO;
}
Expand Down Expand Up @@ -396,12 +392,9 @@ static inline uint8_t spi_esp32_get_frame_size(const struct spi_config *spi_cfg)
return dfs;
}

static int transceive(const struct device *dev,
const struct spi_config *spi_cfg,
const struct spi_buf_set *tx_bufs,
const struct spi_buf_set *rx_bufs, bool asynchronous,
spi_callback_t cb,
void *userdata)
static int transceive(const struct device *dev, const struct spi_config *spi_cfg,
const struct spi_buf_set *tx_bufs, const struct spi_buf_set *rx_bufs,
bool asynchronous, spi_callback_t cb, void *userdata)
{
const struct spi_esp32_config *cfg = dev->config;
struct spi_esp32_data *data = dev->data;
Expand Down Expand Up @@ -441,36 +434,32 @@ static int transceive(const struct device *dev,

spi_esp32_complete(dev, data, cfg->spi, 0);

#endif /* CONFIG_SPI_ESP32_INTERRUPT */
#endif /* CONFIG_SPI_ESP32_INTERRUPT */

done:
spi_context_release(&data->ctx, ret);

return ret;
}

static int spi_esp32_transceive(const struct device *dev,
const struct spi_config *spi_cfg,
static int spi_esp32_transceive(const struct device *dev, const struct spi_config *spi_cfg,
const struct spi_buf_set *tx_bufs,
const struct spi_buf_set *rx_bufs)
{
return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL);
}

#ifdef CONFIG_SPI_ASYNC
static int spi_esp32_transceive_async(const struct device *dev,
const struct spi_config *spi_cfg,
static int spi_esp32_transceive_async(const struct device *dev, const struct spi_config *spi_cfg,
const struct spi_buf_set *tx_bufs,
const struct spi_buf_set *rx_bufs,
spi_callback_t cb,
const struct spi_buf_set *rx_bufs, spi_callback_t cb,
void *userdata)
{
return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata);
}
#endif /* CONFIG_SPI_ASYNC */

static int spi_esp32_release(const struct device *dev,
const struct spi_config *config)
static int spi_esp32_release(const struct device *dev, const struct spi_config *config)
{
struct spi_esp32_data *data = dev->data;

Expand All @@ -479,63 +468,54 @@ static int spi_esp32_release(const struct device *dev,
return 0;
}

static const struct spi_driver_api spi_api = {
.transceive = spi_esp32_transceive,
static const struct spi_driver_api spi_api = {.transceive = spi_esp32_transceive,
#ifdef CONFIG_SPI_ASYNC
.transceive_async = spi_esp32_transceive_async,
.transceive_async = spi_esp32_transceive_async,
#endif
.release = spi_esp32_release
};
.release = spi_esp32_release};

#ifdef CONFIG_SOC_SERIES_ESP32
#define GET_AS_CS(idx) .as_cs = DT_INST_PROP(idx, clk_as_cs),
#else
#define GET_AS_CS(idx)
#endif

#define ESP32_SPI_INIT(idx) \
\
PINCTRL_DT_INST_DEFINE(idx); \
\
static struct spi_esp32_data spi_data_##idx = { \
SPI_CONTEXT_INIT_LOCK(spi_data_##idx, ctx), \
SPI_CONTEXT_INIT_SYNC(spi_data_##idx, ctx), \
SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(idx), ctx) \
.hal = { \
.hw = (spi_dev_t *)DT_INST_REG_ADDR(idx), \
}, \
.dev_config = { \
.half_duplex = DT_INST_PROP(idx, half_duplex), \
GET_AS_CS(idx) \
.positive_cs = DT_INST_PROP(idx, positive_cs), \
.no_compensate = DT_INST_PROP(idx, dummy_comp), \
.sio = DT_INST_PROP(idx, sio) \
} \
}; \
\
static const struct spi_esp32_config spi_config_##idx = { \
.spi = (spi_dev_t *)DT_INST_REG_ADDR(idx), \
\
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \
.duty_cycle = 0, \
.input_delay_ns = 0, \
.irq_source = DT_INST_IRQN(idx), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \
.clock_subsys = \
(clock_control_subsys_t)DT_INST_CLOCKS_CELL(idx, offset), \
.use_iomux = DT_INST_PROP(idx, use_iomux), \
.dma_enabled = DT_INST_PROP(idx, dma_enabled), \
.dma_clk_src = DT_INST_PROP(idx, dma_clk), \
.dma_host = DT_INST_PROP(idx, dma_host), \
.cs_setup = DT_INST_PROP_OR(idx, cs_setup_time, 0), \
.cs_hold = DT_INST_PROP_OR(idx, cs_hold_time, 0), \
.line_idle_low = DT_INST_PROP(idx, line_idle_low), \
.clock_source = SPI_CLK_SRC_DEFAULT, \
}; \
\
DEVICE_DT_INST_DEFINE(idx, &spi_esp32_init, \
NULL, &spi_data_##idx, \
&spi_config_##idx, POST_KERNEL, \
CONFIG_SPI_INIT_PRIORITY, &spi_api);
#define ESP32_SPI_INIT(idx) \
\
PINCTRL_DT_INST_DEFINE(idx); \
\
static struct spi_esp32_data spi_data_##idx = { \
SPI_CONTEXT_INIT_LOCK(spi_data_##idx, ctx), \
SPI_CONTEXT_INIT_SYNC(spi_data_##idx, ctx), \
SPI_CONTEXT_CS_GPIOS_INITIALIZE(DT_DRV_INST(idx), ctx).hal = \
{ \
.hw = (spi_dev_t *)DT_INST_REG_ADDR(idx), \
}, \
.dev_config = {.half_duplex = DT_INST_PROP(idx, half_duplex), \
GET_AS_CS(idx).positive_cs = DT_INST_PROP(idx, positive_cs), \
.no_compensate = DT_INST_PROP(idx, dummy_comp), \
.sio = DT_INST_PROP(idx, sio)}}; \
\
static const struct spi_esp32_config spi_config_##idx = { \
.spi = (spi_dev_t *)DT_INST_REG_ADDR(idx), \
\
.clock_dev = DEVICE_DT_GET(DT_INST_CLOCKS_CTLR(idx)), \
.duty_cycle = 0, \
.input_delay_ns = 0, \
.irq_source = DT_INST_IRQN(idx), \
.pcfg = PINCTRL_DT_INST_DEV_CONFIG_GET(idx), \
.clock_subsys = (clock_control_subsys_t)DT_INST_CLOCKS_CELL(idx, offset), \
.use_iomux = DT_INST_PROP(idx, use_iomux), \
.dma_enabled = DT_INST_PROP(idx, dma_enabled), \
.dma_clk_src = DT_INST_PROP(idx, dma_clk), \
.dma_host = DT_INST_PROP(idx, dma_host), \
.cs_setup = DT_INST_PROP_OR(idx, cs_setup_time, 0), \
.cs_hold = DT_INST_PROP_OR(idx, cs_hold_time, 0), \
.line_idle_low = DT_INST_PROP(idx, line_idle_low), \
.clock_source = SPI_CLK_SRC_DEFAULT, \
}; \
\
DEVICE_DT_INST_DEFINE(idx, &spi_esp32_init, NULL, &spi_data_##idx, &spi_config_##idx, \
POST_KERNEL, CONFIG_SPI_INIT_PRIORITY, &spi_api);

DT_INST_FOREACH_STATUS_OKAY(ESP32_SPI_INIT)

0 comments on commit 856f706

Please sign in to comment.