76fc2eff60752536f39ceb5213d2f091922b97c1
[platform/kernel/u-boot.git] / drivers / power / regulator / rk8xx.c
1 /*
2  * Copyright (C) 2015 Google, Inc
3  * Written by Simon Glass <sjg@chromium.org>
4  *
5  * Based on Rockchip's drivers/power/pmic/pmic_rk808.c:
6  * Copyright (C) 2012 rockchips
7  * zyw <zyw@rock-chips.com>
8  *
9  * SPDX-License-Identifier:     GPL-2.0+
10  */
11
12 #include <common.h>
13 #include <dm.h>
14 #include <errno.h>
15 #include <power/rk8xx_pmic.h>
16 #include <power/pmic.h>
17 #include <power/regulator.h>
18
19 #ifndef CONFIG_SPL_BUILD
20 #define ENABLE_DRIVER
21 #endif
22
23 /* Field Definitions */
24 #define RK808_BUCK_VSEL_MASK    0x3f
25 #define RK808_BUCK4_VSEL_MASK   0xf
26 #define RK808_LDO_VSEL_MASK     0x1f
27
28 #define RK818_BUCK_VSEL_MASK            0x3f
29 #define RK818_BUCK4_VSEL_MASK           0x1f
30 #define RK818_LDO_VSEL_MASK             0x1f
31 #define RK818_LDO3_ON_VSEL_MASK 0xf
32 #define RK818_BOOST_ON_VSEL_MASK        0xe0
33 #define RK818_USB_ILIM_SEL_MASK         0x0f
34 #define RK818_USB_CHG_SD_VSEL_MASK      0x70
35
36
37 struct rk8xx_reg_info {
38         uint min_uv;
39         uint step_uv;
40         s8 vsel_reg;
41         u8 vsel_mask;
42 };
43
44 static const struct rk8xx_reg_info rk808_buck[] = {
45         { 712500, 12500, REG_BUCK1_ON_VSEL, RK808_BUCK_VSEL_MASK, },
46         { 712500, 12500, REG_BUCK2_ON_VSEL, RK808_BUCK_VSEL_MASK, },
47         { 712500, 12500, -1, RK808_BUCK_VSEL_MASK, },
48         { 1800000, 100000, REG_BUCK4_ON_VSEL, RK808_BUCK4_VSEL_MASK, },
49 };
50
51 static const struct rk8xx_reg_info rk818_buck[] = {
52         { 712500, 12500, REG_BUCK1_ON_VSEL, RK818_BUCK_VSEL_MASK, },
53         { 712500, 12500, REG_BUCK2_ON_VSEL, RK818_BUCK_VSEL_MASK, },
54         { 712500, 12500, -1, RK818_BUCK_VSEL_MASK, },
55         { 1800000, 100000, REG_BUCK4_ON_VSEL, RK818_BUCK4_VSEL_MASK, },
56 };
57
58 #ifdef ENABLE_DRIVER
59 static const struct rk8xx_reg_info rk808_ldo[] = {
60         { 1800000, 100000, REG_LDO1_ON_VSEL, RK808_LDO_VSEL_MASK, },
61         { 1800000, 100000, REG_LDO2_ON_VSEL, RK808_LDO_VSEL_MASK, },
62         { 800000, 100000, REG_LDO3_ON_VSEL, RK808_BUCK4_VSEL_MASK, },
63         { 1800000, 100000, REG_LDO4_ON_VSEL, RK808_LDO_VSEL_MASK, },
64         { 1800000, 100000, REG_LDO5_ON_VSEL, RK808_LDO_VSEL_MASK, },
65         { 800000, 100000, REG_LDO6_ON_VSEL, RK808_LDO_VSEL_MASK, },
66         { 800000, 100000, REG_LDO7_ON_VSEL, RK808_LDO_VSEL_MASK, },
67         { 1800000, 100000, REG_LDO8_ON_VSEL, RK808_LDO_VSEL_MASK, },
68 };
69
70 static const struct rk8xx_reg_info rk818_ldo[] = {
71         { 1800000, 100000, REG_LDO1_ON_VSEL, RK818_LDO_VSEL_MASK, },
72         { 1800000, 100000, REG_LDO2_ON_VSEL, RK818_LDO_VSEL_MASK, },
73         { 800000, 100000, REG_LDO3_ON_VSEL, RK818_LDO3_ON_VSEL_MASK, },
74         { 1800000, 100000, REG_LDO4_ON_VSEL, RK818_LDO_VSEL_MASK, },
75         { 1800000, 100000, REG_LDO5_ON_VSEL, RK818_LDO_VSEL_MASK, },
76         { 800000, 100000, REG_LDO6_ON_VSEL, RK818_LDO_VSEL_MASK, },
77         { 800000, 100000, REG_LDO7_ON_VSEL, RK818_LDO_VSEL_MASK, },
78         { 1800000, 100000, REG_LDO8_ON_VSEL, RK818_LDO_VSEL_MASK, },
79 };
80 #endif
81
82 static const u16 rk818_chrg_cur_input_array[] = {
83         450, 800, 850, 1000, 1250, 1500, 1750, 2000, 2250, 2500, 2750, 3000
84 };
85
86 static const uint rk818_chrg_shutdown_vsel_array[] = {
87         2780000, 2850000, 2920000, 2990000, 3060000, 3130000, 3190000, 3260000
88 };
89
90 static const struct rk8xx_reg_info *get_buck_reg(struct udevice *pmic,
91                                              int num)
92 {
93         struct rk8xx_priv *priv = dev_get_priv(pmic);
94         switch (priv->variant) {
95         case RK818_ID:
96                 return &rk818_buck[num];
97         default:
98                 return &rk808_buck[num];
99         }
100 }
101
102 static int _buck_set_value(struct udevice *pmic, int buck, int uvolt)
103 {
104         const struct rk8xx_reg_info *info = get_buck_reg(pmic, buck - 1);
105         int mask = info->vsel_mask;
106         int val;
107
108         if (info->vsel_reg == -1)
109                 return -ENOSYS;
110         val = (uvolt - info->min_uv) / info->step_uv;
111         debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask,
112               val);
113
114         return pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
115 }
116
117 static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
118 {
119         uint mask;
120         int ret;
121
122         buck--;
123         mask = 1 << buck;
124         if (enable) {
125                 ret = pmic_clrsetbits(pmic, REG_DCDC_ILMAX, 0, 3 << (buck * 2));
126                 if (ret)
127                         return ret;
128                 ret = pmic_clrsetbits(pmic, REG_DCDC_UV_ACT, 1 << buck, 0);
129                 if (ret)
130                         return ret;
131         }
132
133         return pmic_clrsetbits(pmic, REG_DCDC_EN, mask, enable ? mask : 0);
134 }
135
136 #ifdef ENABLE_DRIVER
137 static const struct rk8xx_reg_info *get_ldo_reg(struct udevice *pmic,
138                                              int num)
139 {
140         struct rk8xx_priv *priv = dev_get_priv(pmic);
141         switch (priv->variant) {
142         case RK818_ID:
143                 return &rk818_ldo[num];
144         default:
145                 return &rk808_ldo[num];
146         }
147 }
148
149 static int buck_get_value(struct udevice *dev)
150 {
151         int buck = dev->driver_data - 1;
152         const struct rk8xx_reg_info *info = get_buck_reg(dev->parent, buck);
153         int mask = info->vsel_mask;
154         int ret, val;
155
156         if (info->vsel_reg == -1)
157                 return -ENOSYS;
158         ret = pmic_reg_read(dev->parent, info->vsel_reg);
159         if (ret < 0)
160                 return ret;
161         val = ret & mask;
162
163         return info->min_uv + val * info->step_uv;
164 }
165
166 static int buck_set_value(struct udevice *dev, int uvolt)
167 {
168         int buck = dev->driver_data;
169
170         return _buck_set_value(dev->parent, buck, uvolt);
171 }
172
173 static int buck_set_enable(struct udevice *dev, bool enable)
174 {
175         int buck = dev->driver_data;
176
177         return _buck_set_enable(dev->parent, buck, enable);
178 }
179
180 static int buck_get_enable(struct udevice *dev)
181 {
182         int buck = dev->driver_data - 1;
183         int ret;
184         uint mask;
185
186         mask = 1 << buck;
187
188         ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
189         if (ret < 0)
190                 return ret;
191
192         return ret & mask ? true : false;
193 }
194
195 static int ldo_get_value(struct udevice *dev)
196 {
197         int ldo = dev->driver_data - 1;
198         const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
199         int mask = info->vsel_mask;
200         int ret, val;
201
202         if (info->vsel_reg == -1)
203                 return -ENOSYS;
204         ret = pmic_reg_read(dev->parent, info->vsel_reg);
205         if (ret < 0)
206                 return ret;
207         val = ret & mask;
208
209         return info->min_uv + val * info->step_uv;
210 }
211
212 static int ldo_set_value(struct udevice *dev, int uvolt)
213 {
214         int ldo = dev->driver_data - 1;
215         const struct rk8xx_reg_info *info = get_ldo_reg(dev->parent, ldo);
216         int mask = info->vsel_mask;
217         int val;
218
219         if (info->vsel_reg == -1)
220                 return -ENOSYS;
221         val = (uvolt - info->min_uv) / info->step_uv;
222         debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask,
223               val);
224
225         return pmic_clrsetbits(dev->parent, info->vsel_reg, mask, val);
226 }
227
228 static int ldo_set_enable(struct udevice *dev, bool enable)
229 {
230         int ldo = dev->driver_data - 1;
231         uint mask;
232
233         mask = 1 << ldo;
234
235         return pmic_clrsetbits(dev->parent, REG_LDO_EN, mask,
236                                enable ? mask : 0);
237 }
238
239 static int ldo_get_enable(struct udevice *dev)
240 {
241         int ldo = dev->driver_data - 1;
242         int ret;
243         uint mask;
244
245         mask = 1 << ldo;
246
247         ret = pmic_reg_read(dev->parent, REG_LDO_EN);
248         if (ret < 0)
249                 return ret;
250
251         return ret & mask ? true : false;
252 }
253
254 static int switch_set_enable(struct udevice *dev, bool enable)
255 {
256         int sw = dev->driver_data - 1;
257         uint mask;
258
259         mask = 1 << (sw + 5);
260
261         return pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
262                                enable ? mask : 0);
263 }
264
265 static int switch_get_enable(struct udevice *dev)
266 {
267         int sw = dev->driver_data - 1;
268         int ret;
269         uint mask;
270
271         mask = 1 << (sw + 5);
272
273         ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
274         if (ret < 0)
275                 return ret;
276
277         return ret & mask ? true : false;
278 }
279
280 static int rk8xx_buck_probe(struct udevice *dev)
281 {
282         struct dm_regulator_uclass_platdata *uc_pdata;
283
284         uc_pdata = dev_get_uclass_platdata(dev);
285
286         uc_pdata->type = REGULATOR_TYPE_BUCK;
287         uc_pdata->mode_count = 0;
288
289         return 0;
290 }
291
292 static int rk8xx_ldo_probe(struct udevice *dev)
293 {
294         struct dm_regulator_uclass_platdata *uc_pdata;
295
296         uc_pdata = dev_get_uclass_platdata(dev);
297
298         uc_pdata->type = REGULATOR_TYPE_LDO;
299         uc_pdata->mode_count = 0;
300
301         return 0;
302 }
303
304 static int rk8xx_switch_probe(struct udevice *dev)
305 {
306         struct dm_regulator_uclass_platdata *uc_pdata;
307
308         uc_pdata = dev_get_uclass_platdata(dev);
309
310         uc_pdata->type = REGULATOR_TYPE_FIXED;
311         uc_pdata->mode_count = 0;
312
313         return 0;
314 }
315
316 static const struct dm_regulator_ops rk8xx_buck_ops = {
317         .get_value  = buck_get_value,
318         .set_value  = buck_set_value,
319         .get_enable = buck_get_enable,
320         .set_enable = buck_set_enable,
321 };
322
323 static const struct dm_regulator_ops rk8xx_ldo_ops = {
324         .get_value  = ldo_get_value,
325         .set_value  = ldo_set_value,
326         .get_enable = ldo_get_enable,
327         .set_enable = ldo_set_enable,
328 };
329
330 static const struct dm_regulator_ops rk8xx_switch_ops = {
331         .get_enable = switch_get_enable,
332         .set_enable = switch_set_enable,
333 };
334
335 U_BOOT_DRIVER(rk8xx_buck) = {
336         .name = "rk8xx_buck",
337         .id = UCLASS_REGULATOR,
338         .ops = &rk8xx_buck_ops,
339         .probe = rk8xx_buck_probe,
340 };
341
342 U_BOOT_DRIVER(rk8xx_ldo) = {
343         .name = "rk8xx_ldo",
344         .id = UCLASS_REGULATOR,
345         .ops = &rk8xx_ldo_ops,
346         .probe = rk8xx_ldo_probe,
347 };
348
349 U_BOOT_DRIVER(rk8xx_switch) = {
350         .name = "rk8xx_switch",
351         .id = UCLASS_REGULATOR,
352         .ops = &rk8xx_switch_ops,
353         .probe = rk8xx_switch_probe,
354 };
355 #endif
356
357 int rk8xx_spl_configure_buck(struct udevice *pmic, int buck, int uvolt)
358 {
359         int ret;
360
361         ret = _buck_set_value(pmic, buck, uvolt);
362         if (ret)
363                 return ret;
364
365         return _buck_set_enable(pmic, buck, true);
366 }
367
368 int rk818_spl_configure_usb_input_current(struct udevice *pmic, int current_ma)
369 {
370         uint i;
371
372         for (i = 0; i < ARRAY_SIZE(rk818_chrg_cur_input_array); i++)
373                 if (current_ma <= rk818_chrg_cur_input_array[i])
374                         break;
375
376         return pmic_clrsetbits(pmic, REG_USB_CTRL, RK818_USB_ILIM_SEL_MASK, i);
377 }
378
379 int rk818_spl_configure_usb_chrg_shutdown(struct udevice *pmic, int uvolt)
380 {
381         uint i;
382
383         for (i = 0; i < ARRAY_SIZE(rk818_chrg_shutdown_vsel_array); i++)
384                 if (uvolt <= rk818_chrg_shutdown_vsel_array[i])
385                         break;
386
387         return pmic_clrsetbits(pmic, REG_USB_CTRL, RK818_USB_CHG_SD_VSEL_MASK,
388                                i);
389 }