1 /*
2  * Copyright 2022 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #ifndef ZEPHYR_INCLUDE_DRIVERS_I3C_IBI_H_
8 #define ZEPHYR_INCLUDE_DRIVERS_I3C_IBI_H_
9 
10 /**
11  * @brief I3C In-Band Interrupts
12  * @defgroup i3c_ibi I3C In-Band Interrupts
13  * @ingroup i3c_interface
14  * @{
15  */
16 
17 #include <stdint.h>
18 
19 #include <zephyr/device.h>
20 #include <zephyr/kernel.h>
21 #include <zephyr/sys/slist.h>
22 
23 #ifndef CONFIG_I3C_IBI_MAX_PAYLOAD_SIZE
24 #define CONFIG_I3C_IBI_MAX_PAYLOAD_SIZE 0
25 #endif
26 
27 #ifdef __cplusplus
28 extern "C" {
29 #endif
30 
31 struct i3c_device_desc;
32 
33 /**
34  * @brief IBI Types.
35  */
36 enum i3c_ibi_type {
37 	/** Target interrupt */
38 	I3C_IBI_TARGET_INTR,
39 
40 	/** Controller Role Request */
41 	I3C_IBI_CONTROLLER_ROLE_REQUEST,
42 
43 	/** Hot Join Request */
44 	I3C_IBI_HOTJOIN,
45 
46 	I3C_IBI_TYPE_MAX = I3C_IBI_HOTJOIN,
47 
48 	/**
49 	 * Not an actual IBI type, but simply used by
50 	 * the IBI workq for generic callbacks.
51 	 */
52 	I3C_IBI_WORKQUEUE_CB,
53 };
54 
55 /**
56  * @brief Struct for IBI request.
57  */
58 struct i3c_ibi {
59 	/** Type of IBI. */
60 	enum i3c_ibi_type	ibi_type;
61 
62 	/** Pointer to payload of IBI. */
63 	uint8_t			*payload;
64 
65 	/** Length in bytes of the IBI payload. */
66 	uint8_t			payload_len;
67 };
68 
69 /**
70  * @brief Structure of payload buffer for IBI.
71  *
72  * This is used for the IBI callback.
73  */
74 struct i3c_ibi_payload {
75 	/**
76 	 * Length of available data in the payload buffer.
77 	 */
78 	uint8_t payload_len;
79 
80 	/**
81 	 * Pointer to byte array as payload buffer.
82 	 */
83 	uint8_t payload[CONFIG_I3C_IBI_MAX_PAYLOAD_SIZE];
84 };
85 
86 /**
87  * @brief Node about a queued IBI.
88  */
89 struct i3c_ibi_work {
90 	sys_snode_t node;
91 
92 	/**
93 	 * k_work struct.
94 	 */
95 	struct k_work work;
96 
97 	/**
98 	 * IBI type.
99 	 */
100 	enum i3c_ibi_type type;
101 
102 	union {
103 		/**
104 		 * Use for @see I3C_IBI_HOTJOIN.
105 		 */
106 		const struct device *controller;
107 
108 		/**
109 		 * Use for @see I3C_IBI_TARGET_INTR,
110 		 * and @see I3C_IBI_CONTROLLER_ROLE_REQUEST.
111 		 */
112 		struct i3c_device_desc *target;
113 	};
114 
115 	union {
116 		/**
117 		 * IBI payload.
118 		 */
119 		struct i3c_ibi_payload payload;
120 
121 		/**
122 		 * Generic workqueue callback when
123 		 * type is I3C_IBI_WORKQUEUE_CB.
124 		 */
125 		k_work_handler_t work_cb;
126 	};
127 };
128 
129 /**
130  * @brief Function called when In-Band Interrupt received from target device.
131  *
132  * This function is invoked by the controller when the controller
133  * receives an In-Band Interrupt from the target device.
134  *
135  * A success return shall cause the controller to ACK the next byte
136  * received.  An error return shall cause the controller to NACK the
137  * next byte received.
138  *
139  * @param target the device description structure associated with the
140  *               device to which the operation is addressed.
141  * @param payload Payload associated with the IBI. NULL if there is
142  *                no payload.
143  *
144  * @return 0 if the IBI is accepted, or a negative error code.
145  */
146 typedef int (*i3c_target_ibi_cb_t)(struct i3c_device_desc *target,
147 				   struct i3c_ibi_payload *payload);
148 
149 
150 /**
151  * @brief Queue an IBI work item for future processing.
152  *
153  * This queues up an IBI work item in the IBI workqueue
154  * for future processing.
155  *
156  * Note that this will copy the @p ibi_work struct into
157  * internal structure. If there is not enough space to
158  * copy the @p ibi_work struct, this returns -ENOMEM.
159  *
160  * @param ibi_work Pointer to the IBI work item struct.
161  *
162  * @retval 0 If work item is successfully queued.
163  * @retval -ENOMEM If no more free internal node to
164  *                 store IBI work item.
165  * @retval Others @see k_work_submit_to_queue
166  */
167 int i3c_ibi_work_enqueue(struct i3c_ibi_work *ibi_work);
168 
169 /**
170  * @brief Queue a target interrupt IBI for future processing.
171  *
172  * This queues up a target interrupt IBI in the IBI workqueue
173  * for future processing.
174  *
175  * @param target Pointer to target device descriptor.
176  * @param payload Pointer to IBI payload byte array.
177  * @param payload_len Length of payload byte array.
178  *
179  * @retval 0 If work item is successfully queued.
180  * @retval -ENOMEM If no more free internal node to
181  *                 store IBI work item.
182  * @retval Others @see k_work_submit_to_queue
183  */
184 int i3c_ibi_work_enqueue_target_irq(struct i3c_device_desc *target,
185 				    uint8_t *payload, size_t payload_len);
186 
187 /**
188  * @brief Queue a hot join IBI for future processing.
189  *
190  * This queues up a hot join IBI in the IBI workqueue
191  * for future processing.
192  *
193  * @param dev Pointer to controller device driver instance.
194  *
195  * @retval 0 If work item is successfully queued.
196  * @retval -ENOMEM If no more free internal node to
197  *                 store IBI work item.
198  * @retval Others @see k_work_submit_to_queue
199  */
200 int i3c_ibi_work_enqueue_hotjoin(const struct device *dev);
201 
202 /**
203  * @brief Queue a generic callback for future processing.
204  *
205  * This queues up a generic callback in the IBI workqueue
206  * for future processing.
207  *
208  * @param dev Pointer to controller device driver instance.
209  * @param work_cb Callback function.
210  *
211  * @retval 0 If work item is successfully queued.
212  * @retval -ENOMEM If no more free internal node to
213  *                 store IBI work item.
214  * @retval Others @see k_work_submit_to_queue
215  */
216 int i3c_ibi_work_enqueue_cb(const struct device *dev,
217 			    k_work_handler_t work_cb);
218 
219 #ifdef __cplusplus
220 }
221 #endif
222 
223 /**
224  * @}
225  */
226 
227 #endif /* ZEPHYR_INCLUDE_DRIVERS_I3C_IBI_H_ */
228