1.. _i3c_api: 2 3Improved Inter-Integrated Circuit (I3C) Bus 4########################################### 5 6I3C (Improved Inter-Integrated Circuit) is a two-signal shared 7peripheral interface bus. Devices on the bus can operate in 8two roles: as a "controller" that initiates transactions and 9controls the clock, or as a "target" that responds to transaction 10commands. 11 12Currently, the API is based on `I3C Specification`_ version 1.1.1. 13 14.. contents:: 15 :local: 16 :depth: 2 17 18.. _i3c-controller-api: 19 20I3C Controller API 21****************** 22 23Zephyr's I3C controller API is used when an I3C controller controls 24the bus, in particularly the start and stop conditions and the clock. 25This is the most common mode, used to interact with I3C target 26devices such as sensors. 27 28Due to the nature of the I3C, there are devices on the bus where 29they may not have addresses when powered on. Therefore, an additional 30dynamic address assignment needs to be carried out by the I3C 31controller. Because of this, the controller needs to maintain 32separate structures to keep track of device status. This can be done 33at build time, for example, by creating arrays of device descriptors 34for both I3C and I\ :sup:`2`\ C devices: 35 36.. code-block:: c 37 38 static struct i3c_device_desc i3c_device_array[] = I3C_DEVICE_ARRAY_DT_INST(inst); 39 static struct i3c_i2c_device_desc i2c_device_array[] = I3C_I2C_DEVICE_ARRAY_DT_INST(inst); 40 41The macros :c:macro:`I3C_DEVICE_ARRAY_DT_INST` and 42:c:macro:`I3C_I2C_DEVICE_ARRAY_DT_INST` are helper macros to aid in 43create arrays of device descriptors corresponding to the devicetree 44nodes under the I3C controller. 45 46Here is a list of generic steps for initializing the I3C 47controller and the I3C bus inside the device driver 48initialization function: 49 50#. Initialize the data structure of the I3C controller device 51 driver instance. The usual device defining macros such as 52 :c:macro:`DEVICE_DT_INST_DEFINE` can be used, and the initialization 53 function provided as a parameter to the macro. 54 55 * The :c:struct:`i3c_addr_slots` and :c:struct:`i3c_dev_list` are 56 structures to aid in address assignments and device list management. 57 If this is being used, this struct needs to be initialized by calling 58 :c:func:`i3c_addr_slots_init`. These two structures can also be used 59 with various helper functions. 60 61 * Initialize the device descriptors if needed by the controller 62 driver. 63 64#. Initialize the hardware, including but not limited to: 65 66 * Setup pin mux and directions. 67 68 * Setup the clock for the controller. 69 70 * Power on the hardware. 71 72 * Configure the hardware (e.g. SCL clock frequency). 73 74#. Perform bus initialization. There is a generic helper function, 75 :c:func:`i3c_bus_init`, which performs the following steps. 76 This function can be used if the controller does not require 77 any special handling during bus initialization. 78 79 #. Do ``RSTDAA`` to reset dynamic addresses of connected devices. 80 If any connected devices have already been assigned an address, 81 the bookkeeping data structures do not have records of these, 82 for example, at power-on. So it is a good idea to reset and 83 assign them new addresses. 84 85 #. Do ``DISEC`` to disable any events from devices. 86 87 #. Do ``SETDASA`` to use static addresses as dynamic address 88 if so desired. 89 90 * ``SETAASA`` may not be supported for all connected devices 91 to assign static addresses as dynamic addresses. 92 93 * BCR and DCR need to be obtained separately to populate 94 the relevant fields in the I3C target device descriptor 95 struct. 96 97 #. Do ``ENTDAA`` to start dynamic address assignment, if there are 98 still devices without addresses. 99 100 * If there is a device waiting for address, it will send 101 its Provisioned ID, BCR, and DCR back. Match the received 102 Provisioned ID to the list of registered I3C devices. 103 104 * If there is a match, assign an address (either from 105 the stated static address if ``SETDASA`` has not been 106 done, or use a free address). 107 108 * Also, set the BCR and DCR fields in the device descriptor 109 struct. 110 111 * If there is no match, depending on policy, it can be 112 assigned a free address, or the device driver can stop 113 the assignment process and errors out. 114 115 * Note that the I3C API requires device descriptor to 116 function. A device without a device descriptor cannot be 117 accessed through the API. 118 119 * This step can be skipped if there is no connected devices 120 requiring DAA. 121 122 #. These are optional but highly recommended: 123 124 * Do ``GETMRL`` and ``GETMWL`` to get maximum read/write 125 length. 126 127 * Do ``GETMXDS`` to get maximum read/write speed and maximum 128 read turnaround time. 129 130 * The helper function, :c:func:`i3c_bus_init`, would retrieve 131 basic device information such as BCR, DCR, MRL and MWL. 132 133 #. Do ``ENEC`` to re-enable events from devices. 134 135 * The helper function, :c:func:`i3c_bus_init`, only re-enables 136 hot-join events. IBI event should only be enabled when 137 enabling IBI of a device. 138 139In-Band Interrupt (IBI) 140======================= 141 142If a target device can generate In-Band Interrupt (IBI), 143the controller needs to be made aware of it. 144 145* :c:func:`i3c_ibi_enable` to enable IBI of a target device. 146 147 * Some controller hardware have IBI slots which need to be 148 programmed so that the controller can recognize incoming IBIs 149 from a particular target device. 150 151 * If the hardware has IBI slots, :c:func:`i3c_ibi_enable` 152 needs to program those IBI slots. 153 154 * Note that there are usually limited IBI slots on 155 the controller so this operation may fail. 156 157 * The implementation in driver should also send the ``ENEC`` command 158 to enable interrupt of this target device. 159 160* :c:func:`i3c_ibi_disable` to disable IBI of a target device. 161 162 * If controller hardware makes use of IBI slots, this will remove 163 description of the target device from the slots. 164 165 * The implementation in driver should also send the ``DISEC`` command 166 to disable interrupt of this target device. 167 168Device Tree 169=========== 170 171Here is an example for defining a I3C controller in device tree: 172 173.. code-block:: devicetree 174 175 i3c0: i3c@10000 { 176 compatible = "vendor,i3c"; 177 178 #address-cells = < 0x3 >; 179 #size-cells = < 0x0 >; 180 181 reg = < 0x10000 0x1000 >; 182 interrupts = < 0x1F 0x0 >; 183 184 pinctrl-0 = < &pinmux-i3c >; 185 pinctrl-names = "default"; 186 187 i2c-scl-hz = < 400000 >; 188 189 i3c-scl-hz = < 12000000 >; 190 191 status = "okay"; 192 193 i3c-dev0: i3c-dev0@420000ABCD12345678 { 194 compatible = "vendor,i3c-dev"; 195 196 reg = < 0x42 0xABCD 0x12345678 >; 197 198 status = "okay"; 199 }; 200 201 i2c-dev0: i2c-dev0@380000000000000050 { 202 compatible = "vendor-i2c-dev"; 203 204 reg = < 0x38 0x0 0x50 >; 205 206 status = "okay"; 207 }; 208 }; 209 210I3C Devices 211----------- 212 213For I3C devices, the ``reg`` property has 3 elements: 214 215* The first one is the static address of the device. 216 217 * Can be zero if static address is not used. Address will be 218 assigned during DAA (Dynamic Address Assignment). 219 220 * If non-zero and property ``assigned-address`` is not set, 221 this will be the address of the device after SETDASA 222 (Set Dynamic Address from Static Address) is issued. 223 224* Second element is the upper 16-bit of the Provisioned ID (PID) 225 which contains the manufacturer ID left-shifted by 1. This is 226 the bits 33-47 (zero-based) of the 48-bit Provisioned ID. 227 228* Third element contains the lower 32-bit of the Provisioned ID 229 which is a combination of the part ID (left-shifted by 16, 230 bits 16-31 of the PID) and the instance ID (left-shifted by 12, 231 bits 12-15 of the PID). 232 233Note that the unit-address (the part after ``@``) must match 234the ``reg`` property fully where each element is treated as 23532-bit integer, combining to form a 96-bit integer. This is 236required for properly generating device tree macros. 237 238I\ :sup:`2`\ C Devices 239---------------------- 240 241For I\ :sup:`2`\ C devices where the device driver has support for 242working under I3C bus, the device node can be described as 243a child of the I3C controller. If the device driver is written to 244only work with I\ :sup:`2`\ C controllers, define the node under 245the I\ :sup:`2`\ C virtual controller as described below. 246Otherwise, the ``reg`` property, similar to I3C devices, 247has 3 elements: 248 249* The first one is the static address of the device. This must be 250 a valid address as I\ :sup:`2`\ C devices do not support 251 dynamic address assignment. 252 253* Second element is always zero. 254 255 * This is used by various helper macros to determine whether 256 the device tree entry corresponds to a I\ :sup:`2`\ C device. 257 258* Third element is the LVR (Legacy Virtual Register): 259 260 * bit[31:8] are unused. 261 262 * bit[7:5] are the I\ :sup:`2`\ C device index: 263 264 * Index ``0`` 265 266 * I3C device has a 50 ns spike filter where it is not 267 affected by high frequency on SCL. 268 269 * Index ``1`` 270 271 * I\ :sup:`2`\ C device does not have a 50 ns spike filter but 272 can work with high frequency on SCL. 273 274 * Index ``2`` 275 276 * I3C device does not have a 50 ns spike filter and 277 cannot work with high frequency on SCL. 278 279 * bit[4] is the I\ :sup:`2`\ C mode indicator: 280 281 * ``0`` is FM+ mode. 282 283 * ``1`` is FM mode. 284 285Similar to I3C devices, the unit-address must match the ``reg`` 286property fully where each element is treated as 32-bit integer, 287combining to form a 96-bit integer. 288 289Device Drivers for I3C Devices 290============================== 291 292All of the transfer functions of I3C controller API require 293the use of device descriptors, :c:struct:`i3c_device_desc`. 294This struct contains runtime information about a I3C device, 295such as, its dynamic address, BCR, DCR, MRL and MWL. Therefore, 296the device driver of a I3C device should grab a pointer to 297this device descriptor from the controller using 298:c:func:`i3c_device_find`. This function takes an ID parameter 299of type :c:struct:`i3c_device_id` for matching. The returned 300pointer can then be used in subsequent API calls to 301the controller. 302 303I\ :sup:`2`\ C Devices under I3C Bus 304==================================== 305 306Since I3C is backware compatible with I\ :sup:`2`\ C, the I3C controller 307API can accommodate I2C API calls without modifications if the controller 308device driver implements the I2C API. This has the advantage of using 309existing I2C devices without any modifications to their device drivers. 310However, since the I3C controller API works on device descriptors, 311any calls to I2C API will need to look up the corresponding device 312descriptor from the I2C device address. This adds a bit of processing 313cost to any I2C API calls. 314 315On the other hand, a device driver can be extended to utilize native 316I2C device support via the I3C controller API. During device 317initialization, :c:func:`i3c_i2c_device_find` needs to be called to 318retrieve the pointer to the device descriptor. This pointer can be used 319in subsequent API calls. 320 321Note that, with either methods mentioned above, the devicetree node of 322the I2C device must be declared according to I3C standard: 323 324The I\ :sup:`2`\ C virtual controller device driver provides a way to 325interface I\ :sup:`2`\ C devices on the I3C bus where the associated 326device drivers can be used as-is without modifications. This requires 327adding an intermediate node in the device tree: 328 329.. code-block:: devicetree 330 331 i3c0: i3c@10000 { 332 <... I3C controller related properties ...> 333 <... Nodes of I3C devices, if any ...> 334 335 i2c-dev0: i2c-dev0@420000000000000050 { 336 compatible = "vendor-i2c-dev"; 337 338 reg = < 0x42 0x0 0x50 >; 339 340 status = "okay"; 341 }; 342 }; 343 344Configuration Options 345********************* 346 347Related configuration options: 348 349* :kconfig:option:`CONFIG_I3C` 350* :kconfig:option:`CONFIG_I3C_USE_GROUP_ADDR` 351* :kconfig:option:`CONFIG_I3C_USE_IBI` 352* :kconfig:option:`CONFIG_I3C_IBI_MAX_PAYLOAD_SIZE` 353* :kconfig:option:`CONFIG_I3C_CONTROLLER_INIT_PRIORITY` 354 355API Reference 356************* 357 358.. doxygengroup:: i3c_interface 359.. doxygengroup:: i3c_ccc 360.. doxygengroup:: i3c_addresses 361.. doxygengroup:: i3c_target_device 362 363.. _I3C Specification: https://www.mipi.org/specifications/i3c-sensor-specification 364