pin_dm.c 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. * Copyright (c) 2006-2022, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2022-11-26 GuEe-GUI first version
  9. */
  10. #include "pin_dm.h"
  11. static void pin_dm_irq_mask(struct rt_pic_irq *pirq)
  12. {
  13. struct rt_device_pin *gpio = pirq->pic->priv_data;
  14. gpio->ops->pin_irq_enable(&gpio->parent, pirq->hwirq, 0);
  15. }
  16. static void pin_dm_irq_unmask(struct rt_pic_irq *pirq)
  17. {
  18. struct rt_device_pin *gpio = pirq->pic->priv_data;
  19. gpio->ops->pin_irq_enable(&gpio->parent, pirq->hwirq, 1);
  20. }
  21. static rt_err_t pin_dm_irq_set_triger_mode(struct rt_pic_irq *pirq, rt_uint32_t mode)
  22. {
  23. rt_uint8_t pin_mode;
  24. struct rt_device_pin *gpio = pirq->pic->priv_data;
  25. switch (mode)
  26. {
  27. case RT_IRQ_MODE_EDGE_RISING:
  28. pin_mode = PIN_IRQ_MODE_RISING;
  29. break;
  30. case RT_IRQ_MODE_EDGE_FALLING:
  31. pin_mode = PIN_IRQ_MODE_FALLING;
  32. break;
  33. case RT_IRQ_MODE_EDGE_BOTH:
  34. pin_mode = PIN_IRQ_MODE_RISING_FALLING;
  35. break;
  36. case RT_IRQ_MODE_LEVEL_HIGH:
  37. pin_mode = PIN_IRQ_MODE_HIGH_LEVEL;
  38. break;
  39. case RT_IRQ_MODE_LEVEL_LOW:
  40. pin_mode = PIN_IRQ_MODE_LOW_LEVEL;
  41. break;
  42. default:
  43. return -RT_ENOSYS;
  44. }
  45. return gpio->ops->pin_irq_mode(&gpio->parent, pirq->hwirq, pin_mode);
  46. }
  47. static int pin_dm_irq_map(struct rt_pic *pic, int hwirq, rt_uint32_t mode)
  48. {
  49. int irq = -1;
  50. struct rt_device_pin *gpio = pic->priv_data;
  51. struct rt_pic_irq *pirq = rt_pic_find_irq(pic, hwirq);
  52. if (pirq)
  53. {
  54. irq = rt_pic_config_irq(pic, hwirq, hwirq);
  55. if (irq >= 0)
  56. {
  57. rt_pic_cascade(pirq, gpio->irqchip.irq);
  58. rt_pic_irq_set_triger_mode(irq, mode);
  59. }
  60. }
  61. return irq;
  62. }
  63. static rt_err_t pin_dm_irq_parse(struct rt_pic *pic, struct rt_ofw_cell_args *args, struct rt_pic_irq *out_pirq)
  64. {
  65. rt_err_t err = RT_EOK;
  66. if (args->args_count == 2)
  67. {
  68. out_pirq->hwirq = args->args[0];
  69. out_pirq->mode = args->args[1] & RT_IRQ_MODE_MASK;
  70. }
  71. else
  72. {
  73. err = -RT_EINVAL;
  74. }
  75. return err;
  76. }
  77. static struct rt_pic_ops pin_dm_ops =
  78. {
  79. .name = "GPIO",
  80. .irq_enable = pin_dm_irq_mask,
  81. .irq_disable = pin_dm_irq_unmask,
  82. .irq_mask = pin_dm_irq_mask,
  83. .irq_unmask = pin_dm_irq_unmask,
  84. .irq_set_triger_mode = pin_dm_irq_set_triger_mode,
  85. .irq_map = pin_dm_irq_map,
  86. .irq_parse = pin_dm_irq_parse,
  87. };
  88. rt_err_t pin_pic_handle_isr(struct rt_device_pin *gpio, rt_base_t pin)
  89. {
  90. rt_err_t err;
  91. if (gpio)
  92. {
  93. struct rt_pin_irqchip *irqchip = &gpio->irqchip;
  94. if (pin >= irqchip->pin_range[0] && pin <= irqchip->pin_range[1])
  95. {
  96. struct rt_pic_irq *pirq;
  97. pirq = rt_pic_find_irq(&irqchip->parent, pin - irqchip->pin_range[0]);
  98. if (pirq->irq >= 0)
  99. {
  100. err = rt_pic_handle_isr(pirq);
  101. }
  102. else
  103. {
  104. err = -RT_EINVAL;
  105. }
  106. }
  107. else
  108. {
  109. err = -RT_EINVAL;
  110. }
  111. }
  112. else
  113. {
  114. err = -RT_EINVAL;
  115. }
  116. return err;
  117. }
  118. rt_err_t pin_pic_init(struct rt_device_pin *gpio)
  119. {
  120. rt_err_t err;
  121. if (gpio)
  122. {
  123. struct rt_pin_irqchip *irqchip = &gpio->irqchip;
  124. if (irqchip->pin_range[0] >= 0 && irqchip->pin_range[1] >= irqchip->pin_range[0])
  125. {
  126. struct rt_pic *pic = &irqchip->parent;
  127. rt_size_t pin_nr = irqchip->pin_range[1] - irqchip->pin_range[0] + 1;
  128. pic->priv_data = gpio;
  129. pic->ops = &pin_dm_ops;
  130. /* Make sure the type of gpio for pic */
  131. gpio->parent.parent.type = RT_Object_Class_Device;
  132. rt_pic_default_name(&irqchip->parent);
  133. err = rt_pic_linear_irq(pic, pin_nr);
  134. rt_pic_user_extends(pic);
  135. }
  136. else
  137. {
  138. err = -RT_EINVAL;
  139. }
  140. }
  141. else
  142. {
  143. err = -RT_EINVAL;
  144. }
  145. return err;
  146. }
  147. rt_ssize_t rt_pin_get_named_pin(struct rt_device *dev, const char *propname, int index,
  148. rt_uint8_t *out_mode, rt_uint8_t *out_value)
  149. {
  150. rt_ssize_t res = -RT_ENOSYS;
  151. RT_ASSERT(dev != RT_NULL);
  152. #ifdef RT_USING_OFW
  153. if (dev->ofw_node)
  154. {
  155. res = rt_ofw_get_named_pin(dev->ofw_node, propname, index, out_mode, out_value);
  156. }
  157. else
  158. {
  159. res = -RT_EINVAL;
  160. }
  161. #endif /* RT_USING_OFW */
  162. return res;
  163. }
  164. rt_ssize_t rt_pin_get_named_pin_count(struct rt_device *dev, const char *propname)
  165. {
  166. rt_ssize_t count = -RT_ENOSYS;
  167. RT_ASSERT(dev != RT_NULL);
  168. #ifdef RT_USING_OFW
  169. if (dev->ofw_node)
  170. {
  171. count = rt_ofw_get_named_pin_count(dev->ofw_node, propname);
  172. }
  173. else
  174. {
  175. count = -RT_EINVAL;
  176. }
  177. #endif /* RT_USING_OFW */
  178. return count;
  179. }