1 /*
2 * Copyright 2022 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #ifndef ZEPHYR_INCLUDE_DRIVERS_I3C_H_
8 #define ZEPHYR_INCLUDE_DRIVERS_I3C_H_
9
10 /**
11 * @brief I3C Interface
12 * @defgroup i3c_interface I3C Interface
13 * @ingroup io_interfaces
14 * @{
15 */
16
17 #include <zephyr/types.h>
18 #include <zephyr/device.h>
19
20 #include <zephyr/drivers/i3c/addresses.h>
21 #include <zephyr/drivers/i3c/ccc.h>
22 #include <zephyr/drivers/i3c/devicetree.h>
23 #include <zephyr/drivers/i3c/ibi.h>
24 #include <zephyr/drivers/i2c.h>
25
26 #ifdef __cplusplus
27 extern "C" {
28 #endif
29
30 /*
31 * Bus Characteristic Register (BCR)
32 * - BCR[7:6]: Device Role
33 * - 0: I3C Target
34 * - 1: I3C Controller capable
35 * - 2: Reserved
36 * - 3: Reserved
37 * - BCR[5]: Advanced Capabilities
38 * - 0: Does not support optional advanced capabilities.
39 * - 1: Supports optional advanced capabilities which
40 * can be viewed via GETCAPS CCC.
41 * - BCR[4}: Virtual Target Support
42 * - 0: Is not a virtual target.
43 * - 1: Is a virtual target.
44 * - BCR[3]: Offline Capable
45 * - 0: Will always response to I3C commands.
46 * - 1: Will not always response to I3C commands.
47 * - BCR[2]: IBI Payload
48 * - 0: No data bytes following the accepted IBI.
49 * - 1: One data byte (MDB, Mandatory Data Byte) follows
50 * the accepted IBI. Additional data bytes may also
51 * follows.
52 * - BCR[1]: IBI Request Capable
53 * - 0: Not capable
54 * - 1: Capable
55 * - BCR[0]: Max Data Speed Limitation
56 * - 0: No Limitation
57 * - 1: Limitation obtained via GETMXDS CCC.
58 */
59 #define I3C_BCR_MAX_DATA_SPEED_LIMIT BIT(0)
60 #define I3C_BCR_IBI_REQUEST_CAPABLE BIT(1)
61 #define I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE BIT(2)
62 #define I3C_BCR_OFFLINE_CAPABLE BIT(3)
63 #define I3C_BCR_VIRTUAL_TARGET BIT(4)
64 #define I3C_BCR_ADV_CAPABILITIES BIT(5)
65
66 #define I3C_BCR_DEVICE_ROLE_I3C_TARGET 0U
67 #define I3C_BCR_DEVICE_ROLE_I3C_CONTROLLER_CAPABLE 1U
68
69 #define I3C_BCR_DEVICE_ROLE_SHIFT 6U
70 #define I3C_BCR_DEVICE_ROLE_MASK (0x03U << I3C_BCR_DEVICE_ROLE_SHIFT)
71
72 #define I3C_BCR_DEVICE_ROLE(bcr) \
73 (((bcr) & I3C_BCR_DEVICE_ROLE_MASK) >> I3C_BCR_DEVICE_ROLE_SHIFT)
74
75 /*
76 * Legacy Virtual Register (LVR)
77 * - LVR[7:5]: I2C device index:
78 * - 0: I2C device has a 50 ns spike filter where
79 * it is not affected by high frequency on SCL.
80 * - 1: I2C device does not have a 50 ns spike filter
81 * but can work with high frequency on SCL.
82 * - 2: I2C device does not have a 50 ns spike filter
83 * and cannot work with high frequency on SCL.
84 * - LVR[4]: I2C mode indicator:
85 * - 0: FM+ mode
86 * - 1: FM mode
87 * - LVR[3:0]: Reserved.
88 */
89 #define I3C_DCR_I2C_FM_PLUS_MODE 0
90 #define I3C_DCR_I2C_FM_MODE 1
91
92 #define I3C_DCR_I2C_MODE_SHIFT 4
93 #define I3C_DCR_I2C_MODE_MASK BIT(4)
94
95 #define I3C_DCR_I2C_MODE(dcr) \
96 (((mode) & I3C_DCR_I2C_MODE_MASK) >> I3C_DCR_I2C_MODE_SHIFT)
97
98 #define I3C_DCR_I2C_DEV_IDX_0 0
99 #define I3C_DCR_I2C_DEV_IDX_1 1
100 #define I3C_DCR_I2C_DEV_IDX_2 2
101
102 #define I3C_DCR_I2C_DEV_IDX_SHIFT 5
103 #define I3C_DCR_I2C_DEV_IDX_MASK (0x07U << I3C_DCR_I2C_DEV_IDX_SHIFT)
104
105 #define I3C_DCR_I2C_DEV_IDX(dcr) \
106 (((dcr) & I3C_DCR_I2C_DEV_IDX_MASK) >> I3C_DCR_I2C_DEV_IDX_SHIFT)
107
108 /**
109 * @brief I3C bus mode
110 */
111 enum i3c_bus_mode {
112 /** Only I3C devices are on the bus. */
113 I3C_BUS_MODE_PURE,
114
115 /**
116 * Both I3C and legacy I2C devices are on the bus.
117 * The I2C devices have 50ns spike filter on SCL.
118 */
119 I3C_BUS_MODE_MIXED_FAST,
120
121 /**
122 * Both I3C and legacy I2C devices are on the bus.
123 * The I2C devices do not have 50ns spike filter on SCL
124 * and can tolerate maximum SDR SCL clock frequency.
125 */
126 I3C_BUS_MODE_MIXED_LIMITED,
127
128 /**
129 * Both I3C and legacy I2C devices are on the bus.
130 * The I2C devices do not have 50ns spike filter on SCL
131 * but cannot tolerate maximum SDR SCL clock frequency.
132 */
133 I3C_BUS_MODE_MIXED_SLOW,
134
135 I3C_BUS_MODE_MAX = I3C_BUS_MODE_MIXED_SLOW,
136 I3C_BUS_MODE_INVALID,
137 };
138
139 /**
140 * @brief I2C bus speed under I3C bus.
141 *
142 * Only FM and FM+ modes are supported for I2C devices under I3C bus.
143 */
144 enum i3c_i2c_speed_type {
145 /** I2C FM mode */
146 I3C_I2C_SPEED_FM,
147
148 /** I2C FM+ mode */
149 I3C_I2C_SPEED_FMPLUS,
150
151 I3C_I2C_SPEED_MAX = I3C_I2C_SPEED_FMPLUS,
152 I3C_I2C_SPEED_INVALID,
153 };
154
155 /**
156 * @brief I3C data rate
157 *
158 * I3C data transfer rate defined by the I3C specification.
159 */
160 enum i3c_data_rate {
161 /** Single Data Rate messaging */
162 I3C_DATA_RATE_SDR,
163
164 /** High Data Rate - Double Data Rate messaging */
165 I3C_DATA_RATE_HDR_DDR,
166
167 /** High Data Rate - Ternary Symbol Legacy-inclusive-Bus */
168 I3C_DATA_RATE_HDR_TSL,
169
170 /** High Data Rate - Ternary Symbol for Pure Bus */
171 I3C_DATA_RATE_HDR_TSP,
172
173 /** High Data Rate - Bulk Transport */
174 I3C_DATA_RATE_HDR_BT,
175
176 I3C_DATA_RATE_MAX = I3C_DATA_RATE_HDR_BT,
177 I3C_DATA_RATE_INVALID,
178 };
179
180 /**
181 * @brief I3C SDR Controller Error Codes
182 *
183 * These are error codes defined by the I3C specification.
184 *
185 * @c I3C_ERROR_CE_UNKNOWN and @c I3C_ERROR_CE_NONE are not
186 * official error codes according to the specification.
187 * These are there simply to aid in error handling during
188 * interactions with the I3C drivers and subsystem.
189 */
190 enum i3c_sdr_controller_error_codes {
191 /** Transaction after sending CCC */
192 I3C_ERROR_CE0,
193
194 /** Monitoring Error */
195 I3C_ERROR_CE1,
196
197 /** No response to broadcast address (0x7E) */
198 I3C_ERROR_CE2,
199
200 /** Failed Controller Handoff */
201 I3C_ERROR_CE3,
202
203 /** Unknown error (not official error code) */
204 I3C_ERROR_CE_UNKNOWN,
205
206 /** No error (not official error code) */
207 I3C_ERROR_CE_NONE,
208
209 I3C_ERROR_CE_MAX = I3C_ERROR_CE_UNKNOWN,
210 I3C_ERROR_CE_INVALID,
211 };
212
213 /**
214 * @brief I3C SDR Target Error Codes
215 *
216 * These are error codes defined by the I3C specification.
217 *
218 * @c I3C_ERROR_TE_UNKNOWN and @c I3C_ERROR_TE_NONE are not
219 * official error codes according to the specification.
220 * These are there simply to aid in error handling during
221 * interactions with the I3C drivers and subsystem.
222 */
223 enum i3c_sdr_target_error_codes {
224 /**
225 * Invalid Broadcast Address or
226 * Dynamic Address after DA assignment
227 */
228 I3C_ERROR_TE0,
229
230 /** CCC Code */
231 I3C_ERROR_TE1,
232
233 /** Write Data */
234 I3C_ERROR_TE2,
235
236 /** Assigned Address during Dynamic Address Arbitration */
237 I3C_ERROR_TE3,
238
239 /** 0x7E/R missing after RESTART during Dynamic Address Arbitration */
240 I3C_ERROR_TE4,
241
242 /** Transaction after detecting CCC */
243 I3C_ERROR_TE5,
244
245 /** Monitoring Error */
246 I3C_ERROR_TE6,
247
248 /** Dead Bus Recovery */
249 I3C_ERROR_DBR,
250
251 /** Unknown error (not official error code) */
252 I3C_ERROR_TE_UNKNOWN,
253
254 /** No error (not official error code) */
255 I3C_ERROR_TE_NONE,
256
257 I3C_ERROR_TE_MAX = I3C_ERROR_TE_UNKNOWN,
258 I3C_ERROR_TE_INVALID,
259 };
260
261 /*
262 * I3C_MSG_* are I3C Message flags.
263 */
264
265 /** Write message to I3C bus. */
266 #define I3C_MSG_WRITE (0U << 0U)
267
268 /** Read message from I3C bus. */
269 #define I3C_MSG_READ BIT(0)
270
271 /** @cond INTERNAL_HIDDEN */
272 #define I3C_MSG_RW_MASK BIT(0)
273 /** @endcond */
274
275 /** Send STOP after this message. */
276 #define I3C_MSG_STOP BIT(1)
277
278 /**
279 * RESTART I3C transaction for this message.
280 *
281 * @note Not all I3C drivers have or require explicit support for this
282 * feature. Some drivers require this be present on a read message
283 * that follows a write, or vice-versa. Some drivers will merge
284 * adjacent fragments into a single transaction using this flag; some
285 * will not.
286 */
287 #define I3C_MSG_RESTART BIT(2)
288
289 /** Transfer use HDR mode */
290 #define I3C_MSG_HDR BIT(3)
291
292 /** Skip I3C broadcast header. Private Transfers only. */
293 #define I3C_MSG_NBCH BIT(4)
294
295 /** I3C HDR Mode 0 */
296 #define I3C_MSG_HDR_MODE0 BIT(0)
297
298 /** I3C HDR Mode 1 */
299 #define I3C_MSG_HDR_MODE1 BIT(1)
300
301 /** I3C HDR Mode 2 */
302 #define I3C_MSG_HDR_MODE2 BIT(2)
303
304 /** I3C HDR Mode 3 */
305 #define I3C_MSG_HDR_MODE3 BIT(3)
306
307 /** I3C HDR Mode 4 */
308 #define I3C_MSG_HDR_MODE4 BIT(4)
309
310 /** I3C HDR Mode 5 */
311 #define I3C_MSG_HDR_MODE5 BIT(5)
312
313 /** I3C HDR Mode 6 */
314 #define I3C_MSG_HDR_MODE6 BIT(6)
315
316 /** I3C HDR Mode 7 */
317 #define I3C_MSG_HDR_MODE7 BIT(7)
318
319 /** I3C HDR-DDR (Double Data Rate) */
320 #define I3C_MSG_HDR_DDR I3C_MSG_HDR_MODE0
321
322 /** I3C HDR-TSP (Ternary Symbol Pure-bus) */
323 #define I3C_MSG_HDR_TSP I3C_MSG_HDR_MODE1
324
325 /** I3C HDR-TSL (Ternary Symbol Legacy-inclusive-bus) */
326 #define I3C_MSG_HDR_TSL I3C_MSG_HDR_MODE2
327
328 /** I3C HDR-BT (Bulk Transport) */
329 #define I3C_MSG_HDR_BT I3C_MSG_HDR_MODE3
330
331 /**
332 * @brief One I3C Message.
333 *
334 * This defines one I3C message to transact on the I3C bus.
335 *
336 * @note Some of the configurations supported by this API may not be
337 * supported by specific SoC I3C hardware implementations, in
338 * particular features related to bus transactions intended to read or
339 * write data from different buffers within a single transaction.
340 * Invocations of i3c_transfer() may not indicate an error when an
341 * unsupported configuration is encountered. In some cases drivers
342 * will generate separate transactions for each message fragment, with
343 * or without presence of @ref I3C_MSG_RESTART in #flags.
344 */
345 struct i3c_msg {
346 /** Data buffer in bytes */
347 uint8_t *buf;
348
349 /** Length of buffer in bytes */
350 uint32_t len;
351
352 /** Flags for this message */
353 uint8_t flags;
354
355 /**
356 * HDR mode (@c I3C_MSG_HDR_MODE*) for transfer
357 * if any @c I3C_MSG_HDR_* is set in @c flags.
358 *
359 * Use SDR mode if none is set.
360 */
361 uint8_t hdr_mode;
362 };
363
364 /**
365 * @brief Type of configuration being passed to configure function.
366 */
367 enum i3c_config_type {
368 I3C_CONFIG_CONTROLLER,
369 I3C_CONFIG_TARGET,
370 I3C_CONFIG_CUSTOM,
371 };
372
373 /**
374 * @brief Configuration parameters for I3C hardware to act as controller.
375 */
376 struct i3c_config_controller {
377 /**
378 * True if the controller is to be the secondary controller
379 * of the bus. False to be the primary controller.
380 */
381 bool is_secondary;
382
383 struct {
384 /** SCL frequency (in Hz) for I3C transfers. */
385 uint32_t i3c;
386
387 /** SCL frequency (in Hz) for I2C transfers. */
388 uint32_t i2c;
389 } scl;
390
391 /**
392 * Bit mask of supported HDR modes (0 - 7).
393 *
394 * This can be used to enable or disable HDR mode
395 * supported by the hardware at runtime.
396 */
397 uint8_t supported_hdr;
398 };
399
400 /**
401 * @brief Custom I3C configuration parameters.
402 *
403 * This can be used to configure the I3C hardware on parameters
404 * not covered by @see i3c_config_controller or @see i3c_config_target.
405 * Mostly used to configure vendor specific parameters of the I3C
406 * hardware.
407 */
408 struct i3c_config_custom {
409 /** ID of the configuration parameter. */
410 uint32_t id;
411
412 union {
413 /** Value of configuration parameter. */
414 uintptr_t val;
415
416 /**
417 * Pointer to configuration parameter.
418 *
419 * Mainly used to pointer to a struct that
420 * the device driver understands.
421 */
422 void *ptr;
423 };
424 };
425
426 /**
427 * @cond INTERNAL_HIDDEN
428 *
429 * These are for internal use only, so skip these in
430 * public documentation.
431 */
432 struct i3c_device_desc;
433 struct i3c_device_id;
434 struct i3c_i2c_device_desc;
435 struct i3c_target_config;
436
437 __subsystem struct i3c_driver_api {
438 /**
439 * For backward compatibility to I2C API.
440 *
441 * @see i2c_driver_api for more information.
442 *
443 * (DO NOT MOVE! Must be at the beginning.)
444 */
445 struct i2c_driver_api i2c_api;
446
447 /**
448 * Configure the I3C hardware.
449 *
450 * @see i3c_configure
451 *
452 * @param dev Pointer to controller device driver instance.
453 * @param type Type of configuration parameters being passed
454 * in @p config.
455 * @param config Pointer to the configuration parameters.
456 *
457 * @return @see i3c_configure
458 */
459 int (*configure)(const struct device *dev,
460 enum i3c_config_type type, void *config);
461
462 /**
463 * Get configuration of the I3C hardware.
464 *
465 * @see i3c_config_get
466 *
467 * @param[in] dev Pointer to controller device driver instance.
468 * @param[in] type Type of configuration parameters being passed
469 * in @p config.
470 * @param[in, out] config Pointer to the configuration parameters.
471 *
472 * @return @see i3c_config_get
473 */
474 int (*config_get)(const struct device *dev,
475 enum i3c_config_type type, void *config);
476
477 /**
478 * Perform bus recovery
479 *
480 * Controller only API.
481 *
482 * @see i3c_recover_bus
483 *
484 * @param dev Pointer to controller device driver instance.
485 *
486 * @return @see i3c_recover_bus
487 */
488 int (*recover_bus)(const struct device *dev);
489
490 /**
491 * I3C Device Attach
492 *
493 * Optional API.
494 *
495 * @see i3c_attach_i3c_device
496 *
497 * @param dev Pointer to controller device driver instance.
498 * @param target Pointer to target device descriptor.
499 * @param addr Address to attach with
500 *
501 * @return @see i3c_attach_i3c_device
502 */
503 int (*attach_i3c_device)(const struct device *dev,
504 struct i3c_device_desc *target,
505 uint8_t addr);
506
507 /**
508 * I3C Address Update
509 *
510 * Optional API.
511 *
512 * @see i3c_reattach_i3c_device
513 *
514 * @param dev Pointer to controller device driver instance.
515 * @param target Pointer to target device descriptor.
516 * @param old_dyn_addr Old dynamic address
517 *
518 * @return @see i3c_reattach_i3c_device
519 */
520 int (*reattach_i3c_device)(const struct device *dev,
521 struct i3c_device_desc *target,
522 uint8_t old_dyn_addr);
523
524 /**
525 * I3C Device Detach
526 *
527 * Optional API.
528 *
529 * @see i3c_detach_i3c_device
530 *
531 * @param dev Pointer to controller device driver instance.
532 * @param target Pointer to target device descriptor.
533 *
534 * @return @see i3c_detach_i3c_device
535 */
536 int (*detach_i3c_device)(const struct device *dev,
537 struct i3c_device_desc *target);
538
539 /**
540 * I2C Device Attach
541 *
542 * Optional API.
543 *
544 * @see i3c_attach_i2c_device
545 *
546 * @param dev Pointer to controller device driver instance.
547 * @param target Pointer to target device descriptor.
548 *
549 * @return @see i3c_attach_i2c_device
550 */
551 int (*attach_i2c_device)(const struct device *dev,
552 struct i3c_i2c_device_desc *target);
553
554 /**
555 * I2C Device Detach
556 *
557 * Optional API.
558 *
559 * @see i3c_detach_i2c_device
560 *
561 * @param dev Pointer to controller device driver instance.
562 * @param target Pointer to target device descriptor.
563 *
564 * @return @see i3c_detach_i2c_device
565 */
566 int (*detach_i2c_device)(const struct device *dev,
567 struct i3c_i2c_device_desc *target);
568
569 /**
570 * Perform Dynamic Address Assignment via ENTDAA.
571 *
572 * Controller only API.
573 *
574 * @see i3c_do_daa
575 *
576 * @param dev Pointer to controller device driver instance.
577 *
578 * @return @see i3c_do_daa
579 */
580 int (*do_daa)(const struct device *dev);
581
582 /**
583 * Send Common Command Code (CCC).
584 *
585 * Controller only API.
586 *
587 * @see i3c_do_ccc
588 *
589 * @param dev Pointer to controller device driver instance.
590 * @param payload Pointer to the CCC payload.
591 *
592 * @return @see i3c_do_ccc
593 */
594 int (*do_ccc)(const struct device *dev,
595 struct i3c_ccc_payload *payload);
596
597 /**
598 * Transfer messages in I3C mode.
599 *
600 * @see i3c_transfer
601 *
602 * @param dev Pointer to controller device driver instance.
603 * @param target Pointer to target device descriptor.
604 * @param msg Pointer to I3C messages.
605 * @param num_msgs Number of messages to transfer.
606 *
607 * @return @see i3c_transfer
608 */
609 int (*i3c_xfers)(const struct device *dev,
610 struct i3c_device_desc *target,
611 struct i3c_msg *msgs,
612 uint8_t num_msgs);
613
614 /**
615 * Find a registered I3C target device.
616 *
617 * Controller only API.
618 *
619 * This returns the I3C device descriptor of the I3C device
620 * matching the incoming @p id.
621 *
622 * @param dev Pointer to controller device driver instance.
623 * @param id Pointer to I3C device ID.
624 *
625 * @return @see i3c_device_find.
626 */
627 struct i3c_device_desc *(*i3c_device_find)(const struct device *dev,
628 const struct i3c_device_id *id);
629
630 /**
631 * Raise In-Band Interrupt (IBI).
632 *
633 * Target device only API.
634 *
635 * @see i3c_ibi_request
636 *
637 * @param dev Pointer to controller device driver instance.
638 * @param request Pointer to IBI request struct.
639 *
640 * @return @see i3c_ibi_request
641 */
642 int (*ibi_raise)(const struct device *dev,
643 struct i3c_ibi *request);
644
645 /**
646 * Enable receiving IBI from a target.
647 *
648 * Controller only API.
649 *
650 * @see i3c_ibi_enable
651 *
652 * @param dev Pointer to controller device driver instance.
653 * @param target Pointer to target device descriptor.
654 *
655 * @return @see i3c_ibi_enable
656 */
657 int (*ibi_enable)(const struct device *dev,
658 struct i3c_device_desc *target);
659
660 /**
661 * Disable receiving IBI from a target.
662 *
663 * Controller only API.
664 *
665 * @see i3c_ibi_disable
666 *
667 * @param dev Pointer to controller device driver instance.
668 * @param target Pointer to target device descriptor.
669 *
670 * @return @see i3c_ibi_disable
671 */
672 int (*ibi_disable)(const struct device *dev,
673 struct i3c_device_desc *target);
674
675 /**
676 * Register config as target device of a controller.
677 *
678 * This tells the controller to act as a target device
679 * on the I3C bus.
680 *
681 * Target device only API.
682 *
683 * @see i3c_target_register
684 *
685 * @param dev Pointer to the controller device driver instance.
686 * @param cfg I3C target device configuration
687 *
688 * @return @see i3c_target_register
689 */
690 int (*target_register)(const struct device *dev,
691 struct i3c_target_config *cfg);
692
693 /**
694 * Unregister config as target device of a controller.
695 *
696 * This tells the controller to stop acting as a target device
697 * on the I3C bus.
698 *
699 * Target device only API.
700 *
701 * @see i3c_target_unregister
702 *
703 * @param dev Pointer to the controller device driver instance.
704 * @param cfg I3C target device configuration
705 *
706 * @return @see i3c_target_unregister
707 */
708 int (*target_unregister)(const struct device *dev,
709 struct i3c_target_config *cfg);
710
711 /**
712 * Write to the TX FIFO
713 *
714 * This writes to the target tx fifo
715 *
716 * Target device only API.
717 *
718 * @see i3c_target_tx_write
719 *
720 * @param dev Pointer to the controller device driver instance.
721 * @param buf Pointer to the buffer
722 * @param len Length of the buffer
723 *
724 * @return @see i3c_target_tx_write
725 */
726 int (*target_tx_write)(const struct device *dev,
727 uint8_t *buf, uint16_t len);
728 };
729
730 /**
731 * @endcond
732 */
733
734 /**
735 * @brief Structure used for matching I3C devices.
736 */
737 struct i3c_device_id {
738 /** Device Provisioned ID */
739 const uint64_t pid:48;
740 };
741
742 /**
743 * @brief Structure initializer for i3c_device_id from PID
744 *
745 * This helper macro expands to a static initializer for a <tt>struct
746 * i3c_device_id</tt> by populating the PID (Provisioned ID) field.
747 *
748 * @param pid Provisioned ID.
749 */
750 #define I3C_DEVICE_ID(pid) \
751 { \
752 .pid = pid \
753 }
754
755 /**
756 * @brief Structure describing a I3C target device.
757 *
758 * Instances of this are passed to the I3C controller device APIs,
759 * for example:
760 * - i3c_device_register() to tell the controller of a target device.
761 * - i3c_transfers() to initiate data transfers between controller and
762 * target device.
763 *
764 * Fields @c bus, @c pid and @c static_addr must be initialized by
765 * the module that implements the target device behavior prior to
766 * passing the object reference to I3C controller device APIs.
767 * @c static_addr can be zero if target device does not have static
768 * address.
769 *
770 * Field @c node should not be initialized or modified manually.
771 */
772 struct i3c_device_desc {
773 /** Private, do not modify */
774 sys_snode_t node;
775
776 /** I3C bus to which this target device is attached */
777 const struct device * const bus;
778
779 /** Device driver instance of the I3C device */
780 const struct device * const dev;
781
782 /** Device Provisioned ID */
783 const uint64_t pid:48;
784
785 /**
786 * Static address for this target device.
787 *
788 * 0 if static address is not being used, and only dynamic
789 * address is used. This means that the target device must
790 * go through ENTDAA (Dynamic Address Assignment) to get
791 * a dynamic address before it can communicate with
792 * the controller. This means SETAASA and SETDASA CCC
793 * cannot be used to set dynamic address on the target
794 * device (as both are to tell target device to use static
795 * address as dynamic address).
796 */
797 const uint8_t static_addr;
798
799 /**
800 * Initial dynamic address.
801 *
802 * This is specified in the device tree property "assigned-address"
803 * to indicate the desired dynamic address during address
804 * assignment (SETDASA and ENTDAA).
805 *
806 * 0 if there is no preference.
807 */
808 const uint8_t init_dynamic_addr;
809
810 /**
811 * Dynamic Address for this target device used for communication.
812 *
813 * This is to be set by the controller driver in one of
814 * the following situations:
815 * - During Dynamic Address Assignment (during ENTDAA)
816 * - Reset Dynamic Address Assignment (RSTDAA)
817 * - Set All Addresses to Static Addresses (SETAASA)
818 * - Set New Dynamic Address (SETNEWDA)
819 * - Set Dynamic Address from Static Address (SETDASA)
820 *
821 * 0 if address has not been assigned.
822 */
823 uint8_t dynamic_addr;
824
825 #if defined(CONFIG_I3C_USE_GROUP_ADDR) || defined(__DOXYGEN__)
826 /**
827 * Group address for this target device. Set during:
828 * - Reset Group Address(es) (RSTGRPA)
829 * - Set Group Address (SETGRPA)
830 *
831 * 0 if group address has not been assigned.
832 */
833 uint8_t group_addr;
834 #endif /* CONFIG_I3C_USE_GROUP_ADDR */
835
836 /**
837 * Bus Characteristic Register (BCR)
838 * - BCR[7:6]: Device Role
839 * - 0: I3C Target
840 * - 1: I3C Controller capable
841 * - 2: Reserved
842 * - 3: Reserved
843 * - BCR[5]: Advanced Capabilities
844 * - 0: Does not support optional advanced capabilities.
845 * - 1: Supports optional advanced capabilities which
846 * can be viewed via GETCAPS CCC.
847 * - BCR[4}: Virtual Target Support
848 * - 0: Is not a virtual target.
849 * - 1: Is a virtual target.
850 * - BCR[3]: Offline Capable
851 * - 0: Will always response to I3C commands.
852 * - 1: Will not always response to I3C commands.
853 * - BCR[2]: IBI Payload
854 * - 0: No data bytes following the accepted IBI.
855 * - 1: One data byte (MDB, Mandatory Data Byte) follows
856 * the accepted IBI. Additional data bytes may also
857 * follows.
858 * - BCR[1]: IBI Request Capable
859 * - 0: Not capable
860 * - 1: Capable
861 * - BCR[0]: Max Data Speed Limitation
862 * - 0: No Limitation
863 * - 1: Limitation obtained via GETMXDS CCC.
864 */
865 uint8_t bcr;
866
867 /**
868 * Device Characteristic Register (DCR)
869 *
870 * Describes the type of device. Refer to official documentation
871 * on what this number means.
872 */
873 uint8_t dcr;
874
875 struct {
876 /** Maximum Read Speed */
877 uint8_t maxrd;
878
879 /** Maximum Write Speed */
880 uint8_t maxwr;
881
882 /** Maximum Read turnaround time in microseconds. */
883 uint32_t max_read_turnaround;
884 } data_speed;
885
886 struct {
887 /** Maximum Read Length */
888 uint16_t mrl;
889
890 /** Maximum Write Length */
891 uint16_t mwl;
892
893 /** Maximum IBI Payload Size. Valid only if BCR[2] is 1. */
894 uint8_t max_ibi;
895 } data_length;
896
897 /** Private data by the controller to aid in transactions. Do not modify. */
898 void *controller_priv;
899
900 #if defined(CONFIG_I3C_USE_IBI) || defined(__DOXYGEN__)
901 /**
902 * In-Band Interrupt (IBI) callback.
903 */
904 i3c_target_ibi_cb_t ibi_cb;
905 #endif /* CONFIG_I3C_USE_IBI */
906 };
907
908 /**
909 * @brief Structure describing a I2C device on I3C bus.
910 *
911 * Instances of this are passed to the I3C controller device APIs,
912 * for example:
913 * () i3c_i2c_device_register() to tell the controller of an I2C device.
914 * () i3c_i2c_transfers() to initiate data transfers between controller
915 * and I2C device.
916 *
917 * Fields other than @c node must be initialized by the module that
918 * implements the device behavior prior to passing the object
919 * reference to I3C controller device APIs.
920 */
921 struct i3c_i2c_device_desc {
922 /** Private, do not modify */
923 sys_snode_t node;
924
925 /** I3C bus to which this I2C device is attached */
926 const struct device *bus;
927
928 /** Static address for this I2C device. */
929 const uint16_t addr;
930
931 /**
932 * Legacy Virtual Register (LVR)
933 * - LVR[7:5]: I2C device index:
934 * - 0: I2C device has a 50 ns spike filter where
935 * it is not affected by high frequency on SCL.
936 * - 1: I2C device does not have a 50 ns spike filter
937 * but can work with high frequency on SCL.
938 * - 2: I2C device does not have a 50 ns spike filter
939 * and cannot work with high frequency on SCL.
940 * - LVR[4]: I2C mode indicator:
941 * - 0: FM+ mode
942 * - 1: FM mode
943 * - LVR[3:0]: Reserved.
944 */
945 const uint8_t lvr;
946
947 /** Private data by the controller to aid in transactions. Do not modify. */
948 void *controller_priv;
949 };
950
951 /**
952 * @brief Structure for describing attached devices for a controller.
953 *
954 * This contains slists of attached I3C and I2C devices.
955 *
956 * This is a helper struct that can be used by controller device
957 * driver to aid in device management.
958 */
959 struct i3c_dev_attached_list {
960 /**
961 * Address slots:
962 * - Aid in dynamic address assignment.
963 * - Quick way to find out if a target address is
964 * a I3C or I2C device.
965 */
966 struct i3c_addr_slots addr_slots;
967
968 struct {
969 /**
970 * Linked list of attached I3C devices.
971 */
972 sys_slist_t i3c;
973
974 /**
975 * Linked list of attached I2C devices.
976 */
977 sys_slist_t i2c;
978 } devices;
979 };
980
981 /**
982 * @brief Structure for describing known devices for a controller.
983 *
984 * This contains arrays of known I3C and I2C devices.
985 *
986 * This is a helper struct that can be used by controller device
987 * driver to aid in device management.
988 */
989 struct i3c_dev_list {
990 /**
991 * Pointer to array of known I3C devices.
992 */
993 struct i3c_device_desc * const i3c;
994
995 /**
996 * Pointer to array of known I2C devices.
997 */
998 struct i3c_i2c_device_desc * const i2c;
999
1000 /**
1001 * Number of I3C devices in array.
1002 */
1003 const uint8_t num_i3c;
1004
1005 /**
1006 * Number of I2C devices in array.
1007 */
1008 const uint8_t num_i2c;
1009 };
1010
1011 /**
1012 * This structure is common to all I3C drivers and is expected to be
1013 * the first element in the object pointed to by the config field
1014 * in the device structure.
1015 */
1016 struct i3c_driver_config {
1017 /** I3C/I2C device list struct. */
1018 struct i3c_dev_list dev_list;
1019 };
1020
1021 /**
1022 * This structure is common to all I3C drivers and is expected to be the first
1023 * element in the driver's struct driver_data declaration.
1024 */
1025 struct i3c_driver_data {
1026 /** Controller Configuration */
1027 struct i3c_config_controller ctrl_config;
1028
1029 /** Attached I3C/I2C devices and addresses */
1030 struct i3c_dev_attached_list attached_dev;
1031 };
1032
1033 /**
1034 * @brief Find a I3C target device descriptor by ID.
1035 *
1036 * This finds the I3C target device descriptor in the device list
1037 * matching the provided ID struct (@p id).
1038 *
1039 * @param dev_list Pointer to the device list struct.
1040 * @param id Pointer to I3C device ID struct.
1041 *
1042 * @return Pointer the the I3C target device descriptor, or
1043 * NULL if none is found.
1044 */
1045 struct i3c_device_desc *i3c_dev_list_find(const struct i3c_dev_list *dev_list,
1046 const struct i3c_device_id *id);
1047
1048 /**
1049 * @brief Find a I3C target device descriptor by dynamic address.
1050 *
1051 * This finds the I3C target device descriptor in the attached
1052 * device list matching the dynamic address (@p addr)
1053 *
1054 * @param dev_list Pointer to the device list struct.
1055 * @param addr Dynamic address to be matched.
1056 *
1057 * @return Pointer the the I3C target device descriptor, or
1058 * NULL if none is found.
1059 */
1060 struct i3c_device_desc *i3c_dev_list_i3c_addr_find(struct i3c_dev_attached_list *dev_list,
1061 uint8_t addr);
1062
1063 /**
1064 * @brief Find a I2C target device descriptor by address.
1065 *
1066 * This finds the I2C target device descriptor in the attached
1067 * device list matching the address (@p addr)
1068 *
1069 * @param dev_list Pointer to the device list struct.
1070 * @param addr Address to be matched.
1071 *
1072 * @return Pointer the the I2C target device descriptor, or
1073 * NULL if none is found.
1074 */
1075 struct i3c_i2c_device_desc *i3c_dev_list_i2c_addr_find(struct i3c_dev_attached_list *dev_list,
1076 uint16_t addr);
1077
1078 /**
1079 * @brief Helper function to find the default address an i3c device is attached with
1080 *
1081 * This is a helper function to find the default address the
1082 * device will be loaded with. This could be either it's static
1083 * address, a requested dynamic address, or just a dynamic address
1084 * that is available
1085 * @param[in] target The pointer of the device descriptor
1086 * @param[out] addr Address to be assigned to target device.
1087 *
1088 * @retval 0 if successful.
1089 * @retval -EINVAL if the expected default address is already in use
1090 */
1091 int i3c_determine_default_addr(struct i3c_device_desc *target, uint8_t *addr);
1092
1093 /**
1094 * @brief Helper function to find a usable address during ENTDAA.
1095 *
1096 * This is a helper function to find a usable address during
1097 * Dynamic Address Assignment. Given the PID (@p pid), it will
1098 * search through the device list for the matching device
1099 * descriptor. If the device descriptor indicates that there is
1100 * a preferred address (i.e. assigned-address in device tree,
1101 * @see i3c_device_desc::init_dynamic_addr), this preferred
1102 * address will be returned if this address is still available.
1103 * If it is not available, another free address will be returned.
1104 *
1105 * If @p must_match is true, the PID (@p pid) must match
1106 * one of the device in the device list.
1107 *
1108 * If @p must_match is false, this will return an arbitrary
1109 * address. This is useful when not all devices are described in
1110 * device tree. Or else, the DAA process cannot proceed since
1111 * there is no address to be assigned.
1112 *
1113 * If @p assigned_okay is true, it will return the same address
1114 * already assigned to the device
1115 * (@see i3c_device_desc::dynamic_addr). If no address has been
1116 * assigned, it behaves as if @p assigned_okay is false.
1117 * This is useful for assigning the same address to the same
1118 * device (for example, hot-join after device coming back from
1119 * suspend).
1120 *
1121 * If @p assigned_okay is false, the device cannot have an address
1122 * assigned already (that @see i3c_device_desc::dynamic_addr is not
1123 * zero). This is mainly used during the initial DAA.
1124 *
1125 * @param[in] addr_slots Pointer to address slots struct.
1126 * @param[in] dev_list Pointer to the device list struct.
1127 * @param[in] pid Provisioned ID of device to be assigned address.
1128 * @param[in] must_match True if PID must match devices in
1129 * the device list. False otherwise.
1130 * @param[in] assigned_okay True if it is okay to return the
1131 * address already assigned to the target
1132 * matching the PID (@p pid).
1133 * @param[out] target Store the pointer of the device descriptor
1134 * if it matches the incoming PID (@p pid).
1135 * @param[out] addr Address to be assigned to target device.
1136 *
1137 * @retval 0 if successful.
1138 * @retval -ENODEV if no device matches the PID (@p pid) in
1139 * the device list and @p must_match is true.
1140 * @retval -EINVAL if the device matching PID (@p pid) already
1141 * has an address assigned or invalid function
1142 * arguments.
1143 */
1144 int i3c_dev_list_daa_addr_helper(struct i3c_addr_slots *addr_slots,
1145 const struct i3c_dev_list *dev_list,
1146 uint64_t pid, bool must_match,
1147 bool assigned_okay,
1148 struct i3c_device_desc **target,
1149 uint8_t *addr);
1150
1151 /**
1152 * @brief Configure the I3C hardware.
1153 *
1154 * @param dev Pointer to controller device driver instance.
1155 * @param type Type of configuration parameters being passed
1156 * in @p config.
1157 * @param config Pointer to the configuration parameters.
1158 *
1159 * @retval 0 If successful.
1160 * @retval -EINVAL If invalid configure parameters.
1161 * @retval -EIO General Input/Output errors.
1162 * @retval -ENOSYS If not implemented.
1163 */
i3c_configure(const struct device * dev,enum i3c_config_type type,void * config)1164 static inline int i3c_configure(const struct device *dev,
1165 enum i3c_config_type type, void *config)
1166 {
1167 const struct i3c_driver_api *api =
1168 (const struct i3c_driver_api *)dev->api;
1169
1170 if (api->configure == NULL) {
1171 return -ENOSYS;
1172 }
1173
1174 return api->configure(dev, type, config);
1175 }
1176
1177 /**
1178 * @brief Get configuration of the I3C hardware.
1179 *
1180 * This provides a way to get the current configuration of the I3C hardware.
1181 *
1182 * This can return cached config or probed hardware parameters, but it has to
1183 * be up to date with current configuration.
1184 *
1185 * @param[in] dev Pointer to controller device driver instance.
1186 * @param[in] type Type of configuration parameters being passed
1187 * in @p config.
1188 * @param[in,out] config Pointer to the configuration parameters.
1189 *
1190 * Note that if @p type is @c I3C_CONFIG_CUSTOM, @p config must contain
1191 * the ID of the parameter to be retrieved.
1192 *
1193 * @retval 0 If successful.
1194 * @retval -EIO General Input/Output errors.
1195 * @retval -ENOSYS If not implemented.
1196 */
i3c_config_get(const struct device * dev,enum i3c_config_type type,void * config)1197 static inline int i3c_config_get(const struct device *dev,
1198 enum i3c_config_type type, void *config)
1199 {
1200 const struct i3c_driver_api *api =
1201 (const struct i3c_driver_api *)dev->api;
1202
1203 if (api->config_get == NULL) {
1204 return -ENOSYS;
1205 }
1206
1207 return api->config_get(dev, type, config);
1208 }
1209
1210 /**
1211 * @brief Attempt bus recovery on the I3C bus.
1212 *
1213 * This routine asks the controller to attempt bus recovery.
1214 *
1215 * @retval 0 If successful.
1216 * @retval -EBUSY If bus recovery fails.
1217 * @retval -EIO General input / output error.
1218 * @retval -ENOSYS Bus recovery is not supported by the controller driver.
1219 */
i3c_recover_bus(const struct device * dev)1220 static inline int i3c_recover_bus(const struct device *dev)
1221 {
1222 const struct i3c_driver_api *api =
1223 (const struct i3c_driver_api *)dev->api;
1224
1225 if (api->recover_bus == NULL) {
1226 return -ENOSYS;
1227 }
1228
1229 return api->recover_bus(dev);
1230 }
1231
1232 /**
1233 * @brief Attach an I3C device
1234 *
1235 * Called to attach a I3C device to the addresses. This is
1236 * typically called before a SETDASA or ENTDAA to reserve
1237 * the addresses. This will also call the optional api to
1238 * update any registers within the driver if implemented.
1239 *
1240 * @warning
1241 * Use cases involving multiple writers to the i3c/i2c devices must prevent
1242 * concurrent write operations, either by preventing all writers from
1243 * being preempted or by using a mutex to govern writes to the i3c/i2c devices.
1244 *
1245 * @param target Pointer to the target device descriptor
1246 *
1247 * @retval 0 If successful.
1248 * @retval -EINVAL If address is not available or if the device
1249 * has already been attached before
1250 */
1251 int i3c_attach_i3c_device(struct i3c_device_desc *target);
1252
1253 /**
1254 * @brief Reattach I3C device
1255 *
1256 * called after every time an I3C device has its address
1257 * changed. It can be because the device has been powered
1258 * down and has lost its address, or it can happen when a
1259 * device had a static address and has been assigned a
1260 * dynamic address with SETDASA or a dynamic address has
1261 * been updated with SETNEWDA. This will also call the
1262 * optional api to update any registers within the driver
1263 * if implemented.
1264 *
1265 * @warning
1266 * Use cases involving multiple writers to the i3c/i2c devices must prevent
1267 * concurrent write operations, either by preventing all writers from
1268 * being preempted or by using a mutex to govern writes to the i3c/i2c devices.
1269 *
1270 * @param target Pointer to the target device descriptor
1271 * @param old_dyn_addr The old dynamic address of target device, 0 if
1272 * there was no old dynamic address
1273 *
1274 * @retval 0 If successful.
1275 * @retval -EINVAL If address is not available
1276 */
1277 int i3c_reattach_i3c_device(struct i3c_device_desc *target, uint8_t old_dyn_addr);
1278
1279 /**
1280 * @brief Detach I3C Device
1281 *
1282 * called to remove an I3C device and to free up the address
1283 * that it used. If it's dynamic address was not set, then it
1284 * assumed that SETDASA failed and will free it's static addr.
1285 * This will also call the optional api to update any registers
1286 * within the driver if implemented.
1287 *
1288 * @warning
1289 * Use cases involving multiple writers to the i3c/i2c devices must prevent
1290 * concurrent write operations, either by preventing all writers from
1291 * being preempted or by using a mutex to govern writes to the i3c/i2c devices.
1292 *
1293 * @param target Pointer to the target device descriptor
1294 *
1295 * @retval 0 If successful.
1296 * @retval -EINVAL If device is already detached
1297 */
1298 int i3c_detach_i3c_device(struct i3c_device_desc *target);
1299
1300 /**
1301 * @brief Attach an I2C device
1302 *
1303 * Called to attach a I2C device to the addresses. This will
1304 * also call the optional api to update any registers within
1305 * the driver if implemented.
1306 *
1307 * @warning
1308 * Use cases involving multiple writers to the i3c/i2c devices must prevent
1309 * concurrent write operations, either by preventing all writers from
1310 * being preempted or by using a mutex to govern writes to the i3c/i2c devices.
1311 *
1312 * @param target Pointer to the target device descriptor
1313 *
1314 * @retval 0 If successful.
1315 * @retval -EINVAL If address is not available or if the device
1316 * has already been attached before
1317 */
1318 int i3c_attach_i2c_device(struct i3c_i2c_device_desc *target);
1319
1320 /**
1321 * @brief Detach I2C Device
1322 *
1323 * called to remove an I2C device and to free up the address
1324 * that it used. This will also call the optional api to
1325 * update any registers within the driver if implemented.
1326 *
1327 * @warning
1328 * Use cases involving multiple writers to the i3c/i2c devices must prevent
1329 * concurrent write operations, either by preventing all writers from
1330 * being preempted or by using a mutex to govern writes to the i3c/i2c devices.
1331 *
1332 * @param target Pointer to the target device descriptor
1333 *
1334 * @retval 0 If successful.
1335 * @retval -EINVAL If device is already detached
1336 */
1337 int i3c_detach_i2c_device(struct i3c_i2c_device_desc *target);
1338
1339 /**
1340 * @brief Perform Dynamic Address Assignment on the I3C bus.
1341 *
1342 * This routine asks the controller to perform dynamic address assignment
1343 * where the controller belongs. Only the active controller of the bus
1344 * should do this.
1345 *
1346 * @note For controller driver implementation, the controller should perform
1347 * SETDASA to allow static addresses to be the dynamic addresses before
1348 * actually doing ENTDAA.
1349 *
1350 * @param dev Pointer to the device structure for the controller driver
1351 * instance.
1352 *
1353 * @retval 0 If successful.
1354 * @retval -EBUSY Bus is busy.
1355 * @retval -EIO General input / output error.
1356 * @retval -ENODEV If a provisioned ID does not match to any target devices
1357 * in the registered device list.
1358 * @retval -ENOSPC No more free addresses can be assigned to target.
1359 * @retval -ENOSYS Dynamic address assignment is not supported by
1360 * the controller driver.
1361 */
i3c_do_daa(const struct device * dev)1362 static inline int i3c_do_daa(const struct device *dev)
1363 {
1364 const struct i3c_driver_api *api =
1365 (const struct i3c_driver_api *)dev->api;
1366
1367 if (api->do_daa == NULL) {
1368 return -ENOSYS;
1369 }
1370
1371 return api->do_daa(dev);
1372 }
1373
1374 /**
1375 * @brief Send CCC to the bus.
1376 *
1377 * @param dev Pointer to the device structure for the controller driver
1378 * instance.
1379 * @param payload Pointer to the structure describing the CCC payload.
1380 *
1381 * @retval 0 If successful.
1382 * @retval -EBUSY Bus is busy.
1383 * @retval -EIO General Input / output error.
1384 * @retval -EINVAL Invalid valid set in the payload structure.
1385 * @retval -ENOSYS Not implemented.
1386 */
1387 __syscall int i3c_do_ccc(const struct device *dev,
1388 struct i3c_ccc_payload *payload);
1389
z_impl_i3c_do_ccc(const struct device * dev,struct i3c_ccc_payload * payload)1390 static inline int z_impl_i3c_do_ccc(const struct device *dev,
1391 struct i3c_ccc_payload *payload)
1392 {
1393 const struct i3c_driver_api *api =
1394 (const struct i3c_driver_api *)dev->api;
1395
1396 if (api->do_ccc == NULL) {
1397 return -ENOSYS;
1398 }
1399
1400 return api->do_ccc(dev, payload);
1401 }
1402
1403 /**
1404 * @brief Perform data transfer from the controller to a I3C target device.
1405 *
1406 * This routine provides a generic interface to perform data transfer
1407 * to a target device synchronously. Use i3c_read()/i3c_write()
1408 * for simple read or write.
1409 *
1410 * The array of message @a msgs must not be NULL. The number of
1411 * message @a num_msgs may be zero, in which case no transfer occurs.
1412 *
1413 * @note Not all scatter/gather transactions can be supported by all
1414 * drivers. As an example, a gather write (multiple consecutive
1415 * `i3c_msg` buffers all configured for `I3C_MSG_WRITE`) may be packed
1416 * into a single transaction by some drivers, but others may emit each
1417 * fragment as a distinct write transaction, which will not produce
1418 * the same behavior. See the documentation of `struct i3c_msg` for
1419 * limitations on support for multi-message bus transactions.
1420 *
1421 * @param target I3C target device descriptor.
1422 * @param msgs Array of messages to transfer.
1423 * @param num_msgs Number of messages to transfer.
1424 *
1425 * @retval 0 If successful.
1426 * @retval -EBUSY Bus is busy.
1427 * @retval -EIO General input / output error.
1428 */
1429 __syscall int i3c_transfer(struct i3c_device_desc *target,
1430 struct i3c_msg *msgs, uint8_t num_msgs);
1431
z_impl_i3c_transfer(struct i3c_device_desc * target,struct i3c_msg * msgs,uint8_t num_msgs)1432 static inline int z_impl_i3c_transfer(struct i3c_device_desc *target,
1433 struct i3c_msg *msgs, uint8_t num_msgs)
1434 {
1435 const struct i3c_driver_api *api =
1436 (const struct i3c_driver_api *)target->bus->api;
1437
1438 return api->i3c_xfers(target->bus, target, msgs, num_msgs);
1439 }
1440
1441 /**
1442 * Find a registered I3C target device.
1443 *
1444 * Controller only API.
1445 *
1446 * This returns the I3C device descriptor of the I3C device
1447 * matching the incoming @p id.
1448 *
1449 * @param dev Pointer to controller device driver instance.
1450 * @param id Pointer to I3C device ID.
1451 *
1452 * @return Pointer to I3C device descriptor, or NULL if
1453 * no I3C device found matching incoming @p id.
1454 */
1455 static inline
i3c_device_find(const struct device * dev,const struct i3c_device_id * id)1456 struct i3c_device_desc *i3c_device_find(const struct device *dev,
1457 const struct i3c_device_id *id)
1458 {
1459 const struct i3c_driver_api *api =
1460 (const struct i3c_driver_api *)dev->api;
1461
1462 if (api->i3c_device_find == NULL) {
1463 return NULL;
1464 }
1465
1466 return api->i3c_device_find(dev, id);
1467 }
1468
1469 /**
1470 * @brief Raise an In-Band Interrupt (IBI).
1471 *
1472 * This raises an In-Band Interrupt (IBI) to the active controller.
1473 *
1474 * @param dev Pointer to controller device driver instance.
1475 * @param request Pointer to the IBI request struct.
1476 *
1477 * @retval 0 if operation is successful.
1478 * @retval -EIO General input / output error.
1479 */
i3c_ibi_raise(const struct device * dev,struct i3c_ibi * request)1480 static inline int i3c_ibi_raise(const struct device *dev,
1481 struct i3c_ibi *request)
1482 {
1483 const struct i3c_driver_api *api =
1484 (const struct i3c_driver_api *)dev->api;
1485
1486 if (api->ibi_raise == NULL) {
1487 return -ENOSYS;
1488 }
1489
1490 return api->ibi_raise(dev, request);
1491 }
1492
1493 /**
1494 * @brief Enable IBI of a target device.
1495 *
1496 * This enables IBI of a target device where the IBI has already been
1497 * request.
1498 *
1499 * @param target I3C target device descriptor.
1500 *
1501 * @retval 0 If successful.
1502 * @retval -EIO General Input / output error.
1503 * @retval -ENOMEM If these is no more empty entries in
1504 * the controller's IBI table (if the controller
1505 * uses such table).
1506 */
i3c_ibi_enable(struct i3c_device_desc * target)1507 static inline int i3c_ibi_enable(struct i3c_device_desc *target)
1508 {
1509 const struct i3c_driver_api *api =
1510 (const struct i3c_driver_api *)target->bus->api;
1511
1512 if (api->ibi_enable == NULL) {
1513 return -ENOSYS;
1514 }
1515
1516 return api->ibi_enable(target->bus, target);
1517 }
1518
1519 /**
1520 * @brief Disable IBI of a target device.
1521 *
1522 * This enables IBI of a target device where the IBI has already been
1523 * request.
1524 *
1525 * @param target I3C target device descriptor.
1526 *
1527 * @retval 0 If successful.
1528 * @retval -EIO General Input / output error.
1529 * @retval -ENODEV If IBI is not previously enabled for @p target.
1530 */
i3c_ibi_disable(struct i3c_device_desc * target)1531 static inline int i3c_ibi_disable(struct i3c_device_desc *target)
1532 {
1533 const struct i3c_driver_api *api =
1534 (const struct i3c_driver_api *)target->bus->api;
1535
1536 if (api->ibi_disable == NULL) {
1537 return -ENOSYS;
1538 }
1539
1540 return api->ibi_disable(target->bus, target);
1541 }
1542
1543 /**
1544 * @brief Check if target's IBI has payload.
1545 *
1546 * This reads the BCR from the device descriptor struct to determine
1547 * whether IBI from device has payload.
1548 *
1549 * Note that BCR must have been obtained from device and
1550 * @see i3c_device_desc::bcr must be set.
1551 *
1552 * @return True if IBI has payload, false otherwise.
1553 */
i3c_ibi_has_payload(struct i3c_device_desc * target)1554 static inline int i3c_ibi_has_payload(struct i3c_device_desc *target)
1555 {
1556 return (target->bcr & I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE)
1557 == I3C_BCR_IBI_PAYLOAD_HAS_DATA_BYTE;
1558 }
1559
1560 /**
1561 * @brief Check if device is IBI capable.
1562 *
1563 * This reads the BCR from the device descriptor struct to determine
1564 * whether device is capable of IBI.
1565 *
1566 * Note that BCR must have been obtained from device and
1567 * @see i3c_device_desc::bcr must be set.
1568 *
1569 * @return True if IBI has payload, false otherwise.
1570 */
i3c_device_is_ibi_capable(struct i3c_device_desc * target)1571 static inline int i3c_device_is_ibi_capable(struct i3c_device_desc *target)
1572 {
1573 return (target->bcr & I3C_BCR_IBI_REQUEST_CAPABLE)
1574 == I3C_BCR_IBI_REQUEST_CAPABLE;
1575 }
1576
1577 /**
1578 * @brief Write a set amount of data to an I3C target device.
1579 *
1580 * This routine writes a set amount of data synchronously.
1581 *
1582 * @param target I3C target device descriptor.
1583 * @param buf Memory pool from which the data is transferred.
1584 * @param num_bytes Number of bytes to write.
1585 *
1586 * @retval 0 If successful.
1587 * @retval -EBUSY Bus is busy.
1588 * @retval -EIO General input / output error.
1589 */
i3c_write(struct i3c_device_desc * target,const uint8_t * buf,uint32_t num_bytes)1590 static inline int i3c_write(struct i3c_device_desc *target,
1591 const uint8_t *buf, uint32_t num_bytes)
1592 {
1593 struct i3c_msg msg;
1594
1595 msg.buf = (uint8_t *)buf;
1596 msg.len = num_bytes;
1597 msg.flags = I3C_MSG_WRITE | I3C_MSG_STOP;
1598
1599 return i3c_transfer(target, &msg, 1);
1600 }
1601
1602 /**
1603 * @brief Read a set amount of data from an I3C target device.
1604 *
1605 * This routine reads a set amount of data synchronously.
1606 *
1607 * @param target I3C target device descriptor.
1608 * @param buf Memory pool that stores the retrieved data.
1609 * @param num_bytes Number of bytes to read.
1610 *
1611 * @retval 0 If successful.
1612 * @retval -EBUSY Bus is busy.
1613 * @retval -EIO General input / output error.
1614 */
i3c_read(struct i3c_device_desc * target,uint8_t * buf,uint32_t num_bytes)1615 static inline int i3c_read(struct i3c_device_desc *target,
1616 uint8_t *buf, uint32_t num_bytes)
1617 {
1618 struct i3c_msg msg;
1619
1620 msg.buf = buf;
1621 msg.len = num_bytes;
1622 msg.flags = I3C_MSG_READ | I3C_MSG_STOP;
1623
1624 return i3c_transfer(target, &msg, 1);
1625 }
1626
1627 /**
1628 * @brief Write then read data from an I3C target device.
1629 *
1630 * This supports the common operation "this is what I want", "now give
1631 * it to me" transaction pair through a combined write-then-read bus
1632 * transaction.
1633 *
1634 * @param target I3C target device descriptor.
1635 * @param write_buf Pointer to the data to be written
1636 * @param num_write Number of bytes to write
1637 * @param read_buf Pointer to storage for read data
1638 * @param num_read Number of bytes to read
1639 *
1640 * @retval 0 if successful
1641 * @retval -EBUSY Bus is busy.
1642 * @retval -EIO General input / output error.
1643 */
i3c_write_read(struct i3c_device_desc * target,const void * write_buf,size_t num_write,void * read_buf,size_t num_read)1644 static inline int i3c_write_read(struct i3c_device_desc *target,
1645 const void *write_buf, size_t num_write,
1646 void *read_buf, size_t num_read)
1647 {
1648 struct i3c_msg msg[2];
1649
1650 msg[0].buf = (uint8_t *)write_buf;
1651 msg[0].len = num_write;
1652 msg[0].flags = I3C_MSG_WRITE;
1653
1654 msg[1].buf = (uint8_t *)read_buf;
1655 msg[1].len = num_read;
1656 msg[1].flags = I3C_MSG_RESTART | I3C_MSG_READ | I3C_MSG_STOP;
1657
1658 return i3c_transfer(target, msg, 2);
1659 }
1660
1661 /**
1662 * @brief Read multiple bytes from an internal address of an I3C target device.
1663 *
1664 * This routine reads multiple bytes from an internal address of an
1665 * I3C target device synchronously.
1666 *
1667 * Instances of this may be replaced by i3c_write_read().
1668 *
1669 * @param target I3C target device descriptor,
1670 * @param start_addr Internal address from which the data is being read.
1671 * @param buf Memory pool that stores the retrieved data.
1672 * @param num_bytes Number of bytes being read.
1673 *
1674 * @retval 0 If successful.
1675 * @retval -EBUSY Bus is busy.
1676 * @retval -EIO General input / output error.
1677 */
i3c_burst_read(struct i3c_device_desc * target,uint8_t start_addr,uint8_t * buf,uint32_t num_bytes)1678 static inline int i3c_burst_read(struct i3c_device_desc *target,
1679 uint8_t start_addr,
1680 uint8_t *buf,
1681 uint32_t num_bytes)
1682 {
1683 return i3c_write_read(target,
1684 &start_addr, sizeof(start_addr),
1685 buf, num_bytes);
1686 }
1687
1688 /**
1689 * @brief Write multiple bytes to an internal address of an I3C target device.
1690 *
1691 * This routine writes multiple bytes to an internal address of an
1692 * I3C target device synchronously.
1693 *
1694 * @warning The combined write synthesized by this API may not be
1695 * supported on all I3C devices. Uses of this API may be made more
1696 * portable by replacing them with calls to i3c_write() passing a
1697 * buffer containing the combined address and data.
1698 *
1699 * @param target I3C target device descriptor.
1700 * @param start_addr Internal address to which the data is being written.
1701 * @param buf Memory pool from which the data is transferred.
1702 * @param num_bytes Number of bytes being written.
1703 *
1704 * @retval 0 If successful.
1705 * @retval -EBUSY Bus is busy.
1706 * @retval -EIO General input / output error.
1707 */
i3c_burst_write(struct i3c_device_desc * target,uint8_t start_addr,const uint8_t * buf,uint32_t num_bytes)1708 static inline int i3c_burst_write(struct i3c_device_desc *target,
1709 uint8_t start_addr,
1710 const uint8_t *buf,
1711 uint32_t num_bytes)
1712 {
1713 struct i3c_msg msg[2];
1714
1715 msg[0].buf = &start_addr;
1716 msg[0].len = 1U;
1717 msg[0].flags = I3C_MSG_WRITE;
1718
1719 msg[1].buf = (uint8_t *)buf;
1720 msg[1].len = num_bytes;
1721 msg[1].flags = I3C_MSG_WRITE | I3C_MSG_STOP;
1722
1723 return i3c_transfer(target, msg, 2);
1724 }
1725
1726 /**
1727 * @brief Read internal register of an I3C target device.
1728 *
1729 * This routine reads the value of an 8-bit internal register of an I3C target
1730 * device synchronously.
1731 *
1732 * @param target I3C target device descriptor.
1733 * @param reg_addr Address of the internal register being read.
1734 * @param value Memory pool that stores the retrieved register value.
1735 *
1736 * @retval 0 If successful.
1737 * @retval -EBUSY Bus is busy.
1738 * @retval -EIO General input / output error.
1739 */
i3c_reg_read_byte(struct i3c_device_desc * target,uint8_t reg_addr,uint8_t * value)1740 static inline int i3c_reg_read_byte(struct i3c_device_desc *target,
1741 uint8_t reg_addr, uint8_t *value)
1742 {
1743 return i3c_write_read(target,
1744 ®_addr, sizeof(reg_addr),
1745 value, sizeof(*value));
1746 }
1747
1748 /**
1749 * @brief Write internal register of an I3C target device.
1750 *
1751 * This routine writes a value to an 8-bit internal register of an I3C target
1752 * device synchronously.
1753 *
1754 * @note This function internally combines the register and value into
1755 * a single bus transaction.
1756 *
1757 * @param target I3C target device descriptor.
1758 * @param reg_addr Address of the internal register being written.
1759 * @param value Value to be written to internal register.
1760 *
1761 * @retval 0 If successful.
1762 * @retval -EBUSY Bus is busy.
1763 * @retval -EIO General input / output error.
1764 */
i3c_reg_write_byte(struct i3c_device_desc * target,uint8_t reg_addr,uint8_t value)1765 static inline int i3c_reg_write_byte(struct i3c_device_desc *target,
1766 uint8_t reg_addr, uint8_t value)
1767 {
1768 uint8_t tx_buf[2] = {reg_addr, value};
1769
1770 return i3c_write(target, tx_buf, 2);
1771 }
1772
1773 /**
1774 * @brief Update internal register of an I3C target device.
1775 *
1776 * This routine updates the value of a set of bits from an 8-bit internal
1777 * register of an I3C target device synchronously.
1778 *
1779 * @note If the calculated new register value matches the value that
1780 * was read this function will not generate a write operation.
1781 *
1782 * @param target I3C target device descriptor.
1783 * @param reg_addr Address of the internal register being updated.
1784 * @param mask Bitmask for updating internal register.
1785 * @param value Value for updating internal register.
1786 *
1787 * @retval 0 If successful.
1788 * @retval -EBUSY Bus is busy.
1789 * @retval -EIO General input / output error.
1790 */
i3c_reg_update_byte(struct i3c_device_desc * target,uint8_t reg_addr,uint8_t mask,uint8_t value)1791 static inline int i3c_reg_update_byte(struct i3c_device_desc *target,
1792 uint8_t reg_addr, uint8_t mask,
1793 uint8_t value)
1794 {
1795 uint8_t old_value, new_value;
1796 int rc;
1797
1798 rc = i3c_reg_read_byte(target, reg_addr, &old_value);
1799 if (rc != 0) {
1800 return rc;
1801 }
1802
1803 new_value = (old_value & ~mask) | (value & mask);
1804 if (new_value == old_value) {
1805 return 0;
1806 }
1807
1808 return i3c_reg_write_byte(target, reg_addr, new_value);
1809 }
1810
1811 /**
1812 * @brief Dump out an I3C message
1813 *
1814 * Dumps out a list of I3C messages. For any that are writes (W), the data is
1815 * displayed in hex.
1816 *
1817 * It looks something like this (with name "testing"):
1818 *
1819 * @code
1820 * D: I3C msg: testing, addr=56
1821 * D: W len=01:
1822 * D: contents:
1823 * D: 06 |.
1824 * D: W len=0e:
1825 * D: contents:
1826 * D: 00 01 02 03 04 05 06 07 |........
1827 * D: 08 09 0a 0b 0c 0d |......
1828 * @endcode
1829 *
1830 * @param name Name of this dump, displayed at the top.
1831 * @param msgs Array of messages to dump.
1832 * @param num_msgs Number of messages to dump.
1833 * @param target I3C target device descriptor.
1834 */
1835 void i3c_dump_msgs(const char *name, const struct i3c_msg *msgs,
1836 uint8_t num_msgs, struct i3c_device_desc *target);
1837
1838 /**
1839 * @brief Generic helper function to perform bus initialization.
1840 *
1841 * @param dev Pointer to controller device driver instance.
1842 * @param i3c_dev_list Pointer to I3C device list.
1843 *
1844 * @retval 0 If successful.
1845 * @retval -EBUSY Bus is busy.
1846 * @retval -EIO General input / output error.
1847 * @retval -ENODEV If a provisioned ID does not match to any target devices
1848 * in the registered device list.
1849 * @retval -ENOSPC No more free addresses can be assigned to target.
1850 * @retval -ENOSYS Dynamic address assignment is not supported by
1851 * the controller driver.
1852 */
1853 int i3c_bus_init(const struct device *dev,
1854 const struct i3c_dev_list *i3c_dev_list);
1855
1856 /**
1857 * @brief Get basic information from device and update device descriptor.
1858 *
1859 * This retrieves some basic information:
1860 * * Bus Characteristics Register (GETBCR)
1861 * * Device Characteristics Register (GETDCR)
1862 * * Max Read Length (GETMRL)
1863 * * Max Write Length (GETMWL)
1864 * from the device and update the corresponding fields of the device
1865 * descriptor.
1866 *
1867 * This only updates the field(s) in device descriptor
1868 * only if CCC operations succeed.
1869 *
1870 * @param[in,out] target I3C target device descriptor.
1871 *
1872 * @retval 0 if successful.
1873 * @retval -EIO General Input/Output error.
1874 */
1875 int i3c_device_basic_info_get(struct i3c_device_desc *target);
1876
1877 /*
1878 * This needs to be after declaration of struct i3c_driver_api,
1879 * or else compiler complains about undefined type inside
1880 * the static inline API wrappers.
1881 */
1882 #include <zephyr/drivers/i3c/target_device.h>
1883
1884 #ifdef __cplusplus
1885 }
1886 #endif
1887
1888 /**
1889 * @}
1890 */
1891
1892 #include <syscalls/i3c.h>
1893
1894 #endif /* ZEPHYR_INCLUDE_DRIVERS_I3C_H_ */
1895