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 <device.h>
25 #include <drivers/gpio.h>
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 /**
32  * @brief SPI operational mode
33  */
34 #define SPI_OP_MODE_MASTER	0
35 #define SPI_OP_MODE_SLAVE	BIT(0)
36 #define SPI_OP_MODE_MASK	0x1
37 #define SPI_OP_MODE_GET(_operation_) ((_operation_) & SPI_OP_MODE_MASK)
38 
39 /**
40  * @brief SPI Polarity & Phase Modes
41  */
42 
43 /**
44  * Clock Polarity: if set, clock idle state will be 1
45  * and active state will be 0. If untouched, the inverse will be true
46  * which is the default.
47  */
48 #define SPI_MODE_CPOL		BIT(1)
49 
50 /**
51  * Clock Phase: this dictates when is the data captured, and depends
52  * clock's polarity. When SPI_MODE_CPOL is set and this bit as well,
53  * capture will occur on low to high transition and high to low if
54  * this bit is not set (default). This is fully reversed if CPOL is
55  * not set.
56  */
57 #define SPI_MODE_CPHA		BIT(2)
58 
59 /**
60  * Whatever data is transmitted is looped-back to the receiving buffer of
61  * the controller. This is fully controller dependent as some may not
62  * support this, and can be used for testing purposes only.
63  */
64 #define SPI_MODE_LOOP		BIT(3)
65 
66 #define SPI_MODE_MASK		(0xE)
67 #define SPI_MODE_GET(_mode_)			\
68 	((_mode_) & SPI_MODE_MASK)
69 
70 /**
71  * @brief SPI Transfer modes (host controller dependent)
72  */
73 #define SPI_TRANSFER_MSB	(0)
74 #define SPI_TRANSFER_LSB	BIT(4)
75 
76 /**
77  * @brief SPI word size
78  */
79 #define SPI_WORD_SIZE_SHIFT	(5)
80 #define SPI_WORD_SIZE_MASK	(0x3F << SPI_WORD_SIZE_SHIFT)
81 #define SPI_WORD_SIZE_GET(_operation_)					\
82 	(((_operation_) & SPI_WORD_SIZE_MASK) >> SPI_WORD_SIZE_SHIFT)
83 
84 #define SPI_WORD_SET(_word_size_)		\
85 	((_word_size_) << SPI_WORD_SIZE_SHIFT)
86 
87 /**
88  * @brief SPI MISO lines
89  *
90  * Some controllers support dual, quad or octal MISO lines connected to slaves.
91  * Default is single, which is the case most of the time.
92  */
93 #define SPI_LINES_SINGLE	(0 << 11)
94 #define SPI_LINES_DUAL		(1 << 11)
95 #define SPI_LINES_QUAD		(2 << 11)
96 #define SPI_LINES_OCTAL		(3 << 11)
97 
98 #define SPI_LINES_MASK		(0x3 << 11)
99 
100 /**
101  * @brief Specific SPI devices control bits
102  */
103 /* Requests - if possible - to keep CS asserted after the transaction */
104 #define SPI_HOLD_ON_CS		BIT(13)
105 /* Keep the device locked after the transaction for the current config.
106  * Use this with extreme caution (see spi_release() below) as it will
107  * prevent other callers to access the SPI device until spi_release() is
108  * properly called.
109  */
110 #define SPI_LOCK_ON		BIT(14)
111 
112 /* Active high logic on CS - Usually, and by default, CS logic is active
113  * low. However, some devices may require the reverse logic: active high.
114  * This bit will request the controller to use that logic. Note that not
115  * all controllers are able to handle that natively. In this case deferring
116  * the CS control to a gpio line through struct spi_cs_control would be
117  * the solution.
118  */
119 #define SPI_CS_ACTIVE_HIGH	BIT(15)
120 
121 /**
122  * @brief SPI Chip Select control structure
123  *
124  * This can be used to control a CS line via a GPIO line, instead of
125  * using the controller inner CS logic.
126  *
127  * @param gpio_dev is a valid pointer to an actual GPIO device. A NULL pointer
128  *        can be provided to full inhibit CS control if necessary.
129  * @param gpio_pin is a number representing the gpio PIN that will be used
130  *    to act as a CS line
131  * @param delay is a delay in microseconds to wait before starting the
132  *    transmission and before releasing the CS line
133  * @param gpio_dt_flags is the devicetree flags corresponding to how the CS
134  *    line should be driven. GPIO_ACTIVE_LOW/GPIO_ACTIVE_HIGH should be
135  *    equivalent to SPI_CS_ACTIVE_HIGH/SPI_CS_ACTIVE_LOW options in struct
136  *    spi_config.
137  */
138 struct spi_cs_control {
139 	const struct device	*gpio_dev;
140 	uint32_t		delay;
141 	gpio_pin_t		gpio_pin;
142 	gpio_dt_flags_t		gpio_dt_flags;
143 };
144 
145 #ifndef __cplusplus
146 /**
147  * @brief Initialize and get a pointer to a @p spi_cs_control from a
148  *        devicetree node identifier
149  *
150  * This helper is useful for initializing a device on a SPI bus. It
151  * initializes a struct spi_cs_control and returns a pointer to it.
152  * Here, @p node_id is a node identifier for a SPI device, not a SPI
153  * controller.
154  *
155  * Example devicetree fragment:
156  *
157  *     spi@... {
158  *             cs-gpios = <&gpio0 1 GPIO_ACTIVE_LOW>;
159  *             spidev: spi-device@0 { ... };
160  *     };
161  *
162  * Assume that @p gpio0 follows the standard convention for specifying
163  * GPIOs, i.e. it has the following in its binding:
164  *
165  *     gpio-cells:
166  *     - pin
167  *     - flags
168  *
169  * Example usage:
170  *
171  *     struct spi_cs_control *ctrl =
172  *             SPI_CS_CONTROL_PTR_DT(DT_NODELABEL(spidev), 2);
173  *
174  * This example is equivalent to:
175  *
176  *     struct spi_cs_control *ctrl =
177  *             &(struct spi_cs_control) {
178  *                     .gpio_dev = DEVICE_DT_GET(DT_NODELABEL(gpio0)),
179  *                     .delay = 2,
180  *                     .gpio_pin = 1,
181  *                     .gpio_dt_flags = GPIO_ACTIVE_LOW
182  *             };
183  *
184  * This macro is not available in C++.
185  *
186  * @param node_id Devicetree node identifier for a device on a SPI bus
187  * @param delay_ The @p delay field to set in the @p spi_cs_control
188  * @return a pointer to the @p spi_cs_control structure
189  */
190 #define SPI_CS_CONTROL_PTR_DT(node_id, delay_)				\
191 	(&(struct spi_cs_control) {						\
192 		.gpio_dev = DEVICE_DT_GET(				\
193 			DT_SPI_DEV_CS_GPIOS_CTLR(node_id)),		\
194 		.delay = (delay_),					\
195 		.gpio_pin = DT_SPI_DEV_CS_GPIOS_PIN(node_id),		\
196 		.gpio_dt_flags = DT_SPI_DEV_CS_GPIOS_FLAGS(node_id),	\
197 	})
198 
199 /**
200  * @brief Get a pointer to a @p spi_cs_control from a devicetree node
201  *
202  * This is equivalent to
203  * <tt>SPI_CS_CONTROL_PTR_DT(DT_DRV_INST(inst), delay)</tt>.
204  *
205  * Therefore, @p DT_DRV_COMPAT must already be defined before using
206  * this macro.
207  *
208  * This macro is not available in C++.
209  *
210  * @param inst Devicetree node instance number
211  * @param delay_ The @p delay field to set in the @p spi_cs_control
212  * @return a pointer to the @p spi_cs_control structure
213  */
214 #define SPI_CS_CONTROL_PTR_DT_INST(inst, delay_)		\
215 	SPI_CS_CONTROL_PTR_DT(DT_DRV_INST(inst), delay_)
216 #endif
217 
218 /**
219  * @brief SPI controller configuration structure
220  *
221  * @param frequency is the bus frequency in Hertz
222  * @param operation is a bit field with the following parts:
223  *
224  *     operational mode    [ 0 ]       - master or slave.
225  *     mode                [ 1 : 3 ]   - Polarity, phase and loop mode.
226  *     transfer            [ 4 ]       - LSB or MSB first.
227  *     word_size           [ 5 : 10 ]  - Size of a data frame in bits.
228  *     lines               [ 11 : 12 ] - MISO lines: Single/Dual/Quad/Octal.
229  *     cs_hold             [ 13 ]      - Hold on the CS line if possible.
230  *     lock_on             [ 14 ]      - Keep resource locked for the caller.
231  *     cs_active_high      [ 15 ]      - Active high CS logic.
232  * @param slave is the slave number from 0 to host controller slave limit.
233  * @param cs is a valid pointer on a struct spi_cs_control is CS line is
234  *    emulated through a gpio line, or NULL otherwise.
235  *
236  * @note Only cs_hold and lock_on can be changed between consecutive
237  * transceive call. Rest of the attributes are not meant to be tweaked.
238  *
239  * @warning Most drivers use pointer comparison to determine whether a
240  * passed configuration is different from one used in a previous
241  * transaction.  Changes to fields in the structure may not be
242  * detected.
243  */
244 struct spi_config {
245 	uint32_t		frequency;
246 	uint16_t		operation;
247 	uint16_t		slave;
248 
249 	const struct spi_cs_control *cs;
250 };
251 
252 #ifndef __cplusplus
253 /**
254  * @brief Structure initializer for spi_config from devicetree
255  *
256  * This helper macro expands to a static initializer for a <tt>struct
257  * spi_config</tt> by reading the relevant @p frequency, @p slave, and
258  * @p cs data from the devicetree.
259  *
260  * Important: the @p cs field is initialized using
261  * SPI_CS_CONTROL_PTR_DT(). The @p gpio_dev value pointed to by this
262  * structure must be checked using device_is_ready() before use.
263  *
264  * This macro is not available in C++.
265  *
266  * @param node_id Devicetree node identifier for the SPI device whose
267  *                struct spi_config to create an initializer for
268  * @param operation_ the desired @p operation field in the struct spi_config
269  * @param delay_ the desired @p delay field in the struct spi_config's
270  *               spi_cs_control, if there is one
271  */
272 #define SPI_CONFIG_DT(node_id, operation_, delay_)			\
273 	{								\
274 		.frequency = DT_PROP(node_id, spi_max_frequency),	\
275 		.operation = (operation_),				\
276 		.slave = DT_REG_ADDR(node_id),				\
277 		.cs = COND_CODE_1(					\
278 			DT_SPI_DEV_HAS_CS_GPIOS(node_id),		\
279 			(SPI_CS_CONTROL_PTR_DT(node_id, delay_)),	\
280 			(NULL)),					\
281 	}
282 
283 /**
284  * @brief Structure initializer for spi_config from devicetree instance
285  *
286  * This is equivalent to
287  * <tt>SPI_CONFIG_DT(DT_DRV_INST(inst), operation_, delay_)</tt>.
288  *
289  * This macro is not available in C++.
290  *
291  * @param inst Devicetree instance number
292  * @param operation_ the desired @p operation field in the struct spi_config
293  * @param delay_ the desired @p delay field in the struct spi_config's
294  *               spi_cs_control, if there is one
295  */
296 #define SPI_CONFIG_DT_INST(inst, operation_, delay_)	\
297 	SPI_CONFIG_DT(DT_DRV_INST(inst), operation_, delay_)
298 #endif
299 
300 /**
301  * @brief Complete SPI DT information
302  *
303  * @param bus is the SPI bus
304  * @param config is the slave specific configuration
305  */
306 struct spi_dt_spec {
307 	const struct device *bus;
308 	struct spi_config config;
309 };
310 
311 #ifndef __cplusplus
312 /**
313  * @brief Structure initializer for spi_dt_spec from devicetree
314  *
315  * This helper macro expands to a static initializer for a <tt>struct
316  * spi_dt_spec</tt> by reading the relevant bus, frequency, slave, and cs
317  * data from the devicetree.
318  *
319  * Important: multiple fields are automatically constructed by this macro
320  * which must be checked before use. @ref spi_is_ready performs the required
321  * @ref device_is_ready checks.
322  *
323  * This macro is not available in C++.
324  *
325  * @param node_id Devicetree node identifier for the SPI device whose
326  *                struct spi_dt_spec to create an initializer for
327  * @param operation_ the desired @p operation field in the struct spi_config
328  * @param delay_ the desired @p delay field in the struct spi_config's
329  *               spi_cs_control, if there is one
330  */
331 #define SPI_DT_SPEC_GET(node_id, operation_, delay_)		     \
332 	{							     \
333 		.bus = DEVICE_DT_GET(DT_BUS(node_id)),		     \
334 		.config = SPI_CONFIG_DT(node_id, operation_, delay_) \
335 	}
336 
337 /**
338  * @brief Structure initializer for spi_dt_spec from devicetree instance
339  *
340  * This is equivalent to
341  * <tt>SPI_DT_SPEC_GET(DT_DRV_INST(inst), operation_, delay_)</tt>.
342  *
343  * This macro is not available in C++.
344  *
345  * @param inst Devicetree instance number
346  * @param operation_ the desired @p operation field in the struct spi_config
347  * @param delay_ the desired @p delay field in the struct spi_config's
348  *               spi_cs_control, if there is one
349  */
350 #define SPI_DT_SPEC_INST_GET(inst, operation_, delay_) \
351 	SPI_DT_SPEC_GET(DT_DRV_INST(inst), operation_, delay_)
352 #endif
353 
354 /**
355  * @brief SPI buffer structure
356  *
357  * @param buf is a valid pointer on a data buffer, or NULL otherwise.
358  * @param len is the length of the buffer or, if buf is NULL, will be the
359  *    length which as to be sent as dummy bytes (as TX buffer) or
360  *    the length of bytes that should be skipped (as RX buffer).
361  */
362 struct spi_buf {
363 	void *buf;
364 	size_t len;
365 };
366 
367 /**
368  * @brief SPI buffer array structure
369  *
370  * @param buffers is a valid pointer on an array of spi_buf, or NULL.
371  * @param count is the length of the array pointed by buffers.
372  */
373 struct spi_buf_set {
374 	const struct spi_buf *buffers;
375 	size_t count;
376 };
377 
378 /**
379  * @typedef spi_api_io
380  * @brief Callback API for I/O
381  * See spi_transceive() for argument descriptions
382  */
383 typedef int (*spi_api_io)(const struct device *dev,
384 			  const struct spi_config *config,
385 			  const struct spi_buf_set *tx_bufs,
386 			  const struct spi_buf_set *rx_bufs);
387 
388 /**
389  * @typedef spi_api_io
390  * @brief Callback API for asynchronous I/O
391  * See spi_transceive_async() for argument descriptions
392  */
393 typedef int (*spi_api_io_async)(const struct device *dev,
394 				const struct spi_config *config,
395 				const struct spi_buf_set *tx_bufs,
396 				const struct spi_buf_set *rx_bufs,
397 				struct k_poll_signal *async);
398 
399 /**
400  * @typedef spi_api_release
401  * @brief Callback API for unlocking SPI device.
402  * See spi_release() for argument descriptions
403  */
404 typedef int (*spi_api_release)(const struct device *dev,
405 			       const struct spi_config *config);
406 
407 
408 /**
409  * @brief SPI driver API
410  * This is the mandatory API any SPI driver needs to expose.
411  */
412 __subsystem struct spi_driver_api {
413 	spi_api_io transceive;
414 #ifdef CONFIG_SPI_ASYNC
415 	spi_api_io_async transceive_async;
416 #endif /* CONFIG_SPI_ASYNC */
417 	spi_api_release release;
418 };
419 
420 /**
421  * @brief Validate that SPI bus is ready.
422  *
423  * @param spec SPI specification from devicetree
424  *
425  * @retval true if the SPI bus is ready for use.
426  * @retval false if the SPI bus is not ready for use.
427  */
spi_is_ready(const struct spi_dt_spec * spec)428 static inline bool spi_is_ready(const struct spi_dt_spec *spec)
429 {
430 	/* Validate bus is ready */
431 	if (!device_is_ready(spec->bus)) {
432 		return false;
433 	}
434 	/* Validate CS gpio port is ready, if it is used */
435 	if (spec->config.cs &&
436 	    !device_is_ready(spec->config.cs->gpio_dev)) {
437 		return false;
438 	}
439 	return true;
440 }
441 
442 /**
443  * @brief Read/write the specified amount of data from the SPI driver.
444  *
445  * @note This function is synchronous.
446  *
447  * @param dev Pointer to the device structure for the driver instance
448  * @param config Pointer to a valid spi_config structure instance.
449  *        Pointer-comparison may be used to detect changes from
450  *        previous operations.
451  * @param tx_bufs Buffer array where data to be sent originates from,
452  *        or NULL if none.
453  * @param rx_bufs Buffer array where data to be read will be written to,
454  *        or NULL if none.
455  *
456  * @retval frames Positive number of frames received in slave mode.
457  * @retval 0 If successful in master mode.
458  * @retval -errno Negative errno code on failure.
459  */
460 __syscall int spi_transceive(const struct device *dev,
461 			     const struct spi_config *config,
462 			     const struct spi_buf_set *tx_bufs,
463 			     const struct spi_buf_set *rx_bufs);
464 
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)465 static inline int z_impl_spi_transceive(const struct device *dev,
466 					const struct spi_config *config,
467 					const struct spi_buf_set *tx_bufs,
468 					const struct spi_buf_set *rx_bufs)
469 {
470 	const struct spi_driver_api *api =
471 		(const struct spi_driver_api *)dev->api;
472 
473 	return api->transceive(dev, config, tx_bufs, rx_bufs);
474 }
475 
476 /**
477  * @brief Read/write data from an SPI bus specified in @p spi_dt_spec.
478  *
479  * This is equivalent to:
480  *
481  *     spi_transceive(spec->bus, &spec->config, tx_bufs, rx_bufs);
482  *
483  * @param spec SPI specification from devicetree
484  * @param tx_bufs Buffer array where data to be sent originates from,
485  *        or NULL if none.
486  * @param rx_bufs Buffer array where data to be read will be written to,
487  *        or NULL if none.
488  *
489  * @return a value from spi_transceive().
490  */
spi_transceive_dt(const struct spi_dt_spec * spec,const struct spi_buf_set * tx_bufs,const struct spi_buf_set * rx_bufs)491 static inline int spi_transceive_dt(const struct spi_dt_spec *spec,
492 				    const struct spi_buf_set *tx_bufs,
493 				    const struct spi_buf_set *rx_bufs)
494 {
495 	return spi_transceive(spec->bus, &spec->config, tx_bufs, rx_bufs);
496 }
497 
498 /**
499  * @brief Read the specified amount of data from the SPI driver.
500  *
501  * @note This function is synchronous.
502  *
503  * @note This function is an helper function calling spi_transceive.
504  *
505  * @param dev Pointer to the device structure for the driver instance
506  * @param config Pointer to a valid spi_config structure instance.
507  *        Pointer-comparison may be used to detect changes from
508  *        previous operations.
509  * @param rx_bufs Buffer array where data to be read will be written to.
510  *
511  * @retval 0 If successful.
512  * @retval -errno Negative errno code on failure.
513  */
spi_read(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * rx_bufs)514 static inline int spi_read(const struct device *dev,
515 			   const struct spi_config *config,
516 			   const struct spi_buf_set *rx_bufs)
517 {
518 	return spi_transceive(dev, config, NULL, rx_bufs);
519 }
520 
521 /**
522  * @brief Read data from a SPI bus specified in @p spi_dt_spec.
523  *
524  * This is equivalent to:
525  *
526  *     spi_read(spec->bus, &spec->config, rx_bufs);
527  *
528  * @param spec SPI specification from devicetree
529  * @param rx_bufs Buffer array where data to be read will be written to.
530  *
531  * @return a value from spi_read().
532  */
spi_read_dt(const struct spi_dt_spec * spec,const struct spi_buf_set * rx_bufs)533 static inline int spi_read_dt(const struct spi_dt_spec *spec,
534 			      const struct spi_buf_set *rx_bufs)
535 {
536 	return spi_read(spec->bus, &spec->config, rx_bufs);
537 }
538 
539 /**
540  * @brief Write the specified amount of data from the SPI driver.
541  *
542  * @note This function is synchronous.
543  *
544  * @note This function is an helper function calling spi_transceive.
545  *
546  * @param dev Pointer to the device structure for the driver instance
547  * @param config Pointer to a valid spi_config structure instance.
548  *        Pointer-comparison may be used to detect changes from
549  *        previous operations.
550  * @param tx_bufs Buffer array where data to be sent originates from.
551  *
552  * @retval 0 If successful.
553  * @retval -errno Negative errno code on failure.
554  */
spi_write(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs)555 static inline int spi_write(const struct device *dev,
556 			    const struct spi_config *config,
557 			    const struct spi_buf_set *tx_bufs)
558 {
559 	return spi_transceive(dev, config, tx_bufs, NULL);
560 }
561 
562 /**
563  * @brief Write data to a SPI bus specified in @p spi_dt_spec.
564  *
565  * This is equivalent to:
566  *
567  *     spi_write(spec->bus, &spec->config, tx_bufs);
568  *
569  * @param spec SPI specification from devicetree
570  * @param tx_bufs Buffer array where data to be sent originates from.
571  *
572  * @return a value from spi_write().
573  */
spi_write_dt(const struct spi_dt_spec * spec,const struct spi_buf_set * tx_bufs)574 static inline int spi_write_dt(const struct spi_dt_spec *spec,
575 			       const struct spi_buf_set *tx_bufs)
576 {
577 	return spi_write(spec->bus, &spec->config, tx_bufs);
578 }
579 
580 /* Doxygen defines this so documentation is generated. */
581 #ifdef CONFIG_SPI_ASYNC
582 
583 /**
584  * @brief Read/write the specified amount of data from the SPI driver.
585  *
586  * @note This function is asynchronous.
587  *
588  * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC}
589  * is selected.
590  *
591  * @param dev Pointer to the device structure for the driver instance
592  * @param config Pointer to a valid spi_config structure instance.
593  *        Pointer-comparison may be used to detect changes from
594  *        previous operations.
595  * @param tx_bufs Buffer array where data to be sent originates from,
596  *        or NULL if none.
597  * @param rx_bufs Buffer array where data to be read will be written to,
598  *        or NULL if none.
599  * @param async A pointer to a valid and ready to be signaled
600  *        struct k_poll_signal. (Note: if NULL this function will not
601  *        notify the end of the transaction, and whether it went
602  *        successfully or not).
603  *
604  * @retval frames Positive number of frames received in slave mode.
605  * @retval 0 If successful in master mode.
606  * @retval -errno Negative errno code on failure.
607  */
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 * async)608 static inline int spi_transceive_async(const struct device *dev,
609 				       const struct spi_config *config,
610 				       const struct spi_buf_set *tx_bufs,
611 				       const struct spi_buf_set *rx_bufs,
612 				       struct k_poll_signal *async)
613 {
614 	const struct spi_driver_api *api =
615 		(const struct spi_driver_api *)dev->api;
616 
617 	return api->transceive_async(dev, config, tx_bufs, rx_bufs, async);
618 }
619 
620 /**
621  * @brief Read the specified amount of data from the SPI driver.
622  *
623  * @note This function is asynchronous.
624  *
625  * @note This function is an helper function calling spi_transceive_async.
626  *
627  * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC}
628  * is selected.
629  *
630  * @param dev Pointer to the device structure for the driver instance
631  * @param config Pointer to a valid spi_config structure instance.
632  *        Pointer-comparison may be used to detect changes from
633  *        previous operations.
634  * @param rx_bufs Buffer array where data to be read will be written to.
635  * @param async A pointer to a valid and ready to be signaled
636  *        struct k_poll_signal. (Note: if NULL this function will not
637  *        notify the end of the transaction, and whether it went
638  *        successfully or not).
639  *
640  * @retval 0 If successful
641  * @retval -errno Negative errno code on failure.
642  */
spi_read_async(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * rx_bufs,struct k_poll_signal * async)643 static inline int spi_read_async(const struct device *dev,
644 				 const struct spi_config *config,
645 				 const struct spi_buf_set *rx_bufs,
646 				 struct k_poll_signal *async)
647 {
648 	return spi_transceive_async(dev, config, NULL, rx_bufs, async);
649 }
650 
651 /**
652  * @brief Write the specified amount of data from the SPI driver.
653  *
654  * @note This function is asynchronous.
655  *
656  * @note This function is an helper function calling spi_transceive_async.
657  *
658  * @note This function is available only if @kconfig{CONFIG_SPI_ASYNC}
659  * is selected.
660  *
661  * @param dev Pointer to the device structure for the driver instance
662  * @param config Pointer to a valid spi_config structure instance.
663  *        Pointer-comparison may be used to detect changes from
664  *        previous operations.
665  * @param tx_bufs Buffer array where data to be sent originates from.
666  * @param async A pointer to a valid and ready to be signaled
667  *        struct k_poll_signal. (Note: if NULL this function will not
668  *        notify the end of the transaction, and whether it went
669  *        successfully or not).
670  *
671  * @retval 0 If successful.
672  * @retval -errno Negative errno code on failure.
673  */
spi_write_async(const struct device * dev,const struct spi_config * config,const struct spi_buf_set * tx_bufs,struct k_poll_signal * async)674 static inline int spi_write_async(const struct device *dev,
675 				  const struct spi_config *config,
676 				  const struct spi_buf_set *tx_bufs,
677 				  struct k_poll_signal *async)
678 {
679 	return spi_transceive_async(dev, config, tx_bufs, NULL, async);
680 }
681 #endif /* CONFIG_SPI_ASYNC */
682 
683 /**
684  * @brief Release the SPI device locked on by the current config
685  *
686  * Note: This synchronous function is used to release the lock on the SPI
687  *       device that was kept if, and if only, given config parameter was
688  *       the last one to be used (in any of the above functions) and if
689  *       it has the SPI_LOCK_ON bit set into its operation bits field.
690  *       This can be used if the caller needs to keep its hand on the SPI
691  *       device for consecutive transactions.
692  *
693  * @param dev Pointer to the device structure for the driver instance
694  * @param config Pointer to a valid spi_config structure instance.
695  *        Pointer-comparison may be used to detect changes from
696  *        previous operations.
697  *
698  * @retval 0 If successful.
699  * @retval -errno Negative errno code on failure.
700  */
701 __syscall int spi_release(const struct device *dev,
702 			  const struct spi_config *config);
703 
z_impl_spi_release(const struct device * dev,const struct spi_config * config)704 static inline int z_impl_spi_release(const struct device *dev,
705 				     const struct spi_config *config)
706 {
707 	const struct spi_driver_api *api =
708 		(const struct spi_driver_api *)dev->api;
709 
710 	return api->release(dev, config);
711 }
712 
713 /**
714  * @brief Release the SPI device specified in @p spi_dt_spec.
715  *
716  * This is equivalent to:
717  *
718  *     spi_release(spec->bus, &spec->config);
719  *
720  * @param spec SPI specification from devicetree
721  *
722  * @return a value from spi_release().
723  */
spi_release_dt(const struct spi_dt_spec * spec)724 static inline int spi_release_dt(const struct spi_dt_spec *spec)
725 {
726 	return spi_release(spec->bus, &spec->config);
727 }
728 
729 #ifdef __cplusplus
730 }
731 #endif
732 
733 /**
734  * @}
735  */
736 
737 #include <syscalls/spi.h>
738 
739 #endif /* ZEPHYR_INCLUDE_DRIVERS_SPI_H_ */
740