blob: 590c288d6575f7e7282e89a416db784426cbcf15 [file] [log] [blame]
Tom Rini10e47792018-05-06 17:58:06 -04001// SPDX-License-Identifier: GPL-2.0+
Przemyslaw Marczak3753f282015-04-20 20:07:48 +02002/*
3 * Copyright (C) 2015 Samsung Electronics
4 *
5 * Przemyslaw Marczak <p.marczak@samsung.com>
Przemyslaw Marczak3753f282015-04-20 20:07:48 +02006 */
7
8#include <common.h>
Philippe Schenkercdd4bfe2022-04-08 10:07:10 +02009#include <clk.h>
Przemyslaw Marczak3753f282015-04-20 20:07:48 +020010#include <errno.h>
11#include <dm.h>
Philippe Schenkercdd4bfe2022-04-08 10:07:10 +020012#include <linux/delay.h>
Simon Glass0f2af882020-05-10 11:40:05 -060013#include <log.h>
Simon Glassbdd5f812023-09-14 18:21:46 -060014#include <asm/gpio.h>
Przemyslaw Marczak3753f282015-04-20 20:07:48 +020015#include <power/pmic.h>
16#include <power/regulator.h>
Simon Glassbdd5f812023-09-14 18:21:46 -060017#include "regulator_common.h"
Przemyslaw Marczak3753f282015-04-20 20:07:48 +020018
Simon Glass1c1ddf62020-07-19 10:15:44 -060019#include "regulator_common.h"
20
Philippe Schenkercdd4bfe2022-04-08 10:07:10 +020021struct fixed_clock_regulator_plat {
22 struct clk *enable_clock;
23 unsigned int clk_enable_counter;
24};
25
Simon Glassaad29ae2020-12-03 16:55:21 -070026static int fixed_regulator_of_to_plat(struct udevice *dev)
Przemyslaw Marczak3753f282015-04-20 20:07:48 +020027{
Simon Glass71fa5b42020-12-03 16:55:18 -070028 struct dm_regulator_uclass_plat *uc_pdata;
Eugen Hristev81aa1922023-04-19 16:45:25 +030029 struct regulator_common_plat *plat;
Jonas Karlman7257f092023-07-22 13:30:21 +000030 bool gpios;
Przemyslaw Marczak3753f282015-04-20 20:07:48 +020031
Eugen Hristev81aa1922023-04-19 16:45:25 +030032 plat = dev_get_plat(dev);
Simon Glass71fa5b42020-12-03 16:55:18 -070033 uc_pdata = dev_get_uclass_plat(dev);
Przemyslaw Marczak3753f282015-04-20 20:07:48 +020034 if (!uc_pdata)
35 return -ENXIO;
36
Przemyslaw Marczak3753f282015-04-20 20:07:48 +020037 uc_pdata->type = REGULATOR_TYPE_FIXED;
38
Jonas Karlman7257f092023-07-22 13:30:21 +000039 gpios = dev_read_bool(dev, "gpios");
40 return regulator_common_of_to_plat(dev, plat, gpios ? "gpios" : "gpio");
Przemyslaw Marczak3753f282015-04-20 20:07:48 +020041}
42
43static int fixed_regulator_get_value(struct udevice *dev)
44{
Simon Glass71fa5b42020-12-03 16:55:18 -070045 struct dm_regulator_uclass_plat *uc_pdata;
Przemyslaw Marczak3753f282015-04-20 20:07:48 +020046
Simon Glass71fa5b42020-12-03 16:55:18 -070047 uc_pdata = dev_get_uclass_plat(dev);
Przemyslaw Marczak3753f282015-04-20 20:07:48 +020048 if (!uc_pdata)
49 return -ENXIO;
50
51 if (uc_pdata->min_uV != uc_pdata->max_uV) {
52 debug("Invalid constraints for: %s\n", uc_pdata->name);
53 return -EINVAL;
54 }
55
56 return uc_pdata->min_uV;
57}
58
59static int fixed_regulator_get_current(struct udevice *dev)
60{
Simon Glass71fa5b42020-12-03 16:55:18 -070061 struct dm_regulator_uclass_plat *uc_pdata;
Przemyslaw Marczak3753f282015-04-20 20:07:48 +020062
Simon Glass71fa5b42020-12-03 16:55:18 -070063 uc_pdata = dev_get_uclass_plat(dev);
Przemyslaw Marczak3753f282015-04-20 20:07:48 +020064 if (!uc_pdata)
65 return -ENXIO;
66
67 if (uc_pdata->min_uA != uc_pdata->max_uA) {
68 debug("Invalid constraints for: %s\n", uc_pdata->name);
69 return -EINVAL;
70 }
71
72 return uc_pdata->min_uA;
73}
74
Keerthy8690d6a2017-06-13 09:53:46 +053075static int fixed_regulator_get_enable(struct udevice *dev)
Przemyslaw Marczak3753f282015-04-20 20:07:48 +020076{
Simon Glassfa20e932020-12-03 16:55:20 -070077 return regulator_common_get_enable(dev, dev_get_plat(dev));
Przemyslaw Marczak3753f282015-04-20 20:07:48 +020078}
79
80static int fixed_regulator_set_enable(struct udevice *dev, bool enable)
81{
Simon Glassfa20e932020-12-03 16:55:20 -070082 return regulator_common_set_enable(dev, dev_get_plat(dev), enable);
Przemyslaw Marczak3753f282015-04-20 20:07:48 +020083}
84
Philippe Schenkercdd4bfe2022-04-08 10:07:10 +020085static int fixed_clock_regulator_get_enable(struct udevice *dev)
86{
87 struct fixed_clock_regulator_plat *priv = dev_get_priv(dev);
88
89 return priv->clk_enable_counter > 0;
90}
91
92static int fixed_clock_regulator_set_enable(struct udevice *dev, bool enable)
93{
94 struct fixed_clock_regulator_plat *priv = dev_get_priv(dev);
Eugen Hristev81aa1922023-04-19 16:45:25 +030095 struct regulator_common_plat *plat = dev_get_plat(dev);
Philippe Schenkercdd4bfe2022-04-08 10:07:10 +020096 int ret = 0;
97
98 if (enable) {
99 ret = clk_enable(priv->enable_clock);
100 priv->clk_enable_counter++;
101 } else {
102 ret = clk_disable(priv->enable_clock);
103 priv->clk_enable_counter--;
104 }
105 if (ret)
106 return ret;
107
Eugen Hristev81aa1922023-04-19 16:45:25 +0300108 if (enable && plat->startup_delay_us)
109 udelay(plat->startup_delay_us);
Philippe Schenkercdd4bfe2022-04-08 10:07:10 +0200110
Eugen Hristev81aa1922023-04-19 16:45:25 +0300111 if (!enable && plat->off_on_delay_us)
112 udelay(plat->off_on_delay_us);
Philippe Schenkercdd4bfe2022-04-08 10:07:10 +0200113
114 return ret;
115}
116
Przemyslaw Marczak3753f282015-04-20 20:07:48 +0200117static const struct dm_regulator_ops fixed_regulator_ops = {
118 .get_value = fixed_regulator_get_value,
119 .get_current = fixed_regulator_get_current,
120 .get_enable = fixed_regulator_get_enable,
121 .set_enable = fixed_regulator_set_enable,
122};
123
Philippe Schenkercdd4bfe2022-04-08 10:07:10 +0200124static const struct dm_regulator_ops fixed_clock_regulator_ops = {
125 .get_enable = fixed_clock_regulator_get_enable,
126 .set_enable = fixed_clock_regulator_set_enable,
127};
128
Przemyslaw Marczak3753f282015-04-20 20:07:48 +0200129static const struct udevice_id fixed_regulator_ids[] = {
130 { .compatible = "regulator-fixed" },
131 { },
132};
133
Philippe Schenkercdd4bfe2022-04-08 10:07:10 +0200134static const struct udevice_id fixed_clock_regulator_ids[] = {
135 { .compatible = "regulator-fixed-clock" },
136 { },
137};
138
Walter Lozano2901ac62020-06-25 01:10:04 -0300139U_BOOT_DRIVER(regulator_fixed) = {
140 .name = "regulator_fixed",
Przemyslaw Marczak3753f282015-04-20 20:07:48 +0200141 .id = UCLASS_REGULATOR,
142 .ops = &fixed_regulator_ops,
143 .of_match = fixed_regulator_ids,
Simon Glassaad29ae2020-12-03 16:55:21 -0700144 .of_to_plat = fixed_regulator_of_to_plat,
Philippe Schenkercdd4bfe2022-04-08 10:07:10 +0200145 .plat_auto = sizeof(struct regulator_common_plat),
146};
147
148U_BOOT_DRIVER(regulator_fixed_clock) = {
149 .name = "regulator_fixed_clk",
150 .id = UCLASS_REGULATOR,
151 .ops = &fixed_clock_regulator_ops,
152 .of_match = fixed_clock_regulator_ids,
153 .of_to_plat = fixed_regulator_of_to_plat,
154 .plat_auto = sizeof(struct fixed_clock_regulator_plat),
Przemyslaw Marczak3753f282015-04-20 20:07:48 +0200155};