LCOV - code coverage report
Current view: top level - zephyr/drivers - spi.h Coverage Total Hit
Test: new.info Lines: 88.9 % 81 72
Test Date: 2025-03-11 06:50:38

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

Generated by: LCOV version 2.0-1