LCOV - code coverage report
Current view: top level - zephyr/drivers - i3c.h Hit Total Coverage
Test: new.info Lines: 139 157 88.5 %
Date: 2024-12-22 00:14:23

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

Generated by: LCOV version 1.14