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/interrupt.h>
8 #include <linux/kernel.h>
9 #include <linux/mfd/rohm-bd70528.h>
10 #include <linux/module.h>
12 #include <linux/platform_device.h>
13 #include <linux/regmap.h>
14 #include <linux/regulator/driver.h>
15 #include <linux/regulator/machine.h>
16 #include <linux/regulator/of_regulator.h>
17 #include <linux/slab.h>
19 #define BUCK_RAMPRATE_250MV 0
20 #define BUCK_RAMPRATE_125MV 1
21 #define BUCK_RAMP_MAX 250
23 static const struct regulator_linear_range bd70528_buck1_volts
[] = {
24 REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 600000),
25 REGULATOR_LINEAR_RANGE(2750000, 0x2, 0xf, 50000),
27 static const struct regulator_linear_range bd70528_buck2_volts
[] = {
28 REGULATOR_LINEAR_RANGE(1200000, 0x00, 0x1, 300000),
29 REGULATOR_LINEAR_RANGE(1550000, 0x2, 0xd, 50000),
30 REGULATOR_LINEAR_RANGE(3000000, 0xe, 0xf, 300000),
32 static const struct regulator_linear_range bd70528_buck3_volts
[] = {
33 REGULATOR_LINEAR_RANGE(800000, 0x00, 0xd, 50000),
34 REGULATOR_LINEAR_RANGE(1800000, 0xe, 0xf, 0),
37 /* All LDOs have same voltage ranges */
38 static const struct regulator_linear_range bd70528_ldo_volts
[] = {
39 REGULATOR_LINEAR_RANGE(1650000, 0x0, 0x07, 50000),
40 REGULATOR_LINEAR_RANGE(2100000, 0x8, 0x0f, 100000),
41 REGULATOR_LINEAR_RANGE(2850000, 0x10, 0x19, 50000),
42 REGULATOR_LINEAR_RANGE(3300000, 0x19, 0x1f, 0),
45 /* Also both LEDs support same voltages */
46 static const unsigned int led_volts
[] = {
50 static int bd70528_set_ramp_delay(struct regulator_dev
*rdev
, int ramp_delay
)
52 if (ramp_delay
> 0 && ramp_delay
<= BUCK_RAMP_MAX
) {
53 unsigned int ramp_value
= BUCK_RAMPRATE_250MV
;
55 if (ramp_delay
<= 125)
56 ramp_value
= BUCK_RAMPRATE_125MV
;
58 return regmap_update_bits(rdev
->regmap
, rdev
->desc
->vsel_reg
,
59 BD70528_MASK_BUCK_RAMP
,
60 ramp_value
<< BD70528_SIFT_BUCK_RAMP
);
62 dev_err(&rdev
->dev
, "%s: ramp_delay: %d not supported\n",
63 rdev
->desc
->name
, ramp_delay
);
67 static int bd70528_led_set_voltage_sel(struct regulator_dev
*rdev
,
72 ret
= regulator_is_enabled_regmap(rdev
);
77 return regulator_set_voltage_sel_regmap(rdev
, sel
);
80 "LED voltage change not allowed when led is enabled\n");
85 static const struct regulator_ops bd70528_buck_ops
= {
86 .enable
= regulator_enable_regmap
,
87 .disable
= regulator_disable_regmap
,
88 .is_enabled
= regulator_is_enabled_regmap
,
89 .list_voltage
= regulator_list_voltage_linear_range
,
90 .set_voltage_sel
= regulator_set_voltage_sel_regmap
,
91 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
92 .set_voltage_time_sel
= regulator_set_voltage_time_sel
,
93 .set_ramp_delay
= bd70528_set_ramp_delay
,
96 static const struct regulator_ops bd70528_ldo_ops
= {
97 .enable
= regulator_enable_regmap
,
98 .disable
= regulator_disable_regmap
,
99 .is_enabled
= regulator_is_enabled_regmap
,
100 .list_voltage
= regulator_list_voltage_linear_range
,
101 .set_voltage_sel
= regulator_set_voltage_sel_regmap
,
102 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
103 .set_voltage_time_sel
= regulator_set_voltage_time_sel
,
106 static const struct regulator_ops bd70528_led_ops
= {
107 .enable
= regulator_enable_regmap
,
108 .disable
= regulator_disable_regmap
,
109 .is_enabled
= regulator_is_enabled_regmap
,
110 .list_voltage
= regulator_list_voltage_table
,
111 .set_voltage_sel
= bd70528_led_set_voltage_sel
,
112 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
115 static const struct regulator_desc bd70528_desc
[] = {
118 .of_match
= of_match_ptr("BUCK1"),
119 .regulators_node
= of_match_ptr("regulators"),
121 .ops
= &bd70528_buck_ops
,
122 .type
= REGULATOR_VOLTAGE
,
123 .linear_ranges
= bd70528_buck1_volts
,
124 .n_linear_ranges
= ARRAY_SIZE(bd70528_buck1_volts
),
125 .n_voltages
= BD70528_BUCK_VOLTS
,
126 .enable_reg
= BD70528_REG_BUCK1_EN
,
127 .enable_mask
= BD70528_MASK_RUN_EN
,
128 .vsel_reg
= BD70528_REG_BUCK1_VOLT
,
129 .vsel_mask
= BD70528_MASK_BUCK_VOLT
,
130 .owner
= THIS_MODULE
,
134 .of_match
= of_match_ptr("BUCK2"),
135 .regulators_node
= of_match_ptr("regulators"),
137 .ops
= &bd70528_buck_ops
,
138 .type
= REGULATOR_VOLTAGE
,
139 .linear_ranges
= bd70528_buck2_volts
,
140 .n_linear_ranges
= ARRAY_SIZE(bd70528_buck2_volts
),
141 .n_voltages
= BD70528_BUCK_VOLTS
,
142 .enable_reg
= BD70528_REG_BUCK2_EN
,
143 .enable_mask
= BD70528_MASK_RUN_EN
,
144 .vsel_reg
= BD70528_REG_BUCK2_VOLT
,
145 .vsel_mask
= BD70528_MASK_BUCK_VOLT
,
146 .owner
= THIS_MODULE
,
150 .of_match
= of_match_ptr("BUCK3"),
151 .regulators_node
= of_match_ptr("regulators"),
153 .ops
= &bd70528_buck_ops
,
154 .type
= REGULATOR_VOLTAGE
,
155 .linear_ranges
= bd70528_buck3_volts
,
156 .n_linear_ranges
= ARRAY_SIZE(bd70528_buck3_volts
),
157 .n_voltages
= BD70528_BUCK_VOLTS
,
158 .enable_reg
= BD70528_REG_BUCK3_EN
,
159 .enable_mask
= BD70528_MASK_RUN_EN
,
160 .vsel_reg
= BD70528_REG_BUCK3_VOLT
,
161 .vsel_mask
= BD70528_MASK_BUCK_VOLT
,
162 .owner
= THIS_MODULE
,
166 .of_match
= of_match_ptr("LDO1"),
167 .regulators_node
= of_match_ptr("regulators"),
169 .ops
= &bd70528_ldo_ops
,
170 .type
= REGULATOR_VOLTAGE
,
171 .linear_ranges
= bd70528_ldo_volts
,
172 .n_linear_ranges
= ARRAY_SIZE(bd70528_ldo_volts
),
173 .n_voltages
= BD70528_LDO_VOLTS
,
174 .enable_reg
= BD70528_REG_LDO1_EN
,
175 .enable_mask
= BD70528_MASK_RUN_EN
,
176 .vsel_reg
= BD70528_REG_LDO1_VOLT
,
177 .vsel_mask
= BD70528_MASK_LDO_VOLT
,
178 .owner
= THIS_MODULE
,
182 .of_match
= of_match_ptr("LDO2"),
183 .regulators_node
= of_match_ptr("regulators"),
185 .ops
= &bd70528_ldo_ops
,
186 .type
= REGULATOR_VOLTAGE
,
187 .linear_ranges
= bd70528_ldo_volts
,
188 .n_linear_ranges
= ARRAY_SIZE(bd70528_ldo_volts
),
189 .n_voltages
= BD70528_LDO_VOLTS
,
190 .enable_reg
= BD70528_REG_LDO2_EN
,
191 .enable_mask
= BD70528_MASK_RUN_EN
,
192 .vsel_reg
= BD70528_REG_LDO2_VOLT
,
193 .vsel_mask
= BD70528_MASK_LDO_VOLT
,
194 .owner
= THIS_MODULE
,
198 .of_match
= of_match_ptr("LDO3"),
199 .regulators_node
= of_match_ptr("regulators"),
201 .ops
= &bd70528_ldo_ops
,
202 .type
= REGULATOR_VOLTAGE
,
203 .linear_ranges
= bd70528_ldo_volts
,
204 .n_linear_ranges
= ARRAY_SIZE(bd70528_ldo_volts
),
205 .n_voltages
= BD70528_LDO_VOLTS
,
206 .enable_reg
= BD70528_REG_LDO3_EN
,
207 .enable_mask
= BD70528_MASK_RUN_EN
,
208 .vsel_reg
= BD70528_REG_LDO3_VOLT
,
209 .vsel_mask
= BD70528_MASK_LDO_VOLT
,
210 .owner
= THIS_MODULE
,
214 .of_match
= of_match_ptr("LDO_LED1"),
215 .regulators_node
= of_match_ptr("regulators"),
217 .ops
= &bd70528_led_ops
,
218 .type
= REGULATOR_VOLTAGE
,
219 .volt_table
= &led_volts
[0],
220 .n_voltages
= ARRAY_SIZE(led_volts
),
221 .enable_reg
= BD70528_REG_LED_EN
,
222 .enable_mask
= BD70528_MASK_LED1_EN
,
223 .vsel_reg
= BD70528_REG_LED_VOLT
,
224 .vsel_mask
= BD70528_MASK_LED1_VOLT
,
225 .owner
= THIS_MODULE
,
229 .of_match
= of_match_ptr("LDO_LED2"),
230 .regulators_node
= of_match_ptr("regulators"),
232 .ops
= &bd70528_led_ops
,
233 .type
= REGULATOR_VOLTAGE
,
234 .volt_table
= &led_volts
[0],
235 .n_voltages
= ARRAY_SIZE(led_volts
),
236 .enable_reg
= BD70528_REG_LED_EN
,
237 .enable_mask
= BD70528_MASK_LED2_EN
,
238 .vsel_reg
= BD70528_REG_LED_VOLT
,
239 .vsel_mask
= BD70528_MASK_LED2_VOLT
,
240 .owner
= THIS_MODULE
,
245 static int bd70528_probe(struct platform_device
*pdev
)
247 struct rohm_regmap_dev
*bd70528
;
249 struct regulator_config config
= {
250 .dev
= pdev
->dev
.parent
,
253 bd70528
= dev_get_drvdata(pdev
->dev
.parent
);
255 dev_err(&pdev
->dev
, "No MFD driver data\n");
259 config
.regmap
= bd70528
->regmap
;
261 for (i
= 0; i
< ARRAY_SIZE(bd70528_desc
); i
++) {
262 struct regulator_dev
*rdev
;
264 rdev
= devm_regulator_register(&pdev
->dev
, &bd70528_desc
[i
],
268 "failed to register %s regulator\n",
269 bd70528_desc
[i
].name
);
270 return PTR_ERR(rdev
);
276 static struct platform_driver bd70528_regulator
= {
278 .name
= "bd70528-pmic"
280 .probe
= bd70528_probe
,
283 module_platform_driver(bd70528_regulator
);
285 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
286 MODULE_DESCRIPTION("BD70528 voltage regulator driver");
287 MODULE_LICENSE("GPL");
288 MODULE_ALIAS("platform:bd70528-pmic");