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