1 /*
2 * Copyright 2023 Renesas Electronics Corporation
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6 #define DT_DRV_COMPAT renesas_smartbond_regulator
7
8 #include <stdint.h>
9
10 #include <zephyr/drivers/regulator.h>
11 #include <zephyr/logging/log.h>
12 #include <zephyr/sys/linear_range.h>
13 #include <DA1469xAB.h>
14
15 LOG_MODULE_REGISTER(regulator_da1469x, CONFIG_REGULATOR_LOG_LEVEL);
16
17 #define DCDC_REQUESTED (DCDC_DCDC_VDD_REG_DCDC_VDD_ENABLE_HV_Msk |\
18 DCDC_DCDC_VDD_REG_DCDC_VDD_ENABLE_LV_Msk)
19
20 #define DA1469X_LDO_3V0_MODE_VBAT BIT(8)
21 #define DA1469X_LDO_3V0_MODE_VBUS BIT(9)
22
23 static const struct linear_range curren_ranges[] = {
24 LINEAR_RANGE_INIT(30000, 30000, 0, 31),
25 };
26
27 static const struct linear_range vdd_clamp_ranges[] = {
28 LINEAR_RANGE_INIT(706000, 0, 15, 15),
29 LINEAR_RANGE_INIT(798000, 0, 14, 14),
30 LINEAR_RANGE_INIT(828000, 0, 13, 13),
31 LINEAR_RANGE_INIT(861000, 0, 11, 11),
32 LINEAR_RANGE_INIT(862000, 0, 12, 12),
33 LINEAR_RANGE_INIT(889000, 0, 10, 10),
34 LINEAR_RANGE_INIT(918000, 0, 9, 9),
35 LINEAR_RANGE_INIT(946000, 0, 3, 3),
36 LINEAR_RANGE_INIT(952000, 0, 8, 8),
37 LINEAR_RANGE_INIT(978000, 0, 2, 2),
38 LINEAR_RANGE_INIT(1005000, 0, 1, 1),
39 LINEAR_RANGE_INIT(1030000, 0, 7, 7),
40 LINEAR_RANGE_INIT(1037000, 0, 0, 0),
41 LINEAR_RANGE_INIT(1058000, 0, 6, 6),
42 LINEAR_RANGE_INIT(1089000, 0, 5, 5),
43 LINEAR_RANGE_INIT(1120000, 0, 4, 4),
44 };
45
46 static const struct linear_range vdd_ranges[] = {
47 LINEAR_RANGE_INIT(900000, 100000, 0, 3),
48 };
49
50 static const struct linear_range vdd_sleep_ranges[] = {
51 LINEAR_RANGE_INIT(750000, 50000, 0, 3),
52 };
53
54 static const struct linear_range v14_ranges[] = {
55 LINEAR_RANGE_INIT(1200000, 50000, 0, 7),
56 };
57
58 static const struct linear_range v30_ranges[] = {
59 LINEAR_RANGE_INIT(3000000, 300000, 0, 1),
60 };
61
62 static const struct linear_range v18_ranges[] = {
63 LINEAR_RANGE_INIT(1200000, 600000, 0, 1),
64 };
65
66 static const struct linear_range v18p_ranges[] = {
67 LINEAR_RANGE_INIT(1800000, 0, 0, 0),
68 };
69
70 enum da1469x_rail {
71 VDD_CLAMP,
72 VDD_SLEEP,
73 VDD,
74 V14,
75 V18,
76 V18P,
77 V30,
78 };
79
80 struct regulator_da1469x_desc {
81 const struct linear_range *voltage_ranges;
82 const struct linear_range *current_ranges;
83 uint8_t voltage_range_count;
84 /* Bit from POWER_CTRL_REG that can be used for enabling rail */
85 uint32_t enable_mask;
86 uint32_t voltage_idx_mask;
87 volatile uint32_t *dcdc_register;
88 };
89
90 static const struct regulator_da1469x_desc vdd_desc = {
91 .voltage_ranges = vdd_ranges,
92 .current_ranges = curren_ranges,
93 .voltage_range_count = ARRAY_SIZE(vdd_ranges),
94 .enable_mask = CRG_TOP_POWER_CTRL_REG_LDO_CORE_ENABLE_Msk,
95 .voltage_idx_mask = CRG_TOP_POWER_CTRL_REG_VDD_LEVEL_Msk,
96 .dcdc_register = &DCDC->DCDC_VDD_REG,
97 };
98
99 static const struct regulator_da1469x_desc vdd_sleep_desc = {
100 .voltage_ranges = vdd_sleep_ranges,
101 .voltage_range_count = ARRAY_SIZE(vdd_sleep_ranges),
102 .enable_mask = CRG_TOP_POWER_CTRL_REG_LDO_CORE_RET_ENABLE_SLEEP_Msk,
103 .voltage_idx_mask = CRG_TOP_POWER_CTRL_REG_VDD_SLEEP_LEVEL_Msk,
104 };
105
106 static const struct regulator_da1469x_desc vdd_clamp_desc = {
107 .voltage_ranges = vdd_clamp_ranges,
108 .voltage_range_count = ARRAY_SIZE(vdd_clamp_ranges),
109 .enable_mask = 0,
110 .voltage_idx_mask = CRG_TOP_POWER_CTRL_REG_VDD_CLAMP_LEVEL_Msk,
111 };
112
113 static const struct regulator_da1469x_desc v14_desc = {
114 .voltage_ranges = v14_ranges,
115 .current_ranges = curren_ranges,
116 .voltage_range_count = ARRAY_SIZE(v14_ranges),
117 .enable_mask = CRG_TOP_POWER_CTRL_REG_LDO_RADIO_ENABLE_Msk,
118 .voltage_idx_mask = CRG_TOP_POWER_CTRL_REG_V14_LEVEL_Msk,
119 .dcdc_register = &DCDC->DCDC_V14_REG,
120 };
121
122 static const struct regulator_da1469x_desc v18_desc = {
123 .voltage_ranges = v18_ranges,
124 .current_ranges = curren_ranges,
125 .voltage_range_count = ARRAY_SIZE(v18_ranges),
126 .enable_mask = CRG_TOP_POWER_CTRL_REG_LDO_1V8_ENABLE_Msk |
127 CRG_TOP_POWER_CTRL_REG_LDO_1V8_RET_ENABLE_SLEEP_Msk,
128 .voltage_idx_mask = CRG_TOP_POWER_CTRL_REG_V18_LEVEL_Msk,
129 .dcdc_register = &DCDC->DCDC_V18_REG,
130 };
131
132 static const struct regulator_da1469x_desc v18p_desc = {
133 .voltage_ranges = v18p_ranges,
134 .current_ranges = curren_ranges,
135 .voltage_range_count = ARRAY_SIZE(v18p_ranges),
136 .enable_mask = CRG_TOP_POWER_CTRL_REG_LDO_1V8P_ENABLE_Msk |
137 CRG_TOP_POWER_CTRL_REG_LDO_1V8P_RET_ENABLE_SLEEP_Msk,
138 .voltage_idx_mask = 0,
139 .dcdc_register = &DCDC->DCDC_V18P_REG,
140 };
141
142 static const struct regulator_da1469x_desc v30_desc = {
143 .voltage_ranges = v30_ranges,
144 .voltage_range_count = ARRAY_SIZE(v30_ranges),
145 .enable_mask = CRG_TOP_POWER_CTRL_REG_LDO_3V0_RET_ENABLE_SLEEP_Msk |
146 CRG_TOP_POWER_CTRL_REG_LDO_3V0_MODE_Msk,
147 .voltage_idx_mask = CRG_TOP_POWER_CTRL_REG_V30_LEVEL_Msk,
148 };
149
150 #define DA1469X_LDO_VDD_CLAMP_RET 0
151 #define DA1469X_LDO_VDD_SLEEP_RET 0
152 #define DA1469X_LDO_VDD_RET CRG_TOP_POWER_CTRL_REG_LDO_CORE_RET_ENABLE_SLEEP_Msk
153 #define DA1469X_LDO_V14_RET 0
154 #define DA1469X_LDO_V18_RET CRG_TOP_POWER_CTRL_REG_LDO_1V8_RET_ENABLE_SLEEP_Msk
155 #define DA1469X_LDO_V18P_RET CRG_TOP_POWER_CTRL_REG_LDO_1V8P_RET_ENABLE_SLEEP_Msk
156 #define DA1469X_LDO_V30_RET CRG_TOP_POWER_CTRL_REG_LDO_3V0_RET_ENABLE_SLEEP_Msk
157
158 struct regulator_da1469x_config {
159 struct regulator_common_config common;
160 enum da1469x_rail rail;
161 const struct regulator_da1469x_desc *desc;
162 uint32_t power_bits;
163 uint32_t dcdc_bits;
164 };
165
166 struct regulator_da1469x_data {
167 struct regulator_common_data common;
168 };
169
regulator_da1469x_enable(const struct device * dev)170 static int regulator_da1469x_enable(const struct device *dev)
171 {
172 const struct regulator_da1469x_config *config = dev->config;
173 uint32_t reg_val;
174
175 if (config->desc->enable_mask & config->power_bits) {
176 reg_val = CRG_TOP->POWER_CTRL_REG & ~(config->desc->enable_mask);
177 reg_val |= config->power_bits & config->desc->enable_mask;
178 CRG_TOP->POWER_CTRL_REG |= reg_val;
179 }
180
181 if (config->desc->dcdc_register) {
182 reg_val = *config->desc->dcdc_register &
183 ~(DCDC_DCDC_V14_REG_DCDC_V14_ENABLE_HV_Msk |
184 DCDC_DCDC_V14_REG_DCDC_V14_ENABLE_LV_Msk);
185 reg_val |= config->dcdc_bits;
186 *config->desc->dcdc_register = reg_val;
187 }
188
189 /*
190 * Enable DCDC if:
191 * 1. it was not already enabled, and
192 * 2. VBAT is above minimal value
193 * 3. Just turned on rail requested DCDC
194 */
195 if (((DCDC->DCDC_CTRL1_REG & DCDC_DCDC_CTRL1_REG_DCDC_ENABLE_Msk) == 0) &&
196 (CRG_TOP->ANA_STATUS_REG & CRG_TOP_ANA_STATUS_REG_COMP_VBAT_HIGH_Msk) &&
197 config->dcdc_bits & DCDC_REQUESTED) {
198 DCDC->DCDC_CTRL1_REG |= DCDC_DCDC_CTRL1_REG_DCDC_ENABLE_Msk;
199 }
200
201 return 0;
202 }
203
regulator_da1469x_disable(const struct device * dev)204 static int regulator_da1469x_disable(const struct device *dev)
205 {
206 const struct regulator_da1469x_config *config = dev->config;
207 uint32_t reg_val;
208
209 if (config->desc->enable_mask & config->power_bits) {
210 CRG_TOP->POWER_CTRL_REG &= ~(config->desc->enable_mask &
211 config->power_bits);
212 }
213 if (config->desc->dcdc_register) {
214 reg_val = *config->desc->dcdc_register &
215 ~(DCDC_DCDC_V14_REG_DCDC_V14_ENABLE_HV_Msk |
216 DCDC_DCDC_V14_REG_DCDC_V14_ENABLE_LV_Msk);
217 *config->desc->dcdc_register = reg_val;
218 }
219
220 /* Turn off DCDC if it's no longer requested by any rail */
221 if ((DCDC->DCDC_CTRL1_REG & DCDC_DCDC_CTRL1_REG_DCDC_ENABLE_Msk) &&
222 (DCDC->DCDC_VDD_REG & DCDC_REQUESTED) == 0 &&
223 (DCDC->DCDC_V14_REG & DCDC_REQUESTED) == 0 &&
224 (DCDC->DCDC_V18_REG & DCDC_REQUESTED) == 0 &&
225 (DCDC->DCDC_V18P_REG & DCDC_REQUESTED) == 0) {
226 DCDC->DCDC_CTRL1_REG &= ~DCDC_DCDC_CTRL1_REG_DCDC_ENABLE_Msk;
227 }
228
229 return 0;
230 }
231
regulator_da1469x_count_voltages(const struct device * dev)232 static unsigned int regulator_da1469x_count_voltages(const struct device *dev)
233 {
234 const struct regulator_da1469x_config *config = dev->config;
235
236 return linear_range_group_values_count(config->desc->voltage_ranges,
237 config->desc->voltage_range_count);
238 }
239
regulator_da1469x_list_voltage(const struct device * dev,unsigned int idx,int32_t * volt_uv)240 static int regulator_da1469x_list_voltage(const struct device *dev,
241 unsigned int idx,
242 int32_t *volt_uv)
243 {
244 const struct regulator_da1469x_config *config = dev->config;
245
246 if (config->desc->voltage_ranges) {
247 return linear_range_group_get_value(config->desc->voltage_ranges,
248 config->desc->voltage_range_count,
249 idx, volt_uv);
250 }
251
252 return -ENOTSUP;
253 }
254
regulator_da1469x_set_voltage(const struct device * dev,int32_t min_uv,int32_t max_uv)255 static int regulator_da1469x_set_voltage(const struct device *dev, int32_t min_uv,
256 int32_t max_uv)
257 {
258 int ret;
259 const struct regulator_da1469x_config *config = dev->config;
260 uint16_t idx;
261 uint32_t mask;
262
263 ret = linear_range_group_get_win_index(config->desc->voltage_ranges,
264 config->desc->voltage_range_count,
265 min_uv, max_uv, &idx);
266
267 if (ret == 0) {
268 mask = config->desc->voltage_idx_mask;
269 /*
270 * Mask is 0 for V18.
271 * Setting value 1.8V is accepted since range is valid and already checked.
272 */
273 if (mask) {
274 CRG_TOP->POWER_CTRL_REG = (CRG_TOP->POWER_CTRL_REG & ~mask) |
275 FIELD_PREP(mask, idx);
276 }
277 }
278
279 return ret;
280 }
281
regulator_da1469x_get_voltage(const struct device * dev,int32_t * volt_uv)282 static int regulator_da1469x_get_voltage(const struct device *dev,
283 int32_t *volt_uv)
284 {
285 const struct regulator_da1469x_config *config = dev->config;
286 uint16_t idx;
287
288 if (config->desc->voltage_idx_mask) {
289 idx = FIELD_GET(CRG_TOP->POWER_CTRL_REG, config->desc->voltage_idx_mask);
290 } else {
291 idx = 0;
292 }
293
294 return linear_range_group_get_value(config->desc->voltage_ranges,
295 config->desc->voltage_range_count, idx, volt_uv);
296 }
297
regulator_da1469x_set_current_limit(const struct device * dev,int32_t min_ua,int32_t max_ua)298 static int regulator_da1469x_set_current_limit(const struct device *dev,
299 int32_t min_ua, int32_t max_ua)
300 {
301 const struct regulator_da1469x_config *config = dev->config;
302 int ret;
303 uint16_t idx;
304 uint32_t reg_val;
305
306 if (config->desc->current_ranges == NULL) {
307 return -ENOTSUP;
308 }
309
310 ret = linear_range_group_get_win_index(config->desc->current_ranges,
311 1,
312 min_ua, max_ua, &idx);
313 if (ret) {
314 return ret;
315 }
316
317 /* All registers have same bits layout */
318 reg_val = *config->desc->dcdc_register & ~(DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MAX_HV_Msk |
319 DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MAX_LV_Msk |
320 DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MIN_Msk);
321 reg_val |= FIELD_PREP(DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MAX_HV_Msk, idx);
322 reg_val |= FIELD_PREP(DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MAX_LV_Msk, idx);
323 reg_val |= FIELD_PREP(DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MIN_Msk, idx);
324
325 *config->desc->dcdc_register = reg_val;
326
327 return ret;
328 }
329
regulator_da1469x_get_current_limit(const struct device * dev,int32_t * curr_ua)330 static int regulator_da1469x_get_current_limit(const struct device *dev,
331 int32_t *curr_ua)
332 {
333 const struct regulator_da1469x_config *config = dev->config;
334 int ret;
335 uint16_t idx;
336
337 if (config->desc->current_ranges == NULL) {
338 return -ENOTSUP;
339 }
340 idx = FIELD_GET(*config->desc->dcdc_register,
341 DCDC_DCDC_V14_REG_DCDC_V14_CUR_LIM_MAX_HV_Msk);
342 ret = linear_range_group_get_value(config->desc->current_ranges, 1, idx, curr_ua);
343
344 return ret;
345 }
346
347 static const struct regulator_driver_api regulator_da1469x_api = {
348 .enable = regulator_da1469x_enable,
349 .disable = regulator_da1469x_disable,
350 .count_voltages = regulator_da1469x_count_voltages,
351 .list_voltage = regulator_da1469x_list_voltage,
352 .set_voltage = regulator_da1469x_set_voltage,
353 .get_voltage = regulator_da1469x_get_voltage,
354 .set_current_limit = regulator_da1469x_set_current_limit,
355 .get_current_limit = regulator_da1469x_get_current_limit,
356 };
357
regulator_da1469x_init(const struct device * dev)358 static int regulator_da1469x_init(const struct device *dev)
359 {
360 const struct regulator_da1469x_config *config = dev->config;
361
362 regulator_common_data_init(dev);
363
364 if ((config->rail == V30) &&
365 (config->power_bits & CRG_TOP_POWER_CTRL_REG_LDO_3V0_REF_Msk)) {
366 CRG_TOP->POWER_CTRL_REG |= CRG_TOP_POWER_CTRL_REG_LDO_3V0_REF_Msk;
367 }
368
369 return regulator_common_init(dev, 0);
370 }
371
372 #define REGULATOR_DA1469X_DEFINE(node, id, rail_id) \
373 static struct regulator_da1469x_data data_##id; \
374 \
375 static const struct regulator_da1469x_config config_##id = { \
376 .common = REGULATOR_DT_COMMON_CONFIG_INIT(node), \
377 .desc = &id ## _desc, \
378 .power_bits = \
379 (DT_PROP(node, renesas_regulator_v30_clamp) * \
380 CRG_TOP_POWER_CTRL_REG_CLAMP_3V0_VBAT_ENABLE_Msk) | \
381 (DT_PROP(node, renesas_regulator_v30_vbus) * \
382 DA1469X_LDO_3V0_MODE_VBAT) | \
383 (DT_PROP(node, renesas_regulator_v30_vbat) * \
384 DA1469X_LDO_3V0_MODE_VBUS) | \
385 (DT_PROP(node, renesas_regulator_sleep_ldo) * \
386 (DA1469X_LDO_ ## rail_id ##_RET)) | \
387 (DT_PROP(node, renesas_regulator_v30_ref_bandgap) * \
388 CRG_TOP_POWER_CTRL_REG_LDO_3V0_REF_Msk), \
389 .dcdc_bits = \
390 (DT_PROP(node, renesas_regulator_dcdc_vbat_high) * \
391 DCDC_DCDC_VDD_REG_DCDC_VDD_ENABLE_HV_Msk) | \
392 (DT_PROP(node, renesas_regulator_dcdc_vbat_low) * \
393 DCDC_DCDC_VDD_REG_DCDC_VDD_ENABLE_LV_Msk) \
394 }; \
395 DEVICE_DT_DEFINE(node, regulator_da1469x_init, NULL, &data_##id, \
396 &config_##id, PRE_KERNEL_1, \
397 CONFIG_REGULATOR_DA1469X_INIT_PRIORITY, \
398 ®ulator_da1469x_api);
399
400 #define REGULATOR_DA1469X_DEFINE_COND(inst, child, source) \
401 COND_CODE_1(DT_NODE_EXISTS(DT_INST_CHILD(inst, child)), \
402 (REGULATOR_DA1469X_DEFINE( \
403 DT_INST_CHILD(inst, child), child, source)), \
404 ())
405
406 #define REGULATOR_DA1469X_DEFINE_ALL(inst) \
407 REGULATOR_DA1469X_DEFINE_COND(inst, vdd_clamp, VDD_CLAMP) \
408 REGULATOR_DA1469X_DEFINE_COND(inst, vdd_sleep, VDD_SLEEP) \
409 REGULATOR_DA1469X_DEFINE_COND(inst, vdd, VDD) \
410 REGULATOR_DA1469X_DEFINE_COND(inst, v14, V14) \
411 REGULATOR_DA1469X_DEFINE_COND(inst, v18, V18) \
412 REGULATOR_DA1469X_DEFINE_COND(inst, v18p, V18P) \
413 REGULATOR_DA1469X_DEFINE_COND(inst, v30, V30) \
414
415 DT_INST_FOREACH_STATUS_OKAY(REGULATOR_DA1469X_DEFINE_ALL)
416