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