1 /* Copyright 2019 SiFive, Inc */
2 /* SPDX-License-Identifier: Apache-2.0 */
7 #include <metal/compiler.h>
8 #include <metal/interrupt.h>
12 * @brief API for manipulating general-purpose input/output
17 struct __metal_gpio_vtable {
18 int (*disable_input)(struct metal_gpio *, long pins);
19 int (*enable_input)(struct metal_gpio *, long pins);
20 long (*input)(struct metal_gpio *);
21 long (*output)(struct metal_gpio *);
22 int (*disable_output)(struct metal_gpio *, long pins);
23 int (*enable_output)(struct metal_gpio *, long pins);
24 int (*output_set)(struct metal_gpio *, long value);
25 int (*output_clear)(struct metal_gpio *, long value);
26 int (*output_toggle)(struct metal_gpio *, long value);
27 int (*enable_io)(struct metal_gpio *, long pins, long dest);
28 int (*disable_io)(struct metal_gpio *, long pins);
29 int (*config_int)(struct metal_gpio *, long pins, int intr_type);
30 int (*clear_int)(struct metal_gpio *, long pins, int intr_type);
31 struct metal_interrupt* (*interrupt_controller)(struct metal_gpio *gpio);
32 int (*get_interrupt_id)(struct metal_gpio *gpio, int pin);
35 #define METAL_GPIO_INT_DISABLE 0
36 #define METAL_GPIO_INT_RISING 1
37 #define METAL_GPIO_INT_FALLING 2
38 #define METAL_GPIO_INT_BOTH_EDGE 3
39 #define METAL_GPIO_INT_LOW 4
40 #define METAL_GPIO_INT_HIGH 5
41 #define METAL_GPIO_INT_BOTH_LEVEL 6
42 #define METAL_GPIO_INT_MAX 7
46 * @brief The handle for a GPIO interface
49 const struct __metal_gpio_vtable *vtable;
53 * @brief Get a GPIO device handle
54 * @param device_num The GPIO device index
55 * @return The GPIO device handle, or NULL if there is no device at that index
57 struct metal_gpio *metal_gpio_get_device(unsigned int device_num);
60 * @brief enable input on a pin
61 * @param gpio The handle for the GPIO interface
62 * @param pin The pin number indexed from 0
63 * @return 0 if the input is successfully enabled
65 __inline__ int metal_gpio_enable_input(struct metal_gpio *gpio, int pin) {
70 return gpio->vtable->enable_input(gpio, (1 << pin));
74 * @brief Disable input on a pin
75 * @param gpio The handle for the GPIO interface
76 * @param pin The pin number indexed from 0
77 * @return 0 if the input is successfully disabled
79 __inline__ int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) {
84 return gpio->vtable->disable_input(gpio, (1 << pin));
88 * @brief Enable output on a pin
89 * @param gpio The handle for the GPIO interface
90 * @param pin The pin number indexed from 0
91 * @return 0 if the output is successfully enabled
93 __inline__ int metal_gpio_enable_output(struct metal_gpio *gpio, int pin) {
98 return gpio->vtable->enable_output(gpio, (1 << pin));
102 * @brief Disable output on a pin
103 * @param gpio The handle for the GPIO interface
104 * @param pin The pin number indexed from 0
105 * @return 0 if the output is successfully disabled
107 __inline__ int metal_gpio_disable_output(struct metal_gpio *gpio, int pin) {
112 return gpio->vtable->disable_output(gpio, (1 << pin));
116 * @brief Set the output value of a GPIO pin
117 * @param gpio The handle for the GPIO interface
118 * @param pin The pin number indexed from 0
119 * @param value The value to set the pin to
120 * @return 0 if the output is successfully set
122 __inline__ int metal_gpio_set_pin(struct metal_gpio *gpio, int pin, int value) {
128 return gpio->vtable->output_clear(gpio, (1 << pin));
130 return gpio->vtable->output_set(gpio, (1 << pin));
135 * @brief Get the value of the GPIO pin
136 * @param gpio The handle for the GPIO interface
137 * @param pin The pin number indexed from 0
138 * @return The value of the GPIO pin
140 __inline__ int metal_gpio_get_input_pin(struct metal_gpio *gpio, int pin) {
145 long value = gpio->vtable->input(gpio);
147 if(value & (1 << pin)) {
155 * @brief Get the value of the GPIO pin
156 * @param gpio The handle for the GPIO interface
157 * @param pin The pin number indexed from 0
158 * @return The value of the GPIO pin
160 __inline__ int metal_gpio_get_output_pin(struct metal_gpio *gpio, int pin) {
165 long value = gpio->vtable->output(gpio);
167 if(value & (1 << pin)) {
175 * @brief Clears the value of the GPIO pin
176 * @param gpio The handle for the GPIO interface
177 * @param pin The pin number indexed from 0
178 * @return 0 if the pin is successfully cleared
180 __inline__ int metal_gpio_clear_pin(struct metal_gpio *gpio, int pin) {
185 return gpio->vtable->output_clear(gpio, (1 << pin));
189 * @brief Toggles the value of the GPIO pin
190 * @param gpio The handle for the GPIO interface
191 * @param pin The pin number indexed from 0
192 * @return 0 if the pin is successfully toggled
194 __inline__ int metal_gpio_toggle_pin(struct metal_gpio *gpio, int pin) {
199 return gpio->vtable->output_toggle(gpio, (1 << pin));
203 * @brief Enables and sets the pinmux for a GPIO pin
204 * @param gpio The handle for the GPIO interface
205 * @param pin The bitmask for the pin to enable pinmux on
206 * @param io_function The IO function to set
207 * @return 0 if the pinmux is successfully set
209 __inline__ int metal_gpio_enable_pinmux(struct metal_gpio *gpio, int pin, int io_function) {
214 return gpio->vtable->enable_io(gpio, (1 << pin), (io_function << pin));
218 * @brief Disables the pinmux for a GPIO pin
219 * @param gpio The handle for the GPIO interface
220 * @param pin The bitmask for the pin to disable pinmux on
221 * @return 0 if the pinmux is successfully set
223 __inline__ int metal_gpio_disable_pinmux(struct metal_gpio *gpio, int pin) {
228 return gpio->vtable->disable_io(gpio, (1 << pin));
232 * @brief Config gpio interrupt type
233 * @param gpio The handle for the GPIO interface
234 * @param pin The bitmask for the pin to enable gpio interrupt
235 * @param intr_type The interrupt type
236 * @return 0 if the interrupt mode is setup properly
238 __inline__ int metal_gpio_config_interrupt(struct metal_gpio *gpio, int pin, int intr_type) {
243 return gpio->vtable->config_int(gpio, (1 << pin), intr_type);
247 * @brief Clear gpio interrupt status
248 * @param gpio The handle for the GPIO interface
249 * @param pin The bitmask for the pin to clear gpio interrupt
250 * @param intr_type The interrupt type to be clear
251 * @return 0 if the interrupt is cleared
253 __inline__ int metal_gpio_clear_interrupt(struct metal_gpio *gpio, int pin, int intr_type) {
258 return gpio->vtable->clear_int(gpio, (1 << pin), intr_type);
262 * @brief Get the interrupt controller for a gpio
264 * @param gpio The handle for the gpio
265 * @return A pointer to the interrupt controller responsible for handling
268 __inline__ struct metal_interrupt*
269 metal_gpio_interrupt_controller(struct metal_gpio *gpio) {
270 return gpio->vtable->interrupt_controller(gpio);
274 * @brief Get the interrupt id for a gpio
276 * @param gpio The handle for the gpio
277 * @param pin The bitmask for the pin to get gpio interrupt id
278 * @return The interrupt id corresponding to a gpio.
280 __inline__ int metal_gpio_get_interrupt_id(struct metal_gpio *gpio, int pin) {
281 return gpio->vtable->get_interrupt_id(gpio, pin);