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