drv_gpio.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /* SPDX-License-Identifier: Apache-2.0 */
  2. /* Copyright (c) 2006-2018, RT-Thread Development Team
  3. * Copyright (c) 2020, duhuanpeng<548708880@qq.com>
  4. *
  5. * Change Logs:
  6. * Date Author Notes
  7. * 2015-01-20 Bernard the first version
  8. * 2017-10-20 ZYH add mode open drain and input pull down
  9. * 2020-06-01 Du Huanpeng GPIO driver based on <components/drivers/include/drivers/pin.h>
  10. */
  11. #include <rtthread.h>
  12. #include <drivers/pin.h>
  13. #include <rthw.h>
  14. #include <ls2k1000.h>
  15. struct loongson_gpio {
  16. rt_uint64_t GPIO0_OEN;
  17. rt_uint64_t GPIO1_OEN; /* Reserved */
  18. rt_uint64_t GPIO0_O;
  19. rt_uint64_t GPIO1_O; /* Reserved */
  20. rt_uint64_t GPIO0_I;
  21. rt_uint64_t GPIO1_I; /* Reserved */
  22. rt_uint64_t GPIO0_INTEN;
  23. rt_uint64_t GPIO1_INTEN; /* Reserved */
  24. };
  25. #ifdef RT_USING_PIN
  26. static void loongson_pin_mode(struct rt_device *device, rt_base_t pin, rt_base_t mode)
  27. {
  28. struct loongson_gpio *gpio;
  29. rt_uint64_t m;
  30. gpio = (void *)device->user_data;
  31. m = (rt_uint64_t)1 << pin;
  32. switch (mode) {
  33. case PIN_MODE_OUTPUT:
  34. gpio->GPIO0_OEN &= ~m;
  35. break;
  36. case PIN_MODE_INPUT:
  37. gpio->GPIO0_OEN |= m;
  38. break;
  39. case PIN_MODE_INPUT_PULLUP:
  40. gpio->GPIO0_OEN |= m;
  41. break;
  42. case PIN_MODE_INPUT_PULLDOWN:
  43. gpio->GPIO0_OEN |= m;
  44. break;
  45. case PIN_MODE_OUTPUT_OD:
  46. gpio->GPIO0_OEN &= ~m;
  47. break;
  48. default:
  49. /* error */
  50. rt_kprintf("error\n");
  51. }
  52. }
  53. static void loongson_pin_write(struct rt_device *device, rt_base_t pin, rt_base_t value)
  54. {
  55. struct loongson_gpio *gpio;
  56. rt_uint64_t m;
  57. if (pin < 0 || pin >= 60) {
  58. rt_kprintf("error\n");
  59. return;
  60. }
  61. gpio = (void *)device->user_data;
  62. m = (rt_uint64_t)1 << pin;
  63. if (value)
  64. gpio->GPIO0_O |= m;
  65. else
  66. gpio->GPIO0_O &= ~m;
  67. }
  68. static int loongson_pin_read(struct rt_device *device, rt_base_t pin)
  69. {
  70. struct loongson_gpio *gpio;
  71. int rc;
  72. gpio = (void *)device->user_data;
  73. rt_uint64_t m;
  74. m = gpio->GPIO1_I;
  75. m &= (rt_uint64_t)1 << pin;
  76. rc = !!m;
  77. return rc;
  78. }
  79. /* TODO: add GPIO interrupt */
  80. static rt_err_t loongson_pin_attach_irq(struct rt_device *device, rt_int32_t pin, rt_uint32_t mode, void (*hdr)(void *args), void *args)
  81. {
  82. struct loongson_gpio *gpio;
  83. gpio = (void *)device->user_data;
  84. return RT_EOK;
  85. }
  86. static rt_err_t loongson_pin_detach_irq(struct rt_device *device, rt_int32_t pin)
  87. {
  88. struct loongson_gpio *gpio;
  89. gpio = (void *)device->user_data;
  90. return RT_EOK;
  91. }
  92. static rt_err_t loongson_pin_irq_enable(struct rt_device *device, rt_base_t pin, rt_uint32_t enabled)
  93. {
  94. struct loongson_gpio *gpio;
  95. gpio = (void *)device->user_data;
  96. return RT_EOK;
  97. }
  98. static struct rt_pin_ops loongson_pin_ops = {
  99. .pin_mode = loongson_pin_mode,
  100. .pin_write = loongson_pin_write,
  101. .pin_read = loongson_pin_read,
  102. /* TODO: add GPIO interrupt */
  103. .pin_attach_irq = loongson_pin_attach_irq,
  104. .pin_detach_irq = loongson_pin_detach_irq,
  105. .pin_irq_enable = loongson_pin_irq_enable,
  106. };
  107. int loongson_pin_init(void)
  108. {
  109. int rc;
  110. static struct loongson_gpio *loongson_gpio_priv;
  111. loongson_gpio_priv = (void *)GPIO_BASE;
  112. rc = rt_device_pin_register("pin", &loongson_pin_ops, loongson_gpio_priv);
  113. return rc;
  114. }
  115. INIT_BOARD_EXPORT(loongson_pin_init);
  116. #endif /*RT_USING_PIN */