pwr_regulator.c 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. // SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
  2. /*
  3. * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
  4. */
  5. #include <common.h>
  6. #include <dm.h>
  7. #include <errno.h>
  8. #include <regmap.h>
  9. #include <syscon.h>
  10. #include <dm/device_compat.h>
  11. #include <linux/err.h>
  12. #include <power/pmic.h>
  13. #include <power/regulator.h>
  14. #define STM32MP_PWR_CR3 0xc
  15. #define STM32MP_PWR_CR3_USB33DEN BIT(24)
  16. #define STM32MP_PWR_CR3_USB33RDY BIT(26)
  17. #define STM32MP_PWR_CR3_REG18DEN BIT(28)
  18. #define STM32MP_PWR_CR3_REG18RDY BIT(29)
  19. #define STM32MP_PWR_CR3_REG11DEN BIT(30)
  20. #define STM32MP_PWR_CR3_REG11RDY BIT(31)
  21. struct stm32mp_pwr_reg_info {
  22. u32 enable;
  23. u32 ready;
  24. char *name;
  25. };
  26. struct stm32mp_pwr_priv {
  27. struct regmap *regmap;
  28. };
  29. static int stm32mp_pwr_write(struct udevice *dev, uint reg,
  30. const uint8_t *buff, int len)
  31. {
  32. struct stm32mp_pwr_priv *priv = dev_get_priv(dev);
  33. u32 val = *(u32 *)buff;
  34. if (len != 4)
  35. return -EINVAL;
  36. return regmap_write(priv->regmap, STM32MP_PWR_CR3, val);
  37. }
  38. static int stm32mp_pwr_read(struct udevice *dev, uint reg, uint8_t *buff,
  39. int len)
  40. {
  41. struct stm32mp_pwr_priv *priv = dev_get_priv(dev);
  42. if (len != 4)
  43. return -EINVAL;
  44. return regmap_read(priv->regmap, STM32MP_PWR_CR3, (u32 *)buff);
  45. }
  46. static int stm32mp_pwr_ofdata_to_platdata(struct udevice *dev)
  47. {
  48. struct stm32mp_pwr_priv *priv = dev_get_priv(dev);
  49. struct regmap *regmap;
  50. regmap = syscon_get_regmap_by_driver_data(STM32MP_SYSCON_PWR);
  51. if (IS_ERR(regmap)) {
  52. pr_err("%s: unable to find regmap (%ld)\n", __func__,
  53. PTR_ERR(regmap));
  54. return PTR_ERR(regmap);
  55. }
  56. priv->regmap = regmap;
  57. return 0;
  58. }
  59. static const struct pmic_child_info pwr_children_info[] = {
  60. { .prefix = "reg", .driver = "stm32mp_pwr_regulator"},
  61. { .prefix = "usb", .driver = "stm32mp_pwr_regulator"},
  62. { },
  63. };
  64. static int stm32mp_pwr_bind(struct udevice *dev)
  65. {
  66. int children;
  67. children = pmic_bind_children(dev, dev->node, pwr_children_info);
  68. if (!children)
  69. dev_dbg(dev, "no child found\n");
  70. return 0;
  71. }
  72. static struct dm_pmic_ops stm32mp_pwr_ops = {
  73. .read = stm32mp_pwr_read,
  74. .write = stm32mp_pwr_write,
  75. };
  76. static const struct udevice_id stm32mp_pwr_ids[] = {
  77. { .compatible = "st,stm32mp1,pwr-reg" },
  78. { }
  79. };
  80. U_BOOT_DRIVER(stm32mp_pwr_pmic) = {
  81. .name = "stm32mp_pwr_pmic",
  82. .id = UCLASS_PMIC,
  83. .of_match = stm32mp_pwr_ids,
  84. .bind = stm32mp_pwr_bind,
  85. .ops = &stm32mp_pwr_ops,
  86. .ofdata_to_platdata = stm32mp_pwr_ofdata_to_platdata,
  87. .priv_auto_alloc_size = sizeof(struct stm32mp_pwr_priv),
  88. };
  89. static const struct stm32mp_pwr_reg_info stm32mp_pwr_reg11 = {
  90. .enable = STM32MP_PWR_CR3_REG11DEN,
  91. .ready = STM32MP_PWR_CR3_REG11RDY,
  92. .name = "reg11"
  93. };
  94. static const struct stm32mp_pwr_reg_info stm32mp_pwr_reg18 = {
  95. .enable = STM32MP_PWR_CR3_REG18DEN,
  96. .ready = STM32MP_PWR_CR3_REG18RDY,
  97. .name = "reg18"
  98. };
  99. static const struct stm32mp_pwr_reg_info stm32mp_pwr_usb33 = {
  100. .enable = STM32MP_PWR_CR3_USB33DEN,
  101. .ready = STM32MP_PWR_CR3_USB33RDY,
  102. .name = "usb33"
  103. };
  104. static const struct stm32mp_pwr_reg_info *stm32mp_pwr_reg_infos[] = {
  105. &stm32mp_pwr_reg11,
  106. &stm32mp_pwr_reg18,
  107. &stm32mp_pwr_usb33,
  108. NULL
  109. };
  110. static int stm32mp_pwr_regulator_probe(struct udevice *dev)
  111. {
  112. const struct stm32mp_pwr_reg_info **p = stm32mp_pwr_reg_infos;
  113. struct dm_regulator_uclass_platdata *uc_pdata;
  114. uc_pdata = dev_get_uclass_platdata(dev);
  115. while (*p) {
  116. int rc;
  117. rc = dev_read_stringlist_search(dev, "regulator-name",
  118. (*p)->name);
  119. if (rc >= 0) {
  120. dev_dbg(dev, "found regulator %s\n", (*p)->name);
  121. break;
  122. } else if (rc != -ENODATA) {
  123. return rc;
  124. }
  125. p++;
  126. }
  127. if (!*p) {
  128. int i = 0;
  129. const char *s;
  130. dev_dbg(dev, "regulator ");
  131. while (dev_read_string_index(dev, "regulator-name",
  132. i++, &s) >= 0)
  133. dev_dbg(dev, "%s'%s' ", (i > 1) ? ", " : "", s);
  134. dev_dbg(dev, "%s not supported\n", (i > 2) ? "are" : "is");
  135. return -EINVAL;
  136. }
  137. uc_pdata->type = REGULATOR_TYPE_FIXED;
  138. dev->priv = (void *)*p;
  139. return 0;
  140. }
  141. static int stm32mp_pwr_regulator_set_value(struct udevice *dev, int uV)
  142. {
  143. struct dm_regulator_uclass_platdata *uc_pdata;
  144. uc_pdata = dev_get_uclass_platdata(dev);
  145. if (!uc_pdata)
  146. return -ENXIO;
  147. if (uc_pdata->min_uV != uV) {
  148. dev_dbg(dev, "Invalid uV=%d for: %s\n", uV, uc_pdata->name);
  149. return -EINVAL;
  150. }
  151. return 0;
  152. }
  153. static int stm32mp_pwr_regulator_get_value(struct udevice *dev)
  154. {
  155. struct dm_regulator_uclass_platdata *uc_pdata;
  156. uc_pdata = dev_get_uclass_platdata(dev);
  157. if (!uc_pdata)
  158. return -ENXIO;
  159. if (uc_pdata->min_uV != uc_pdata->max_uV) {
  160. dev_dbg(dev, "Invalid constraints for: %s\n", uc_pdata->name);
  161. return -EINVAL;
  162. }
  163. return uc_pdata->min_uV;
  164. }
  165. static int stm32mp_pwr_regulator_get_enable(struct udevice *dev)
  166. {
  167. const struct stm32mp_pwr_reg_info *p = dev_get_priv(dev);
  168. int rc;
  169. u32 reg;
  170. rc = pmic_read(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));
  171. if (rc)
  172. return rc;
  173. dev_dbg(dev, "%s id %s\n", p->name, (reg & p->enable) ? "on" : "off");
  174. return (reg & p->enable) != 0;
  175. }
  176. static int stm32mp_pwr_regulator_set_enable(struct udevice *dev, bool enable)
  177. {
  178. const struct stm32mp_pwr_reg_info *p = dev_get_priv(dev);
  179. int rc;
  180. u32 reg;
  181. u32 time_start;
  182. dev_dbg(dev, "Turning %s %s\n", enable ? "on" : "off", p->name);
  183. rc = pmic_read(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));
  184. if (rc)
  185. return rc;
  186. /* if regulator is already in the wanted state, nothing to do */
  187. if (!!(reg & p->enable) == enable)
  188. return 0;
  189. reg &= ~p->enable;
  190. if (enable)
  191. reg |= p->enable;
  192. rc = pmic_write(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));
  193. if (rc)
  194. return rc;
  195. if (!enable)
  196. return 0;
  197. /* waiting ready for enable */
  198. time_start = get_timer(0);
  199. while (1) {
  200. rc = pmic_read(dev->parent, 0, (uint8_t *)&reg, sizeof(reg));
  201. if (rc)
  202. return rc;
  203. if (reg & p->ready)
  204. break;
  205. if (get_timer(time_start) > CONFIG_SYS_HZ) {
  206. dev_dbg(dev, "%s: timeout\n", p->name);
  207. return -ETIMEDOUT;
  208. }
  209. }
  210. return 0;
  211. }
  212. static const struct dm_regulator_ops stm32mp_pwr_regulator_ops = {
  213. .set_value = stm32mp_pwr_regulator_set_value,
  214. .get_value = stm32mp_pwr_regulator_get_value,
  215. .get_enable = stm32mp_pwr_regulator_get_enable,
  216. .set_enable = stm32mp_pwr_regulator_set_enable,
  217. };
  218. U_BOOT_DRIVER(stm32mp_pwr_regulator) = {
  219. .name = "stm32mp_pwr_regulator",
  220. .id = UCLASS_REGULATOR,
  221. .ops = &stm32mp_pwr_regulator_ops,
  222. .probe = stm32mp_pwr_regulator_probe,
  223. };