1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Change Logs:
7 * Date Author Notes
8 * 2023-09-23 GuEe-GUI first version
9 */
10
11 #include "regulator_dm.h"
12
13 struct regulator_fixed
14 {
15 struct rt_regulator_node parent;
16 struct rt_regulator_param param;
17
18 rt_base_t enable_pin;
19 const char *input_supply;
20 };
21
22 #define raw_to_regulator_fixed(raw) rt_container_of(raw, struct regulator_fixed, parent)
23
regulator_fixed_enable(struct rt_regulator_node * reg_np)24 static rt_err_t regulator_fixed_enable(struct rt_regulator_node *reg_np)
25 {
26 struct regulator_fixed *rf = raw_to_regulator_fixed(reg_np);
27 struct rt_regulator_param *param = &rf->param;
28
29 if (rf->enable_pin < 0 || param->always_on)
30 {
31 return RT_EOK;
32 }
33
34 rt_pin_mode(rf->enable_pin, PIN_MODE_OUTPUT);
35 rt_pin_write(rf->enable_pin, param->enable_active_high ? PIN_HIGH : PIN_LOW);
36
37 return RT_EOK;
38 }
39
regulator_fixed_disable(struct rt_regulator_node * reg_np)40 static rt_err_t regulator_fixed_disable(struct rt_regulator_node *reg_np)
41 {
42 struct regulator_fixed *rf = raw_to_regulator_fixed(reg_np);
43 struct rt_regulator_param *param = &rf->param;
44
45 if (rf->enable_pin < 0 || param->always_on)
46 {
47 return RT_EOK;
48 }
49
50 rt_pin_mode(rf->enable_pin, PIN_MODE_OUTPUT);
51 rt_pin_write(rf->enable_pin, param->enable_active_high ? PIN_LOW: PIN_HIGH);
52
53 return RT_EOK;
54 }
55
regulator_fixed_is_enabled(struct rt_regulator_node * reg_np)56 static rt_bool_t regulator_fixed_is_enabled(struct rt_regulator_node *reg_np)
57 {
58 rt_uint8_t active;
59 struct regulator_fixed *rf = raw_to_regulator_fixed(reg_np);
60 struct rt_regulator_param *param = &rf->param;
61
62 if (rf->enable_pin < 0 || param->always_on)
63 {
64 return RT_TRUE;
65 }
66
67 rt_pin_mode(rf->enable_pin, PIN_MODE_INPUT);
68 active = rt_pin_read(rf->enable_pin);
69
70 if (param->enable_active_high)
71 {
72 return active == PIN_HIGH;
73 }
74
75 return active == PIN_LOW;
76 }
77
regulator_fixed_get_voltage(struct rt_regulator_node * reg_np)78 static int regulator_fixed_get_voltage(struct rt_regulator_node *reg_np)
79 {
80 struct regulator_fixed *rf = raw_to_regulator_fixed(reg_np);
81
82 return rf->param.min_uvolt + (rf->param.max_uvolt - rf->param.min_uvolt) / 2;
83 }
84
85 static const struct rt_regulator_ops regulator_fixed_ops =
86 {
87 .enable = regulator_fixed_enable,
88 .disable = regulator_fixed_disable,
89 .is_enabled = regulator_fixed_is_enabled,
90 .get_voltage = regulator_fixed_get_voltage,
91 };
92
regulator_fixed_probe(struct rt_platform_device * pdev)93 static rt_err_t regulator_fixed_probe(struct rt_platform_device *pdev)
94 {
95 rt_err_t err;
96 rt_uint32_t val;
97 struct rt_device *dev = &pdev->parent;
98 struct regulator_fixed *rf = rt_calloc(1, sizeof(*rf));
99 struct rt_regulator_node *rnp;
100
101 if (!rf)
102 {
103 return -RT_ENOMEM;
104 }
105
106 regulator_ofw_parse(dev->ofw_node, &rf->param);
107
108 rnp = &rf->parent;
109 rnp->supply_name = rf->param.name;
110 rnp->ops = ®ulator_fixed_ops;
111 rnp->param = &rf->param;
112 rnp->dev = &pdev->parent;
113
114 rf->enable_pin = rt_pin_get_named_pin(dev, "enable", 0, RT_NULL, RT_NULL);
115
116 if (rf->enable_pin < 0)
117 {
118 rf->enable_pin = rt_pin_get_named_pin(dev, RT_NULL, 0, RT_NULL, RT_NULL);
119 }
120
121 if (rf->enable_pin < 0)
122 {
123 rf->enable_pin = -1;
124 }
125
126 rt_pin_ctrl_confs_apply(dev, 0);
127
128 if (!rt_dm_dev_prop_read_u32(dev, "startup-delay-us", &val))
129 {
130 rf->param.enable_delay = val;
131 }
132
133 if (!rt_dm_dev_prop_read_u32(dev, "off-on-delay-us", &val))
134 {
135 rf->param.off_on_delay = val;
136 }
137
138 if ((err = rt_regulator_register(rnp)))
139 {
140 goto _fail;
141 }
142
143 return RT_EOK;
144
145 _fail:
146 rt_free(rf);
147
148 return err;
149 }
150
151 static const struct rt_ofw_node_id regulator_fixed_ofw_ids[] =
152 {
153 { .compatible = "regulator-fixed" },
154 { /* sentinel */ }
155 };
156
157 static struct rt_platform_driver regulator_fixed_driver =
158 {
159 .name = "reg-fixed-voltage",
160 .ids = regulator_fixed_ofw_ids,
161
162 .probe = regulator_fixed_probe,
163 };
164
regulator_fixed_register(void)165 static int regulator_fixed_register(void)
166 {
167 rt_platform_driver_register(®ulator_fixed_driver);
168
169 return 0;
170 }
171 INIT_SUBSYS_EXPORT(regulator_fixed_register);
172