Merge branches 'clk-doc', 'clk-more-critical', 'clk-meson' and 'clk-basic-be' into...
[linux-2.6-microblaze.git] / drivers / regulator / bd70528-regulator.c
1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2018 ROHM Semiconductors
3 // bd70528-regulator.c ROHM BD70528MWV regulator driver
4
5 #include <linux/delay.h>
6 #include <linux/err.h>
7 #include <linux/gpio.h>
8 #include <linux/interrupt.h>
9 #include <linux/kernel.h>
10 #include <linux/mfd/rohm-bd70528.h>
11 #include <linux/module.h>
12 #include <linux/of.h>
13 #include <linux/platform_device.h>
14 #include <linux/regmap.h>
15 #include <linux/regulator/driver.h>
16 #include <linux/regulator/machine.h>
17 #include <linux/regulator/of_regulator.h>
18 #include <linux/slab.h>
19
20 #define BUCK_RAMPRATE_250MV 0
21 #define BUCK_RAMPRATE_125MV 1
22 #define BUCK_RAMP_MAX 250
23
24 static const struct regulator_linear_range bd70528_buck1_volts[] = {
25         REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 600000),
26         REGULATOR_LINEAR_RANGE(2750000, 0x2, 0xf, 50000),
27 };
28 static const struct regulator_linear_range bd70528_buck2_volts[] = {
29         REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 300000),
30         REGULATOR_LINEAR_RANGE(1550000, 0x2, 0xd, 50000),
31         REGULATOR_LINEAR_RANGE(3000000, 0xe, 0xf, 300000),
32 };
33 static const struct regulator_linear_range bd70528_buck3_volts[] = {
34         REGULATOR_LINEAR_RANGE(800000, 0x00, 0xd, 50000),
35         REGULATOR_LINEAR_RANGE(1800000, 0xe, 0xf, 0),
36 };
37
38 /* All LDOs have same voltage ranges */
39 static const struct regulator_linear_range bd70528_ldo_volts[] = {
40         REGULATOR_LINEAR_RANGE(1650000, 0x0, 0x07, 50000),
41         REGULATOR_LINEAR_RANGE(2100000, 0x8, 0x0f, 100000),
42         REGULATOR_LINEAR_RANGE(2850000, 0x10, 0x19, 50000),
43         REGULATOR_LINEAR_RANGE(3300000, 0x19, 0x1f, 0),
44 };
45
46 /* Also both LEDs support same voltages */
47 static const unsigned int led_volts[] = {
48         20000, 30000
49 };
50
51 static int bd70528_set_ramp_delay(struct regulator_dev *rdev, int ramp_delay)
52 {
53         if (ramp_delay > 0 && ramp_delay <= BUCK_RAMP_MAX) {
54                 unsigned int ramp_value = BUCK_RAMPRATE_250MV;
55
56                 if (ramp_delay <= 125)
57                         ramp_value = BUCK_RAMPRATE_125MV;
58
59                 return regmap_update_bits(rdev->regmap, rdev->desc->vsel_reg,
60                                   BD70528_MASK_BUCK_RAMP,
61                                   ramp_value << BD70528_SIFT_BUCK_RAMP);
62         }
63         dev_err(&rdev->dev, "%s: ramp_delay: %d not supported\n",
64                 rdev->desc->name, ramp_delay);
65         return -EINVAL;
66 }
67
68 static int bd70528_led_set_voltage_sel(struct regulator_dev *rdev,
69                                        unsigned int sel)
70 {
71         int ret;
72
73         ret = regulator_is_enabled_regmap(rdev);
74         if (ret < 0)
75                 return ret;
76
77         if (ret == 0)
78                 return regulator_set_voltage_sel_regmap(rdev, sel);
79
80         dev_err(&rdev->dev,
81                 "LED voltage change not allowed when led is enabled\n");
82
83         return -EBUSY;
84 }
85
86 static const struct regulator_ops bd70528_buck_ops = {
87         .enable = regulator_enable_regmap,
88         .disable = regulator_disable_regmap,
89         .is_enabled = regulator_is_enabled_regmap,
90         .list_voltage = regulator_list_voltage_linear_range,
91         .set_voltage_sel = regulator_set_voltage_sel_regmap,
92         .get_voltage_sel = regulator_get_voltage_sel_regmap,
93         .set_voltage_time_sel = regulator_set_voltage_time_sel,
94         .set_ramp_delay = bd70528_set_ramp_delay,
95 };
96
97 static const struct regulator_ops bd70528_ldo_ops = {
98         .enable = regulator_enable_regmap,
99         .disable = regulator_disable_regmap,
100         .is_enabled = regulator_is_enabled_regmap,
101         .list_voltage = regulator_list_voltage_linear_range,
102         .set_voltage_sel = regulator_set_voltage_sel_regmap,
103         .get_voltage_sel = regulator_get_voltage_sel_regmap,
104         .set_voltage_time_sel = regulator_set_voltage_time_sel,
105         .set_ramp_delay = bd70528_set_ramp_delay,
106 };
107
108 static const struct regulator_ops bd70528_led_ops = {
109         .enable = regulator_enable_regmap,
110         .disable = regulator_disable_regmap,
111         .is_enabled = regulator_is_enabled_regmap,
112         .list_voltage = regulator_list_voltage_table,
113         .set_voltage_sel = bd70528_led_set_voltage_sel,
114         .get_voltage_sel = regulator_get_voltage_sel_regmap,
115 };
116
117 static const struct regulator_desc bd70528_desc[] = {
118         {
119                 .name = "buck1",
120                 .of_match = of_match_ptr("BUCK1"),
121                 .regulators_node = of_match_ptr("regulators"),
122                 .id = BD70528_BUCK1,
123                 .ops = &bd70528_buck_ops,
124                 .type = REGULATOR_VOLTAGE,
125                 .linear_ranges = bd70528_buck1_volts,
126                 .n_linear_ranges = ARRAY_SIZE(bd70528_buck1_volts),
127                 .n_voltages = BD70528_BUCK_VOLTS,
128                 .enable_reg = BD70528_REG_BUCK1_EN,
129                 .enable_mask = BD70528_MASK_RUN_EN,
130                 .vsel_reg = BD70528_REG_BUCK1_VOLT,
131                 .vsel_mask = BD70528_MASK_BUCK_VOLT,
132                 .owner = THIS_MODULE,
133         },
134         {
135                 .name = "buck2",
136                 .of_match = of_match_ptr("BUCK2"),
137                 .regulators_node = of_match_ptr("regulators"),
138                 .id = BD70528_BUCK2,
139                 .ops = &bd70528_buck_ops,
140                 .type = REGULATOR_VOLTAGE,
141                 .linear_ranges = bd70528_buck2_volts,
142                 .n_linear_ranges = ARRAY_SIZE(bd70528_buck2_volts),
143                 .n_voltages = BD70528_BUCK_VOLTS,
144                 .enable_reg = BD70528_REG_BUCK2_EN,
145                 .enable_mask = BD70528_MASK_RUN_EN,
146                 .vsel_reg = BD70528_REG_BUCK2_VOLT,
147                 .vsel_mask = BD70528_MASK_BUCK_VOLT,
148                 .owner = THIS_MODULE,
149         },
150         {
151                 .name = "buck3",
152                 .of_match = of_match_ptr("BUCK3"),
153                 .regulators_node = of_match_ptr("regulators"),
154                 .id = BD70528_BUCK3,
155                 .ops = &bd70528_buck_ops,
156                 .type = REGULATOR_VOLTAGE,
157                 .linear_ranges = bd70528_buck3_volts,
158                 .n_linear_ranges = ARRAY_SIZE(bd70528_buck3_volts),
159                 .n_voltages = BD70528_BUCK_VOLTS,
160                 .enable_reg = BD70528_REG_BUCK3_EN,
161                 .enable_mask = BD70528_MASK_RUN_EN,
162                 .vsel_reg = BD70528_REG_BUCK3_VOLT,
163                 .vsel_mask = BD70528_MASK_BUCK_VOLT,
164                 .owner = THIS_MODULE,
165         },
166         {
167                 .name = "ldo1",
168                 .of_match = of_match_ptr("LDO1"),
169                 .regulators_node = of_match_ptr("regulators"),
170                 .id = BD70528_LDO1,
171                 .ops = &bd70528_ldo_ops,
172                 .type = REGULATOR_VOLTAGE,
173                 .linear_ranges = bd70528_ldo_volts,
174                 .n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts),
175                 .n_voltages = BD70528_LDO_VOLTS,
176                 .enable_reg = BD70528_REG_LDO1_EN,
177                 .enable_mask = BD70528_MASK_RUN_EN,
178                 .vsel_reg = BD70528_REG_LDO1_VOLT,
179                 .vsel_mask = BD70528_MASK_LDO_VOLT,
180                 .owner = THIS_MODULE,
181         },
182         {
183                 .name = "ldo2",
184                 .of_match = of_match_ptr("LDO2"),
185                 .regulators_node = of_match_ptr("regulators"),
186                 .id = BD70528_LDO2,
187                 .ops = &bd70528_ldo_ops,
188                 .type = REGULATOR_VOLTAGE,
189                 .linear_ranges = bd70528_ldo_volts,
190                 .n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts),
191                 .n_voltages = BD70528_LDO_VOLTS,
192                 .enable_reg = BD70528_REG_LDO2_EN,
193                 .enable_mask = BD70528_MASK_RUN_EN,
194                 .vsel_reg = BD70528_REG_LDO2_VOLT,
195                 .vsel_mask = BD70528_MASK_LDO_VOLT,
196                 .owner = THIS_MODULE,
197         },
198         {
199                 .name = "ldo3",
200                 .of_match = of_match_ptr("LDO3"),
201                 .regulators_node = of_match_ptr("regulators"),
202                 .id = BD70528_LDO3,
203                 .ops = &bd70528_ldo_ops,
204                 .type = REGULATOR_VOLTAGE,
205                 .linear_ranges = bd70528_ldo_volts,
206                 .n_linear_ranges = ARRAY_SIZE(bd70528_ldo_volts),
207                 .n_voltages = BD70528_LDO_VOLTS,
208                 .enable_reg = BD70528_REG_LDO3_EN,
209                 .enable_mask = BD70528_MASK_RUN_EN,
210                 .vsel_reg = BD70528_REG_LDO3_VOLT,
211                 .vsel_mask = BD70528_MASK_LDO_VOLT,
212                 .owner = THIS_MODULE,
213         },
214         {
215                 .name = "ldo_led1",
216                 .of_match = of_match_ptr("LDO_LED1"),
217                 .regulators_node = of_match_ptr("regulators"),
218                 .id = BD70528_LED1,
219                 .ops = &bd70528_led_ops,
220                 .type = REGULATOR_VOLTAGE,
221                 .volt_table = &led_volts[0],
222                 .n_voltages = ARRAY_SIZE(led_volts),
223                 .enable_reg = BD70528_REG_LED_EN,
224                 .enable_mask = BD70528_MASK_LED1_EN,
225                 .vsel_reg = BD70528_REG_LED_VOLT,
226                 .vsel_mask = BD70528_MASK_LED1_VOLT,
227                 .owner = THIS_MODULE,
228         },
229         {
230                 .name = "ldo_led2",
231                 .of_match = of_match_ptr("LDO_LED2"),
232                 .regulators_node = of_match_ptr("regulators"),
233                 .id = BD70528_LED2,
234                 .ops = &bd70528_led_ops,
235                 .type = REGULATOR_VOLTAGE,
236                 .volt_table = &led_volts[0],
237                 .n_voltages = ARRAY_SIZE(led_volts),
238                 .enable_reg = BD70528_REG_LED_EN,
239                 .enable_mask = BD70528_MASK_LED2_EN,
240                 .vsel_reg = BD70528_REG_LED_VOLT,
241                 .vsel_mask = BD70528_MASK_LED2_VOLT,
242                 .owner = THIS_MODULE,
243         },
244
245 };
246
247 static int bd70528_probe(struct platform_device *pdev)
248 {
249         struct rohm_regmap_dev *bd70528;
250         int i;
251         struct regulator_config config = {
252                 .dev = pdev->dev.parent,
253         };
254
255         bd70528 = dev_get_drvdata(pdev->dev.parent);
256         if (!bd70528) {
257                 dev_err(&pdev->dev, "No MFD driver data\n");
258                 return -EINVAL;
259         }
260
261         config.regmap = bd70528->regmap;
262
263         for (i = 0; i < ARRAY_SIZE(bd70528_desc); i++) {
264                 struct regulator_dev *rdev;
265
266                 rdev = devm_regulator_register(&pdev->dev, &bd70528_desc[i],
267                                                &config);
268                 if (IS_ERR(rdev)) {
269                         dev_err(&pdev->dev,
270                                 "failed to register %s regulator\n",
271                                 bd70528_desc[i].name);
272                         return PTR_ERR(rdev);
273                 }
274         }
275         return 0;
276 }
277
278 static struct platform_driver bd70528_regulator = {
279         .driver = {
280                 .name = "bd70528-pmic"
281         },
282         .probe = bd70528_probe,
283 };
284
285 module_platform_driver(bd70528_regulator);
286
287 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
288 MODULE_DESCRIPTION("BD70528 voltage regulator driver");
289 MODULE_LICENSE("GPL");