07b0eb4adf420076564d6971fdc6ae49421eecd5
[cascardo/linux.git] / drivers / regulator / rk808-regulator.c
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 #include <linux/module.h>
20 #include <linux/i2c.h>
21 #include <linux/mfd/rk808.h>
22 #include <linux/of_device.h>
23 #include <linux/regulator/driver.h>
24 #include <linux/regulator/of_regulator.h>
25
26 /* Field Definitions */
27 #define RK808_BUCK_VSEL_MASK    0x3f
28 #define RK808_BUCK4_VSEL_MASK   0xf
29 #define RK808_LDO_VSEL_MASK     0x1f
30
31 static const struct regulator_linear_range rk808_buck_voltage_ranges[] = {
32         REGULATOR_LINEAR_RANGE(700000, 0, 63, 12500),
33 };
34
35 static const struct regulator_linear_range rk808_buck4_voltage_ranges[] = {
36         REGULATOR_LINEAR_RANGE(1800000, 0, 15, 100000),
37 };
38
39 static const struct regulator_linear_range rk808_ldo_voltage_ranges[] = {
40         REGULATOR_LINEAR_RANGE(1800000, 0, 16, 100000),
41 };
42
43 static const struct regulator_linear_range rk808_ldo3_voltage_ranges[] = {
44         REGULATOR_LINEAR_RANGE(800000, 0, 13, 100000),
45         REGULATOR_LINEAR_RANGE(2500000, 15, 15, 0),
46 };
47
48 static const struct regulator_linear_range rk808_ldo6_voltage_ranges[] = {
49         REGULATOR_LINEAR_RANGE(800000, 0, 17, 100000),
50 };
51
52 static struct regulator_ops rk808_reg_ops = {
53         .list_voltage           = regulator_list_voltage_linear_range,
54         .map_voltage            = regulator_map_voltage_linear_range,
55         .get_voltage_sel        = regulator_get_voltage_sel_regmap,
56         .set_voltage_sel        = regulator_set_voltage_sel_regmap,
57         .enable                 = regulator_enable_regmap,
58         .disable                = regulator_disable_regmap,
59         .is_enabled             = regulator_is_enabled_regmap,
60 };
61
62 static struct regulator_ops rk808_switch_ops = {
63         .enable = regulator_enable_regmap,
64         .disable = regulator_disable_regmap,
65         .is_enabled = regulator_is_enabled_regmap,
66 };
67
68 static const struct regulator_desc rk808_reg[] = {
69         {
70                 .name = "DCDC_REG1",
71                 .supply_name = "vcc1",
72                 .id = RK808_ID_DCDC1,
73                 .ops = &rk808_reg_ops,
74                 .type = REGULATOR_VOLTAGE,
75                 .n_voltages = 64,
76                 .linear_ranges = rk808_buck_voltage_ranges,
77                 .n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges),
78                 .vsel_reg = RK808_BUCK1_ON_VSEL_REG,
79                 .vsel_mask = RK808_BUCK_VSEL_MASK,
80                 .enable_reg = RK808_DCDC_EN_REG,
81                 .enable_mask = BIT(0),
82                 .owner = THIS_MODULE,
83         }, {
84                 .name = "DCDC_REG2",
85                 .supply_name = "vcc2",
86                 .id = RK808_ID_DCDC2,
87                 .ops = &rk808_reg_ops,
88                 .type = REGULATOR_VOLTAGE,
89                 .n_voltages = 64,
90                 .linear_ranges = rk808_buck_voltage_ranges,
91                 .n_linear_ranges = ARRAY_SIZE(rk808_buck_voltage_ranges),
92                 .vsel_reg = RK808_BUCK2_ON_VSEL_REG,
93                 .vsel_mask = RK808_BUCK_VSEL_MASK,
94                 .enable_reg = RK808_DCDC_EN_REG,
95                 .enable_mask = BIT(1),
96                 .owner = THIS_MODULE,
97         }, {
98                 .name = "DCDC_REG3",
99                 .supply_name = "vcc3",
100                 .id = RK808_ID_DCDC3,
101                 .ops = &rk808_switch_ops,
102                 .type = REGULATOR_VOLTAGE,
103                 .n_voltages = 1,
104                 .enable_reg = RK808_DCDC_EN_REG,
105                 .enable_mask = BIT(2),
106                 .owner = THIS_MODULE,
107         }, {
108                 .name = "DCDC_REG4",
109                 .supply_name = "vcc4",
110                 .id = RK808_ID_DCDC4,
111                 .ops = &rk808_reg_ops,
112                 .type = REGULATOR_VOLTAGE,
113                 .n_voltages = 16,
114                 .linear_ranges = rk808_buck4_voltage_ranges,
115                 .n_linear_ranges = ARRAY_SIZE(rk808_buck4_voltage_ranges),
116                 .vsel_reg = RK808_BUCK4_ON_VSEL_REG,
117                 .vsel_mask = RK808_BUCK4_VSEL_MASK,
118                 .enable_reg = RK808_DCDC_EN_REG,
119                 .enable_mask = BIT(3),
120                 .owner = THIS_MODULE,
121         }, {
122                 .name = "LDO_REG1",
123                 .supply_name = "vcc6",
124                 .id = RK808_ID_LDO1,
125                 .ops = &rk808_reg_ops,
126                 .type = REGULATOR_VOLTAGE,
127                 .n_voltages = 17,
128                 .linear_ranges = rk808_ldo_voltage_ranges,
129                 .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
130                 .vsel_reg = RK808_LDO1_ON_VSEL_REG,
131                 .vsel_mask = RK808_LDO_VSEL_MASK,
132                 .enable_reg = RK808_LDO_EN_REG,
133                 .enable_mask = BIT(0),
134                 .owner = THIS_MODULE,
135         }, {
136                 .name = "LDO_REG2",
137                 .supply_name = "vcc6",
138                 .id = RK808_ID_LDO2,
139                 .ops = &rk808_reg_ops,
140                 .type = REGULATOR_VOLTAGE,
141                 .n_voltages = 17,
142                 .linear_ranges = rk808_ldo_voltage_ranges,
143                 .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
144                 .vsel_reg = RK808_LDO2_ON_VSEL_REG,
145                 .vsel_mask = RK808_LDO_VSEL_MASK,
146                 .enable_reg = RK808_LDO_EN_REG,
147                 .enable_mask = BIT(1),
148                 .owner = THIS_MODULE,
149         }, {
150                 .name = "LDO_REG3",
151                 .supply_name = "vcc7",
152                 .id = RK808_ID_LDO3,
153                 .ops = &rk808_reg_ops,
154                 .type = REGULATOR_VOLTAGE,
155                 .n_voltages = 16,
156                 .linear_ranges = rk808_ldo3_voltage_ranges,
157                 .n_linear_ranges = ARRAY_SIZE(rk808_ldo3_voltage_ranges),
158                 .vsel_reg = RK808_LDO3_ON_VSEL_REG,
159                 .vsel_mask = RK808_BUCK4_VSEL_MASK,
160                 .enable_reg = RK808_LDO_EN_REG,
161                 .enable_mask = BIT(2),
162                 .owner = THIS_MODULE,
163         }, {
164                 .name = "LDO_REG4",
165                 .supply_name = "vcc9",
166                 .id = RK808_ID_LDO4,
167                 .ops = &rk808_reg_ops,
168                 .type = REGULATOR_VOLTAGE,
169                 .n_voltages = 17,
170                 .linear_ranges = rk808_ldo_voltage_ranges,
171                 .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
172                 .vsel_reg = RK808_LDO4_ON_VSEL_REG,
173                 .vsel_mask = RK808_LDO_VSEL_MASK,
174                 .enable_reg = RK808_LDO_EN_REG,
175                 .enable_mask = BIT(3),
176                 .owner = THIS_MODULE,
177         }, {
178                 .name = "LDO_REG5",
179                 .supply_name = "vcc9",
180                 .id = RK808_ID_LDO5,
181                 .ops = &rk808_reg_ops,
182                 .type = REGULATOR_VOLTAGE,
183                 .n_voltages = 17,
184                 .linear_ranges = rk808_ldo_voltage_ranges,
185                 .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
186                 .vsel_reg = RK808_LDO5_ON_VSEL_REG,
187                 .vsel_mask = RK808_LDO_VSEL_MASK,
188                 .enable_reg = RK808_LDO_EN_REG,
189                 .enable_mask = BIT(4),
190                 .owner = THIS_MODULE,
191         }, {
192                 .name = "LDO_REG6",
193                 .supply_name = "vcc10",
194                 .id = RK808_ID_LDO6,
195                 .ops = &rk808_reg_ops,
196                 .type = REGULATOR_VOLTAGE,
197                 .n_voltages = 18,
198                 .linear_ranges = rk808_ldo6_voltage_ranges,
199                 .n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges),
200                 .vsel_reg = RK808_LDO6_ON_VSEL_REG,
201                 .vsel_mask = RK808_LDO_VSEL_MASK,
202                 .enable_reg = RK808_LDO_EN_REG,
203                 .enable_mask = BIT(5),
204                 .owner = THIS_MODULE,
205         }, {
206                 .name = "LDO_REG7",
207                 .supply_name = "vcc7",
208                 .id = RK808_ID_LDO7,
209                 .ops = &rk808_reg_ops,
210                 .type = REGULATOR_VOLTAGE,
211                 .n_voltages = 18,
212                 .linear_ranges = rk808_ldo6_voltage_ranges,
213                 .n_linear_ranges = ARRAY_SIZE(rk808_ldo6_voltage_ranges),
214                 .vsel_reg = RK808_LDO7_ON_VSEL_REG,
215                 .vsel_mask = RK808_LDO_VSEL_MASK,
216                 .enable_reg = RK808_LDO_EN_REG,
217                 .enable_mask = BIT(6),
218                 .owner = THIS_MODULE,
219         }, {
220                 .name = "LDO_REG8",
221                 .supply_name = "vcc11",
222                 .id = RK808_ID_LDO8,
223                 .ops = &rk808_reg_ops,
224                 .type = REGULATOR_VOLTAGE,
225                 .n_voltages = 17,
226                 .linear_ranges = rk808_ldo_voltage_ranges,
227                 .n_linear_ranges = ARRAY_SIZE(rk808_ldo_voltage_ranges),
228                 .vsel_reg = RK808_LDO8_ON_VSEL_REG,
229                 .vsel_mask = RK808_LDO_VSEL_MASK,
230                 .enable_reg = RK808_LDO_EN_REG,
231                 .enable_mask = BIT(7),
232                 .owner = THIS_MODULE,
233         }, {
234                 .name = "SWITCH_REG1",
235                 .supply_name = "vcc8",
236                 .id = RK808_ID_SWITCH1,
237                 .ops = &rk808_switch_ops,
238                 .type = REGULATOR_VOLTAGE,
239                 .enable_reg = RK808_DCDC_EN_REG,
240                 .enable_mask = BIT(5),
241                 .owner = THIS_MODULE,
242         }, {
243                 .name = "SWITCH_REG2",
244                 .supply_name = "vcc12",
245                 .id = RK808_ID_SWITCH2,
246                 .ops = &rk808_switch_ops,
247                 .type = REGULATOR_VOLTAGE,
248                 .enable_reg = RK808_DCDC_EN_REG,
249                 .enable_mask = BIT(6),
250                 .owner = THIS_MODULE,
251         },
252 };
253
254 static struct of_regulator_match rk808_reg_matches[] = {
255         [RK808_ID_DCDC1]        = { .name = "DCDC_REG1" },
256         [RK808_ID_DCDC2]        = { .name = "DCDC_REG2" },
257         [RK808_ID_DCDC3]        = { .name = "DCDC_REG3" },
258         [RK808_ID_DCDC4]        = { .name = "DCDC_REG4" },
259         [RK808_ID_LDO1]         = { .name = "LDO_REG1" },
260         [RK808_ID_LDO2]         = { .name = "LDO_REG2" },
261         [RK808_ID_LDO3]         = { .name = "LDO_REG3" },
262         [RK808_ID_LDO4]         = { .name = "LDO_REG4" },
263         [RK808_ID_LDO5]         = { .name = "LDO_REG5" },
264         [RK808_ID_LDO6]         = { .name = "LDO_REG6" },
265         [RK808_ID_LDO7]         = { .name = "LDO_REG7" },
266         [RK808_ID_LDO8]         = { .name = "LDO_REG8" },
267         [RK808_ID_SWITCH1]      = { .name = "SWITCH_REG1" },
268         [RK808_ID_SWITCH2]      = { .name = "SWITCH_REG2" },
269 };
270
271 static int rk808_regulator_probe(struct platform_device *pdev)
272 {
273         struct rk808 *rk808 = dev_get_drvdata(pdev->dev.parent);
274         struct i2c_client *client = rk808->i2c;
275         struct device_node *reg_np;
276         struct regulator_config config = {};
277         struct regulator_dev *rk808_rdev;
278         int ret, i;
279
280         reg_np = of_get_child_by_name(client->dev.of_node, "regulators");
281         if (!reg_np)
282                 return -ENXIO;
283
284         ret = of_regulator_match(&pdev->dev, reg_np, rk808_reg_matches,
285                                  RK808_NUM_REGULATORS);
286         of_node_put(reg_np);
287         if (ret < 0)
288                 return ret;
289
290         /* Instantiate the regulators */
291         for (i = 0; i < RK808_NUM_REGULATORS; i++) {
292                 if (!rk808_reg_matches[i].init_data ||
293                     !rk808_reg_matches[i].of_node)
294                         continue;
295
296                 config.dev = &client->dev;
297                 config.driver_data = rk808;
298                 config.regmap = rk808->regmap;
299                 config.of_node = rk808_reg_matches[i].of_node;
300                 config.init_data = rk808_reg_matches[i].init_data;
301
302                 rk808_rdev = devm_regulator_register(&pdev->dev,
303                                                      &rk808_reg[i], &config);
304                 if (IS_ERR(rk808_rdev)) {
305                         dev_err(&client->dev,
306                                 "failed to register %d regulator\n", i);
307                         return PTR_ERR(rk808_rdev);
308                 }
309         }
310
311         return 0;
312 }
313
314 static struct platform_driver rk808_regulator_driver = {
315         .probe = rk808_regulator_probe,
316         .driver = {
317                 .name = "rk808-regulator",
318                 .owner = THIS_MODULE,
319         },
320 };
321
322 module_platform_driver(rk808_regulator_driver);
323
324 MODULE_DESCRIPTION("regulator driver for the rk808 series PMICs");
325 MODULE_AUTHOR("Chris Zhong<zyw@rock-chips.com>");
326 MODULE_AUTHOR("Zhang Qing<zhangqing@rock-chips.com>");
327 MODULE_LICENSE("GPL");
328 MODULE_ALIAS("platform:rk808-regulator");