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