pwr_regulator.c 6.2 KB

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