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