LCOV - code coverage report
Current view: top level - zephyr/drivers - spi.h Coverage Total Hit
Test: new.info Lines: 91.5 % 82 75
Test Date: 2025-09-05 16:43:28

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

Generated by: LCOV version 2.0-1