Line data Source code
1 1 : /*
2 : * Copyright (c) 2016 Intel Corporation.
3 : *
4 : * SPDX-License-Identifier: Apache-2.0
5 : */
6 :
7 : /**
8 : * @file
9 : * @brief Header file for GPIO utility functions
10 : * @ingroup gpio_interface
11 : */
12 :
13 : #ifndef ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_UTILS_H_
14 : #define ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_UTILS_H_
15 :
16 : /**
17 : * @addtogroup gpio_interface
18 : * @{
19 : */
20 :
21 : #include <stdbool.h>
22 : #include <stdint.h>
23 : #include <errno.h>
24 :
25 : #include <zephyr/devicetree.h>
26 : #include <zephyr/drivers/gpio.h>
27 : #include <zephyr/sys/__assert.h>
28 : #include <zephyr/sys/slist.h>
29 : #include <zephyr/tracing/tracing.h>
30 :
31 : #ifdef __cplusplus
32 : extern "C" {
33 : #endif
34 :
35 : /**
36 : * @brief Makes a bitmask of allowed GPIOs from a number of GPIOs.
37 : *
38 : * @param ngpios number of GPIOs
39 : * @return the bitmask of allowed gpios
40 : */
41 1 : #define GPIO_PORT_PIN_MASK_FROM_NGPIOS(ngpios) \
42 : ((gpio_port_pins_t)(((uint64_t)1 << (ngpios)) - 1U))
43 :
44 : /**
45 : * @brief Makes a bitmask of allowed GPIOs from the @p "gpio-reserved-ranges"
46 : * and @p "ngpios" DT properties values
47 : *
48 : * @param node_id GPIO controller node identifier.
49 : * @return the bitmask of allowed gpios
50 : * @see GPIO_DT_PORT_PIN_MASK_NGPIOS_EXC()
51 : */
52 1 : #define GPIO_PORT_PIN_MASK_FROM_DT_NODE(node_id) \
53 : GPIO_DT_PORT_PIN_MASK_NGPIOS_EXC(node_id, DT_PROP(node_id, ngpios))
54 :
55 : /**
56 : * @brief Make a bitmask of allowed GPIOs from a DT_DRV_COMPAT instance's GPIO
57 : * @p "gpio-reserved-ranges" and @p "ngpios" DT properties values
58 : *
59 : * @param inst DT_DRV_COMPAT instance number
60 : * @return the bitmask of allowed gpios
61 : * @see GPIO_DT_PORT_PIN_MASK_NGPIOS_EXC()
62 : */
63 1 : #define GPIO_PORT_PIN_MASK_FROM_DT_INST(inst) \
64 : GPIO_PORT_PIN_MASK_FROM_DT_NODE(DT_DRV_INST(inst))
65 :
66 : /**
67 : * @brief Generic function to insert or remove a callback from a callback list
68 : *
69 : * @param callbacks A pointer to the original list of callbacks (can be NULL)
70 : * @param callback A pointer of the callback to insert or remove from the list
71 : * @param set A boolean indicating insertion or removal of the callback
72 : *
73 : * @return 0 on success, negative errno otherwise.
74 : */
75 1 : static inline int gpio_manage_callback(sys_slist_t *callbacks,
76 : struct gpio_callback *callback,
77 : bool set)
78 : {
79 : __ASSERT(callback, "No callback!");
80 : __ASSERT(callback->handler, "No callback handler!");
81 :
82 : if (!sys_slist_is_empty(callbacks)) {
83 : if (!sys_slist_find_and_remove(callbacks, &callback->node)) {
84 : if (!set) {
85 : return -EINVAL;
86 : }
87 : }
88 : } else if (!set) {
89 : return -EINVAL;
90 : }
91 :
92 : if (set) {
93 : sys_slist_prepend(callbacks, &callback->node);
94 : }
95 :
96 : return 0;
97 : }
98 :
99 : /**
100 : * @brief Generic function to go through and fire callback from a callback list
101 : *
102 : * @param list A pointer on the gpio callback list
103 : * @param port A pointer on the gpio driver instance
104 : * @param pins The actual pin mask that triggered the interrupt
105 : */
106 1 : static inline void gpio_fire_callbacks(sys_slist_t *list,
107 : const struct device *port,
108 : uint32_t pins)
109 : {
110 : struct gpio_callback *cb, *tmp;
111 :
112 : sys_port_trace_gpio_fire_callbacks_enter(list, port, pins);
113 :
114 : SYS_SLIST_FOR_EACH_CONTAINER_SAFE(list, cb, tmp, node) {
115 : if (cb->pin_mask & pins) {
116 : __ASSERT(cb->handler, "No callback handler!");
117 :
118 : cb->handler(port, cb, cb->pin_mask & pins);
119 : sys_port_trace_gpio_fire_callback(port, cb);
120 : }
121 : }
122 : }
123 :
124 : #ifdef __cplusplus
125 : }
126 : #endif
127 :
128 : /**
129 : * @}
130 : */
131 :
132 : #endif /* ZEPHYR_INCLUDE_DRIVERS_GPIO_GPIO_UTILS_H_ */
|