Line data Source code
1 1 : /*
2 : * Copyright (c) 2022 Andrei-Edward Popa <andrei.popa105@yahoo.com>
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @ingroup reset_controller_interface
10 : * @brief Main header file for reset controller driver API.
11 : */
12 :
13 : #ifndef ZEPHYR_INCLUDE_DRIVERS_RESET_H_
14 : #define ZEPHYR_INCLUDE_DRIVERS_RESET_H_
15 :
16 : /**
17 : * @brief Interfaces for reset controllers.
18 : * @defgroup reset_controller_interface Reset Controller
19 : * @since 3.1
20 : * @version 0.2.0
21 : * @ingroup io_interfaces
22 : * @{
23 : */
24 :
25 : #include <errno.h>
26 :
27 : #include <zephyr/types.h>
28 : #include <zephyr/device.h>
29 :
30 : #ifdef __cplusplus
31 : extern "C" {
32 : #endif
33 :
34 : /** Reset controller device configuration. */
35 1 : struct reset_dt_spec {
36 : /** Reset controller device. */
37 1 : const struct device *dev;
38 : /** Reset line. */
39 1 : uint32_t id;
40 : };
41 :
42 : /**
43 : * @brief Static initializer for a @p reset_dt_spec
44 : *
45 : * This returns a static initializer for a @p reset_dt_spec structure given a
46 : * devicetree node identifier, a property specifying a Reset Controller and an index.
47 : *
48 : * Example devicetree fragment:
49 : *
50 : * n: node {
51 : * resets = <&reset 10>;
52 : * }
53 : *
54 : * Example usage:
55 : *
56 : * const struct reset_dt_spec spec = RESET_DT_SPEC_GET_BY_IDX(DT_NODELABEL(n), 0);
57 : * // Initializes 'spec' to:
58 : * // {
59 : * // .dev = DEVICE_DT_GET(DT_NODELABEL(reset)),
60 : * // .id = 10
61 : * // }
62 : *
63 : * The 'reset' field must still be checked for readiness, e.g. using
64 : * device_is_ready(). It is an error to use this macro unless the node
65 : * exists, has the given property, and that property specifies a reset
66 : * controller reset line id as shown above.
67 : *
68 : * @param node_id devicetree node identifier
69 : * @param idx logical index into "resets"
70 : * @return static initializer for a struct reset_dt_spec for the property
71 : */
72 1 : #define RESET_DT_SPEC_GET_BY_IDX(node_id, idx) \
73 : { \
74 : .dev = DEVICE_DT_GET(DT_RESET_CTLR_BY_IDX(node_id, idx)), \
75 : .id = DT_RESET_ID_BY_IDX(node_id, idx) \
76 : }
77 :
78 : /**
79 : * @brief Like RESET_DT_SPEC_GET_BY_IDX(), with a fallback to a default value
80 : *
81 : * If the devicetree node identifier 'node_id' refers to a node with a
82 : * 'resets' property, this expands to
83 : * <tt>RESET_DT_SPEC_GET_BY_IDX(node_id, idx)</tt>. The @p
84 : * default_value parameter is not expanded in this case.
85 : *
86 : * Otherwise, this expands to @p default_value.
87 : *
88 : * @param node_id devicetree node identifier
89 : * @param idx logical index into the 'resets' property
90 : * @param default_value fallback value to expand to
91 : * @return static initializer for a struct reset_dt_spec for the property,
92 : * or default_value if the node or property do not exist
93 : */
94 1 : #define RESET_DT_SPEC_GET_BY_IDX_OR(node_id, idx, default_value) \
95 : COND_CODE_1(DT_NODE_HAS_PROP(node_id, resets), \
96 : (RESET_DT_SPEC_GET_BY_IDX(node_id, idx)), \
97 : (default_value))
98 :
99 : /**
100 : * @brief Equivalent to RESET_DT_SPEC_GET_BY_IDX(node_id, 0).
101 : *
102 : * @param node_id devicetree node identifier
103 : * @return static initializer for a struct reset_dt_spec for the property
104 : * @see RESET_DT_SPEC_GET_BY_IDX()
105 : */
106 1 : #define RESET_DT_SPEC_GET(node_id) \
107 : RESET_DT_SPEC_GET_BY_IDX(node_id, 0)
108 :
109 : /**
110 : * @brief Equivalent to
111 : * RESET_DT_SPEC_GET_BY_IDX_OR(node_id, 0, default_value).
112 : *
113 : * @param node_id devicetree node identifier
114 : * @param default_value fallback value to expand to
115 : * @return static initializer for a struct reset_dt_spec for the property,
116 : * or default_value if the node or property do not exist
117 : */
118 1 : #define RESET_DT_SPEC_GET_OR(node_id, default_value) \
119 : RESET_DT_SPEC_GET_BY_IDX_OR(node_id, 0, default_value)
120 :
121 : /**
122 : * @brief Static initializer for a @p reset_dt_spec from a DT_DRV_COMPAT
123 : * instance's Reset Controller property at an index.
124 : *
125 : * @param inst DT_DRV_COMPAT instance number
126 : * @param idx logical index into "resets"
127 : * @return static initializer for a struct reset_dt_spec for the property
128 : * @see RESET_DT_SPEC_GET_BY_IDX()
129 : */
130 1 : #define RESET_DT_SPEC_INST_GET_BY_IDX(inst, idx) \
131 : RESET_DT_SPEC_GET_BY_IDX(DT_DRV_INST(inst), idx)
132 :
133 : /**
134 : * @brief Static initializer for a @p reset_dt_spec from a DT_DRV_COMPAT
135 : * instance's 'resets' property at an index, with fallback
136 : *
137 : * @param inst DT_DRV_COMPAT instance number
138 : * @param idx logical index into the 'resets' property
139 : * @param default_value fallback value to expand to
140 : * @return static initializer for a struct reset_dt_spec for the property,
141 : * or default_value if the node or property do not exist
142 : */
143 1 : #define RESET_DT_SPEC_INST_GET_BY_IDX_OR(inst, idx, default_value) \
144 : COND_CODE_1(DT_PROP_HAS_IDX(DT_DRV_INST(inst), resets, idx), \
145 : (RESET_DT_SPEC_GET_BY_IDX(DT_DRV_INST(inst), idx)), \
146 : (default_value))
147 :
148 : /**
149 : * @brief Equivalent to RESET_DT_SPEC_INST_GET_BY_IDX(inst, 0).
150 : *
151 : * @param inst DT_DRV_COMPAT instance number
152 : * @return static initializer for a struct reset_dt_spec for the property
153 : * @see RESET_DT_SPEC_INST_GET_BY_IDX()
154 : */
155 1 : #define RESET_DT_SPEC_INST_GET(inst) \
156 : RESET_DT_SPEC_INST_GET_BY_IDX(inst, 0)
157 :
158 : /**
159 : * @brief Equivalent to
160 : * RESET_DT_SPEC_INST_GET_BY_IDX_OR(node_id, 0, default_value).
161 : *
162 : * @param inst DT_DRV_COMPAT instance number
163 : * @param default_value fallback value to expand to
164 : * @return static initializer for a struct reset_dt_spec for the property,
165 : * or default_value if the node or property do not exist
166 : */
167 1 : #define RESET_DT_SPEC_INST_GET_OR(inst, default_value) \
168 : RESET_DT_SPEC_INST_GET_BY_IDX_OR(inst, 0, default_value)
169 :
170 : /** @cond INTERNAL_HIDDEN */
171 :
172 : /**
173 : * API template to get the reset status of the device.
174 : *
175 : * @see reset_status
176 : */
177 : typedef int (*reset_api_status)(const struct device *dev, uint32_t id, uint8_t *status);
178 :
179 : /**
180 : * API template to put the device in reset state.
181 : *
182 : * @see reset_line_assert
183 : */
184 : typedef int (*reset_api_line_assert)(const struct device *dev, uint32_t id);
185 :
186 : /**
187 : * API template to take out the device from reset state.
188 : *
189 : * @see reset_line_deassert
190 : */
191 : typedef int (*reset_api_line_deassert)(const struct device *dev, uint32_t id);
192 :
193 : /**
194 : * API template to reset the device.
195 : *
196 : * @see reset_line_toggle
197 : */
198 : typedef int (*reset_api_line_toggle)(const struct device *dev, uint32_t id);
199 :
200 : /**
201 : * @brief Reset Controller driver API
202 : */
203 : __subsystem struct reset_driver_api {
204 : reset_api_status status;
205 : reset_api_line_assert line_assert;
206 : reset_api_line_deassert line_deassert;
207 : reset_api_line_toggle line_toggle;
208 : };
209 :
210 : /** @endcond */
211 :
212 : /**
213 : * @brief Get the reset status
214 : *
215 : * This function returns the reset status of the device.
216 : *
217 : * @param dev Reset controller device.
218 : * @param id Reset line.
219 : * @param status Where to write the reset status.
220 : *
221 : * @retval 0 On success.
222 : * @retval -ENOSYS If the functionality is not implemented by the driver.
223 : * @retval -errno Other negative errno in case of failure.
224 : */
225 1 : __syscall int reset_status(const struct device *dev, uint32_t id, uint8_t *status);
226 :
227 : static inline int z_impl_reset_status(const struct device *dev, uint32_t id, uint8_t *status)
228 : {
229 : const struct reset_driver_api *api = (const struct reset_driver_api *)dev->api;
230 :
231 : if (api->status == NULL) {
232 : return -ENOSYS;
233 : }
234 :
235 : return api->status(dev, id, status);
236 : }
237 :
238 : /**
239 : * @brief Get the reset status from a @p reset_dt_spec.
240 : *
241 : * This is equivalent to:
242 : *
243 : * reset_status(spec->dev, spec->id, status);
244 : *
245 : * @param spec Reset controller specification from devicetree
246 : * @param status Where to write the reset status.
247 : *
248 : * @return a value from reset_status()
249 : */
250 1 : static inline int reset_status_dt(const struct reset_dt_spec *spec, uint8_t *status)
251 : {
252 : return reset_status(spec->dev, spec->id, status);
253 : }
254 :
255 : /**
256 : * @brief Put the device in reset state
257 : *
258 : * This function sets/clears the reset bits of the device,
259 : * depending on the logic level (active-high/active-low).
260 : *
261 : * @param dev Reset controller device.
262 : * @param id Reset line.
263 : *
264 : * @retval 0 On success.
265 : * @retval -ENOSYS If the functionality is not implemented by the driver.
266 : * @retval -errno Other negative errno in case of failure.
267 : */
268 1 : __syscall int reset_line_assert(const struct device *dev, uint32_t id);
269 :
270 : static inline int z_impl_reset_line_assert(const struct device *dev, uint32_t id)
271 : {
272 : const struct reset_driver_api *api = (const struct reset_driver_api *)dev->api;
273 :
274 : if (api->line_assert == NULL) {
275 : return -ENOSYS;
276 : }
277 :
278 : return api->line_assert(dev, id);
279 : }
280 :
281 : /**
282 : * @brief Assert the reset state from a @p reset_dt_spec.
283 : *
284 : * This is equivalent to:
285 : *
286 : * reset_line_assert(spec->dev, spec->id);
287 : *
288 : * @param spec Reset controller specification from devicetree
289 : *
290 : * @return a value from reset_line_assert()
291 : */
292 1 : static inline int reset_line_assert_dt(const struct reset_dt_spec *spec)
293 : {
294 : return reset_line_assert(spec->dev, spec->id);
295 : }
296 :
297 : /**
298 : * @brief Take out the device from reset state.
299 : *
300 : * This function sets/clears the reset bits of the device,
301 : * depending on the logic level (active-low/active-high).
302 : *
303 : * @param dev Reset controller device.
304 : * @param id Reset line.
305 : *
306 : * @retval 0 On success.
307 : * @retval -ENOSYS If the functionality is not implemented by the driver.
308 : * @retval -errno Other negative errno in case of failure.
309 : */
310 1 : __syscall int reset_line_deassert(const struct device *dev, uint32_t id);
311 :
312 : static inline int z_impl_reset_line_deassert(const struct device *dev, uint32_t id)
313 : {
314 : const struct reset_driver_api *api = (const struct reset_driver_api *)dev->api;
315 :
316 : if (api->line_deassert == NULL) {
317 : return -ENOSYS;
318 : }
319 :
320 : return api->line_deassert(dev, id);
321 : }
322 :
323 : /**
324 : * @brief Deassert the reset state from a @p reset_dt_spec.
325 : *
326 : * This is equivalent to:
327 : *
328 : * reset_line_deassert(spec->dev, spec->id)
329 : *
330 : * @param spec Reset controller specification from devicetree
331 : *
332 : * @return a value from reset_line_deassert()
333 : */
334 1 : static inline int reset_line_deassert_dt(const struct reset_dt_spec *spec)
335 : {
336 : return reset_line_deassert(spec->dev, spec->id);
337 : }
338 :
339 : /**
340 : * @brief Reset the device.
341 : *
342 : * This function performs reset for a device (assert + deassert).
343 : *
344 : * @param dev Reset controller device.
345 : * @param id Reset line.
346 : *
347 : * @retval 0 On success.
348 : * @retval -ENOSYS If the functionality is not implemented by the driver.
349 : * @retval -errno Other negative errno in case of failure.
350 : */
351 1 : __syscall int reset_line_toggle(const struct device *dev, uint32_t id);
352 :
353 : static inline int z_impl_reset_line_toggle(const struct device *dev, uint32_t id)
354 : {
355 : const struct reset_driver_api *api = (const struct reset_driver_api *)dev->api;
356 :
357 : if (api->line_toggle == NULL) {
358 : return -ENOSYS;
359 : }
360 :
361 : return api->line_toggle(dev, id);
362 : }
363 :
364 : /**
365 : * @brief Reset the device from a @p reset_dt_spec.
366 : *
367 : * This is equivalent to:
368 : *
369 : * reset_line_toggle(spec->dev, spec->id)
370 : *
371 : * @param spec Reset controller specification from devicetree
372 : *
373 : * @return a value from reset_line_toggle()
374 : */
375 1 : static inline int reset_line_toggle_dt(const struct reset_dt_spec *spec)
376 : {
377 : return reset_line_toggle(spec->dev, spec->id);
378 : }
379 :
380 : /**
381 : * @}
382 : */
383 :
384 : #ifdef __cplusplus
385 : }
386 : #endif
387 :
388 : #include <zephyr/syscalls/reset.h>
389 :
390 : #endif /* ZEPHYR_INCLUDE_DRIVERS_RESET_H_ */
|