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
,
104 .set_ramp_delay
= bd70528_set_ramp_delay
,
107 static const struct regulator_ops bd70528_led_ops
= {
108 .enable
= regulator_enable_regmap
,
109 .disable
= regulator_disable_regmap
,
110 .is_enabled
= regulator_is_enabled_regmap
,
111 .list_voltage
= regulator_list_voltage_table
,
112 .set_voltage_sel
= bd70528_led_set_voltage_sel
,
113 .get_voltage_sel
= regulator_get_voltage_sel_regmap
,
116 static const struct regulator_desc bd70528_desc
[] = {
119 .of_match
= of_match_ptr("BUCK1"),
120 .regulators_node
= of_match_ptr("regulators"),
122 .ops
= &bd70528_buck_ops
,
123 .type
= REGULATOR_VOLTAGE
,
124 .linear_ranges
= bd70528_buck1_volts
,
125 .n_linear_ranges
= ARRAY_SIZE(bd70528_buck1_volts
),
126 .n_voltages
= BD70528_BUCK_VOLTS
,
127 .enable_reg
= BD70528_REG_BUCK1_EN
,
128 .enable_mask
= BD70528_MASK_RUN_EN
,
129 .vsel_reg
= BD70528_REG_BUCK1_VOLT
,
130 .vsel_mask
= BD70528_MASK_BUCK_VOLT
,
131 .owner
= THIS_MODULE
,
135 .of_match
= of_match_ptr("BUCK2"),
136 .regulators_node
= of_match_ptr("regulators"),
138 .ops
= &bd70528_buck_ops
,
139 .type
= REGULATOR_VOLTAGE
,
140 .linear_ranges
= bd70528_buck2_volts
,
141 .n_linear_ranges
= ARRAY_SIZE(bd70528_buck2_volts
),
142 .n_voltages
= BD70528_BUCK_VOLTS
,
143 .enable_reg
= BD70528_REG_BUCK2_EN
,
144 .enable_mask
= BD70528_MASK_RUN_EN
,
145 .vsel_reg
= BD70528_REG_BUCK2_VOLT
,
146 .vsel_mask
= BD70528_MASK_BUCK_VOLT
,
147 .owner
= THIS_MODULE
,
151 .of_match
= of_match_ptr("BUCK3"),
152 .regulators_node
= of_match_ptr("regulators"),
154 .ops
= &bd70528_buck_ops
,
155 .type
= REGULATOR_VOLTAGE
,
156 .linear_ranges
= bd70528_buck3_volts
,
157 .n_linear_ranges
= ARRAY_SIZE(bd70528_buck3_volts
),
158 .n_voltages
= BD70528_BUCK_VOLTS
,
159 .enable_reg
= BD70528_REG_BUCK3_EN
,
160 .enable_mask
= BD70528_MASK_RUN_EN
,
161 .vsel_reg
= BD70528_REG_BUCK3_VOLT
,
162 .vsel_mask
= BD70528_MASK_BUCK_VOLT
,
163 .owner
= THIS_MODULE
,
167 .of_match
= of_match_ptr("LDO1"),
168 .regulators_node
= of_match_ptr("regulators"),
170 .ops
= &bd70528_ldo_ops
,
171 .type
= REGULATOR_VOLTAGE
,
172 .linear_ranges
= bd70528_ldo_volts
,
173 .n_linear_ranges
= ARRAY_SIZE(bd70528_ldo_volts
),
174 .n_voltages
= BD70528_LDO_VOLTS
,
175 .enable_reg
= BD70528_REG_LDO1_EN
,
176 .enable_mask
= BD70528_MASK_RUN_EN
,
177 .vsel_reg
= BD70528_REG_LDO1_VOLT
,
178 .vsel_mask
= BD70528_MASK_LDO_VOLT
,
179 .owner
= THIS_MODULE
,
183 .of_match
= of_match_ptr("LDO2"),
184 .regulators_node
= of_match_ptr("regulators"),
186 .ops
= &bd70528_ldo_ops
,
187 .type
= REGULATOR_VOLTAGE
,
188 .linear_ranges
= bd70528_ldo_volts
,
189 .n_linear_ranges
= ARRAY_SIZE(bd70528_ldo_volts
),
190 .n_voltages
= BD70528_LDO_VOLTS
,
191 .enable_reg
= BD70528_REG_LDO2_EN
,
192 .enable_mask
= BD70528_MASK_RUN_EN
,
193 .vsel_reg
= BD70528_REG_LDO2_VOLT
,
194 .vsel_mask
= BD70528_MASK_LDO_VOLT
,
195 .owner
= THIS_MODULE
,
199 .of_match
= of_match_ptr("LDO3"),
200 .regulators_node
= of_match_ptr("regulators"),
202 .ops
= &bd70528_ldo_ops
,
203 .type
= REGULATOR_VOLTAGE
,
204 .linear_ranges
= bd70528_ldo_volts
,
205 .n_linear_ranges
= ARRAY_SIZE(bd70528_ldo_volts
),
206 .n_voltages
= BD70528_LDO_VOLTS
,
207 .enable_reg
= BD70528_REG_LDO3_EN
,
208 .enable_mask
= BD70528_MASK_RUN_EN
,
209 .vsel_reg
= BD70528_REG_LDO3_VOLT
,
210 .vsel_mask
= BD70528_MASK_LDO_VOLT
,
211 .owner
= THIS_MODULE
,
215 .of_match
= of_match_ptr("LDO_LED1"),
216 .regulators_node
= of_match_ptr("regulators"),
218 .ops
= &bd70528_led_ops
,
219 .type
= REGULATOR_VOLTAGE
,
220 .volt_table
= &led_volts
[0],
221 .n_voltages
= ARRAY_SIZE(led_volts
),
222 .enable_reg
= BD70528_REG_LED_EN
,
223 .enable_mask
= BD70528_MASK_LED1_EN
,
224 .vsel_reg
= BD70528_REG_LED_VOLT
,
225 .vsel_mask
= BD70528_MASK_LED1_VOLT
,
226 .owner
= THIS_MODULE
,
230 .of_match
= of_match_ptr("LDO_LED2"),
231 .regulators_node
= of_match_ptr("regulators"),
233 .ops
= &bd70528_led_ops
,
234 .type
= REGULATOR_VOLTAGE
,
235 .volt_table
= &led_volts
[0],
236 .n_voltages
= ARRAY_SIZE(led_volts
),
237 .enable_reg
= BD70528_REG_LED_EN
,
238 .enable_mask
= BD70528_MASK_LED2_EN
,
239 .vsel_reg
= BD70528_REG_LED_VOLT
,
240 .vsel_mask
= BD70528_MASK_LED2_VOLT
,
241 .owner
= THIS_MODULE
,
246 static int bd70528_probe(struct platform_device
*pdev
)
248 struct rohm_regmap_dev
*bd70528
;
250 struct regulator_config config
= {
251 .dev
= pdev
->dev
.parent
,
254 bd70528
= dev_get_drvdata(pdev
->dev
.parent
);
256 dev_err(&pdev
->dev
, "No MFD driver data\n");
260 config
.regmap
= bd70528
->regmap
;
262 for (i
= 0; i
< ARRAY_SIZE(bd70528_desc
); i
++) {
263 struct regulator_dev
*rdev
;
265 rdev
= devm_regulator_register(&pdev
->dev
, &bd70528_desc
[i
],
269 "failed to register %s regulator\n",
270 bd70528_desc
[i
].name
);
271 return PTR_ERR(rdev
);
277 static struct platform_driver bd70528_regulator
= {
279 .name
= "bd70528-pmic"
281 .probe
= bd70528_probe
,
284 module_platform_driver(bd70528_regulator
);
286 MODULE_AUTHOR("Matti Vaittinen <matti.vaittinen@fi.rohmeurope.com>");
287 MODULE_DESCRIPTION("BD70528 voltage regulator driver");
288 MODULE_LICENSE("GPL");