LCOV - code coverage report
Current view: top level - zephyr/drivers - i3c.h Coverage Total Hit
Test: new.info Lines: 90.5 % 199 180
Test Date: 2025-10-20 12:20:01

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

Generated by: LCOV version 2.0-1