1 /*
2 * Copyright 2022 Intel Corporation
3 * Copyright 2023 Meta Platforms, Inc. and its affiliates
4 *
5 * SPDX-License-Identifier: Apache-2.0
6 */
7
8 #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 #define I3C_BCR_MAX_DATA_SPEED_LIMIT BIT(0)
87
88 /** @brief IBI Request Capable bit. */
89 #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 #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 #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 #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 #define I3C_BCR_ADV_CAPABILITIES BIT(5)
124
125 /** Device Role - I3C Target. */
126 #define I3C_BCR_DEVICE_ROLE_I3C_TARGET 0U
127
128 /** Device Role - I3C Controller Capable. */
129 #define I3C_BCR_DEVICE_ROLE_I3C_CONTROLLER_CAPABLE 1U
130
131 /** Device Role bit shift mask. */
132 #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 #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 #define I3C_LVR_I2C_FM_PLUS_MODE 0
168
169 /** I2C FM Mode. */
170 #define I3C_LVR_I2C_FM_MODE 1
171
172 /** I2C Mode Indicator bitmask. */
173 #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 #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 #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 #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 #define I3C_LVR_I2C_DEV_IDX_2 2
208
209 /** I2C Device Index bitmask. */
210 #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 #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 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 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 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 #define I3C_MSG_WRITE (0U << 0U)
308
309 /** Read message from I3C bus. */
310 #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 #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 #define I3C_MSG_RESTART BIT(2)
329
330 /** Transfer use HDR mode */
331 #define I3C_MSG_HDR BIT(3)
332
333 /** Skip I3C broadcast header. Private Transfers only. */
334 #define I3C_MSG_NBCH BIT(4)
335
336 /** I3C HDR Mode 0 */
337 #define I3C_MSG_HDR_MODE0 BIT(0)
338
339 /** I3C HDR Mode 1 */
340 #define I3C_MSG_HDR_MODE1 BIT(1)
341
342 /** I3C HDR Mode 2 */
343 #define I3C_MSG_HDR_MODE2 BIT(2)
344
345 /** I3C HDR Mode 3 */
346 #define I3C_MSG_HDR_MODE3 BIT(3)
347
348 /** I3C HDR Mode 4 */
349 #define I3C_MSG_HDR_MODE4 BIT(4)
350
351 /** I3C HDR Mode 5 */
352 #define I3C_MSG_HDR_MODE5 BIT(5)
353
354 /** I3C HDR Mode 6 */
355 #define I3C_MSG_HDR_MODE6 BIT(6)
356
357 /** I3C HDR Mode 7 */
358 #define I3C_MSG_HDR_MODE7 BIT(7)
359
360 /** I3C HDR-DDR (Double Data Rate) */
361 #define I3C_MSG_HDR_DDR I3C_MSG_HDR_MODE0
362
363 /** I3C HDR-TSP (Ternary Symbol Pure-bus) */
364 #define I3C_MSG_HDR_TSP I3C_MSG_HDR_MODE1
365
366 /** I3C HDR-TSL (Ternary Symbol Legacy-inclusive-bus) */
367 #define I3C_MSG_HDR_TSL I3C_MSG_HDR_MODE2
368
369 /** I3C HDR-BT (Bulk Transport) */
370 #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 struct i3c_msg {
394 /** Data buffer in bytes */
395 uint8_t *buf;
396
397 /** Length of buffer in bytes */
398 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 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 enum i3c_sdr_controller_error_types err;
416
417 /** Flags for this message */
418 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 uint8_t hdr_mode;
427
428 /** HDR command code field (7-bit) for HDR-DDR, HDR-TSP and HDR-TSL */
429 uint8_t hdr_cmd_code;
430 };
431
432 /** @} */
433
434 /**
435 * @brief Type of configuration being passed to configure function.
436 */
437 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 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 bool is_secondary;
452
453 struct {
454 /** SCL frequency (in Hz) for I3C transfers. */
455 uint32_t i3c;
456
457 /** SCL frequency (in Hz) for I2C transfers. */
458 uint32_t i2c;
459 } 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 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 struct i3c_config_custom {
479 /** ID of the configuration parameter. */
480 uint32_t id;
481
482 union {
483 /** Value of configuration parameter. */
484 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 void *ptr;
493 };
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
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
701 /**
702 * ACK or NACK IBI HJ Requests
703 *
704 * @see ibi_hj_response()
705 *
706 * @param dev Pointer to controller device driver instance.
707 * @param ack True to ack, False to nack
708 *
709 * @return See ibi_hj_response()
710 */
711 int (*ibi_hj_response)(const struct device *dev,
712 bool ack);
713
714 /**
715 * Raise In-Band Interrupt (IBI).
716 *
717 * Target device only API.
718 *
719 * @see i3c_ibi_request()
720 *
721 * @param dev Pointer to controller device driver instance.
722 * @param request Pointer to IBI request struct.
723 *
724 * @return See i3c_ibi_request()
725 */
726 int (*ibi_raise)(const struct device *dev,
727 struct i3c_ibi *request);
728
729 /**
730 * Enable receiving IBI from a target.
731 *
732 * Controller only API.
733 *
734 * @see i3c_ibi_enable()
735 *
736 * @param dev Pointer to controller device driver instance.
737 * @param target Pointer to target device descriptor.
738 *
739 * @return See i3c_ibi_enable()
740 */
741 int (*ibi_enable)(const struct device *dev,
742 struct i3c_device_desc *target);
743
744 /**
745 * Disable receiving IBI from a target.
746 *
747 * Controller only API.
748 *
749 * @see i3c_ibi_disable()
750 *
751 * @param dev Pointer to controller device driver instance.
752 * @param target Pointer to target device descriptor.
753 *
754 * @return See i3c_ibi_disable()
755 */
756 int (*ibi_disable)(const struct device *dev,
757 struct i3c_device_desc *target);
758
759 /**
760 * Register config as target device of a controller.
761 *
762 * This tells the controller to act as a target device
763 * on the I3C bus.
764 *
765 * Target device only API.
766 *
767 * @see i3c_target_register()
768 *
769 * @param dev Pointer to the controller device driver instance.
770 * @param cfg I3C target device configuration
771 *
772 * @return See i3c_target_register()
773 */
774 int (*target_register)(const struct device *dev,
775 struct i3c_target_config *cfg);
776
777 /**
778 * Unregister config as target device of a controller.
779 *
780 * This tells the controller to stop acting as a target device
781 * on the I3C bus.
782 *
783 * Target device only API.
784 *
785 * @see i3c_target_unregister()
786 *
787 * @param dev Pointer to the controller device driver instance.
788 * @param cfg I3C target device configuration
789 *
790 * @return See i3c_target_unregister()
791 */
792 int (*target_unregister)(const struct device *dev,
793 struct i3c_target_config *cfg);
794
795 /**
796 * Write to the TX FIFO
797 *
798 * This writes to the target tx fifo
799 *
800 * Target device only API.
801 *
802 * @see i3c_target_tx_write()
803 *
804 * @param dev Pointer to the controller device driver instance.
805 * @param buf Pointer to the buffer
806 * @param len Length of the buffer
807 * @param hdr_mode HDR mode
808 *
809 * @return See i3c_target_tx_write()
810 */
811 int (*target_tx_write)(const struct device *dev,
812 uint8_t *buf, uint16_t len, uint8_t hdr_mode);
813
814 /**
815 * ACK or NACK controller handoffs
816 *
817 * This will tell the target to ACK or NACK controller handoffs
818 * from the CCC GETACCCR
819 *
820 * Target device only API.
821 *
822 * @see i3c_target_controller_handoff()
823 *
824 * @param dev Pointer to the controller device driver instance.
825 * @param accept True to ACK controller handoffs, False to NACK.
826 *
827 * @return See i3c_target_controller_handoff()
828 */
829 int (*target_controller_handoff)(const struct device *dev,
830 bool accept);
831
832 #ifdef CONFIG_I3C_RTIO
833 /**
834 * RTIO
835 *
836 * @see i3c_iodev_submit()
837 *
838 * @param dev Pointer to the controller device driver instance.
839 * @param iodev_sqe Pointer to the
840 *
841 * @return See i3c_iodev_submit()
842 */
843 void (*iodev_submit)(const struct device *dev,
844 struct rtio_iodev_sqe *iodev_sqe);
845 #endif
846 };
847
848 /**
849 * @endcond
850 */
851
852 /**
853 * @brief Structure used for matching I3C devices.
854 */
855 struct i3c_device_id {
856 /** Device Provisioned ID */
857 const uint64_t pid:48;
858 };
859
860 /**
861 * @brief Structure initializer for i3c_device_id from PID
862 *
863 * This helper macro expands to a static initializer for a i3c_device_id
864 * by populating the PID (Provisioned ID) field.
865 *
866 * @param pid Provisioned ID.
867 */
868 #define I3C_DEVICE_ID(pid) \
869 { \
870 .pid = pid \
871 }
872
873 /**
874 * @brief Structure describing a I3C target device.
875 *
876 * Instances of this are passed to the I3C controller device APIs,
877 * for example:
878 * - i3c_device_register() to tell the controller of a target device.
879 * - i3c_transfers() to initiate data transfers between controller and
880 * target device.
881 *
882 * Fields #bus, #pid and #static_addr must be initialized by the module that
883 * implements the target device behavior prior to passing the object reference
884 * to I3C controller device APIs. #static_addr can be zero if target device does
885 * not have static address.
886 *
887 * Internal field @c node should not be initialized or modified manually.
888 */
889 struct i3c_device_desc {
890 sys_snode_t node;
891
892 /** I3C bus to which this target device is attached */
893 const struct device * const bus;
894
895 /** Device driver instance of the I3C device */
896 const struct device * const dev;
897
898 /** Device Provisioned ID */
899 const uint64_t pid;
900
901 /**
902 * Static address for this target device.
903 *
904 * 0 if static address is not being used, and only dynamic
905 * address is used. This means that the target device must
906 * go through ENTDAA (Dynamic Address Assignment) to get
907 * a dynamic address before it can communicate with
908 * the controller. This means SETAASA and SETDASA CCC
909 * cannot be used to set dynamic address on the target
910 * device (as both are to tell target device to use static
911 * address as dynamic address).
912 */
913 const uint8_t static_addr;
914
915 /**
916 * Initial dynamic address.
917 *
918 * This is specified in the device tree property "assigned-address"
919 * to indicate the desired dynamic address during address
920 * assignment (SETDASA and ENTDAA).
921 *
922 * 0 if there is no preference.
923 */
924 const uint8_t init_dynamic_addr;
925
926 /**
927 * Device support for SETAASA
928 *
929 * This will be used as an optimization for bus initializtion if the
930 * device supports SETAASA.
931 */
932 const bool supports_setaasa;
933
934 /**
935 * Dynamic Address for this target device used for communication.
936 *
937 * This is to be set by the controller driver in one of
938 * the following situations:
939 * - During Dynamic Address Assignment (during ENTDAA)
940 * - Reset Dynamic Address Assignment (RSTDAA)
941 * - Set All Addresses to Static Addresses (SETAASA)
942 * - Set New Dynamic Address (SETNEWDA)
943 * - Set Dynamic Address from Static Address (SETDASA)
944 *
945 * 0 if address has not been assigned.
946 */
947 uint8_t dynamic_addr;
948
949 #if defined(CONFIG_I3C_USE_GROUP_ADDR) || defined(__DOXYGEN__)
950 /**
951 * Group address for this target device. Set during:
952 * - Reset Group Address(es) (RSTGRPA)
953 * - Set Group Address (SETGRPA)
954 *
955 * 0 if group address has not been assigned.
956 * Only available if @kconfig{CONFIG_I3C_USE_GROUP_ADDR} is set.
957 */
958 uint8_t group_addr;
959 #endif /* CONFIG_I3C_USE_GROUP_ADDR */
960
961 /**
962 * Bus Characteristic Register (BCR)
963 * @see @ref I3C_BCR
964 */
965 uint8_t bcr;
966
967 /**
968 * Device Characteristic Register (DCR)
969 *
970 * Describes the type of device. Refer to official documentation
971 * on what this number means.
972 */
973 uint8_t dcr;
974
975 struct {
976 /** Maximum Read Speed */
977 uint8_t maxrd;
978
979 /** Maximum Write Speed */
980 uint8_t maxwr;
981
982 /** Maximum Read turnaround time in microseconds. */
983 uint32_t max_read_turnaround;
984 } data_speed;
985
986 struct {
987 /** Maximum Read Length */
988 uint16_t mrl;
989
990 /** Maximum Write Length */
991 uint16_t mwl;
992
993 /** Maximum IBI Payload Size. Valid only if BCR[2] is 1. */
994 uint8_t max_ibi;
995 } data_length;
996
997 /** Controller Handoff Delay Parameters */
998 uint8_t crhdly1;
999
1000 /** Describes advanced (Target) capabilities and features */
1001 struct {
1002 union {
1003 /**
1004 * I3C v1.0 HDR Capabilities (@c I3C_CCC_GETCAPS1_*)
1005 * - Bit[0]: HDR-DDR
1006 * - Bit[1]: HDR-TSP
1007 * - Bit[2]: HDR-TSL
1008 * - Bit[7:3]: Reserved
1009 */
1010 uint8_t gethdrcap;
1011
1012 /**
1013 * I3C v1.1+ GETCAPS1 (@c I3C_CCC_GETCAPS1_*)
1014 * - Bit[0]: HDR-DDR
1015 * - Bit[1]: HDR-TSP
1016 * - Bit[2]: HDR-TSL
1017 * - Bit[3]: HDR-BT
1018 * - Bit[7:4]: Reserved
1019 */
1020 uint8_t getcap1;
1021 };
1022
1023 /**
1024 * GETCAPS2 (@c I3C_CCC_GETCAPS2_*)
1025 * - Bit[3:0]: I3C 1.x Specification Version
1026 * - Bit[5:4]: Group Address Capabilities
1027 * - Bit[6]: HDR-DDR Write Abort
1028 * - Bit[7]: HDR-DDR Abort CRC
1029 */
1030 uint8_t getcap2;
1031
1032 /**
1033 * GETCAPS3 (@c I3C_CCC_GETCAPS3_*)
1034 * - Bit[0]: Multi-Lane (ML) Data Transfer Support
1035 * - Bit[1]: Device to Device Transfer (D2DXFER) Support
1036 * - Bit[2]: Device to Device Transfer (D2DXFER) IBI Capable
1037 * - Bit[3]: Defining Byte Support in GETCAPS
1038 * - Bit[4]: Defining Byte Support in GETSTATUS
1039 * - Bit[5]: HDR-BT CRC-32 Support
1040 * - Bit[6]: IBI MDB Support for Pending Read Notification
1041 * - Bit[7]: Reserved
1042 */
1043 uint8_t getcap3;
1044
1045 /**
1046 * GETCAPS4
1047 * - Bit[7:0]: Reserved
1048 */
1049 uint8_t getcap4;
1050 } getcaps;
1051
1052 /* Describes Controller Feature Capabilities */
1053 struct {
1054 /**
1055 * CRCAPS1
1056 * - Bit[0]: Hot-Join Support
1057 * - Bit[1]: Group Management Support
1058 * - Bit[2]: Multi-Lane Support
1059 * - Bit[7:3]: Reserved
1060 */
1061 uint8_t crcaps1;
1062
1063 /**
1064 * CRCAPS2
1065 * - Bit[0]: In-Band Interrupt Support
1066 * - Bit[1]: Controller Pass-Back
1067 * - Bit[2]: Deep Sleep Capable
1068 * - Bit[3]: Delayed Controller Handoff
1069 * - Bit[7:4]: Reserved
1070 */
1071 uint8_t crcaps2;
1072 } crcaps;
1073
1074 /** @cond INTERNAL_HIDDEN */
1075 /**
1076 * Private data by the controller to aid in transactions. Do not modify.
1077 */
1078 void *controller_priv;
1079 /** @endcond */
1080
1081 #if defined(CONFIG_I3C_USE_IBI) || defined(__DOXYGEN__)
1082 /**
1083 * In-Band Interrupt (IBI) callback.
1084 * Only available if @kconfig{CONFIG_I3C_USE_IBI} is set.
1085 */
1086 i3c_target_ibi_cb_t ibi_cb;
1087 #endif /* CONFIG_I3C_USE_IBI */
1088 };
1089
1090 /**
1091 * @brief Structure describing a I2C device on I3C bus.
1092 *
1093 * Instances of this are passed to the I3C controller device APIs,
1094 * for example:
1095 * () i3c_i2c_device_register() to tell the controller of an I2C device.
1096 * () i3c_i2c_transfers() to initiate data transfers between controller
1097 * and I2C device.
1098 *
1099 * Fields other than @c node must be initialized by the module that
1100 * implements the device behavior prior to passing the object
1101 * reference to I3C controller device APIs.
1102 */
1103 struct i3c_i2c_device_desc {
1104 sys_snode_t node;
1105
1106 /** I3C bus to which this I2C device is attached */
1107 const struct device *bus;
1108
1109 /** Static address for this I2C device. */
1110 const uint16_t addr;
1111
1112 /**
1113 * Legacy Virtual Register (LVR)
1114 * @see @ref I3C_LVR
1115 */
1116 const uint8_t lvr;
1117
1118 /** @cond INTERNAL_HIDDEN */
1119 /**
1120 * Private data by the controller to aid in transactions. Do not modify.
1121 */
1122 void *controller_priv;
1123 /** @endcond */
1124 };
1125
1126 /**
1127 * @brief Structure for describing attached devices for a controller.
1128 *
1129 * This contains slists of attached I3C and I2C devices.
1130 *
1131 * This is a helper struct that can be used by controller device
1132 * driver to aid in device management.
1133 */
1134 struct i3c_dev_attached_list {
1135 /**
1136 * Address slots:
1137 * - Aid in dynamic address assignment.
1138 * - Quick way to find out if a target address is
1139 * a I3C or I2C device.
1140 */
1141 struct i3c_addr_slots addr_slots;
1142
1143 struct {
1144 /**
1145 * Linked list of attached I3C devices.
1146 */
1147 sys_slist_t i3c;
1148
1149 /**
1150 * Linked list of attached I2C devices.
1151 */
1152 sys_slist_t i2c;
1153 } devices;
1154 };
1155
1156 /**
1157 * @brief Structure for describing known devices for a controller.
1158 *
1159 * This contains arrays of known I3C and I2C devices.
1160 *
1161 * This is a helper struct that can be used by controller device
1162 * driver to aid in device management.
1163 */
1164 struct i3c_dev_list {
1165 /**
1166 * Pointer to array of known I3C devices.
1167 */
1168 struct i3c_device_desc * const i3c;
1169
1170 /**
1171 * Pointer to array of known I2C devices.
1172 */
1173 struct i3c_i2c_device_desc * const i2c;
1174
1175 /**
1176 * Number of I3C devices in array.
1177 */
1178 const uint8_t num_i3c;
1179
1180 /**
1181 * Number of I2C devices in array.
1182 */
1183 const uint8_t num_i2c;
1184 };
1185
1186 /**
1187 * This structure is common to all I3C drivers and is expected to be
1188 * the first element in the object pointed to by the config field
1189 * in the device structure.
1190 */
1191 struct i3c_driver_config {
1192 /** I3C/I2C device list struct. */
1193 struct i3c_dev_list dev_list;
1194 };
1195
1196 /**
1197 * This structure is common to all I3C drivers and is expected to be the first
1198 * element in the driver's struct driver_data declaration.
1199 */
1200 struct i3c_driver_data {
1201 /** Controller Configuration */
1202 struct i3c_config_controller ctrl_config;
1203
1204 /** Attached I3C/I2C devices and addresses */
1205 struct i3c_dev_attached_list attached_dev;
1206
1207 /** Received DEFTGTS Pointer */
1208 struct i3c_ccc_deftgts *deftgts;
1209
1210 /** DEFTGTS refreshed */
1211 bool deftgts_refreshed;
1212 };
1213
1214 /**
1215 * @brief iterate over all I3C devices present on the bus
1216 *
1217 * @param bus: the I3C bus device pointer
1218 * @param desc: an I3C device descriptor pointer updated to point to the current slot
1219 * at each iteration of the loop
1220 */
1221 #define I3C_BUS_FOR_EACH_I3CDEV(bus, desc) \
1222 SYS_SLIST_FOR_EACH_CONTAINER( \
1223 &((struct i3c_driver_data *)(bus->data))->attached_dev.devices.i3c, desc, node)
1224
1225 /**
1226 * @brief iterate over all I2C devices present on the bus
1227 *
1228 * @param bus: the I3C bus device pointer
1229 * @param desc: an I2C device descriptor pointer updated to point to the current slot
1230 * at each iteration of the loop
1231 */
1232 #define I3C_BUS_FOR_EACH_I2CDEV(bus, desc) \
1233 SYS_SLIST_FOR_EACH_CONTAINER( \
1234 &((struct i3c_driver_data *)(bus->data))->attached_dev.devices.i2c, desc, node)
1235
1236 /**
1237 * @brief Find a I3C target device descriptor by ID.
1238 *
1239 * This finds the I3C target device descriptor in the device list
1240 * matching the provided ID struct (@p id).
1241 *
1242 * @param dev_list Pointer to the device list struct.
1243 * @param id Pointer to I3C device ID struct.
1244 *
1245 * @return Pointer to the I3C target device descriptor, or
1246 * `NULL` if none is found.
1247 */
1248 struct i3c_device_desc *i3c_dev_list_find(const struct i3c_dev_list *dev_list,
1249 const struct i3c_device_id *id);
1250
1251 /**
1252 * @brief Find a I3C target device descriptor by dynamic address.
1253 *
1254 * This finds the I3C target device descriptor in the attached
1255 * device list matching the dynamic address (@p addr)
1256 *
1257 * @param dev Pointer to controller device driver instance.
1258 * @param addr Dynamic address to be matched.
1259 *
1260 * @return Pointer to the I3C target device descriptor, or
1261 * `NULL` if none is found.
1262 */
1263 struct i3c_device_desc *i3c_dev_list_i3c_addr_find(const struct device *dev,
1264 uint8_t addr);
1265
1266 /**
1267 * @brief Find a I3C target device descriptor by static address.
1268 *
1269 * This finds the I3C target device descriptor in the attached
1270 * device list matching the static address (@p addr)
1271 *
1272 * @param dev Pointer to controller device driver instance.
1273 * @param addr static address to be matched.
1274 *
1275 * @return Pointer to the I3C target device descriptor, or
1276 * `NULL` if none is found.
1277 */
1278 struct i3c_device_desc *i3c_dev_list_i3c_static_addr_find(const struct device *dev,
1279 uint8_t addr);
1280
1281 /**
1282 * @brief Find a I2C target device descriptor by address.
1283 *
1284 * This finds the I2C target device descriptor in the attached
1285 * device list matching the address (@p addr)
1286 *
1287 * @param dev Pointer to controller device driver instance.
1288 * @param addr Address to be matched.
1289 *
1290 * @return Pointer to the I2C target device descriptor, or
1291 * `NULL` if none is found.
1292 */
1293 struct i3c_i2c_device_desc *i3c_dev_list_i2c_addr_find(const struct device *dev,
1294 uint16_t addr);
1295
1296 /**
1297 * @brief Helper function to find a usable address during ENTDAA.
1298 *
1299 * This is a helper function to find a usable address during
1300 * Dynamic Address Assignment. Given the PID (@p pid), it will
1301 * search through the device list for the matching device
1302 * descriptor. If the device descriptor indicates that there is
1303 * a preferred address (i.e. assigned-address in device tree,
1304 * i3c_device_desc::init_dynamic_addr), this preferred
1305 * address will be returned if this address is still available.
1306 * If it is not available, another free address will be returned.
1307 *
1308 * If @p must_match is true, the PID (@p pid) must match
1309 * one of the device in the device list.
1310 *
1311 * If @p must_match is false, this will return an arbitrary
1312 * address. This is useful when not all devices are described in
1313 * device tree. Or else, the DAA process cannot proceed since
1314 * there is no address to be assigned.
1315 *
1316 * If @p assigned_okay is true, it will return the same address
1317 * already assigned to the device
1318 * (i3c_device_desc::dynamic_addr). If no address has been
1319 * assigned, it behaves as if @p assigned_okay is false.
1320 * This is useful for assigning the same address to the same
1321 * device (for example, hot-join after device coming back from
1322 * suspend).
1323 *
1324 * If @p assigned_okay is false, the device cannot have an address
1325 * assigned already (that i3c_device_desc::dynamic_addr is not
1326 * zero). This is mainly used during the initial DAA.
1327 *
1328 * @param[in] addr_slots Pointer to address slots struct.
1329 * @param[in] dev_list Pointer to the device list struct.
1330 * @param[in] pid Provisioned ID of device to be assigned address.
1331 * @param[in] must_match True if PID must match devices in
1332 * the device list. False otherwise.
1333 * @param[in] assigned_okay True if it is okay to return the
1334 * address already assigned to the target
1335 * matching the PID (@p pid).
1336 * @param[out] target Store the pointer of the device descriptor
1337 * if it matches the incoming PID (@p pid).
1338 * @param[out] addr Address to be assigned to target device.
1339 *
1340 * @retval 0 if successful.
1341 * @retval -ENODEV if no device matches the PID (@p pid) in
1342 * the device list and @p must_match is true.
1343 * @retval -EINVAL if the device matching PID (@p pid) already
1344 * has an address assigned or invalid function
1345 * arguments.
1346 */
1347 int i3c_dev_list_daa_addr_helper(struct i3c_addr_slots *addr_slots,
1348 const struct i3c_dev_list *dev_list,
1349 uint64_t pid, bool must_match,
1350 bool assigned_okay,
1351 struct i3c_device_desc **target,
1352 uint8_t *addr);
1353
1354 /**
1355 * @brief Configure the I3C hardware.
1356 *
1357 * @param dev Pointer to controller device driver instance.
1358 * @param type Type of configuration parameters being passed
1359 * in @p config.
1360 * @param config Pointer to the configuration parameters.
1361 *
1362 * @retval 0 If successful.
1363 * @retval -EINVAL If invalid configure parameters.
1364 * @retval -EIO General Input/Output errors.
1365 * @retval -ENOSYS If not implemented.
1366 */
i3c_configure(const struct device * dev,enum i3c_config_type type,void * config)1367 static inline int i3c_configure(const struct device *dev,
1368 enum i3c_config_type type, void *config)
1369 {
1370 const struct i3c_driver_api *api =
1371 (const struct i3c_driver_api *)dev->api;
1372
1373 if (api->configure == NULL) {
1374 return -ENOSYS;
1375 }
1376
1377 return api->configure(dev, type, config);
1378 }
1379
1380 /**
1381 * @brief Get the controller device configuration for an I3C device.
1382 *
1383 * This function retrieves the configuration parameters specific to an
1384 * I3C controller device. It is a type-safe wrapper around @ref i3c_config_get
1385 * that ensures the correct structure type is passed.
1386 *
1387 * @param dev Pointer to the I3C controller device instance.
1388 * @param config Pointer to a @ref i3c_config_controller structure
1389 * where the configuration will be stored.
1390 *
1391 * @retval 0 If successful.
1392 * @retval -EIO General Input/Output errors.
1393 * @retval -ENOSYS If not implemented.
1394 */
i3c_configure_controller(const struct device * dev,struct i3c_config_controller * config)1395 static inline int i3c_configure_controller(const struct device *dev,
1396 struct i3c_config_controller *config)
1397 {
1398 return i3c_configure(dev, I3C_CONFIG_CONTROLLER, config);
1399 }
1400
1401 /**
1402 * @brief Get the target device configuration for an I3C device.
1403 *
1404 * This function retrieves the configuration parameters specific to an
1405 * I3C target device. It is a type-safe wrapper around @ref i3c_config_get
1406 * that ensures the correct structure type is passed.
1407 *
1408 * @param dev Pointer to the I3C controller device instance.
1409 * @param config Pointer to a @ref i3c_config_target structure
1410 * where the configuration will be stored.
1411 *
1412 * @retval 0 If successful.
1413 * @retval -EIO General Input/Output errors.
1414 * @retval -ENOSYS If not implemented.
1415 */
i3c_configure_target(const struct device * dev,struct i3c_config_target * config)1416 static inline int i3c_configure_target(const struct device *dev,
1417 struct i3c_config_target *config)
1418 {
1419 return i3c_configure(dev, I3C_CONFIG_TARGET, config);
1420 }
1421
1422 /**
1423 * @brief Get configuration of the I3C hardware.
1424 *
1425 * This provides a way to get the current configuration of the I3C hardware.
1426 *
1427 * This can return cached config or probed hardware parameters, but it has to
1428 * be up to date with current configuration.
1429 *
1430 * @param[in] dev Pointer to controller device driver instance.
1431 * @param[in] type Type of configuration parameters being passed
1432 * in @p config.
1433 * @param[in,out] config Pointer to the configuration parameters.
1434 *
1435 * Note that if @p type is #I3C_CONFIG_CUSTOM, @p config must contain
1436 * the ID of the parameter to be retrieved.
1437 *
1438 * @retval 0 If successful.
1439 * @retval -EIO General Input/Output errors.
1440 * @retval -ENOSYS If not implemented.
1441 */
i3c_config_get(const struct device * dev,enum i3c_config_type type,void * config)1442 static inline int i3c_config_get(const struct device *dev,
1443 enum i3c_config_type type, void *config)
1444 {
1445 const struct i3c_driver_api *api =
1446 (const struct i3c_driver_api *)dev->api;
1447
1448 if (api->config_get == NULL) {
1449 return -ENOSYS;
1450 }
1451
1452 return api->config_get(dev, type, config);
1453 }
1454
1455 /**
1456 * @brief Get the controller device configuration for an I3C device.
1457 *
1458 * This function sets the configuration parameters specific to an
1459 * I3C controller device. It is a type-safe wrapper around @ref i3c_config_get
1460 * that ensures the correct structure type is passed.
1461 *
1462 * @param[in] dev Pointer to the I3C controller device instance.
1463 * @param[out] config Pointer to a @ref i3c_config_controller structure
1464 * where the configuration will be used.
1465 *
1466 * @retval 0 If successful.
1467 * @retval -EIO General Input/Output errors.
1468 * @retval -ENOSYS If not implemented.
1469 */
i3c_config_get_controller(const struct device * dev,struct i3c_config_controller * config)1470 static inline int i3c_config_get_controller(const struct device *dev,
1471 struct i3c_config_controller *config)
1472 {
1473 return i3c_config_get(dev, I3C_CONFIG_CONTROLLER, config);
1474 }
1475
1476 /**
1477 * @brief Get the target device configuration for an I3C device.
1478 *
1479 * This function sets the configuration parameters specific to an
1480 * I3C target device. It is a type-safe wrapper around @ref i3c_config_get
1481 * that ensures the correct structure type is passed.
1482 *
1483 * @param[in] dev Pointer to the I3C controller device instance.
1484 * @param[out] config Pointer to a @ref i3c_config_target structure
1485 * where the configuration will be used.
1486 *
1487 * @retval 0 If successful.
1488 * @retval -EIO General Input/Output errors.
1489 * @retval -ENOSYS If not implemented.
1490 */
i3c_config_get_target(const struct device * dev,struct i3c_config_target * config)1491 static inline int i3c_config_get_target(const struct device *dev,
1492 struct i3c_config_target *config)
1493 {
1494 return i3c_config_get(dev, I3C_CONFIG_TARGET, config);
1495 }
1496
1497 /**
1498 * @brief Attempt bus recovery on the I3C bus.
1499 *
1500 * This routine asks the controller to attempt bus recovery.
1501 *
1502 * @retval 0 If successful.
1503 * @retval -EBUSY If bus recovery fails.
1504 * @retval -EIO General input / output error.
1505 * @retval -ENOSYS Bus recovery is not supported by the controller driver.
1506 */
i3c_recover_bus(const struct device * dev)1507 static inline int i3c_recover_bus(const struct device *dev)
1508 {
1509 const struct i3c_driver_api *api =
1510 (const struct i3c_driver_api *)dev->api;
1511
1512 if (api->recover_bus == NULL) {
1513 return -ENOSYS;
1514 }
1515
1516 return api->recover_bus(dev);
1517 }
1518
1519 /**
1520 * @brief Attach an I3C device
1521 *
1522 * Called to attach a I3C device to the addresses. This is
1523 * typically called before a SETDASA or ENTDAA to reserve
1524 * the addresses. This will also call the optional api to
1525 * update any registers within the driver if implemented.
1526 *
1527 * @warning
1528 * Use cases involving multiple writers to the i3c/i2c devices must prevent
1529 * concurrent write operations, either by preventing all writers from
1530 * being preempted or by using a mutex to govern writes to the i3c/i2c devices.
1531 *
1532 * @param target Pointer to the target device descriptor
1533 *
1534 * @retval 0 If successful.
1535 * @retval -EINVAL If address is not available or if the device
1536 * has already been attached before
1537 */
1538 int i3c_attach_i3c_device(struct i3c_device_desc *target);
1539
1540 /**
1541 * @brief Reattach I3C device
1542 *
1543 * called after every time an I3C device has its address
1544 * changed. It can be because the device has been powered
1545 * down and has lost its address, or it can happen when a
1546 * device had a static address and has been assigned a
1547 * dynamic address with SETDASA or a dynamic address has
1548 * been updated with SETNEWDA. This will also call the
1549 * optional api to update any registers within the driver
1550 * if implemented.
1551 *
1552 * @warning
1553 * Use cases involving multiple writers to the i3c/i2c devices must prevent
1554 * concurrent write operations, either by preventing all writers from
1555 * being preempted or by using a mutex to govern writes to the i3c/i2c devices.
1556 *
1557 * @param target Pointer to the target device descriptor
1558 * @param old_dyn_addr The old dynamic address of target device, 0 if
1559 * there was no old dynamic address
1560 *
1561 * @retval 0 If successful.
1562 * @retval -EINVAL If address is not available
1563 */
1564 int i3c_reattach_i3c_device(struct i3c_device_desc *target, uint8_t old_dyn_addr);
1565
1566 /**
1567 * @brief Detach I3C Device
1568 *
1569 * called to remove an I3C device and to free up the address
1570 * that it used. If it's dynamic address was not set, then it
1571 * assumed that SETDASA failed and will free it's static addr.
1572 * This will also call the optional api to update any registers
1573 * within the driver if implemented.
1574 *
1575 * @warning
1576 * Use cases involving multiple writers to the i3c/i2c devices must prevent
1577 * concurrent write operations, either by preventing all writers from
1578 * being preempted or by using a mutex to govern writes to the i3c/i2c devices.
1579 *
1580 * @param target Pointer to the target device descriptor
1581 *
1582 * @retval 0 If successful.
1583 * @retval -EINVAL If device is already detached
1584 */
1585 int i3c_detach_i3c_device(struct i3c_device_desc *target);
1586
1587 /**
1588 * @brief Attach an I2C device
1589 *
1590 * Called to attach a I2C device to the addresses. This will
1591 * also call the optional api to update any registers within
1592 * the driver if implemented.
1593 *
1594 * @warning
1595 * Use cases involving multiple writers to the i3c/i2c devices must prevent
1596 * concurrent write operations, either by preventing all writers from
1597 * being preempted or by using a mutex to govern writes to the i3c/i2c devices.
1598 *
1599 * @param target Pointer to the target device descriptor
1600 *
1601 * @retval 0 If successful.
1602 * @retval -EINVAL If address is not available or if the device
1603 * has already been attached before
1604 */
1605 int i3c_attach_i2c_device(struct i3c_i2c_device_desc *target);
1606
1607 /**
1608 * @brief Detach I2C Device
1609 *
1610 * called to remove an I2C device and to free up the address
1611 * that it used. This will also call the optional api to
1612 * update any registers within the driver if implemented.
1613 *
1614 * @warning
1615 * Use cases involving multiple writers to the i3c/i2c devices must prevent
1616 * concurrent write operations, either by preventing all writers from
1617 * being preempted or by using a mutex to govern writes to the i3c/i2c devices.
1618 *
1619 * @param target Pointer to the target device descriptor
1620 *
1621 * @retval 0 If successful.
1622 * @retval -EINVAL If device is already detached
1623 */
1624 int i3c_detach_i2c_device(struct i3c_i2c_device_desc *target);
1625
1626 /**
1627 * @brief Perform Dynamic Address Assignment on the I3C bus.
1628 *
1629 * This routine asks the controller to perform dynamic address assignment
1630 * where the controller belongs. Only the active controller of the bus
1631 * should do this.
1632 *
1633 * @note For controller driver implementation, the controller should perform
1634 * SETDASA to allow static addresses to be the dynamic addresses before
1635 * actually doing ENTDAA.
1636 *
1637 * @param dev Pointer to the device structure for the controller driver
1638 * instance.
1639 *
1640 * @retval 0 If successful.
1641 * @retval -EBUSY Bus is busy.
1642 * @retval -EIO General input / output error.
1643 * @retval -ENODEV If a provisioned ID does not match to any target devices
1644 * in the registered device list.
1645 * @retval -ENOSPC No more free addresses can be assigned to target.
1646 * @retval -ENOSYS Dynamic address assignment is not supported by
1647 * the controller driver.
1648 */
i3c_do_daa(const struct device * dev)1649 static inline int i3c_do_daa(const struct device *dev)
1650 {
1651 const struct i3c_driver_api *api =
1652 (const struct i3c_driver_api *)dev->api;
1653
1654 if (api->do_daa == NULL) {
1655 return -ENOSYS;
1656 }
1657
1658 return api->do_daa(dev);
1659 }
1660
1661 /**
1662 * @brief Send CCC to the bus.
1663 *
1664 * @param dev Pointer to the device structure for the controller driver
1665 * instance.
1666 * @param payload Pointer to the structure describing the CCC payload.
1667 *
1668 * @retval 0 If successful.
1669 * @retval -EBUSY Bus is busy.
1670 * @retval -EIO General Input / output error.
1671 * @retval -EINVAL Invalid valid set in the payload structure.
1672 * @retval -ENOSYS Not implemented.
1673 */
1674 __syscall int i3c_do_ccc(const struct device *dev,
1675 struct i3c_ccc_payload *payload);
1676
z_impl_i3c_do_ccc(const struct device * dev,struct i3c_ccc_payload * payload)1677 static inline int z_impl_i3c_do_ccc(const struct device *dev,
1678 struct i3c_ccc_payload *payload)
1679 {
1680 const struct i3c_driver_api *api =
1681 (const struct i3c_driver_api *)dev->api;
1682
1683 if (api->do_ccc == NULL) {
1684 return -ENOSYS;
1685 }
1686
1687 return api->do_ccc(dev, payload);
1688 }
1689
1690 /**
1691 * @addtogroup i3c_transfer_api
1692 * @{
1693 */
1694
1695 /**
1696 * @brief Perform data transfer from the controller to a I3C target device.
1697 *
1698 * This routine provides a generic interface to perform data transfer
1699 * to a target device synchronously. Use i3c_read()/i3c_write()
1700 * for simple read or write.
1701 *
1702 * The array of message @p msgs must not be `NULL`. The number of
1703 * message @p num_msgs may be zero, in which case no transfer occurs.
1704 *
1705 * @note Not all scatter/gather transactions can be supported by all
1706 * drivers. As an example, a gather write (multiple consecutive
1707 * i3c_msg buffers all configured for #I3C_MSG_WRITE) may be packed
1708 * into a single transaction by some drivers, but others may emit each
1709 * fragment as a distinct write transaction, which will not produce
1710 * the same behavior. See the documentation of i3c_msg for
1711 * limitations on support for multi-message bus transactions.
1712 *
1713 * @param target I3C target device descriptor.
1714 * @param msgs Array of messages to transfer.
1715 * @param num_msgs Number of messages to transfer.
1716 *
1717 * @retval 0 If successful.
1718 * @retval -EBUSY Bus is busy.
1719 * @retval -EIO General input / output error.
1720 */
1721 __syscall int i3c_transfer(struct i3c_device_desc *target,
1722 struct i3c_msg *msgs, uint8_t num_msgs);
1723
z_impl_i3c_transfer(struct i3c_device_desc * target,struct i3c_msg * msgs,uint8_t num_msgs)1724 static inline int z_impl_i3c_transfer(struct i3c_device_desc *target,
1725 struct i3c_msg *msgs, uint8_t num_msgs)
1726 {
1727 const struct i3c_driver_api *api =
1728 (const struct i3c_driver_api *)target->bus->api;
1729
1730 return api->i3c_xfers(target->bus, target, msgs, num_msgs);
1731 }
1732
1733 /** @} */
1734
1735 /**
1736 * Find a registered I3C target device.
1737 *
1738 * Controller only API.
1739 *
1740 * This returns the I3C device descriptor of the I3C device
1741 * matching the incoming @p id.
1742 *
1743 * @param dev Pointer to controller device driver instance.
1744 * @param id Pointer to I3C device ID.
1745 *
1746 * @return Pointer to I3C device descriptor, or `NULL` if
1747 * no I3C device found matching incoming @p id.
1748 */
1749 static inline
i3c_device_find(const struct device * dev,const struct i3c_device_id * id)1750 struct i3c_device_desc *i3c_device_find(const struct device *dev,
1751 const struct i3c_device_id *id)
1752 {
1753 const struct i3c_driver_api *api =
1754 (const struct i3c_driver_api *)dev->api;
1755
1756 if (api->i3c_device_find == NULL) {
1757 return NULL;
1758 }
1759
1760 return api->i3c_device_find(dev, id);
1761 }
1762
1763 /**
1764 * @addtogroup i3c_ibi
1765 * @{
1766 */
1767
1768 /**
1769 * @brief ACK or NACK IBI HJ Requests
1770 *
1771 * This tells the controller to Acknowledge or Not Acknowledge
1772 * In-Band Interrupt Hot-Join Requests.
1773 *
1774 * @param dev Pointer to controller device driver instance.
1775 * @param ack True to ack, False to nack
1776 *
1777 * @retval 0 if operation is successful.
1778 * @retval -EIO General input / output error.
1779 */
i3c_ibi_hj_response(const struct device * dev,bool ack)1780 static inline int i3c_ibi_hj_response(const struct device *dev,
1781 bool ack)
1782 {
1783 const struct i3c_driver_api *api =
1784 (const struct i3c_driver_api *)dev->api;
1785
1786 if (api->ibi_hj_response == NULL) {
1787 return -ENOSYS;
1788 }
1789
1790 return api->ibi_hj_response(dev, ack);
1791 }
1792
1793 /**
1794 * @brief Raise an In-Band Interrupt (IBI).
1795 *
1796 * This raises an In-Band Interrupt (IBI) to the active controller.
1797 *
1798 * @param dev Pointer to controller device driver instance.
1799 * @param request Pointer to the IBI request struct.
1800 *
1801 * @retval 0 if operation is successful.
1802 * @retval -EIO General input / output error.
1803 */
i3c_ibi_raise(const struct device * dev,struct i3c_ibi * request)1804 static inline int i3c_ibi_raise(const struct device *dev,
1805 struct i3c_ibi *request)
1806 {
1807 const struct i3c_driver_api *api =
1808 (const struct i3c_driver_api *)dev->api;
1809
1810 if (api->ibi_raise == NULL) {
1811 return -ENOSYS;
1812 }
1813
1814 return api->ibi_raise(dev, request);
1815 }
1816
1817 /**
1818 * @brief Enable IBI of a target device.
1819 *
1820 * This enables IBI of a target device where the IBI has already been
1821 * request.
1822 *
1823 * @param target I3C target device descriptor.
1824 *
1825 * @retval 0 If successful.
1826 * @retval -EIO General Input / output error.
1827 * @retval -ENOMEM If these is no more empty entries in
1828 * the controller's IBI table (if the controller
1829 * uses such table).
1830 */
i3c_ibi_enable(struct i3c_device_desc * target)1831 static inline int i3c_ibi_enable(struct i3c_device_desc *target)
1832 {
1833 const struct i3c_driver_api *api =
1834 (const struct i3c_driver_api *)target->bus->api;
1835
1836 if (api->ibi_enable == NULL) {
1837 return -ENOSYS;
1838 }
1839
1840 return api->ibi_enable(target->bus, target);
1841 }
1842
1843 /**
1844 * @brief Disable IBI of a target device.
1845 *
1846 * This enables IBI of a target device where the IBI has already been
1847 * request.
1848 *
1849 * @param target I3C target device descriptor.
1850 *
1851 * @retval 0 If successful.
1852 * @retval -EIO General Input / output error.
1853 * @retval -ENODEV If IBI is not previously enabled for @p target.
1854 */
i3c_ibi_disable(struct i3c_device_desc * target)1855 static inline int i3c_ibi_disable(struct i3c_device_desc *target)
1856 {
1857 const struct i3c_driver_api *api =
1858 (const struct i3c_driver_api *)target->bus->api;
1859
1860 if (api->ibi_disable == NULL) {
1861 return -ENOSYS;
1862 }
1863
1864 return api->ibi_disable(target->bus, target);
1865 }
1866
1867 /**
1868 * @brief Check if target's IBI has payload.
1869 *
1870 * This reads the BCR from the device descriptor struct to determine
1871 * whether IBI from device has payload.
1872 *
1873 * Note that BCR must have been obtained from device and
1874 * i3c_device_desc::bcr must be set.
1875 *
1876 * @return True if IBI has payload, false otherwise.
1877 */
i3c_ibi_has_payload(struct i3c_device_desc * target)1878 static inline int i3c_ibi_has_payload(struct i3c_device_desc *target)
1879 {
1880 return (target->bcr & I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE)
1881 == I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE;
1882 }
1883
1884 /**
1885 * @brief Check if device is IBI capable.
1886 *
1887 * This reads the BCR from the device descriptor struct to determine
1888 * whether device is capable of IBI.
1889 *
1890 * Note that BCR must have been obtained from device and
1891 * i3c_device_desc::bcr must be set.
1892 *
1893 * @return True if IBI has payload, false otherwise.
1894 */
i3c_device_is_ibi_capable(struct i3c_device_desc * target)1895 static inline int i3c_device_is_ibi_capable(struct i3c_device_desc *target)
1896 {
1897 return (target->bcr & I3C_BCR_IBI_REQUEST_CAPABLE)
1898 == I3C_BCR_IBI_REQUEST_CAPABLE;
1899 }
1900
1901 /**
1902 * @brief Check if the target is controller capable
1903 *
1904 * This reads the BCR from the device descriptor struct to determine
1905 * whether the target is controller capable
1906 *
1907 * Note that BCR must have been obtained from device and
1908 * i3c_device_desc::bcr must be set.
1909 *
1910 * @return True if target is controller capable, false otherwise.
1911 */
i3c_device_is_controller_capable(struct i3c_device_desc * target)1912 static inline int i3c_device_is_controller_capable(struct i3c_device_desc *target)
1913 {
1914 return I3C_BCR_DEVICE_ROLE(target->bcr)
1915 == I3C_BCR_DEVICE_ROLE_I3C_CONTROLLER_CAPABLE;
1916 }
1917
1918 /** @} */
1919
1920 /**
1921 * @addtogroup i3c_transfer_api
1922 * @{
1923 */
1924
1925 /**
1926 * @brief Write a set amount of data to an I3C target device.
1927 *
1928 * This routine writes a set amount of data synchronously.
1929 *
1930 * @param target I3C target device descriptor.
1931 * @param buf Memory pool from which the data is transferred.
1932 * @param num_bytes Number of bytes to write.
1933 *
1934 * @retval 0 If successful.
1935 * @retval -EBUSY Bus is busy.
1936 * @retval -EIO General input / output error.
1937 */
i3c_write(struct i3c_device_desc * target,const uint8_t * buf,uint32_t num_bytes)1938 static inline int i3c_write(struct i3c_device_desc *target,
1939 const uint8_t *buf, uint32_t num_bytes)
1940 {
1941 struct i3c_msg msg;
1942
1943 msg.buf = (uint8_t *)buf;
1944 msg.len = num_bytes;
1945 msg.flags = I3C_MSG_WRITE | I3C_MSG_STOP;
1946 msg.hdr_mode = 0;
1947 msg.hdr_cmd_code = 0;
1948
1949 return i3c_transfer(target, &msg, 1);
1950 }
1951
1952 /**
1953 * @brief Read a set amount of data from an I3C target device.
1954 *
1955 * This routine reads a set amount of data synchronously.
1956 *
1957 * @param target I3C target device descriptor.
1958 * @param buf Memory pool that stores the retrieved data.
1959 * @param num_bytes Number of bytes to read.
1960 *
1961 * @retval 0 If successful.
1962 * @retval -EBUSY Bus is busy.
1963 * @retval -EIO General input / output error.
1964 */
i3c_read(struct i3c_device_desc * target,uint8_t * buf,uint32_t num_bytes)1965 static inline int i3c_read(struct i3c_device_desc *target,
1966 uint8_t *buf, uint32_t num_bytes)
1967 {
1968 struct i3c_msg msg;
1969
1970 msg.buf = buf;
1971 msg.len = num_bytes;
1972 msg.flags = I3C_MSG_READ | I3C_MSG_STOP;
1973 msg.hdr_mode = 0;
1974 msg.hdr_cmd_code = 0;
1975
1976 return i3c_transfer(target, &msg, 1);
1977 }
1978
1979 /**
1980 * @brief Write then read data from an I3C target device.
1981 *
1982 * This supports the common operation "this is what I want", "now give
1983 * it to me" transaction pair through a combined write-then-read bus
1984 * transaction.
1985 *
1986 * @param target I3C target device descriptor.
1987 * @param write_buf Pointer to the data to be written
1988 * @param num_write Number of bytes to write
1989 * @param read_buf Pointer to storage for read data
1990 * @param num_read Number of bytes to read
1991 *
1992 * @retval 0 if successful
1993 * @retval -EBUSY Bus is busy.
1994 * @retval -EIO General input / output error.
1995 */
i3c_write_read(struct i3c_device_desc * target,const void * write_buf,size_t num_write,void * read_buf,size_t num_read)1996 static inline int i3c_write_read(struct i3c_device_desc *target,
1997 const void *write_buf, size_t num_write,
1998 void *read_buf, size_t num_read)
1999 {
2000 struct i3c_msg msg[2];
2001
2002 msg[0].buf = (uint8_t *)write_buf;
2003 msg[0].len = num_write;
2004 msg[0].flags = I3C_MSG_WRITE;
2005 msg[0].hdr_mode = 0;
2006 msg[0].hdr_cmd_code = 0;
2007
2008 msg[1].buf = (uint8_t *)read_buf;
2009 msg[1].len = num_read;
2010 msg[1].flags = I3C_MSG_RESTART | I3C_MSG_READ | I3C_MSG_STOP;
2011 msg[1].hdr_mode = 0;
2012 msg[1].hdr_cmd_code = 0;
2013
2014 return i3c_transfer(target, msg, 2);
2015 }
2016
2017 /**
2018 * @brief Read multiple bytes from an internal address of an I3C target device.
2019 *
2020 * This routine reads multiple bytes from an internal address of an
2021 * I3C target device synchronously.
2022 *
2023 * Instances of this may be replaced by i3c_write_read().
2024 *
2025 * @param target I3C target device descriptor,
2026 * @param start_addr Internal address from which the data is being read.
2027 * @param buf Memory pool that stores the retrieved data.
2028 * @param num_bytes Number of bytes being read.
2029 *
2030 * @retval 0 If successful.
2031 * @retval -EBUSY Bus is busy.
2032 * @retval -EIO General input / output error.
2033 */
i3c_burst_read(struct i3c_device_desc * target,uint8_t start_addr,uint8_t * buf,uint32_t num_bytes)2034 static inline int i3c_burst_read(struct i3c_device_desc *target,
2035 uint8_t start_addr,
2036 uint8_t *buf,
2037 uint32_t num_bytes)
2038 {
2039 return i3c_write_read(target,
2040 &start_addr, sizeof(start_addr),
2041 buf, num_bytes);
2042 }
2043
2044 /**
2045 * @brief Write multiple bytes to an internal address of an I3C target device.
2046 *
2047 * This routine writes multiple bytes to an internal address of an
2048 * I3C target device synchronously.
2049 *
2050 * @warning The combined write synthesized by this API may not be
2051 * supported on all I3C devices. Uses of this API may be made more
2052 * portable by replacing them with calls to i3c_write() passing a
2053 * buffer containing the combined address and data.
2054 *
2055 * @param target I3C target device descriptor.
2056 * @param start_addr Internal address to which the data is being written.
2057 * @param buf Memory pool from which the data is transferred.
2058 * @param num_bytes Number of bytes being written.
2059 *
2060 * @retval 0 If successful.
2061 * @retval -EBUSY Bus is busy.
2062 * @retval -EIO General input / output error.
2063 */
i3c_burst_write(struct i3c_device_desc * target,uint8_t start_addr,const uint8_t * buf,uint32_t num_bytes)2064 static inline int i3c_burst_write(struct i3c_device_desc *target,
2065 uint8_t start_addr,
2066 const uint8_t *buf,
2067 uint32_t num_bytes)
2068 {
2069 struct i3c_msg msg[2];
2070
2071 msg[0].buf = &start_addr;
2072 msg[0].len = 1U;
2073 msg[0].flags = I3C_MSG_WRITE;
2074 msg[0].hdr_mode = 0;
2075 msg[0].hdr_cmd_code = 0;
2076
2077 msg[1].buf = (uint8_t *)buf;
2078 msg[1].len = num_bytes;
2079 msg[1].flags = I3C_MSG_WRITE | I3C_MSG_STOP;
2080 msg[1].hdr_mode = 0;
2081 msg[1].hdr_cmd_code = 0;
2082
2083 return i3c_transfer(target, msg, 2);
2084 }
2085
2086 /**
2087 * @brief Read internal register of an I3C target device.
2088 *
2089 * This routine reads the value of an 8-bit internal register of an I3C target
2090 * device synchronously.
2091 *
2092 * @param target I3C target device descriptor.
2093 * @param reg_addr Address of the internal register being read.
2094 * @param value Memory pool that stores the retrieved register value.
2095 *
2096 * @retval 0 If successful.
2097 * @retval -EBUSY Bus is busy.
2098 * @retval -EIO General input / output error.
2099 */
i3c_reg_read_byte(struct i3c_device_desc * target,uint8_t reg_addr,uint8_t * value)2100 static inline int i3c_reg_read_byte(struct i3c_device_desc *target,
2101 uint8_t reg_addr, uint8_t *value)
2102 {
2103 return i3c_write_read(target,
2104 ®_addr, sizeof(reg_addr),
2105 value, sizeof(*value));
2106 }
2107
2108 /**
2109 * @brief Write internal register of an I3C target device.
2110 *
2111 * This routine writes a value to an 8-bit internal register of an I3C target
2112 * device synchronously.
2113 *
2114 * @note This function internally combines the register and value into
2115 * a single bus transaction.
2116 *
2117 * @param target I3C target device descriptor.
2118 * @param reg_addr Address of the internal register being written.
2119 * @param value Value to be written to internal register.
2120 *
2121 * @retval 0 If successful.
2122 * @retval -EBUSY Bus is busy.
2123 * @retval -EIO General input / output error.
2124 */
i3c_reg_write_byte(struct i3c_device_desc * target,uint8_t reg_addr,uint8_t value)2125 static inline int i3c_reg_write_byte(struct i3c_device_desc *target,
2126 uint8_t reg_addr, uint8_t value)
2127 {
2128 uint8_t tx_buf[2] = {reg_addr, value};
2129
2130 return i3c_write(target, tx_buf, 2);
2131 }
2132
2133 /**
2134 * @brief Update internal register of an I3C target device.
2135 *
2136 * This routine updates the value of a set of bits from an 8-bit internal
2137 * register of an I3C target device synchronously.
2138 *
2139 * @note If the calculated new register value matches the value that
2140 * was read this function will not generate a write operation.
2141 *
2142 * @param target I3C target device descriptor.
2143 * @param reg_addr Address of the internal register being updated.
2144 * @param mask Bitmask for updating internal register.
2145 * @param value Value for updating internal register.
2146 *
2147 * @retval 0 If successful.
2148 * @retval -EBUSY Bus is busy.
2149 * @retval -EIO General input / output error.
2150 */
i3c_reg_update_byte(struct i3c_device_desc * target,uint8_t reg_addr,uint8_t mask,uint8_t value)2151 static inline int i3c_reg_update_byte(struct i3c_device_desc *target,
2152 uint8_t reg_addr, uint8_t mask,
2153 uint8_t value)
2154 {
2155 uint8_t old_value, new_value;
2156 int rc;
2157
2158 rc = i3c_reg_read_byte(target, reg_addr, &old_value);
2159 if (rc != 0) {
2160 return rc;
2161 }
2162
2163 new_value = (old_value & ~mask) | (value & mask);
2164 if (new_value == old_value) {
2165 return 0;
2166 }
2167
2168 return i3c_reg_write_byte(target, reg_addr, new_value);
2169 }
2170
2171 /**
2172 * @brief Dump out an I3C message
2173 *
2174 * Dumps out a list of I3C messages. For any that are writes (W), the data is
2175 * displayed in hex.
2176 *
2177 * It looks something like this (with name "testing"):
2178 *
2179 * @code
2180 * D: I3C msg: testing, addr=56
2181 * D: W len=01:
2182 * D: contents:
2183 * D: 06 |.
2184 * D: W len=0e:
2185 * D: contents:
2186 * D: 00 01 02 03 04 05 06 07 |........
2187 * D: 08 09 0a 0b 0c 0d |......
2188 * @endcode
2189 *
2190 * @param name Name of this dump, displayed at the top.
2191 * @param msgs Array of messages to dump.
2192 * @param num_msgs Number of messages to dump.
2193 * @param target I3C target device descriptor.
2194 */
2195 void i3c_dump_msgs(const char *name, const struct i3c_msg *msgs,
2196 uint8_t num_msgs, struct i3c_device_desc *target);
2197
2198 /** @} */
2199
2200 /**
2201 * @brief Generic helper function to perform bus initialization.
2202 *
2203 * @param dev Pointer to controller device driver instance.
2204 * @param i3c_dev_list Pointer to I3C device list.
2205 *
2206 * @retval 0 If successful.
2207 * @retval -EBUSY Bus is busy.
2208 * @retval -EIO General input / output error.
2209 * @retval -ENODEV If a provisioned ID does not match to any target devices
2210 * in the registered device list.
2211 * @retval -ENOSPC No more free addresses can be assigned to target.
2212 * @retval -ENOSYS Dynamic address assignment is not supported by
2213 * the controller driver.
2214 */
2215 int i3c_bus_init(const struct device *dev,
2216 const struct i3c_dev_list *i3c_dev_list);
2217
2218 /**
2219 * @brief Get basic information from device and update device descriptor.
2220 *
2221 * This retrieves some basic information:
2222 * * Bus Characteristics Register (GETBCR)
2223 * * Device Characteristics Register (GETDCR)
2224 * from the device and update the corresponding fields of the device
2225 * descriptor.
2226 *
2227 * This only updates the field(s) in device descriptor
2228 * only if CCC operations succeed.
2229 *
2230 * @param[in,out] target I3C target device descriptor.
2231 *
2232 * @retval 0 if successful.
2233 * @retval -EIO General Input/Output error.
2234 */
2235 int i3c_device_basic_info_get(struct i3c_device_desc *target);
2236
2237 /**
2238 * @brief Get advanced information from device and update device descriptor.
2239 *
2240 * This retrieves some information:
2241 * * Max Read Length (GETMRL)
2242 * * Max Write Length (GETMWL)
2243 * * Get Capabilities (GETCAPS)
2244 * * Max Device Speed (GETMXDS) (if applicable)
2245 * from the device and update the corresponding fields of the device
2246 * descriptor.
2247 *
2248 * This only updates the field(s) in device descriptor
2249 * only if CCC operations succeed.
2250 *
2251 * @note This should only be called after i3c_device_basic_info_get() or
2252 * if the BCR was already obtained through ENTDAA, DEFTGTS, or GETBCR.
2253 *
2254 * @param[in,out] target I3C target device descriptor.
2255 *
2256 * @retval 0 if successful.
2257 * @retval -EIO General Input/Output error.
2258 */
2259 int i3c_device_adv_info_get(struct i3c_device_desc *target);
2260
2261 /**
2262 * @brief Get all information from device and update device descriptor.
2263 *
2264 * This retrieves all information:
2265 * * Bus Characteristics Register (GETBCR)
2266 * * Device Characteristics Register (GETDCR)
2267 * * Max Read Length (GETMRL)
2268 * * Max Write Length (GETMWL)
2269 * * Get Capabilities (GETCAPS)
2270 * * Max Device Speed (GETMXDS) (if applicable)
2271 * from the device and update the corresponding fields of the device
2272 * descriptor.
2273 *
2274 * This only updates the field(s) in device descriptor
2275 * only if CCC operations succeed.
2276 *
2277 * @param[in,out] target I3C target device descriptor.
2278 *
2279 * @retval 0 if successful.
2280 * @retval -EIO General Input/Output error.
2281 */
i3c_device_info_get(struct i3c_device_desc * target)2282 static inline int i3c_device_info_get(struct i3c_device_desc *target)
2283 {
2284 int rc;
2285
2286 rc = i3c_device_basic_info_get(target);
2287 if (rc != 0) {
2288 return rc;
2289 }
2290
2291 return i3c_device_adv_info_get(target);
2292 }
2293
2294 /**
2295 * @brief Check if the bus has a secondary controller.
2296 *
2297 * This reads the BCR from the device descriptor struct of all targets
2298 * to determine whether a device is a secondary controller.
2299 *
2300 * @param dev Pointer to controller device driver instance.
2301 *
2302 * @return True if the bus has a secondary controller, false otherwise.
2303 */
2304 bool i3c_bus_has_sec_controller(const struct device *dev);
2305
2306 /**
2307 * @brief Send the CCC DEFTGTS
2308 *
2309 * This builds the payload required for DEFTGTS and transmits it out
2310 *
2311 * @param dev Pointer to controller device driver instance.
2312 *
2313 * @retval 0 if successful.
2314 * @retval -ENOMEM No memory to build the payload.
2315 * @retval -EIO General Input/Output error.
2316 */
2317 int i3c_bus_deftgts(const struct device *dev);
2318
2319 /**
2320 * @brief Calculate odd parity
2321 *
2322 * Calculate the Odd Parity of a Target Address.
2323 *
2324 * @param p The 7b target dynamic address
2325 *
2326 * @return The odd parity bit
2327 */
2328 uint8_t i3c_odd_parity(uint8_t p);
2329
2330 /**
2331 * @brief Perform Controller Handoff
2332 *
2333 * This performs the controller handoff according to 5.1.7.1 of
2334 * I3C v1.1.1 Specification.
2335 *
2336 * @param target I3C target device descriptor.
2337 * @param requested True if the target requested the Handoff, False if
2338 * the active controller is passing it to a secondary controller
2339 *
2340 * @retval 0 if successful.
2341 * @retval -EIO General Input/Output error.
2342 * @retval -EBUSY Target cannot accept Controller Handoff
2343 */
2344 int i3c_device_controller_handoff(const struct i3c_device_desc *target, bool requested);
2345
2346 #ifdef CONFIG_I3C_USE_IBI
2347 /**
2348 * @brief Call back for when Controllership is Handoffed to itself
2349 *
2350 * This reads the DEFTGTS it received earlier and processes it by reading
2351 * the PIDs of all the devices with GETPID and then matching it with known
2352 * PIDS. If it does not match, then it will attempt to grab a mem slab
2353 * for i3c_device_desc. It will then obtain the standard I3C information
2354 * from the device.
2355 *
2356 * @param work pointer to the work item.
2357 */
2358 void i3c_sec_handoffed(struct k_work *work);
2359 #endif
2360
2361 #if CONFIG_I3C_NUM_OF_DESC_MEM_SLABS > 0
2362
2363 /**
2364 * @brief Allocate memory for a i3c device descriptor
2365 *
2366 * This allocates memory from a mem slab for a i3c_device_desc
2367 *
2368 * @retval Pointer to allocated i3c_device_desc
2369 * @retval NULL if no mem slabs available
2370 */
2371 struct i3c_device_desc *i3c_device_desc_alloc(void);
2372
2373 /**
2374 * @brief Free memory from a i3c device descriptor
2375 *
2376 * This frees memory from a mem slab of a i3c_device_desc
2377 *
2378 * @param desc Pointer to allocated i3c_device_desc
2379 */
2380 void i3c_device_desc_free(struct i3c_device_desc *desc);
2381
2382 /**
2383 * @brief Report if the i3c device descriptor was from a mem slab
2384 *
2385 * This reports if the i3c_device_desc was from a memory slab
2386 *
2387 * @param desc Pointer to a i3c_device_desc
2388 *
2389 * @return True if from a memory slab, False if not
2390 */
2391 bool i3c_device_desc_in_pool(struct i3c_device_desc *desc);
2392
2393 #else
2394
i3c_device_desc_alloc(void)2395 static inline struct i3c_device_desc *i3c_device_desc_alloc(void)
2396 {
2397 return NULL;
2398 }
2399
i3c_device_desc_free(struct i3c_device_desc * desc)2400 static inline void i3c_device_desc_free(struct i3c_device_desc *desc)
2401 {
2402 ARG_UNUSED(desc);
2403 }
2404
i3c_device_desc_in_pool(struct i3c_device_desc * desc)2405 static inline bool i3c_device_desc_in_pool(struct i3c_device_desc *desc)
2406 {
2407 ARG_UNUSED(desc);
2408 return false;
2409 }
2410
2411 #endif /* CONFIG_I3C_NUM_OF_DESC_MEM_SLABS > 0 */
2412
2413 #if CONFIG_I3C_I2C_NUM_OF_DESC_MEM_SLABS > 0
2414
2415 /**
2416 * @brief Allocate memory for a i3c i2c device descriptor
2417 *
2418 * This allocates memory from a mem slab for a i3c_i2c_device_desc
2419 *
2420 * @return Pointer to allocated i3c_i2c_device_desc, NULL if none
2421 * available
2422 */
2423 struct i3c_i2c_device_desc *i3c_i2c_device_desc_alloc(void);
2424
2425 /**
2426 * @brief Free memory from a i3c i2c device descriptor
2427 *
2428 * This frees memory from a mem slab of a i3c_i2c_device_desc
2429 *
2430 * @param desc Pointer to allocated i3c_i2c_device_desc
2431 */
2432 void i3c_i2c_device_desc_free(struct i3c_i2c_device_desc *desc);
2433
2434 /**
2435 * @brief Report if the i3c i2c device descriptor was from a mem slab
2436 *
2437 * This reports if the i3c_i2c_device_desc was from a memory slab
2438 *
2439 * @param desc Pointer to a i3c_i2c_device_desc
2440 *
2441 * @return True if from a memory slab, False if not
2442 */
2443 bool i3c_i2c_device_desc_in_pool(struct i3c_i2c_device_desc *desc);
2444
2445 #else
2446
i3c_i2c_device_desc_alloc(void)2447 static inline struct i3c_i2c_device_desc *i3c_i2c_device_desc_alloc(void)
2448 {
2449 return NULL;
2450 }
2451
i3c_i2c_device_desc_free(struct i3c_i2c_device_desc * desc)2452 static inline void i3c_i2c_device_desc_free(struct i3c_i2c_device_desc *desc)
2453 {
2454 ARG_UNUSED(desc);
2455 }
2456
i3c_i2c_device_desc_in_pool(struct i3c_i2c_device_desc * desc)2457 static inline bool i3c_i2c_device_desc_in_pool(struct i3c_i2c_device_desc *desc)
2458 {
2459 ARG_UNUSED(desc);
2460 return false;
2461 }
2462
2463 #endif /* CONFIG_I3C_I2C_NUM_OF_DESC_MEM_SLABS > 0 */
2464
2465 #if defined(CONFIG_I3C_RTIO) || defined(__DOXYGEN__)
2466
2467 struct i3c_iodev_data {
2468 const struct device *bus;
2469 const struct i3c_device_id dev_id;
2470 };
2471
2472 /**
2473 * @brief Fallback submit implementation
2474 *
2475 * This implementation will schedule a blocking I3C transaction on the bus via the RTIO work
2476 * queue. It is only used if the I3C driver did not implement the iodev_submit function.
2477 *
2478 * @param dev Pointer to the device structure for an I3C controller driver.
2479 * @param iodev_sqe Prepared submissions queue entry connected to an iodev
2480 * defined by I3C_DT_IODEV_DEFINE.
2481 */
2482 void i3c_iodev_submit_fallback(const struct device *dev, struct rtio_iodev_sqe *iodev_sqe);
2483
2484 /**
2485 * @brief Submit request(s) to an I3C device with RTIO
2486 *
2487 * @param iodev_sqe Prepared submissions queue entry connected to an iodev
2488 * defined by I3C_DT_IODEV_DEFINE.
2489 */
i3c_iodev_submit(struct rtio_iodev_sqe * iodev_sqe)2490 static inline void i3c_iodev_submit(struct rtio_iodev_sqe *iodev_sqe)
2491 {
2492 const struct i3c_iodev_data *data =
2493 (const struct i3c_iodev_data *)iodev_sqe->sqe.iodev->data;
2494 const struct i3c_driver_api *api = (const struct i3c_driver_api *)data->bus->api;
2495
2496 if (api->iodev_submit == NULL) {
2497 rtio_iodev_sqe_err(iodev_sqe, -ENOSYS);
2498 return;
2499 }
2500 api->iodev_submit(data->bus, iodev_sqe);
2501 }
2502
2503 extern const struct rtio_iodev_api i3c_iodev_api;
2504
2505 /**
2506 * @brief Define an iodev for a given dt node on the bus
2507 *
2508 * These do not need to be shared globally but doing so
2509 * will save a small amount of memory.
2510 *
2511 * @param name Symbolic name of the iodev to define
2512 * @param node_id Devicetree node identifier
2513 */
2514 #define I3C_DT_IODEV_DEFINE(name, node_id) \
2515 const struct i3c_iodev_data _i3c_iodev_data_##name = { \
2516 .bus = DEVICE_DT_GET(DT_BUS(node_id)), \
2517 .dev_id = I3C_DEVICE_ID_DT(node_id), \
2518 }; \
2519 RTIO_IODEV_DEFINE(name, &i3c_iodev_api, (void *)&_i3c_iodev_data_##name)
2520
2521 /**
2522 * @brief Copy the i3c_msgs into a set of RTIO requests
2523 *
2524 * @param r RTIO context
2525 * @param iodev RTIO IODev to target for the submissions
2526 * @param msgs Array of messages
2527 * @param num_msgs Number of i3c msgs in array
2528 *
2529 * @retval sqe Last submission in the queue added
2530 * @retval NULL Not enough memory in the context to copy the requests
2531 */
2532 struct rtio_sqe *i3c_rtio_copy(struct rtio *r,
2533 struct rtio_iodev *iodev,
2534 const struct i3c_msg *msgs,
2535 uint8_t num_msgs);
2536
2537 #endif /* CONFIG_I3C_RTIO */
2538
2539 /*
2540 * This needs to be after declaration of struct i3c_driver_api,
2541 * or else compiler complains about undefined type inside
2542 * the static inline API wrappers.
2543 */
2544 #include <zephyr/drivers/i3c/target_device.h>
2545
2546 /*
2547 * Include High-Data-Rate (HDR) inline helper functions
2548 */
2549 #include <zephyr/drivers/i3c/hdr_ddr.h>
2550
2551 #ifdef __cplusplus
2552 }
2553 #endif
2554
2555 /**
2556 * @}
2557 */
2558
2559 #include <zephyr/syscalls/i3c.h>
2560
2561 #endif /* ZEPHYR_INCLUDE_DRIVERS_I3C_H_ */
2562