LCOV - code coverage report
Current view: top level - zephyr/drivers - i3c.h Coverage Total Hit
Test: new.info Lines: 91.2 % 193 176
Test Date: 2025-09-05 20:47:19

            Line data    Source code
       1            0 : /*
       2              :  * Copyright 2022 Intel Corporation
       3              :  * Copyright 2023 Meta Platforms, Inc. and its affiliates
       4              :  *
       5              :  * SPDX-License-Identifier: Apache-2.0
       6              :  */
       7              : 
       8              : #ifndef ZEPHYR_INCLUDE_DRIVERS_I3C_H_
       9              : #define ZEPHYR_INCLUDE_DRIVERS_I3C_H_
      10              : 
      11              : /**
      12              :  * @brief I3C Interface
      13              :  * @defgroup i3c_interface I3C Interface
      14              :  * @since 3.2
      15              :  * @version 0.1.0
      16              :  * @ingroup io_interfaces
      17              :  * @{
      18              :  */
      19              : 
      20              : #include <errno.h>
      21              : #include <stdint.h>
      22              : #include <stddef.h>
      23              : 
      24              : #include <zephyr/device.h>
      25              : #include <zephyr/drivers/i3c/addresses.h>
      26              : #include <zephyr/drivers/i3c/error_types.h>
      27              : #include <zephyr/drivers/i3c/ccc.h>
      28              : #include <zephyr/drivers/i3c/devicetree.h>
      29              : #include <zephyr/drivers/i3c/ibi.h>
      30              : #include <zephyr/drivers/i2c.h>
      31              : #include <zephyr/sys/slist.h>
      32              : #include <zephyr/sys/util.h>
      33              : #include <zephyr/rtio/rtio.h>
      34              : 
      35              : #ifdef __cplusplus
      36              : extern "C" {
      37              : #endif
      38              : 
      39              : /**
      40              :  * @name Bus Characteristic Register (BCR)
      41              :  * @anchor I3C_BCR
      42              :  *
      43              :  * - BCR[7:6]: Device Role
      44              :  *   - 0: I3C Target
      45              :  *   - 1: I3C Controller capable
      46              :  *   - 2: Reserved
      47              :  *   - 3: Reserved
      48              :  *   .
      49              :  * - BCR[5]: Advanced Capabilities
      50              :  *   - 0: Does not support optional advanced capabilities.
      51              :  *   - 1: Supports optional advanced capabilities which
      52              :  *        can be viewed via GETCAPS CCC.
      53              :  *   .
      54              :  * - BCR[4]: Virtual Target Support
      55              :  *   - 0: Is not a virtual target.
      56              :  *   - 1: Is a virtual target.
      57              :  *   .
      58              :  * - BCR[3]: Offline Capable
      59              :  *   - 0: Will always response to I3C commands.
      60              :  *   - 1: Will not always response to I3C commands.
      61              :  *   .
      62              :  * - BCR[2]: IBI Payload
      63              :  *   - 0: No data bytes following the accepted IBI.
      64              :  *   - 1: One data byte (MDB, Mandatory Data Byte) follows
      65              :  *        the accepted IBI. Additional data bytes may also
      66              :  *        follows.
      67              :  *   .
      68              :  * - BCR[1]: IBI Request Capable
      69              :  *   - 0: Not capable
      70              :  *   - 1: Capable
      71              :  *   .
      72              :  * - BCR[0]: Max Data Speed Limitation
      73              :  *   - 0: No Limitation
      74              :  *   - 1: Limitation obtained via GETMXDS CCC.
      75              :  *   .
      76              :  *
      77              :  * @{
      78              :  */
      79              : 
      80              : /**
      81              :  * @brief Max Data Speed Limitation bit.
      82              :  *
      83              :  * 0 - No Limitation.
      84              :  * 1 - Limitation obtained via GETMXDS CCC.
      85              :  */
      86            1 : #define I3C_BCR_MAX_DATA_SPEED_LIMIT                    BIT(0)
      87              : 
      88              : /** @brief IBI Request Capable bit. */
      89            1 : #define I3C_BCR_IBI_REQUEST_CAPABLE                     BIT(1)
      90              : 
      91              : /**
      92              :  * @brief IBI Payload bit.
      93              :  *
      94              :  * 0 - No data bytes following the accepted IBI.
      95              :  * 1 - One data byte (MDB, Mandatory Data Byte) follows the accepted IBI.
      96              :  *     Additional data bytes may also follows.
      97              :  */
      98            1 : #define I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE               BIT(2)
      99              : 
     100              : /**
     101              :  * @brief Offline Capable bit.
     102              :  *
     103              :  * 0 - Will always respond to I3C commands.
     104              :  * 1 - Will not always respond to I3C commands.
     105              :  */
     106            1 : #define I3C_BCR_OFFLINE_CAPABLE                         BIT(3)
     107              : 
     108              : /**
     109              :  * @brief Virtual Target Support bit.
     110              :  *
     111              :  * 0 - Is not a virtual target.
     112              :  * 1 - Is a virtual target.
     113              :  */
     114            1 : #define I3C_BCR_VIRTUAL_TARGET                          BIT(4)
     115              : 
     116              : /**
     117              :  * @brief Advanced Capabilities bit.
     118              :  *
     119              :  * 0 - Does not support optional advanced capabilities.
     120              :  * 1 - Supports optional advanced capabilities which can be viewed via
     121              :  *     GETCAPS CCC.
     122              :  */
     123            1 : #define I3C_BCR_ADV_CAPABILITIES                        BIT(5)
     124              : 
     125              : /** Device Role - I3C Target. */
     126            1 : #define I3C_BCR_DEVICE_ROLE_I3C_TARGET                  0U
     127              : 
     128              : /** Device Role - I3C Controller Capable. */
     129            1 : #define I3C_BCR_DEVICE_ROLE_I3C_CONTROLLER_CAPABLE      1U
     130              : 
     131              : /** Device Role bit shift mask. */
     132            1 : #define I3C_BCR_DEVICE_ROLE_MASK                        GENMASK(7U, 6U)
     133              : 
     134              : /**
     135              :  * @brief Device Role
     136              :  *
     137              :  * Obtain Device Role value from the BCR value obtained via GETBCR.
     138              :  *
     139              :  * @param bcr BCR value
     140              :  */
     141            1 : #define I3C_BCR_DEVICE_ROLE(bcr)                        \
     142              :         FIELD_GET(I3C_BCR_DEVICE_ROLE_MASK, (bcr))
     143              : 
     144              : /** @} */
     145              : 
     146              : /**
     147              :  * @name Legacy Virtual Register (LVR)
     148              :  * @anchor I3C_LVR
     149              :  *
     150              :  * Legacy Virtual Register (LVR)
     151              :  * - LVR[7:5]: I2C device index:
     152              :  *   - 0: I2C device has a 50 ns spike filter where
     153              :  *        it is not affected by high frequency on SCL.
     154              :  *   - 1: I2C device does not have a 50 ns spike filter
     155              :  *        but can work with high frequency on SCL.
     156              :  *   - 2: I2C device does not have a 50 ns spike filter
     157              :  *        and cannot work with high frequency on SCL.
     158              :  * - LVR[4]: I2C mode indicator:
     159              :  *   - 0: FM+ mode
     160              :  *   - 1: FM mode
     161              :  * - LVR[3:0]: Reserved.
     162              :  *
     163              :  * @{
     164              :  */
     165              : 
     166              : /** I2C FM+ Mode. */
     167            1 : #define I3C_LVR_I2C_FM_PLUS_MODE                        0
     168              : 
     169              : /** I2C FM Mode. */
     170            1 : #define I3C_LVR_I2C_FM_MODE                             1
     171              : 
     172              : /** I2C Mode Indicator bitmask. */
     173            1 : #define I3C_LVR_I2C_MODE_MASK                           BIT(4)
     174              : 
     175              : /**
     176              :  * @brief I2C Mode
     177              :  *
     178              :  * Obtain I2C Mode value from the LVR value.
     179              :  *
     180              :  * @param lvr LVR value
     181              :  */
     182            1 : #define I3C_LVR_I2C_MODE(lvr)                           \
     183              :         FIELD_GET(I3C_LVR_I2C_MODE_MASK, (lvr))
     184              : 
     185              : /**
     186              :  * @brief I2C Device Index 0.
     187              :  *
     188              :  * I2C device has a 50 ns spike filter where it is not affected by high
     189              :  * frequency on SCL.
     190              :  */
     191            1 : #define I3C_LVR_I2C_DEV_IDX_0                           0
     192              : 
     193              : /**
     194              :  * @brief I2C Device Index 1.
     195              :  *
     196              :  * I2C device does not have a 50 ns spike filter but can work with high
     197              :  * frequency on SCL.
     198              :  */
     199            1 : #define I3C_LVR_I2C_DEV_IDX_1                           1
     200              : 
     201              : /**
     202              :  * @brief I2C Device Index 2.
     203              :  *
     204              :  * I2C device does not have a 50 ns spike filter and cannot work with high
     205              :  * frequency on SCL.
     206              :  */
     207            1 : #define I3C_LVR_I2C_DEV_IDX_2                           2
     208              : 
     209              : /** I2C Device Index bitmask. */
     210            1 : #define I3C_LVR_I2C_DEV_IDX_MASK                        GENMASK(7U, 5U)
     211              : 
     212              : /**
     213              :  * @brief I2C Device Index
     214              :  *
     215              :  * Obtain I2C Device Index value from the LVR value.
     216              :  *
     217              :  * @param lvr LVR value
     218              :  */
     219            1 : #define I3C_LVR_I2C_DEV_IDX(lvr)                        \
     220              :         FIELD_GET(I3C_LVR_I2C_DEV_IDX_MASK, (lvr))
     221              : 
     222              : /** @} */
     223              : 
     224              : /**
     225              :  * @brief I3C bus mode
     226              :  */
     227            0 : enum i3c_bus_mode {
     228              :         /** Only I3C devices are on the bus. */
     229              :         I3C_BUS_MODE_PURE,
     230              : 
     231              :         /**
     232              :          * Both I3C and legacy I2C devices are on the bus.
     233              :          * The I2C devices have 50ns spike filter on SCL.
     234              :          */
     235              :         I3C_BUS_MODE_MIXED_FAST,
     236              : 
     237              :         /**
     238              :          * Both I3C and legacy I2C devices are on the bus.
     239              :          * The I2C devices do not have 50ns spike filter on SCL
     240              :          * and can tolerate maximum SDR SCL clock frequency.
     241              :          */
     242              :         I3C_BUS_MODE_MIXED_LIMITED,
     243              : 
     244              :         /**
     245              :          * Both I3C and legacy I2C devices are on the bus.
     246              :          * The I2C devices do not have 50ns spike filter on SCL
     247              :          * but cannot tolerate maximum SDR SCL clock frequency.
     248              :          */
     249              :         I3C_BUS_MODE_MIXED_SLOW,
     250              : 
     251              :         I3C_BUS_MODE_MAX = I3C_BUS_MODE_MIXED_SLOW,
     252              :         I3C_BUS_MODE_INVALID,
     253              : };
     254              : 
     255              : /**
     256              :  * @brief I2C bus speed under I3C bus.
     257              :  *
     258              :  * Only FM and FM+ modes are supported for I2C devices under I3C bus.
     259              :  */
     260            0 : enum i3c_i2c_speed_type {
     261              :         /** I2C FM mode */
     262              :         I3C_I2C_SPEED_FM,
     263              : 
     264              :         /** I2C FM+ mode */
     265              :         I3C_I2C_SPEED_FMPLUS,
     266              : 
     267              :         I3C_I2C_SPEED_MAX = I3C_I2C_SPEED_FMPLUS,
     268              :         I3C_I2C_SPEED_INVALID,
     269              : };
     270              : 
     271              : /**
     272              :  * @brief I3C data rate
     273              :  *
     274              :  * I3C data transfer rate defined by the I3C specification.
     275              :  */
     276            0 : enum i3c_data_rate {
     277              :         /** Single Data Rate messaging */
     278              :         I3C_DATA_RATE_SDR,
     279              : 
     280              :         /** High Data Rate - Double Data Rate messaging */
     281              :         I3C_DATA_RATE_HDR_DDR,
     282              : 
     283              :         /** High Data Rate - Ternary Symbol Legacy-inclusive-Bus */
     284              :         I3C_DATA_RATE_HDR_TSL,
     285              : 
     286              :         /** High Data Rate - Ternary Symbol for Pure Bus */
     287              :         I3C_DATA_RATE_HDR_TSP,
     288              : 
     289              :         /** High Data Rate - Bulk Transport */
     290              :         I3C_DATA_RATE_HDR_BT,
     291              : 
     292              :         I3C_DATA_RATE_MAX = I3C_DATA_RATE_HDR_BT,
     293              :         I3C_DATA_RATE_INVALID,
     294              : };
     295              : 
     296              : /**
     297              :  * @brief I3C Transfer API
     298              :  * @defgroup i3c_transfer_api I3C Transfer API
     299              :  * @{
     300              :  */
     301              : 
     302              : /*
     303              :  * I3C_MSG_* are I3C Message flags.
     304              :  */
     305              : 
     306              : /** Write message to I3C bus. */
     307            1 : #define I3C_MSG_WRITE                   (0U << 0U)
     308              : 
     309              : /** Read message from I3C bus. */
     310            1 : #define I3C_MSG_READ                    BIT(0)
     311              : 
     312              : /** @cond INTERNAL_HIDDEN */
     313              : #define I3C_MSG_RW_MASK                 BIT(0)
     314              : /** @endcond  */
     315              : 
     316              : /** Send STOP after this message. */
     317            1 : #define I3C_MSG_STOP                    BIT(1)
     318              : 
     319              : /**
     320              :  * RESTART I3C transaction for this message.
     321              :  *
     322              :  * @note Not all I3C drivers have or require explicit support for this
     323              :  * feature. Some drivers require this be present on a read message
     324              :  * that follows a write, or vice-versa.  Some drivers will merge
     325              :  * adjacent fragments into a single transaction using this flag; some
     326              :  * will not.
     327              :  */
     328            1 : #define I3C_MSG_RESTART                 BIT(2)
     329              : 
     330              : /** Transfer use HDR mode */
     331            1 : #define I3C_MSG_HDR                     BIT(3)
     332              : 
     333              : /** Skip I3C broadcast header. Private Transfers only. */
     334            1 : #define I3C_MSG_NBCH                    BIT(4)
     335              : 
     336              : /** I3C HDR Mode 0 */
     337            1 : #define I3C_MSG_HDR_MODE0               BIT(0)
     338              : 
     339              : /** I3C HDR Mode 1 */
     340            1 : #define I3C_MSG_HDR_MODE1               BIT(1)
     341              : 
     342              : /** I3C HDR Mode 2 */
     343            1 : #define I3C_MSG_HDR_MODE2               BIT(2)
     344              : 
     345              : /** I3C HDR Mode 3 */
     346            1 : #define I3C_MSG_HDR_MODE3               BIT(3)
     347              : 
     348              : /** I3C HDR Mode 4 */
     349            1 : #define I3C_MSG_HDR_MODE4               BIT(4)
     350              : 
     351              : /** I3C HDR Mode 5 */
     352            1 : #define I3C_MSG_HDR_MODE5               BIT(5)
     353              : 
     354              : /** I3C HDR Mode 6 */
     355            1 : #define I3C_MSG_HDR_MODE6               BIT(6)
     356              : 
     357              : /** I3C HDR Mode 7 */
     358            1 : #define I3C_MSG_HDR_MODE7               BIT(7)
     359              : 
     360              : /** I3C HDR-DDR (Double Data Rate) */
     361            1 : #define I3C_MSG_HDR_DDR                 I3C_MSG_HDR_MODE0
     362              : 
     363              : /** I3C HDR-TSP (Ternary Symbol Pure-bus) */
     364            1 : #define I3C_MSG_HDR_TSP                 I3C_MSG_HDR_MODE1
     365              : 
     366              : /** I3C HDR-TSL (Ternary Symbol Legacy-inclusive-bus) */
     367            1 : #define I3C_MSG_HDR_TSL                 I3C_MSG_HDR_MODE2
     368              : 
     369              : /** I3C HDR-BT (Bulk Transport) */
     370            1 : #define I3C_MSG_HDR_BT                  I3C_MSG_HDR_MODE3
     371              : 
     372              : /** @} */
     373              : 
     374              : /**
     375              :  * @addtogroup i3c_transfer_api
     376              :  * @{
     377              :  */
     378              : 
     379              : /**
     380              :  * @brief One I3C Message.
     381              :  *
     382              :  * This defines one I3C message to transact on the I3C bus.
     383              :  *
     384              :  * @note Some of the configurations supported by this API may not be
     385              :  * supported by specific SoC I3C hardware implementations, in
     386              :  * particular features related to bus transactions intended to read or
     387              :  * write data from different buffers within a single transaction.
     388              :  * Invocations of i3c_transfer() may not indicate an error when an
     389              :  * unsupported configuration is encountered.  In some cases drivers
     390              :  * will generate separate transactions for each message fragment, with
     391              :  * or without presence of #I3C_MSG_RESTART in #flags.
     392              :  */
     393            1 : struct i3c_msg {
     394              :         /** Data buffer in bytes */
     395            1 :         uint8_t                 *buf;
     396              : 
     397              :         /** Length of buffer in bytes */
     398            1 :         uint32_t                len;
     399              : 
     400              :         /**
     401              :          * Total number of bytes transferred
     402              :          *
     403              :          * A Target can issue an EoD or the Controller can abort a transfer
     404              :          * before the length of the buffer. It is expected for the driver to
     405              :          * write to this after the transfer.
     406              :          */
     407            1 :         uint32_t                num_xfer;
     408              : 
     409              :         /**
     410              :          * SDR Error Type
     411              :          *
     412              :          * Error from I3C Specification v1.1.1 section 5.1.10.2. It is expected
     413              :          * for the driver to write to this.
     414              :          */
     415            1 :         enum i3c_sdr_controller_error_types err;
     416              : 
     417              :         /** Flags for this message */
     418            1 :         uint8_t                 flags;
     419              : 
     420              :         /**
     421              :          * HDR mode (@c I3C_MSG_HDR_MODE*) for transfer
     422              :          * if any @c I3C_MSG_HDR_* is set in #flags.
     423              :          *
     424              :          * Use SDR mode if none is set.
     425              :          */
     426            1 :         uint8_t                 hdr_mode;
     427              : 
     428              :         /** HDR command code field (7-bit) for HDR-DDR, HDR-TSP and HDR-TSL */
     429            1 :         uint8_t                 hdr_cmd_code;
     430              : };
     431              : 
     432              : /** @} */
     433              : 
     434              : /**
     435              :  * @brief Type of configuration being passed to configure function.
     436              :  */
     437            0 : enum i3c_config_type {
     438              :         I3C_CONFIG_CONTROLLER,
     439              :         I3C_CONFIG_TARGET,
     440              :         I3C_CONFIG_CUSTOM,
     441              : };
     442              : 
     443              : /**
     444              :  * @brief Configuration parameters for I3C hardware to act as controller.
     445              :  */
     446            1 : struct i3c_config_controller {
     447              :         /**
     448              :          * True if the controller is to be the secondary controller
     449              :          * of the bus. False to be the primary controller.
     450              :          */
     451            1 :         bool is_secondary;
     452              : 
     453              :         struct {
     454              :                 /** SCL frequency (in Hz) for I3C transfers. */
     455            1 :                 uint32_t i3c;
     456              : 
     457              :                 /** SCL frequency (in Hz) for I2C transfers. */
     458            1 :                 uint32_t i2c;
     459            0 :         } scl;
     460              : 
     461              :         /**
     462              :          * Bit mask of supported HDR modes (0 - 7).
     463              :          *
     464              :          * This can be used to enable or disable HDR mode
     465              :          * supported by the hardware at runtime.
     466              :          */
     467            1 :         uint8_t supported_hdr;
     468              : };
     469              : 
     470              : /**
     471              :  * @brief Custom I3C configuration parameters.
     472              :  *
     473              :  * This can be used to configure the I3C hardware on parameters
     474              :  * not covered by i3c_config_controller or i3c_config_target.
     475              :  * Mostly used to configure vendor specific parameters of the I3C
     476              :  * hardware.
     477              :  */
     478            1 : struct i3c_config_custom {
     479              :         /** ID of the configuration parameter. */
     480            1 :         uint32_t id;
     481              : 
     482              :         union {
     483              :                 /** Value of configuration parameter. */
     484            1 :                 uintptr_t val;
     485              : 
     486              :                 /**
     487              :                  * Pointer to configuration parameter.
     488              :                  *
     489              :                  * Mainly used to pointer to a struct that
     490              :                  * the device driver understands.
     491              :                  */
     492            1 :                 void *ptr;
     493            0 :         };
     494              : };
     495              : 
     496              : /**
     497              :  * @cond INTERNAL_HIDDEN
     498              :  *
     499              :  * These are for internal use only, so skip these in
     500              :  * public documentation.
     501              :  */
     502              : struct i3c_device_desc;
     503              : struct i3c_device_id;
     504              : struct i3c_i2c_device_desc;
     505              : struct i3c_target_config;
     506              : struct i3c_config_target;
     507              : 
     508              : __subsystem struct i3c_driver_api {
     509              :         /**
     510              :          * For backward compatibility to I2C API.
     511              :          *
     512              :          * @see i2c_driver_api for more information.
     513              :          *
     514              :          * @internal
     515              :          * @warning DO NOT MOVE! Must be at the beginning.
     516              :          * @endinternal
     517              :          */
     518              :         struct i2c_driver_api i2c_api;
     519              : 
     520              :         /**
     521              :          * Configure the I3C hardware.
     522              :          *
     523              :          * @see i3c_configure()
     524              :          *
     525              :          * @param dev Pointer to controller device driver instance.
     526              :          * @param type Type of configuration parameters being passed
     527              :          *             in @p config.
     528              :          * @param config Pointer to the configuration parameters.
     529              :          *
     530              :          * @return See i3c_configure()
     531              :          */
     532              :         int (*configure)(const struct device *dev,
     533              :                          enum i3c_config_type type, void *config);
     534              : 
     535              :         /**
     536              :          * Get configuration of the I3C hardware.
     537              :          *
     538              :          * @see i3c_config_get()
     539              :          *
     540              :          * @param[in] dev Pointer to controller device driver instance.
     541              :          * @param[in] type Type of configuration parameters being passed
     542              :          *                 in @p config.
     543              :          * @param[in, out] config Pointer to the configuration parameters.
     544              :          *
     545              :          * @return See i3c_config_get()
     546              :          */
     547              :         int (*config_get)(const struct device *dev,
     548              :                           enum i3c_config_type type, void *config);
     549              : #if defined(CONFIG_I3C_CONTROLLER) || defined(__DOXYGEN__)
     550              :         /**
     551              :          * Perform bus recovery
     552              :          *
     553              :          * Controller only API.
     554              :          *
     555              :          * @see i3c_recover_bus()
     556              :          *
     557              :          * @param dev Pointer to controller device driver instance.
     558              :          *
     559              :          * @return See i3c_recover_bus()
     560              :          */
     561              :         int (*recover_bus)(const struct device *dev);
     562              : 
     563              :         /**
     564              :          * I3C Device Attach
     565              :          *
     566              :          * Optional API.
     567              :          *
     568              :          * @see i3c_attach_i3c_device()
     569              :          *
     570              :          * @param dev Pointer to controller device driver instance.
     571              :          * @param target Pointer to target device descriptor.
     572              :          *
     573              :          * @return See i3c_attach_i3c_device()
     574              :          */
     575              :         int (*attach_i3c_device)(const struct device *dev,
     576              :                                  struct i3c_device_desc *target);
     577              : 
     578              :         /**
     579              :          * I3C Address Update
     580              :          *
     581              :          * Optional API.
     582              :          *
     583              :          * @see i3c_reattach_i3c_device()
     584              :          *
     585              :          * @param dev Pointer to controller device driver instance.
     586              :          * @param target Pointer to target device descriptor.
     587              :          * @param old_dyn_addr Old dynamic address
     588              :          *
     589              :          * @return See i3c_reattach_i3c_device()
     590              :          */
     591              :         int (*reattach_i3c_device)(const struct device *dev,
     592              :                                    struct i3c_device_desc *target,
     593              :                                    uint8_t old_dyn_addr);
     594              : 
     595              :         /**
     596              :          * I3C Device Detach
     597              :          *
     598              :          * Optional API.
     599              :          *
     600              :          * @see i3c_detach_i3c_device()
     601              :          *
     602              :          * @param dev Pointer to controller device driver instance.
     603              :          * @param target Pointer to target device descriptor.
     604              :          *
     605              :          * @return See i3c_detach_i3c_device()
     606              :          */
     607              :         int (*detach_i3c_device)(const struct device *dev,
     608              :                                  struct i3c_device_desc *target);
     609              : 
     610              :         /**
     611              :          * I2C Device Attach
     612              :          *
     613              :          * Optional API.
     614              :          *
     615              :          * @see i3c_attach_i2c_device()
     616              :          *
     617              :          * @param dev Pointer to controller device driver instance.
     618              :          * @param target Pointer to target device descriptor.
     619              :          *
     620              :          * @return See i3c_attach_i2c_device()
     621              :          */
     622              :         int (*attach_i2c_device)(const struct device *dev,
     623              :                                  struct i3c_i2c_device_desc *target);
     624              : 
     625              :         /**
     626              :          * I2C Device Detach
     627              :          *
     628              :          * Optional API.
     629              :          *
     630              :          * @see i3c_detach_i2c_device()
     631              :          *
     632              :          * @param dev Pointer to controller device driver instance.
     633              :          * @param target Pointer to target device descriptor.
     634              :          *
     635              :          * @return See i3c_detach_i2c_device()
     636              :          */
     637              :         int (*detach_i2c_device)(const struct device *dev,
     638              :                                  struct i3c_i2c_device_desc *target);
     639              : 
     640              :         /**
     641              :          * Perform Dynamic Address Assignment via ENTDAA.
     642              :          *
     643              :          * Controller only API.
     644              :          *
     645              :          * @see i3c_do_daa()
     646              :          *
     647              :          * @param dev Pointer to controller device driver instance.
     648              :          *
     649              :          * @return See i3c_do_daa()
     650              :          */
     651              :         int (*do_daa)(const struct device *dev);
     652              : 
     653              :         /**
     654              :          * Send Common Command Code (CCC).
     655              :          *
     656              :          * Controller only API.
     657              :          *
     658              :          * @see i3c_do_ccc()
     659              :          *
     660              :          * @param dev Pointer to controller device driver instance.
     661              :          * @param payload Pointer to the CCC payload.
     662              :          *
     663              :          * @return See i3c_do_ccc()
     664              :          */
     665              :         int (*do_ccc)(const struct device *dev,
     666              :                       struct i3c_ccc_payload *payload);
     667              : 
     668              :         /**
     669              :          * Transfer messages in I3C mode.
     670              :          *
     671              :          * @see i3c_transfer()
     672              :          *
     673              :          * @param dev Pointer to controller device driver instance.
     674              :          * @param target Pointer to target device descriptor.
     675              :          * @param msg Pointer to I3C messages.
     676              :          * @param num_msgs Number of messages to transfer.
     677              :          *
     678              :          * @return See i3c_transfer()
     679              :          */
     680              :         int (*i3c_xfers)(const struct device *dev,
     681              :                          struct i3c_device_desc *target,
     682              :                          struct i3c_msg *msgs,
     683              :                          uint8_t num_msgs);
     684              : 
     685              :         /**
     686              :          * Find a registered I3C target device.
     687              :          *
     688              :          * Controller only API.
     689              :          *
     690              :          * This returns the I3C device descriptor of the I3C device
     691              :          * matching the incoming @p id.
     692              :          *
     693              :          * @param dev Pointer to controller device driver instance.
     694              :          * @param id Pointer to I3C device ID.
     695              :          *
     696              :          * @return See i3c_device_find().
     697              :          */
     698              :         struct i3c_device_desc *(*i3c_device_find)(const struct device *dev,
     699              :                                                    const struct i3c_device_id *id);
     700              : #endif /* CONFIG_I3C_CONTROLLER */
     701              : #ifdef CONFIG_I3C_USE_IBI
     702              : #if defined(CONFIG_I3C_TARGET) || defined(__DOXYGEN__)
     703              :         /**
     704              :          * Raise In-Band Interrupt (IBI).
     705              :          *
     706              :          * Target device only API.
     707              :          *
     708              :          * @see i3c_ibi_request()
     709              :          *
     710              :          * @param dev Pointer to controller device driver instance.
     711              :          * @param request Pointer to IBI request struct.
     712              :          *
     713              :          * @return See i3c_ibi_request()
     714              :          */
     715              :         int (*ibi_raise)(const struct device *dev,
     716              :                          struct i3c_ibi *request);
     717              : #endif /* CONFIG_I3C_TARGET */
     718              : #if defined(CONFIG_I3C_CONTROLLER) || defined(__DOXYGEN__)
     719              :         /**
     720              :          * ACK or NACK IBI HJ Requests
     721              :          *
     722              :          * @see ibi_hj_response()
     723              :          *
     724              :          * @param dev Pointer to controller device driver instance.
     725              :          * @param ack True to ack, False to nack
     726              :          *
     727              :          * @return See ibi_hj_response()
     728              :          */
     729              :         int (*ibi_hj_response)(const struct device *dev,
     730              :                                bool ack);
     731              : 
     732              :         /**
     733              :          * Enable receiving IBI from a target.
     734              :          *
     735              :          * Controller only API.
     736              :          *
     737              :          * @see i3c_ibi_enable()
     738              :          *
     739              :          * @param dev Pointer to controller device driver instance.
     740              :          * @param target Pointer to target device descriptor.
     741              :          *
     742              :          * @return See i3c_ibi_enable()
     743              :          */
     744              :         int (*ibi_enable)(const struct device *dev,
     745              :                           struct i3c_device_desc *target);
     746              : 
     747              :         /**
     748              :          * Disable receiving IBI from a target.
     749              :          *
     750              :          * Controller only API.
     751              :          *
     752              :          * @see i3c_ibi_disable()
     753              :          *
     754              :          * @param dev Pointer to controller device driver instance.
     755              :          * @param target Pointer to target device descriptor.
     756              :          *
     757              :          * @return See i3c_ibi_disable()
     758              :          */
     759              :         int (*ibi_disable)(const struct device *dev,
     760              :                            struct i3c_device_desc *target);
     761              : #endif /* CONFIG_I3C_CONTROLLER */
     762              : #endif /* CONFIG_I3C_USE_IBI */
     763              : #if defined(CONFIG_I3C_TARGET) || defined(__DOXYGEN__)
     764              :         /**
     765              :          * Register config as target device of a controller.
     766              :          *
     767              :          * This tells the controller to act as a target device
     768              :          * on the I3C bus.
     769              :          *
     770              :          * Target device only API.
     771              :          *
     772              :          * @see i3c_target_register()
     773              :          *
     774              :          * @param dev Pointer to the controller device driver instance.
     775              :          * @param cfg I3C target device configuration
     776              :          *
     777              :          * @return See i3c_target_register()
     778              :          */
     779              :         int (*target_register)(const struct device *dev,
     780              :                                struct i3c_target_config *cfg);
     781              : 
     782              :         /**
     783              :          * Unregister config as target device of a controller.
     784              :          *
     785              :          * This tells the controller to stop acting as a target device
     786              :          * on the I3C bus.
     787              :          *
     788              :          * Target device only API.
     789              :          *
     790              :          * @see i3c_target_unregister()
     791              :          *
     792              :          * @param dev Pointer to the controller device driver instance.
     793              :          * @param cfg I3C target device configuration
     794              :          *
     795              :          * @return See i3c_target_unregister()
     796              :          */
     797              :         int (*target_unregister)(const struct device *dev,
     798              :                                  struct i3c_target_config *cfg);
     799              : 
     800              :         /**
     801              :          * Write to the TX FIFO
     802              :          *
     803              :          * This writes to the target tx fifo
     804              :          *
     805              :          * Target device only API.
     806              :          *
     807              :          * @see i3c_target_tx_write()
     808              :          *
     809              :          * @param dev Pointer to the controller device driver instance.
     810              :          * @param buf Pointer to the buffer
     811              :          * @param len Length of the buffer
     812              :          * @param hdr_mode HDR mode
     813              :          *
     814              :          * @return See i3c_target_tx_write()
     815              :          */
     816              :         int (*target_tx_write)(const struct device *dev,
     817              :                                uint8_t *buf, uint16_t len, uint8_t hdr_mode);
     818              : 
     819              :         /**
     820              :          * ACK or NACK controller handoffs
     821              :          *
     822              :          * This will tell the target to ACK or NACK controller handoffs
     823              :          * from the CCC GETACCCR
     824              :          *
     825              :          * Target device only API.
     826              :          *
     827              :          * @see i3c_target_controller_handoff()
     828              :          *
     829              :          * @param dev Pointer to the controller device driver instance.
     830              :          * @param accept True to ACK controller handoffs, False to NACK.
     831              :          *
     832              :          * @return See i3c_target_controller_handoff()
     833              :          */
     834              :         int (*target_controller_handoff)(const struct device *dev,
     835              :                                          bool accept);
     836              : #endif /* CONFIG_I3C_TARGET */
     837              : #if defined(CONFIG_I3C_RTIO) || defined(__DOXYGEN__)
     838              :         /**
     839              :          * RTIO
     840              :          *
     841              :          * @see i3c_iodev_submit()
     842              :          *
     843              :          * @param dev Pointer to the controller device driver instance.
     844              :          * @param iodev_sqe Pointer to the
     845              :          *
     846              :          * @return See i3c_iodev_submit()
     847              :          */
     848              :         void (*iodev_submit)(const struct device *dev,
     849              :                              struct rtio_iodev_sqe *iodev_sqe);
     850              : #endif /* CONFIG_I3C_RTIO */
     851              : };
     852              : 
     853              : /**
     854              :  * @endcond
     855              :  */
     856              : 
     857              : /**
     858              :  * @brief Structure used for matching I3C devices.
     859              :  */
     860            1 : struct i3c_device_id {
     861              :         /** Device Provisioned ID */
     862            1 :         uint64_t pid:48;
     863              : };
     864              : 
     865              : /**
     866              :  * @brief Structure initializer for i3c_device_id from PID
     867              :  *
     868              :  * This helper macro expands to a static initializer for a i3c_device_id
     869              :  * by populating the PID (Provisioned ID) field.
     870              :  *
     871              :  * @param pid Provisioned ID.
     872              :  */
     873            1 : #define I3C_DEVICE_ID(pid)                                              \
     874              :         {                                                               \
     875              :                 .pid = pid                                              \
     876              :         }
     877              : 
     878              : /**
     879              :  * @brief Structure describing a I3C target device.
     880              :  *
     881              :  * Instances of this are passed to the I3C controller device APIs,
     882              :  * for example:
     883              :  * - i3c_device_register() to tell the controller of a target device.
     884              :  * - i3c_transfers() to initiate data transfers between controller and
     885              :  *   target device.
     886              :  *
     887              :  * Fields #bus, #pid and #static_addr must be initialized by the module that
     888              :  * implements the target device behavior prior to passing the object reference
     889              :  * to I3C controller device APIs. #static_addr can be zero if target device does
     890              :  * not have static address.
     891              :  *
     892              :  * Internal field @c node should not be initialized or modified manually.
     893              :  */
     894            1 : struct i3c_device_desc {
     895            0 :         sys_snode_t node;
     896              : 
     897              :         /** I3C bus to which this target device is attached */
     898            1 :         const struct device *bus;
     899              : 
     900              :         /** Device driver instance of the I3C device */
     901            1 :         const struct device *dev;
     902              : 
     903              :         /** Device Provisioned ID */
     904            1 :         uint64_t pid;
     905              : 
     906              :         /**
     907              :          * Static address for this target device.
     908              :          *
     909              :          * 0 if static address is not being used, and only dynamic
     910              :          * address is used. This means that the target device must
     911              :          * go through ENTDAA (Dynamic Address Assignment) to get
     912              :          * a dynamic address before it can communicate with
     913              :          * the controller. This means SETAASA and SETDASA CCC
     914              :          * cannot be used to set dynamic address on the target
     915              :          * device (as both are to tell target device to use static
     916              :          * address as dynamic address).
     917              :          */
     918            1 :         uint8_t static_addr;
     919              : 
     920              :         /**
     921              :          * Initial dynamic address.
     922              :          *
     923              :          * This is specified in the device tree property "assigned-address"
     924              :          * to indicate the desired dynamic address during address
     925              :          * assignment (SETDASA and ENTDAA).
     926              :          *
     927              :          * 0 if there is no preference.
     928              :          */
     929            1 :         const uint8_t init_dynamic_addr;
     930              : 
     931              :         /**
     932              :          * Device Flags
     933              :          *
     934              :          * BIT[0]: This shall be used as an optimization for bus initializtion if the
     935              :          * device supports SETAASA.
     936              :          * BIT[1]: This shall be used to indicate if the device is a I3C v1.0 device
     937              :          */
     938            1 :         const uint8_t flags;
     939              : 
     940              :         /**
     941              :          * Dynamic Address for this target device used for communication.
     942              :          *
     943              :          * This is to be set by the controller driver in one of
     944              :          * the following situations:
     945              :          * - During Dynamic Address Assignment (during ENTDAA)
     946              :          * - Reset Dynamic Address Assignment (RSTDAA)
     947              :          * - Set All Addresses to Static Addresses (SETAASA)
     948              :          * - Set New Dynamic Address (SETNEWDA)
     949              :          * - Set Dynamic Address from Static Address (SETDASA)
     950              :          *
     951              :          * 0 if address has not been assigned.
     952              :          */
     953            1 :         uint8_t dynamic_addr;
     954              : 
     955              :         /**
     956              :          * Bus Characteristic Register (BCR)
     957              :          * @see @ref I3C_BCR
     958              :          */
     959            1 :         uint8_t bcr;
     960              : 
     961              :         /**
     962              :          * Device Characteristic Register (DCR)
     963              :          *
     964              :          * Describes the type of device. Refer to official documentation
     965              :          * on what this number means.
     966              :          */
     967            1 :         uint8_t dcr;
     968              : 
     969              :         struct {
     970              :                 /** Maximum Read Speed */
     971            1 :                 uint8_t maxrd;
     972              : 
     973              :                 /** Maximum Write Speed */
     974            1 :                 uint8_t maxwr;
     975              : 
     976              :                 /** Maximum Read turnaround time in microseconds. */
     977            1 :                 uint32_t max_read_turnaround;
     978            0 :         } data_speed;
     979              : 
     980              :         struct {
     981              :                 /** Maximum Read Length */
     982            1 :                 uint16_t mrl;
     983              : 
     984              :                 /** Maximum Write Length */
     985            1 :                 uint16_t mwl;
     986              : 
     987              :                 /** Maximum IBI Payload Size. Valid only if BCR[2] is 1. */
     988            1 :                 uint8_t max_ibi;
     989            0 :         } data_length;
     990              : 
     991              :         /** Controller Handoff Delay Parameters */
     992            1 :         uint8_t crhdly1;
     993              : 
     994              :         /** Describes advanced (Target) capabilities and features */
     995              :         struct {
     996              :                 union {
     997              :                         /**
     998              :                          * I3C v1.0 HDR Capabilities (@c I3C_CCC_GETCAPS1_*)
     999              :                          * - Bit[0]: HDR-DDR
    1000              :                          * - Bit[1]: HDR-TSP
    1001              :                          * - Bit[2]: HDR-TSL
    1002              :                          * - Bit[7:3]: Reserved
    1003              :                          */
    1004            1 :                         uint8_t gethdrcap;
    1005              : 
    1006              :                         /**
    1007              :                          * I3C v1.1+ GETCAPS1 (@c I3C_CCC_GETCAPS1_*)
    1008              :                          * - Bit[0]: HDR-DDR
    1009              :                          * - Bit[1]: HDR-TSP
    1010              :                          * - Bit[2]: HDR-TSL
    1011              :                          * - Bit[3]: HDR-BT
    1012              :                          * - Bit[7:4]: Reserved
    1013              :                          */
    1014            1 :                         uint8_t getcap1;
    1015              :                 };
    1016              : 
    1017              :                 /**
    1018              :                  *  GETCAPS2 (@c I3C_CCC_GETCAPS2_*)
    1019              :                  * - Bit[3:0]: I3C 1.x Specification Version
    1020              :                  * - Bit[5:4]: Group Address Capabilities
    1021              :                  * - Bit[6]: HDR-DDR Write Abort
    1022              :                  * - Bit[7]: HDR-DDR Abort CRC
    1023              :                  */
    1024            1 :                 uint8_t getcap2;
    1025              : 
    1026              :                 /**
    1027              :                  * GETCAPS3 (@c I3C_CCC_GETCAPS3_*)
    1028              :                  * - Bit[0]: Multi-Lane (ML) Data Transfer Support
    1029              :                  * - Bit[1]: Device to Device Transfer (D2DXFER) Support
    1030              :                  * - Bit[2]: Device to Device Transfer (D2DXFER) IBI Capable
    1031              :                  * - Bit[3]: Defining Byte Support in GETCAPS
    1032              :                  * - Bit[4]: Defining Byte Support in GETSTATUS
    1033              :                  * - Bit[5]: HDR-BT CRC-32 Support
    1034              :                  * - Bit[6]: IBI MDB Support for Pending Read Notification
    1035              :                  * - Bit[7]: Reserved
    1036              :                  */
    1037            1 :                 uint8_t getcap3;
    1038              : 
    1039              :                 /**
    1040              :                  * GETCAPS4
    1041              :                  * - Bit[7:0]: Reserved
    1042              :                  */
    1043            1 :                 uint8_t getcap4;
    1044            1 :         } getcaps;
    1045              : 
    1046              :         /* Describes Controller Feature Capabilities */
    1047              :         struct {
    1048              :                 /**
    1049              :                  * CRCAPS1
    1050              :                  * - Bit[0]: Hot-Join Support
    1051              :                  * - Bit[1]: Group Management Support
    1052              :                  * - Bit[2]: Multi-Lane Support
    1053              :                  * - Bit[7:3]: Reserved
    1054              :                  */
    1055            1 :                 uint8_t crcaps1;
    1056              : 
    1057              :                 /**
    1058              :                  * CRCAPS2
    1059              :                  * - Bit[0]: In-Band Interrupt Support
    1060              :                  * - Bit[1]: Controller Pass-Back
    1061              :                  * - Bit[2]: Deep Sleep Capable
    1062              :                  * - Bit[3]: Delayed Controller Handoff
    1063              :                  * - Bit[7:4]: Reserved
    1064              :                  */
    1065            1 :                 uint8_t crcaps2;
    1066            0 :         } crcaps;
    1067              : 
    1068              :         /** @cond INTERNAL_HIDDEN */
    1069              :         /**
    1070              :          * Private data by the controller to aid in transactions. Do not modify.
    1071              :          */
    1072              :         void *controller_priv;
    1073              :         /** @endcond */
    1074              : 
    1075              : #if defined(CONFIG_I3C_USE_IBI) || defined(__DOXYGEN__)
    1076              :         /**
    1077              :          * In-Band Interrupt (IBI) callback.
    1078              :          * Only available if @kconfig{CONFIG_I3C_USE_IBI} is set.
    1079              :          */
    1080            1 :         i3c_target_ibi_cb_t ibi_cb;
    1081              : #endif /* CONFIG_I3C_USE_IBI */
    1082              : };
    1083              : 
    1084              : /**
    1085              :  * @brief Structure describing a I2C device on I3C bus.
    1086              :  *
    1087              :  * Instances of this are passed to the I3C controller device APIs,
    1088              :  * for example:
    1089              :  * () i3c_i2c_device_register() to tell the controller of an I2C device.
    1090              :  * () i3c_i2c_transfers() to initiate data transfers between controller
    1091              :  *    and I2C device.
    1092              :  *
    1093              :  * Fields other than @c node must be initialized by the module that
    1094              :  * implements the device behavior prior to passing the object
    1095              :  * reference to I3C controller device APIs.
    1096              :  */
    1097            1 : struct i3c_i2c_device_desc {
    1098            0 :         sys_snode_t node;
    1099              : 
    1100              :         /** I3C bus to which this I2C device is attached */
    1101            1 :         const struct device *bus;
    1102              : 
    1103              :         /** Static address for this I2C device. */
    1104            1 :         uint16_t addr;
    1105              : 
    1106              :         /**
    1107              :          * Legacy Virtual Register (LVR)
    1108              :          * @see @ref I3C_LVR
    1109              :          */
    1110            1 :         uint8_t lvr;
    1111              : 
    1112              :         /** @cond INTERNAL_HIDDEN */
    1113              :         /**
    1114              :          * Private data by the controller to aid in transactions. Do not modify.
    1115              :          */
    1116              :         void *controller_priv;
    1117              :         /** @endcond */
    1118              : };
    1119              : 
    1120              : /**
    1121              :  * @brief Structure for describing attached devices for a controller.
    1122              :  *
    1123              :  * This contains slists of attached I3C and I2C devices.
    1124              :  *
    1125              :  * This is a helper struct that can be used by controller device
    1126              :  * driver to aid in device management.
    1127              :  */
    1128            1 : struct i3c_dev_attached_list {
    1129              :         /**
    1130              :          * Address slots:
    1131              :          * - Aid in dynamic address assignment.
    1132              :          * - Quick way to find out if a target address is
    1133              :          *   a I3C or I2C device.
    1134              :          */
    1135            1 :         struct i3c_addr_slots addr_slots;
    1136              : 
    1137              :         struct {
    1138              :                 /**
    1139              :                  * Linked list of attached I3C devices.
    1140              :                  */
    1141            1 :                 sys_slist_t i3c;
    1142              : 
    1143              :                 /**
    1144              :                  * Linked list of attached I2C devices.
    1145              :                  */
    1146            1 :                 sys_slist_t i2c;
    1147            0 :         } devices;
    1148              : };
    1149              : 
    1150              : /**
    1151              :  * @brief Structure for describing known devices for a controller.
    1152              :  *
    1153              :  * This contains arrays of known I3C and I2C devices.
    1154              :  *
    1155              :  * This is a helper struct that can be used by controller device
    1156              :  * driver to aid in device management.
    1157              :  */
    1158            1 : struct i3c_dev_list {
    1159              :         /**
    1160              :          * Pointer to array of known I3C devices.
    1161              :          */
    1162            1 :         struct i3c_device_desc * const i3c;
    1163              : 
    1164              :         /**
    1165              :          * Pointer to array of known I2C devices.
    1166              :          */
    1167            1 :         struct i3c_i2c_device_desc * const i2c;
    1168              : 
    1169              :         /**
    1170              :          * Number of I3C devices in array.
    1171              :          */
    1172            1 :         const uint8_t num_i3c;
    1173              : 
    1174              :         /**
    1175              :          * Number of I2C devices in array.
    1176              :          */
    1177            1 :         const uint8_t num_i2c;
    1178              : };
    1179              : 
    1180              : /**
    1181              :  * This structure is common to all I3C drivers and is expected to be
    1182              :  * the first element in the object pointed to by the config field
    1183              :  * in the device structure.
    1184              :  */
    1185            1 : struct i3c_driver_config {
    1186              : #if defined(CONFIG_I3C_CONTROLLER) || defined(__DOXYGEN__)
    1187              :         /** I3C/I2C device list struct. */
    1188            1 :         struct i3c_dev_list dev_list;
    1189              : 
    1190              :         /** I3C Primary Controller Dynamic Address */
    1191            1 :         uint8_t primary_controller_da;
    1192              : #elif defined(CONFIG_CPP)
    1193              :        /* Empty struct has size 0 in C, size 1 in C++. Force them to be the same. */
    1194              :         uint8_t unused_cpp_size_compatibility;
    1195              : #endif
    1196              : };
    1197              : 
    1198              : #if defined(CONFIG_CPP)
    1199              : BUILD_ASSERT(sizeof(struct i3c_driver_config) >= 1);
    1200              : #endif
    1201              : 
    1202              : /**
    1203              :  * This structure is common to all I3C drivers and is expected to be the first
    1204              :  * element in the driver's struct driver_data declaration.
    1205              :  */
    1206            1 : struct i3c_driver_data {
    1207              :         /** Controller Configuration */
    1208            1 :         struct i3c_config_controller ctrl_config;
    1209              : #if defined(CONFIG_I3C_CONTROLLER) || defined(__DOXYGEN__)
    1210              :         /** Attached I3C/I2C devices and addresses */
    1211            1 :         struct i3c_dev_attached_list attached_dev;
    1212              : #if defined(CONFIG_I3C_TARGET) || defined(__DOXYGEN__)
    1213              :         /** Received DEFTGTS Pointer */
    1214            1 :         struct i3c_ccc_deftgts *deftgts;
    1215              : 
    1216              :         /** DEFTGTS refreshed */
    1217            1 :         bool deftgts_refreshed;
    1218              : #endif /* CONFIG_I3C_TARGET */
    1219              : #endif /* CONFIG_I3C_CONTROLLER */
    1220              : };
    1221              : #if defined(CONFIG_I3C_CONTROLLER) || defined(__DOXYGEN__)
    1222              : /**
    1223              :  * @brief iterate over all I3C devices present on the bus
    1224              :  *
    1225              :  * @param bus: the I3C bus device pointer
    1226              :  * @param desc: an I3C device descriptor pointer updated to point to the current slot
    1227              :  *       at each iteration of the loop
    1228              :  */
    1229            1 : #define I3C_BUS_FOR_EACH_I3CDEV(bus, desc)                                                         \
    1230              :         SYS_SLIST_FOR_EACH_CONTAINER(                                                              \
    1231              :                 &((struct i3c_driver_data *)(bus->data))->attached_dev.devices.i3c, desc, node)
    1232              : 
    1233              : /**
    1234              :  * @brief iterate over all I2C devices present on the bus
    1235              :  *
    1236              :  * @param bus: the I3C bus device pointer
    1237              :  * @param desc: an I2C device descriptor pointer updated to point to the current slot
    1238              :  *       at each iteration of the loop
    1239              :  */
    1240            1 : #define I3C_BUS_FOR_EACH_I2CDEV(bus, desc)                                                         \
    1241              :         SYS_SLIST_FOR_EACH_CONTAINER(                                                              \
    1242              :                 &((struct i3c_driver_data *)(bus->data))->attached_dev.devices.i2c, desc, node)
    1243              : 
    1244              : /**
    1245              :  * @brief Find a I3C target device descriptor by ID.
    1246              :  *
    1247              :  * This finds the I3C target device descriptor in the device list
    1248              :  * matching the provided ID struct (@p id).
    1249              :  *
    1250              :  * @param dev_list Pointer to the device list struct.
    1251              :  * @param id Pointer to I3C device ID struct.
    1252              :  *
    1253              :  * @return Pointer to the I3C target device descriptor, or
    1254              :  *         `NULL` if none is found.
    1255              :  */
    1256            1 : struct i3c_device_desc *i3c_dev_list_find(const struct i3c_dev_list *dev_list,
    1257              :                                           const struct i3c_device_id *id);
    1258              : 
    1259              : /**
    1260              :  * @brief Find a I3C target device descriptor by dynamic address.
    1261              :  *
    1262              :  * This finds the I3C target device descriptor in the attached
    1263              :  * device list matching the dynamic address (@p addr)
    1264              :  *
    1265              :  * @param dev Pointer to controller device driver instance.
    1266              :  * @param addr Dynamic address to be matched.
    1267              :  *
    1268              :  * @return Pointer to the I3C target device descriptor, or
    1269              :  *         `NULL` if none is found.
    1270              :  */
    1271            1 : struct i3c_device_desc *i3c_dev_list_i3c_addr_find(const struct device *dev,
    1272              :                                                    uint8_t addr);
    1273              : 
    1274              : /**
    1275              :  * @brief Find a I3C target device descriptor by static address.
    1276              :  *
    1277              :  * This finds the I3C target device descriptor in the attached
    1278              :  * device list matching the static address (@p addr)
    1279              :  *
    1280              :  * @param dev Pointer to controller device driver instance.
    1281              :  * @param addr static address to be matched.
    1282              :  *
    1283              :  * @return Pointer to the I3C target device descriptor, or
    1284              :  *         `NULL` if none is found.
    1285              :  */
    1286            1 : struct i3c_device_desc *i3c_dev_list_i3c_static_addr_find(const struct device *dev,
    1287              :                                                           uint8_t addr);
    1288              : 
    1289              : /**
    1290              :  * @brief Find a I2C target device descriptor by address.
    1291              :  *
    1292              :  * This finds the I2C target device descriptor in the attached
    1293              :  * device list matching the address (@p addr)
    1294              :  *
    1295              :  * @param dev Pointer to controller device driver instance.
    1296              :  * @param addr Address to be matched.
    1297              :  *
    1298              :  * @return Pointer to the I2C target device descriptor, or
    1299              :  *         `NULL` if none is found.
    1300              :  */
    1301            1 : struct i3c_i2c_device_desc *i3c_dev_list_i2c_addr_find(const struct device *dev,
    1302              :                                                        uint16_t addr);
    1303              : 
    1304              : /**
    1305              :  * @brief Helper function to find a usable address during ENTDAA.
    1306              :  *
    1307              :  * This is a helper function to find a usable address during
    1308              :  * Dynamic Address Assignment. Given the PID (@p pid), it will
    1309              :  * search through the device list for the matching device
    1310              :  * descriptor. If the device descriptor indicates that there is
    1311              :  * a preferred address (i.e. assigned-address in device tree,
    1312              :  * i3c_device_desc::init_dynamic_addr), this preferred
    1313              :  * address will be returned if this address is still available.
    1314              :  * If it is not available, another free address will be returned.
    1315              :  *
    1316              :  * If @p must_match is true, the PID (@p pid) must match
    1317              :  * one of the device in the device list.
    1318              :  *
    1319              :  * If @p must_match is false, this will return an arbitrary
    1320              :  * address. This is useful when not all devices are described in
    1321              :  * device tree. Or else, the DAA process cannot proceed since
    1322              :  * there is no address to be assigned.
    1323              :  *
    1324              :  * If @p assigned_okay is true, it will return the same address
    1325              :  * already assigned to the device
    1326              :  * (i3c_device_desc::dynamic_addr). If no address has been
    1327              :  * assigned, it behaves as if @p assigned_okay is false.
    1328              :  * This is useful for assigning the same address to the same
    1329              :  * device (for example, hot-join after device coming back from
    1330              :  * suspend).
    1331              :  *
    1332              :  * If @p assigned_okay is false, the device cannot have an address
    1333              :  * assigned already (that i3c_device_desc::dynamic_addr is not
    1334              :  * zero). This is mainly used during the initial DAA.
    1335              :  *
    1336              :  * @param[in] addr_slots Pointer to address slots struct.
    1337              :  * @param[in] dev_list Pointer to the device list struct.
    1338              :  * @param[in] pid Provisioned ID of device to be assigned address.
    1339              :  * @param[in] must_match True if PID must match devices in
    1340              :  *                       the device list. False otherwise.
    1341              :  * @param[in] assigned_okay True if it is okay to return the
    1342              :  *                          address already assigned to the target
    1343              :  *                          matching the PID (@p pid).
    1344              :  * @param[out] target Store the pointer of the device descriptor
    1345              :  *                    if it matches the incoming PID (@p pid).
    1346              :  * @param[out] addr Address to be assigned to target device.
    1347              :  *
    1348              :  * @retval 0 if successful.
    1349              :  * @retval -ENODEV if no device matches the PID (@p pid) in
    1350              :  *                 the device list and @p must_match is true.
    1351              :  * @retval -EINVAL if the device matching PID (@p pid) already
    1352              :  *                 has an address assigned or invalid function
    1353              :  *                 arguments.
    1354              :  */
    1355            1 : int i3c_dev_list_daa_addr_helper(struct i3c_addr_slots *addr_slots,
    1356              :                                  const struct i3c_dev_list *dev_list,
    1357              :                                  uint64_t pid, bool must_match,
    1358              :                                  bool assigned_okay,
    1359              :                                  struct i3c_device_desc **target,
    1360              :                                  uint8_t *addr);
    1361              : #endif /* CONFIG_I3C_CONTROLLER */
    1362              : /**
    1363              :  * @brief Configure the I3C hardware.
    1364              :  *
    1365              :  * @param dev Pointer to controller device driver instance.
    1366              :  * @param type Type of configuration parameters being passed
    1367              :  *             in @p config.
    1368              :  * @param config Pointer to the configuration parameters.
    1369              :  *
    1370              :  * @retval 0 If successful.
    1371              :  * @retval -EINVAL If invalid configure parameters.
    1372              :  * @retval -EIO General Input/Output errors.
    1373              :  * @retval -ENOSYS If not implemented.
    1374              :  */
    1375            1 : static inline int i3c_configure(const struct device *dev,
    1376              :                                 enum i3c_config_type type, void *config)
    1377              : {
    1378              :         const struct i3c_driver_api *api =
    1379              :                 (const struct i3c_driver_api *)dev->api;
    1380              : 
    1381              :         if (api->configure == NULL) {
    1382              :                 return -ENOSYS;
    1383              :         }
    1384              : 
    1385              :         return api->configure(dev, type, config);
    1386              : }
    1387              : #if defined(CONFIG_I3C_CONTROLLER) || defined(__DOXYGEN__)
    1388              : /**
    1389              :  * @brief Get the controller device configuration for an I3C device.
    1390              :  *
    1391              :  * This function retrieves the configuration parameters specific to an
    1392              :  * I3C controller device. It is a type-safe wrapper around @ref i3c_config_get
    1393              :  * that ensures the correct structure type is passed.
    1394              :  *
    1395              :  * @param dev Pointer to the I3C controller device instance.
    1396              :  * @param config Pointer to a @ref i3c_config_controller structure
    1397              :  *               where the configuration will be stored.
    1398              :  *
    1399              :  * @retval 0 If successful.
    1400              :  * @retval -EIO General Input/Output errors.
    1401              :  * @retval -ENOSYS If not implemented.
    1402              :  */
    1403            1 : static inline int i3c_configure_controller(const struct device *dev,
    1404              :                                            struct i3c_config_controller *config)
    1405              : {
    1406              :         return i3c_configure(dev, I3C_CONFIG_CONTROLLER, config);
    1407              : }
    1408              : #endif /* CONFIG_I3C_CONTROLLER */
    1409              : #if defined(CONFIG_I3C_TARGET) || defined(__DOXYGEN__)
    1410              : /**
    1411              :  * @brief Get the target device configuration for an I3C device.
    1412              :  *
    1413              :  * This function retrieves the configuration parameters specific to an
    1414              :  * I3C target device. It is a type-safe wrapper around @ref i3c_config_get
    1415              :  * that ensures the correct structure type is passed.
    1416              :  *
    1417              :  * @param dev Pointer to the I3C controller device instance.
    1418              :  * @param config Pointer to a @ref i3c_config_target structure
    1419              :  *                    where the configuration will be stored.
    1420              :  *
    1421              :  * @retval 0 If successful.
    1422              :  * @retval -EIO General Input/Output errors.
    1423              :  * @retval -ENOSYS If not implemented.
    1424              :  */
    1425            1 : static inline int i3c_configure_target(const struct device *dev,
    1426              :                                        struct i3c_config_target *config)
    1427              : {
    1428              :         return i3c_configure(dev, I3C_CONFIG_TARGET, config);
    1429              : }
    1430              : #endif /* CONFIG_I3C_TARGET */
    1431              : /**
    1432              :  * @brief Get configuration of the I3C hardware.
    1433              :  *
    1434              :  * This provides a way to get the current configuration of the I3C hardware.
    1435              :  *
    1436              :  * This can return cached config or probed hardware parameters, but it has to
    1437              :  * be up to date with current configuration.
    1438              :  *
    1439              :  * @param[in] dev Pointer to controller device driver instance.
    1440              :  * @param[in] type Type of configuration parameters being passed
    1441              :  *                 in @p config.
    1442              :  * @param[in,out] config Pointer to the configuration parameters.
    1443              :  *
    1444              :  * Note that if @p type is #I3C_CONFIG_CUSTOM, @p config must contain
    1445              :  * the ID of the parameter to be retrieved.
    1446              :  *
    1447              :  * @retval 0 If successful.
    1448              :  * @retval -EIO General Input/Output errors.
    1449              :  * @retval -ENOSYS If not implemented.
    1450              :  */
    1451            1 : static inline int i3c_config_get(const struct device *dev,
    1452              :                                  enum i3c_config_type type, void *config)
    1453              : {
    1454              :         const struct i3c_driver_api *api =
    1455              :                 (const struct i3c_driver_api *)dev->api;
    1456              : 
    1457              :         if (api->config_get == NULL) {
    1458              :                 return -ENOSYS;
    1459              :         }
    1460              : 
    1461              :         return api->config_get(dev, type, config);
    1462              : }
    1463              : #if defined(CONFIG_I3C_CONTROLLER) || defined(__DOXYGEN__)
    1464              : /**
    1465              :  * @brief Get the controller device configuration for an I3C device.
    1466              :  *
    1467              :  * This function sets the configuration parameters specific to an
    1468              :  * I3C controller device. It is a type-safe wrapper around @ref i3c_config_get
    1469              :  * that ensures the correct structure type is passed.
    1470              :  *
    1471              :  * @param[in] dev Pointer to the I3C controller device instance.
    1472              :  * @param[out] config Pointer to a @ref i3c_config_controller structure
    1473              :  *                    where the configuration will be used.
    1474              :  *
    1475              :  * @retval 0 If successful.
    1476              :  * @retval -EIO General Input/Output errors.
    1477              :  * @retval -ENOSYS If not implemented.
    1478              :  */
    1479            1 : static inline int i3c_config_get_controller(const struct device *dev,
    1480              :                                             struct i3c_config_controller *config)
    1481              : {
    1482              :         return i3c_config_get(dev, I3C_CONFIG_CONTROLLER, config);
    1483              : }
    1484              : #endif /* CONFIG_I3C_CONTROLLER */
    1485              : #if defined(CONFIG_I3C_TARGET) || defined(__DOXYGEN__)
    1486              : /**
    1487              :  * @brief Get the target device configuration for an I3C device.
    1488              :  *
    1489              :  * This function sets the configuration parameters specific to an
    1490              :  * I3C target device. It is a type-safe wrapper around @ref i3c_config_get
    1491              :  * that ensures the correct structure type is passed.
    1492              :  *
    1493              :  * @param[in] dev Pointer to the I3C controller device instance.
    1494              :  * @param[out] config Pointer to a @ref i3c_config_target structure
    1495              :  *                    where the configuration will be used.
    1496              :  *
    1497              :  * @retval 0 If successful.
    1498              :  * @retval -EIO General Input/Output errors.
    1499              :  * @retval -ENOSYS If not implemented.
    1500              :  */
    1501            1 : static inline int i3c_config_get_target(const struct device *dev,
    1502              :                                         struct i3c_config_target *config)
    1503              : {
    1504              :         return i3c_config_get(dev, I3C_CONFIG_TARGET, config);
    1505              : }
    1506              : #endif /* CONFIG_I3C_TARGET */
    1507              : #if defined(CONFIG_I3C_CONTROLLER) || defined(__DOXYGEN__)
    1508              : /**
    1509              :  * @brief Attempt bus recovery on the I3C bus.
    1510              :  *
    1511              :  * This routine asks the controller to attempt bus recovery.
    1512              :  *
    1513              :  * @retval 0 If successful.
    1514              :  * @retval -EBUSY If bus recovery fails.
    1515              :  * @retval -EIO General input / output error.
    1516              :  * @retval -ENOSYS Bus recovery is not supported by the controller driver.
    1517              :  */
    1518            1 : static inline int i3c_recover_bus(const struct device *dev)
    1519              : {
    1520              :         const struct i3c_driver_api *api =
    1521              :                 (const struct i3c_driver_api *)dev->api;
    1522              : 
    1523              :         if (api->recover_bus == NULL) {
    1524              :                 return -ENOSYS;
    1525              :         }
    1526              : 
    1527              :         return api->recover_bus(dev);
    1528              : }
    1529              : 
    1530              : /**
    1531              :  * @brief Attach an I3C device
    1532              :  *
    1533              :  * Called to attach a I3C device to the addresses. This is
    1534              :  * typically called before a SETDASA or ENTDAA to reserve
    1535              :  * the addresses. This will also call the optional api to
    1536              :  * update any registers within the driver if implemented.
    1537              :  *
    1538              :  * @warning
    1539              :  * Use cases involving multiple writers to the i3c/i2c devices must prevent
    1540              :  * concurrent write operations, either by preventing all writers from
    1541              :  * being preempted or by using a mutex to govern writes to the i3c/i2c devices.
    1542              :  *
    1543              :  * @param target Pointer to the target device descriptor
    1544              :  *
    1545              :  * @retval 0 If successful.
    1546              :  * @retval -EINVAL If address is not available or if the device
    1547              :  *     has already been attached before
    1548              :  */
    1549            1 : int i3c_attach_i3c_device(struct i3c_device_desc *target);
    1550              : 
    1551              : /**
    1552              :  * @brief Reattach I3C device
    1553              :  *
    1554              :  * called after every time an I3C device has its address
    1555              :  * changed. It can be because the device has been powered
    1556              :  * down and has lost its address, or it can happen when a
    1557              :  * device had a static address and has been assigned a
    1558              :  * dynamic address with SETDASA or a dynamic address has
    1559              :  * been updated with SETNEWDA. This will also call the
    1560              :  * optional api to update any registers within the driver
    1561              :  * if implemented.
    1562              :  *
    1563              :  * @warning
    1564              :  * Use cases involving multiple writers to the i3c/i2c devices must prevent
    1565              :  * concurrent write operations, either by preventing all writers from
    1566              :  * being preempted or by using a mutex to govern writes to the i3c/i2c devices.
    1567              :  *
    1568              :  * @param target Pointer to the target device descriptor
    1569              :  * @param old_dyn_addr The old dynamic address of target device, 0 if
    1570              :  *            there was no old dynamic address
    1571              :  *
    1572              :  * @retval 0 If successful.
    1573              :  * @retval -EINVAL If address is not available
    1574              :  */
    1575            1 : int i3c_reattach_i3c_device(struct i3c_device_desc *target, uint8_t old_dyn_addr);
    1576              : 
    1577              : /**
    1578              :  * @brief Detach I3C Device
    1579              :  *
    1580              :  * called to remove an I3C device and to free up the address
    1581              :  * that it used. If it's dynamic address was not set, then it
    1582              :  * assumed that SETDASA failed and will free it's static addr.
    1583              :  * This will also call the optional api to update any registers
    1584              :  * within the driver if implemented.
    1585              :  *
    1586              :  * @warning
    1587              :  * Use cases involving multiple writers to the i3c/i2c devices must prevent
    1588              :  * concurrent write operations, either by preventing all writers from
    1589              :  * being preempted or by using a mutex to govern writes to the i3c/i2c devices.
    1590              :  *
    1591              :  * @param target Pointer to the target device descriptor
    1592              :  *
    1593              :  * @retval 0 If successful.
    1594              :  * @retval -EINVAL If device is already detached
    1595              :  */
    1596            1 : int i3c_detach_i3c_device(struct i3c_device_desc *target);
    1597              : 
    1598              : /**
    1599              :  * @brief Attach an I2C device
    1600              :  *
    1601              :  * Called to attach a I2C device to the addresses. This will
    1602              :  * also call the optional api to update any registers within
    1603              :  * the driver if implemented.
    1604              :  *
    1605              :  * @warning
    1606              :  * Use cases involving multiple writers to the i3c/i2c devices must prevent
    1607              :  * concurrent write operations, either by preventing all writers from
    1608              :  * being preempted or by using a mutex to govern writes to the i3c/i2c devices.
    1609              :  *
    1610              :  * @param target Pointer to the target device descriptor
    1611              :  *
    1612              :  * @retval 0 If successful.
    1613              :  * @retval -EINVAL If address is not available or if the device
    1614              :  *     has already been attached before
    1615              :  */
    1616            1 : int i3c_attach_i2c_device(struct i3c_i2c_device_desc *target);
    1617              : 
    1618              : /**
    1619              :  * @brief Detach I2C Device
    1620              :  *
    1621              :  * called to remove an I2C device and to free up the address
    1622              :  * that it used. This will also call the optional api to
    1623              :  * update any registers within the driver if implemented.
    1624              :  *
    1625              :  * @warning
    1626              :  * Use cases involving multiple writers to the i3c/i2c devices must prevent
    1627              :  * concurrent write operations, either by preventing all writers from
    1628              :  * being preempted or by using a mutex to govern writes to the i3c/i2c devices.
    1629              :  *
    1630              :  * @param target Pointer to the target device descriptor
    1631              :  *
    1632              :  * @retval 0 If successful.
    1633              :  * @retval -EINVAL If device is already detached
    1634              :  */
    1635            1 : int i3c_detach_i2c_device(struct i3c_i2c_device_desc *target);
    1636              : 
    1637              : /**
    1638              :  * @brief Perform Dynamic Address Assignment on the I3C bus.
    1639              :  *
    1640              :  * This routine asks the controller to perform dynamic address assignment
    1641              :  * where the controller belongs. Only the active controller of the bus
    1642              :  * should do this.
    1643              :  *
    1644              :  * @note For controller driver implementation, the controller should perform
    1645              :  * SETDASA to allow static addresses to be the dynamic addresses before
    1646              :  * actually doing ENTDAA.
    1647              :  *
    1648              :  * @param dev Pointer to the device structure for the controller driver
    1649              :  *            instance.
    1650              :  *
    1651              :  * @retval 0 If successful.
    1652              :  * @retval -EBUSY Bus is busy.
    1653              :  * @retval -EIO General input / output error.
    1654              :  * @retval -ENODEV If a provisioned ID does not match to any target devices
    1655              :  *                 in the registered device list.
    1656              :  * @retval -ENOSPC No more free addresses can be assigned to target.
    1657              :  * @retval -ENOSYS Dynamic address assignment is not supported by
    1658              :  *                 the controller driver.
    1659              :  */
    1660            1 : static inline int i3c_do_daa(const struct device *dev)
    1661              : {
    1662              :         const struct i3c_driver_api *api =
    1663              :                 (const struct i3c_driver_api *)dev->api;
    1664              : 
    1665              :         if (api->do_daa == NULL) {
    1666              :                 return -ENOSYS;
    1667              :         }
    1668              : 
    1669              :         return api->do_daa(dev);
    1670              : }
    1671              : 
    1672              : /**
    1673              :  * @brief Send CCC to the bus.
    1674              :  *
    1675              :  * @param dev Pointer to the device structure for the controller driver
    1676              :  *            instance.
    1677              :  * @param payload Pointer to the structure describing the CCC payload.
    1678              :  *
    1679              :  * @retval 0 If successful.
    1680              :  * @retval -EBUSY Bus is busy.
    1681              :  * @retval -EIO General Input / output error.
    1682              :  * @retval -EINVAL Invalid valid set in the payload structure.
    1683              :  * @retval -ENOSYS Not implemented.
    1684              :  */
    1685            1 : __syscall int i3c_do_ccc(const struct device *dev,
    1686              :                          struct i3c_ccc_payload *payload);
    1687              : 
    1688              : static inline int z_impl_i3c_do_ccc(const struct device *dev,
    1689              :                                     struct i3c_ccc_payload *payload)
    1690              : {
    1691              :         const struct i3c_driver_api *api =
    1692              :                 (const struct i3c_driver_api *)dev->api;
    1693              : 
    1694              :         if (api->do_ccc == NULL) {
    1695              :                 return -ENOSYS;
    1696              :         }
    1697              : 
    1698              :         return api->do_ccc(dev, payload);
    1699              : }
    1700              : 
    1701              : /**
    1702              :  * @addtogroup i3c_transfer_api
    1703              :  * @{
    1704              :  */
    1705              : 
    1706              : /**
    1707              :  * @brief Perform data transfer from the controller to a I3C target device.
    1708              :  *
    1709              :  * This routine provides a generic interface to perform data transfer
    1710              :  * to a target device synchronously. Use i3c_read()/i3c_write()
    1711              :  * for simple read or write.
    1712              :  *
    1713              :  * The array of message @p msgs must not be `NULL`.  The number of
    1714              :  * message @p num_msgs may be zero, in which case no transfer occurs.
    1715              :  *
    1716              :  * @note Not all scatter/gather transactions can be supported by all
    1717              :  * drivers.  As an example, a gather write (multiple consecutive
    1718              :  * i3c_msg buffers all configured for #I3C_MSG_WRITE) may be packed
    1719              :  * into a single transaction by some drivers, but others may emit each
    1720              :  * fragment as a distinct write transaction, which will not produce
    1721              :  * the same behavior.  See the documentation of i3c_msg for
    1722              :  * limitations on support for multi-message bus transactions.
    1723              :  *
    1724              :  * @param target I3C target device descriptor.
    1725              :  * @param msgs Array of messages to transfer.
    1726              :  * @param num_msgs Number of messages to transfer.
    1727              :  *
    1728              :  * @retval 0 If successful.
    1729              :  * @retval -EBUSY Bus is busy.
    1730              :  * @retval -EIO General input / output error.
    1731              :  */
    1732            1 : __syscall int i3c_transfer(struct i3c_device_desc *target,
    1733              :                            struct i3c_msg *msgs, uint8_t num_msgs);
    1734              : 
    1735              : static inline int z_impl_i3c_transfer(struct i3c_device_desc *target,
    1736              :                                       struct i3c_msg *msgs, uint8_t num_msgs)
    1737              : {
    1738              :         const struct i3c_driver_api *api =
    1739              :                 (const struct i3c_driver_api *)target->bus->api;
    1740              : 
    1741              :         return api->i3c_xfers(target->bus, target, msgs, num_msgs);
    1742              : }
    1743              : 
    1744              : /** @} */
    1745              : 
    1746              : /**
    1747              :  * Find a registered I3C target device.
    1748              :  *
    1749              :  * Controller only API.
    1750              :  *
    1751              :  * This returns the I3C device descriptor of the I3C device
    1752              :  * matching the incoming @p id.
    1753              :  *
    1754              :  * @param dev Pointer to controller device driver instance.
    1755              :  * @param id Pointer to I3C device ID.
    1756              :  *
    1757              :  * @return Pointer to I3C device descriptor, or `NULL` if
    1758              :  *         no I3C device found matching incoming @p id.
    1759              :  */
    1760              : static inline
    1761            1 : struct i3c_device_desc *i3c_device_find(const struct device *dev,
    1762              :                                         const struct i3c_device_id *id)
    1763              : {
    1764              :         const struct i3c_driver_api *api =
    1765              :                 (const struct i3c_driver_api *)dev->api;
    1766              : 
    1767              :         if (api->i3c_device_find == NULL) {
    1768              :                 return NULL;
    1769              :         }
    1770              : 
    1771              :         return api->i3c_device_find(dev, id);
    1772              : }
    1773              : #endif /* CONFIG_I3C_CONTROLLER */
    1774              : #if defined(CONFIG_I3C_USE_IBI) || defined(__DOXYGEN__)
    1775              : /**
    1776              :  * @addtogroup i3c_ibi
    1777              :  * @{
    1778              :  */
    1779              : 
    1780              : #if defined(CONFIG_I3C_CONTROLLER) || defined(__DOXYGEN__)
    1781              : /**
    1782              :  * @brief ACK or NACK IBI HJ Requests
    1783              :  *
    1784              :  * This tells the controller to Acknowledge or Not Acknowledge
    1785              :  * In-Band Interrupt Hot-Join Requests.
    1786              :  *
    1787              :  * @param dev Pointer to controller device driver instance.
    1788              :  * @param ack True to ack, False to nack
    1789              :  *
    1790              :  * @retval 0 if operation is successful.
    1791              :  * @retval -EIO General input / output error.
    1792              :  */
    1793            1 : static inline int i3c_ibi_hj_response(const struct device *dev,
    1794              :                                       bool ack)
    1795              : {
    1796              :         const struct i3c_driver_api *api =
    1797              :                 (const struct i3c_driver_api *)dev->api;
    1798              : 
    1799              :         if (api->ibi_hj_response == NULL) {
    1800              :                 return -ENOSYS;
    1801              :         }
    1802              : 
    1803              :         return api->ibi_hj_response(dev, ack);
    1804              : }
    1805              : #endif /* CONFIG_I3C_CONTROLLER */
    1806              : #if defined(CONFIG_I3C_TARGET) || defined(__DOXYGEN__)
    1807              : /**
    1808              :  * @brief Raise an In-Band Interrupt (IBI).
    1809              :  *
    1810              :  * This raises an In-Band Interrupt (IBI) to the active controller.
    1811              :  *
    1812              :  * @param dev Pointer to controller device driver instance.
    1813              :  * @param request Pointer to the IBI request struct.
    1814              :  *
    1815              :  * @retval 0 if operation is successful.
    1816              :  * @retval -EIO General input / output error.
    1817              :  */
    1818            1 : static inline int i3c_ibi_raise(const struct device *dev,
    1819              :                                 struct i3c_ibi *request)
    1820              : {
    1821              :         const struct i3c_driver_api *api =
    1822              :                 (const struct i3c_driver_api *)dev->api;
    1823              : 
    1824              :         if (api->ibi_raise == NULL) {
    1825              :                 return -ENOSYS;
    1826              :         }
    1827              : 
    1828              :         return api->ibi_raise(dev, request);
    1829              : }
    1830              : #endif /* CONFIG_I3C_TARGET */
    1831              : #if defined(CONFIG_I3C_CONTROLLER) || defined(__DOXYGEN__)
    1832              : /**
    1833              :  * @brief Enable IBI of a target device.
    1834              :  *
    1835              :  * This enables IBI of a target device where the IBI has already been
    1836              :  * request.
    1837              :  *
    1838              :  * @param target I3C target device descriptor.
    1839              :  *
    1840              :  * @retval 0 If successful.
    1841              :  * @retval -EIO General Input / output error.
    1842              :  * @retval -ENOMEM If these is no more empty entries in
    1843              :  *                 the controller's IBI table (if the controller
    1844              :  *                 uses such table).
    1845              :  */
    1846            1 : static inline int i3c_ibi_enable(struct i3c_device_desc *target)
    1847              : {
    1848              :         const struct i3c_driver_api *api =
    1849              :                 (const struct i3c_driver_api *)target->bus->api;
    1850              : 
    1851              :         if (api->ibi_enable == NULL) {
    1852              :                 return -ENOSYS;
    1853              :         }
    1854              : 
    1855              :         return api->ibi_enable(target->bus, target);
    1856              : }
    1857              : 
    1858              : /**
    1859              :  * @brief Disable IBI of a target device.
    1860              :  *
    1861              :  * This enables IBI of a target device where the IBI has already been
    1862              :  * request.
    1863              :  *
    1864              :  * @param target I3C target device descriptor.
    1865              :  *
    1866              :  * @retval 0 If successful.
    1867              :  * @retval -EIO General Input / output error.
    1868              :  * @retval -ENODEV If IBI is not previously enabled for @p target.
    1869              :  */
    1870            1 : static inline int i3c_ibi_disable(struct i3c_device_desc *target)
    1871              : {
    1872              :         const struct i3c_driver_api *api =
    1873              :                 (const struct i3c_driver_api *)target->bus->api;
    1874              : 
    1875              :         if (api->ibi_disable == NULL) {
    1876              :                 return -ENOSYS;
    1877              :         }
    1878              : 
    1879              :         return api->ibi_disable(target->bus, target);
    1880              : }
    1881              : #endif /* CONFIG_I3C_CONTROLLER */
    1882              : #endif /* CONFIG_I3C_USE_IBI */
    1883              : /**
    1884              :  * @brief Check if target's IBI has payload.
    1885              :  *
    1886              :  * This reads the BCR from the device descriptor struct to determine
    1887              :  * whether IBI from device has payload.
    1888              :  *
    1889              :  * Note that BCR must have been obtained from device and
    1890              :  * i3c_device_desc::bcr must be set.
    1891              :  *
    1892              :  * @return True if IBI has payload, false otherwise.
    1893              :  */
    1894            1 : static inline int i3c_ibi_has_payload(struct i3c_device_desc *target)
    1895              : {
    1896              :         return (target->bcr & I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE)
    1897              :                 == I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE;
    1898              : }
    1899              : 
    1900              : /**
    1901              :  * @brief Check if device is IBI capable.
    1902              :  *
    1903              :  * This reads the BCR from the device descriptor struct to determine
    1904              :  * whether device is capable of IBI.
    1905              :  *
    1906              :  * Note that BCR must have been obtained from device and
    1907              :  * i3c_device_desc::bcr must be set.
    1908              :  *
    1909              :  * @return True if IBI has payload, false otherwise.
    1910              :  */
    1911            1 : static inline int i3c_device_is_ibi_capable(struct i3c_device_desc *target)
    1912              : {
    1913              :         return (target->bcr & I3C_BCR_IBI_REQUEST_CAPABLE)
    1914              :                 == I3C_BCR_IBI_REQUEST_CAPABLE;
    1915              : }
    1916              : 
    1917              : /**
    1918              :  * @brief Check if the target is controller capable
    1919              :  *
    1920              :  * This reads the BCR from the device descriptor struct to determine
    1921              :  * whether the target is controller capable
    1922              :  *
    1923              :  * Note that BCR must have been obtained from device and
    1924              :  * i3c_device_desc::bcr must be set.
    1925              :  *
    1926              :  * @return True if target is controller capable, false otherwise.
    1927              :  */
    1928            1 : static inline int i3c_device_is_controller_capable(struct i3c_device_desc *target)
    1929              : {
    1930              :         return I3C_BCR_DEVICE_ROLE(target->bcr)
    1931              :                 == I3C_BCR_DEVICE_ROLE_I3C_CONTROLLER_CAPABLE;
    1932              : }
    1933              : 
    1934              : /** @} */
    1935              : #if defined(CONFIG_I3C_CONTROLLER) || defined(__DOXYGEN__)
    1936              : /**
    1937              :  * @addtogroup i3c_transfer_api
    1938              :  * @{
    1939              :  */
    1940              : 
    1941              : /**
    1942              :  * @brief Write a set amount of data to an I3C target device.
    1943              :  *
    1944              :  * This routine writes a set amount of data synchronously.
    1945              :  *
    1946              :  * @param target I3C target device descriptor.
    1947              :  * @param buf Memory pool from which the data is transferred.
    1948              :  * @param num_bytes Number of bytes to write.
    1949              :  *
    1950              :  * @retval 0 If successful.
    1951              :  * @retval -EBUSY Bus is busy.
    1952              :  * @retval -EIO General input / output error.
    1953              :  */
    1954            1 : static inline int i3c_write(struct i3c_device_desc *target,
    1955              :                             const uint8_t *buf, uint32_t num_bytes)
    1956              : {
    1957              :         struct i3c_msg msg;
    1958              : 
    1959              :         msg.buf = (uint8_t *)buf;
    1960              :         msg.len = num_bytes;
    1961              :         msg.flags = I3C_MSG_WRITE | I3C_MSG_STOP;
    1962              :         msg.hdr_mode = 0;
    1963              :         msg.hdr_cmd_code = 0;
    1964              : 
    1965              :         return i3c_transfer(target, &msg, 1);
    1966              : }
    1967              : 
    1968              : /**
    1969              :  * @brief Read a set amount of data from an I3C target device.
    1970              :  *
    1971              :  * This routine reads a set amount of data synchronously.
    1972              :  *
    1973              :  * @param target I3C target device descriptor.
    1974              :  * @param buf Memory pool that stores the retrieved data.
    1975              :  * @param num_bytes Number of bytes to read.
    1976              :  *
    1977              :  * @retval 0 If successful.
    1978              :  * @retval -EBUSY Bus is busy.
    1979              :  * @retval -EIO General input / output error.
    1980              :  */
    1981            1 : static inline int i3c_read(struct i3c_device_desc *target,
    1982              :                            uint8_t *buf, uint32_t num_bytes)
    1983              : {
    1984              :         struct i3c_msg msg;
    1985              : 
    1986              :         msg.buf = buf;
    1987              :         msg.len = num_bytes;
    1988              :         msg.flags = I3C_MSG_READ | I3C_MSG_STOP;
    1989              :         msg.hdr_mode = 0;
    1990              :         msg.hdr_cmd_code = 0;
    1991              : 
    1992              :         return i3c_transfer(target, &msg, 1);
    1993              : }
    1994              : 
    1995              : /**
    1996              :  * @brief Write then read data from an I3C target device.
    1997              :  *
    1998              :  * This supports the common operation "this is what I want", "now give
    1999              :  * it to me" transaction pair through a combined write-then-read bus
    2000              :  * transaction.
    2001              :  *
    2002              :  * @param target I3C target device descriptor.
    2003              :  * @param write_buf Pointer to the data to be written
    2004              :  * @param num_write Number of bytes to write
    2005              :  * @param read_buf Pointer to storage for read data
    2006              :  * @param num_read Number of bytes to read
    2007              :  *
    2008              :  * @retval 0 if successful
    2009              :  * @retval -EBUSY Bus is busy.
    2010              :  * @retval -EIO General input / output error.
    2011              :  */
    2012            1 : static inline int i3c_write_read(struct i3c_device_desc *target,
    2013              :                                  const void *write_buf, size_t num_write,
    2014              :                                  void *read_buf, size_t num_read)
    2015              : {
    2016              :         struct i3c_msg msg[2];
    2017              : 
    2018              :         msg[0].buf = (uint8_t *)write_buf;
    2019              :         msg[0].len = num_write;
    2020              :         msg[0].flags = I3C_MSG_WRITE;
    2021              :         msg[0].hdr_mode = 0;
    2022              :         msg[0].hdr_cmd_code = 0;
    2023              : 
    2024              :         msg[1].buf = (uint8_t *)read_buf;
    2025              :         msg[1].len = num_read;
    2026              :         msg[1].flags = I3C_MSG_RESTART | I3C_MSG_READ | I3C_MSG_STOP;
    2027              :         msg[1].hdr_mode = 0;
    2028              :         msg[1].hdr_cmd_code = 0;
    2029              : 
    2030              :         return i3c_transfer(target, msg, 2);
    2031              : }
    2032              : 
    2033              : /**
    2034              :  * @brief Read multiple bytes from an internal address of an I3C target device.
    2035              :  *
    2036              :  * This routine reads multiple bytes from an internal address of an
    2037              :  * I3C target device synchronously.
    2038              :  *
    2039              :  * Instances of this may be replaced by i3c_write_read().
    2040              :  *
    2041              :  * @param target I3C target device descriptor,
    2042              :  * @param start_addr Internal address from which the data is being read.
    2043              :  * @param buf Memory pool that stores the retrieved data.
    2044              :  * @param num_bytes Number of bytes being read.
    2045              :  *
    2046              :  * @retval 0 If successful.
    2047              :  * @retval -EBUSY Bus is busy.
    2048              :  * @retval -EIO General input / output error.
    2049              :  */
    2050            1 : static inline int i3c_burst_read(struct i3c_device_desc *target,
    2051              :                                  uint8_t start_addr,
    2052              :                                  uint8_t *buf,
    2053              :                                  uint32_t num_bytes)
    2054              : {
    2055              :         return i3c_write_read(target,
    2056              :                               &start_addr, sizeof(start_addr),
    2057              :                               buf, num_bytes);
    2058              : }
    2059              : 
    2060              : /**
    2061              :  * @brief Write multiple bytes to an internal address of an I3C target device.
    2062              :  *
    2063              :  * This routine writes multiple bytes to an internal address of an
    2064              :  * I3C target device synchronously.
    2065              :  *
    2066              :  * @warning The combined write synthesized by this API may not be
    2067              :  * supported on all I3C devices.  Uses of this API may be made more
    2068              :  * portable by replacing them with calls to i3c_write() passing a
    2069              :  * buffer containing the combined address and data.
    2070              :  *
    2071              :  * @param target I3C target device descriptor.
    2072              :  * @param start_addr Internal address to which the data is being written.
    2073              :  * @param buf Memory pool from which the data is transferred.
    2074              :  * @param num_bytes Number of bytes being written.
    2075              :  *
    2076              :  * @retval 0 If successful.
    2077              :  * @retval -EBUSY Bus is busy.
    2078              :  * @retval -EIO General input / output error.
    2079              :  */
    2080            1 : static inline int i3c_burst_write(struct i3c_device_desc *target,
    2081              :                                   uint8_t start_addr,
    2082              :                                   const uint8_t *buf,
    2083              :                                   uint32_t num_bytes)
    2084              : {
    2085              :         struct i3c_msg msg[2];
    2086              : 
    2087              :         msg[0].buf = &start_addr;
    2088              :         msg[0].len = 1U;
    2089              :         msg[0].flags = I3C_MSG_WRITE;
    2090              :         msg[0].hdr_mode = 0;
    2091              :         msg[0].hdr_cmd_code = 0;
    2092              : 
    2093              :         msg[1].buf = (uint8_t *)buf;
    2094              :         msg[1].len = num_bytes;
    2095              :         msg[1].flags = I3C_MSG_WRITE | I3C_MSG_STOP;
    2096              :         msg[1].hdr_mode = 0;
    2097              :         msg[1].hdr_cmd_code = 0;
    2098              : 
    2099              :         return i3c_transfer(target, msg, 2);
    2100              : }
    2101              : 
    2102              : /**
    2103              :  * @brief Read internal register of an I3C target device.
    2104              :  *
    2105              :  * This routine reads the value of an 8-bit internal register of an I3C target
    2106              :  * device synchronously.
    2107              :  *
    2108              :  * @param target I3C target device descriptor.
    2109              :  * @param reg_addr Address of the internal register being read.
    2110              :  * @param value Memory pool that stores the retrieved register value.
    2111              :  *
    2112              :  * @retval 0 If successful.
    2113              :  * @retval -EBUSY Bus is busy.
    2114              :  * @retval -EIO General input / output error.
    2115              :  */
    2116            1 : static inline int i3c_reg_read_byte(struct i3c_device_desc *target,
    2117              :                                     uint8_t reg_addr, uint8_t *value)
    2118              : {
    2119              :         return i3c_write_read(target,
    2120              :                               &reg_addr, sizeof(reg_addr),
    2121              :                               value, sizeof(*value));
    2122              : }
    2123              : 
    2124              : /**
    2125              :  * @brief Write internal register of an I3C target device.
    2126              :  *
    2127              :  * This routine writes a value to an 8-bit internal register of an I3C target
    2128              :  * device synchronously.
    2129              :  *
    2130              :  * @note This function internally combines the register and value into
    2131              :  * a single bus transaction.
    2132              :  *
    2133              :  * @param target I3C target device descriptor.
    2134              :  * @param reg_addr Address of the internal register being written.
    2135              :  * @param value Value to be written to internal register.
    2136              :  *
    2137              :  * @retval 0 If successful.
    2138              :  * @retval -EBUSY Bus is busy.
    2139              :  * @retval -EIO General input / output error.
    2140              :  */
    2141            1 : static inline int i3c_reg_write_byte(struct i3c_device_desc *target,
    2142              :                                      uint8_t reg_addr, uint8_t value)
    2143              : {
    2144              :         uint8_t tx_buf[2] = {reg_addr, value};
    2145              : 
    2146              :         return i3c_write(target, tx_buf, 2);
    2147              : }
    2148              : 
    2149              : /**
    2150              :  * @brief Update internal register of an I3C target device.
    2151              :  *
    2152              :  * This routine updates the value of a set of bits from an 8-bit internal
    2153              :  * register of an I3C target device synchronously.
    2154              :  *
    2155              :  * @note If the calculated new register value matches the value that
    2156              :  * was read this function will not generate a write operation.
    2157              :  *
    2158              :  * @param target I3C target device descriptor.
    2159              :  * @param reg_addr Address of the internal register being updated.
    2160              :  * @param mask Bitmask for updating internal register.
    2161              :  * @param value Value for updating internal register.
    2162              :  *
    2163              :  * @retval 0 If successful.
    2164              :  * @retval -EBUSY Bus is busy.
    2165              :  * @retval -EIO General input / output error.
    2166              :  */
    2167            1 : static inline int i3c_reg_update_byte(struct i3c_device_desc *target,
    2168              :                                       uint8_t reg_addr, uint8_t mask,
    2169              :                                       uint8_t value)
    2170              : {
    2171              :         uint8_t old_value, new_value;
    2172              :         int rc;
    2173              : 
    2174              :         rc = i3c_reg_read_byte(target, reg_addr, &old_value);
    2175              :         if (rc != 0) {
    2176              :                 return rc;
    2177              :         }
    2178              : 
    2179              :         new_value = (old_value & ~mask) | (value & mask);
    2180              :         if (new_value == old_value) {
    2181              :                 return 0;
    2182              :         }
    2183              : 
    2184              :         return i3c_reg_write_byte(target, reg_addr, new_value);
    2185              : }
    2186              : 
    2187              : /**
    2188              :  * @brief Dump out an I3C message
    2189              :  *
    2190              :  * Dumps out a list of I3C messages. For any that are writes (W), the data is
    2191              :  * displayed in hex.
    2192              :  *
    2193              :  * It looks something like this (with name "testing"):
    2194              :  *
    2195              :  * @code
    2196              :  * D: I3C msg: testing, addr=56
    2197              :  * D:    W len=01:
    2198              :  * D: contents:
    2199              :  * D: 06                      |.
    2200              :  * D:    W len=0e:
    2201              :  * D: contents:
    2202              :  * D: 00 01 02 03 04 05 06 07 |........
    2203              :  * D: 08 09 0a 0b 0c 0d       |......
    2204              :  * @endcode
    2205              :  *
    2206              :  * @param name Name of this dump, displayed at the top.
    2207              :  * @param msgs Array of messages to dump.
    2208              :  * @param num_msgs Number of messages to dump.
    2209              :  * @param target I3C target device descriptor.
    2210              :  */
    2211            1 : void i3c_dump_msgs(const char *name, const struct i3c_msg *msgs,
    2212              :                    uint8_t num_msgs, struct i3c_device_desc *target);
    2213              : 
    2214              : /** @} */
    2215              : 
    2216              : /**
    2217              :  * @brief Generic helper function to perform bus initialization.
    2218              :  *
    2219              :  * @param dev Pointer to controller device driver instance.
    2220              :  * @param i3c_dev_list Pointer to I3C device list.
    2221              :  *
    2222              :  * @retval 0 If successful.
    2223              :  * @retval -EBUSY Bus is busy.
    2224              :  * @retval -EIO General input / output error.
    2225              :  * @retval -ENODEV If a provisioned ID does not match to any target devices
    2226              :  *                 in the registered device list.
    2227              :  * @retval -ENOSPC No more free addresses can be assigned to target.
    2228              :  * @retval -ENOSYS Dynamic address assignment is not supported by
    2229              :  *                 the controller driver.
    2230              :  */
    2231            1 : int i3c_bus_init(const struct device *dev,
    2232              :                  const struct i3c_dev_list *i3c_dev_list);
    2233              : 
    2234              : /**
    2235              :  * @brief Get basic information from device and update device descriptor.
    2236              :  *
    2237              :  * This retrieves some basic information:
    2238              :  *   * Bus Characteristics Register (GETBCR)
    2239              :  *   * Device Characteristics Register (GETDCR)
    2240              :  * from the device and update the corresponding fields of the device
    2241              :  * descriptor.
    2242              :  *
    2243              :  * This only updates the field(s) in device descriptor
    2244              :  * only if CCC operations succeed.
    2245              :  *
    2246              :  * @param[in,out] target I3C target device descriptor.
    2247              :  *
    2248              :  * @retval 0 if successful.
    2249              :  * @retval -EIO General Input/Output error.
    2250              :  */
    2251            1 : int i3c_device_basic_info_get(struct i3c_device_desc *target);
    2252              : 
    2253              : /**
    2254              :  * @brief Get advanced information from device and update device descriptor.
    2255              :  *
    2256              :  * This retrieves some information:
    2257              :  *   * Max Read Length (GETMRL)
    2258              :  *   * Max Write Length (GETMWL)
    2259              :  *   * Get Capabilities (GETCAPS)
    2260              :  *   * Max Device Speed (GETMXDS) (if applicable)
    2261              :  * from the device and update the corresponding fields of the device
    2262              :  * descriptor.
    2263              :  *
    2264              :  * This only updates the field(s) in device descriptor
    2265              :  * only if CCC operations succeed.
    2266              :  *
    2267              :  * @note This should only be called after i3c_device_basic_info_get() or
    2268              :  * if the BCR was already obtained through ENTDAA, DEFTGTS, or GETBCR.
    2269              :  *
    2270              :  * @param[in,out] target I3C target device descriptor.
    2271              :  *
    2272              :  * @retval 0 if successful.
    2273              :  * @retval -EIO General Input/Output error.
    2274              :  */
    2275            1 : int i3c_device_adv_info_get(struct i3c_device_desc *target);
    2276              : 
    2277              : /**
    2278              :  * @brief Get all information from device and update device descriptor.
    2279              :  *
    2280              :  * This retrieves all information:
    2281              :  *   * Bus Characteristics Register (GETBCR)
    2282              :  *   * Device Characteristics Register (GETDCR)
    2283              :  *   * Max Read Length (GETMRL)
    2284              :  *   * Max Write Length (GETMWL)
    2285              :  *   * Get Capabilities (GETCAPS)
    2286              :  *   * Max Device Speed (GETMXDS) (if applicable)
    2287              :  * from the device and update the corresponding fields of the device
    2288              :  * descriptor.
    2289              :  *
    2290              :  * This only updates the field(s) in device descriptor
    2291              :  * only if CCC operations succeed.
    2292              :  *
    2293              :  * @param[in,out] target I3C target device descriptor.
    2294              :  *
    2295              :  * @retval 0 if successful.
    2296              :  * @retval -EIO General Input/Output error.
    2297              :  */
    2298            1 : static inline int i3c_device_info_get(struct i3c_device_desc *target)
    2299              : {
    2300              :         int rc;
    2301              : 
    2302              :         rc = i3c_device_basic_info_get(target);
    2303              :         if (rc != 0) {
    2304              :                 return rc;
    2305              :         }
    2306              : 
    2307              :         return i3c_device_adv_info_get(target);
    2308              : }
    2309              : 
    2310              : /**
    2311              :  * @brief Check if the bus has a secondary controller.
    2312              :  *
    2313              :  * This reads the BCR from the device descriptor struct of all targets
    2314              :  * to determine whether a device is a secondary controller.
    2315              :  *
    2316              :  * @param dev Pointer to controller device driver instance.
    2317              :  *
    2318              :  * @return True if the bus has a secondary controller, false otherwise.
    2319              :  */
    2320            1 : bool i3c_bus_has_sec_controller(const struct device *dev);
    2321              : 
    2322              : /**
    2323              :  * @brief Reset all devices on the bus and clear their dynamic addresses.
    2324              :  *
    2325              :  * Sends the RSTDAA (Reset Dynamic Address Assignment) CCC to all devices on the bus.
    2326              :  *
    2327              :  * @param dev Pointer to the controller device driver instance.
    2328              :  *
    2329              :  * @retval 0 If successful.
    2330              :  * @retval -EIO General Input/Output error.
    2331              :  */
    2332            1 : int i3c_bus_rstdaa_all(const struct device *dev);
    2333              : 
    2334              : /**
    2335              :  * @brief Assign a dynamic address to a device using its static address.
    2336              :  *
    2337              :  * Sends the SETDASA (Set Dynamic Address from Static Address) CCC to the target device.
    2338              :  *
    2339              :  * @param desc Pointer to the target device descriptor.
    2340              :  * @param dynamic_addr The dynamic address to assign to the device.
    2341              :  *
    2342              :  * @retval 0 If successful.
    2343              :  * @retval -EADDRNOTAVAIL If the address is not available.
    2344              :  * @retval -EIO General Input/Output error.
    2345              :  */
    2346            1 : int i3c_bus_setdasa(struct i3c_device_desc *desc, uint8_t dynamic_addr);
    2347              : 
    2348              : /**
    2349              :  * @brief Assign a new dynamic address to a device.
    2350              :  *
    2351              :  * Sends the SETNEWDA (Set New Dynamic Address) CCC to the target device.
    2352              :  *
    2353              :  * @param desc Pointer to the target device descriptor.
    2354              :  * @param dynamic_addr The new dynamic address to assign to the device.
    2355              :  *
    2356              :  * @retval 0 If successful.
    2357              :  * @retval -EADDRNOTAVAIL If the address is not available.
    2358              :  * @retval -EIO General Input/Output error.
    2359              :  */
    2360            1 : int i3c_bus_setnewda(struct i3c_device_desc *desc, uint8_t dynamic_addr);
    2361              : 
    2362              : /**
    2363              :  * @brief Assign static addresses as dynamic addresses for all devices on the bus.
    2364              :  *
    2365              :  * Sends the SETAASA (Set All Addresses to Static Address) CCC to all devices on the bus.
    2366              :  *
    2367              :  * @param dev Pointer to the controller device driver instance.
    2368              :  *
    2369              :  * @retval 0 If successful.
    2370              :  * @retval -EIO General Input/Output error.
    2371              :  */
    2372            1 : int i3c_bus_setaasa(const struct device *dev);
    2373              : 
    2374              : /**
    2375              :  * @brief Retrieve the Bus Characteristics Register (BCR) of a device.
    2376              :  *
    2377              :  * Sends the GETBCR CCC to the target device and updates its descriptor.
    2378              :  *
    2379              :  * @param desc Pointer to the target device descriptor.
    2380              :  *
    2381              :  * @retval 0 If successful.
    2382              :  * @retval -EIO General Input/Output error.
    2383              :  */
    2384            1 : int i3c_bus_getbcr(struct i3c_device_desc *desc);
    2385              : 
    2386              : /**
    2387              :  * @brief Retrieve the Device Characteristics Register (DCR) of a device.
    2388              :  *
    2389              :  * Sends the GETDCR CCC to the target device and updates its descriptor.
    2390              :  *
    2391              :  * @param desc Pointer to the target device descriptor.
    2392              :  *
    2393              :  * @retval 0 If successful.
    2394              :  * @retval -EIO General Input/Output error.
    2395              :  */
    2396            1 : int i3c_bus_getdcr(struct i3c_device_desc *desc);
    2397              : 
    2398              : /**
    2399              :  * @brief Retrieve the Provisional ID (PID) of a device.
    2400              :  *
    2401              :  * Sends the GETPID CCC to the target device and updates its descriptor.
    2402              :  *
    2403              :  * @param desc Pointer to the target device descriptor.
    2404              :  *
    2405              :  * @retval 0 If successful.
    2406              :  * @retval -EIO General Input/Output error.
    2407              :  */
    2408            1 : int i3c_bus_getpid(struct i3c_device_desc *desc);
    2409              : 
    2410              : /**
    2411              :  * @brief Retrieve the Maximum Read Length (MRL) of a device.
    2412              :  *
    2413              :  * Sends the GETMRL CCC to the target device and updates its descriptor.
    2414              :  *
    2415              :  * @param desc Pointer to the target device descriptor.
    2416              :  *
    2417              :  * @retval 0 If successful.
    2418              :  * @retval -EIO General Input/Output error.
    2419              :  */
    2420            1 : int i3c_bus_getmrl(struct i3c_device_desc *desc);
    2421              : 
    2422              : /**
    2423              :  * @brief Retrieve the Maximum Write Length (MWL) of a device.
    2424              :  *
    2425              :  * Sends the GETMWL CCC to the target device and updates its descriptor.
    2426              :  *
    2427              :  * @param desc Pointer to the target device descriptor.
    2428              :  *
    2429              :  * @retval 0 If successful.
    2430              :  * @retval -EIO General Input/Output error.
    2431              :  */
    2432            1 : int i3c_bus_getmwl(struct i3c_device_desc *desc);
    2433              : 
    2434              : /**
    2435              :  * @brief Set the Maximum Read Length (MRL) for a device.
    2436              :  *
    2437              :  * Sends the SETMRL CCC to the target device.
    2438              :  *
    2439              :  * @param desc Pointer to the target device descriptor.
    2440              :  * @param mrl Maximum read length to set.
    2441              :  * @param ibi_len Maximum IBI length to set.
    2442              :  *
    2443              :  * @retval 0 If successful.
    2444              :  * @retval -EIO General Input/Output error.
    2445              :  */
    2446            1 : int i3c_bus_setmrl(struct i3c_device_desc *desc, uint16_t mrl, uint8_t ibi_len);
    2447              : 
    2448              : /**
    2449              :  * @brief Set the Maximum Write Length (MWL) for a device.
    2450              :  *
    2451              :  * Sends the SETMWL CCC to the target device.
    2452              :  *
    2453              :  * @param desc Pointer to the target device descriptor.
    2454              :  * @param mwl Maximum write length to set.
    2455              :  *
    2456              :  * @retval 0 If successful.
    2457              :  * @retval -EIO General Input/Output error.
    2458              :  */
    2459            1 : int i3c_bus_setmwl(struct i3c_device_desc *desc, uint16_t mwl);
    2460              : 
    2461              : /**
    2462              :  * @brief Set the Maximum Read Length (MRL) for all devices on the bus.
    2463              :  *
    2464              :  * Sends the SETMRL CCC to all devices on the bus.
    2465              :  *
    2466              :  * @param dev Pointer to the controller device driver instance.
    2467              :  * @param mrl Maximum read length to set.
    2468              :  * @param ibi_len Maximum IBI length to set.
    2469              :  * @param has_ibi_size True if to transmit max ibi len
    2470              :  *
    2471              :  * @retval 0 If successful.
    2472              :  * @retval -EIO General Input/Output error.
    2473              :  */
    2474            1 : int i3c_bus_setmrl_all(const struct device *dev, uint16_t mrl, uint8_t ibi_len, bool has_ibi_size);
    2475              : 
    2476              : /**
    2477              :  * @brief Set the Maximum Write Length (MWL) for all devices on the bus.
    2478              :  *
    2479              :  * Sends the SETMWL CCC to all devices on the bus.
    2480              :  *
    2481              :  * @param dev Pointer to the controller device driver instance.
    2482              :  * @param mwl Maximum write length to set.
    2483              :  *
    2484              :  * @retval 0 If successful.
    2485              :  * @retval -EIO General Input/Output error.
    2486              :  */
    2487            1 : int i3c_bus_setmwl_all(const struct device *dev, uint16_t mwl);
    2488              : 
    2489              : #if defined(CONFIG_I3C_TARGET) || defined(__DOXYGEN__)
    2490              : /**
    2491              :  * @brief Retrieve the Active Controller's Dynamic Address (ACCCR).
    2492              :  *
    2493              :  * Sends the GETACCCR CCC to the target device and verifies the response.
    2494              :  *
    2495              :  * @param desc Pointer to the target device descriptor.
    2496              :  *
    2497              :  * @retval 0 If successful.
    2498              :  * @retval -EIO General Input/Output error.
    2499              :  */
    2500            1 : int i3c_bus_getacccr(struct i3c_device_desc *desc);
    2501              : 
    2502              : /**
    2503              :  * @brief Send the CCC DEFTGTS
    2504              :  *
    2505              :  * This builds the payload required for DEFTGTS and transmits it out
    2506              :  *
    2507              :  * @param dev Pointer to controller device driver instance.
    2508              :  *
    2509              :  * @retval 0 if successful.
    2510              :  * @retval -ENOMEM No memory to build the payload.
    2511              :  * @retval -EIO General Input/Output error.
    2512              :  */
    2513            1 : int i3c_bus_deftgts(const struct device *dev);
    2514              : #endif /* CONFIG_I3C_TARGET */
    2515              : 
    2516              : /**
    2517              :  * @brief Calculate odd parity
    2518              :  *
    2519              :  * Calculate the Odd Parity of a Target Address.
    2520              :  *
    2521              :  * @param p The 7b target dynamic address
    2522              :  *
    2523              :  * @return The odd parity bit
    2524              :  */
    2525            1 : uint8_t i3c_odd_parity(uint8_t p);
    2526              : 
    2527              : /**
    2528              :  * @brief Perform Controller Handoff
    2529              :  *
    2530              :  * This performs the controller handoff according to 5.1.7.1 of
    2531              :  * I3C v1.1.1 Specification.
    2532              :  *
    2533              :  * @param target I3C target device descriptor.
    2534              :  * @param requested True if the target requested the Handoff, False if
    2535              :  * the active controller is passing it to a secondary controller
    2536              :  *
    2537              :  * @retval 0 if successful.
    2538              :  * @retval -EIO General Input/Output error.
    2539              :  * @retval -EBUSY Target cannot accept Controller Handoff
    2540              :  */
    2541            1 : int i3c_device_controller_handoff(struct i3c_device_desc *target, bool requested);
    2542              : #endif /* CONFIG_I3C_CONTROLLER */
    2543              : 
    2544              : #if defined(CONFIG_I3C_USE_IBI) || defined(__DOXYGEN__)
    2545              : #if (defined(CONFIG_I3C_CONTROLLER) && defined(CONFIG_I3C_TARGET)) || defined(__DOXYGEN__)
    2546              : /**
    2547              :  * @brief Call back for when Controllership is Handoffed to itself
    2548              :  *
    2549              :  * This reads the DEFTGTS it received earlier and processes it by reading
    2550              :  * the PIDs of all the devices with GETPID and then matching it with known
    2551              :  * PIDS. If it does not match, then it will attempt to grab a mem slab
    2552              :  * for i3c_device_desc. It will then obtain the standard I3C information
    2553              :  * from the device.
    2554              :  *
    2555              :  * @param work pointer to the work item.
    2556              :  */
    2557            1 : void i3c_sec_handoffed(struct k_work *work);
    2558              : #endif /* CONFIG_I3C_CONTROLLER && CONFIG_I3C_TARGET */
    2559              : #endif /* CONFIG_I3C_USE_IBI */
    2560              : 
    2561              : #if (defined(CONFIG_I3C_NUM_OF_DESC_MEM_SLABS) && CONFIG_I3C_NUM_OF_DESC_MEM_SLABS > 0) ||         \
    2562              :         defined(__DOXYGEN__)
    2563              : 
    2564              : /**
    2565              :  * @brief Allocate memory for a i3c device descriptor
    2566              :  *
    2567              :  * This allocates memory from a mem slab for a i3c_device_desc
    2568              :  *
    2569              :  * @retval Pointer to allocated i3c_device_desc
    2570              :  * @retval NULL if no mem slabs available
    2571              :  */
    2572            1 : struct i3c_device_desc *i3c_device_desc_alloc(void);
    2573              : 
    2574              : /**
    2575              :  * @brief Free memory from a i3c device descriptor
    2576              :  *
    2577              :  * This frees memory from a mem slab of a i3c_device_desc
    2578              :  *
    2579              :  * @param desc Pointer to allocated i3c_device_desc
    2580              :  */
    2581            1 : void i3c_device_desc_free(struct i3c_device_desc *desc);
    2582              : 
    2583              : /**
    2584              :  * @brief Report if the i3c device descriptor was from a mem slab
    2585              :  *
    2586              :  * This reports if the i3c_device_desc was from a memory slab
    2587              :  *
    2588              :  * @param desc Pointer to a i3c_device_desc
    2589              :  *
    2590              :  * @return True if from a memory slab, False if not
    2591              :  */
    2592            1 : bool i3c_device_desc_in_pool(struct i3c_device_desc *desc);
    2593              : 
    2594              : #else
    2595              : 
    2596              : static inline struct i3c_device_desc *i3c_device_desc_alloc(void)
    2597              : {
    2598              :         return NULL;
    2599              : }
    2600              : 
    2601              : static inline void i3c_device_desc_free(struct i3c_device_desc *desc)
    2602              : {
    2603              :         ARG_UNUSED(desc);
    2604              : }
    2605              : 
    2606              : static inline bool i3c_device_desc_in_pool(struct i3c_device_desc *desc)
    2607              : {
    2608              :         ARG_UNUSED(desc);
    2609              :         return false;
    2610              : }
    2611              : 
    2612              : #endif /* CONFIG_I3C_NUM_OF_DESC_MEM_SLABS > 0 */
    2613              : 
    2614              : #if (defined(CONFIG_I3C_I2C_NUM_OF_DESC_MEM_SLABS) && CONFIG_I3C_I2C_NUM_OF_DESC_MEM_SLABS > 0) || \
    2615              :         defined(__DOXYGEN__)
    2616              : 
    2617              : /**
    2618              :  * @brief Allocate memory for a i3c i2c device descriptor
    2619              :  *
    2620              :  * This allocates memory from a mem slab for a i3c_i2c_device_desc
    2621              :  *
    2622              :  * @return Pointer to allocated i3c_i2c_device_desc, NULL if none
    2623              :  *         available
    2624              :  */
    2625            1 : struct i3c_i2c_device_desc *i3c_i2c_device_desc_alloc(void);
    2626              : 
    2627              : /**
    2628              :  * @brief Free memory from a i3c i2c device descriptor
    2629              :  *
    2630              :  * This frees memory from a mem slab of a i3c_i2c_device_desc
    2631              :  *
    2632              :  * @param desc Pointer to allocated i3c_i2c_device_desc
    2633              :  */
    2634            1 : void i3c_i2c_device_desc_free(struct i3c_i2c_device_desc *desc);
    2635              : 
    2636              : /**
    2637              :  * @brief Report if the i3c i2c device descriptor was from a mem slab
    2638              :  *
    2639              :  * This reports if the i3c_i2c_device_desc was from a memory slab
    2640              :  *
    2641              :  * @param desc Pointer to a i3c_i2c_device_desc
    2642              :  *
    2643              :  * @return True if from a memory slab, False if not
    2644              :  */
    2645            1 : bool i3c_i2c_device_desc_in_pool(struct i3c_i2c_device_desc *desc);
    2646              : 
    2647              : #else
    2648              : 
    2649              : static inline struct i3c_i2c_device_desc *i3c_i2c_device_desc_alloc(void)
    2650              : {
    2651              :         return NULL;
    2652              : }
    2653              : 
    2654              : static inline void i3c_i2c_device_desc_free(struct i3c_i2c_device_desc *desc)
    2655              : {
    2656              :         ARG_UNUSED(desc);
    2657              : }
    2658              : 
    2659              : static inline bool i3c_i2c_device_desc_in_pool(struct i3c_i2c_device_desc *desc)
    2660              : {
    2661              :         ARG_UNUSED(desc);
    2662              :         return false;
    2663              : }
    2664              : 
    2665              : #endif /* CONFIG_I3C_I2C_NUM_OF_DESC_MEM_SLABS > 0 */
    2666              : 
    2667              : #if defined(CONFIG_I3C_RTIO) || defined(__DOXYGEN__)
    2668              : 
    2669            0 : struct i3c_iodev_data {
    2670            0 :         const struct device *bus;
    2671            0 :         const struct i3c_device_id dev_id;
    2672              : };
    2673              : 
    2674              : /**
    2675              :  * @brief Fallback submit implementation
    2676              :  *
    2677              :  * This implementation will schedule a blocking I3C transaction on the bus via the RTIO work
    2678              :  * queue. It is only used if the I3C driver did not implement the iodev_submit function.
    2679              :  *
    2680              :  * @param dev Pointer to the device structure for an I3C controller driver.
    2681              :  * @param iodev_sqe Prepared submissions queue entry connected to an iodev
    2682              :  *                  defined by I3C_DT_IODEV_DEFINE.
    2683              :  */
    2684            1 : void i3c_iodev_submit_fallback(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe);
    2685              : 
    2686              : /**
    2687              :  * @brief Submit request(s) to an I3C device with RTIO
    2688              :  *
    2689              :  * @param iodev_sqe Prepared submissions queue entry connected to an iodev
    2690              :  *                  defined by I3C_DT_IODEV_DEFINE.
    2691              :  */
    2692            1 : static inline void i3c_iodev_submit(struct rtio_iodev_sqe *iodev_sqe)
    2693              : {
    2694              :         const struct i3c_iodev_data *data =
    2695              :                 (const struct i3c_iodev_data *)iodev_sqe->sqe.iodev->data;
    2696              :         const struct i3c_driver_api *api = (const struct i3c_driver_api *)data->bus->api;
    2697              : 
    2698              :         if (api->iodev_submit == NULL) {
    2699              :                 rtio_iodev_sqe_err(iodev_sqe, -ENOSYS);
    2700              :                 return;
    2701              :         }
    2702              :         api->iodev_submit(data->bus, iodev_sqe);
    2703              : }
    2704              : 
    2705            0 : extern const struct rtio_iodev_api i3c_iodev_api;
    2706              : 
    2707              : /**
    2708              :  * @brief Define an iodev for a given dt node on the bus
    2709              :  *
    2710              :  * These do not need to be shared globally but doing so
    2711              :  * will save a small amount of memory.
    2712              :  *
    2713              :  * @param name Symbolic name of the iodev to define
    2714              :  * @param node_id Devicetree node identifier
    2715              :  */
    2716            1 : #define I3C_DT_IODEV_DEFINE(name, node_id)                                      \
    2717              :         const struct i3c_iodev_data _i3c_iodev_data_##name = {                  \
    2718              :                 .bus = DEVICE_DT_GET(DT_BUS(node_id)),                          \
    2719              :                 .dev_id = I3C_DEVICE_ID_DT(node_id),                            \
    2720              :         };                                                                      \
    2721              :         RTIO_IODEV_DEFINE(name, &i3c_iodev_api, (void *)&_i3c_iodev_data_##name)
    2722              : 
    2723              : /**
    2724              :  * @brief Copy the i3c_msgs into a set of RTIO requests
    2725              :  *
    2726              :  * @param r RTIO context
    2727              :  * @param iodev RTIO IODev to target for the submissions
    2728              :  * @param msgs Array of messages
    2729              :  * @param num_msgs Number of i3c msgs in array
    2730              :  *
    2731              :  * @retval sqe Last submission in the queue added
    2732              :  * @retval NULL Not enough memory in the context to copy the requests
    2733              :  */
    2734            1 : struct rtio_sqe *i3c_rtio_copy(struct rtio *r,
    2735              :                                struct rtio_iodev *iodev,
    2736              :                                const struct i3c_msg *msgs,
    2737              :                                uint8_t num_msgs);
    2738              : 
    2739              : #endif /* CONFIG_I3C_RTIO */
    2740              : 
    2741              : #if defined(CONFIG_I3C_TARGET) || defined(__DOXYGEN__)
    2742              : /*
    2743              :  * This needs to be after declaration of struct i3c_driver_api,
    2744              :  * or else compiler complains about undefined type inside
    2745              :  * the static inline API wrappers.
    2746              :  */
    2747              : #include <zephyr/drivers/i3c/target_device.h>
    2748              : #endif /* CONFIG_I3C_TARGET */
    2749              : 
    2750              : #if defined(CONFIG_I3C_CONTROLLER) || defined(__DOXYGEN__)
    2751              : /*
    2752              :  * Include High-Data-Rate (HDR) inline helper functions
    2753              :  */
    2754              : #include <zephyr/drivers/i3c/hdr_ddr.h>
    2755              : #endif /* CONFIG_I3C_CONTROLLER */
    2756              : 
    2757              : #ifdef __cplusplus
    2758              : }
    2759              : #endif
    2760              : 
    2761              : /**
    2762              :  * @}
    2763              :  */
    2764              : 
    2765              : #include <zephyr/syscalls/i3c.h>
    2766              : 
    2767              : #endif /* ZEPHYR_INCLUDE_DRIVERS_I3C_H_ */
        

Generated by: LCOV version 2.0-1