regulator-gpio.c 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309
  1. /*
  2. * Copyright (c) 2006-2023, RT-Thread Development Team
  3. *
  4. * SPDX-License-Identifier: Apache-2.0
  5. *
  6. * Change Logs:
  7. * Date Author Notes
  8. * 2023-09-23 GuEe-GUI first version
  9. */
  10. #include <dt-bindings/pin/state.h>
  11. #include "regulator_dm.h"
  12. struct regulator_gpio_state
  13. {
  14. rt_uint32_t value;
  15. rt_uint32_t gpios;
  16. };
  17. struct regulator_gpio_desc
  18. {
  19. rt_base_t pin;
  20. rt_uint32_t flags;
  21. };
  22. struct regulator_gpio
  23. {
  24. struct rt_regulator_node parent;
  25. rt_base_t enable_pin;
  26. rt_size_t pins_nr;
  27. struct regulator_gpio_desc *pins_desc;
  28. int state;
  29. rt_size_t states_nr;
  30. struct regulator_gpio_state *states;
  31. const char *input_supply;
  32. rt_uint32_t startup_delay;
  33. rt_uint32_t off_on_delay;
  34. rt_bool_t enabled_at_boot;
  35. struct rt_regulator_param param;
  36. };
  37. #define raw_to_regulator_gpio(raw) rt_container_of(raw, struct regulator_gpio, parent)
  38. static rt_err_t regulator_gpio_enable(struct rt_regulator_node *reg_np)
  39. {
  40. struct regulator_gpio *rg = raw_to_regulator_gpio(reg_np);
  41. struct rt_regulator_param *param = &rg->param;
  42. if (param->always_on)
  43. {
  44. return RT_EOK;
  45. }
  46. if (rg->enable_pin >= 0)
  47. {
  48. rt_pin_mode(rg->enable_pin, PIN_MODE_OUTPUT);
  49. rt_pin_write(rg->enable_pin, param->enable_active_high ? PIN_HIGH : PIN_LOW);
  50. }
  51. return RT_EOK;
  52. }
  53. static rt_err_t regulator_gpio_disable(struct rt_regulator_node *reg_np)
  54. {
  55. struct regulator_gpio *rg = raw_to_regulator_gpio(reg_np);
  56. struct rt_regulator_param *param = &rg->param;
  57. if (param->always_on)
  58. {
  59. return RT_EOK;
  60. }
  61. if (rg->enable_pin >= 0)
  62. {
  63. rt_pin_mode(rg->enable_pin, PIN_MODE_OUTPUT);
  64. rt_pin_write(rg->enable_pin, param->enable_active_high ? PIN_LOW : PIN_HIGH);
  65. }
  66. return RT_EOK;
  67. }
  68. static rt_bool_t regulator_gpio_is_enabled(struct rt_regulator_node *reg_np)
  69. {
  70. struct regulator_gpio *rg = raw_to_regulator_gpio(reg_np);
  71. struct rt_regulator_param *param = &rg->param;
  72. if (param->always_on)
  73. {
  74. return RT_TRUE;
  75. }
  76. if (rg->enable_pin >= 0)
  77. {
  78. rt_uint8_t active_val = param->enable_active_high ? PIN_LOW : PIN_HIGH;
  79. rt_pin_mode(rg->enable_pin, PIN_MODE_INPUT);
  80. return rt_pin_read(rg->enable_pin) == active_val;
  81. }
  82. return RT_TRUE;
  83. }
  84. static rt_err_t regulator_gpio_set_voltage(struct rt_regulator_node *reg_np,
  85. int min_uvolt, int max_uvolt)
  86. {
  87. int target = 0, best_val = RT_REGULATOR_UVOLT_INVALID;
  88. struct regulator_gpio *rg = raw_to_regulator_gpio(reg_np);
  89. for (int i = 0; i < rg->states_nr; ++i)
  90. {
  91. struct regulator_gpio_state *state = &rg->states[i];
  92. if (state->value < best_val &&
  93. state->value >= min_uvolt &&
  94. state->value <= max_uvolt)
  95. {
  96. target = state->gpios;
  97. best_val = state->value;
  98. }
  99. }
  100. if (best_val == RT_REGULATOR_UVOLT_INVALID)
  101. {
  102. return -RT_EINVAL;
  103. }
  104. for (int i = 0; i < rg->pins_nr; ++i)
  105. {
  106. int state = (target >> i) & 1;
  107. struct regulator_gpio_desc *gpiod = &rg->pins_desc[i];
  108. rt_pin_mode(gpiod->pin, PIN_MODE_OUTPUT);
  109. rt_pin_write(gpiod->pin, gpiod->flags == PIND_OUT_HIGH ? state : !state);
  110. }
  111. rg->state = target;
  112. return RT_EOK;
  113. }
  114. static int regulator_gpio_get_voltage(struct rt_regulator_node *reg_np)
  115. {
  116. struct regulator_gpio *rg = raw_to_regulator_gpio(reg_np);
  117. for (int i = 0; i < rg->states_nr; ++i)
  118. {
  119. if (rg->states[i].gpios == rg->state)
  120. {
  121. return rg->states[i].value;
  122. }
  123. }
  124. return -RT_EINVAL;
  125. }
  126. static const struct rt_regulator_ops regulator_gpio_ops =
  127. {
  128. .enable = regulator_gpio_enable,
  129. .disable = regulator_gpio_disable,
  130. .is_enabled = regulator_gpio_is_enabled,
  131. .set_voltage = regulator_gpio_set_voltage,
  132. .get_voltage = regulator_gpio_get_voltage,
  133. };
  134. static rt_err_t regulator_gpio_probe(struct rt_platform_device *pdev)
  135. {
  136. rt_err_t err;
  137. struct rt_device *dev = &pdev->parent;
  138. struct regulator_gpio *rg = rt_calloc(1, sizeof(*rg));
  139. struct rt_regulator_node *rgp;
  140. if (!rg)
  141. {
  142. return -RT_ENOMEM;
  143. }
  144. regulator_ofw_parse(dev->ofw_node, &rg->param);
  145. rgp = &rg->parent;
  146. rgp->supply_name = rg->param.name;
  147. rgp->ops = &regulator_gpio_ops;
  148. rgp->param = &rg->param;
  149. rgp->dev = &pdev->parent;
  150. rt_dm_dev_prop_read_u32(dev, "startup-delay-us", &rg->startup_delay);
  151. rt_dm_dev_prop_read_u32(dev, "off-on-delay-us", &rg->off_on_delay);
  152. /* GPIO flags are ignored, we check by enable-active-high */
  153. rg->enable_pin = rt_pin_get_named_pin(dev, "enable", 0, RT_NULL, RT_NULL);
  154. if (rg->enable_pin < 0 && rg->enable_pin != PIN_NONE)
  155. {
  156. err = rg->enable_pin;
  157. goto _fail;
  158. }
  159. rg->pins_nr = rt_pin_get_named_pin_count(dev, "gpios");
  160. if (rg->pins_nr > 0)
  161. {
  162. rg->pins_desc = rt_malloc(sizeof(*rg->pins_desc) * rg->pins_nr);
  163. if (!rg->pins_desc)
  164. {
  165. err = -RT_ENOMEM;
  166. goto _fail;
  167. }
  168. for (int i = 0; i < rg->pins_nr; ++i)
  169. {
  170. rt_uint32_t val;
  171. struct regulator_gpio_desc *gpiod = &rg->pins_desc[i];
  172. gpiod->pin = rt_pin_get_named_pin(dev, RT_NULL, i, RT_NULL, RT_NULL);
  173. if (gpiod->pin < 0)
  174. {
  175. err = gpiod->pin;
  176. goto _fail;
  177. }
  178. if (rt_dm_dev_prop_read_u32_index(dev, "gpios-states", i, &val) < 0)
  179. {
  180. gpiod->flags = PIND_OUT_HIGH;
  181. }
  182. else
  183. {
  184. gpiod->flags = val ? PIND_OUT_HIGH : PIND_OUT_LOW;
  185. }
  186. if (gpiod->flags == PIND_OUT_HIGH)
  187. {
  188. rg->state |= 1 << i;
  189. }
  190. }
  191. }
  192. rg->states_nr = rt_dm_dev_prop_count_of_u32(dev, "states") / 2;
  193. if (rg->states_nr < 0)
  194. {
  195. err = -RT_EIO;
  196. goto _fail;
  197. }
  198. rg->states = rt_malloc(sizeof(*rg->states) * rg->states_nr);
  199. if (!rg->states)
  200. {
  201. err = -RT_ENOMEM;
  202. goto _fail;
  203. }
  204. for (int i = 0; i < rg->states_nr; ++i)
  205. {
  206. rt_dm_dev_prop_read_u32_index(dev, "states", i * 2, &rg->states[i].value);
  207. rt_dm_dev_prop_read_u32_index(dev, "states", i * 2 + 1, &rg->states[i].gpios);
  208. }
  209. if ((err = rt_regulator_register(rgp)))
  210. {
  211. goto _fail;
  212. }
  213. return RT_EOK;
  214. _fail:
  215. if (rg->pins_desc)
  216. {
  217. rt_free(rg->pins_desc);
  218. }
  219. if (rg->states)
  220. {
  221. rt_free(rg->states);
  222. }
  223. rt_free(rg);
  224. return err;
  225. }
  226. static const struct rt_ofw_node_id regulator_gpio_ofw_ids[] =
  227. {
  228. { .compatible = "regulator-gpio" },
  229. { /* sentinel */ }
  230. };
  231. static struct rt_platform_driver regulator_gpio_driver =
  232. {
  233. .name = "regulator-gpio",
  234. .ids = regulator_gpio_ofw_ids,
  235. .probe = regulator_gpio_probe,
  236. };
  237. static int regulator_gpio_register(void)
  238. {
  239. rt_platform_driver_register(&regulator_gpio_driver);
  240. return 0;
  241. }
  242. INIT_SUBSYS_EXPORT(regulator_gpio_register);