gpio.h 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284
  1. /* Copyright 2019 SiFive, Inc */
  2. /* SPDX-License-Identifier: Apache-2.0 */
  3. #ifndef METAL__GPIO_H
  4. #define METAL__GPIO_H
  5. #include <metal/compiler.h>
  6. #include <metal/interrupt.h>
  7. /*!
  8. * @file gpio.h
  9. * @brief API for manipulating general-purpose input/output
  10. */
  11. struct metal_gpio;
  12. struct __metal_gpio_vtable {
  13. int (*disable_input)(struct metal_gpio *, long pins);
  14. int (*enable_input)(struct metal_gpio *, long pins);
  15. long (*input)(struct metal_gpio *);
  16. long (*output)(struct metal_gpio *);
  17. int (*disable_output)(struct metal_gpio *, long pins);
  18. int (*enable_output)(struct metal_gpio *, long pins);
  19. int (*output_set)(struct metal_gpio *, long value);
  20. int (*output_clear)(struct metal_gpio *, long value);
  21. int (*output_toggle)(struct metal_gpio *, long value);
  22. int (*enable_io)(struct metal_gpio *, long pins, long dest);
  23. int (*disable_io)(struct metal_gpio *, long pins);
  24. int (*config_int)(struct metal_gpio *, long pins, int intr_type);
  25. int (*clear_int)(struct metal_gpio *, long pins, int intr_type);
  26. struct metal_interrupt* (*interrupt_controller)(struct metal_gpio *gpio);
  27. int (*get_interrupt_id)(struct metal_gpio *gpio, int pin);
  28. };
  29. #define METAL_GPIO_INT_DISABLE 0
  30. #define METAL_GPIO_INT_RISING 1
  31. #define METAL_GPIO_INT_FALLING 2
  32. #define METAL_GPIO_INT_BOTH_EDGE 3
  33. #define METAL_GPIO_INT_LOW 4
  34. #define METAL_GPIO_INT_HIGH 5
  35. #define METAL_GPIO_INT_BOTH_LEVEL 6
  36. #define METAL_GPIO_INT_MAX 7
  37. /*!
  38. * @struct metal_gpio
  39. * @brief The handle for a GPIO interface
  40. */
  41. struct metal_gpio {
  42. const struct __metal_gpio_vtable *vtable;
  43. };
  44. /*!
  45. * @brief Get a GPIO device handle
  46. * @param device_num The GPIO device index
  47. * @return The GPIO device handle, or NULL if there is no device at that index
  48. */
  49. struct metal_gpio *metal_gpio_get_device(unsigned int device_num);
  50. /*!
  51. * @brief enable input on a pin
  52. * @param gpio The handle for the GPIO interface
  53. * @param pin The pin number indexed from 0
  54. * @return 0 if the input is successfully enabled
  55. */
  56. __inline__ int metal_gpio_enable_input(struct metal_gpio *gpio, int pin) {
  57. if(!gpio) {
  58. return 1;
  59. }
  60. return gpio->vtable->enable_input(gpio, (1 << pin));
  61. }
  62. /*!
  63. * @brief Disable input on a pin
  64. * @param gpio The handle for the GPIO interface
  65. * @param pin The pin number indexed from 0
  66. * @return 0 if the input is successfully disabled
  67. */
  68. __inline__ int metal_gpio_disable_input(struct metal_gpio *gpio, int pin) {
  69. if(!gpio) {
  70. return 1;
  71. }
  72. return gpio->vtable->disable_input(gpio, (1 << pin));
  73. }
  74. /*!
  75. * @brief Enable output on a pin
  76. * @param gpio The handle for the GPIO interface
  77. * @param pin The pin number indexed from 0
  78. * @return 0 if the output is successfully enabled
  79. */
  80. __inline__ int metal_gpio_enable_output(struct metal_gpio *gpio, int pin) {
  81. if(!gpio) {
  82. return 1;
  83. }
  84. return gpio->vtable->enable_output(gpio, (1 << pin));
  85. }
  86. /*!
  87. * @brief Disable output on a pin
  88. * @param gpio The handle for the GPIO interface
  89. * @param pin The pin number indexed from 0
  90. * @return 0 if the output is successfully disabled
  91. */
  92. __inline__ int metal_gpio_disable_output(struct metal_gpio *gpio, int pin) {
  93. if(!gpio) {
  94. return 1;
  95. }
  96. return gpio->vtable->disable_output(gpio, (1 << pin));
  97. }
  98. /*!
  99. * @brief Set the output value of a GPIO pin
  100. * @param gpio The handle for the GPIO interface
  101. * @param pin The pin number indexed from 0
  102. * @param value The value to set the pin to
  103. * @return 0 if the output is successfully set
  104. */
  105. __inline__ int metal_gpio_set_pin(struct metal_gpio *gpio, int pin, int value) {
  106. if(!gpio) {
  107. return 1;
  108. }
  109. if(value == 0) {
  110. return gpio->vtable->output_clear(gpio, (1 << pin));
  111. } else {
  112. return gpio->vtable->output_set(gpio, (1 << pin));
  113. }
  114. }
  115. /*!
  116. * @brief Get the value of the GPIO pin
  117. * @param gpio The handle for the GPIO interface
  118. * @param pin The pin number indexed from 0
  119. * @return The value of the GPIO pin
  120. */
  121. __inline__ int metal_gpio_get_input_pin(struct metal_gpio *gpio, int pin) {
  122. if(!gpio) {
  123. return 0;
  124. }
  125. long value = gpio->vtable->input(gpio);
  126. if(value & (1 << pin)) {
  127. return 1;
  128. } else {
  129. return 0;
  130. }
  131. }
  132. /*!
  133. * @brief Get the value of the GPIO pin
  134. * @param gpio The handle for the GPIO interface
  135. * @param pin The pin number indexed from 0
  136. * @return The value of the GPIO pin
  137. */
  138. __inline__ int metal_gpio_get_output_pin(struct metal_gpio *gpio, int pin) {
  139. if(!gpio) {
  140. return 0;
  141. }
  142. long value = gpio->vtable->output(gpio);
  143. if(value & (1 << pin)) {
  144. return 1;
  145. } else {
  146. return 0;
  147. }
  148. }
  149. /*!
  150. * @brief Clears the value of the GPIO pin
  151. * @param gpio The handle for the GPIO interface
  152. * @param pin The pin number indexed from 0
  153. * @return 0 if the pin is successfully cleared
  154. */
  155. __inline__ int metal_gpio_clear_pin(struct metal_gpio *gpio, int pin) {
  156. if(!gpio) {
  157. return 1;
  158. }
  159. return gpio->vtable->output_clear(gpio, (1 << pin));
  160. }
  161. /*!
  162. * @brief Toggles the value of the GPIO pin
  163. * @param gpio The handle for the GPIO interface
  164. * @param pin The pin number indexed from 0
  165. * @return 0 if the pin is successfully toggled
  166. */
  167. __inline__ int metal_gpio_toggle_pin(struct metal_gpio *gpio, int pin) {
  168. if(!gpio) {
  169. return 1;
  170. }
  171. return gpio->vtable->output_toggle(gpio, (1 << pin));
  172. }
  173. /*!
  174. * @brief Enables and sets the pinmux for a GPIO pin
  175. * @param gpio The handle for the GPIO interface
  176. * @param pin The bitmask for the pin to enable pinmux on
  177. * @param io_function The IO function to set
  178. * @return 0 if the pinmux is successfully set
  179. */
  180. __inline__ int metal_gpio_enable_pinmux(struct metal_gpio *gpio, int pin, int io_function) {
  181. if(!gpio) {
  182. return 1;
  183. }
  184. return gpio->vtable->enable_io(gpio, (1 << pin), (io_function << pin));
  185. }
  186. /*!
  187. * @brief Disables the pinmux for a GPIO pin
  188. * @param gpio The handle for the GPIO interface
  189. * @param pin The bitmask for the pin to disable pinmux on
  190. * @return 0 if the pinmux is successfully set
  191. */
  192. __inline__ int metal_gpio_disable_pinmux(struct metal_gpio *gpio, int pin) {
  193. if(!gpio) {
  194. return 1;
  195. }
  196. return gpio->vtable->disable_io(gpio, (1 << pin));
  197. }
  198. /*!
  199. * @brief Config gpio interrupt type
  200. * @param gpio The handle for the GPIO interface
  201. * @param pin The bitmask for the pin to enable gpio interrupt
  202. * @param intr_type The interrupt type
  203. * @return 0 if the interrupt mode is setup properly
  204. */
  205. __inline__ int metal_gpio_config_interrupt(struct metal_gpio *gpio, int pin, int intr_type) {
  206. if(!gpio) {
  207. return 1;
  208. }
  209. return gpio->vtable->config_int(gpio, (1 << pin), intr_type);
  210. }
  211. /*!
  212. * @brief Clear gpio interrupt status
  213. * @param gpio The handle for the GPIO interface
  214. * @param pin The bitmask for the pin to clear gpio interrupt
  215. * @param intr_type The interrupt type to be clear
  216. * @return 0 if the interrupt is cleared
  217. */
  218. __inline__ int metal_gpio_clear_interrupt(struct metal_gpio *gpio, int pin, int intr_type) {
  219. if(!gpio) {
  220. return 1;
  221. }
  222. return gpio->vtable->clear_int(gpio, (1 << pin), intr_type);
  223. }
  224. /*!
  225. * @brief Get the interrupt controller for a gpio
  226. *
  227. * @param gpio The handle for the gpio
  228. * @return A pointer to the interrupt controller responsible for handling
  229. * gpio interrupts.
  230. */
  231. __inline__ struct metal_interrupt*
  232. metal_gpio_interrupt_controller(struct metal_gpio *gpio) {
  233. return gpio->vtable->interrupt_controller(gpio);
  234. }
  235. /*!
  236. * @brief Get the interrupt id for a gpio
  237. *
  238. * @param gpio The handle for the gpio
  239. * @param pin The bitmask for the pin to get gpio interrupt id
  240. * @return The interrupt id corresponding to a gpio.
  241. */
  242. __inline__ int metal_gpio_get_interrupt_id(struct metal_gpio *gpio, int pin) {
  243. return gpio->vtable->get_interrupt_id(gpio, pin);
  244. }
  245. #endif