I3C

I3C (Improved Inter-Integrated Circuit) is a two-signal shared peripheral interface bus. Devices on the bus can operate in two roles: as a “controller” that initiates transactions and controls the clock, or as a “target” that responds to transaction commands.

Currently, the API is based on I3C Specification version 1.1.1.

I3C Controller API

Zephyr’s I3C controller API is used when an I3C controller controls the bus, in particularly the start and stop conditions and the clock. This is the most common mode, used to interact with I3C target devices such as sensors.

Due to the nature of the I3C, there are devices on the bus where they may not have addresses when powered on. Therefore, an additional dynamic address assignment needs to be carried out by the I3C controller. Because of this, the controller needs to maintain separate structures to keep track of device status. This can be done at build time, for example, by creating arrays of device descriptors for both I3C and I2C devices:

static struct i3c_device_desc i3c_device_array[] = I3C_DEVICE_ARRAY_DT_INST(inst);
static struct i3c_i2c_device_desc i2c_device_array[] = I3C_I2C_DEVICE_ARRAY_DT_INST(inst);

The macros I3C_DEVICE_ARRAY_DT_INST and I3C_I2C_DEVICE_ARRAY_DT_INST are helper macros to aid in create arrays of device descriptors corresponding to the devicetree nodes under the I3C controller.

Here is a list of generic steps for initializing the I3C controller and the I3C bus inside the device driver initialization function:

  1. Initialize the data structure of the I3C controller device driver instance. The usual device defining macros such as DEVICE_DT_INST_DEFINE can be used, and the initialization function provided as a parameter to the macro.

    • The i3c_addr_slots and i3c_dev_list are structures to aid in address assignments and device list management. If this is being used, this struct needs to be initialized by calling i3c_addr_slots_init(). These two structures can also be used with various helper functions.

    • Initialize the device descriptors if needed by the controller driver.

  2. Initialize the hardware, including but not limited to:

    • Setup pin mux and directions.

    • Setup the clock for the controller.

    • Power on the hardware.

    • Configure the hardware (e.g. SCL clock frequency).

  3. Perform bus initialization. There is a generic helper function, i3c_bus_init(), which performs the following steps. This function can be used if the controller does not require any special handling during bus initialization.

    1. Do RSTDAA to reset dynamic addresses of connected devices. If any connected devices have already been assigned an address, the bookkeeping data structures do not have records of these, for example, at power-on. So it is a good idea to reset and assign them new addresses.

    2. Do DISEC to disable any events from devices.

    3. Do SETDASA to use static addresses as dynamic address if so desired.

      • SETAASA may not be supported for all connected devices to assign static addresses as dynamic addresses.

      • BCR and DCR need to be obtained separately to populate the relevant fields in the I3C target device descriptor struct.

    4. Do ENTDAA to start dynamic address assignment, if there are still devices without addresses.

      • If there is a device waiting for address, it will send its Provisioned ID, BCR, and DCR back. Match the received Provisioned ID to the list of registered I3C devices.

        • If there is a match, assign an address (either from the stated static address if SETDASA has not been done, or use a free address).

          • Also, set the BCR and DCR fields in the device descriptor struct.

        • If there is no match, depending on policy, it can be assigned a free address, or the device driver can stop the assignment process and errors out.

          • Note that the I3C API requires device descriptor to function. A device without a device descriptor cannot be accessed through the API.

      • This step can be skipped if there is no connected devices requiring DAA.

    5. These are optional but highly recommended:

      • Do GETMRL and GETMWL to get maximum read/write length.

      • Do GETMXDS to get maximum read/write speed and maximum read turnaround time.

      • The helper function, i3c_bus_init(), would retrieve basic device information such as BCR, DCR, MRL and MWL.

    6. Do ENEC to re-enable events from devices.

      • The helper function, i3c_bus_init(), only re-enables hot-join events. IBI event should only be enabled when enabling IBI of a device.

In-Band Interrupt (IBI)

If a target device can generate In-Band Interrupt (IBI), the controller needs to be made aware of it.

  • i3c_ibi_enable() to enable IBI of a target device.

    • Some controller hardware have IBI slots which need to be programmed so that the controller can recognize incoming IBIs from a particular target device.

      • If the hardware has IBI slots, i3c_ibi_enable() needs to program those IBI slots.

      • Note that there are usually limited IBI slots on the controller so this operation may fail.

    • The implementation in driver should also send the ENEC command to enable interrupt of this target device.

  • i3c_ibi_disable() to disable IBI of a target device.

    • If controller hardware makes use of IBI slots, this will remove description of the target device from the slots.

    • The implementation in driver should also send the DISEC command to disable interrupt of this target device.

Device Tree

Here is an example for defining a I3C controller in device tree:

i3c0: i3c@10000 {
        compatible = "vendor,i3c";

        #address-cells = < 0x3 >;
        #size-cells = < 0x0 >;

        reg = < 0x10000 0x1000 >;
        interrupts = < 0x1F 0x0 >;

        pinctrl-0 = < &pinmux-i3c >;
        pinctrl-names = "default";

        i2c-scl-hz = < 400000 >;

        i3c-scl-hz = < 12000000 >;

        status = "okay";

        i3c-dev0: i3c-dev0@420000ABCD12345678 {
                compatible = "vendor,i3c-dev";

                reg = < 0x42 0xABCD 0x12345678 >;

                status = "okay";
        };

        i2c-dev0: i2c-dev0@380000000000000050 {
                compatible = "vendor-i2c-dev";

                reg = < 0x38 0x0 0x50 >;

                status = "okay";
        };
};

I3C Devices

For I3C devices, the reg property has 3 elements:

  • The first one is the static address of the device.

    • Can be zero if static address is not used. Address will be assigned during DAA (Dynamic Address Assignment).

    • If non-zero and property assigned-address is not set, this will be the address of the device after SETDASA (Set Dynamic Address from Static Address) is issued.

  • Second element is the upper 16-bit of the Provisioned ID (PID) which contains the manufacturer ID left-shifted by 1. This is the bits 33-47 (zero-based) of the 48-bit Provisioned ID.

  • Third element contains the lower 32-bit of the Provisioned ID which is a combination of the part ID (left-shifted by 16, bits 16-31 of the PID) and the instance ID (left-shifted by 12, bits 12-15 of the PID).

Note that the unit-address (the part after @) must match the reg property fully where each element is treated as 32-bit integer, combining to form a 96-bit integer. This is required for properly generating device tree macros.

I2C Devices

For I2C devices where the device driver has support for working under I3C bus, the device node can be described as a child of the I3C controller. If the device driver is written to only work with I2C controllers, define the node under the I2C virtual controller as described below. Otherwise, the reg property, similar to I3C devices, has 3 elements:

  • The first one is the static address of the device. This must be a valid address as I2C devices do not support dynamic address assignment.

  • Second element is always zero.

    • This is used by various helper macros to determine whether the device tree entry corresponds to a I2C device.

  • Third element is the LVR (Legacy Virtual Register):

    • bit[31:8] are unused.

    • bit[7:5] are the I2C device index:

      • Index 0

        • I3C device has a 50 ns spike filter where it is not affected by high frequency on SCL.

      • Index 1

        • I2C device does not have a 50 ns spike filter but can work with high frequency on SCL.

      • Index 2

        • I3C device does not have a 50 ns spike filter and cannot work with high frequency on SCL.

    • bit[4] is the I2C mode indicator:

      • 0 is FM+ mode.

      • 1 is FM mode.

Similar to I3C devices, the unit-address must match the reg property fully where each element is treated as 32-bit integer, combining to form a 96-bit integer.

Device Drivers for I3C Devices

All of the transfer functions of I3C controller API require the use of device descriptors, i3c_device_desc. This struct contains runtime information about a I3C device, such as, its dynamic address, BCR, DCR, MRL and MWL. Therefore, the device driver of a I3C device should grab a pointer to this device descriptor from the controller using i3c_device_find(). This function takes an ID parameter of type i3c_device_id for matching. The returned pointer can then be used in subsequent API calls to the controller.

I2C Devices under I3C Bus

Since I3C is backware compatible with I2C, the I3C controller API can accommodate I2C API calls without modifications if the controller device driver implements the I2C API. This has the advantage of using existing I2C devices without any modifications to their device drivers. However, since the I3C controller API works on device descriptors, any calls to I2C API will need to look up the corresponding device descriptor from the I2C device address. This adds a bit of processing cost to any I2C API calls.

On the other hand, a device driver can be extended to utilize native I2C device support via the I3C controller API. During device initialization, i3c_i2c_device_find() needs to be called to retrieve the pointer to the device descriptor. This pointer can be used in subsequent API calls.

Note that, with either methods mentioned above, the devicetree node of the I2C device must be declared according to I3C standard:

The I2C virtual controller device driver provides a way to interface I2C devices on the I3C bus where the associated device drivers can be used as-is without modifications. This requires adding an intermediate node in the device tree:

i3c0: i3c@10000 {
        <... I3C controller related properties ...>
        <... Nodes of I3C devices, if any ...>

        i2c-dev0: i2c-dev0@420000000000000050 {
                compatible = "vendor-i2c-dev";

                reg = < 0x42 0x0 0x50 >;

                status = "okay";
        };
};

Configuration Options

Related configuration options:

API Reference

group i3c_interface

I3C Interface.

Defines

I3C_BCR_MAX_DATA_SPEED_LIMIT
I3C_BCR_IBI_REQUEST_CAPABLE
I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE
I3C_BCR_OFFLINE_CAPABLE
I3C_BCR_VIRTUAL_TARGET
I3C_BCR_ADV_CAPABILITIES
I3C_BCR_DEVICE_ROLE_I3C_TARGET
I3C_BCR_DEVICE_ROLE_I3C_CONTROLLER_CAPABLE
I3C_BCR_DEVICE_ROLE_SHIFT
I3C_BCR_DEVICE_ROLE_MASK
I3C_BCR_DEVICE_ROLE(bcr)
I3C_DCR_I2C_FM_PLUS_MODE
I3C_DCR_I2C_FM_MODE
I3C_DCR_I2C_MODE_SHIFT
I3C_DCR_I2C_MODE_MASK
I3C_DCR_I2C_MODE(dcr)
I3C_DCR_I2C_DEV_IDX_0
I3C_DCR_I2C_DEV_IDX_1
I3C_DCR_I2C_DEV_IDX_2
I3C_DCR_I2C_DEV_IDX_SHIFT
I3C_DCR_I2C_DEV_IDX_MASK
I3C_DCR_I2C_DEV_IDX(dcr)
I3C_MSG_WRITE

Write message to I3C bus.

I3C_MSG_READ

Read message from I3C bus.

I3C_MSG_STOP

Send STOP after this message.

I3C_MSG_RESTART

RESTART I3C transaction for this message.

Note

Not all I3C drivers have or require explicit support for this feature. Some drivers require this be present on a read message that follows a write, or vice-versa. Some drivers will merge adjacent fragments into a single transaction using this flag; some will not.

I3C_MSG_HDR

Transfer use HDR mode

I3C_MSG_NBCH

Skip I3C broadcast header. Private Transfers only.

I3C_MSG_HDR_MODE0

I3C HDR Mode 0

I3C_MSG_HDR_MODE1

I3C HDR Mode 1

I3C_MSG_HDR_MODE2

I3C HDR Mode 2

I3C_MSG_HDR_MODE3

I3C HDR Mode 3

I3C_MSG_HDR_MODE4

I3C HDR Mode 4

I3C_MSG_HDR_MODE5

I3C HDR Mode 5

I3C_MSG_HDR_MODE6

I3C HDR Mode 6

I3C_MSG_HDR_MODE7

I3C HDR Mode 7

I3C_MSG_HDR_DDR

I3C HDR-DDR (Double Data Rate)

I3C_MSG_HDR_TSP

I3C HDR-TSP (Ternary Symbol Pure-bus)

I3C_MSG_HDR_TSL

I3C HDR-TSL (Ternary Symbol Legacy-inclusive-bus)

I3C_MSG_HDR_BT

I3C HDR-BT (Bulk Transport)

I3C_DEVICE_ID(pid)

Structure initializer for i3c_device_id from PID.

This helper macro expands to a static initializer for a struct i3c_device_id by populating the PID (Provisioned ID) field.

Parameters
  • pid – Provisioned ID.

Enums

enum i3c_bus_mode

I3C bus mode.

Values:

enumerator I3C_BUS_MODE_PURE

Only I3C devices are on the bus.

enumerator I3C_BUS_MODE_MIXED_FAST

Both I3C and legacy I2C devices are on the bus. The I2C devices have 50ns spike filter on SCL.

enumerator I3C_BUS_MODE_MIXED_LIMITED

Both I3C and legacy I2C devices are on the bus. The I2C devices do not have 50ns spike filter on SCL and can tolerate maximum SDR SCL clock frequency.

enumerator I3C_BUS_MODE_MIXED_SLOW

Both I3C and legacy I2C devices are on the bus. The I2C devices do not have 50ns spike filter on SCL but cannot tolerate maximum SDR SCL clock frequency.

enumerator I3C_BUS_MODE_MAX = I3C_BUS_MODE_MIXED_SLOW
enumerator I3C_BUS_MODE_INVALID
enum i3c_i2c_speed_type

I2C bus speed under I3C bus.

Only FM and FM+ modes are supported for I2C devices under I3C bus.

Values:

enumerator I3C_I2C_SPEED_FM

I2C FM mode

enumerator I3C_I2C_SPEED_FMPLUS

I2C FM+ mode

enumerator I3C_I2C_SPEED_MAX = I3C_I2C_SPEED_FMPLUS
enumerator I3C_I2C_SPEED_INVALID
enum i3c_data_rate

I3C data rate.

I3C data transfer rate defined by the I3C specification.

Values:

enumerator I3C_DATA_RATE_SDR

Single Data Rate messaging

enumerator I3C_DATA_RATE_HDR_DDR

High Data Rate - Double Data Rate messaging

enumerator I3C_DATA_RATE_HDR_TSL

High Data Rate - Ternary Symbol Legacy-inclusive-Bus

enumerator I3C_DATA_RATE_HDR_TSP

High Data Rate - Ternary Symbol for Pure Bus

enumerator I3C_DATA_RATE_HDR_BT

High Data Rate - Bulk Transport

enumerator I3C_DATA_RATE_MAX = I3C_DATA_RATE_HDR_BT
enumerator I3C_DATA_RATE_INVALID
enum i3c_sdr_controller_error_codes

I3C SDR Controller Error Codes.

These are error codes defined by the I3C specification.

I3C_ERROR_CE_UNKNOWN and I3C_ERROR_CE_NONE are not official error codes according to the specification. These are there simply to aid in error handling during interactions with the I3C drivers and subsystem.

Values:

enumerator I3C_ERROR_CE0

Transaction after sending CCC

enumerator I3C_ERROR_CE1

Monitoring Error

enumerator I3C_ERROR_CE2

No response to broadcast address (0x7E)

enumerator I3C_ERROR_CE3

Failed Controller Handoff

enumerator I3C_ERROR_CE_UNKNOWN

Unknown error (not official error code)

enumerator I3C_ERROR_CE_NONE

No error (not official error code)

enumerator I3C_ERROR_CE_MAX = I3C_ERROR_CE_UNKNOWN
enumerator I3C_ERROR_CE_INVALID
enum i3c_sdr_target_error_codes

I3C SDR Target Error Codes.

These are error codes defined by the I3C specification.

I3C_ERROR_TE_UNKNOWN and I3C_ERROR_TE_NONE are not official error codes according to the specification. These are there simply to aid in error handling during interactions with the I3C drivers and subsystem.

Values:

enumerator I3C_ERROR_TE0

Invalid Broadcast Address or Dynamic Address after DA assignment

enumerator I3C_ERROR_TE1

CCC Code

enumerator I3C_ERROR_TE2

Write Data

enumerator I3C_ERROR_TE3

Assigned Address during Dynamic Address Arbitration

enumerator I3C_ERROR_TE4

0x7E/R missing after RESTART during Dynamic Address Arbitration

enumerator I3C_ERROR_TE5

Transaction after detecting CCC

enumerator I3C_ERROR_TE6

Monitoring Error

enumerator I3C_ERROR_DBR

Dead Bus Recovery

enumerator I3C_ERROR_TE_UNKNOWN

Unknown error (not official error code)

enumerator I3C_ERROR_TE_NONE

No error (not official error code)

enumerator I3C_ERROR_TE_MAX = I3C_ERROR_TE_UNKNOWN
enumerator I3C_ERROR_TE_INVALID
enum i3c_config_type

Type of configuration being passed to configure function.

Values:

enumerator I3C_CONFIG_CONTROLLER
enumerator I3C_CONFIG_TARGET
enumerator I3C_CONFIG_CUSTOM

Functions

struct i3c_device_desc *i3c_dev_list_find(const struct i3c_dev_list *dev_list, const struct i3c_device_id *id)

Find a I3C target device descriptor by ID.

This finds the I3C target device descriptor in the device list matching the provided ID struct (id).

Parameters
  • dev_list – Pointer to the device list struct.

  • id – Pointer to I3C device ID struct.

Returns

Pointer the the I3C target device descriptor, or NULL if none is found.

struct i3c_device_desc *i3c_dev_list_i3c_addr_find(const struct i3c_dev_list *dev_list, uint8_t addr)

Find a I3C target device descriptor by dynamic address.

This finds the I3C target device descriptor in the device list matching the dynamic address (addr)

Parameters
  • dev_list – Pointer to the device list struct.

  • addr – Dynamic address to be matched.

Returns

Pointer the the I3C target device descriptor, or NULL if none is found.

struct i3c_i2c_device_desc *i3c_dev_list_i2c_addr_find(const struct i3c_dev_list *dev_list, uint16_t addr)

Find a I2C target device descriptor by address.

This finds the I2C target device descriptor in the device list matching the address (addr)

Parameters
  • dev_list – Pointer to the device list struct.

  • addr – Address to be matched.

Returns

Pointer the the I2C target device descriptor, or NULL if none is found.

int i3c_dev_list_daa_addr_helper(struct i3c_addr_slots *addr_slots, const struct i3c_dev_list *dev_list, uint64_t pid, bool must_match, bool assigned_okay, struct i3c_device_desc **target, uint8_t *addr)

Helper function to find a usable address during ENTDAA.

This is a helper function to find a usable address during Dynamic Address Assignment. Given the PID (pid

), it will search through the device list for the matching device descriptor. If the device descriptor indicates that there is a preferred address (i.e. assigned-address in device tree,

If

must_match is true, the PID (pid) must match one of the device in the device list.

See also

i3c_device_desc::init_dynamic_addr), this preferred address will be returned if this address is still available. If it is not available, another free address will be returned.

If must_match is false, this will return an arbitrary address. This is useful when not all devices are described in device tree. Or else, the DAA process cannot proceed since there is no address to be assigned.

If assigned_okay

is true, it will return the same address already assigned to the device (

If

assigned_okay is false, the device cannot have an address assigned already (that

See also

i3c_device_desc::dynamic_addr). If no address has been assigned, it behaves as if assigned_okay is false. This is useful for assigning the same address to the same device (for example, hot-join after device coming back from suspend).

See also

i3c_device_desc::dynamic_addr is not zero). This is mainly used during the initial DAA.

Parameters
  • addr_slots[in] Pointer to address slots struct.

  • dev_list[in] Pointer to the device list struct.

  • pid[in] Provisioned ID of device to be assigned address.

  • must_match[in] True if PID must match devices in the device list. False otherwise.

  • assigned_okay[in] True if it is okay to return the address already assigned to the target matching the PID (pid).

  • target[out] Store the pointer of the device descriptor if it matches the incoming PID (pid).

  • addr[out] Address to be assigned to target device.

Return values
  • 0 – if successful.

  • -ENODEV – if no device matches the PID (pid) in the device list and must_match is true.

  • -EINVAL – if the device matching PID (pid) already has an address assigned or invalid function arguments.

static inline int i3c_configure(const struct device *dev, enum i3c_config_type type, void *config)

Configure the I3C hardware.

Parameters
  • dev – Pointer to controller device driver instance.

  • type – Type of configuration parameters being passed in config.

  • config – Pointer to the configuration parameters.

Return values
  • 0 – If successful.

  • -EINVAL – If invalid configure parameters.

  • -EIO – General Input/Output errors.

  • -ENOSYS – If not implemented.

static inline int i3c_config_get(const struct device *dev, enum i3c_config_type type, void *config)

Get configuration of the I3C hardware.

This provides a way to get the current configuration of the I3C hardware.

This can return cached config or probed hardware parameters, but it has to be up to date with current configuration.

Note that if type is I3C_CONFIG_CUSTOM, config must contain the ID of the parameter to be retrieved.

Parameters
  • dev[in] Pointer to controller device driver instance.

  • type[in] Type of configuration parameters being passed in config.

  • config[inout] Pointer to the configuration parameters.

Return values
  • 0 – If successful.

  • -EIO – General Input/Output errors.

  • -ENOSYS – If not implemented.

static inline int i3c_recover_bus(const struct device *dev)

Attempt bus recovery on the I3C bus.

This routine asks the controller to attempt bus recovery.

Return values
  • 0 – If successful.

  • -EBUSY – If bus recovery fails.

  • -EIO – General input / output error.

  • -ENOSYS – Bus recovery is not supported by the controller driver.

static inline int i3c_do_daa(const struct device *dev)

Perform Dynamic Address Assignment on the I3C bus.

This routine asks the controller to perform dynamic address assignment where the controller belongs. Only the active controller of the bus should do this.

Note

For controller driver implementation, the controller should perform SETDASA to allow static addresses to be the dynamic addresses before actually doing ENTDAA.

Parameters
  • dev – Pointer to the device structure for the controller driver instance.

Return values
  • 0 – If successful.

  • -EBUSY – Bus is busy.

  • -EIO – General input / output error.

  • -ENODEV – If a provisioned ID does not match to any target devices in the registered device list.

  • -ENOSPC – No more free addresses can be assigned to target.

  • -ENOSYS – Dynamic address assignment is not supported by the controller driver.

int i3c_do_ccc(const struct device *dev, struct i3c_ccc_payload *payload)

Send CCC to the bus.

Parameters
  • dev – Pointer to the device structure for the controller driver instance.

  • payload – Pointer to the structure describing the CCC payload.

Return values
  • 0 – If successful.

  • -EBUSY – Bus is busy.

  • -EIO – General Input / output error.

  • -EINVAL – Invalid valid set in the payload structure.

  • -ENOSYS – Not implemented.

int i3c_transfer(struct i3c_device_desc *target, struct i3c_msg *msgs, uint8_t num_msgs)

Perform data transfer from the controller to a I3C target device.

This routine provides a generic interface to perform data transfer to a target device synchronously. Use i3c_read()/i3c_write() for simple read or write.

The array of message msgs must not be NULL. The number of message num_msgs may be zero, in which case no transfer occurs.

Note

Not all scatter/gather transactions can be supported by all drivers. As an example, a gather write (multiple consecutive i3c_msg buffers all configured for I3C_MSG_WRITE) may be packed into a single transaction by some drivers, but others may emit each fragment as a distinct write transaction, which will not produce the same behavior. See the documentation of struct i3c_msg for limitations on support for multi-message bus transactions.

Parameters
  • target – I3C target device descriptor.

  • msgs – Array of messages to transfer.

  • num_msgs – Number of messages to transfer.

Return values
  • 0 – If successful.

  • -EBUSY – Bus is busy.

  • -EIO – General input / output error.

static inline struct i3c_device_desc *i3c_device_find(const struct device *dev, const struct i3c_device_id *id)

Find a registered I3C target device.

Controller only API.

This returns the I3C device descriptor of the I3C device matching the incoming id.

Parameters
  • dev – Pointer to controller device driver instance.

  • id – Pointer to I3C device ID.

Returns

Pointer to I3C device descriptor, or NULL if no I3C device found matching incoming id.

static inline int i3c_ibi_raise(const struct device *dev, struct i3c_ibi *request)

Raise an In-Band Interrupt (IBI).

This raises an In-Band Interrupt (IBI) to the active controller.

Parameters
  • dev – Pointer to controller device driver instance.

  • request – Pointer to the IBI request struct.

Return values
  • 0 – if operation is successful.

  • -EIO – General input / output error.

static inline int i3c_ibi_enable(struct i3c_device_desc *target)

Enable IBI of a target device.

This enables IBI of a target device where the IBI has already been request.

Parameters
  • target – I3C target device descriptor.

Return values
  • 0 – If successful.

  • -EIO – General Input / output error.

  • -ENOMEM – If these is no more empty entries in the controller’s IBI table (if the controller uses such table).

static inline int i3c_ibi_disable(struct i3c_device_desc *target)

Disable IBI of a target device.

This enables IBI of a target device where the IBI has already been request.

Parameters
  • target – I3C target device descriptor.

Return values
  • 0 – If successful.

  • -EIO – General Input / output error.

  • -ENODEV – If IBI is not previously enabled for target.

static inline int i3c_ibi_has_payload(struct i3c_device_desc *target)

Check if target’s IBI has payload.

This reads the BCR from the device descriptor struct to determine whether IBI from device has payload.

Note that BCR must have been obtained from device and

See also

i3c_device_desc::bcr must be set.

Returns

True if IBI has payload, false otherwise.

static inline int i3c_device_is_ibi_capable(struct i3c_device_desc *target)

Check if device is IBI capable.

This reads the BCR from the device descriptor struct to determine whether device is capable of IBI.

Note that BCR must have been obtained from device and

See also

i3c_device_desc::bcr must be set.

Returns

True if IBI has payload, false otherwise.

static inline int i3c_write(struct i3c_device_desc *target, const uint8_t *buf, uint32_t num_bytes)

Write a set amount of data to an I3C target device.

This routine writes a set amount of data synchronously.

Parameters
  • target – I3C target device descriptor.

  • buf – Memory pool from which the data is transferred.

  • num_bytes – Number of bytes to write.

Return values
  • 0 – If successful.

  • -EBUSY – Bus is busy.

  • -EIO – General input / output error.

static inline int i3c_read(struct i3c_device_desc *target, uint8_t *buf, uint32_t num_bytes)

Read a set amount of data from an I3C target device.

This routine reads a set amount of data synchronously.

Parameters
  • target – I3C target device descriptor.

  • buf – Memory pool that stores the retrieved data.

  • num_bytes – Number of bytes to read.

Return values
  • 0 – If successful.

  • -EBUSY – Bus is busy.

  • -EIO – General input / output error.

static inline int i3c_write_read(struct i3c_device_desc *target, const void *write_buf, size_t num_write, void *read_buf, size_t num_read)

Write then read data from an I3C target device.

This supports the common operation “this is what I want”, “now give

it to me” transaction pair through a combined write-then-read bus transaction.

Parameters
  • target – I3C target device descriptor.

  • write_buf – Pointer to the data to be written

  • num_write – Number of bytes to write

  • read_buf – Pointer to storage for read data

  • num_read – Number of bytes to read

Return values
  • 0 – if successful

  • -EBUSY – Bus is busy.

  • -EIO – General input / output error.

static inline int i3c_burst_read(struct i3c_device_desc *target, uint8_t start_addr, uint8_t *buf, uint32_t num_bytes)

Read multiple bytes from an internal address of an I3C target device.

This routine reads multiple bytes from an internal address of an I3C target device synchronously.

Instances of this may be replaced by i3c_write_read().

Parameters
  • target – I3C target device descriptor,

  • start_addr – Internal address from which the data is being read.

  • buf – Memory pool that stores the retrieved data.

  • num_bytes – Number of bytes being read.

Return values
  • 0 – If successful.

  • -EBUSY – Bus is busy.

  • -EIO – General input / output error.

static inline int i3c_burst_write(struct i3c_device_desc *target, uint8_t start_addr, const uint8_t *buf, uint32_t num_bytes)

Write multiple bytes to an internal address of an I3C target device.

This routine writes multiple bytes to an internal address of an I3C target device synchronously.

Warning

The combined write synthesized by this API may not be supported on all I3C devices. Uses of this API may be made more portable by replacing them with calls to i3c_write() passing a buffer containing the combined address and data.

Parameters
  • target – I3C target device descriptor.

  • start_addr – Internal address to which the data is being written.

  • buf – Memory pool from which the data is transferred.

  • num_bytes – Number of bytes being written.

Return values
  • 0 – If successful.

  • -EBUSY – Bus is busy.

  • -EIO – General input / output error.

static inline int i3c_reg_read_byte(struct i3c_device_desc *target, uint8_t reg_addr, uint8_t *value)

Read internal register of an I3C target device.

This routine reads the value of an 8-bit internal register of an I3C target device synchronously.

Parameters
  • target – I3C target device descriptor.

  • reg_addr – Address of the internal register being read.

  • value – Memory pool that stores the retrieved register value.

Return values
  • 0 – If successful.

  • -EBUSY – Bus is busy.

  • -EIO – General input / output error.

static inline int i3c_reg_write_byte(struct i3c_device_desc *target, uint8_t reg_addr, uint8_t value)

Write internal register of an I3C target device.

This routine writes a value to an 8-bit internal register of an I3C target device synchronously.

Note

This function internally combines the register and value into a single bus transaction.

Parameters
  • target – I3C target device descriptor.

  • reg_addr – Address of the internal register being written.

  • value – Value to be written to internal register.

Return values
  • 0 – If successful.

  • -EBUSY – Bus is busy.

  • -EIO – General input / output error.

static inline int i3c_reg_update_byte(struct i3c_device_desc *target, uint8_t reg_addr, uint8_t mask, uint8_t value)

Update internal register of an I3C target device.

This routine updates the value of a set of bits from an 8-bit internal register of an I3C target device synchronously.

Note

If the calculated new register value matches the value that was read this function will not generate a write operation.

Parameters
  • target – I3C target device descriptor.

  • reg_addr – Address of the internal register being updated.

  • mask – Bitmask for updating internal register.

  • value – Value for updating internal register.

Return values
  • 0 – If successful.

  • -EBUSY – Bus is busy.

  • -EIO – General input / output error.

void i3c_dump_msgs(const char *name, const struct i3c_msg *msgs, uint8_t num_msgs, struct i3c_device_desc *target)

Dump out an I3C message.

Dumps out a list of I3C messages. For any that are writes (W), the data is displayed in hex.

It looks something like this (with name “testing”):

D: I3C msg: testing, addr=56
D:    W len=01:
D: contents:
D: 06                      |.
D:    W len=0e:
D: contents:
D: 00 01 02 03 04 05 06 07 |........
D: 08 09 0a 0b 0c 0d       |......

Parameters
  • name – Name of this dump, displayed at the top.

  • msgs – Array of messages to dump.

  • num_msgs – Number of messages to dump.

  • target – I3C target device descriptor.

int i3c_bus_init(const struct device *dev, const struct i3c_dev_list *i3c_dev_list)

Generic helper function to perform bus initialization.

Parameters
  • dev – Pointer to controller device driver instance.

  • i3c_dev_list – Pointer to I3C device list.

Return values
  • 0 – If successful.

  • -EBUSY – Bus is busy.

  • -EIO – General input / output error.

  • -ENODEV – If a provisioned ID does not match to any target devices in the registered device list.

  • -ENOSPC – No more free addresses can be assigned to target.

  • -ENOSYS – Dynamic address assignment is not supported by the controller driver.

int i3c_device_basic_info_get(struct i3c_device_desc *target)

Get basic information from device and update device descriptor.

This retrieves some basic information:

  • Bus Characteristics Register (GETBCR)

  • Device Characteristics Register (GETDCR)

  • Max Read Length (GETMRL)

  • Max Write Length (GETMWL) from the device and update the corresponding fields of the device descriptor.

This only updates the field(s) in device descriptor only if CCC operations succeed.

Parameters
  • target[inout] I3C target device descriptor.

Return values
  • 0 – if successful.

  • -EIO – General Input/Output error.

struct i3c_msg
#include <i3c.h>

One I3C Message.

This defines one I3C message to transact on the I3C bus.

Note

Some of the configurations supported by this API may not be supported by specific SoC I3C hardware implementations, in particular features related to bus transactions intended to read or write data from different buffers within a single transaction. Invocations of i3c_transfer() may not indicate an error when an unsupported configuration is encountered. In some cases drivers will generate separate transactions for each message fragment, with or without presence of I3C_MSG_RESTART in flags.

Public Members

uint8_t *buf

Data buffer in bytes

uint32_t len

Length of buffer in bytes

uint8_t flags

Flags for this message

uint8_t hdr_mode

HDR mode (I3C_MSG_HDR_MODE*) for transfer if any I3C_MSG_HDR_* is set in flags.

Use SDR mode if none is set.

struct i3c_config_controller
#include <i3c.h>

Configuration parameters for I3C hardware to act as controller.

Public Members

bool is_secondary

True if the controller is to be the secondary controller of the bus. False to be the primary controller.

uint32_t i3c

SCL frequency (in Hz) for I3C transfers.

uint32_t i2c

SCL frequency (in Hz) for I2C transfers.

uint8_t supported_hdr

Bit mask of supported HDR modes (0 - 7).

This can be used to enable or disable HDR mode supported by the hardware at runtime.

struct i3c_config_custom
#include <i3c.h>

Custom I3C configuration parameters.

This can be used to configure the I3C hardware on parameters not covered by

See also

i3c_config_controller or

See also

i3c_config_target. Mostly used to configure vendor specific parameters of the I3C hardware.

Public Members

uint32_t id

ID of the configuration parameter.

uintptr_t val

Value of configuration parameter.

void *ptr

Pointer to configuration parameter.

Mainly used to pointer to a struct that the device driver understands.

struct i3c_device_id
#include <i3c.h>

Structure used for matching I3C devices.

Public Members

const uint64_t pid

Device Provisioned ID

struct i3c_device_desc
#include <i3c.h>

Structure describing a I3C target device.

Instances of this are passed to the I3C controller device APIs, for example:

  • i3c_device_register() to tell the controller of a target device.

  • i3c_transfers() to initiate data transfers between controller and target device.

Fields bus, pid and static_addr must be initialized by the module that implements the target device behavior prior to passing the object reference to I3C controller device APIs. static_addr can be zero if target device does not have static address.

Field node should not be initialized or modified manually.

Public Members

sys_snode_t node

Private, do not modify

const struct device *const bus

I3C bus to which this target device is attached

const struct device *const dev

Device driver instance of the I3C device

const uint64_t pid

Device Provisioned ID

const uint8_t static_addr

Static address for this target device.

0 if static address is not being used, and only dynamic address is used. This means that the target device must go through ENTDAA (Dynamic Address Assignment) to get a dynamic address before it can communicate with the controller. This means SETAASA and SETDASA CCC cannot be used to set dynamic address on the target device (as both are to tell target device to use static address as dynamic address).

const uint8_t init_dynamic_addr

Initial dynamic address.

This is specified in the device tree property “assigned-address” to indicate the desired dynamic address during address assignment (SETDASA and ENTDAA).

0 if there is no preference.

uint8_t dynamic_addr

Dynamic Address for this target device used for communication.

This is to be set by the controller driver in one of the following situations:

  • During Dynamic Address Assignment (during ENTDAA)

  • Reset Dynamic Address Assignment (RSTDAA)

  • Set All Addresses to Static Addresses (SETAASA)

  • Set New Dynamic Address (SETNEWDA)

  • Set Dynamic Address from Static Address (SETDASA)

0 if address has not been assigned.

uint8_t group_addr

Group address for this target device. Set during:

  • Reset Group Address(es) (RSTGRPA)

  • Set Group Address (SETGRPA)

0 if group address has not been assigned.

uint8_t bcr

Bus Characteristic Register (BCR)

  • BCR[7:6]: Device Role

    • 0: I3C Target

    • 1: I3C Controller capable

    • 2: Reserved

    • 3: Reserved

  • BCR[5]: Advanced Capabilities

    • 0: Does not support optional advanced capabilities.

    • 1: Supports optional advanced capabilities which can be viewed via GETCAPS CCC.

  • BCR[4}: Virtual Target Support

    • 0: Is not a virtual target.

    • 1: Is a virtual target.

  • BCR[3]: Offline Capable

    • 0: Will always response to I3C commands.

    • 1: Will not always response to I3C commands.

  • BCR[2]: IBI Payload

    • 0: No data bytes following the accepted IBI.

    • 1: One data byte (MDB, Mandatory Data Byte) follows the accepted IBI. Additional data bytes may also follows.

  • BCR[1]: IBI Request Capable

    • 0: Not capable

    • 1: Capable

  • BCR[0]: Max Data Speed Limitation

    • 0: No Limitation

    • 1: Limitation obtained via GETMXDS CCC.

uint8_t dcr

Device Characteristic Register (DCR)

Describes the type of device. Refer to official documentation on what this number means.

uint8_t maxrd

Maximum Read Speed

uint8_t maxwr

Maximum Write Speed

uint32_t max_read_turnaround

Maximum Read turnaround time in microseconds.

uint16_t mrl

Maximum Read Length

uint16_t mwl

Maximum Write Length

uint8_t max_ibi

Maximum IBI Payload Size. Valid only if BCR[2] is 1.

void *controller_priv

Private data by the controller to aid in transactions. Do not modify.

i3c_target_ibi_cb_t ibi_cb

In-Band Interrupt (IBI) callback.

struct i3c_i2c_device_desc
#include <i3c.h>

Structure describing a I2C device on I3C bus.

Instances of this are passed to the I3C controller device APIs, for example: () i3c_i2c_device_register() to tell the controller of an I2C device. () i3c_i2c_transfers() to initiate data transfers between controller and I2C device.

Fields other than node must be initialized by the module that implements the device behavior prior to passing the object reference to I3C controller device APIs.

Public Members

sys_snode_t node

Private, do not modify

const struct device *bus

I3C bus to which this I2C device is attached

const uint16_t addr

Static address for this I2C device.

const uint8_t lvr

Legacy Virtual Register (LVR)

  • LVR[7:5]: I2C device index:

    • 0: I2C device has a 50 ns spike filter where it is not affected by high frequency on SCL.

    • 1: I2C device does not have a 50 ns spike filter but can work with high frequency on SCL.

    • 2: I2C device does not have a 50 ns spike filter and cannot work with high frequency on SCL.

  • LVR[4]: I2C mode indicator:

    • 0: FM+ mode

    • 1: FM mode

  • LVR[3:0]: Reserved.

void *controller_priv

Private data by the controller to aid in transactions. Do not modify.

struct i3c_dev_list
#include <i3c.h>

Structure for describing attached devices for a controller.

This contains arrays of attached I3C and I2C devices.

This is a helper struct that can be used by controller device driver to aid in device management.

Public Members

struct i3c_device_desc *const i3c

Pointer to array of attached I3C devices.

struct i3c_i2c_device_desc *const i2c

Pointer to array of attached I2C devices.

const uint8_t num_i3c

Number of I3C devices in array.

const uint8_t num_i2c

Number of I2C devices in array.

group i3c_ccc

I3C Common Command Codes.

Defines

I3C_CCC_BROADCAST_MAX_ID

Maximum CCC ID for broadcast

I3C_CCC_ENEC(broadcast)

Enable Events Command

Parameters
  • broadcast – True if broadcast, false if direct.

I3C_CCC_DISEC(broadcast)

Disable Events Command

Parameters
  • broadcast – True if broadcast, false if direct.

I3C_CCC_ENTAS(as, broadcast)

Enter Activity State

Parameters
  • as – Desired activity state

  • broadcast – True if broadcast, false if direct.

I3C_CCC_ENTAS0(broadcast)

Enter Activity State 0

Parameters
  • broadcast – True if broadcast, false if direct.

I3C_CCC_ENTAS1(broadcast)

Enter Activity State 1

Parameters
  • broadcast – True if broadcast, false if direct.

I3C_CCC_ENTAS2(broadcast)

Enter Activity State 2

Parameters
  • broadcast – True if broadcast, false if direct.

I3C_CCC_ENTAS3(broadcast)

Enter Activity State 3

Parameters
  • broadcast – True if broadcast, false if direct.

I3C_CCC_RSTDAA

Reset Dynamic Address Assignment (Broadcast)

I3C_CCC_ENTDAA

Enter Dynamic Address Assignment (Broadcast)

I3C_CCC_DEFTGTS

Define List of Targets (Broadcast)

I3C_CCC_SETMWL(broadcast)

Set Max Write Length (Broadcast or Direct)

Parameters
  • broadcast – True if broadcast, false if direct.

I3C_CCC_SETMRL(broadcast)

Set Max Read Length (Broadcast or Direct)

Parameters
  • broadcast – True if broadcast, false if direct.

I3C_CCC_ENTTM

Enter Test Mode (Broadcast)

I3C_CCC_SETBUSCON

Set Bus Context (Broadcast)

I3C_CCC_ENDXFER(broadcast)

Data Transfer Ending Procedure Control

Parameters
  • broadcast – True if broadcast, false if direct.

I3C_CCC_ENTHDR(x)

Enter HDR Mode (HDR-DDR) (Broadcast)

I3C_CCC_ENTHDR0

Enter HDR Mode 0 (HDR-DDR) (Broadcast)

I3C_CCC_ENTHDR1

Enter HDR Mode 1 (HDR-TSP) (Broadcast)

I3C_CCC_ENTHDR2

Enter HDR Mode 2 (HDR-TSL) (Broadcast)

I3C_CCC_ENTHDR3

Enter HDR Mode 3 (HDR-BT) (Broadcast)

I3C_CCC_ENTHDR4

Enter HDR Mode 4 (Broadcast)

I3C_CCC_ENTHDR5

Enter HDR Mode 5 (Broadcast)

I3C_CCC_ENTHDR6

Enter HDR Mode 6 (Broadcast)

I3C_CCC_ENTHDR7

Enter HDR Mode 7 (Broadcast)

I3C_CCC_SETXTIME(broadcast)

Exchange Timing Information (Broadcast or Direct)

Parameters
  • broadcast – True if broadcast, false if direct.

I3C_CCC_SETAASA

Set All Addresses to Static Addresses (Broadcast)

I3C_CCC_RSTACT(broadcast)

Target Reset Action

Parameters
  • broadcast – True if broadcast, false if direct.

I3C_CCC_DEFGRPA

Define List of Group Address (Broadcast)

I3C_CCC_RSTGRPA(broadcast)

Reset Group Address

Parameters
  • broadcast – True if broadcast, false if direct.

I3C_CCC_MLANE(broadcast)

Multi-Lane Data Transfer Control (Broadcast)

I3C_CCC_VENDOR(broadcast, id)

Vendor/Standard Extension

Parameters
  • broadcast – True if broadcast, false if direct.

  • id – Extension ID.

I3C_CCC_SETDASA

Set Dynamic Address from Static Address (Direct)

I3C_CCC_SETNEWDA

Set New Dynamic Address (Direct)

I3C_CCC_GETMWL

Get Max Write Length (Direct)

I3C_CCC_GETMRL

Get Max Read Length (Direct)

I3C_CCC_GETPID

Get Provisioned ID (Direct)

I3C_CCC_GETBCR

Get Bus Characteristics Register (Direct)

I3C_CCC_GETDCR

Get Device Characteristics Register (Direct)

I3C_CCC_GETSTATUS

Get Device Status (Direct)

I3C_CCC_GETACCCR

Get Accept Controller Role (Direct)

I3C_CCC_SETBRGTGT

Set Bridge Targets (Direct)

I3C_CCC_GETMXDS

Get Max Data Speed (Direct)

I3C_CCC_GETCAPS

Get Optional Feature Capabilities (Direct)

I3C_CCC_SETROUTE

Set Route (Direct)

I3C_CCC_D2DXFER

Device to Device(s) Tunneling Control (Direct)

I3C_CCC_GETXTIME

Get Exchange Timing Information (Direct)

I3C_CCC_SETGRPA

Set Group Address (Direct)

I3C_CCC_ENEC_EVT_ENINTR
I3C_CCC_ENEC_EVT_ENCR
I3C_CCC_ENEC_EVT_ENHJ
I3C_CCC_ENEC_EVT_ALL
I3C_CCC_DISEC_EVT_DISINTR
I3C_CCC_DISEC_EVT_DISCR
I3C_CCC_DISEC_EVT_DISHJ
I3C_CCC_DISEC_EVT_ALL
I3C_CCC_EVT_INTR
I3C_CCC_EVT_CR
I3C_CCC_EVT_HJ
I3C_CCC_EVT_ALL
I3C_CCC_GETSTATUS_PROTOCOL_ERR
I3C_CCC_GETSTATUS_ACTIVITY_MODE_SHIFT
I3C_CCC_GETSTATUS_ACTIVITY_MODE_MASK
I3C_CCC_GETSTATUS_ACTIVITY_MODE(status)
I3C_CCC_GETSTATUS_NUM_INT_SHIFT
I3C_CCC_GETSTATUS_NUM_INT_MASK
I3C_CCC_GETSTATUS_NUM_INT(status)
I3C_CCC_GETSTATUS_PRECR_DEEP_SLEEP_DETECTED
I3C_CCC_GETSTATUS_PRECR_HANDOFF_DELAY_NACK
I3C_CCC_GETMXDS_MAX_SDR_FSCL_MAX
I3C_CCC_GETMXDS_MAX_SDR_FSCL_8MHZ
I3C_CCC_GETMXDS_MAX_SDR_FSCL_6MHZ
I3C_CCC_GETMXDS_MAX_SDR_FSCL_4MHZ
I3C_CCC_GETMXDS_MAX_SDR_FSCL_2MHZ
I3C_CCC_GETMXDS_TSCO_8NS
I3C_CCC_GETMXDS_TSCO_9NS
I3C_CCC_GETMXDS_TSCO_10NS
I3C_CCC_GETMXDS_TSCO_11NS
I3C_CCC_GETMXDS_TSCO_12NS
I3C_CCC_GETMXDS_TSCO_GT_12NS
I3C_CCC_GETMXDS_MAXWR_DEFINING_BYTE_SUPPORT
I3C_CCC_GETMXDS_MAXWR_MAX_SDR_FSCL_SHIFT
I3C_CCC_GETMXDS_MAXWR_MAX_SDR_FSCL_MASK
I3C_CCC_GETMXDS_MAXWR_MAX_SDR_FSCL(maxwr)
I3C_CCC_GETMXDS_MAXRD_W2R_PERMITS_STOP_BETWEEN
I3C_CCC_GETMXDS_MAXRD_TSCO_SHIFT
I3C_CCC_GETMXDS_MAXRD_TSCO_MASK
I3C_CCC_GETMXDS_MAXRD_TSCO(maxrd)
I3C_CCC_GETMXDS_MAXRD_MAX_SDR_FSCL_SHIFT
I3C_CCC_GETMXDS_MAXRD_MAX_SDR_FSCL_MASK
I3C_CCC_GETMXDS_MAXRD_MAX_SDR_FSCL(maxrd)
I3C_CCC_GETMXDS_CRDHLY1_SET_BUS_ACT_STATE
I3C_CCC_GETMXDS_CRDHLY1_CTRL_HANDOFF_ACT_STATE_SHIFT
I3C_CCC_GETMXDS_CRDHLY1_CTRL_HANDOFF_ACT_STATE_MASK
I3C_CCC_GETMXDS_CRDHLY1_CTRL_HANDOFF_ACT_STATE(crhdly1)
I3C_CCC_GETCAPS1_HDR_DDR
I3C_CCC_GETCAPS1_HDR_BT
I3C_CCC_GETCAPS1_HDR_MODE(x)
I3C_CCC_GETCAPS1_HDR_MODE0
I3C_CCC_GETCAPS1_HDR_MODE1
I3C_CCC_GETCAPS1_HDR_MODE2
I3C_CCC_GETCAPS1_HDR_MODE3
I3C_CCC_GETCAPS1_HDR_MODE4
I3C_CCC_GETCAPS1_HDR_MODE5
I3C_CCC_GETCAPS1_HDR_MODE6
I3C_CCC_GETCAPS1_HDR_MODE7
I3C_CCC_GETCAPS2_HDRDDR_WRITE_ABORT
I3C_CCC_GETCAPS2_HDRDDR_ABORT_CRC
I3C_CCC_GETCAPS2_GRPADDR_CAP_SHIFT
I3C_CCC_GETCAPS2_GRPADDR_CAP_MASK
I3C_CCC_GETCAPS2_GRPADDR_CAP(getcaps2)
I3C_CCC_GETCAPS2_SPEC_VER_SHIFT
I3C_CCC_GETCAPS2_SPEC_VER_MASK
I3C_CCC_GETCAPS2_SPEC_VER(getcaps2)
I3C_CCC_GETCAPS3_MLAME_SUPPORT
I3C_CCC_GETCAPS3_D2DXFER_SUPPORT
I3C_CCC_GETCAPS3_D3DXFER_IBI_CAPABLE
I3C_CCC_GETCAPS3_GETCAPS_DEFINING_BYTE_SUPPORT
I3C_CCC_GETCAPS3_GETSTATUS_DEFINING_BYTE_SUPPORT
I3C_CCC_GETCAPS3_HDRBT_CRC32_SUPPORT
I3C_CCC_GETCAPS3_IBI_MDR_PENDING_READ_NOTIFICATION

Enums

enum i3c_ccc_getstatus_fmt

Indicate which format of GETSTATUS to use.

Values:

enumerator GETSTATUS_FORMAT_1
enumerator GETSTATUS_FORMAT_2
enum i3c_ccc_getstatus_defbyte

Values:

enumerator GETSTATUS_FORMAT_2_TGTSTAT = 0x00U
enumerator GETSTATUS_FORMAT_2_PRECR = 0x91U
enumerator GETSTATUS_FORMAT_2_INVALID = 0x100U
enum i3c_ccc_rstact_defining_byte

Values:

enumerator I3C_CCC_RSTACT_NO_RESET = 0x00U
enumerator I3C_CCC_RSTACT_PERIPHERAL_ONLY = 0x01U
enumerator I3C_CCC_RSTACT_RESET_WHOLE_TARGET = 0x02U
enumerator I3C_CCC_RSTACT_DEBUG_NETWORK_ADAPTER = 0x03U
enumerator I3C_CCC_RSTACT_VIRTUAL_TARGET_DETECT = 0x04U

Functions

static inline bool i3c_ccc_is_payload_broadcast(const struct i3c_ccc_payload *payload)

Test if I3C CCC payload is for broadcast.

This tests if the CCC payload is for broadcast.

Parameters
  • payload[in] Pointer to the CCC payload.

Return values
  • true – if payload target is broadcast

  • false – if payload target is direct

int i3c_ccc_do_getbcr(struct i3c_device_desc *target, struct i3c_ccc_getbcr *bcr)

Get BCR from a target.

Helper function to get BCR (Bus Characteristic Register) from target device.

See also

i3c_do_ccc

Parameters
  • target[in] Pointer to the target device descriptor.

  • bcr[out] Pointer to the BCR payload structure.

Returns

int i3c_ccc_do_getdcr(struct i3c_device_desc *target, struct i3c_ccc_getdcr *dcr)

Get DCR from a target.

Helper function to get DCR (Device Characteristic Register) from target device.

See also

i3c_do_ccc

Parameters
  • target[in] Pointer to the target device descriptor.

  • dcr[out] Pointer to the DCR payload structure.

Returns

int i3c_ccc_do_getpid(struct i3c_device_desc *target, struct i3c_ccc_getpid *pid)

Get PID from a target.

Helper function to get PID (Provisioned ID) from target device.

See also

i3c_do_ccc

Parameters
  • target[in] Pointer to the target device descriptor.

  • pid[out] Pointer to the PID payload structure.

Returns

int i3c_ccc_do_rstact_all(const struct device *controller, enum i3c_ccc_rstact_defining_byte action)

Broadcast RSTACT to reset I3C Peripheral.

Helper function to broadcast Target Reset Action (RSTACT) to all connected targets to Reset the I3C Peripheral Only (0x01).

See also

i3c_do_ccc

Parameters
  • controller[in] Pointer to the controller device driver instance.

  • action[in] What reset action to perform.

Returns

int i3c_ccc_do_rstdaa_all(const struct device *controller)

Broadcast RSTDAA to reset dynamic addresses for all targets.

Helper function to reset dynamic addresses of all connected targets.

See also

i3c_do_ccc

Parameters
  • controller[in] Pointer to the controller device driver instance.

Returns

int i3c_ccc_do_setdasa(const struct i3c_device_desc *target)

Set Dynamic Address from Static Address for a target.

Helper function to do SETDASA (Set Dynamic Address from Static Address) for a particular target.

Note this does not update target with the new dynamic address.

See also

i3c_do_ccc

Parameters
  • target[in] Pointer to the target device descriptor where the device is configured with a static address.

Returns

int i3c_ccc_do_events_all_set(const struct device *controller, bool enable, struct i3c_ccc_events *events)

Broadcast ENEC/DISEC to enable/disable target events.

Helper function to broadcast Target Events Command to enable or disable target events (ENEC/DISEC).

See also

i3c_do_ccc

Parameters
  • controller[in] Pointer to the controller device driver instance.

  • enable[in] ENEC if true, DISEC if false.

  • events[in] Pointer to the event struct.

Returns

int i3c_ccc_do_events_set(struct i3c_device_desc *target, bool enable, struct i3c_ccc_events *events)

Direct CCC ENEC/DISEC to enable/disable target events.

Helper function to send Target Events Command to enable or disable target events (ENEC/DISEC) on a single target.

See also

i3c_do_ccc

Parameters
  • target[in] Pointer to the target device descriptor.

  • enable[in] ENEC if true, DISEC if false.

  • events[in] Pointer to the event struct.

Returns

int i3c_ccc_do_setmwl_all(const struct device *controller, const struct i3c_ccc_mwl *mwl)

Broadcast SETMWL to Set Maximum Write Length.

Helper function to do SETMWL (Set Maximum Write Length) to all connected targets.

See also

i3c_do_ccc

Parameters
  • controller[in] Pointer to the controller device driver instance.

  • mwl[in] Pointer to SETMWL payload.

Returns

int i3c_ccc_do_setmwl(const struct i3c_device_desc *target, const struct i3c_ccc_mwl *mwl)

Single target SETMWL to Set Maximum Write Length.

Helper function to do SETMWL (Set Maximum Write Length) to one target.

See also

i3c_do_ccc

Parameters
  • target[in] Pointer to the target device descriptor.

  • mwl[in] Pointer to SETMWL payload.

Returns

int i3c_ccc_do_getmwl(const struct i3c_device_desc *target, struct i3c_ccc_mwl *mwl)

Single target GETMWL to Get Maximum Write Length.

Helper function to do GETMWL (Get Maximum Write Length) of one target.

See also

i3c_do_ccc

Parameters
  • target[in] Pointer to the target device descriptor.

  • mwl[out] Pointer to GETMWL payload.

Returns

int i3c_ccc_do_setmrl_all(const struct device *controller, const struct i3c_ccc_mrl *mrl, bool has_ibi_size)

Broadcast SETMRL to Set Maximum Read Length.

Helper function to do SETMRL (Set Maximum Read Length) to all connected targets.

See also

i3c_do_ccc

Parameters
  • controller[in] Pointer to the controller device driver instance.

  • mrl[in] Pointer to SETMRL payload.

  • has_ibi_size[in] True if also sending the optional IBI payload size. False if not sending.

Returns

int i3c_ccc_do_setmrl(const struct i3c_device_desc *target, const struct i3c_ccc_mrl *mrl)

Single target SETMRL to Set Maximum Read Length.

Helper function to do SETMRL (Set Maximum Read Length) to one target.

Note this uses the BCR of the target to determine whether to send the optional IBI payload size.

See also

i3c_do_ccc

Parameters
  • target[in] Pointer to the target device descriptor.

  • mrl[in] Pointer to SETMRL payload.

Returns

int i3c_ccc_do_getmrl(const struct i3c_device_desc *target, struct i3c_ccc_mrl *mrl)

Single target GETMRL to Get Maximum Read Length.

Helper function to do GETMRL (Get Maximum Read Length) of one target.

Note this uses the BCR of the target to determine whether to send the optional IBI payload size.

See also

i3c_do_ccc

Parameters
  • target[in] Pointer to the target device descriptor.

  • mrl[out] Pointer to GETMRL payload.

Returns

int i3c_ccc_do_getstatus(const struct i3c_device_desc *target, union i3c_ccc_getstatus *status, enum i3c_ccc_getstatus_fmt fmt, enum i3c_ccc_getstatus_defbyte defbyte)

Single target GETSTATUS to Get Target Status.

Helper function to do GETSTATUS (Get Target Status) of one target.

Note this uses the BCR of the target to determine whether to send the optional IBI payload size.

See also

i3c_do_ccc

Parameters
  • target[in] Pointer to the target device descriptor.

  • status[out] Pointer to GETSTATUS payload.

  • fmt[in] Which GETSTATUS to use.

  • defbyte[in] Defining Byte if using format 2.

Returns

static inline int i3c_ccc_do_getstatus_fmt1(const struct i3c_device_desc *target, union i3c_ccc_getstatus *status)

Single target GETSTATUS to Get Target Status (Format 1).

Helper function to do GETSTATUS (Get Target Status, format 1) of one target.

See also

i3c_do_ccc

Parameters
  • target[in] Pointer to the target device descriptor.

  • status[out] Pointer to GETSTATUS payload.

Returns

static inline int i3c_ccc_do_getstatus_fmt2(const struct i3c_device_desc *target, union i3c_ccc_getstatus *status, enum i3c_ccc_getstatus_defbyte defbyte)

Single target GETSTATUS to Get Target Status (Format 2).

Helper function to do GETSTATUS (Get Target Status, format 2) of one target.

See also

i3c_do_ccc

Parameters
  • target[in] Pointer to the target device descriptor.

  • status[out] Pointer to GETSTATUS payload.

  • defbyte[in] Defining Byte for GETSTATUS format 2.

Returns

struct i3c_ccc_target_payload
#include <ccc.h>

Payload structure for Direct CCC to one target.

Public Members

uint8_t addr

Target address

uint8_t rnw

0 for Write, 1 for Read

uint8_t *data

  • For Write CCC, pointer to the byte array of data to be sent, which may contain the Sub-Command Byte and additional data.

  • For Read CCC, pointer to the byte buffer for data to be read into.

size_t data_len

Length in bytes for data.

struct i3c_ccc_payload
#include <ccc.h>

Payload structure for one CCC transaction.

Public Members

uint8_t id

The CCC ID (I3C_CCC_*).

uint8_t *data

Pointer to byte array of data for this CCC.

This is the bytes following the CCC command in CCC frame. Set to NULL if no associated data.

size_t data_len

Length in bytes for optional data array.

struct i3c_ccc_target_payload *payloads

Array of struct i3c_ccc_target_payload.

Each element describes the target and associated payloads for this CCC.

Use with Direct CCC.

size_t num_targets

Number of targets

struct i3c_ccc_events
#include <ccc.h>

Payload for ENEC/DISEC CCC (Target Events Command).

Public Members

uint8_t events

Event byte:

  • Bit[0]: ENINT/DISINT:

    • Target Interrupt Requests

  • Bit[1]: ENCR/DISCR:

    • Controller Role Requests

  • Bit[3]: ENHJ/DISHJ:

    • Hot-Join Event

struct i3c_ccc_mwl
#include <ccc.h>

Payload for SETMWL/GETMWL CCC (Set/Get Maximum Write Length).

Note

For drivers and help functions, the raw data coming back from target device is in big endian. This needs to be translated back to CPU endianness before passing back to function caller.

Public Members

uint16_t len

Maximum Write Length

struct i3c_ccc_mrl
#include <ccc.h>

Payload for SETMRL/GETMRL CCC (Set/Get Maximum Read Length).

Note

For drivers and help functions, the raw data coming back from target device is in big endian. This needs to be translated back to CPU endianness before passing back to function caller.

Public Members

uint16_t len

Maximum Read Length

uint8_t ibi_len

Optional IBI Payload Size

struct i3c_ccc_deftgts_active_controller
#include <ccc.h>

The active controller part of payload for DEFTGTS CCC.

This is used by DEFTGTS (Define List of Targets) CCC to describe the active controller on the I3C bus.

Public Members

uint8_t addr

Dynamic Address of Active Controller

uint8_t dcr

Device Characteristic Register of Active Controller

uint8_t bcr

Bus Characteristic Register of Active Controller

uint8_t static_addr

Static Address of Active Controller

struct i3c_ccc_deftgts_target
#include <ccc.h>

The target device part of payload for DEFTGTS CCC.

This is used by DEFTGTS (Define List of Targets) CCC to describe the existing target devices on the I3C bus.

Public Members

uint8_t addr

Dynamic Address of a target device, or a group address

uint8_t dcr

Device Characteristic Register of a I3C target device or a group.

uint8_t lvr

Legacy Virtual Register for legacy I2C device.

uint8_t bcr

Bus Characteristic Register of a target device or a group

uint8_t static_addr

Static Address of a target device or a group

struct i3c_ccc_deftgts
#include <ccc.h>

Payload for DEFTGTS CCC (Define List of Targets).

Note

i3c_ccc_deftgts_target is an array of targets, where the number of elements is dependent on the number of I3C targets on the bus. Please have enough space for both read and write of this CCC.

Public Members

struct i3c_ccc_deftgts_active_controller active_controller

Data describing the active controller

struct i3c_ccc_deftgts_target targets[]

Data describing the target(s) on the bus

struct i3c_ccc_address
#include <ccc.h>

Payload for a single device address.

This is used for:

  • SETDASA (Set Dynamic Address from Static Address)

  • SETNEWDA (Set New Dynamic Address)

  • SETGRPA (Set Group Address)

  • GETACCCR (Get Accept Controller Role)

Note that the target address is encoded within struct i3c_ccc_target_payload instead of being encoded in this payload.

Public Members

uint8_t addr

  • For SETDASA, Static Address to be assigned as Dynamic Address.

  • For SETNEWDA, new Dynamic Address to be assigned.

  • For SETGRPA, new Group Address to be set.

  • For GETACCCR, the correct address of Secondary Controller.

Note

For SETDATA, SETNEWDA and SETGRAP, the address is left-shift by 1, and bit[0] is always 0.

Note

Fpr SET GETACCCR, the address is left-shift by 1, and bit[0] is the calculated odd parity bit.

struct i3c_ccc_getpid
#include <ccc.h>

Payload for GETPID CCC (Get Provisioned ID).

Public Members

uint8_t pid[6]

48-bit Provisioned ID.

Note

Data is big-endian where first byte is MSB.

struct i3c_ccc_getbcr
#include <ccc.h>

Payload for GETBCR CCC (Get Bus Characteristics Register).

Public Members

uint8_t bcr

Bus Characteristics Register

struct i3c_ccc_getdcr
#include <ccc.h>

Payload for GETDCR CCC (Get Device Characteristics Register).

Public Members

uint8_t dcr

Device Characteristics Register

union i3c_ccc_getstatus
#include <ccc.h>

Payload for GETSTATUS CCC (Get Device Status).

Public Members

uint16_t status

Device Status

  • Bit[15:8]: Reserved.

  • Bit[7:6]: Activity Mode.

  • Bit[5]: Protocol Error.

  • Bit[4]: Reserved.

  • Bit[3:0]: Number of Pending Interrupts.

Note

For drivers and help functions, the raw data coming back from target device is in big endian. This needs to be translated back to CPU endianness before passing back to function caller.

struct i3c_ccc_getstatus.[anonymous] fmt1
uint16_t tgtstat

Defining Byte 0x00: TGTSTAT

See also

i3c_ccc_getstatus::fmt1::status

uint16_t precr

Defining Byte 0x91: PRECR

  • Bit[15:8]: Vendor Reserved

  • Bit[7:2]: Reserved

  • Bit[1]: Handoff Delay NACK

  • Bit[0]: Deep Sleep Detected

Note

For drivers and help functions, the raw data coming back from target device is in big endian. This needs to be translated back to CPU endianness before passing back to function caller.

uint16_t raw_u16
union i3c_ccc_getstatus.[anonymous] fmt2
struct i3c_ccc_setbrgtgt_tgt
#include <ccc.h>

One Bridged Target for SETBRGTGT payload.

Public Members

uint8_t addr

Dynamic address of the bridged target.

Note

The address is left-shift by 1, and bit[0] is always 0.

uint16_t id

16-bit ID for the bridged target.

Note

For drivers and help functions, the raw data coming back from target device is in big endian. This needs to be translated back to CPU endianness before passing back to function caller.

struct i3c_ccc_setbrgtgt
#include <ccc.h>

Payload for SETBRGTGT CCC (Set Bridge Targets).

Note that the bridge target address is encoded within struct i3c_ccc_target_payload instead of being encoded in this payload.

Public Members

uint8_t count

Number of bridged targets

struct i3c_ccc_setbrgtgt_tgt targets[]

Array of bridged targets

union i3c_ccc_getmxds
#include <ccc.h>

Payload for GETMXDS CCC (Get Max Data Speed).

Note

This is only for GETMXDS Format 1 and Format 2.

Public Members

uint8_t maxwr

maxWr

uint8_t maxrd

maxRd

struct i3c_ccc_getmxds.[anonymous] fmt1
uint8_t maxrdturn[3]

Maximum Read Turnaround Time in microsecond.

This is in little-endian where first byte is LSB.

struct i3c_ccc_getmxds.[anonymous] fmt2
uint8_t wrrdturn

Defining Byte 0x00: WRRDTURN

uint8_t crhdly1

Defining Byte 0x91: CRHDLY

  • Bit[2]: Set Bus Actibity State

  • Bit[1:0]: Controller Handoff Activity State

struct i3c_ccc_getmxds.[anonymous] fmt3
struct i3c_ccc_getcaps
#include <ccc.h>

Payload for GETCAPS CCC (Get Optional Feature Capabilities).

Note

Only support GETCAPS Format 1.

Public Members

uint8_t getcaps[4]

GETCAP[1-4] bytes.

group i3c_addresses

I3C Address-related Helper Code.

Defines

I3C_BROADCAST_ADDR
I3C_MAX_ADDR

Enums

enum i3c_addr_slot_status

Values:

enumerator I3C_ADDR_SLOT_STATUS_FREE = 0U
enumerator I3C_ADDR_SLOT_STATUS_RSVD
enumerator I3C_ADDR_SLOT_STATUS_I3C_DEV
enumerator I3C_ADDR_SLOT_STATUS_I2C_DEV
enumerator I3C_ADDR_SLOT_STATUS_MASK = 0x03U

Functions

int i3c_addr_slots_init(struct i3c_addr_slots *slots, const struct i3c_dev_list *dev_list)

Initialize the I3C address slots struct.

This clears out the assigned address bits, and set the reserved address bits according to the I3C specification.

Parameters
  • slots – Pointer to address slots struct.

  • dev_list – Pointer to device list struct.

Return values
  • 0 – if successful.

  • -EINVAL – if duplicate addresses.

void i3c_addr_slots_set(struct i3c_addr_slots *slots, uint8_t dev_addr, enum i3c_addr_slot_status status)

Set the address status of a device.

Parameters
  • slots – Pointer to the address slots structure.

  • dev_addr – Device address.

  • status – New status for the address dev_addr.

enum i3c_addr_slot_status i3c_addr_slots_status(struct i3c_addr_slots *slots, uint8_t dev_addr)

Get the address status of a device.

Parameters
  • slots – Pointer to the address slots structure.

  • dev_addr – Device address.

Returns

Address status for the address dev_addr.

bool i3c_addr_slots_is_free(struct i3c_addr_slots *slots, uint8_t dev_addr)

Check if the address is free.

Parameters
  • slots – Pointer to the address slots structure.

  • dev_addr – Device address.

Return values
  • true – if address is free.

  • false – if address is not free.

uint8_t i3c_addr_slots_next_free_find(struct i3c_addr_slots *slots)

Find the next free address.

This can be used to find the next free address that can be assigned to a new device.

Parameters
  • slots – Pointer to the address slots structure.

Returns

The next free address, or 0 if none found.

static inline void i3c_addr_slots_mark_free(struct i3c_addr_slots *addr_slots, uint8_t addr)

Mark the address as free (not used) in device list.

Parameters
  • addr_slots – Pointer to the address slots struct.

  • addr – Device address.

static inline void i3c_addr_slots_mark_rsvd(struct i3c_addr_slots *addr_slots, uint8_t addr)

Mark the address as reserved in device list.

Parameters
  • addr_slots – Pointer to the address slots struct.

  • addr – Device address.

static inline void i3c_addr_slots_mark_i3c(struct i3c_addr_slots *addr_slots, uint8_t addr)

Mark the address as I3C device in device list.

Parameters
  • addr_slots – Pointer to the address slots struct.

  • addr – Device address.

static inline void i3c_addr_slots_mark_i2c(struct i3c_addr_slots *addr_slots, uint8_t addr)

Mark the address as I2C device in device list.

Parameters
  • addr_slots – Pointer to the address slots struct.

  • addr – Device address.

struct i3c_addr_slots
#include <addresses.h>

Structure to keep track of addresses on I3C bus.