pwm_regulator.c 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2016 Rockchip Electronics Co., Ltd
  4. *
  5. * Based on kernel drivers/regulator/pwm-regulator.c
  6. * Copyright (C) 2014 - STMicroelectronics Inc.
  7. * Author: Lee Jones <lee.jones@linaro.org>
  8. */
  9. #include <common.h>
  10. #include <dm.h>
  11. #include <errno.h>
  12. #include <log.h>
  13. #include <pwm.h>
  14. #include <asm/global_data.h>
  15. #include <dm/device_compat.h>
  16. #include <power/regulator.h>
  17. DECLARE_GLOBAL_DATA_PTR;
  18. struct pwm_regulator_info {
  19. /* pwm id corresponding to the PWM driver */
  20. int pwm_id;
  21. /* the period of one PWM cycle */
  22. int period_ns;
  23. /*
  24. * the polarity of one PWM
  25. * 0: normal polarity
  26. * 1: inverted polarity
  27. */
  28. bool polarity;
  29. struct udevice *pwm;
  30. /* initialize voltage of regulator */
  31. int init_voltage;
  32. /* the maximum voltage of regulator */
  33. int max_voltage;
  34. /* the minimum voltage of regulator */
  35. int min_voltage;
  36. /* the current voltage of regulator */
  37. int volt_uV;
  38. };
  39. static int pwm_regulator_enable(struct udevice *dev, bool enable)
  40. {
  41. struct pwm_regulator_info *priv = dev_get_priv(dev);
  42. return pwm_set_enable(priv->pwm, priv->pwm_id, enable);
  43. }
  44. static int pwm_voltage_to_duty_cycle_percentage(struct udevice *dev, int req_uV)
  45. {
  46. struct pwm_regulator_info *priv = dev_get_priv(dev);
  47. int min_uV = priv->min_voltage;
  48. int max_uV = priv->max_voltage;
  49. int diff = max_uV - min_uV;
  50. return ((req_uV * 100) - (min_uV * 100)) / diff;
  51. }
  52. static int pwm_regulator_get_voltage(struct udevice *dev)
  53. {
  54. struct pwm_regulator_info *priv = dev_get_priv(dev);
  55. return priv->volt_uV;
  56. }
  57. static int pwm_regulator_set_voltage(struct udevice *dev, int uvolt)
  58. {
  59. struct pwm_regulator_info *priv = dev_get_priv(dev);
  60. int duty_cycle;
  61. int ret = 0;
  62. duty_cycle = pwm_voltage_to_duty_cycle_percentage(dev, uvolt);
  63. ret = pwm_set_invert(priv->pwm, priv->pwm_id, priv->polarity);
  64. if (ret) {
  65. dev_err(dev, "Failed to init PWM\n");
  66. return ret;
  67. }
  68. ret = pwm_set_config(priv->pwm, priv->pwm_id,
  69. priv->period_ns, (priv->period_ns / 100) * duty_cycle);
  70. if (ret) {
  71. dev_err(dev, "Failed to configure PWM\n");
  72. return ret;
  73. }
  74. priv->volt_uV = uvolt;
  75. return ret;
  76. }
  77. static int pwm_regulator_of_to_plat(struct udevice *dev)
  78. {
  79. struct pwm_regulator_info *priv = dev_get_priv(dev);
  80. struct ofnode_phandle_args args;
  81. int ret;
  82. ret = dev_read_phandle_with_args(dev, "pwms", "#pwm-cells", 0, 0, &args);
  83. if (ret) {
  84. debug("%s: Cannot get PWM phandle: ret=%d\n", __func__, ret);
  85. return ret;
  86. }
  87. priv->period_ns = args.args[1];
  88. priv->polarity = args.args[2];
  89. priv->init_voltage = dev_read_u32_default(dev, "regulator-init-microvolt", -1);
  90. if (priv->init_voltage < 0) {
  91. printf("Cannot find regulator pwm init_voltage\n");
  92. return -EINVAL;
  93. }
  94. ret = uclass_get_device_by_ofnode(UCLASS_PWM, args.node, &priv->pwm);
  95. if (ret) {
  96. debug("%s: Cannot get PWM: ret=%d\n", __func__, ret);
  97. return ret;
  98. }
  99. return 0;
  100. }
  101. static int pwm_regulator_probe(struct udevice *dev)
  102. {
  103. struct pwm_regulator_info *priv = dev_get_priv(dev);
  104. struct dm_regulator_uclass_plat *uc_pdata;
  105. uc_pdata = dev_get_uclass_plat(dev);
  106. uc_pdata->type = REGULATOR_TYPE_BUCK;
  107. uc_pdata->mode_count = 0;
  108. priv->max_voltage = uc_pdata->max_uV;
  109. priv->min_voltage = uc_pdata->min_uV;
  110. if (priv->init_voltage)
  111. pwm_regulator_set_voltage(dev, priv->init_voltage);
  112. return 0;
  113. }
  114. static const struct dm_regulator_ops pwm_regulator_ops = {
  115. .get_value = pwm_regulator_get_voltage,
  116. .set_value = pwm_regulator_set_voltage,
  117. .set_enable = pwm_regulator_enable,
  118. };
  119. static const struct udevice_id pwm_regulator_ids[] = {
  120. { .compatible = "pwm-regulator" },
  121. { }
  122. };
  123. U_BOOT_DRIVER(pwm_regulator) = {
  124. .name = "pwm_regulator",
  125. .id = UCLASS_REGULATOR,
  126. .ops = &pwm_regulator_ops,
  127. .probe = pwm_regulator_probe,
  128. .of_match = pwm_regulator_ids,
  129. .of_to_plat = pwm_regulator_of_to_plat,
  130. .priv_auto = sizeof(struct pwm_regulator_info),
  131. };