123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284 |
- /* Copyright 2019 SiFive, Inc */
- /* SPDX-License-Identifier: Apache-2.0 */
- #ifndef METAL__GPIO_H
- #define METAL__GPIO_H
- #include <metal/compiler.h>
- #include <metal/interrupt.h>
- /*!
- * @file gpio.h
- * @brief API for manipulating general-purpose input/output
- */
- struct metal_gpio;
- struct __metal_gpio_vtable {
- int (*disable_input)(struct metal_gpio *, long pins);
- int (*enable_input)(struct metal_gpio *, long pins);
- long (*input)(struct metal_gpio *);
- long (*output)(struct metal_gpio *);
- int (*disable_output)(struct metal_gpio *, long pins);
- int (*enable_output)(struct metal_gpio *, long pins);
- int (*output_set)(struct metal_gpio *, long value);
- int (*output_clear)(struct metal_gpio *, long value);
- int (*output_toggle)(struct metal_gpio *, long value);
- int (*enable_io)(struct metal_gpio *, long pins, long dest);
- int (*disable_io)(struct metal_gpio *, long pins);
- int (*config_int)(struct metal_gpio *, long pins, int intr_type);
- int (*clear_int)(struct metal_gpio *, long pins, int intr_type);
- struct metal_interrupt* (*interrupt_controller)(struct metal_gpio *gpio);
- int (*get_interrupt_id)(struct metal_gpio *gpio, int pin);
- };
- #define METAL_GPIO_INT_DISABLE 0
- #define METAL_GPIO_INT_RISING 1
- #define METAL_GPIO_INT_FALLING 2
- #define METAL_GPIO_INT_BOTH_EDGE 3
- #define METAL_GPIO_INT_LOW 4
- #define METAL_GPIO_INT_HIGH 5
- #define METAL_GPIO_INT_BOTH_LEVEL 6
- #define METAL_GPIO_INT_MAX 7
- /*!
- * @struct metal_gpio
- * @brief The handle for a GPIO interface
- */
- struct metal_gpio {
- const struct __metal_gpio_vtable *vtable;
- };
- /*!
- * @brief Get a GPIO device handle
- * @param device_num The GPIO device index
- * @return The GPIO device handle, or NULL if there is no device at that index
- */
- struct metal_gpio *metal_gpio_get_device(unsigned int device_num);
- /*!
- * @brief enable input on a pin
- * @param gpio The handle for the GPIO interface
- * @param pin The pin number indexed from 0
- * @return 0 if the input is successfully enabled
- */
- __inline__ int metal_gpio_enable_input(struct metal_gpio *gpio, int pin) {
- if(!gpio) {
- return 1;
- }
- return gpio->vtable->enable_input(gpio, (1 << pin));
- }
- /*!
- * @brief Disable input on a pin
- * @param gpio The handle for the GPIO interface
- * @param pin The pin number indexed from 0
- * @return 0 if the input is successfully disabled
- */
- __inline__ int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) {
- if(!gpio) {
- return 1;
- }
- return gpio->vtable->disable_input(gpio, (1 << pin));
- }
- /*!
- * @brief Enable output on a pin
- * @param gpio The handle for the GPIO interface
- * @param pin The pin number indexed from 0
- * @return 0 if the output is successfully enabled
- */
- __inline__ int metal_gpio_enable_output(struct metal_gpio *gpio, int pin) {
- if(!gpio) {
- return 1;
- }
- return gpio->vtable->enable_output(gpio, (1 << pin));
- }
- /*!
- * @brief Disable output on a pin
- * @param gpio The handle for the GPIO interface
- * @param pin The pin number indexed from 0
- * @return 0 if the output is successfully disabled
- */
- __inline__ int metal_gpio_disable_output(struct metal_gpio *gpio, int pin) {
- if(!gpio) {
- return 1;
- }
- return gpio->vtable->disable_output(gpio, (1 << pin));
- }
- /*!
- * @brief Set the output value of a GPIO pin
- * @param gpio The handle for the GPIO interface
- * @param pin The pin number indexed from 0
- * @param value The value to set the pin to
- * @return 0 if the output is successfully set
- */
- __inline__ int metal_gpio_set_pin(struct metal_gpio *gpio, int pin, int value) {
- if(!gpio) {
- return 1;
- }
- if(value == 0) {
- return gpio->vtable->output_clear(gpio, (1 << pin));
- } else {
- return gpio->vtable->output_set(gpio, (1 << pin));
- }
- }
- /*!
- * @brief Get the value of the GPIO pin
- * @param gpio The handle for the GPIO interface
- * @param pin The pin number indexed from 0
- * @return The value of the GPIO pin
- */
- __inline__ int metal_gpio_get_input_pin(struct metal_gpio *gpio, int pin) {
- if(!gpio) {
- return 0;
- }
- long value = gpio->vtable->input(gpio);
- if(value & (1 << pin)) {
- return 1;
- } else {
- return 0;
- }
- }
- /*!
- * @brief Get the value of the GPIO pin
- * @param gpio The handle for the GPIO interface
- * @param pin The pin number indexed from 0
- * @return The value of the GPIO pin
- */
- __inline__ int metal_gpio_get_output_pin(struct metal_gpio *gpio, int pin) {
- if(!gpio) {
- return 0;
- }
- long value = gpio->vtable->output(gpio);
- if(value & (1 << pin)) {
- return 1;
- } else {
- return 0;
- }
- }
- /*!
- * @brief Clears the value of the GPIO pin
- * @param gpio The handle for the GPIO interface
- * @param pin The pin number indexed from 0
- * @return 0 if the pin is successfully cleared
- */
- __inline__ int metal_gpio_clear_pin(struct metal_gpio *gpio, int pin) {
- if(!gpio) {
- return 1;
- }
- return gpio->vtable->output_clear(gpio, (1 << pin));
- }
- /*!
- * @brief Toggles the value of the GPIO pin
- * @param gpio The handle for the GPIO interface
- * @param pin The pin number indexed from 0
- * @return 0 if the pin is successfully toggled
- */
- __inline__ int metal_gpio_toggle_pin(struct metal_gpio *gpio, int pin) {
- if(!gpio) {
- return 1;
- }
- return gpio->vtable->output_toggle(gpio, (1 << pin));
- }
- /*!
- * @brief Enables and sets the pinmux for a GPIO pin
- * @param gpio The handle for the GPIO interface
- * @param pin The bitmask for the pin to enable pinmux on
- * @param io_function The IO function to set
- * @return 0 if the pinmux is successfully set
- */
- __inline__ int metal_gpio_enable_pinmux(struct metal_gpio *gpio, int pin, int io_function) {
- if(!gpio) {
- return 1;
- }
- return gpio->vtable->enable_io(gpio, (1 << pin), (io_function << pin));
- }
- /*!
- * @brief Disables the pinmux for a GPIO pin
- * @param gpio The handle for the GPIO interface
- * @param pin The bitmask for the pin to disable pinmux on
- * @return 0 if the pinmux is successfully set
- */
- __inline__ int metal_gpio_disable_pinmux(struct metal_gpio *gpio, int pin) {
- if(!gpio) {
- return 1;
- }
- return gpio->vtable->disable_io(gpio, (1 << pin));
- }
- /*!
- * @brief Config gpio interrupt type
- * @param gpio The handle for the GPIO interface
- * @param pin The bitmask for the pin to enable gpio interrupt
- * @param intr_type The interrupt type
- * @return 0 if the interrupt mode is setup properly
- */
- __inline__ int metal_gpio_config_interrupt(struct metal_gpio *gpio, int pin, int intr_type) {
- if(!gpio) {
- return 1;
- }
- return gpio->vtable->config_int(gpio, (1 << pin), intr_type);
- }
- /*!
- * @brief Clear gpio interrupt status
- * @param gpio The handle for the GPIO interface
- * @param pin The bitmask for the pin to clear gpio interrupt
- * @param intr_type The interrupt type to be clear
- * @return 0 if the interrupt is cleared
- */
- __inline__ int metal_gpio_clear_interrupt(struct metal_gpio *gpio, int pin, int intr_type) {
- if(!gpio) {
- return 1;
- }
- return gpio->vtable->clear_int(gpio, (1 << pin), intr_type);
- }
- /*!
- * @brief Get the interrupt controller for a gpio
- *
- * @param gpio The handle for the gpio
- * @return A pointer to the interrupt controller responsible for handling
- * gpio interrupts.
- */
- __inline__ struct metal_interrupt*
- metal_gpio_interrupt_controller(struct metal_gpio *gpio) {
- return gpio->vtable->interrupt_controller(gpio);
- }
- /*!
- * @brief Get the interrupt id for a gpio
- *
- * @param gpio The handle for the gpio
- * @param pin The bitmask for the pin to get gpio interrupt id
- * @return The interrupt id corresponding to a gpio.
- */
- __inline__ int metal_gpio_get_interrupt_id(struct metal_gpio *gpio, int pin) {
- return gpio->vtable->get_interrupt_id(gpio, pin);
- }
- #endif
|