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