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 * @brief SPI controller configuration structure
273 *
274 * @param frequency is the bus frequency in Hertz
275 * @param operation is a bit field with the following parts:
276 *
277 * operational mode [ 0 ] - master or slave.
278 * mode [ 1 : 3 ] - Polarity, phase and loop mode.
279 * transfer [ 4 ] - LSB or MSB first.
280 * word_size [ 5 : 10 ] - Size of a data frame in bits.
281 * duplex [ 11 ] - full/half duplex.
282 * cs_hold [ 12 ] - Hold on the CS line if possible.
283 * lock_on [ 13 ] - Keep resource locked for the caller.
284 * cs_active_high [ 14 ] - Active high CS logic.
285 * format [ 15 ] - Motorola or TI frame format (optional).
286 * if @kconfig{CONFIG_SPI_EXTENDED_MODES} is defined:
287 * lines [ 16 : 17 ] - MISO lines: Single/Dual/Quad/Octal.
288 * reserved [ 18 : 31 ] - reserved for future use.
289 * @param slave is the slave number from 0 to host controller slave limit.
290 * @param cs is a valid pointer on a struct spi_cs_control is CS line is
291 * emulated through a gpio line, or NULL otherwise.
292 * @warning Most drivers use pointer comparison to determine whether a
293 * passed configuration is different from one used in a previous
294 * transaction. Changes to fields in the structure may not be
295 * detected.
296 */
297 struct spi_config {
298 uint32_t frequency;
299 #if defined(CONFIG_SPI_EXTENDED_MODES)
300 uint32_t operation;
301 uint16_t slave;
302 uint16_t _unused;
303 #else
304 uint16_t operation;
305 uint16_t slave;
306 #endif /* CONFIG_SPI_EXTENDED_MODES */
307
308 struct spi_cs_control cs;
309 };
310
311 /**
312 * @brief Structure initializer for spi_config from devicetree
313 *
314 * This helper macro expands to a static initializer for a <tt>struct
315 * spi_config</tt> by reading the relevant @p frequency, @p slave, and
316 * @p cs data from the devicetree.
317 *
318 * Important: the @p cs field is initialized using
319 * SPI_CS_CONTROL_INIT(). The @p gpio_dev value pointed to by this
320 * structure must be checked using device_is_ready() before use.
321 *
322 * @param node_id Devicetree node identifier for the SPI device whose
323 * struct spi_config to create an initializer for
324 * @param operation_ the desired @p operation field in the struct spi_config
325 * @param delay_ the desired @p delay field in the struct spi_config's
326 * spi_cs_control, if there is one
327 */
328 #define SPI_CONFIG_DT(node_id, operation_, delay_) \
329 { \
330 .frequency = DT_PROP(node_id, spi_max_frequency), \
331 .operation = (operation_) | \
332 DT_PROP(node_id, duplex) | \
333 DT_PROP(node_id, frame_format), \
334 .slave = DT_REG_ADDR(node_id), \
335 .cs = SPI_CS_CONTROL_INIT(node_id, delay_), \
336 }
337
338 /**
339 * @brief Structure initializer for spi_config from devicetree instance
340 *
341 * This is equivalent to
342 * <tt>SPI_CONFIG_DT(DT_DRV_INST(inst), operation_, delay_)</tt>.
343 *
344 * @param inst Devicetree instance number
345 * @param operation_ the desired @p operation field in the struct spi_config
346 * @param delay_ the desired @p delay field in the struct spi_config's
347 * spi_cs_control, if there is one
348 */
349 #define SPI_CONFIG_DT_INST(inst, operation_, delay_) \
350 SPI_CONFIG_DT(DT_DRV_INST(inst), operation_, delay_)
351
352 /**
353 * @brief Complete SPI DT information
354 *
355 * @param bus is the SPI bus
356 * @param config is the slave specific configuration
357 */
358 struct spi_dt_spec {
359 const struct device *bus;
360 struct spi_config config;
361 };
362
363 /**
364 * @brief Structure initializer for spi_dt_spec from devicetree
365 *
366 * This helper macro expands to a static initializer for a <tt>struct
367 * spi_dt_spec</tt> by reading the relevant bus, frequency, slave, and cs
368 * data from the devicetree.
369 *
370 * Important: multiple fields are automatically constructed by this macro
371 * which must be checked before use. @ref spi_is_ready performs the required
372 * @ref device_is_ready checks.
373 * @deprecated Use @ref spi_is_ready_dt instead.
374 *
375 * @param node_id Devicetree node identifier for the SPI device whose
376 * struct spi_dt_spec to create an initializer for
377 * @param operation_ the desired @p operation field in the struct spi_config
378 * @param delay_ the desired @p delay field in the struct spi_config's
379 * spi_cs_control, if there is one
380 */
381 #define SPI_DT_SPEC_GET(node_id, operation_, delay_) \
382 { \
383 .bus = DEVICE_DT_GET(DT_BUS(node_id)), \
384 .config = SPI_CONFIG_DT(node_id, operation_, delay_) \
385 }
386
387 /**
388 * @brief Structure initializer for spi_dt_spec from devicetree instance
389 *
390 * This is equivalent to
391 * <tt>SPI_DT_SPEC_GET(DT_DRV_INST(inst), operation_, delay_)</tt>.
392 *
393 * @param inst Devicetree instance number
394 * @param operation_ the desired @p operation field in the struct spi_config
395 * @param delay_ the desired @p delay field in the struct spi_config's
396 * spi_cs_control, if there is one
397 */
398 #define SPI_DT_SPEC_INST_GET(inst, operation_, delay_) \
399 SPI_DT_SPEC_GET(DT_DRV_INST(inst), operation_, delay_)
400
401 /**
402 * @brief SPI buffer structure
403 *
404 * @param buf is a valid pointer on a data buffer, or NULL otherwise.
405 * @param len is the length of the buffer or, if buf is NULL, will be the
406 * length which as to be sent as dummy bytes (as TX buffer) or
407 * the length of bytes that should be skipped (as RX buffer).
408 */
409 struct spi_buf {
410 void *buf;
411 size_t len;
412 };
413
414 /**
415 * @brief SPI buffer array structure
416 *
417 * @param buffers is a valid pointer on an array of spi_buf, or NULL.
418 * @param count is the length of the array pointed by buffers.
419 */
420 struct spi_buf_set {
421 const struct spi_buf *buffers;
422 size_t count;
423 };
424
425 #if defined(CONFIG_SPI_STATS)
426 STATS_SECT_START(spi)
427 STATS_SECT_ENTRY32(rx_bytes)
428 STATS_SECT_ENTRY32(tx_bytes)
429 STATS_SECT_ENTRY32(transfer_error)
430 STATS_SECT_END;
431
432 STATS_NAME_START(spi)
433 STATS_NAME(spi, rx_bytes)
434 STATS_NAME(spi, tx_bytes)
435 STATS_NAME(spi, transfer_error)
436 STATS_NAME_END(spi);
437
438 /**
439 * @brief SPI specific device state which allows for SPI device class specific additions
440 */
441 struct spi_device_state {
442 struct device_state devstate;
443 struct stats_spi stats;
444 };
445
446 /**
447 * @brief Get pointer to SPI statistics structure
448 */
449 #define Z_SPI_GET_STATS(dev_) \
450 CONTAINER_OF(dev_->state, struct spi_device_state, devstate)->stats
451
452 /**
453 * @brief Increment the rx bytes for a SPI device
454 *
455 * @param dev_ Pointer to the device structure for the driver instance.
456 */
457 #define SPI_STATS_RX_BYTES_INCN(dev_, n) \
458 STATS_INCN(Z_SPI_GET_STATS(dev_), rx_bytes, n)
459
460 /**
461 * @brief Increment the tx bytes for a SPI device
462 *
463 * @param dev_ Pointer to the device structure for the driver instance.
464 */
465 #define SPI_STATS_TX_BYTES_INCN(dev_, n) \
466 STATS_INCN(Z_SPI_GET_STATS(dev_), tx_bytes, n)
467
468 /**
469 * @brief Increment the transfer error counter for a SPI device
470 *
471 * The transfer error count is incremented when there occurred a transfer error
472 *
473 * @param dev_ Pointer to the device structure for the driver instance.
474 */
475 #define SPI_STATS_TRANSFER_ERROR_INC(dev_) \
476 STATS_INC(Z_SPI_GET_STATS(dev_), transfer_error)
477
478 /**
479 * @brief Define a statically allocated and section assigned SPI device state
480 */
481 #define Z_SPI_DEVICE_STATE_DEFINE(dev_id) \
482 static struct spi_device_state Z_DEVICE_STATE_NAME(dev_id) \
483 __attribute__((__section__(".z_devstate")));
484
485 /**
486 * @brief Define an SPI device init wrapper function
487 *
488 * This does device instance specific initialization of common data (such as stats)
489 * and calls the given init_fn
490 */
491 #define Z_SPI_INIT_FN(dev_id, init_fn) \
492 static inline int UTIL_CAT(dev_id, _init)(const struct device *dev) \
493 { \
494 struct spi_device_state *state = \
495 CONTAINER_OF(dev->state, struct spi_device_state, devstate); \
496 stats_init(&state->stats.s_hdr, STATS_SIZE_32, 3, \
497 STATS_NAME_INIT_PARMS(spi)); \
498 stats_register(dev->name, &(state->stats.s_hdr)); \
499 return init_fn(dev); \
500 }
501
502 /**
503 * @brief Like DEVICE_DT_DEFINE() with SPI specifics.
504 *
505 * @details Defines a device which implements the SPI API. May
506 * generate a custom device_state container struct and init_fn
507 * wrapper when needed depending on SPI @kconfig{CONFIG_SPI_STATS}.
508 *
509 * @param node_id The devicetree node identifier.
510 * @param init_fn Name of the init function of the driver.
511 * @param pm_device PM device resources reference (NULL if device does not use PM).
512 * @param data_ptr Pointer to the device's private data.
513 * @param cfg_ptr The address to the structure containing the configuration
514 * information for this instance of the driver.
515 * @param level The initialization level. See SYS_INIT() for details.
516 * @param prio Priority within the selected initialization level. See SYS_INIT()
517 * for details.
518 * @param api_ptr Provides an initial pointer to the API function struct used by
519 * the driver. Can be NULL.
520 */
521 #define SPI_DEVICE_DT_DEFINE(node_id, init_fn, pm_device, \
522 data_ptr, cfg_ptr, level, prio, \
523 api_ptr, ...) \
524 Z_SPI_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
525 Z_SPI_INIT_FN(Z_DEVICE_DT_DEV_ID(node_id), init_fn) \
526 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
527 DEVICE_DT_NAME(node_id), \
528 &UTIL_CAT(Z_DEVICE_DT_DEV_ID(node_id), _init), \
529 pm_device, \
530 data_ptr, cfg_ptr, level, prio, \
531 api_ptr, \
532 &(Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)).devstate), \
533 __VA_ARGS__)
534
spi_transceive_stats(const struct device * dev,int error,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs)535 static inline void spi_transceive_stats(const struct device *dev, int error,
536 const struct spi_buf_set *tx_bufs,
537 const struct spi_buf_set *rx_bufs)
538 {
539 uint32_t tx_bytes;
540 uint32_t rx_bytes;
541
542 if (error) {
543 SPI_STATS_TRANSFER_ERROR_INC(dev);
544 }
545
546 if (tx_bufs) {
547 tx_bytes = tx_bufs->count ? tx_bufs->buffers->len : 0;
548 SPI_STATS_TX_BYTES_INCN(dev, tx_bytes);
549 }
550
551 if (rx_bufs) {
552 rx_bytes = rx_bufs->count ? rx_bufs->buffers->len : 0;
553 SPI_STATS_RX_BYTES_INCN(dev, rx_bytes);
554 }
555 }
556
557 #else /*CONFIG_SPI_STATS*/
558
559 #define SPI_DEVICE_DT_DEFINE(node_id, init_fn, pm, \
560 data, config, level, prio, \
561 api, ...) \
562 Z_DEVICE_STATE_DEFINE(Z_DEVICE_DT_DEV_ID(node_id)); \
563 Z_DEVICE_DEFINE(node_id, Z_DEVICE_DT_DEV_ID(node_id), \
564 DEVICE_DT_NAME(node_id), init_fn, pm, data, config, \
565 level, prio, api, \
566 &Z_DEVICE_STATE_NAME(Z_DEVICE_DT_DEV_ID(node_id)), \
567 __VA_ARGS__)
568
569 #define SPI_STATS_RX_BYTES_INC(dev_)
570 #define SPI_STATS_TX_BYTES_INC(dev_)
571 #define SPI_STATS_TRANSFER_ERROR_INC(dev_)
572
573 #define spi_transceive_stats(dev, error, tx_bufs, rx_bufs)
574
575 #endif /*CONFIG_SPI_STATS*/
576
577 /**
578 * @typedef spi_api_io
579 * @brief Callback API for I/O
580 * See spi_transceive() for argument descriptions
581 */
582 typedef int (*spi_api_io)(const struct device *dev,
583 const struct spi_config *config,
584 const struct spi_buf_set *tx_bufs,
585 const struct spi_buf_set *rx_bufs);
586
587 /**
588 * @brief SPI callback for asynchronous transfer requests
589 *
590 * @param dev SPI device which is notifying of transfer completion or error
591 * @param result Result code of the transfer request. 0 is success, -errno for failure.
592 * @param data Transfer requester supplied data which is passed along to the callback.
593 */
594 typedef void (*spi_callback_t)(const struct device *dev, int result, void *data);
595
596 /**
597 * @typedef spi_api_io
598 * @brief Callback API for asynchronous I/O
599 * See spi_transceive_async() for argument descriptions
600 */
601 typedef int (*spi_api_io_async)(const struct device *dev,
602 const struct spi_config *config,
603 const struct spi_buf_set *tx_bufs,
604 const struct spi_buf_set *rx_bufs,
605 spi_callback_t cb,
606 void *userdata);
607
608 #if defined(CONFIG_SPI_RTIO) || defined(DOXYGEN)
609
610 /**
611 * @typedef spi_api_iodev_submit
612 * @brief Callback API for submitting work to a SPI device with RTIO
613 */
614 typedef void (*spi_api_iodev_submit)(const struct device *dev,
615 struct rtio_iodev_sqe *iodev_sqe);
616 #endif /* CONFIG_SPI_RTIO */
617
618 /**
619 * @typedef spi_api_release
620 * @brief Callback API for unlocking SPI device.
621 * See spi_release() for argument descriptions
622 */
623 typedef int (*spi_api_release)(const struct device *dev,
624 const struct spi_config *config);
625
626
627 /**
628 * @brief SPI driver API
629 * This is the mandatory API any SPI driver needs to expose.
630 */
631 __subsystem struct spi_driver_api {
632 spi_api_io transceive;
633 #ifdef CONFIG_SPI_ASYNC
634 spi_api_io_async transceive_async;
635 #endif /* CONFIG_SPI_ASYNC */
636 #ifdef CONFIG_SPI_RTIO
637 spi_api_iodev_submit iodev_submit;
638 #endif /* CONFIG_SPI_RTIO */
639 spi_api_release release;
640 };
641
642 /**
643 * @brief Check if SPI CS is controlled using a GPIO.
644 *
645 * @param config SPI configuration.
646 * @return true If CS is controlled using a GPIO.
647 * @return false If CS is controlled by hardware or any other means.
648 */
spi_cs_is_gpio(const struct spi_config * config)649 static inline bool spi_cs_is_gpio(const struct spi_config *config)
650 {
651 return config->cs.gpio.port != NULL;
652 }
653
654 /**
655 * @brief Check if SPI CS in @ref spi_dt_spec is controlled using a GPIO.
656 *
657 * @param spec SPI specification from devicetree.
658 * @return true If CS is controlled using a GPIO.
659 * @return false If CS is controlled by hardware or any other means.
660 */
spi_cs_is_gpio_dt(const struct spi_dt_spec * spec)661 static inline bool spi_cs_is_gpio_dt(const struct spi_dt_spec *spec)
662 {
663 return spi_cs_is_gpio(&spec->config);
664 }
665
666 /**
667 * @brief Validate that SPI bus is ready.
668 *
669 * @param spec SPI specification from devicetree
670 *
671 * @retval true if the SPI bus is ready for use.
672 * @retval false if the SPI bus is not ready for use.
673 */
674 __deprecated
spi_is_ready(const struct spi_dt_spec * spec)675 static inline bool spi_is_ready(const struct spi_dt_spec *spec)
676 {
677 /* Validate bus is ready */
678 if (!device_is_ready(spec->bus)) {
679 return false;
680 }
681 /* Validate CS gpio port is ready, if it is used */
682 if (spi_cs_is_gpio_dt(spec) &&
683 !device_is_ready(spec->config.cs.gpio.port)) {
684 return false;
685 }
686 return true;
687 }
688
689 /**
690 * @brief Validate that SPI bus (and CS gpio if defined) is ready.
691 *
692 * @param spec SPI specification from devicetree
693 *
694 * @retval true if the SPI bus is ready for use.
695 * @retval false if the SPI bus (or the CS gpio defined) is not ready for use.
696 */
spi_is_ready_dt(const struct spi_dt_spec * spec)697 static inline bool spi_is_ready_dt(const struct spi_dt_spec *spec)
698 {
699 /* Validate bus is ready */
700 if (!device_is_ready(spec->bus)) {
701 return false;
702 }
703 /* Validate CS gpio port is ready, if it is used */
704 if (spi_cs_is_gpio_dt(spec) &&
705 !device_is_ready(spec->config.cs.gpio.port)) {
706 return false;
707 }
708 return true;
709 }
710
711 /**
712 * @brief Read/write the specified amount of data from the SPI driver.
713 *
714 * @note This function is synchronous.
715 *
716 * @param dev Pointer to the device structure for the driver instance
717 * @param config Pointer to a valid spi_config structure instance.
718 * Pointer-comparison may be used to detect changes from
719 * previous operations.
720 * @param tx_bufs Buffer array where data to be sent originates from,
721 * or NULL if none.
722 * @param rx_bufs Buffer array where data to be read will be written to,
723 * or NULL if none.
724 *
725 * @retval frames Positive number of frames received in slave mode.
726 * @retval 0 If successful in master mode.
727 * @retval -errno Negative errno code on failure.
728 */
729 __syscall int spi_transceive(const struct device *dev,
730 const struct spi_config *config,
731 const struct spi_buf_set *tx_bufs,
732 const struct spi_buf_set *rx_bufs);
733
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)734 static inline int z_impl_spi_transceive(const struct device *dev,
735 const struct spi_config *config,
736 const struct spi_buf_set *tx_bufs,
737 const struct spi_buf_set *rx_bufs)
738 {
739 const struct spi_driver_api *api =
740 (const struct spi_driver_api *)dev->api;
741 int ret;
742
743 ret = api->transceive(dev, config, tx_bufs, rx_bufs);
744 spi_transceive_stats(dev, ret, tx_bufs, rx_bufs);
745
746 return ret;
747 }
748
749 /**
750 * @brief Read/write data from an SPI bus specified in @p spi_dt_spec.
751 *
752 * This is equivalent to:
753 *
754 * spi_transceive(spec->bus, &spec->config, tx_bufs, rx_bufs);
755 *
756 * @param spec SPI specification from devicetree
757 * @param tx_bufs Buffer array where data to be sent originates from,
758 * or NULL if none.
759 * @param rx_bufs Buffer array where data to be read will be written to,
760 * or NULL if none.
761 *
762 * @return a value from spi_transceive().
763 */
spi_transceive_dt(const struct spi_dt_spec * spec,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs)764 static inline int spi_transceive_dt(const struct spi_dt_spec *spec,
765 const struct spi_buf_set *tx_bufs,
766 const struct spi_buf_set *rx_bufs)
767 {
768 return spi_transceive(spec->bus, &spec->config, tx_bufs, rx_bufs);
769 }
770
771 /**
772 * @brief Read the specified amount of data from the SPI driver.
773 *
774 * @note This function is synchronous.
775 *
776 * @note This function is an helper function calling spi_transceive.
777 *
778 * @param dev Pointer to the device structure for the driver instance
779 * @param config Pointer to a valid spi_config structure instance.
780 * Pointer-comparison may be used to detect changes from
781 * previous operations.
782 * @param rx_bufs Buffer array where data to be read will be written to.
783 *
784 * @retval 0 If successful.
785 * @retval -errno Negative errno code on failure.
786 */
spi_read(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * rx_bufs)787 static inline int spi_read(const struct device *dev,
788 const struct spi_config *config,
789 const struct spi_buf_set *rx_bufs)
790 {
791 return spi_transceive(dev, config, NULL, rx_bufs);
792 }
793
794 /**
795 * @brief Read data from a SPI bus specified in @p spi_dt_spec.
796 *
797 * This is equivalent to:
798 *
799 * spi_read(spec->bus, &spec->config, rx_bufs);
800 *
801 * @param spec SPI specification from devicetree
802 * @param rx_bufs Buffer array where data to be read will be written to.
803 *
804 * @return a value from spi_read().
805 */
spi_read_dt(const struct spi_dt_spec * spec,const struct spi_buf_set * rx_bufs)806 static inline int spi_read_dt(const struct spi_dt_spec *spec,
807 const struct spi_buf_set *rx_bufs)
808 {
809 return spi_read(spec->bus, &spec->config, rx_bufs);
810 }
811
812 /**
813 * @brief Write the specified amount of data from the SPI driver.
814 *
815 * @note This function is synchronous.
816 *
817 * @note This function is an helper function calling spi_transceive.
818 *
819 * @param dev Pointer to the device structure for the driver instance
820 * @param config Pointer to a valid spi_config structure instance.
821 * Pointer-comparison may be used to detect changes from
822 * previous operations.
823 * @param tx_bufs Buffer array where data to be sent originates from.
824 *
825 * @retval 0 If successful.
826 * @retval -errno Negative errno code on failure.
827 */
spi_write(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs)828 static inline int spi_write(const struct device *dev,
829 const struct spi_config *config,
830 const struct spi_buf_set *tx_bufs)
831 {
832 return spi_transceive(dev, config, tx_bufs, NULL);
833 }
834
835 /**
836 * @brief Write data to a SPI bus specified in @p spi_dt_spec.
837 *
838 * This is equivalent to:
839 *
840 * spi_write(spec->bus, &spec->config, tx_bufs);
841 *
842 * @param spec SPI specification from devicetree
843 * @param tx_bufs Buffer array where data to be sent originates from.
844 *
845 * @return a value from spi_write().
846 */
spi_write_dt(const struct spi_dt_spec * spec,const struct spi_buf_set * tx_bufs)847 static inline int spi_write_dt(const struct spi_dt_spec *spec,
848 const struct spi_buf_set *tx_bufs)
849 {
850 return spi_write(spec->bus, &spec->config, tx_bufs);
851 }
852
853 /* Doxygen defines this so documentation is generated. */
854 #ifdef CONFIG_SPI_ASYNC
855
856 /**
857 * @brief Read/write the specified amount of data from the SPI driver.
858 *
859 * @note This function is asynchronous.
860 *
861 * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC}
862 * is selected.
863 *
864 * @param dev Pointer to the device structure for the driver instance
865 * @param config Pointer to a valid spi_config structure instance.
866 * Pointer-comparison may be used to detect changes from
867 * previous operations.
868 * @param tx_bufs Buffer array where data to be sent originates from,
869 * or NULL if none.
870 * @param rx_bufs Buffer array where data to be read will be written to,
871 * or NULL if none.
872 * @param callback Function pointer to completion callback.
873 * (Note: if NULL this function will not
874 * notify the end of the transaction, and whether it went
875 * successfully or not).
876 * @param userdata Userdata passed to callback
877 *
878 * @retval frames Positive number of frames received in slave mode.
879 * @retval 0 If successful in master mode.
880 * @retval -errno Negative errno code on failure.
881 */
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)882 static inline int spi_transceive_cb(const struct device *dev,
883 const struct spi_config *config,
884 const struct spi_buf_set *tx_bufs,
885 const struct spi_buf_set *rx_bufs,
886 spi_callback_t callback,
887 void *userdata)
888 {
889 const struct spi_driver_api *api =
890 (const struct spi_driver_api *)dev->api;
891
892 return api->transceive_async(dev, config, tx_bufs, rx_bufs, callback, userdata);
893 }
894
895 #ifdef CONFIG_POLL
896
897 /** @cond INTERNAL_HIDDEN */
898 void z_spi_transfer_signal_cb(const struct device *dev, int result, void *userdata);
899 /** @endcond */
900
901 /**
902 * @brief Read/write the specified amount of data from the SPI driver.
903 *
904 * @note This function is asynchronous.
905 *
906 * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC}
907 * and @kconfig{CONFIG_POLL} are selected.
908 *
909 * @param dev Pointer to the device structure for the driver instance
910 * @param config Pointer to a valid spi_config structure instance.
911 * Pointer-comparison may be used to detect changes from
912 * previous operations.
913 * @param tx_bufs Buffer array where data to be sent originates from,
914 * or NULL if none.
915 * @param rx_bufs Buffer array where data to be read will be written to,
916 * or NULL if none.
917 * @param sig A pointer to a valid and ready to be signaled
918 * struct k_poll_signal. (Note: if NULL this function will not
919 * notify the end of the transaction, and whether it went
920 * successfully or not).
921 *
922 * @retval frames Positive number of frames received in slave mode.
923 * @retval 0 If successful in master mode.
924 * @retval -errno Negative errno code on failure.
925 */
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)926 static inline int spi_transceive_signal(const struct device *dev,
927 const struct spi_config *config,
928 const struct spi_buf_set *tx_bufs,
929 const struct spi_buf_set *rx_bufs,
930 struct k_poll_signal *sig)
931 {
932 const struct spi_driver_api *api =
933 (const struct spi_driver_api *)dev->api;
934 spi_callback_t cb = (sig == NULL) ? NULL : z_spi_transfer_signal_cb;
935
936 return api->transceive_async(dev, config, tx_bufs, rx_bufs, cb, sig);
937 }
938
939 /**
940 * @brief Alias for spi_transceive_signal for backwards compatibility
941 *
942 * @deprecated
943 * @see spi_transceive_signal
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 an 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
989 * @see spi_read_signal
990 */
spi_read_async(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * rx_bufs,struct k_poll_signal * sig)991 __deprecated static inline int spi_read_async(const struct device *dev,
992 const struct spi_config *config,
993 const struct spi_buf_set *rx_bufs,
994 struct k_poll_signal *sig)
995 {
996 return spi_read_signal(dev, config, rx_bufs, sig);
997 }
998
999 /**
1000 * @brief Write the specified amount of data from the SPI driver.
1001 *
1002 * @note This function is asynchronous.
1003 *
1004 * @note This function is an helper function calling spi_transceive_async.
1005 *
1006 * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC}
1007 * and @kconfig{CONFIG_POLL} are selected.
1008 *
1009 * @param dev Pointer to the device structure for the driver instance
1010 * @param config Pointer to a valid spi_config structure instance.
1011 * Pointer-comparison may be used to detect changes from
1012 * previous operations.
1013 * @param tx_bufs Buffer array where data to be sent originates from.
1014 * @param sig A pointer to a valid and ready to be signaled
1015 * struct k_poll_signal. (Note: if NULL this function will not
1016 * notify the end of the transaction, and whether it went
1017 * successfully or not).
1018 *
1019 * @retval 0 If successful.
1020 * @retval -errno Negative errno code on failure.
1021 */
spi_write_signal(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,struct k_poll_signal * sig)1022 static inline int spi_write_signal(const struct device *dev,
1023 const struct spi_config *config,
1024 const struct spi_buf_set *tx_bufs,
1025 struct k_poll_signal *sig)
1026 {
1027 return spi_transceive_signal(dev, config, tx_bufs, NULL, sig);
1028 }
1029
1030 /**
1031 * @brief Alias for spi_read_signal for backwards compatibility
1032 *
1033 * @deprecated
1034 * @see spi_read_signal
1035 */
spi_write_async(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,struct k_poll_signal * sig)1036 __deprecated static inline int spi_write_async(const struct device *dev,
1037 const struct spi_config *config,
1038 const struct spi_buf_set *tx_bufs,
1039 struct k_poll_signal *sig)
1040 {
1041 return spi_write_signal(dev, config, tx_bufs, sig);
1042 }
1043
1044 #endif /* CONFIG_POLL */
1045
1046 #endif /* CONFIG_SPI_ASYNC */
1047
1048
1049 #if defined(CONFIG_SPI_RTIO) || defined(DOXYGEN)
1050
1051 /**
1052 * @brief Submit a SPI device with a request
1053 *
1054 * @param dev SPI device
1055 * @param iodev_sqe Prepared submissions queue entry connected to an iodev
1056 * defined by SPI_IODEV_DEFINE.
1057 * Must live as long as the request is in flight.
1058 *
1059 * @retval 0 If successful.
1060 * @retval -errno Negative errno code on failure.
1061 */
spi_iodev_submit(struct rtio_iodev_sqe * iodev_sqe)1062 static inline void spi_iodev_submit(struct rtio_iodev_sqe *iodev_sqe)
1063 {
1064 const struct spi_dt_spec *dt_spec = iodev_sqe->sqe.iodev->data;
1065 const struct device *dev = dt_spec->bus;
1066 const struct spi_driver_api *api = (const struct spi_driver_api *)dev->api;
1067
1068 api->iodev_submit(dt_spec->bus, iodev_sqe);
1069 }
1070
1071 extern const struct rtio_iodev_api spi_iodev_api;
1072
1073 /**
1074 * @brief Define an iodev for a given dt node on the bus
1075 *
1076 * These do not need to be shared globally but doing so
1077 * will save a small amount of memory.
1078 *
1079 * @param node DT_NODE
1080 */
1081 #define SPI_DT_IODEV_DEFINE(name, node_id, operation_, delay_) \
1082 const struct spi_dt_spec _spi_dt_spec_##name = \
1083 SPI_DT_SPEC_GET(node_id, operation_, delay_); \
1084 RTIO_IODEV_DEFINE(name, &spi_iodev_api, (void *)&_spi_dt_spec_##name)
1085
1086 /**
1087 * @brief Validate that SPI bus (and CS gpio if defined) is ready.
1088 *
1089 * @param spi_iodev SPI iodev defined with SPI_DT_IODEV_DEFINE
1090 *
1091 * @retval true if the SPI bus is ready for use.
1092 * @retval false if the SPI bus (or the CS gpio defined) is not ready for use.
1093 */
spi_is_ready_iodev(const struct rtio_iodev * spi_iodev)1094 static inline bool spi_is_ready_iodev(const struct rtio_iodev *spi_iodev)
1095 {
1096 struct spi_dt_spec *spec = spi_iodev->data;
1097
1098 return spi_is_ready_dt(spec);
1099 }
1100
1101 /**
1102 * @brief Copy the tx_bufs and rx_bufs into a set of RTIO requests
1103 *
1104 * @param r rtio context
1105 * @param iodev iodev to transceive with
1106 * @param tx_bufs transmit buffer set
1107 * @param rx_bufs receive buffer set
1108 * @param sqe[out] Last sqe submitted, NULL if not enough memory
1109 *
1110 * @retval Number of submission queue entries
1111 * @retval -ENOMEM out of memory
1112 */
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)1113 static inline int spi_rtio_copy(struct rtio *r,
1114 struct rtio_iodev *iodev,
1115 const struct spi_buf_set *tx_bufs,
1116 const struct spi_buf_set *rx_bufs,
1117 struct rtio_sqe **last_sqe)
1118 {
1119 int ret = 0;
1120 size_t tx_count = tx_bufs ? tx_bufs->count : 0;
1121 size_t rx_count = rx_bufs ? rx_bufs->count : 0;
1122
1123 uint32_t tx = 0, tx_len = 0;
1124 uint32_t rx = 0, rx_len = 0;
1125 uint8_t *tx_buf, *rx_buf;
1126
1127 struct rtio_sqe *sqe = NULL;
1128
1129 if (tx < tx_count) {
1130 tx_buf = tx_bufs->buffers[tx].buf;
1131 tx_len = tx_bufs->buffers[tx].len;
1132 } else {
1133 tx_buf = NULL;
1134 tx_len = rx_bufs->buffers[rx].len;
1135 }
1136
1137 if (rx < rx_count) {
1138 rx_buf = rx_bufs->buffers[rx].buf;
1139 rx_len = rx_bufs->buffers[rx].len;
1140 } else {
1141 rx_buf = NULL;
1142 rx_len = tx_bufs->buffers[tx].len;
1143 }
1144
1145
1146 while ((tx < tx_count || rx < rx_count) && (tx_len > 0 || rx_len > 0)) {
1147 sqe = rtio_sqe_acquire(r);
1148
1149 if (sqe == NULL) {
1150 ret = -ENOMEM;
1151 rtio_sqe_drop_all(r);
1152 goto out;
1153 }
1154
1155 ret++;
1156
1157 /* If tx/rx len are same, we can do a simple transceive */
1158 if (tx_len == rx_len) {
1159 if (tx_buf == NULL) {
1160 rtio_sqe_prep_read(sqe, iodev, RTIO_PRIO_NORM,
1161 rx_buf, rx_len, NULL);
1162 } else if (rx_buf == NULL) {
1163 rtio_sqe_prep_write(sqe, iodev, RTIO_PRIO_NORM,
1164 tx_buf, tx_len, NULL);
1165 } else {
1166 rtio_sqe_prep_transceive(sqe, iodev, RTIO_PRIO_NORM,
1167 tx_buf, rx_buf, rx_len, NULL);
1168 }
1169 tx++;
1170 rx++;
1171 if (rx < rx_count) {
1172 rx_buf = rx_bufs->buffers[rx].buf;
1173 rx_len = rx_bufs->buffers[rx].len;
1174 } else {
1175 rx_buf = NULL;
1176 rx_len = 0;
1177 }
1178 if (tx < tx_count) {
1179 tx_buf = tx_bufs->buffers[tx].buf;
1180 tx_len = tx_bufs->buffers[tx].len;
1181 } else {
1182 tx_buf = NULL;
1183 tx_len = 0;
1184 }
1185 } else if (tx_len == 0) {
1186 rtio_sqe_prep_read(sqe, iodev, RTIO_PRIO_NORM,
1187 (uint8_t *)rx_buf,
1188 (uint32_t)rx_len,
1189 NULL);
1190 rx++;
1191 if (rx < rx_count) {
1192 rx_buf = rx_bufs->buffers[rx].buf;
1193 rx_len = rx_bufs->buffers[rx].len;
1194 } else {
1195 rx_buf = NULL;
1196 rx_len = 0;
1197 }
1198 } else if (rx_len == 0) {
1199 rtio_sqe_prep_write(sqe, iodev, RTIO_PRIO_NORM,
1200 (uint8_t *)tx_buf,
1201 (uint32_t)tx_len,
1202 NULL);
1203 tx++;
1204 if (tx < tx_count) {
1205 tx_buf = rx_bufs->buffers[rx].buf;
1206 tx_len = rx_bufs->buffers[rx].len;
1207 } else {
1208 tx_buf = NULL;
1209 tx_len = 0;
1210 }
1211 } else if (tx_len > rx_len) {
1212 rtio_sqe_prep_transceive(sqe, iodev, RTIO_PRIO_NORM,
1213 (uint8_t *)tx_buf,
1214 (uint8_t *)rx_buf,
1215 (uint32_t)rx_len,
1216 NULL);
1217 tx_len -= rx_len;
1218 tx_buf += rx_len;
1219 rx++;
1220 if (rx < rx_count) {
1221 rx_buf = rx_bufs->buffers[rx].buf;
1222 rx_len = rx_bufs->buffers[rx].len;
1223 } else {
1224 rx_buf = NULL;
1225 rx_len = tx_len;
1226 }
1227 } else if (rx_len > tx_len) {
1228 rtio_sqe_prep_transceive(sqe, iodev, RTIO_PRIO_NORM,
1229 (uint8_t *)tx_buf,
1230 (uint8_t *)rx_buf,
1231 (uint32_t)tx_len,
1232 NULL);
1233 rx_len -= tx_len;
1234 rx_buf += tx_len;
1235 tx++;
1236 if (tx < tx_count) {
1237 tx_buf = tx_bufs->buffers[tx].buf;
1238 tx_len = tx_bufs->buffers[tx].len;
1239 } else {
1240 tx_buf = NULL;
1241 tx_len = rx_len;
1242 }
1243 } else {
1244 __ASSERT_NO_MSG("Invalid spi_rtio_copy state");
1245 }
1246
1247 sqe->flags = RTIO_SQE_TRANSACTION;
1248 }
1249
1250 if (sqe != NULL) {
1251 sqe->flags = 0;
1252 *last_sqe = sqe;
1253 }
1254
1255 out:
1256 return ret;
1257 }
1258
1259 #endif /* CONFIG_SPI_RTIO */
1260
1261 /**
1262 * @brief Release the SPI device locked on and/or the CS by the current config
1263 *
1264 * Note: This synchronous function is used to release either the lock on the
1265 * SPI device and/or the CS line that was kept if, and if only,
1266 * given config parameter was the last one to be used (in any of the
1267 * above functions) and if it has the SPI_LOCK_ON bit set and/or the
1268 * SPI_HOLD_ON_CS bit set into its operation bits field.
1269 * This can be used if the caller needs to keep its hand on the SPI
1270 * device for consecutive transactions and/or if it needs the device to
1271 * stay selected. Usually both bits will be used along each other, so the
1272 * the device is locked and stays on until another operation is necessary
1273 * or until it gets released with the present function.
1274 *
1275 * @param dev Pointer to the device structure for the driver instance
1276 * @param config Pointer to a valid spi_config structure instance.
1277 *
1278 * @retval 0 If successful.
1279 * @retval -errno Negative errno code on failure.
1280 */
1281 __syscall int spi_release(const struct device *dev,
1282 const struct spi_config *config);
1283
z_impl_spi_release(const struct device * dev,const struct spi_config * config)1284 static inline int z_impl_spi_release(const struct device *dev,
1285 const struct spi_config *config)
1286 {
1287 const struct spi_driver_api *api =
1288 (const struct spi_driver_api *)dev->api;
1289
1290 return api->release(dev, config);
1291 }
1292
1293 /**
1294 * @brief Release the SPI device specified in @p spi_dt_spec.
1295 *
1296 * This is equivalent to:
1297 *
1298 * spi_release(spec->bus, &spec->config);
1299 *
1300 * @param spec SPI specification from devicetree
1301 *
1302 * @return a value from spi_release().
1303 */
spi_release_dt(const struct spi_dt_spec * spec)1304 static inline int spi_release_dt(const struct spi_dt_spec *spec)
1305 {
1306 return spi_release(spec->bus, &spec->config);
1307 }
1308
1309 #ifdef __cplusplus
1310 }
1311 #endif
1312
1313 /**
1314 * @}
1315 */
1316
1317 #include <syscalls/spi.h>
1318
1319 #endif /* ZEPHYR_INCLUDE_DRIVERS_SPI_H_ */
1320