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