1 /*
2 * Copyright (c) 2015 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Public API for SPI drivers and applications
10 */
11
12 #ifndef ZEPHYR_INCLUDE_DRIVERS_SPI_H_
13 #define ZEPHYR_INCLUDE_DRIVERS_SPI_H_
14
15 /**
16 * @brief SPI Interface
17 * @defgroup spi_interface SPI Interface
18 * @ingroup io_interfaces
19 * @{
20 */
21
22 #include <zephyr/types.h>
23 #include <stddef.h>
24 #include <zephyr/device.h>
25 #include <zephyr/dt-bindings/spi/spi.h>
26 #include <zephyr/drivers/gpio.h>
27 #include <zephyr/kernel.h>
28 #include <zephyr/sys/__assert.h>
29 #include <zephyr/rtio/rtio.h>
30 #include <zephyr/stats/stats.h>
31
32 #ifdef __cplusplus
33 extern "C" {
34 #endif
35
36 /**
37 * @name SPI operational mode
38 * @{
39 */
40 #define SPI_OP_MODE_MASTER 0U /**< Master mode. */
41 #define SPI_OP_MODE_SLAVE BIT(0) /**< Slave mode. */
42 /** @cond INTERNAL_HIDDEN */
43 #define SPI_OP_MODE_MASK 0x1U
44 /** @endcond */
45 /** Get SPI operational mode. */
46 #define SPI_OP_MODE_GET(_operation_) ((_operation_) & SPI_OP_MODE_MASK)
47 /** @} */
48
49 /**
50 * @name SPI Polarity & Phase Modes
51 * @{
52 */
53
54 /**
55 * Clock Polarity: if set, clock idle state will be 1
56 * and active state will be 0. If untouched, the inverse will be true
57 * which is the default.
58 */
59 #define SPI_MODE_CPOL BIT(1)
60
61 /**
62 * Clock Phase: this dictates when is the data captured, and depends
63 * clock's polarity. When SPI_MODE_CPOL is set and this bit as well,
64 * capture will occur on low to high transition and high to low if
65 * this bit is not set (default). This is fully reversed if CPOL is
66 * not set.
67 */
68 #define SPI_MODE_CPHA BIT(2)
69
70 /**
71 * Whatever data is transmitted is looped-back to the receiving buffer of
72 * the controller. This is fully controller dependent as some may not
73 * support this, and can be used for testing purposes only.
74 */
75 #define SPI_MODE_LOOP BIT(3)
76 /** @cond INTERNAL_HIDDEN */
77 #define SPI_MODE_MASK (0xEU)
78 /** @endcond */
79 /** Get SPI polarity and phase mode bits. */
80 #define SPI_MODE_GET(_mode_) \
81 ((_mode_) & SPI_MODE_MASK)
82
83 /** @} */
84
85 /**
86 * @name SPI Transfer modes (host controller dependent)
87 * @{
88 */
89 #define SPI_TRANSFER_MSB (0U) /**< Most significant bit first. */
90 #define SPI_TRANSFER_LSB BIT(4) /**< Least significant bit first. */
91 /** @} */
92
93 /**
94 * @name SPI word size
95 * @{
96 */
97 /** @cond INTERNAL_HIDDEN */
98 #define SPI_WORD_SIZE_SHIFT (5U)
99 #define SPI_WORD_SIZE_MASK (0x3FU << SPI_WORD_SIZE_SHIFT)
100 /** @endcond */
101 /** Get SPI word size. */
102 #define SPI_WORD_SIZE_GET(_operation_) \
103 (((_operation_) & SPI_WORD_SIZE_MASK) >> SPI_WORD_SIZE_SHIFT)
104 /** Set SPI word size. */
105 #define SPI_WORD_SET(_word_size_) \
106 ((_word_size_) << SPI_WORD_SIZE_SHIFT)
107 /** @} */
108
109 /**
110 * @name Specific SPI devices control bits
111 * @{
112 */
113 /** Requests - if possible - to keep CS asserted after the transaction */
114 #define SPI_HOLD_ON_CS BIT(12)
115 /** Keep the device locked after the transaction for the current config.
116 * Use this with extreme caution (see spi_release() below) as it will
117 * prevent other callers to access the SPI device until spi_release() is
118 * properly called.
119 */
120 #define SPI_LOCK_ON BIT(13)
121
122 /** Active high logic on CS. Usually, and by default, CS logic is active
123 * low. However, some devices may require the reverse logic: active high.
124 * This bit will request the controller to use that logic. Note that not
125 * all controllers are able to handle that natively. In this case deferring
126 * the CS control to a gpio line through struct spi_cs_control would be
127 * the solution.
128 */
129 #define SPI_CS_ACTIVE_HIGH BIT(14)
130 /** @} */
131
132 /**
133 * @name SPI MISO lines
134 * @{
135 *
136 * Some controllers support dual, quad or octal MISO lines connected to slaves.
137 * Default is single, which is the case most of the time.
138 * Without @kconfig{CONFIG_SPI_EXTENDED_MODES} being enabled, single is the
139 * only supported one.
140 */
141 #define SPI_LINES_SINGLE (0U << 16) /**< Single line */
142 #define SPI_LINES_DUAL (1U << 16) /**< Dual lines */
143 #define SPI_LINES_QUAD (2U << 16) /**< Quad lines */
144 #define SPI_LINES_OCTAL (3U << 16) /**< Octal lines */
145
146 #define SPI_LINES_MASK (0x3U << 16) /**< Mask for MISO lines in spi_operation_t */
147
148 /** @} */
149
150 /**
151 * @brief SPI Chip Select control structure
152 *
153 * This can be used to control a CS line via a GPIO line, instead of
154 * using the controller inner CS logic.
155 *
156 */
157 struct spi_cs_control {
158 /**
159 * GPIO devicetree specification of CS GPIO.
160 * The device pointer can be set to NULL to fully inhibit CS control if
161 * necessary. The GPIO flags GPIO_ACTIVE_LOW/GPIO_ACTIVE_HIGH should be
162 * equivalent to SPI_CS_ACTIVE_HIGH/SPI_CS_ACTIVE_LOW options in struct
163 * spi_config.
164 */
165 struct gpio_dt_spec gpio;
166 /**
167 * Delay in microseconds to wait before starting the
168 * transmission and before releasing the CS line.
169 */
170 uint32_t delay;
171 };
172
173 /**
174 * @brief Get a <tt>struct gpio_dt_spec</tt> for a SPI device's chip select pin
175 *
176 * Example devicetree fragment:
177 *
178 * @code{.devicetree}
179 * gpio1: gpio@abcd0001 { ... };
180 *
181 * gpio2: gpio@abcd0002 { ... };
182 *
183 * spi@abcd0003 {
184 * compatible = "vnd,spi";
185 * cs-gpios = <&gpio1 10 GPIO_ACTIVE_LOW>,
186 * <&gpio2 20 GPIO_ACTIVE_LOW>;
187 *
188 * a: spi-dev-a@0 {
189 * reg = <0>;
190 * };
191 *
192 * b: spi-dev-b@1 {
193 * reg = <1>;
194 * };
195 * };
196 * @endcode
197 *
198 * Example usage:
199 *
200 * @code{.c}
201 * SPI_CS_GPIOS_DT_SPEC_GET(DT_NODELABEL(a)) \
202 * // { DEVICE_DT_GET(DT_NODELABEL(gpio1)), 10, GPIO_ACTIVE_LOW }
203 * SPI_CS_GPIOS_DT_SPEC_GET(DT_NODELABEL(b)) \
204 * // { DEVICE_DT_GET(DT_NODELABEL(gpio2)), 20, GPIO_ACTIVE_LOW }
205 * @endcode
206 *
207 * @param spi_dev a SPI device node identifier
208 * @return #gpio_dt_spec struct corresponding with spi_dev's chip select
209 */
210 #define SPI_CS_GPIOS_DT_SPEC_GET(spi_dev) \
211 GPIO_DT_SPEC_GET_BY_IDX_OR(DT_BUS(spi_dev), cs_gpios, \
212 DT_REG_ADDR(spi_dev), {})
213
214 /**
215 * @brief Get a <tt>struct gpio_dt_spec</tt> for a SPI device's chip select pin
216 *
217 * This is equivalent to
218 * <tt>SPI_CS_GPIOS_DT_SPEC_GET(DT_DRV_INST(inst))</tt>.
219 *
220 * @param inst Devicetree instance number
221 * @return #gpio_dt_spec struct corresponding with spi_dev's chip select
222 */
223 #define SPI_CS_GPIOS_DT_SPEC_INST_GET(inst) \
224 SPI_CS_GPIOS_DT_SPEC_GET(DT_DRV_INST(inst))
225
226 /**
227 * @brief Initialize and get a pointer to a @p spi_cs_control from a
228 * devicetree node identifier
229 *
230 * This helper is useful for initializing a device on a SPI bus. It
231 * initializes a struct spi_cs_control and returns a pointer to it.
232 * Here, @p node_id is a node identifier for a SPI device, not a SPI
233 * controller.
234 *
235 * Example devicetree fragment:
236 *
237 * @code{.devicetree}
238 * spi@abcd0001 {
239 * cs-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
240 * spidev: spi-device@0 { ... };
241 * };
242 * @endcode
243 *
244 * Example usage:
245 *
246 * @code{.c}
247 * struct spi_cs_control ctrl =
248 * SPI_CS_CONTROL_INIT(DT_NODELABEL(spidev), 2);
249 * @endcode
250 *
251 * This example is equivalent to:
252 *
253 * @code{.c}
254 * struct spi_cs_control ctrl = {
255 * .gpio = SPI_CS_GPIOS_DT_SPEC_GET(DT_NODELABEL(spidev)),
256 * .delay = 2,
257 * };
258 * @endcode
259 *
260 * @param node_id Devicetree node identifier for a device on a SPI bus
261 * @param delay_ The @p delay field to set in the @p spi_cs_control
262 * @return a pointer to the @p spi_cs_control structure
263 */
264 #define SPI_CS_CONTROL_INIT(node_id, delay_) \
265 { \
266 .gpio = SPI_CS_GPIOS_DT_SPEC_GET(node_id), \
267 .delay = (delay_), \
268 }
269
270 /**
271 * @brief Get a pointer to a @p spi_cs_control from a devicetree node
272 *
273 * This is equivalent to
274 * <tt>SPI_CS_CONTROL_INIT(DT_DRV_INST(inst), delay)</tt>.
275 *
276 * Therefore, @p DT_DRV_COMPAT must already be defined before using
277 * this macro.
278 *
279 * @param inst Devicetree node instance number
280 * @param delay_ The @p delay field to set in the @p spi_cs_control
281 * @return a pointer to the @p spi_cs_control structure
282 */
283 #define SPI_CS_CONTROL_INIT_INST(inst, delay_) \
284 SPI_CS_CONTROL_INIT(DT_DRV_INST(inst), delay_)
285
286 /**
287 * @typedef spi_operation_t
288 * Opaque type to hold the SPI operation flags.
289 */
290 #if defined(CONFIG_SPI_EXTENDED_MODES)
291 typedef uint32_t spi_operation_t;
292 #else
293 typedef uint16_t spi_operation_t;
294 #endif
295
296 /**
297 * @brief SPI controller configuration structure
298 */
299 struct spi_config {
300 /** @brief Bus frequency in Hertz. */
301 uint32_t frequency;
302 /**
303 * @brief Operation flags.
304 *
305 * It is a bit field with the following parts:
306 *
307 * - 0: Master or slave.
308 * - 1..3: Polarity, phase and loop mode.
309 * - 4: LSB or MSB first.
310 * - 5..10: Size of a data frame in bits.
311 * - 11: Full/half duplex.
312 * - 12: Hold on the CS line if possible.
313 * - 13: Keep resource locked for the caller.
314 * - 14: Active high CS logic.
315 * - 15: Motorola or TI frame format (optional).
316 *
317 * If @kconfig{CONFIG_SPI_EXTENDED_MODES} is enabled:
318 *
319 * - 16..17: MISO lines (Single/Dual/Quad/Octal).
320 * - 18..31: Reserved for future use.
321 */
322 spi_operation_t operation;
323 /** @brief Slave number from 0 to host controller slave limit. */
324 uint16_t slave;
325 /**
326 * @brief GPIO chip-select line (optional, must be initialized to zero
327 * if not used).
328 */
329 struct spi_cs_control cs;
330 };
331
332 /**
333 * @brief Structure initializer for spi_config from devicetree
334 *
335 * This helper macro expands to a static initializer for a <tt>struct
336 * spi_config</tt> by reading the relevant @p frequency, @p slave, and
337 * @p cs data from the devicetree.
338 *
339 * @param node_id Devicetree node identifier for the SPI device whose
340 * struct spi_config to create an initializer for
341 * @param operation_ the desired @p operation field in the struct spi_config
342 * @param delay_ the desired @p delay field in the struct spi_config's
343 * spi_cs_control, if there is one
344 */
345 #define SPI_CONFIG_DT(node_id, operation_, delay_) \
346 { \
347 .frequency = DT_PROP(node_id, spi_max_frequency), \
348 .operation = (operation_) | \
349 DT_PROP(node_id, duplex) | \
350 DT_PROP(node_id, frame_format) | \
351 COND_CODE_1(DT_PROP(node_id, spi_cpol), SPI_MODE_CPOL, (0)) | \
352 COND_CODE_1(DT_PROP(node_id, spi_cpha), SPI_MODE_CPHA, (0)) | \
353 COND_CODE_1(DT_PROP(node_id, spi_hold_cs), SPI_HOLD_ON_CS, (0)), \
354 .slave = DT_REG_ADDR(node_id), \
355 .cs = SPI_CS_CONTROL_INIT(node_id, delay_), \
356 }
357
358 /**
359 * @brief Structure initializer for spi_config from devicetree instance
360 *
361 * This is equivalent to
362 * <tt>SPI_CONFIG_DT(DT_DRV_INST(inst), operation_, delay_)</tt>.
363 *
364 * @param inst Devicetree instance number
365 * @param operation_ the desired @p operation field in the struct spi_config
366 * @param delay_ the desired @p delay field in the struct spi_config's
367 * spi_cs_control, if there is one
368 */
369 #define SPI_CONFIG_DT_INST(inst, operation_, delay_) \
370 SPI_CONFIG_DT(DT_DRV_INST(inst), operation_, delay_)
371
372 /**
373 * @brief Complete SPI DT information
374 */
375 struct spi_dt_spec {
376 /** SPI bus */
377 const struct device *bus;
378 /** Slave specific configuration */
379 struct spi_config config;
380 };
381
382 /**
383 * @brief Structure initializer for spi_dt_spec from devicetree
384 *
385 * This helper macro expands to a static initializer for a <tt>struct
386 * spi_dt_spec</tt> by reading the relevant bus, frequency, slave, and cs
387 * data from the devicetree.
388 *
389 * Important: multiple fields are automatically constructed by this macro
390 * which must be checked before use. @ref spi_is_ready performs the required
391 * @ref device_is_ready checks.
392 * @deprecated Use @ref spi_is_ready_dt instead.
393 *
394 * @param node_id Devicetree node identifier for the SPI device whose
395 * struct spi_dt_spec to create an initializer for
396 * @param operation_ the desired @p operation field in the struct spi_config
397 * @param delay_ the desired @p delay field in the struct spi_config's
398 * spi_cs_control, if there is one
399 */
400 #define SPI_DT_SPEC_GET(node_id, operation_, delay_) \
401 { \
402 .bus = DEVICE_DT_GET(DT_BUS(node_id)), \
403 .config = SPI_CONFIG_DT(node_id, operation_, delay_) \
404 }
405
406 /**
407 * @brief Structure initializer for spi_dt_spec from devicetree instance
408 *
409 * This is equivalent to
410 * <tt>SPI_DT_SPEC_GET(DT_DRV_INST(inst), operation_, delay_)</tt>.
411 *
412 * @param inst Devicetree instance number
413 * @param operation_ the desired @p operation field in the struct spi_config
414 * @param delay_ the desired @p delay field in the struct spi_config's
415 * spi_cs_control, if there is one
416 */
417 #define SPI_DT_SPEC_INST_GET(inst, operation_, delay_) \
418 SPI_DT_SPEC_GET(DT_DRV_INST(inst), operation_, delay_)
419
420 /**
421 * @brief SPI buffer structure
422 */
423 struct spi_buf {
424 /** Valid pointer to a data buffer, or NULL otherwise */
425 void *buf;
426 /** Length of the buffer @a buf.
427 * If @a buf is NULL, length which as to be sent as dummy bytes (as TX
428 * buffer) or the length of bytes that should be skipped (as RX buffer).
429 */
430 size_t len;
431 };
432
433 /**
434 * @brief SPI buffer array structure
435 */
436 struct spi_buf_set {
437 /** Pointer to an array of spi_buf, or NULL */
438 const struct spi_buf *buffers;
439 /** Length of the array pointed by @a buffers */
440 size_t count;
441 };
442
443 #if defined(CONFIG_SPI_STATS)
444 STATS_SECT_START(spi)
445 STATS_SECT_ENTRY32(rx_bytes)
446 STATS_SECT_ENTRY32(tx_bytes)
447 STATS_SECT_ENTRY32(transfer_error)
448 STATS_SECT_END;
449
450 STATS_NAME_START(spi)
451 STATS_NAME(spi, rx_bytes)
452 STATS_NAME(spi, tx_bytes)
453 STATS_NAME(spi, transfer_error)
454 STATS_NAME_END(spi);
455
456 /**
457 * @brief SPI specific device state which allows for SPI device class specific additions
458 */
459 struct spi_device_state {
460 struct device_state devstate;
461 struct stats_spi stats;
462 };
463
464 /**
465 * @brief Get pointer to SPI statistics structure
466 */
467 #define Z_SPI_GET_STATS(dev_) \
468 CONTAINER_OF(dev_->state, struct spi_device_state, devstate)->stats
469
470 /**
471 * @brief Increment the rx bytes for a SPI device
472 *
473 * @param dev_ Pointer to the device structure for the driver instance.
474 */
475 #define SPI_STATS_RX_BYTES_INCN(dev_, n) \
476 STATS_INCN(Z_SPI_GET_STATS(dev_), rx_bytes, n)
477
478 /**
479 * @brief Increment the tx bytes for a SPI device
480 *
481 * @param dev_ Pointer to the device structure for the driver instance.
482 */
483 #define SPI_STATS_TX_BYTES_INCN(dev_, n) \
484 STATS_INCN(Z_SPI_GET_STATS(dev_), tx_bytes, n)
485
486 /**
487 * @brief Increment the transfer error counter for a SPI device
488 *
489 * The transfer error count is incremented when there occurred a transfer error
490 *
491 * @param dev_ Pointer to the device structure for the driver instance.
492 */
493 #define SPI_STATS_TRANSFER_ERROR_INC(dev_) \
494 STATS_INC(Z_SPI_GET_STATS(dev_), transfer_error)
495
496 /**
497 * @brief Define a statically allocated and section assigned SPI device state
498 */
499 #define Z_SPI_DEVICE_STATE_DEFINE(dev_id) \
500 static struct spi_device_state Z_DEVICE_STATE_NAME(dev_id) \
501 __attribute__((__section__(".z_devstate")));
502
503 /**
504 * @brief Define an SPI device init wrapper function
505 *
506 * This does device instance specific initialization of common data (such as stats)
507 * and calls the given init_fn
508 */
509 #define Z_SPI_INIT_FN(dev_id, init_fn) \
510 static inline int UTIL_CAT(dev_id, _init)(const struct device *dev) \
511 { \
512 struct spi_device_state *state = \
513 CONTAINER_OF(dev->state, struct spi_device_state, devstate); \
514 stats_init(&state->stats.s_hdr, STATS_SIZE_32, 3, \
515 STATS_NAME_INIT_PARMS(spi)); \
516 stats_register(dev->name, &(state->stats.s_hdr)); \
517 return init_fn(dev); \
518 }
519
520 /**
521 * @brief Like DEVICE_DT_DEFINE() with SPI specifics.
522 *
523 * @details Defines a device which implements the SPI API. May
524 * generate a custom device_state container struct and init_fn
525 * wrapper when needed depending on SPI @kconfig{CONFIG_SPI_STATS}.
526 *
527 * @param node_id The devicetree node identifier.
528 * @param init_fn Name of the init function of the driver.
529 * @param pm_device PM device resources reference (NULL if device does not use PM).
530 * @param data_ptr Pointer to the device's private data.
531 * @param cfg_ptr The address to the structure containing the configuration
532 * information for this instance of the driver.
533 * @param level The initialization level. See SYS_INIT() for details.
534 * @param prio Priority within the selected initialization level. See SYS_INIT()
535 * for details.
536 * @param api_ptr Provides an initial pointer to the API function struct used by
537 * the driver. Can be NULL.
538 */
539 #define SPI_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
540 data_ptr, cfg_ptr, level, prio, \
541 api_ptr, ...) \
542 Z_SPI_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
543 Z_SPI_INIT_FN(Z_DEVICE_DT_DEV_ID(node_id), init_fn) \
544 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
545 DEVICE_DT_NAME(node_id), \
546 &UTIL_CAT(Z_DEVICE_DT_DEV_ID(node_id), _init), \
547 pm_device, \
548 data_ptr, cfg_ptr, level, prio, \
549 api_ptr, \
550 &(Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)).devstate), \
551 __VA_ARGS__)
552
spi_transceive_stats(const struct device * dev,int error,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs)553 static inline void spi_transceive_stats(const struct device *dev, int error,
554 const struct spi_buf_set *tx_bufs,
555 const struct spi_buf_set *rx_bufs)
556 {
557 uint32_t tx_bytes;
558 uint32_t rx_bytes;
559
560 if (error) {
561 SPI_STATS_TRANSFER_ERROR_INC(dev);
562 }
563
564 if (tx_bufs) {
565 tx_bytes = tx_bufs->count ? tx_bufs->buffers->len : 0;
566 SPI_STATS_TX_BYTES_INCN(dev, tx_bytes);
567 }
568
569 if (rx_bufs) {
570 rx_bytes = rx_bufs->count ? rx_bufs->buffers->len : 0;
571 SPI_STATS_RX_BYTES_INCN(dev, rx_bytes);
572 }
573 }
574
575 #else /*CONFIG_SPI_STATS*/
576
577 #define SPI_DEVICE_DT_DEFINE(node_id, init_fn, pm, \
578 data, config, level, prio, \
579 api, ...) \
580 Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
581 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
582 DEVICE_DT_NAME(node_id), init_fn, pm, data, config, \
583 level, prio, api, \
584 &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \
585 __VA_ARGS__)
586
587 #define SPI_STATS_RX_BYTES_INC(dev_)
588 #define SPI_STATS_TX_BYTES_INC(dev_)
589 #define SPI_STATS_TRANSFER_ERROR_INC(dev_)
590
591 #define spi_transceive_stats(dev, error, tx_bufs, rx_bufs)
592
593 #endif /*CONFIG_SPI_STATS*/
594
595 /**
596 * @typedef spi_api_io
597 * @brief Callback API for I/O
598 * See spi_transceive() for argument descriptions
599 */
600 typedef int (*spi_api_io)(const struct device *dev,
601 const struct spi_config *config,
602 const struct spi_buf_set *tx_bufs,
603 const struct spi_buf_set *rx_bufs);
604
605 /**
606 * @brief SPI callback for asynchronous transfer requests
607 *
608 * @param dev SPI device which is notifying of transfer completion or error
609 * @param result Result code of the transfer request. 0 is success, -errno for failure.
610 * @param data Transfer requester supplied data which is passed along to the callback.
611 */
612 typedef void (*spi_callback_t)(const struct device *dev, int result, void *data);
613
614 /**
615 * @typedef spi_api_io
616 * @brief Callback API for asynchronous I/O
617 * See spi_transceive_async() for argument descriptions
618 */
619 typedef int (*spi_api_io_async)(const struct device *dev,
620 const struct spi_config *config,
621 const struct spi_buf_set *tx_bufs,
622 const struct spi_buf_set *rx_bufs,
623 spi_callback_t cb,
624 void *userdata);
625
626 #if defined(CONFIG_SPI_RTIO) || defined(DOXYGEN)
627
628 /**
629 * @typedef spi_api_iodev_submit
630 * @brief Callback API for submitting work to a SPI device with RTIO
631 */
632 typedef void (*spi_api_iodev_submit)(const struct device *dev,
633 struct rtio_iodev_sqe *iodev_sqe);
634 #endif /* CONFIG_SPI_RTIO */
635
636 /**
637 * @typedef spi_api_release
638 * @brief Callback API for unlocking SPI device.
639 * See spi_release() for argument descriptions
640 */
641 typedef int (*spi_api_release)(const struct device *dev,
642 const struct spi_config *config);
643
644
645 /**
646 * @brief SPI driver API
647 * This is the mandatory API any SPI driver needs to expose.
648 */
649 __subsystem struct spi_driver_api {
650 spi_api_io transceive;
651 #ifdef CONFIG_SPI_ASYNC
652 spi_api_io_async transceive_async;
653 #endif /* CONFIG_SPI_ASYNC */
654 #ifdef CONFIG_SPI_RTIO
655 spi_api_iodev_submit iodev_submit;
656 #endif /* CONFIG_SPI_RTIO */
657 spi_api_release release;
658 };
659
660 /**
661 * @brief Check if SPI CS is controlled using a GPIO.
662 *
663 * @param config SPI configuration.
664 * @return true If CS is controlled using a GPIO.
665 * @return false If CS is controlled by hardware or any other means.
666 */
spi_cs_is_gpio(const struct spi_config * config)667 static inline bool spi_cs_is_gpio(const struct spi_config *config)
668 {
669 return config->cs.gpio.port != NULL;
670 }
671
672 /**
673 * @brief Check if SPI CS in @ref spi_dt_spec is controlled using a GPIO.
674 *
675 * @param spec SPI specification from devicetree.
676 * @return true If CS is controlled using a GPIO.
677 * @return false If CS is controlled by hardware or any other means.
678 */
spi_cs_is_gpio_dt(const struct spi_dt_spec * spec)679 static inline bool spi_cs_is_gpio_dt(const struct spi_dt_spec *spec)
680 {
681 return spi_cs_is_gpio(&spec->config);
682 }
683
684 /**
685 * @brief Validate that SPI bus is ready.
686 *
687 * @param spec SPI specification from devicetree
688 *
689 * @retval true if the SPI bus is ready for use.
690 * @retval false if the SPI bus is not ready for use.
691 */
692 __deprecated
spi_is_ready(const struct spi_dt_spec * spec)693 static inline bool spi_is_ready(const struct spi_dt_spec *spec)
694 {
695 /* Validate bus is ready */
696 if (!device_is_ready(spec->bus)) {
697 return false;
698 }
699 /* Validate CS gpio port is ready, if it is used */
700 if (spi_cs_is_gpio_dt(spec) &&
701 !gpio_is_ready_dt(&spec->config.cs.gpio)) {
702 return false;
703 }
704 return true;
705 }
706
707 /**
708 * @brief Validate that SPI bus (and CS gpio if defined) is ready.
709 *
710 * @param spec SPI specification from devicetree
711 *
712 * @retval true if the SPI bus is ready for use.
713 * @retval false if the SPI bus (or the CS gpio defined) is not ready for use.
714 */
spi_is_ready_dt(const struct spi_dt_spec * spec)715 static inline bool spi_is_ready_dt(const struct spi_dt_spec *spec)
716 {
717 /* Validate bus is ready */
718 if (!device_is_ready(spec->bus)) {
719 return false;
720 }
721 /* Validate CS gpio port is ready, if it is used */
722 if (spi_cs_is_gpio_dt(spec) &&
723 !gpio_is_ready_dt(&spec->config.cs.gpio)) {
724 return false;
725 }
726 return true;
727 }
728
729 /**
730 * @brief Read/write the specified amount of data from the SPI driver.
731 *
732 * @note This function is synchronous.
733 *
734 * @param dev Pointer to the device structure for the driver instance
735 * @param config Pointer to a valid spi_config structure instance.
736 * Pointer-comparison may be used to detect changes from
737 * previous operations.
738 * @param tx_bufs Buffer array where data to be sent originates from,
739 * or NULL if none.
740 * @param rx_bufs Buffer array where data to be read will be written to,
741 * or NULL if none.
742 *
743 * @retval frames Positive number of frames received in slave mode.
744 * @retval 0 If successful in master mode.
745 * @retval -errno Negative errno code on failure.
746 */
747 __syscall int spi_transceive(const struct device *dev,
748 const struct spi_config *config,
749 const struct spi_buf_set *tx_bufs,
750 const struct spi_buf_set *rx_bufs);
751
z_impl_spi_transceive(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs)752 static inline int z_impl_spi_transceive(const struct device *dev,
753 const struct spi_config *config,
754 const struct spi_buf_set *tx_bufs,
755 const struct spi_buf_set *rx_bufs)
756 {
757 const struct spi_driver_api *api =
758 (const struct spi_driver_api *)dev->api;
759 int ret;
760
761 ret = api->transceive(dev, config, tx_bufs, rx_bufs);
762 spi_transceive_stats(dev, ret, tx_bufs, rx_bufs);
763
764 return ret;
765 }
766
767 /**
768 * @brief Read/write data from an SPI bus specified in @p spi_dt_spec.
769 *
770 * This is equivalent to:
771 *
772 * spi_transceive(spec->bus, &spec->config, tx_bufs, rx_bufs);
773 *
774 * @param spec SPI specification from devicetree
775 * @param tx_bufs Buffer array where data to be sent originates from,
776 * or NULL if none.
777 * @param rx_bufs Buffer array where data to be read will be written to,
778 * or NULL if none.
779 *
780 * @return a value from spi_transceive().
781 */
spi_transceive_dt(const struct spi_dt_spec * spec,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs)782 static inline int spi_transceive_dt(const struct spi_dt_spec *spec,
783 const struct spi_buf_set *tx_bufs,
784 const struct spi_buf_set *rx_bufs)
785 {
786 return spi_transceive(spec->bus, &spec->config, tx_bufs, rx_bufs);
787 }
788
789 /**
790 * @brief Read the specified amount of data from the SPI driver.
791 *
792 * @note This function is synchronous.
793 *
794 * @note This function is a helper function calling spi_transceive.
795 *
796 * @param dev Pointer to the device structure for the driver instance
797 * @param config Pointer to a valid spi_config structure instance.
798 * Pointer-comparison may be used to detect changes from
799 * previous operations.
800 * @param rx_bufs Buffer array where data to be read will be written to.
801 *
802 * @retval frames Positive number of frames received in slave mode.
803 * @retval 0 If successful.
804 * @retval -errno Negative errno code on failure.
805 */
spi_read(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * rx_bufs)806 static inline int spi_read(const struct device *dev,
807 const struct spi_config *config,
808 const struct spi_buf_set *rx_bufs)
809 {
810 return spi_transceive(dev, config, NULL, rx_bufs);
811 }
812
813 /**
814 * @brief Read data from a SPI bus specified in @p spi_dt_spec.
815 *
816 * This is equivalent to:
817 *
818 * spi_read(spec->bus, &spec->config, rx_bufs);
819 *
820 * @param spec SPI specification from devicetree
821 * @param rx_bufs Buffer array where data to be read will be written to.
822 *
823 * @return a value from spi_read().
824 */
spi_read_dt(const struct spi_dt_spec * spec,const struct spi_buf_set * rx_bufs)825 static inline int spi_read_dt(const struct spi_dt_spec *spec,
826 const struct spi_buf_set *rx_bufs)
827 {
828 return spi_read(spec->bus, &spec->config, rx_bufs);
829 }
830
831 /**
832 * @brief Write the specified amount of data from the SPI driver.
833 *
834 * @note This function is synchronous.
835 *
836 * @note This function is a helper function calling spi_transceive.
837 *
838 * @param dev Pointer to the device structure for the driver instance
839 * @param config Pointer to a valid spi_config structure instance.
840 * Pointer-comparison may be used to detect changes from
841 * previous operations.
842 * @param tx_bufs Buffer array where data to be sent originates from.
843 *
844 * @retval 0 If successful.
845 * @retval -errno Negative errno code on failure.
846 */
spi_write(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs)847 static inline int spi_write(const struct device *dev,
848 const struct spi_config *config,
849 const struct spi_buf_set *tx_bufs)
850 {
851 return spi_transceive(dev, config, tx_bufs, NULL);
852 }
853
854 /**
855 * @brief Write data to a SPI bus specified in @p spi_dt_spec.
856 *
857 * This is equivalent to:
858 *
859 * spi_write(spec->bus, &spec->config, tx_bufs);
860 *
861 * @param spec SPI specification from devicetree
862 * @param tx_bufs Buffer array where data to be sent originates from.
863 *
864 * @return a value from spi_write().
865 */
spi_write_dt(const struct spi_dt_spec * spec,const struct spi_buf_set * tx_bufs)866 static inline int spi_write_dt(const struct spi_dt_spec *spec,
867 const struct spi_buf_set *tx_bufs)
868 {
869 return spi_write(spec->bus, &spec->config, tx_bufs);
870 }
871
872 #if defined(CONFIG_SPI_ASYNC) || defined(__DOXYGEN__)
873
874 /**
875 * @brief Read/write the specified amount of data from the SPI driver.
876 *
877 * @note This function is asynchronous.
878 *
879 * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC}
880 * is selected.
881 *
882 * @param dev Pointer to the device structure for the driver instance
883 * @param config Pointer to a valid spi_config structure instance.
884 * Pointer-comparison may be used to detect changes from
885 * previous operations.
886 * @param tx_bufs Buffer array where data to be sent originates from,
887 * or NULL if none.
888 * @param rx_bufs Buffer array where data to be read will be written to,
889 * or NULL if none.
890 * @param callback Function pointer to completion callback.
891 * (Note: if NULL this function will not
892 * notify the end of the transaction, and whether it went
893 * successfully or not).
894 * @param userdata Userdata passed to callback
895 *
896 * @retval frames Positive number of frames received in slave mode.
897 * @retval 0 If successful in master mode.
898 * @retval -errno Negative errno code on failure.
899 */
spi_transceive_cb(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs,spi_callback_t callback,void * userdata)900 static inline int spi_transceive_cb(const struct device *dev,
901 const struct spi_config *config,
902 const struct spi_buf_set *tx_bufs,
903 const struct spi_buf_set *rx_bufs,
904 spi_callback_t callback,
905 void *userdata)
906 {
907 const struct spi_driver_api *api =
908 (const struct spi_driver_api *)dev->api;
909
910 return api->transceive_async(dev, config, tx_bufs, rx_bufs, callback, userdata);
911 }
912
913 #if defined(CONFIG_POLL) || defined(__DOXYGEN__)
914
915 /** @cond INTERNAL_HIDDEN */
916 void z_spi_transfer_signal_cb(const struct device *dev, int result, void *userdata);
917 /** @endcond */
918
919 /**
920 * @brief Read/write the specified amount of data from the SPI driver.
921 *
922 * @note This function is asynchronous.
923 *
924 * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC}
925 * and @kconfig{CONFIG_POLL} are selected.
926 *
927 * @param dev Pointer to the device structure for the driver instance
928 * @param config Pointer to a valid spi_config structure instance.
929 * Pointer-comparison may be used to detect changes from
930 * previous operations.
931 * @param tx_bufs Buffer array where data to be sent originates from,
932 * or NULL if none.
933 * @param rx_bufs Buffer array where data to be read will be written to,
934 * or NULL if none.
935 * @param sig A pointer to a valid and ready to be signaled
936 * struct k_poll_signal. (Note: if NULL this function will not
937 * notify the end of the transaction, and whether it went
938 * successfully or not).
939 *
940 * @retval frames Positive number of frames received in slave mode.
941 * @retval 0 If successful in master mode.
942 * @retval -errno Negative errno code on failure.
943 */
spi_transceive_signal(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs,struct k_poll_signal * sig)944 static inline int spi_transceive_signal(const struct device *dev,
945 const struct spi_config *config,
946 const struct spi_buf_set *tx_bufs,
947 const struct spi_buf_set *rx_bufs,
948 struct k_poll_signal *sig)
949 {
950 const struct spi_driver_api *api =
951 (const struct spi_driver_api *)dev->api;
952 spi_callback_t cb = (sig == NULL) ? NULL : z_spi_transfer_signal_cb;
953
954 return api->transceive_async(dev, config, tx_bufs, rx_bufs, cb, sig);
955 }
956
957 /**
958 * @brief Alias for spi_transceive_signal for backwards compatibility
959 *
960 * @deprecated Use @ref spi_transceive_signal instead.
961 */
spi_transceive_async(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs,struct k_poll_signal * sig)962 __deprecated static inline int spi_transceive_async(const struct device *dev,
963 const struct spi_config *config,
964 const struct spi_buf_set *tx_bufs,
965 const struct spi_buf_set *rx_bufs,
966 struct k_poll_signal *sig)
967 {
968 return spi_transceive_signal(dev, config, tx_bufs, rx_bufs, sig);
969 }
970
971 /**
972 * @brief Read the specified amount of data from the SPI driver.
973 *
974 * @note This function is asynchronous.
975 *
976 * @note This function is a helper function calling spi_transceive_signal.
977 *
978 * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC}
979 * and @kconfig{CONFIG_POLL} are selected.
980 *
981 * @param dev Pointer to the device structure for the driver instance
982 * @param config Pointer to a valid spi_config structure instance.
983 * Pointer-comparison may be used to detect changes from
984 * previous operations.
985 * @param rx_bufs Buffer array where data to be read will be written to.
986 * @param sig A pointer to a valid and ready to be signaled
987 * struct k_poll_signal. (Note: if NULL this function will not
988 * notify the end of the transaction, and whether it went
989 * successfully or not).
990 *
991 * @retval frames Positive number of frames received in slave mode.
992 * @retval 0 If successful
993 * @retval -errno Negative errno code on failure.
994 */
spi_read_signal(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * rx_bufs,struct k_poll_signal * sig)995 static inline int spi_read_signal(const struct device *dev,
996 const struct spi_config *config,
997 const struct spi_buf_set *rx_bufs,
998 struct k_poll_signal *sig)
999 {
1000 return spi_transceive_signal(dev, config, NULL, rx_bufs, sig);
1001 }
1002
1003 /**
1004 * @brief Alias for spi_read_signal for backwards compatibility
1005 *
1006 * @deprecated Use @ref spi_read_signal instead.
1007 */
spi_read_async(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * rx_bufs,struct k_poll_signal * sig)1008 __deprecated static inline int spi_read_async(const struct device *dev,
1009 const struct spi_config *config,
1010 const struct spi_buf_set *rx_bufs,
1011 struct k_poll_signal *sig)
1012 {
1013 return spi_read_signal(dev, config, rx_bufs, sig);
1014 }
1015
1016 /**
1017 * @brief Write the specified amount of data from the SPI driver.
1018 *
1019 * @note This function is asynchronous.
1020 *
1021 * @note This function is a helper function calling spi_transceive_async.
1022 *
1023 * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC}
1024 * and @kconfig{CONFIG_POLL} are selected.
1025 *
1026 * @param dev Pointer to the device structure for the driver instance
1027 * @param config Pointer to a valid spi_config structure instance.
1028 * Pointer-comparison may be used to detect changes from
1029 * previous operations.
1030 * @param tx_bufs Buffer array where data to be sent originates from.
1031 * @param sig A pointer to a valid and ready to be signaled
1032 * struct k_poll_signal. (Note: if NULL this function will not
1033 * notify the end of the transaction, and whether it went
1034 * successfully or not).
1035 *
1036 * @retval 0 If successful.
1037 * @retval -errno Negative errno code on failure.
1038 */
spi_write_signal(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,struct k_poll_signal * sig)1039 static inline int spi_write_signal(const struct device *dev,
1040 const struct spi_config *config,
1041 const struct spi_buf_set *tx_bufs,
1042 struct k_poll_signal *sig)
1043 {
1044 return spi_transceive_signal(dev, config, tx_bufs, NULL, sig);
1045 }
1046
1047 /**
1048 * @brief Alias for spi_write_signal for backwards compatibility
1049 *
1050 * @deprecated Use @ref spi_write_signal instead.
1051 */
spi_write_async(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,struct k_poll_signal * sig)1052 __deprecated static inline int spi_write_async(const struct device *dev,
1053 const struct spi_config *config,
1054 const struct spi_buf_set *tx_bufs,
1055 struct k_poll_signal *sig)
1056 {
1057 return spi_write_signal(dev, config, tx_bufs, sig);
1058 }
1059
1060 #endif /* CONFIG_POLL */
1061
1062 #endif /* CONFIG_SPI_ASYNC */
1063
1064
1065 #if defined(CONFIG_SPI_RTIO) || defined(__DOXYGEN__)
1066
1067 /**
1068 * @brief Submit a SPI device with a request
1069 *
1070 * @param iodev_sqe Prepared submissions queue entry connected to an iodev
1071 * defined by SPI_IODEV_DEFINE.
1072 * Must live as long as the request is in flight.
1073 */
spi_iodev_submit(struct rtio_iodev_sqe * iodev_sqe)1074 static inline void spi_iodev_submit(struct rtio_iodev_sqe *iodev_sqe)
1075 {
1076 const struct spi_dt_spec *dt_spec = iodev_sqe->sqe.iodev->data;
1077 const struct device *dev = dt_spec->bus;
1078 const struct spi_driver_api *api = (const struct spi_driver_api *)dev->api;
1079
1080 api->iodev_submit(dt_spec->bus, iodev_sqe);
1081 }
1082
1083 extern const struct rtio_iodev_api spi_iodev_api;
1084
1085 /**
1086 * @brief Define an iodev for a given dt node on the bus
1087 *
1088 * These do not need to be shared globally but doing so
1089 * will save a small amount of memory.
1090 *
1091 * @param name Symbolic name to use for defining the iodev
1092 * @param node_id Devicetree node identifier
1093 * @param operation_ SPI operational mode
1094 * @param delay_ Chip select delay in microseconds
1095 */
1096 #define SPI_DT_IODEV_DEFINE(name, node_id, operation_, delay_) \
1097 const struct spi_dt_spec _spi_dt_spec_##name = \
1098 SPI_DT_SPEC_GET(node_id, operation_, delay_); \
1099 RTIO_IODEV_DEFINE(name, &spi_iodev_api, (void *)&_spi_dt_spec_##name)
1100
1101 /**
1102 * @brief Validate that SPI bus (and CS gpio if defined) is ready.
1103 *
1104 * @param spi_iodev SPI iodev defined with SPI_DT_IODEV_DEFINE
1105 *
1106 * @retval true if the SPI bus is ready for use.
1107 * @retval false if the SPI bus (or the CS gpio defined) is not ready for use.
1108 */
spi_is_ready_iodev(const struct rtio_iodev * spi_iodev)1109 static inline bool spi_is_ready_iodev(const struct rtio_iodev *spi_iodev)
1110 {
1111 struct spi_dt_spec *spec = spi_iodev->data;
1112
1113 return spi_is_ready_dt(spec);
1114 }
1115
1116 /**
1117 * @brief Copy the tx_bufs and rx_bufs into a set of RTIO requests
1118 *
1119 * @param[in] r rtio context
1120 * @param[in] iodev iodev to transceive with
1121 * @param[in] tx_bufs transmit buffer set
1122 * @param[in] rx_bufs receive buffer set
1123 * @param[out] last_sqe last sqe submitted, NULL if not enough memory
1124 *
1125 * @retval Number of submission queue entries
1126 * @retval -ENOMEM out of memory
1127 */
spi_rtio_copy(struct rtio * r,struct rtio_iodev * iodev,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs,struct rtio_sqe ** last_sqe)1128 static inline int spi_rtio_copy(struct rtio *r,
1129 struct rtio_iodev *iodev,
1130 const struct spi_buf_set *tx_bufs,
1131 const struct spi_buf_set *rx_bufs,
1132 struct rtio_sqe **last_sqe)
1133 {
1134 int ret = 0;
1135 size_t tx_count = tx_bufs ? tx_bufs->count : 0;
1136 size_t rx_count = rx_bufs ? rx_bufs->count : 0;
1137
1138 uint32_t tx = 0, tx_len = 0;
1139 uint32_t rx = 0, rx_len = 0;
1140 uint8_t *tx_buf, *rx_buf;
1141
1142 struct rtio_sqe *sqe = NULL;
1143
1144 if (tx < tx_count) {
1145 tx_buf = tx_bufs->buffers[tx].buf;
1146 tx_len = tx_bufs->buffers[tx].len;
1147 } else {
1148 tx_buf = NULL;
1149 tx_len = rx_bufs->buffers[rx].len;
1150 }
1151
1152 if (rx < rx_count) {
1153 rx_buf = rx_bufs->buffers[rx].buf;
1154 rx_len = rx_bufs->buffers[rx].len;
1155 } else {
1156 rx_buf = NULL;
1157 rx_len = tx_bufs->buffers[tx].len;
1158 }
1159
1160
1161 while ((tx < tx_count || rx < rx_count) && (tx_len > 0 || rx_len > 0)) {
1162 sqe = rtio_sqe_acquire(r);
1163
1164 if (sqe == NULL) {
1165 ret = -ENOMEM;
1166 rtio_sqe_drop_all(r);
1167 goto out;
1168 }
1169
1170 ret++;
1171
1172 /* If tx/rx len are same, we can do a simple transceive */
1173 if (tx_len == rx_len) {
1174 if (tx_buf == NULL) {
1175 rtio_sqe_prep_read(sqe, iodev, RTIO_PRIO_NORM,
1176 rx_buf, rx_len, NULL);
1177 } else if (rx_buf == NULL) {
1178 rtio_sqe_prep_write(sqe, iodev, RTIO_PRIO_NORM,
1179 tx_buf, tx_len, NULL);
1180 } else {
1181 rtio_sqe_prep_transceive(sqe, iodev, RTIO_PRIO_NORM,
1182 tx_buf, rx_buf, rx_len, NULL);
1183 }
1184 tx++;
1185 rx++;
1186 if (rx < rx_count) {
1187 rx_buf = rx_bufs->buffers[rx].buf;
1188 rx_len = rx_bufs->buffers[rx].len;
1189 } else {
1190 rx_buf = NULL;
1191 rx_len = 0;
1192 }
1193 if (tx < tx_count) {
1194 tx_buf = tx_bufs->buffers[tx].buf;
1195 tx_len = tx_bufs->buffers[tx].len;
1196 } else {
1197 tx_buf = NULL;
1198 tx_len = 0;
1199 }
1200 } else if (tx_len == 0) {
1201 rtio_sqe_prep_read(sqe, iodev, RTIO_PRIO_NORM,
1202 (uint8_t *)rx_buf,
1203 (uint32_t)rx_len,
1204 NULL);
1205 rx++;
1206 if (rx < rx_count) {
1207 rx_buf = rx_bufs->buffers[rx].buf;
1208 rx_len = rx_bufs->buffers[rx].len;
1209 } else {
1210 rx_buf = NULL;
1211 rx_len = 0;
1212 }
1213 } else if (rx_len == 0) {
1214 rtio_sqe_prep_write(sqe, iodev, RTIO_PRIO_NORM,
1215 (uint8_t *)tx_buf,
1216 (uint32_t)tx_len,
1217 NULL);
1218 tx++;
1219 if (tx < tx_count) {
1220 tx_buf = rx_bufs->buffers[rx].buf;
1221 tx_len = rx_bufs->buffers[rx].len;
1222 } else {
1223 tx_buf = NULL;
1224 tx_len = 0;
1225 }
1226 } else if (tx_len > rx_len) {
1227 rtio_sqe_prep_transceive(sqe, iodev, RTIO_PRIO_NORM,
1228 (uint8_t *)tx_buf,
1229 (uint8_t *)rx_buf,
1230 (uint32_t)rx_len,
1231 NULL);
1232 tx_len -= rx_len;
1233 tx_buf += rx_len;
1234 rx++;
1235 if (rx < rx_count) {
1236 rx_buf = rx_bufs->buffers[rx].buf;
1237 rx_len = rx_bufs->buffers[rx].len;
1238 } else {
1239 rx_buf = NULL;
1240 rx_len = tx_len;
1241 }
1242 } else if (rx_len > tx_len) {
1243 rtio_sqe_prep_transceive(sqe, iodev, RTIO_PRIO_NORM,
1244 (uint8_t *)tx_buf,
1245 (uint8_t *)rx_buf,
1246 (uint32_t)tx_len,
1247 NULL);
1248 rx_len -= tx_len;
1249 rx_buf += tx_len;
1250 tx++;
1251 if (tx < tx_count) {
1252 tx_buf = tx_bufs->buffers[tx].buf;
1253 tx_len = tx_bufs->buffers[tx].len;
1254 } else {
1255 tx_buf = NULL;
1256 tx_len = rx_len;
1257 }
1258 } else {
1259 __ASSERT_NO_MSG("Invalid spi_rtio_copy state");
1260 }
1261
1262 sqe->flags = RTIO_SQE_TRANSACTION;
1263 }
1264
1265 if (sqe != NULL) {
1266 sqe->flags = 0;
1267 *last_sqe = sqe;
1268 }
1269
1270 out:
1271 return ret;
1272 }
1273
1274 #endif /* CONFIG_SPI_RTIO */
1275
1276 /**
1277 * @brief Release the SPI device locked on and/or the CS by the current config
1278 *
1279 * Note: This synchronous function is used to release either the lock on the
1280 * SPI device and/or the CS line that was kept if, and if only,
1281 * given config parameter was the last one to be used (in any of the
1282 * above functions) and if it has the SPI_LOCK_ON bit set and/or the
1283 * SPI_HOLD_ON_CS bit set into its operation bits field.
1284 * This can be used if the caller needs to keep its hand on the SPI
1285 * device for consecutive transactions and/or if it needs the device to
1286 * stay selected. Usually both bits will be used along each other, so the
1287 * the device is locked and stays on until another operation is necessary
1288 * or until it gets released with the present function.
1289 *
1290 * @param dev Pointer to the device structure for the driver instance
1291 * @param config Pointer to a valid spi_config structure instance.
1292 *
1293 * @retval 0 If successful.
1294 * @retval -errno Negative errno code on failure.
1295 */
1296 __syscall int spi_release(const struct device *dev,
1297 const struct spi_config *config);
1298
z_impl_spi_release(const struct device * dev,const struct spi_config * config)1299 static inline int z_impl_spi_release(const struct device *dev,
1300 const struct spi_config *config)
1301 {
1302 const struct spi_driver_api *api =
1303 (const struct spi_driver_api *)dev->api;
1304
1305 return api->release(dev, config);
1306 }
1307
1308 /**
1309 * @brief Release the SPI device specified in @p spi_dt_spec.
1310 *
1311 * This is equivalent to:
1312 *
1313 * spi_release(spec->bus, &spec->config);
1314 *
1315 * @param spec SPI specification from devicetree
1316 *
1317 * @return a value from spi_release().
1318 */
spi_release_dt(const struct spi_dt_spec * spec)1319 static inline int spi_release_dt(const struct spi_dt_spec *spec)
1320 {
1321 return spi_release(spec->bus, &spec->config);
1322 }
1323
1324 #ifdef __cplusplus
1325 }
1326 #endif
1327
1328 /**
1329 * @}
1330 */
1331
1332 #include <syscalls/spi.h>
1333
1334 #endif /* ZEPHYR_INCLUDE_DRIVERS_SPI_H_ */
1335