1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (C) 2018 ROHM Semiconductors
3 // bd70528-regulator.c ROHM BD70528MWV regulator driver
5 #include <linux/delay.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>
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>
20 #define BUCK_RAMPRATE_250MV 0
21 #define BUCK_RAMPRATE_125MV 1
22 #define BUCK_RAMP_MAX 250
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),
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),
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),
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),
46 /* Also both LEDs support same voltages */
47 static const unsigned int led_volts
[] = {
51 static int bd70528_set_ramp_delay(struct regulator_dev
*rdev
, int ramp_delay
)
53 if (ramp_delay
> 0 && ramp_delay
<= BUCK_RAMP_MAX
) {
54 unsigned int ramp_value
= BUCK_RAMPRATE_250MV
;
56 if (ramp_delay
<= 125)
57 ramp_value
= BUCK_RAMPRATE_125MV
;
59 return regmap_update_bits(rdev
->regmap
, rdev
->desc
->vsel_reg
,
60 BD70528_MASK_BUCK_RAMP
,
61 ramp_value
<< BD70528_SIFT_BUCK_RAMP
);
63 dev_err(&rdev
->dev
, "%s: ramp_delay: %d not supported\n",
64 rdev
->desc
->name
, ramp_delay
);
68 static int bd70528_led_set_voltage_sel(struct regulator_dev
*rdev
,
73 ret
= regulator_is_enabled_regmap(rdev
);
78 return regulator_set_voltage_sel_regmap(rdev
, sel
);
81 "LED voltage change not allowed when led is enabled\n");
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
,
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
,
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
,
117 static const struct regulator_desc bd70528_desc
[] = {
120 .of_match
= of_match_ptr("BUCK1"),
121 .regulators_node
= of_match_ptr("regulators"),
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
,
136 .of_match
= of_match_ptr("BUCK2"),
137 .regulators_node
= of_match_ptr("regulators"),
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
,
152 .of_match
= of_match_ptr("BUCK3"),
153 .regulators_node
= of_match_ptr("regulators"),
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
,
168 .of_match
= of_match_ptr("LDO1"),
169 .regulators_node
= of_match_ptr("regulators"),
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
,
184 .of_match
= of_match_ptr("LDO2"),
185 .regulators_node
= of_match_ptr("regulators"),
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
,
200 .of_match
= of_match_ptr("LDO3"),
201 .regulators_node
= of_match_ptr("regulators"),
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
,
216 .of_match
= of_match_ptr("LDO_LED1"),
217 .regulators_node
= of_match_ptr("regulators"),
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
,
231 .of_match
= of_match_ptr("LDO_LED2"),
232 .regulators_node
= of_match_ptr("regulators"),
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
,
247 static int bd70528_probe(struct platform_device
*pdev
)
249 struct rohm_regmap_dev
*bd70528
;
251 struct regulator_config config
= {
252 .dev
= pdev
->dev
.parent
,
255 bd70528
= dev_get_drvdata(pdev
->dev
.parent
);
257 dev_err(&pdev
->dev
, "No MFD driver data\n");
261 config
.regmap
= bd70528
->regmap
;
263 for (i
= 0; i
< ARRAY_SIZE(bd70528_desc
); i
++) {
264 struct regulator_dev
*rdev
;
266 rdev
= devm_regulator_register(&pdev
->dev
, &bd70528_desc
[i
],
270 "failed to register %s regulator\n",
271 bd70528_desc
[i
].name
);
272 return PTR_ERR(rdev
);
278 static struct platform_driver bd70528_regulator
= {
280 .name
= "bd70528-pmic"
282 .probe
= bd70528_probe
,
285 module_platform_driver(bd70528_regulator
);
287 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
288 MODULE_DESCRIPTION("BD70528 voltage regulator driver");
289 MODULE_LICENSE("GPL");