2 * Regulator driver for Rockchip RK808
4 * Copyright (c) 2014, Fuzhou Rockchip Electronics Co., Ltd
6 * Author: Chris Zhong <zyw@rock-chips.com>
7 * Author: Zhang Qing <zhangqing@rock-chips.com>
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.
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
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>
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>
35 #define RK808_BUCK_VSEL_MASK 0x3f
36 #define RK808_BUCK4_VSEL_MASK 0xf
37 #define RK808_LDO_VSEL_MASK 0x1f
39 static 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,
46 static 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,
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])
57 static 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,
69 * rk808 voltage number
71 static const struct regulator_linear_range rk808_buck_voltage_ranges[] = {
72 REGULATOR_LINEAR_RANGE(700000, 0, 63, 12500),
75 static const struct regulator_linear_range rk808_buck4_voltage_ranges[] = {
76 REGULATOR_LINEAR_RANGE(1800000, 0, 15, 100000),
79 static const struct regulator_linear_range rk808_ldo_voltage_ranges[] = {
80 REGULATOR_LINEAR_RANGE(1800000, 0, 16, 100000),
83 static 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),
88 static const struct regulator_linear_range rk808_ldo6_voltage_ranges[] = {
89 REGULATOR_LINEAR_RANGE(800000, 0, 17, 100000),
92 static 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,
102 static struct regulator_ops rk808_switch_ops = {
103 .enable = regulator_enable_regmap,
104 .disable = regulator_disable_regmap,
105 .is_enabled = regulator_is_enabled_regmap,
108 static const struct regulator_desc rk808_reg[] = {
111 .id = RK808_ID_DCDC1,
112 .ops = &rk808_reg_ops,
113 .type = REGULATOR_VOLTAGE,
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,
124 .id = RK808_ID_DCDC2,
125 .ops = &rk808_reg_ops,
126 .type = REGULATOR_VOLTAGE,
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,
137 .id = RK808_ID_DCDC3,
138 .ops = &rk808_switch_ops,
139 .type = REGULATOR_VOLTAGE,
141 .enable_reg = RK808_DCDC_EN_REG,
142 .enable_mask = BIT(2),
143 .owner = THIS_MODULE,
146 .id = RK808_ID_DCDC4,
147 .ops = &rk808_reg_ops,
148 .type = REGULATOR_VOLTAGE,
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,
160 .ops = &rk808_reg_ops,
161 .type = REGULATOR_VOLTAGE,
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,
173 .ops = &rk808_reg_ops,
174 .type = REGULATOR_VOLTAGE,
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,
186 .ops = &rk808_reg_ops,
187 .type = REGULATOR_VOLTAGE,
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,
199 .ops = &rk808_reg_ops,
200 .type = REGULATOR_VOLTAGE,
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,
212 .ops = &rk808_reg_ops,
213 .type = REGULATOR_VOLTAGE,
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,
225 .ops = &rk808_reg_ops,
226 .type = REGULATOR_VOLTAGE,
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,
238 .ops = &rk808_reg_ops,
239 .type = REGULATOR_VOLTAGE,
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,
251 .ops = &rk808_reg_ops,
252 .type = REGULATOR_VOLTAGE,
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,
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,
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,
280 static 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" },
297 static int rk808_regulator_dts(struct i2c_client *client,
298 struct rk808_board *pdata)
300 struct device_node *np, *reg_np;
303 np = client->dev.of_node;
305 dev_err(&client->dev, "could not find pmic sub-node\n");
309 reg_np = of_get_child_by_name(np, "regulators");
313 ret = of_regulator_match(&client->dev, reg_np, rk808_reg_matches,
314 RK808_NUM_REGULATORS);
316 dev_err(&client->dev,
317 "failed to parse regulator data: %d\n", ret);
321 for (i = 0; i < RK808_NUM_REGULATORS; i++) {
322 if (!rk808_reg_matches[i].init_data ||
323 !rk808_reg_matches[i].of_node)
326 pdata->rk808_init_data[i] = rk808_reg_matches[i].init_data;
327 pdata->of_node[i] = rk808_reg_matches[i].of_node;
333 static int rk808_regulator_probe(struct platform_device *pdev)
335 struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
336 struct i2c_client *client = rk808->i2c;
337 struct rk808_board *pdata = dev_get_platdata(&client->dev);
338 struct regulator_config config = {};
339 struct regulator_dev *rk808_rdev;
340 struct regulator_init_data *reg_data;
345 pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
350 ret = rk808_regulator_dts(client, pdata);
354 /* Instantiate the regulators */
355 for (i = 0; i < RK808_NUM_REGULATORS; i++) {
356 reg_data = pdata->rk808_init_data[i];
360 config.dev = &client->dev;
361 config.driver_data = rk808;
362 config.regmap = rk808->regmap;
364 if (client->dev.of_node)
365 config.of_node = pdata->of_node[i];
367 reg_data->supply_regulator = rk808_reg[i].name;
368 config.init_data = reg_data;
370 rk808_rdev = devm_regulator_register(&pdev->dev,
371 &rk808_reg[i], &config);
372 if (IS_ERR(rk808_rdev)) {
373 dev_err(&client->dev,
374 "failed to register %d regulator\n", i);
375 return PTR_ERR(rk808_rdev);
381 static struct platform_driver rk808_regulator_driver = {
382 .probe = rk808_regulator_probe,
384 .name = "rk808-regulator",
385 .owner = THIS_MODULE,
389 module_platform_driver(rk808_regulator_driver);
391 MODULE_DESCRIPTION("regulator driver for the rk808 series PMICs");
392 MODULE_AUTHOR("Chris Zhong<zyw@rock-chips.com>");
393 MODULE_AUTHOR("Zhang Qing<zhanqging@rock-chips.com>");
394 MODULE_LICENSE("GPL");
395 MODULE_ALIAS("platform:rk808-regulator");