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