Line data Source code
1 0 : /*
2 : * Copyright 2022 Intel Corporation
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : #ifndef ZEPHYR_INCLUDE_DRIVERS_I3C_TARGET_DEVICE_H_
8 : #define ZEPHYR_INCLUDE_DRIVERS_I3C_TARGET_DEVICE_H_
9 :
10 : /**
11 : * @brief I3C Target Device API
12 : * @defgroup i3c_target_device I3C Target Device API
13 : * @ingroup i3c_interface
14 : * @{
15 : */
16 :
17 : #include <errno.h>
18 : #include <stddef.h>
19 : #include <stdint.h>
20 :
21 : #include <zephyr/device.h>
22 : #include <zephyr/sys/slist.h>
23 :
24 : #ifdef __cplusplus
25 : extern "C" {
26 : #endif
27 :
28 : struct i3c_driver_api;
29 :
30 : /**
31 : * @brief Configuration parameters for I3C hardware to act as target device.
32 : *
33 : * This can also be used to configure the controller if it is to act as
34 : * a target on the bus.
35 : */
36 1 : struct i3c_config_target {
37 : /**
38 : * If the hardware is currently acting as a target device
39 : * on the bus.
40 : */
41 1 : bool enabled;
42 :
43 : /**
44 : * I3C target dynamic address.
45 : *
46 : * Currently assigned dynamic address. 0 if no address
47 : * assigned.
48 : *
49 : * @note Only writeable if the hardware acts as a primary
50 : * controller
51 : */
52 1 : uint8_t dynamic_addr;
53 :
54 : /**
55 : * I3C target static address.
56 : *
57 : * Used used when operating as a secondary controller
58 : * or as a target device.
59 : */
60 1 : uint8_t static_addr;
61 :
62 : /** Provisioned ID. */
63 1 : uint64_t pid;
64 :
65 : /**
66 : * True if lower 32-bit of Provisioned ID is random.
67 : *
68 : * This sets the bit 32 of Provisioned ID which means
69 : * the lower 32-bit is random value.
70 : */
71 1 : bool pid_random;
72 :
73 : /** Bus Characteristics Register (BCR). */
74 1 : uint8_t bcr;
75 :
76 : /** Device Characteristics Register (DCR). */
77 1 : uint8_t dcr;
78 :
79 : /** Maximum Read Length (MRL). */
80 1 : uint16_t max_read_len;
81 :
82 : /** Maximum Write Length (MWL). */
83 1 : uint16_t max_write_len;
84 :
85 : /**
86 : * Bit mask of supported HDR modes (0 - 7).
87 : */
88 1 : uint8_t supported_hdr;
89 : };
90 :
91 : /**
92 : * @brief Structure describing a device that supports the I3C target API.
93 : *
94 : * Instances of this are passed to the i3c_target_register() and
95 : * i3c_target_unregister() functions to indicate addition and removal
96 : * of a target device, respective.
97 : *
98 : * Fields other than @c node must be initialized by the module that
99 : * implements the device behavior prior to passing the object
100 : * reference to i3c_target_register().
101 : */
102 1 : struct i3c_target_config {
103 0 : sys_snode_t node;
104 :
105 : /**
106 : * Flags for the target device defined by I3C_TARGET_FLAGS_*
107 : * constants.
108 : */
109 1 : uint8_t flags;
110 :
111 : /** Address for this target device */
112 1 : uint8_t address;
113 :
114 : /** Callback functions */
115 1 : const struct i3c_target_callbacks *callbacks;
116 : };
117 :
118 0 : struct i3c_target_callbacks {
119 : /**
120 : * @brief Function called when a write to the device is initiated.
121 : *
122 : * This function is invoked by the controller when the bus completes
123 : * a start condition for a write operation to the address associated
124 : * with a particular device.
125 : *
126 : * A success return shall cause the controller to ACK the next byte
127 : * received. An error return shall cause the controller to NACK the
128 : * next byte received.
129 : *
130 : * @param config Configuration structure associated with the
131 : * device to which the operation is addressed.
132 : *
133 : * @return 0 if the write is accepted, or a negative error code.
134 : */
135 1 : int (*write_requested_cb)(struct i3c_target_config *config);
136 :
137 : /**
138 : * @brief Function called when a write to the device is continued.
139 : *
140 : * This function is invoked by the controller when it completes
141 : * reception of a byte of data in an ongoing write operation to the
142 : * device.
143 : *
144 : * A success return shall cause the controller to ACK the next byte
145 : * received. An error return shall cause the controller to NACK the
146 : * next byte received.
147 : *
148 : * @param config Configuration structure associated with the
149 : * device to which the operation is addressed.
150 : *
151 : * @param val the byte received by the controller.
152 : *
153 : * @return 0 if more data can be accepted, or a negative error
154 : * code.
155 : */
156 1 : int (*write_received_cb)(struct i3c_target_config *config,
157 : uint8_t val);
158 :
159 : /**
160 : * @brief Function called when a read from the device is initiated.
161 : *
162 : * This function is invoked by the controller when the bus completes a
163 : * start condition for a read operation from the address associated
164 : * with a particular device.
165 : *
166 : * The value returned in @p val will be transmitted. A success
167 : * return shall cause the controller to react to additional read
168 : * operations. An error return shall cause the controller to ignore
169 : * bus operations until a new start condition is received.
170 : *
171 : * @param config Configuration structure associated with the
172 : * device to which the operation is addressed.
173 : *
174 : * @param val Pointer to storage for the first byte of data to return
175 : * for the read request.
176 : *
177 : * @return 0 if more data can be requested, or a negative error code.
178 : */
179 1 : int (*read_requested_cb)(struct i3c_target_config *config,
180 : uint8_t *val);
181 :
182 : /**
183 : * @brief Function called when a read from the device is continued.
184 : *
185 : * This function is invoked by the controller when the bus is ready to
186 : * provide additional data for a read operation from the address
187 : * associated with the device device.
188 : *
189 : * The value returned in @p val will be transmitted. A success
190 : * return shall cause the controller to react to additional read
191 : * operations. An error return shall cause the controller to ignore
192 : * bus operations until a new start condition is received.
193 : *
194 : * @param config Configuration structure associated with the
195 : * device to which the operation is addressed.
196 : *
197 : * @param val Pointer to storage for the next byte of data to return
198 : * for the read request.
199 : *
200 : * @return 0 if data has been provided, or a negative error code.
201 : */
202 1 : int (*read_processed_cb)(struct i3c_target_config *config,
203 : uint8_t *val);
204 :
205 : #ifdef CONFIG_I3C_TARGET_BUFFER_MODE
206 : /** @brief Function called when a write to the device is completed.
207 : *
208 : * This function is invoked by the controller when it completes
209 : * reception of data from the source buffer to the destination
210 : * buffer in an ongoing write operation to the device.
211 : *
212 : * @param config Configuration structure associated with the
213 : * device to which the operation is addressed.
214 : *
215 : * @param ptr pointer to the buffer that contains the data to be transferred.
216 : *
217 : * @param len the length of the data to be transferred.
218 : */
219 : void (*buf_write_received_cb)(struct i3c_target_config *config, uint8_t *ptr, uint32_t len);
220 :
221 : /** @brief Function called when a read from the device is initiated.
222 : *
223 : * This function is invoked by the controller when the bus is ready to
224 : * provide additional data by buffer for a read operation from the address
225 : * associated with the device.
226 : *
227 : * The value returned in @p **ptr and @p *len will be transmitted. A success
228 : * return shall cause the controller to react to additional read operations.
229 : * An error return shall cause the controller to ignore bus operations until
230 : * a new start condition is received.
231 : *
232 : * @param config the configuration structure associated with the
233 : * device to which the operation is addressed.
234 : *
235 : * @param ptr pointer to storage for the address of data buffer to return
236 : * for the read request.
237 : *
238 : * @param len pointer to storage for the length of the data to be transferred
239 : * for the read request.
240 : *
241 : * @param hdr_mode HDR mode
242 : *
243 : * @return 0 if data has been provided, or a negative error code.
244 : */
245 : int (*buf_read_requested_cb)(struct i3c_target_config *config, uint8_t **ptr, uint32_t *len,
246 : uint8_t *hdr_mode);
247 : #endif
248 : /**
249 : * @brief Function called when a stop condition is observed after a
250 : * start condition addressed to a particular device.
251 : *
252 : * This function is invoked by the controller when the bus is ready to
253 : * provide additional data for a read operation from the address
254 : * associated with the device device. After the function returns the
255 : * controller shall enter a state where it is ready to react to new
256 : * start conditions.
257 : *
258 : * @param config Configuration structure associated with the
259 : * device to which the operation is addressed.
260 : *
261 : * @return Ignored.
262 : */
263 1 : int (*stop_cb)(struct i3c_target_config *config);
264 :
265 : /**
266 : * @brief Function called when an active controller handoffs controlership
267 : * to this target.
268 : *
269 : * This function is invoked by the active controller when it handoffs
270 : * controllership to this target. This can happen wither the target has
271 : * requested it or if the active controller chooses to handoff to the
272 : * controller capable target.
273 : *
274 : * @param config Configuration structure associated with the
275 : * device to which the operation is addressed.
276 : *
277 : * @return Ignored.
278 : */
279 1 : int (*controller_handoff_cb)(struct i3c_target_config *config);
280 : };
281 :
282 0 : __subsystem struct i3c_target_driver_api {
283 0 : int (*driver_register)(const struct device *dev);
284 0 : int (*driver_unregister)(const struct device *dev);
285 : };
286 :
287 : /**
288 : * @brief Accept or Decline Controller Handoffs
289 : *
290 : * This sets the target to ACK or NACK handoffs from the active
291 : * controller from the CCC GETACCCR.
292 : *
293 : * @param dev Pointer to the device structure for an I3C controller
294 : * driver configured in target mode.
295 : * @param accept True to ACK controller handoffs, False to NACK
296 : *
297 : * @retval 0 Is successful
298 : */
299 1 : static inline int i3c_target_controller_handoff(const struct device *dev,
300 : bool accept)
301 : {
302 : const struct i3c_driver_api *api =
303 : (const struct i3c_driver_api *)dev->api;
304 :
305 : if (api->target_controller_handoff == NULL) {
306 : return -ENOSYS;
307 : }
308 :
309 : return api->target_controller_handoff(dev, accept);
310 : }
311 :
312 : /**
313 : * @brief Writes to the target's TX FIFO
314 : *
315 : * Write to the TX FIFO @p dev I3C bus driver using the provided
316 : * buffer and length. Some I3C targets will NACK read requests until data
317 : * is written to the TX FIFO. This function will write as much as it can
318 : * to the FIFO return the total number of bytes written. It is then up to
319 : * the application to utalize the target callbacks to write the remaining
320 : * data. Negative returns indicate error.
321 : *
322 : * Most of the existing hardware allows simultaneous support for master
323 : * and target mode. This is however not guaranteed.
324 : *
325 : * @param dev Pointer to the device structure for an I3C controller
326 : * driver configured in target mode.
327 : * @param buf Pointer to the buffer
328 : * @param len Length of the buffer
329 : * @param hdr_mode HDR mode see @c I3C_MSG_HDR_MODE*
330 : *
331 : * @retval Total number of bytes written
332 : * @retval -ENOTSUP Not in Target Mode or HDR Mode not supported
333 : * @retval -ENOSPC No space in Tx FIFO
334 : * @retval -ENOSYS If target mode is not implemented
335 : */
336 1 : static inline int i3c_target_tx_write(const struct device *dev,
337 : uint8_t *buf, uint16_t len, uint8_t hdr_mode)
338 : {
339 : const struct i3c_driver_api *api =
340 : (const struct i3c_driver_api *)dev->api;
341 :
342 : if (api->target_tx_write == NULL) {
343 : return -ENOSYS;
344 : }
345 :
346 : return api->target_tx_write(dev, buf, len, hdr_mode);
347 : }
348 :
349 : /**
350 : * @brief Registers the provided config as target device of a controller.
351 : *
352 : * Enable I3C target mode for the @p dev I3C bus driver using the provided
353 : * config struct (@p cfg) containing the functions and parameters to send bus
354 : * events. The I3C target will be registered at the address provided as
355 : * @ref i3c_target_config.address struct member. Any I3C bus events related
356 : * to the target mode will be passed onto I3C target device driver via a set of
357 : * callback functions provided in the 'callbacks' struct member.
358 : *
359 : * Most of the existing hardware allows simultaneous support for master
360 : * and target mode. This is however not guaranteed.
361 : *
362 : * @param dev Pointer to the device structure for an I3C controller
363 : * driver configured in target mode.
364 : * @param cfg Config struct with functions and parameters used by
365 : * the I3C target driver to send bus events
366 : *
367 : * @retval 0 Is successful
368 : * @retval -EINVAL If parameters are invalid
369 : * @retval -EIO General input / output error.
370 : * @retval -ENOSYS If target mode is not implemented
371 : */
372 1 : static inline int i3c_target_register(const struct device *dev,
373 : struct i3c_target_config *cfg)
374 : {
375 : const struct i3c_driver_api *api =
376 : (const struct i3c_driver_api *)dev->api;
377 :
378 : if (api->target_register == NULL) {
379 : return -ENOSYS;
380 : }
381 :
382 : return api->target_register(dev, cfg);
383 : }
384 :
385 : /**
386 : * @brief Unregisters the provided config as target device
387 : *
388 : * This routine disables I3C target mode for the @p dev I3C bus driver using
389 : * the provided config struct (@p cfg) containing the functions and parameters
390 : * to send bus events.
391 : *
392 : * @param dev Pointer to the device structure for an I3C controller
393 : * driver configured in target mode.
394 : * @param cfg Config struct with functions and parameters used by
395 : * the I3C target driver to send bus events
396 : *
397 : * @retval 0 Is successful
398 : * @retval -EINVAL If parameters are invalid
399 : * @retval -ENOSYS If target mode is not implemented
400 : */
401 1 : static inline int i3c_target_unregister(const struct device *dev,
402 : struct i3c_target_config *cfg)
403 : {
404 : const struct i3c_driver_api *api =
405 : (const struct i3c_driver_api *)dev->api;
406 :
407 : if (api->target_unregister == NULL) {
408 : return -ENOSYS;
409 : }
410 :
411 : return api->target_unregister(dev, cfg);
412 : }
413 :
414 : #ifdef __cplusplus
415 : }
416 : #endif
417 :
418 : /**
419 : * @}
420 : */
421 :
422 : #endif /* ZEPHYR_INCLUDE_DRIVERS_I3C_TARGET_DEVICE_H_ */
|