]> git.sur5r.net Git - u-boot/blob - drivers/power/regulator/rk808.c
serial: Add serial driver for Intel MID
[u-boot] / drivers / power / regulator / rk808.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/rk808_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 struct rk808_reg_info {
24         uint min_uv;
25         uint step_uv;
26         s8 vsel_reg;
27         u8 vsel_bits;
28 };
29
30 static const struct rk808_reg_info rk808_buck[] = {
31         { 712500, 12500, REG_BUCK1_ON_VSEL, 6, },
32         { 712500, 12500, REG_BUCK2_ON_VSEL, 6, },
33         { 712500, 12500, -1, 6, },
34         { 1800000, 100000, REG_BUCK4_ON_VSEL, 4, },
35 };
36
37 static const struct rk808_reg_info rk808_ldo[] = {
38         { 1800000, 100000, LDO1_ON_VSEL, 5, },
39         { 1800000, 100000, LDO2_ON_VSEL, 5, },
40         { 800000, 100000, LDO3_ON_VSEL, 4, },
41         { 1800000, 100000, LDO4_ON_VSEL, 5, },
42         { 1800000, 100000, LDO5_ON_VSEL, 5, },
43         { 800000, 100000, LDO6_ON_VSEL, 5, },
44         { 800000, 100000, LDO7_ON_VSEL, 5, },
45         { 1800000, 100000, LDO8_ON_VSEL, 5, },
46 };
47
48
49 static int _buck_set_value(struct udevice *pmic, int buck, int uvolt)
50 {
51         const struct rk808_reg_info *info = &rk808_buck[buck - 1];
52         int mask = (1 << info->vsel_bits) - 1;
53         int val;
54
55         if (info->vsel_reg == -1)
56                 return -ENOSYS;
57         val = (uvolt - info->min_uv) / info->step_uv;
58         debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask,
59               val);
60
61         return pmic_clrsetbits(pmic, info->vsel_reg, mask, val);
62 }
63
64 static int _buck_set_enable(struct udevice *pmic, int buck, bool enable)
65 {
66         uint mask;
67         int ret;
68
69         buck--;
70         mask = 1 << buck;
71         if (enable) {
72                 ret = pmic_clrsetbits(pmic, DCDC_ILMAX, 0, 3 << (buck * 2));
73                 if (ret)
74                         return ret;
75                 ret = pmic_clrsetbits(pmic, REG_DCDC_UV_ACT, 1 << buck, 0);
76                 if (ret)
77                         return ret;
78         }
79
80         return pmic_clrsetbits(pmic, REG_DCDC_EN, mask, enable ? mask : 0);
81 }
82
83 #ifdef ENABLE_DRIVER
84 static int buck_get_value(struct udevice *dev)
85 {
86         int buck = dev->driver_data - 1;
87         const struct rk808_reg_info *info = &rk808_buck[buck];
88         int mask = (1 << info->vsel_bits) - 1;
89         int ret, val;
90
91         if (info->vsel_reg == -1)
92                 return -ENOSYS;
93         ret = pmic_reg_read(dev->parent, info->vsel_reg);
94         if (ret < 0)
95                 return ret;
96         val = ret & mask;
97
98         return info->min_uv + val * info->step_uv;
99 }
100
101 static int buck_set_value(struct udevice *dev, int uvolt)
102 {
103         int buck = dev->driver_data;
104
105         return _buck_set_value(dev->parent, buck, uvolt);
106 }
107
108 static int buck_set_enable(struct udevice *dev, bool enable)
109 {
110         int buck = dev->driver_data;
111
112         return _buck_set_enable(dev->parent, buck, enable);
113 }
114
115 static bool buck_get_enable(struct udevice *dev)
116 {
117         int buck = dev->driver_data - 1;
118         int ret;
119         uint mask;
120
121         mask = 1 << buck;
122
123         ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
124         if (ret < 0)
125                 return ret;
126
127         return ret & mask ? true : false;
128 }
129
130 static int ldo_get_value(struct udevice *dev)
131 {
132         int ldo = dev->driver_data - 1;
133         const struct rk808_reg_info *info = &rk808_ldo[ldo];
134         int mask = (1 << info->vsel_bits) - 1;
135         int ret, val;
136
137         if (info->vsel_reg == -1)
138                 return -ENOSYS;
139         ret = pmic_reg_read(dev->parent, info->vsel_reg);
140         if (ret < 0)
141                 return ret;
142         val = ret & mask;
143
144         return info->min_uv + val * info->step_uv;
145 }
146
147 static int ldo_set_value(struct udevice *dev, int uvolt)
148 {
149         int ldo = dev->driver_data - 1;
150         const struct rk808_reg_info *info = &rk808_ldo[ldo];
151         int mask = (1 << info->vsel_bits) - 1;
152         int val;
153
154         if (info->vsel_reg == -1)
155                 return -ENOSYS;
156         val = (uvolt - info->min_uv) / info->step_uv;
157         debug("%s: reg=%x, mask=%x, val=%x\n", __func__, info->vsel_reg, mask,
158               val);
159
160         return pmic_clrsetbits(dev->parent, info->vsel_reg, mask, val);
161 }
162
163 static int ldo_set_enable(struct udevice *dev, bool enable)
164 {
165         int ldo = dev->driver_data - 1;
166         uint mask;
167
168         mask = 1 << ldo;
169
170         return pmic_clrsetbits(dev->parent, REG_LDO_EN, mask,
171                                enable ? mask : 0);
172 }
173
174 static bool ldo_get_enable(struct udevice *dev)
175 {
176         int ldo = dev->driver_data - 1;
177         int ret;
178         uint mask;
179
180         mask = 1 << ldo;
181
182         ret = pmic_reg_read(dev->parent, REG_LDO_EN);
183         if (ret < 0)
184                 return ret;
185
186         return ret & mask ? true : false;
187 }
188
189 static int switch_set_enable(struct udevice *dev, bool enable)
190 {
191         int sw = dev->driver_data - 1;
192         uint mask;
193
194         mask = 1 << (sw + 5);
195
196         return pmic_clrsetbits(dev->parent, REG_DCDC_EN, mask,
197                                enable ? mask : 0);
198 }
199
200 static bool switch_get_enable(struct udevice *dev)
201 {
202         int sw = dev->driver_data - 1;
203         int ret;
204         uint mask;
205
206         mask = 1 << (sw + 5);
207
208         ret = pmic_reg_read(dev->parent, REG_DCDC_EN);
209         if (ret < 0)
210                 return ret;
211
212         return ret & mask ? true : false;
213 }
214
215 static int rk808_buck_probe(struct udevice *dev)
216 {
217         struct dm_regulator_uclass_platdata *uc_pdata;
218
219         uc_pdata = dev_get_uclass_platdata(dev);
220
221         uc_pdata->type = REGULATOR_TYPE_BUCK;
222         uc_pdata->mode_count = 0;
223
224         return 0;
225 }
226
227 static int rk808_ldo_probe(struct udevice *dev)
228 {
229         struct dm_regulator_uclass_platdata *uc_pdata;
230
231         uc_pdata = dev_get_uclass_platdata(dev);
232
233         uc_pdata->type = REGULATOR_TYPE_LDO;
234         uc_pdata->mode_count = 0;
235
236         return 0;
237 }
238
239 static int rk808_switch_probe(struct udevice *dev)
240 {
241         struct dm_regulator_uclass_platdata *uc_pdata;
242
243         uc_pdata = dev_get_uclass_platdata(dev);
244
245         uc_pdata->type = REGULATOR_TYPE_FIXED;
246         uc_pdata->mode_count = 0;
247
248         return 0;
249 }
250
251 static const struct dm_regulator_ops rk808_buck_ops = {
252         .get_value  = buck_get_value,
253         .set_value  = buck_set_value,
254         .get_enable = buck_get_enable,
255         .set_enable = buck_set_enable,
256 };
257
258 static const struct dm_regulator_ops rk808_ldo_ops = {
259         .get_value  = ldo_get_value,
260         .set_value  = ldo_set_value,
261         .get_enable = ldo_get_enable,
262         .set_enable = ldo_set_enable,
263 };
264
265 static const struct dm_regulator_ops rk808_switch_ops = {
266         .get_enable = switch_get_enable,
267         .set_enable = switch_set_enable,
268 };
269
270 U_BOOT_DRIVER(rk808_buck) = {
271         .name = "rk808_buck",
272         .id = UCLASS_REGULATOR,
273         .ops = &rk808_buck_ops,
274         .probe = rk808_buck_probe,
275 };
276
277 U_BOOT_DRIVER(rk808_ldo) = {
278         .name = "rk808_ldo",
279         .id = UCLASS_REGULATOR,
280         .ops = &rk808_ldo_ops,
281         .probe = rk808_ldo_probe,
282 };
283
284 U_BOOT_DRIVER(rk808_switch) = {
285         .name = "rk808_switch",
286         .id = UCLASS_REGULATOR,
287         .ops = &rk808_switch_ops,
288         .probe = rk808_switch_probe,
289 };
290 #endif
291
292 int rk808_spl_configure_buck(struct udevice *pmic, int buck, int uvolt)
293 {
294         int ret;
295
296         ret = _buck_set_value(pmic, buck, uvolt);
297         if (ret)
298                 return ret;
299
300         return _buck_set_enable(pmic, buck, true);
301 }