Prepare v2024.10
[platform/kernel/u-boot.git] / drivers / power / regulator / fixed.c
1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3  *  Copyright (C) 2015 Samsung Electronics
4  *
5  *  Przemyslaw Marczak <p.marczak@samsung.com>
6  */
7
8 #include <clk.h>
9 #include <errno.h>
10 #include <dm.h>
11 #include <linux/delay.h>
12 #include <log.h>
13 #include <asm/gpio.h>
14 #include <power/pmic.h>
15 #include <power/regulator.h>
16 #include "regulator_common.h"
17
18 #include "regulator_common.h"
19
20 struct fixed_clock_regulator_plat {
21         struct clk *enable_clock;
22         unsigned int clk_enable_counter;
23 };
24
25 static int fixed_regulator_of_to_plat(struct udevice *dev)
26 {
27         struct dm_regulator_uclass_plat *uc_pdata;
28         struct regulator_common_plat *plat;
29         bool gpios;
30
31         plat = dev_get_plat(dev);
32         uc_pdata = dev_get_uclass_plat(dev);
33         if (!uc_pdata)
34                 return -ENXIO;
35
36         uc_pdata->type = REGULATOR_TYPE_FIXED;
37
38         gpios = dev_read_bool(dev, "gpios");
39         return regulator_common_of_to_plat(dev, plat, gpios ? "gpios" : "gpio");
40 }
41
42 static int fixed_regulator_get_value(struct udevice *dev)
43 {
44         struct dm_regulator_uclass_plat *uc_pdata;
45
46         uc_pdata = dev_get_uclass_plat(dev);
47         if (!uc_pdata)
48                 return -ENXIO;
49
50         if (uc_pdata->min_uV != uc_pdata->max_uV) {
51                 debug("Invalid constraints for: %s\n", uc_pdata->name);
52                 return -EINVAL;
53         }
54
55         return uc_pdata->min_uV;
56 }
57
58 static int fixed_regulator_get_current(struct udevice *dev)
59 {
60         struct dm_regulator_uclass_plat *uc_pdata;
61
62         uc_pdata = dev_get_uclass_plat(dev);
63         if (!uc_pdata)
64                 return -ENXIO;
65
66         if (uc_pdata->min_uA != uc_pdata->max_uA) {
67                 debug("Invalid constraints for: %s\n", uc_pdata->name);
68                 return -EINVAL;
69         }
70
71         return uc_pdata->min_uA;
72 }
73
74 static int fixed_regulator_get_enable(struct udevice *dev)
75 {
76         return regulator_common_get_enable(dev, dev_get_plat(dev));
77 }
78
79 static int fixed_regulator_set_enable(struct udevice *dev, bool enable)
80 {
81         return regulator_common_set_enable(dev, dev_get_plat(dev), enable);
82 }
83
84 static int fixed_clock_regulator_get_enable(struct udevice *dev)
85 {
86         struct fixed_clock_regulator_plat *priv = dev_get_priv(dev);
87
88         return priv->clk_enable_counter > 0;
89 }
90
91 static int fixed_clock_regulator_set_enable(struct udevice *dev, bool enable)
92 {
93         struct fixed_clock_regulator_plat *priv = dev_get_priv(dev);
94         struct regulator_common_plat *plat = dev_get_plat(dev);
95         int ret = 0;
96
97         if (enable) {
98                 ret = clk_enable(priv->enable_clock);
99                 priv->clk_enable_counter++;
100         } else {
101                 ret = clk_disable(priv->enable_clock);
102                 priv->clk_enable_counter--;
103         }
104         if (ret)
105                 return ret;
106
107         if (enable && plat->startup_delay_us)
108                 udelay(plat->startup_delay_us);
109
110         if (!enable && plat->off_on_delay_us)
111                 udelay(plat->off_on_delay_us);
112
113         return ret;
114 }
115
116 static const struct dm_regulator_ops fixed_regulator_ops = {
117         .get_value      = fixed_regulator_get_value,
118         .get_current    = fixed_regulator_get_current,
119         .get_enable     = fixed_regulator_get_enable,
120         .set_enable     = fixed_regulator_set_enable,
121 };
122
123 static const struct dm_regulator_ops fixed_clock_regulator_ops = {
124         .get_enable     = fixed_clock_regulator_get_enable,
125         .set_enable     = fixed_clock_regulator_set_enable,
126 };
127
128 static const struct udevice_id fixed_regulator_ids[] = {
129         { .compatible = "regulator-fixed" },
130         { },
131 };
132
133 static const struct udevice_id fixed_clock_regulator_ids[] = {
134         { .compatible = "regulator-fixed-clock" },
135         { },
136 };
137
138 U_BOOT_DRIVER(regulator_fixed) = {
139         .name = "regulator_fixed",
140         .id = UCLASS_REGULATOR,
141         .ops = &fixed_regulator_ops,
142         .of_match = fixed_regulator_ids,
143         .of_to_plat = fixed_regulator_of_to_plat,
144         .plat_auto = sizeof(struct regulator_common_plat),
145 };
146
147 U_BOOT_DRIVER(regulator_fixed_clock) = {
148         .name = "regulator_fixed_clk",
149         .id = UCLASS_REGULATOR,
150         .ops = &fixed_clock_regulator_ops,
151         .of_match = fixed_clock_regulator_ids,
152         .of_to_plat = fixed_regulator_of_to_plat,
153         .plat_auto = sizeof(struct fixed_clock_regulator_plat),
154 };