1 /*
2  * Copyright (c) 2024 Intel Corporation
3  * Copyright (c) 2024 Meta Platforms
4  *
5  * SPDX-License-Identifier: Apache-2.0
6  */
7 
8 #ifndef ZEPHYR_DRIVERS_I3C_RTIO_H_
9 #define ZEPHYR_DRIVERS_I3C_RTIO_H_
10 
11 #include <zephyr/kernel.h>
12 #include <zephyr/drivers/i3c.h>
13 #include <zephyr/rtio/rtio.h>
14 
15 #ifdef __cplusplus
16 extern "C" {
17 #endif
18 
19 /**
20  * @brief Driver context for implementing i3c with rtio
21  */
22 struct i3c_rtio {
23 	struct k_sem lock;
24 	struct k_spinlock slock;
25 	struct rtio *r;
26 	struct mpsc io_q;
27 	struct rtio_iodev iodev;
28 	struct rtio_iodev_sqe *txn_head;
29 	struct rtio_iodev_sqe *txn_curr;
30 	struct i3c_device_desc *i3c_desc;
31 };
32 
33 /**
34  * @brief Statically define an i3c_rtio context
35  *
36  * @param _name Symbolic name of the context
37  * @param _sq_sz Submission queue entry pool size
38  * @param _cq_sz Completion queue entry pool size
39  */
40 #define I3C_RTIO_DEFINE(_name, _sq_sz, _cq_sz)		\
41 	RTIO_DEFINE(CONCAT(_name, _r), _sq_sz, _cq_sz);	\
42 	static struct i3c_rtio _name = {		\
43 		.r = &CONCAT(_name, _r),		\
44 	};
45 
46 /**
47  * @brief Copy an array of i3c_msgs to rtio submissions and a transaction
48  *
49  * @retval sqe Last sqe setup in the copy
50  * @retval NULL Not enough memory to copy the transaction
51  */
52 struct rtio_sqe *i3c_rtio_copy(struct rtio *r, struct rtio_iodev *iodev, const struct i3c_msg *msgs,
53 			       uint8_t num_msgs);
54 
55 /**
56  * @brief Initialize an i3c rtio context
57  *
58  * @param ctx I3C RTIO driver context
59  */
60 void i3c_rtio_init(struct i3c_rtio *ctx);
61 
62 /**
63  * @brief Signal that the current (ctx->txn_curr) submission has been completed
64  *
65  * @param ctx I3C RTIO driver context
66  * @param status Completion status, negative values are errors
67  *
68  * @retval true Next submission is ready to start
69  * @retval false No more submissions to work on
70  */
71 bool i3c_rtio_complete(struct i3c_rtio *ctx, int status);
72 
73 /**
74  * @brief Submit, atomically, a submission to work on at some point
75  *
76  * @retval true Next submission is ready to start
77  * @retval false No new submission to start or submissions are in progress already
78  */
79 bool i3c_rtio_submit(struct i3c_rtio *ctx, struct rtio_iodev_sqe *iodev_sqe);
80 
81 /**
82  * @brief Configure the I3C bus controller
83  *
84  * Provides a compatible API for the existing i3c_configure API, and blocks the
85  * caller until the transfer completes.
86  *
87  * See i3c_configure().
88  */
89 int i3c_rtio_configure(struct i3c_rtio *ctx, enum i3c_config_type type, void *config);
90 
91 /**
92  * @brief Transfer i3c messages in a blocking call
93  *
94  * Provides a compatible API for the existing i3c_transfer API, and blocks the caller
95  * until the transfer completes.
96  *
97  * See i3c_transfer().
98  */
99 int i3c_rtio_transfer(struct i3c_rtio *ctx, struct i3c_msg *msgs, uint8_t num_msgs,
100 			       struct i3c_device_desc *desc);
101 
102 /**
103  * @brief Perform an I3C bus recovery in a blocking call
104  *
105  * Provides a compatible API for the existing i3c_recover API, and blocks the caller
106  * until the process completes.
107  *
108  * See i3c_recover().
109  */
110 int i3c_rtio_recover(struct i3c_rtio *ctx);
111 
112 /**
113  * @brief Perform an I3C CCC in a blocking call
114  *
115  * Provides a compatible API for the existing i3c_do_ccc API, and blocks the caller
116  * until the process completes.
117  *
118  * See i3c_do_ccc().
119  */
120 int i3c_rtio_ccc(struct i3c_rtio *ctx, struct i3c_ccc_payload *payload);
121 
122 #ifdef __cplusplus
123 }
124 #endif
125 
126 #endif /* ZEPHYR_DRVIERS_I3C_RTIO_H_ */
127