Lines Matching +full:spi +full:- +full:dev
2 * Copyright (c) 2017 - 2018, Nordic Semiconductor ASA
4 * SPDX-License-Identifier: Apache-2.0
7 #include <zephyr/drivers/spi.h>
8 #include <zephyr/drivers/spi/rtio.h>
23 const struct device *dev; member
30 nrfx_spi_t spi; member
87 static int configure(const struct device *dev, in configure() argument
90 struct spi_nrfx_data *dev_data = dev->data; in configure()
91 const struct spi_nrfx_config *dev_config = dev->config; in configure()
92 struct spi_context *ctx = &dev_data->ctx; in configure()
96 if (dev_data->initialized && spi_context_configured(ctx, spi_cfg)) { in configure()
101 if (spi_cfg->operation & SPI_HALF_DUPLEX) { in configure()
102 LOG_ERR("Half-duplex not supported"); in configure()
103 return -ENOTSUP; in configure()
106 if (SPI_OP_MODE_GET(spi_cfg->operation) != SPI_OP_MODE_MASTER) { in configure()
107 LOG_ERR("Slave mode is not supported on %s", dev->name); in configure()
108 return -EINVAL; in configure()
111 if (spi_cfg->operation & SPI_MODE_LOOP) { in configure()
113 return -EINVAL; in configure()
117 (spi_cfg->operation & SPI_LINES_MASK) != SPI_LINES_SINGLE) { in configure()
119 return -EINVAL; in configure()
122 if (SPI_WORD_SIZE_GET(spi_cfg->operation) != 8) { in configure()
124 return -EINVAL; in configure()
127 if (spi_cfg->frequency < 125000) { in configure()
129 return -EINVAL; in configure()
132 config = dev_config->def_config; in configure()
134 config.frequency = get_nrf_spi_frequency(spi_cfg->frequency); in configure()
135 config.mode = get_nrf_spi_mode(spi_cfg->operation); in configure()
136 config.bit_order = get_nrf_spi_bit_order(spi_cfg->operation); in configure()
138 nrf_gpio_pin_write(nrf_spi_sck_pin_get(dev_config->spi.p_reg), in configure()
139 spi_cfg->operation & SPI_MODE_CPOL ? 1 : 0); in configure()
141 if (dev_data->initialized) { in configure()
142 nrfx_spi_uninit(&dev_config->spi); in configure()
143 dev_data->initialized = false; in configure()
146 result = nrfx_spi_init(&dev_config->spi, &config, in configure()
150 return -EIO; in configure()
153 dev_data->initialized = true; in configure()
155 ctx->config = spi_cfg; in configure()
160 static void finish_transaction(const struct device *dev, int error) in finish_transaction() argument
162 struct spi_nrfx_data *dev_data = dev->data; in finish_transaction()
163 struct spi_context *ctx = &dev_data->ctx; in finish_transaction()
167 spi_context_complete(ctx, dev, error); in finish_transaction()
168 dev_data->busy = false; in finish_transaction()
171 static void transfer_next_chunk(const struct device *dev) in transfer_next_chunk() argument
173 const struct spi_nrfx_config *dev_config = dev->config; in transfer_next_chunk()
174 struct spi_nrfx_data *dev_data = dev->data; in transfer_next_chunk()
175 struct spi_context *ctx = &dev_data->ctx; in transfer_next_chunk()
184 dev_data->chunk_len = chunk_len; in transfer_next_chunk()
186 xfer.p_tx_buffer = ctx->tx_buf; in transfer_next_chunk()
188 xfer.p_rx_buffer = ctx->rx_buf; in transfer_next_chunk()
190 result = nrfx_spi_xfer(&dev_config->spi, &xfer, 0); in transfer_next_chunk()
195 error = -EIO; in transfer_next_chunk()
198 finish_transaction(dev, error); in transfer_next_chunk()
205 if (p_event->type == NRFX_SPI_EVENT_DONE) { in event_handler()
209 if (dev_data->chunk_len == 0) { in event_handler()
210 finish_transaction(dev_data->dev, -ETIMEDOUT); in event_handler()
214 spi_context_update_tx(&dev_data->ctx, 1, dev_data->chunk_len); in event_handler()
215 spi_context_update_rx(&dev_data->ctx, 1, dev_data->chunk_len); in event_handler()
217 transfer_next_chunk(dev_data->dev); in event_handler()
221 static int transceive(const struct device *dev, in transceive() argument
229 struct spi_nrfx_data *dev_data = dev->data; in transceive()
230 const struct spi_nrfx_config *dev_config = dev->config; in transceive()
233 spi_context_lock(&dev_data->ctx, asynchronous, cb, userdata, spi_cfg); in transceive()
235 error = configure(dev, spi_cfg); in transceive()
237 dev_data->busy = true; in transceive()
239 if (dev_config->wake_pin != WAKE_PIN_NOT_USED) { in transceive()
240 error = spi_nrfx_wake_request(&dev_config->wake_gpiote, in transceive()
241 dev_config->wake_pin); in transceive()
242 if (error == -ETIMEDOUT) { in transceive()
252 spi_context_buffers_setup(&dev_data->ctx, tx_bufs, rx_bufs, 1); in transceive()
253 spi_context_cs_control(&dev_data->ctx, true); in transceive()
255 transfer_next_chunk(dev); in transceive()
257 error = spi_context_wait_for_completion(&dev_data->ctx); in transceive()
258 if (error == -ETIMEDOUT) { in transceive()
263 dev_data->chunk_len = 0; in transceive()
267 nrfx_spi_uninit(&dev_config->spi); in transceive()
268 dev_data->initialized = false; in transceive()
274 finish_transaction(dev, -ETIMEDOUT); in transceive()
277 k_sem_reset(&dev_data->ctx.sync); in transceive()
280 spi_context_cs_control(&dev_data->ctx, false); in transceive()
283 spi_context_release(&dev_data->ctx, error); in transceive()
288 static int spi_nrfx_transceive(const struct device *dev, in spi_nrfx_transceive() argument
293 return transceive(dev, spi_cfg, tx_bufs, rx_bufs, false, NULL, NULL); in spi_nrfx_transceive()
297 static int spi_nrfx_transceive_async(const struct device *dev, in spi_nrfx_transceive_async() argument
304 return transceive(dev, spi_cfg, tx_bufs, rx_bufs, true, cb, userdata); in spi_nrfx_transceive_async()
308 static int spi_nrfx_release(const struct device *dev, in spi_nrfx_release() argument
311 struct spi_nrfx_data *dev_data = dev->data; in spi_nrfx_release()
313 if (!spi_context_configured(&dev_data->ctx, spi_cfg)) { in spi_nrfx_release()
314 return -EINVAL; in spi_nrfx_release()
317 if (dev_data->busy) { in spi_nrfx_release()
318 return -EBUSY; in spi_nrfx_release()
321 spi_context_unlock_unconditionally(&dev_data->ctx); in spi_nrfx_release()
326 static DEVICE_API(spi, spi_nrfx_driver_api) = {
338 static int spi_nrfx_pm_action(const struct device *dev, in spi_nrfx_pm_action() argument
342 struct spi_nrfx_data *dev_data = dev->data; in spi_nrfx_pm_action()
343 const struct spi_nrfx_config *dev_config = dev->config; in spi_nrfx_pm_action()
347 ret = pinctrl_apply_state(dev_config->pcfg, in spi_nrfx_pm_action()
358 if (dev_data->initialized) { in spi_nrfx_pm_action()
359 nrfx_spi_uninit(&dev_config->spi); in spi_nrfx_pm_action()
360 dev_data->initialized = false; in spi_nrfx_pm_action()
363 ret = pinctrl_apply_state(dev_config->pcfg, in spi_nrfx_pm_action()
371 ret = -ENOTSUP; in spi_nrfx_pm_action()
378 static int spi_nrfx_init(const struct device *dev) in spi_nrfx_init() argument
380 const struct spi_nrfx_config *dev_config = dev->config; in spi_nrfx_init()
381 struct spi_nrfx_data *dev_data = dev->data; in spi_nrfx_init()
384 err = pinctrl_apply_state(dev_config->pcfg, PINCTRL_STATE_DEFAULT); in spi_nrfx_init()
389 if (dev_config->wake_pin != WAKE_PIN_NOT_USED) { in spi_nrfx_init()
390 err = spi_nrfx_wake_init(&dev_config->wake_gpiote, dev_config->wake_pin); in spi_nrfx_init()
391 if (err == -ENODEV) { in spi_nrfx_init()
395 if (err == -EIO) { in spi_nrfx_init()
401 dev_config->irq_connect(); in spi_nrfx_init()
403 err = spi_context_cs_configure_all(&dev_data->ctx); in spi_nrfx_init()
408 spi_context_unlock_unconditionally(&dev_data->ctx); in spi_nrfx_init()
416 * - HAL design (requirement of drv_inst_idx in nrfx_spi_t)
417 * - Name-based HAL IRQ handlers, e.g. nrfx_spi_0_irq_handler
420 #define SPI(idx) DT_NODELABEL(spi##idx) macro
421 #define SPI_PROP(idx, prop) DT_PROP(SPI(idx), prop)
424 NRF_DT_CHECK_NODE_HAS_PINCTRL_SLEEP(SPI(idx)); \
427 IRQ_CONNECT(DT_IRQN(SPI(idx)), DT_IRQ(SPI(idx), priority), \
433 SPI_CONTEXT_CS_GPIOS_INITIALIZE(SPI(idx), ctx) \
434 .dev = DEVICE_DT_GET(SPI(idx)), \
437 PINCTRL_DT_DEFINE(SPI(idx)); \
439 .spi = { \
440 .p_reg = (NRF_SPI_Type *)DT_REG_ADDR(SPI(idx)), \
450 .pcfg = PINCTRL_DT_DEV_CONFIG_GET(SPI(idx)), \
451 .wake_pin = NRF_DT_GPIOS_TO_PSEL_OR(SPI(idx), wake_gpios, \
453 .wake_gpiote = WAKE_GPIOTE_INSTANCE(SPI(idx)), \
455 BUILD_ASSERT(!DT_NODE_HAS_PROP(SPI(idx), wake_gpios) || \
456 !(DT_GPIO_FLAGS(SPI(idx), wake_gpios) & GPIO_ACTIVE_LOW), \
458 PM_DEVICE_DT_DEFINE(SPI(idx), spi_nrfx_pm_action); \
459 SPI_DEVICE_DT_DEFINE(SPI(idx), \
461 PM_DEVICE_DT_GET(SPI(idx)), \