dev_pin_dm.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  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 "dev_pin_dm.h"
  11. static rt_size_t pin_total_nr = 0;
  12. static RT_DEFINE_SPINLOCK(pin_lock);
  13. static rt_list_t pin_nodes = RT_LIST_OBJECT_INIT(pin_nodes);
  14. static struct rt_device_pin *pin_device_find(rt_ubase_t pin)
  15. {
  16. struct rt_device_pin *gpio = RT_NULL, *gpio_tmp;
  17. rt_spin_lock(&pin_lock);
  18. rt_list_for_each_entry(gpio_tmp, &pin_nodes, list)
  19. {
  20. if (pin >= gpio_tmp->pin_start &&
  21. pin - gpio_tmp->pin_start < gpio_tmp->pin_nr)
  22. {
  23. gpio = gpio_tmp;
  24. break;
  25. }
  26. }
  27. rt_spin_unlock(&pin_lock);
  28. return gpio;
  29. }
  30. static void pin_api_mode(struct rt_device *device, rt_base_t pin, rt_uint8_t mode)
  31. {
  32. struct rt_device_pin *gpio = pin_device_find(pin);
  33. if (gpio && gpio->ops->pin_mode)
  34. {
  35. gpio->ops->pin_mode(&gpio->parent, pin - gpio->pin_start, mode);
  36. }
  37. }
  38. static void pin_api_write(struct rt_device *device, rt_base_t pin, rt_uint8_t value)
  39. {
  40. struct rt_device_pin *gpio = pin_device_find(pin);
  41. if (gpio && gpio->ops->pin_write)
  42. {
  43. gpio->ops->pin_write(&gpio->parent, pin - gpio->pin_start, value);
  44. }
  45. }
  46. static rt_ssize_t pin_api_read(struct rt_device *device, rt_base_t pin)
  47. {
  48. struct rt_device_pin *gpio = pin_device_find(pin);
  49. if (gpio && gpio->ops->pin_read)
  50. {
  51. return gpio->ops->pin_read(&gpio->parent, pin - gpio->pin_start);
  52. }
  53. return -RT_EINVAL;
  54. }
  55. static rt_err_t pin_api_attach_irq(struct rt_device *device, rt_base_t pin,
  56. rt_uint8_t mode, void (*hdr)(void *args), void *args)
  57. {
  58. struct rt_device_pin *gpio = pin_device_find(pin);
  59. if (gpio)
  60. {
  61. rt_base_t pin_index = pin - gpio->pin_start;
  62. if (!gpio->ops->pin_attach_irq)
  63. {
  64. rt_err_t err;
  65. struct rt_pin_irq_hdr *legacy_isr;
  66. if ((err = gpio->ops->pin_irq_mode(&gpio->parent, pin_index, mode)))
  67. {
  68. return err;
  69. }
  70. legacy_isr = &gpio->legacy_isr[pin_index];
  71. legacy_isr->pin = pin_index;
  72. legacy_isr->mode = mode;
  73. legacy_isr->hdr = hdr;
  74. legacy_isr->args = args;
  75. return RT_EOK;
  76. }
  77. else
  78. {
  79. return gpio->ops->pin_attach_irq(&gpio->parent, pin_index, mode, hdr, args);
  80. }
  81. }
  82. return -RT_EINVAL;
  83. }
  84. static rt_err_t pin_api_detach_irq(struct rt_device *device, rt_base_t pin)
  85. {
  86. struct rt_device_pin *gpio = pin_device_find(pin);
  87. if (gpio)
  88. {
  89. rt_base_t pin_index = pin - gpio->pin_start;
  90. if (!gpio->ops->pin_detach_irq)
  91. {
  92. struct rt_pin_irq_hdr *legacy_isr;
  93. legacy_isr = &gpio->legacy_isr[pin_index];
  94. rt_memset(legacy_isr, 0, sizeof(*legacy_isr));
  95. return RT_EOK;
  96. }
  97. else
  98. {
  99. return gpio->ops->pin_detach_irq(&gpio->parent, pin);
  100. }
  101. }
  102. return -RT_EINVAL;
  103. }
  104. static rt_err_t pin_api_irq_enable(struct rt_device *device, rt_base_t pin,
  105. rt_uint8_t enabled)
  106. {
  107. struct rt_device_pin *gpio = pin_device_find(pin);
  108. if (gpio && gpio->ops->pin_irq_enable)
  109. {
  110. return gpio->ops->pin_irq_enable(&gpio->parent, pin - gpio->pin_start, enabled);
  111. }
  112. return -RT_EINVAL;
  113. }
  114. static rt_base_t pin_api_get(const char *name)
  115. {
  116. rt_base_t res = -RT_EINVAL;
  117. struct rt_device_pin *gpio;
  118. rt_spin_lock(&pin_lock);
  119. rt_list_for_each_entry(gpio, &pin_nodes, list)
  120. {
  121. if (gpio->ops->pin_get && !(res = gpio->ops->pin_get(name)))
  122. {
  123. break;
  124. }
  125. }
  126. rt_spin_unlock(&pin_lock);
  127. return res;
  128. }
  129. static rt_err_t pin_api_debounce(struct rt_device *device, rt_base_t pin,
  130. rt_uint32_t debounce)
  131. {
  132. struct rt_device_pin *gpio = pin_device_find(pin);
  133. if (gpio && gpio->ops->pin_debounce)
  134. {
  135. return gpio->ops->pin_debounce(&gpio->parent, pin - gpio->pin_start, debounce);
  136. }
  137. return -RT_EINVAL;
  138. }
  139. static rt_err_t pin_api_irq_mode(struct rt_device *device, rt_base_t pin,
  140. rt_uint8_t mode)
  141. {
  142. struct rt_device_pin *gpio = pin_device_find(pin);
  143. if (gpio && gpio->ops->pin_irq_mode)
  144. {
  145. return gpio->ops->pin_irq_mode(&gpio->parent, pin - gpio->pin_start, mode);
  146. }
  147. return -RT_EINVAL;
  148. }
  149. static const struct rt_pin_ops pin_api_dm_ops =
  150. {
  151. .pin_mode = pin_api_mode,
  152. .pin_write = pin_api_write,
  153. .pin_read = pin_api_read,
  154. .pin_attach_irq = pin_api_attach_irq,
  155. .pin_detach_irq = pin_api_detach_irq,
  156. .pin_irq_enable = pin_api_irq_enable,
  157. .pin_get = pin_api_get,
  158. .pin_debounce = pin_api_debounce,
  159. .pin_irq_mode = pin_api_irq_mode,
  160. };
  161. rt_err_t pin_api_init(struct rt_device_pin *gpio, rt_size_t pin_nr)
  162. {
  163. rt_err_t err = RT_EOK;
  164. if (!gpio || !gpio->ops)
  165. {
  166. return -RT_EINVAL;
  167. }
  168. rt_spin_lock(&pin_lock);
  169. if (rt_list_isempty(&pin_nodes))
  170. {
  171. rt_spin_unlock(&pin_lock);
  172. rt_device_pin_register("gpio", &pin_api_dm_ops, RT_NULL);
  173. rt_spin_lock(&pin_lock);
  174. }
  175. gpio->pin_start = pin_total_nr;
  176. gpio->pin_nr = pin_nr;
  177. pin_total_nr += pin_nr;
  178. rt_list_init(&gpio->list);
  179. rt_list_insert_before(&pin_nodes, &gpio->list);
  180. rt_spin_unlock(&pin_lock);
  181. return err;
  182. }
  183. static void pin_dm_irq_mask(struct rt_pic_irq *pirq)
  184. {
  185. struct rt_device_pin *gpio = pirq->pic->priv_data;
  186. gpio->ops->pin_irq_enable(&gpio->parent, pirq->hwirq, 0);
  187. }
  188. static void pin_dm_irq_unmask(struct rt_pic_irq *pirq)
  189. {
  190. struct rt_device_pin *gpio = pirq->pic->priv_data;
  191. gpio->ops->pin_irq_enable(&gpio->parent, pirq->hwirq, 1);
  192. }
  193. static rt_err_t pin_dm_irq_set_triger_mode(struct rt_pic_irq *pirq, rt_uint32_t mode)
  194. {
  195. rt_uint8_t pin_mode;
  196. struct rt_device_pin *gpio = pirq->pic->priv_data;
  197. switch (mode)
  198. {
  199. case RT_IRQ_MODE_EDGE_RISING:
  200. pin_mode = PIN_IRQ_MODE_RISING;
  201. break;
  202. case RT_IRQ_MODE_EDGE_FALLING:
  203. pin_mode = PIN_IRQ_MODE_FALLING;
  204. break;
  205. case RT_IRQ_MODE_EDGE_BOTH:
  206. pin_mode = PIN_IRQ_MODE_RISING_FALLING;
  207. break;
  208. case RT_IRQ_MODE_LEVEL_HIGH:
  209. pin_mode = PIN_IRQ_MODE_HIGH_LEVEL;
  210. break;
  211. case RT_IRQ_MODE_LEVEL_LOW:
  212. pin_mode = PIN_IRQ_MODE_LOW_LEVEL;
  213. break;
  214. default:
  215. return -RT_ENOSYS;
  216. }
  217. return gpio->ops->pin_irq_mode(&gpio->parent, pirq->hwirq, pin_mode);
  218. }
  219. static int pin_dm_irq_map(struct rt_pic *pic, int hwirq, rt_uint32_t mode)
  220. {
  221. int irq = -1;
  222. struct rt_device_pin *gpio = pic->priv_data;
  223. struct rt_pic_irq *pirq = rt_pic_find_irq(pic, hwirq);
  224. if (pirq)
  225. {
  226. irq = rt_pic_config_irq(pic, hwirq, hwirq);
  227. if (irq >= 0)
  228. {
  229. rt_pic_cascade(pirq, gpio->irqchip.irq);
  230. rt_pic_irq_set_triger_mode(irq, mode);
  231. }
  232. }
  233. return irq;
  234. }
  235. static rt_err_t pin_dm_irq_parse(struct rt_pic *pic,
  236. struct rt_ofw_cell_args *args, struct rt_pic_irq *out_pirq)
  237. {
  238. rt_err_t err = RT_EOK;
  239. if (args->args_count == 2)
  240. {
  241. out_pirq->hwirq = args->args[0];
  242. out_pirq->mode = args->args[1] & RT_IRQ_MODE_MASK;
  243. }
  244. else
  245. {
  246. err = -RT_EINVAL;
  247. }
  248. return err;
  249. }
  250. const static struct rt_pic_ops pin_dm_ops =
  251. {
  252. .name = "GPIO",
  253. .irq_enable = pin_dm_irq_mask,
  254. .irq_disable = pin_dm_irq_unmask,
  255. .irq_mask = pin_dm_irq_mask,
  256. .irq_unmask = pin_dm_irq_unmask,
  257. .irq_set_triger_mode = pin_dm_irq_set_triger_mode,
  258. .irq_map = pin_dm_irq_map,
  259. .irq_parse = pin_dm_irq_parse,
  260. };
  261. rt_err_t pin_pic_handle_isr(struct rt_device_pin *gpio, rt_base_t pin)
  262. {
  263. rt_err_t err;
  264. if (gpio)
  265. {
  266. rt_ubase_t pin_index = pin;
  267. struct rt_pin_irqchip *irqchip = &gpio->irqchip;
  268. if (pin_index < gpio->pin_nr)
  269. {
  270. struct rt_pic_irq *pirq;
  271. struct rt_pin_irq_hdr *legacy_isr;
  272. pirq = rt_pic_find_irq(&irqchip->parent, pin_index);
  273. if (pirq->irq >= 0)
  274. {
  275. err = rt_pic_handle_isr(pirq);
  276. }
  277. else
  278. {
  279. err = -RT_EINVAL;
  280. }
  281. legacy_isr = &gpio->legacy_isr[pin_index];
  282. if (legacy_isr->hdr)
  283. {
  284. legacy_isr->hdr(legacy_isr->args);
  285. }
  286. }
  287. else
  288. {
  289. err = -RT_EINVAL;
  290. }
  291. }
  292. else
  293. {
  294. err = -RT_EINVAL;
  295. }
  296. return err;
  297. }
  298. rt_err_t pin_pic_init(struct rt_device_pin *gpio, int pin_irq)
  299. {
  300. rt_err_t err;
  301. if (gpio)
  302. {
  303. struct rt_pin_irqchip *irqchip = &gpio->irqchip;
  304. struct rt_pic *pic = &irqchip->parent;
  305. irqchip->irq = pin_irq;
  306. if (!gpio->pin_nr)
  307. {
  308. return -RT_EINVAL;
  309. }
  310. gpio->legacy_isr = rt_calloc(gpio->pin_nr, sizeof(*gpio->legacy_isr));
  311. if (!gpio->legacy_isr)
  312. {
  313. return -RT_ENOMEM;
  314. }
  315. pic->priv_data = gpio;
  316. pic->ops = &pin_dm_ops;
  317. /* Make sure the type of gpio for pic */
  318. gpio->parent.parent.type = RT_Object_Class_Device;
  319. rt_pic_default_name(&irqchip->parent);
  320. err = rt_pic_linear_irq(pic, gpio->pin_nr);
  321. rt_pic_user_extends(pic);
  322. err = RT_EOK;
  323. }
  324. else
  325. {
  326. err = -RT_EINVAL;
  327. }
  328. return err;
  329. }
  330. rt_ssize_t rt_pin_get_named_pin(struct rt_device *dev, const char *propname, int index,
  331. rt_uint8_t *out_mode, rt_uint8_t *out_value)
  332. {
  333. rt_ssize_t res = -RT_ENOSYS;
  334. RT_ASSERT(dev != RT_NULL);
  335. #ifdef RT_USING_OFW
  336. if (dev->ofw_node)
  337. {
  338. res = rt_ofw_get_named_pin(dev->ofw_node, propname, index, out_mode, out_value);
  339. }
  340. else
  341. {
  342. res = -RT_EINVAL;
  343. }
  344. #endif /* RT_USING_OFW */
  345. return res;
  346. }
  347. rt_ssize_t rt_pin_get_named_pin_count(struct rt_device *dev, const char *propname)
  348. {
  349. rt_ssize_t count = -RT_ENOSYS;
  350. RT_ASSERT(dev != RT_NULL);
  351. #ifdef RT_USING_OFW
  352. if (dev->ofw_node)
  353. {
  354. count = rt_ofw_get_named_pin_count(dev->ofw_node, propname);
  355. }
  356. else
  357. {
  358. count = -RT_EINVAL;
  359. }
  360. #endif /* RT_USING_OFW */
  361. return count;
  362. }