1 /* 2 * GPIO driver definitions. 3 * (See below for additional copyright and licensing notices.) 4 * 5 * Copyright (C) 2017, 2018, 2023, 2024 Paul Boddie <paul@boddie.org.uk> 6 * 7 * This program is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU General Public License as 9 * published by the Free Software Foundation; either version 2 of 10 * the License, or (at your option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 * GNU General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License 18 * along with this program; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 20 * Boston, MA 02110-1301, USA 21 * 22 * 23 * Subject to other copyrights, being derived from the gpio headers in the io 24 * package. 25 * 26 * This file is part of TUD:OS and distributed under the terms of the 27 * GNU General Public License 2. 28 * Please see the COPYING-GPL-2 file for details. 29 */ 30 31 #pragma once 32 33 #include <l4/vbus/vbus_gpio.h> 34 #include <stdint.h> 35 36 struct gpio_port 37 { 38 uint32_t pull_ups, pull_downs; 39 }; 40 41 typedef struct Pin_slice 42 { 43 unsigned offset; 44 unsigned mask; 45 } Pin_slice; 46 47 #ifdef __cplusplus 48 49 namespace Hw { 50 51 // IRQ control for each GPIO pin. 52 53 class Gpio_irq_pin 54 { 55 public: 56 virtual void do_mask() = 0; 57 virtual void do_unmask() = 0; 58 virtual bool do_set_mode(unsigned mode) = 0; 59 virtual int clear() = 0; 60 virtual bool enabled() = 0; 61 }; 62 63 // GPIO peripheral control. 64 65 class Gpio_chip 66 { 67 public: 68 /// Modes used for setup() 69 enum Fix_mode 70 { 71 Input = L4VBUS_GPIO_SETUP_INPUT, ///< Configure as input pin 72 Output = L4VBUS_GPIO_SETUP_OUTPUT, ///< Configure as output pin 73 Irq = L4VBUS_GPIO_SETUP_IRQ, ///< Configure as IRQ source 74 }; 75 76 /// Modes used for pull up / pull down (config_pull()) 77 enum Pull_mode 78 { 79 Pull_none = L4VBUS_GPIO_PIN_PULL_NONE, ///< No pull up or pull down resistors 80 Pull_up = L4VBUS_GPIO_PIN_PULL_UP, ///< Enable pull up resistor 81 Pull_down = L4VBUS_GPIO_PIN_PULL_DOWN, ///< Enable pull down resistor 82 }; 83 84 // Generic function options 85 enum Function_levels 86 { 87 Function_gpio, 88 Function_alt, 89 Function_irq, 90 }; 91 92 virtual void request(unsigned pin) = 0; 93 virtual void free(unsigned pin) = 0; 94 95 /** 96 * \brief Request number of pins from GPIO chip 97 * \return Number of pins of this GPIO chip 98 */ 99 virtual unsigned nr_pins() const = 0; 100 101 /** 102 * \brief Generic (platform independent) setup for a pin. 103 * \param pin the pin number to configure. 104 * \param mode the mode for the pin (see Fix_mode). 105 * \param value the value if the pin is configured as output. 106 */ 107 virtual void setup(unsigned pin, unsigned mode, int value = 0) = 0; 108 109 /** 110 * \brief Generic (platform independet) function to set a pin's pull up/down mode 111 * \param pin The pin number to configure. 112 * \param mode The pull up/down mode (see Pull_mode). 113 */ 114 virtual void config_pull(unsigned pin, unsigned mode) = 0; 115 116 /** 117 * \brief Set platform specific pad configuration. 118 * \param pin the pin to configure. 119 * \param func a platform specific sub-function of a pad to be configured 120 * \param value a platform specific value for the given sub-function. 121 */ 122 virtual void config_pad(unsigned pin, unsigned func, unsigned value) = 0; 123 124 /** 125 * \brief Get Platform specific pad configuration. 126 * \param pin the pin to configure. 127 * \param func a platform specific sub-function of a pad to be configured 128 * \retparam value a platform specific value for the given sub-function. 129 */ 130 virtual void config_get(unsigned pin, unsigned func, unsigned *value) = 0; 131 132 /** 133 * \brief Get platform specific pad configuration. 134 * \param pin the pin to configure. 135 * \param func a platform specific sub-function of a pad to be configured 136 * \param value a platform specific value for the given sub-function. 137 */ 138 virtual void config_pad_get(unsigned pin, unsigned *func, unsigned *value) = 0; 139 140 /** 141 * \brief Get the value of the given pin (generic API). 142 * \param pin the pin to read the value from. 143 */ 144 virtual int get(unsigned pin) = 0; 145 146 /** 147 * \brief Set the value of the given pin (generic API). 148 * \pre The pin has to be configured as output before using this function, 149 * otherwise this call will be ignored. 150 * \param pin the pin to write the value to. 151 * \param value the value to program for output (0 or 1). 152 */ 153 virtual void set(unsigned pin, int value) = 0; 154 155 /** 156 * \brief Setup multiple pins (generic API) 157 * \param mask the pins to actually set up. 158 * \param mode the mode for the pins (see Fix_mode). 159 * \param outvalue the value if configured as output. 160 */ 161 virtual void multi_setup(Pin_slice const &mask, unsigned mode, unsigned outvalue = 0) = 0; 162 163 /** 164 * \brief Configure multiple pads at once (platform specific API). 165 * \param mask the pads to configure. 166 * \param func the platform-specific sub-function to configure. 167 * \param value the platform-specific value to set for the sub-function. 168 * \see config_pad() 169 */ 170 virtual void multi_config_pad(Pin_slice const &mask, unsigned func, unsigned value) = 0; 171 172 /** 173 * \brief Set the value for multiple output pins at once. 174 * \param mask the pins that shall actually be set to the given values. 175 * \param data the bit-wise value for each pin to set (according to mask). 176 */ 177 virtual void multi_set(Pin_slice const &mask, unsigned data) = 0; 178 179 /** 180 * \brief Get the value for all pins at once. 181 */ 182 virtual unsigned multi_get(unsigned offset) = 0; 183 184 185 void output(unsigned pin, int value) 186 { setup(pin, Output, value); } 187 188 void input(unsigned pin) 189 { setup(pin, Input); } 190 191 void multi_output(Pin_slice const &mask, unsigned data) 192 { multi_setup(mask, mask.mask, data); } 193 194 void multi_input(Pin_slice const &mask) 195 { multi_setup(mask, ~mask.mask); } 196 }; 197 198 } 199 200 #else 201 202 typedef enum { 203 false = 0, 204 true = 1 205 } bool; 206 207 /// Modes used for setup() 208 enum Fix_mode 209 { 210 Fix_input = L4VBUS_GPIO_SETUP_INPUT, ///< Configure as input pin 211 Fix_output = L4VBUS_GPIO_SETUP_OUTPUT, ///< Configure as output pin 212 Fix_irq = L4VBUS_GPIO_SETUP_IRQ, ///< Configure as IRQ source 213 }; 214 215 /// Modes used for pull up / pull down (config_pull()) 216 enum Pull_mode 217 { 218 Pull_none = L4VBUS_GPIO_PIN_PULL_NONE, ///< No pull up or pull down resistors 219 Pull_up = L4VBUS_GPIO_PIN_PULL_UP, ///< Enable pull up resistor 220 Pull_down = L4VBUS_GPIO_PIN_PULL_DOWN, ///< Enable pull down resistor 221 }; 222 223 // Generic function options 224 enum Function_levels 225 { 226 Function_gpio, 227 Function_alt, 228 Function_irq, 229 }; 230 231 #endif /* __cplusplus */