fixed.c 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148
  1. // SPDX-License-Identifier: GPL-2.0+
  2. /*
  3. * Copyright (C) 2015 Samsung Electronics
  4. *
  5. * Przemyslaw Marczak <p.marczak@samsung.com>
  6. */
  7. #include <common.h>
  8. #include <errno.h>
  9. #include <dm.h>
  10. #include <i2c.h>
  11. #include <asm/gpio.h>
  12. #include <power/pmic.h>
  13. #include <power/regulator.h>
  14. struct fixed_regulator_platdata {
  15. struct gpio_desc gpio; /* GPIO for regulator enable control */
  16. unsigned int startup_delay_us;
  17. };
  18. static int fixed_regulator_ofdata_to_platdata(struct udevice *dev)
  19. {
  20. struct dm_regulator_uclass_platdata *uc_pdata;
  21. struct fixed_regulator_platdata *dev_pdata;
  22. struct gpio_desc *gpio;
  23. int flags = GPIOD_IS_OUT;
  24. int ret;
  25. dev_pdata = dev_get_platdata(dev);
  26. uc_pdata = dev_get_uclass_platdata(dev);
  27. if (!uc_pdata)
  28. return -ENXIO;
  29. /* Set type to fixed */
  30. uc_pdata->type = REGULATOR_TYPE_FIXED;
  31. if (dev_read_bool(dev, "enable-active-high"))
  32. flags |= GPIOD_IS_OUT_ACTIVE;
  33. /* Get fixed regulator optional enable GPIO desc */
  34. gpio = &dev_pdata->gpio;
  35. ret = gpio_request_by_name(dev, "gpio", 0, gpio, flags);
  36. if (ret) {
  37. debug("Fixed regulator optional enable GPIO - not found! Error: %d\n",
  38. ret);
  39. if (ret != -ENOENT)
  40. return ret;
  41. }
  42. /* Get optional ramp up delay */
  43. dev_pdata->startup_delay_us = dev_read_u32_default(dev,
  44. "startup-delay-us", 0);
  45. return 0;
  46. }
  47. static int fixed_regulator_get_value(struct udevice *dev)
  48. {
  49. struct dm_regulator_uclass_platdata *uc_pdata;
  50. uc_pdata = dev_get_uclass_platdata(dev);
  51. if (!uc_pdata)
  52. return -ENXIO;
  53. if (uc_pdata->min_uV != uc_pdata->max_uV) {
  54. debug("Invalid constraints for: %s\n", uc_pdata->name);
  55. return -EINVAL;
  56. }
  57. return uc_pdata->min_uV;
  58. }
  59. static int fixed_regulator_get_current(struct udevice *dev)
  60. {
  61. struct dm_regulator_uclass_platdata *uc_pdata;
  62. uc_pdata = dev_get_uclass_platdata(dev);
  63. if (!uc_pdata)
  64. return -ENXIO;
  65. if (uc_pdata->min_uA != uc_pdata->max_uA) {
  66. debug("Invalid constraints for: %s\n", uc_pdata->name);
  67. return -EINVAL;
  68. }
  69. return uc_pdata->min_uA;
  70. }
  71. static int fixed_regulator_get_enable(struct udevice *dev)
  72. {
  73. struct fixed_regulator_platdata *dev_pdata = dev_get_platdata(dev);
  74. /* Enable GPIO is optional */
  75. if (!dev_pdata->gpio.dev)
  76. return true;
  77. return dm_gpio_get_value(&dev_pdata->gpio);
  78. }
  79. static int fixed_regulator_set_enable(struct udevice *dev, bool enable)
  80. {
  81. struct fixed_regulator_platdata *dev_pdata = dev_get_platdata(dev);
  82. int ret;
  83. debug("%s: dev='%s', enable=%d, delay=%d, has_gpio=%d\n", __func__,
  84. dev->name, enable, dev_pdata->startup_delay_us,
  85. dm_gpio_is_valid(&dev_pdata->gpio));
  86. /* Enable GPIO is optional */
  87. if (!dm_gpio_is_valid(&dev_pdata->gpio)) {
  88. if (!enable)
  89. return -ENOSYS;
  90. return 0;
  91. }
  92. ret = dm_gpio_set_value(&dev_pdata->gpio, enable);
  93. if (ret) {
  94. pr_err("Can't set regulator : %s gpio to: %d\n", dev->name,
  95. enable);
  96. return ret;
  97. }
  98. if (enable && dev_pdata->startup_delay_us)
  99. udelay(dev_pdata->startup_delay_us);
  100. debug("%s: done\n", __func__);
  101. return 0;
  102. }
  103. static const struct dm_regulator_ops fixed_regulator_ops = {
  104. .get_value = fixed_regulator_get_value,
  105. .get_current = fixed_regulator_get_current,
  106. .get_enable = fixed_regulator_get_enable,
  107. .set_enable = fixed_regulator_set_enable,
  108. };
  109. static const struct udevice_id fixed_regulator_ids[] = {
  110. { .compatible = "regulator-fixed" },
  111. { },
  112. };
  113. U_BOOT_DRIVER(fixed_regulator) = {
  114. .name = "fixed regulator",
  115. .id = UCLASS_REGULATOR,
  116. .ops = &fixed_regulator_ops,
  117. .of_match = fixed_regulator_ids,
  118. .ofdata_to_platdata = fixed_regulator_ofdata_to_platdata,
  119. .platdata_auto_alloc_size = sizeof(struct fixed_regulator_platdata),
  120. };