regulator: RK808: modify for struct rk808 change
[linux-2.6-block.git] / drivers / regulator / rk808-regulator.c
CommitLineData
2cd64ae3
CZ
1/*
2 * Regulator driver for Rockchip RK808
3 *
4 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
5 *
6 * Author: Chris Zhong <zyw@rock-chips.com>
7 * Author: Zhang Qing <zhangqing@rock-chips.com>
8 *
9 * This program is free software; you can redistribute it and/or modify it
10 * under the terms and conditions of the GNU General Public License,
11 * version 2, as published by the Free Software Foundation.
12 *
13 * This program is distributed in the hope it will be useful, but WITHOUT
14 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
16 * more details.
17 *
18 */
19
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/i2c.h>
23#include <linux/err.h>
24#include <linux/platform_device.h>
25#include <linux/mfd/rk808.h>
26#include <linux/of.h>
27#include <linux/of_device.h>
28#include <linux/regulator/driver.h>
29#include <linux/regulator/of_regulator.h>
30#include <linux/regmap.h>
31#include <linux/slab.h>
32/*
33 * Field Definitions.
34 */
35#define RK808_BUCK_VSEL_MASK 0x3f
36#define RK808_BUCK4_VSEL_MASK 0xf
37#define RK808_LDO_VSEL_MASK 0x1f
38
39static const int buck_set_vol_base_addr[] = {
40 RK808_BUCK1_ON_VSEL_REG,
41 RK808_BUCK2_ON_VSEL_REG,
42 RK808_BUCK3_CONFIG_REG,
43 RK808_BUCK4_ON_VSEL_REG,
44};
45
46static const int buck_contr_base_addr[] = {
47 RK808_BUCK1_CONFIG_REG,
48 RK808_BUCK2_CONFIG_REG,
49 RK808_BUCK3_CONFIG_REG,
50 RK808_BUCK4_CONFIG_REG,
51};
52
53#define rk808_BUCK_SET_VOL_REG(x) (buck_set_vol_base_addr[x])
54#define rk808_BUCK_CONTR_REG(x) (buck_contr_base_addr[x])
55#define rk808_LDO_SET_VOL_REG(x) (ldo_set_vol_base_addr[x])
56
57static const int ldo_set_vol_base_addr[] = {
58 RK808_LDO1_ON_VSEL_REG,
59 RK808_LDO2_ON_VSEL_REG,
60 RK808_LDO3_ON_VSEL_REG,
61 RK808_LDO4_ON_VSEL_REG,
62 RK808_LDO5_ON_VSEL_REG,
63 RK808_LDO6_ON_VSEL_REG,
64 RK808_LDO7_ON_VSEL_REG,
65 RK808_LDO8_ON_VSEL_REG,
66};
67
68/*
69 * rk808 voltage number
70 */
71static const struct regulator_linear_range rk808_buck_voltage_ranges[] = {
72 REGULATOR_LINEAR_RANGE(700000, 0, 63, 12500),
73};
74
75static const struct regulator_linear_range rk808_buck4_voltage_ranges[] = {
76 REGULATOR_LINEAR_RANGE(1800000, 0, 15, 100000),
77};
78
79static const struct regulator_linear_range rk808_ldo_voltage_ranges[] = {
80 REGULATOR_LINEAR_RANGE(1800000, 0, 16, 100000),
81};
82
83static const struct regulator_linear_range rk808_ldo3_voltage_ranges[] = {
84 REGULATOR_LINEAR_RANGE(800000, 0, 13, 100000),
85 REGULATOR_LINEAR_RANGE(2500000, 15, 15, 0),
86};
87
88static const struct regulator_linear_range rk808_ldo6_voltage_ranges[] = {
89 REGULATOR_LINEAR_RANGE(800000, 0, 17, 100000),
90};
91
92static struct regulator_ops rk808_reg_ops = {
93 .list_voltage = regulator_list_voltage_linear_range,
94 .map_voltage = regulator_map_voltage_linear_range,
95 .get_voltage_sel = regulator_get_voltage_sel_regmap,
96 .set_voltage_sel = regulator_set_voltage_sel_regmap,
97 .enable = regulator_enable_regmap,
98 .disable = regulator_disable_regmap,
99 .is_enabled = regulator_is_enabled_regmap,
100};
101
102static struct regulator_ops rk808_switch_ops = {
103 .enable = regulator_enable_regmap,
104 .disable = regulator_disable_regmap,
105 .is_enabled = regulator_is_enabled_regmap,
106};
107
108static const struct regulator_desc rk808_reg[] = {
109 {
110 .name = "DCDC_REG1",
111 .id = RK808_ID_DCDC1,
112 .ops = &rk808_reg_ops,
113 .type = REGULATOR_VOLTAGE,
114 .n_voltages = 64,
115 .linear_ranges = rk808_buck_voltage_ranges,
116 .n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges),
117 .vsel_reg = RK808_BUCK1_ON_VSEL_REG,
118 .vsel_mask = RK808_BUCK_VSEL_MASK,
119 .enable_reg = RK808_DCDC_EN_REG,
120 .enable_mask = BIT(0),
121 .owner = THIS_MODULE,
122 }, {
123 .name = "DCDC_REG2",
124 .id = RK808_ID_DCDC2,
125 .ops = &rk808_reg_ops,
126 .type = REGULATOR_VOLTAGE,
127 .n_voltages = 64,
128 .linear_ranges = rk808_buck_voltage_ranges,
129 .n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges),
130 .vsel_reg = RK808_BUCK2_ON_VSEL_REG,
131 .vsel_mask = RK808_BUCK_VSEL_MASK,
132 .enable_reg = RK808_DCDC_EN_REG,
133 .enable_mask = BIT(1),
134 .owner = THIS_MODULE,
135 }, {
136 .name = "DCDC_REG3",
137 .id = RK808_ID_DCDC3,
138 .ops = &rk808_switch_ops,
139 .type = REGULATOR_VOLTAGE,
140 .n_voltages = 1,
141 .enable_reg = RK808_DCDC_EN_REG,
142 .enable_mask = BIT(2),
143 .owner = THIS_MODULE,
144 }, {
145 .name = "DCDC_REG4",
146 .id = RK808_ID_DCDC4,
147 .ops = &rk808_reg_ops,
148 .type = REGULATOR_VOLTAGE,
149 .n_voltages = 17,
150 .linear_ranges = rk808_buck4_voltage_ranges,
151 .n_linear_ranges = ARRAY_SIZE(rk808_buck4_voltage_ranges),
152 .vsel_reg = RK808_BUCK4_ON_VSEL_REG,
153 .vsel_mask = RK808_BUCK4_VSEL_MASK,
154 .enable_reg = RK808_DCDC_EN_REG,
155 .enable_mask = BIT(3),
156 .owner = THIS_MODULE,
157 }, {
158 .name = "LDO_REG1",
159 .id = RK808_ID_LDO1,
160 .ops = &rk808_reg_ops,
161 .type = REGULATOR_VOLTAGE,
162 .n_voltages = 17,
163 .linear_ranges = rk808_ldo_voltage_ranges,
164 .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
165 .vsel_reg = RK808_LDO1_ON_VSEL_REG,
166 .vsel_mask = RK808_LDO_VSEL_MASK,
167 .enable_reg = RK808_LDO_EN_REG,
168 .enable_mask = BIT(0),
169 .owner = THIS_MODULE,
170 }, {
171 .name = "LDO_REG2",
172 .id = RK808_ID_LDO2,
173 .ops = &rk808_reg_ops,
174 .type = REGULATOR_VOLTAGE,
175 .n_voltages = 17,
176 .linear_ranges = rk808_ldo_voltage_ranges,
177 .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
178 .vsel_reg = RK808_LDO2_ON_VSEL_REG,
179 .vsel_mask = RK808_LDO_VSEL_MASK,
180 .enable_reg = RK808_LDO_EN_REG,
181 .enable_mask = BIT(1),
182 .owner = THIS_MODULE,
183 }, {
184 .name = "LDO_REG3",
185 .id = RK808_ID_LDO3,
186 .ops = &rk808_reg_ops,
187 .type = REGULATOR_VOLTAGE,
188 .n_voltages = 16,
189 .linear_ranges = rk808_ldo3_voltage_ranges,
190 .n_linear_ranges = ARRAY_SIZE(rk808_ldo3_voltage_ranges),
191 .vsel_reg = RK808_LDO3_ON_VSEL_REG,
192 .vsel_mask = RK808_BUCK4_VSEL_MASK,
193 .enable_reg = RK808_LDO_EN_REG,
194 .enable_mask = BIT(2),
195 .owner = THIS_MODULE,
196 }, {
197 .name = "LDO_REG4",
198 .id = RK808_ID_LDO4,
199 .ops = &rk808_reg_ops,
200 .type = REGULATOR_VOLTAGE,
201 .n_voltages = 17,
202 .linear_ranges = rk808_ldo_voltage_ranges,
203 .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
204 .vsel_reg = RK808_LDO4_ON_VSEL_REG,
205 .vsel_mask = RK808_LDO_VSEL_MASK,
206 .enable_reg = RK808_LDO_EN_REG,
207 .enable_mask = BIT(3),
208 .owner = THIS_MODULE,
209 }, {
210 .name = "LDO_REG5",
211 .id = RK808_ID_LDO5,
212 .ops = &rk808_reg_ops,
213 .type = REGULATOR_VOLTAGE,
214 .n_voltages = 17,
215 .linear_ranges = rk808_ldo_voltage_ranges,
216 .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
217 .vsel_reg = RK808_LDO5_ON_VSEL_REG,
218 .vsel_mask = RK808_LDO_VSEL_MASK,
219 .enable_reg = RK808_LDO_EN_REG,
220 .enable_mask = BIT(4),
221 .owner = THIS_MODULE,
222 }, {
223 .name = "LDO_REG6",
224 .id = RK808_ID_LDO6,
225 .ops = &rk808_reg_ops,
226 .type = REGULATOR_VOLTAGE,
227 .n_voltages = 18,
228 .linear_ranges = rk808_ldo6_voltage_ranges,
229 .n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges),
230 .vsel_reg = RK808_LDO6_ON_VSEL_REG,
231 .vsel_mask = RK808_LDO_VSEL_MASK,
232 .enable_reg = RK808_LDO_EN_REG,
233 .enable_mask = BIT(5),
234 .owner = THIS_MODULE,
235 }, {
236 .name = "LDO_REG7",
237 .id = RK808_ID_LDO7,
238 .ops = &rk808_reg_ops,
239 .type = REGULATOR_VOLTAGE,
240 .n_voltages = 18,
241 .linear_ranges = rk808_ldo6_voltage_ranges,
242 .n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges),
243 .vsel_reg = RK808_LDO7_ON_VSEL_REG,
244 .vsel_mask = RK808_LDO_VSEL_MASK,
245 .enable_reg = RK808_LDO_EN_REG,
246 .enable_mask = BIT(6),
247 .owner = THIS_MODULE,
248 }, {
249 .name = "LDO_REG8",
250 .id = RK808_ID_LDO8,
251 .ops = &rk808_reg_ops,
252 .type = REGULATOR_VOLTAGE,
253 .n_voltages = 17,
254 .linear_ranges = rk808_ldo_voltage_ranges,
255 .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
256 .vsel_reg = RK808_LDO8_ON_VSEL_REG,
257 .vsel_mask = RK808_LDO_VSEL_MASK,
258 .enable_reg = RK808_LDO_EN_REG,
259 .enable_mask = BIT(7),
260 .owner = THIS_MODULE,
261 }, {
262 .name = "SWITCH_REG1",
263 .id = RK808_ID_SWITCH1,
264 .ops = &rk808_switch_ops,
265 .type = REGULATOR_VOLTAGE,
266 .enable_reg = RK808_DCDC_EN_REG,
267 .enable_mask = BIT(5),
268 .owner = THIS_MODULE,
269 }, {
270 .name = "SWITCH_REG2",
271 .id = RK808_ID_SWITCH2,
272 .ops = &rk808_switch_ops,
273 .type = REGULATOR_VOLTAGE,
274 .enable_reg = RK808_DCDC_EN_REG,
275 .enable_mask = BIT(6),
276 .owner = THIS_MODULE,
277 },
278};
279
280static struct of_regulator_match rk808_reg_matches[] = {
281 [RK808_ID_DCDC1] = { .name = "DCDC_REG1" },
282 [RK808_ID_DCDC2] = { .name = "DCDC_REG2" },
283 [RK808_ID_DCDC3] = { .name = "DCDC_REG3" },
284 [RK808_ID_DCDC4] = { .name = "DCDC_REG4" },
285 [RK808_ID_LDO1] = { .name = "LDO_REG1" },
286 [RK808_ID_LDO2] = { .name = "LDO_REG2" },
287 [RK808_ID_LDO3] = { .name = "LDO_REG3" },
288 [RK808_ID_LDO4] = { .name = "LDO_REG4" },
289 [RK808_ID_LDO5] = { .name = "LDO_REG5" },
290 [RK808_ID_LDO6] = { .name = "LDO_REG6" },
291 [RK808_ID_LDO7] = { .name = "LDO_REG7" },
292 [RK808_ID_LDO8] = { .name = "LDO_REG8" },
293 [RK808_ID_SWITCH1] = { .name = "SWITCH_REG1" },
294 [RK808_ID_SWITCH2] = { .name = "SWITCH_REG2" },
295};
296
297static int rk808_regulator_dts(struct rk808 *rk808)
298{
2cd64ae3 299 struct device_node *np, *reg_np;
d76c333e
CZ
300 struct i2c_client *client = rk808->i2c;
301 struct rk808_board *pdata = rk808->pdata;
2cd64ae3
CZ
302 int i, ret;
303
d76c333e 304 np = client->dev.of_node;
2cd64ae3 305 if (!np) {
d76c333e 306 dev_err(&client->dev, "could not find pmic sub-node\n");
2cd64ae3
CZ
307 return -ENXIO;
308 }
309
310 reg_np = of_get_child_by_name(np, "regulators");
311 if (!reg_np)
312 return -ENXIO;
313
d76c333e 314 ret = of_regulator_match(&client->dev, reg_np, rk808_reg_matches,
2cd64ae3 315 RK808_NUM_REGULATORS);
d76c333e
CZ
316 if (ret < 0) {
317 dev_err(&client->dev,
2cd64ae3
CZ
318 "failed to parse regulator data: %d\n", ret);
319 return ret;
320 }
321
322 for (i = 0; i < RK808_NUM_REGULATORS; i++) {
323 if (!rk808_reg_matches[i].init_data ||
324 !rk808_reg_matches[i].of_node)
325 continue;
326
327 pdata->rk808_init_data[i] = rk808_reg_matches[i].init_data;
328 pdata->of_node[i] = rk808_reg_matches[i].of_node;
329 }
330
331 return 0;
332}
333
334static int rk808_regulator_probe(struct platform_device *pdev)
335{
336 struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
d76c333e
CZ
337 struct i2c_client *client = rk808->i2c;
338 struct rk808_board *pdata = rk808->pdata;
462004f1 339 struct regulator_config config = {};
2cd64ae3
CZ
340 struct regulator_dev *rk808_rdev;
341 struct regulator_init_data *reg_data;
342 int i = 0;
343 int ret = 0;
344
2cd64ae3 345 if (!pdata) {
d76c333e
CZ
346 dev_warn(&client->dev, "%s no pdata, create it\n", __func__);
347 pdata = devm_kzalloc(&client->dev, sizeof(*pdata), GFP_KERNEL);
2cd64ae3
CZ
348 if (!pdata)
349 return -ENOMEM;
350 }
351
352 ret = rk808_regulator_dts(rk808);
353 if (ret)
354 return ret;
355
356 rk808->num_regulators = RK808_NUM_REGULATORS;
357 rk808->rdev = devm_kzalloc(&pdev->dev, RK808_NUM_REGULATORS *
358 sizeof(struct regulator_dev *), GFP_KERNEL);
359 if (!rk808->rdev)
360 return -ENOMEM;
361
362 /* Instantiate the regulators */
363 for (i = 0; i < RK808_NUM_REGULATORS; i++) {
364 reg_data = pdata->rk808_init_data[i];
365 if (!reg_data)
366 continue;
367
d76c333e 368 config.dev = &client->dev;
2cd64ae3
CZ
369 config.driver_data = rk808;
370 config.regmap = rk808->regmap;
371
d76c333e 372 if (client->dev.of_node)
2cd64ae3
CZ
373 config.of_node = pdata->of_node[i];
374
375 reg_data->supply_regulator = rk808_reg[i].name;
376 config.init_data = reg_data;
377
378 rk808_rdev = devm_regulator_register(&pdev->dev,
379 &rk808_reg[i], &config);
380 if (IS_ERR(rk808_rdev)) {
d76c333e 381 dev_err(&client->dev,
2cd64ae3
CZ
382 "failed to register %d regulator\n", i);
383 return PTR_ERR(rk808_rdev);
384 }
385 rk808->rdev[i] = rk808_rdev;
386 }
387 return 0;
388}
389
390static struct platform_driver rk808_regulator_driver = {
391 .probe = rk808_regulator_probe,
392 .driver = {
393 .name = "rk808-regulator",
394 .owner = THIS_MODULE,
395 },
396};
397
398module_platform_driver(rk808_regulator_driver);
399
400MODULE_DESCRIPTION("regulator driver for the rk808 series PMICs");
401MODULE_AUTHOR("Chris Zhong<zyw@rock-chips.com>");
402MODULE_AUTHOR("Zhang Qing<zhanqging@rock-chips.com>");
403MODULE_LICENSE("GPL");
404MODULE_ALIAS("platform:rk808-regulator");