Skip to content

Commit 3a5e6e4

Browse files
systec-awebroonie
authored andcommitted
regulator: tps65086: Select dedicated regulator config for chip variant
Some configurations differ between chip variants, e,g. the register to control the on of state of LDOA1 and SWB2. Thus, it is necessary to choose the correct configuration for a dedicated device. If the wrong configuration was used, the LDOA1 output that was disabled by the bootloader was enabled in Kernel again. Each chip variant gets its dedicated configuration selected by the chip ID previously collected from MFD probe function. The VTT enum value (tps65086_regulators) is shifted because not all chip variants have a separate SWB2 switch. Sometimes they are merged. So the configuration possibilities differ, thus the regulator configuration arrays have a different length. Signed-off-by: Andre Werner <andre.werner@systec-electronic.com> Link: https://lore.kernel.org/r/20230818083721.29790-5-andre.werner@systec-electronic.com Signed-off-by: Mark Brown <broonie@kernel.org>
1 parent 1c6350f commit 3a5e6e4

File tree

2 files changed

+183
-8
lines changed

2 files changed

+183
-8
lines changed

drivers/regulator/tps65086-regulator.c

Lines changed: 180 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,15 @@
1515
#include <linux/mfd/tps65086.h>
1616

1717
enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1,
18-
LDOA2, LDOA3, SWA1, SWB1, SWB2, VTT };
18+
LDOA2, LDOA3, VTT, SWA1, SWB1, SWB2 };
19+
20+
/* Selector for regulator configuration regarding PMIC chip ID. */
21+
enum tps65086_ids {
22+
TPS6508640 = 0,
23+
TPS65086401,
24+
TPS6508641,
25+
TPS65086470,
26+
};
1927

2028
#define TPS65086_REGULATOR(_name, _of, _id, _nv, _vr, _vm, _er, _em, _lr, _dr, _dm) \
2129
[_id] = { \
@@ -57,12 +65,24 @@ enum tps65086_regulators { BUCK1, BUCK2, BUCK3, BUCK4, BUCK5, BUCK6, LDOA1,
5765
}, \
5866
}
5967

68+
69+
#define TPS65086_REGULATOR_CONFIG(_chip_id, _config) \
70+
[_chip_id] = { \
71+
.config = _config, \
72+
.num_elems = ARRAY_SIZE(_config), \
73+
}
74+
6075
struct tps65086_regulator {
6176
struct regulator_desc desc;
6277
unsigned int decay_reg;
6378
unsigned int decay_mask;
6479
};
6580

81+
struct tps65086_regulator_config {
82+
struct tps65086_regulator * const config;
83+
const unsigned int num_elems;
84+
};
85+
6686
static const struct linear_range tps65086_10mv_ranges[] = {
6787
REGULATOR_LINEAR_RANGE(0, 0x0, 0x0, 0),
6888
REGULATOR_LINEAR_RANGE(410000, 0x1, 0x7F, 10000),
@@ -114,7 +134,125 @@ static int tps65086_of_parse_cb(struct device_node *dev,
114134
const struct regulator_desc *desc,
115135
struct regulator_config *config);
116136

117-
static struct tps65086_regulator regulators[] = {
137+
static struct tps65086_regulator tps6508640_regulator_config[] = {
138+
TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
139+
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
140+
tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
141+
BIT(0)),
142+
TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL,
143+
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1),
144+
tps65086_10mv_ranges, TPS65086_BUCK2CTRL,
145+
BIT(0)),
146+
TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID,
147+
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2),
148+
tps65086_10mv_ranges, TPS65086_BUCK3DECAY,
149+
BIT(0)),
150+
TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID,
151+
BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0),
152+
tps65086_10mv_ranges, TPS65086_BUCK4VID,
153+
BIT(0)),
154+
TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID,
155+
BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0),
156+
tps65086_10mv_ranges, TPS65086_BUCK5CTRL,
157+
BIT(0)),
158+
TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID,
159+
BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0),
160+
tps65086_10mv_ranges, TPS65086_BUCK6CTRL,
161+
BIT(0)),
162+
TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL,
163+
VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7),
164+
tps65086_ldoa1_ranges, 0, 0),
165+
TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID,
166+
VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0),
167+
tps65086_ldoa23_ranges, 0, 0),
168+
TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
169+
VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
170+
tps65086_ldoa23_ranges, 0, 0),
171+
TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
172+
TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
173+
TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
174+
TPS65086_SWITCH("SWB2", "swb2", SWB2, TPS65086_LDOA1CTRL, BIT(0)),
175+
};
176+
177+
static struct tps65086_regulator tps65086401_regulator_config[] = {
178+
TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
179+
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
180+
tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
181+
BIT(0)),
182+
TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL,
183+
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1),
184+
tps65086_10mv_ranges, TPS65086_BUCK2CTRL,
185+
BIT(0)),
186+
TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID,
187+
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2),
188+
tps65086_10mv_ranges, TPS65086_BUCK3DECAY,
189+
BIT(0)),
190+
TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID,
191+
BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0),
192+
tps65086_10mv_ranges, TPS65086_BUCK4VID,
193+
BIT(0)),
194+
TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID,
195+
BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0),
196+
tps65086_10mv_ranges, TPS65086_BUCK5CTRL,
197+
BIT(0)),
198+
TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID,
199+
BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0),
200+
tps65086_10mv_ranges, TPS65086_BUCK6CTRL,
201+
BIT(0)),
202+
TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL,
203+
VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7),
204+
tps65086_ldoa1_ranges, 0, 0),
205+
TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID,
206+
VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0),
207+
tps65086_ldoa23_ranges, 0, 0),
208+
TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
209+
VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
210+
tps65086_ldoa23_ranges, 0, 0),
211+
TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
212+
TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
213+
TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
214+
};
215+
216+
static struct tps65086_regulator tps6508641_regulator_config[] = {
217+
TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
218+
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
219+
tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
220+
BIT(0)),
221+
TPS65086_REGULATOR("BUCK2", "buck2", BUCK2, 0x80, TPS65086_BUCK2CTRL,
222+
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(1),
223+
tps65086_10mv_ranges, TPS65086_BUCK2CTRL,
224+
BIT(0)),
225+
TPS65086_REGULATOR("BUCK3", "buck3", BUCK3, 0x80, TPS65086_BUCK3VID,
226+
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(2),
227+
tps65086_10mv_ranges, TPS65086_BUCK3DECAY,
228+
BIT(0)),
229+
TPS65086_REGULATOR("BUCK4", "buck4", BUCK4, 0x80, TPS65086_BUCK4VID,
230+
BUCK_VID_MASK, TPS65086_BUCK4CTRL, BIT(0),
231+
tps65086_10mv_ranges, TPS65086_BUCK4VID,
232+
BIT(0)),
233+
TPS65086_REGULATOR("BUCK5", "buck5", BUCK5, 0x80, TPS65086_BUCK5VID,
234+
BUCK_VID_MASK, TPS65086_BUCK5CTRL, BIT(0),
235+
tps65086_10mv_ranges, TPS65086_BUCK5CTRL,
236+
BIT(0)),
237+
TPS65086_REGULATOR("BUCK6", "buck6", BUCK6, 0x80, TPS65086_BUCK6VID,
238+
BUCK_VID_MASK, TPS65086_BUCK6CTRL, BIT(0),
239+
tps65086_10mv_ranges, TPS65086_BUCK6CTRL,
240+
BIT(0)),
241+
TPS65086_REGULATOR("LDOA1", "ldoa1", LDOA1, 0xF, TPS65086_LDOA1CTRL,
242+
VDOA1_VID_MASK, TPS65086_SWVTT_EN, BIT(7),
243+
tps65086_ldoa1_ranges, 0, 0),
244+
TPS65086_REGULATOR("LDOA2", "ldoa2", LDOA2, 0x10, TPS65086_LDOA2VID,
245+
VDOA23_VID_MASK, TPS65086_LDOA2CTRL, BIT(0),
246+
tps65086_ldoa23_ranges, 0, 0),
247+
TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
248+
VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
249+
tps65086_ldoa23_ranges, 0, 0),
250+
TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
251+
TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
252+
TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
253+
};
254+
255+
static struct tps65086_regulator tps65086470_regulator_config[] = {
118256
TPS65086_REGULATOR("BUCK1", "buck1", BUCK1, 0x80, TPS65086_BUCK1CTRL,
119257
BUCK_VID_MASK, TPS65086_BUCK123CTRL, BIT(0),
120258
tps65086_10mv_ranges, TPS65086_BUCK1CTRL,
@@ -148,16 +286,25 @@ static struct tps65086_regulator regulators[] = {
148286
TPS65086_REGULATOR("LDOA3", "ldoa3", LDOA3, 0x10, TPS65086_LDOA3VID,
149287
VDOA23_VID_MASK, TPS65086_LDOA3CTRL, BIT(0),
150288
tps65086_ldoa23_ranges, 0, 0),
289+
TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
151290
TPS65086_SWITCH("SWA1", "swa1", SWA1, TPS65086_SWVTT_EN, BIT(5)),
152291
TPS65086_SWITCH("SWB1", "swb1", SWB1, TPS65086_SWVTT_EN, BIT(6)),
153292
TPS65086_SWITCH("SWB2", "swb2", SWB2, TPS65086_SWVTT_EN, BIT(7)),
154-
TPS65086_SWITCH("VTT", "vtt", VTT, TPS65086_SWVTT_EN, BIT(4)),
293+
};
294+
295+
static const struct tps65086_regulator_config regulator_configs[] = {
296+
TPS65086_REGULATOR_CONFIG(TPS6508640, tps6508640_regulator_config),
297+
TPS65086_REGULATOR_CONFIG(TPS65086401, tps65086401_regulator_config),
298+
TPS65086_REGULATOR_CONFIG(TPS6508641, tps6508641_regulator_config),
299+
TPS65086_REGULATOR_CONFIG(TPS65086470, tps65086470_regulator_config)
155300
};
156301

157302
static int tps65086_of_parse_cb(struct device_node *node,
158303
const struct regulator_desc *desc,
159304
struct regulator_config *config)
160305
{
306+
struct tps65086 * const tps = dev_get_drvdata(config->dev);
307+
struct tps65086_regulator *regulators = tps->reg_config->config;
161308
int ret;
162309

163310
/* Check for 25mV step mode */
@@ -203,22 +350,47 @@ static int tps65086_regulator_probe(struct platform_device *pdev)
203350
{
204351
struct tps65086 *tps = dev_get_drvdata(pdev->dev.parent);
205352
struct regulator_config config = { };
353+
unsigned int selector_reg_config;
206354
struct regulator_dev *rdev;
207355
int i;
208356

357+
/* Select regulator configuration for used PMIC device */
358+
switch (tps->chip_id) {
359+
case TPS6508640_ID:
360+
selector_reg_config = TPS6508640;
361+
break;
362+
case TPS65086401_ID:
363+
selector_reg_config = TPS65086401;
364+
break;
365+
case TPS6508641_ID:
366+
selector_reg_config = TPS6508641;
367+
break;
368+
case TPS65086470_ID:
369+
selector_reg_config = TPS65086470;
370+
break;
371+
default:
372+
dev_err(tps->dev, "Unknown device ID. Cannot determine regulator config.\n");
373+
return -ENODEV;
374+
}
375+
tps->reg_config = &regulator_configs[selector_reg_config];
376+
209377
platform_set_drvdata(pdev, tps);
210378

211379
config.dev = &pdev->dev;
212380
config.dev->of_node = tps->dev->of_node;
213381
config.driver_data = tps;
214382
config.regmap = tps->regmap;
215383

216-
for (i = 0; i < ARRAY_SIZE(regulators); i++) {
217-
rdev = devm_regulator_register(&pdev->dev, &regulators[i].desc,
218-
&config);
384+
for (i = 0; i < tps->reg_config->num_elems; ++i) {
385+
struct regulator_desc * const desc_ptr = &tps->reg_config->config[i].desc;
386+
387+
dev_dbg(tps->dev, "Index: %u; Regulator name: \"%s\"; Regulator ID: %d\n",
388+
i, desc_ptr->name, desc_ptr->id);
389+
390+
rdev = devm_regulator_register(&pdev->dev, desc_ptr, &config);
219391
if (IS_ERR(rdev)) {
220-
dev_err(tps->dev, "failed to register %s regulator\n",
221-
pdev->name);
392+
dev_err(tps->dev, "failed to register %d \"%s\" regulator\n",
393+
i, desc_ptr->name);
222394
return PTR_ERR(rdev);
223395
}
224396
}

include/linux/mfd/tps65086.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ enum tps65086_irqs {
9999
TPS65086_IRQ_FAULT,
100100
};
101101

102+
struct tps65086_regulator_config;
103+
102104
/**
103105
* struct tps65086 - state holder for the tps65086 driver
104106
*
@@ -108,6 +110,7 @@ struct tps65086 {
108110
struct device *dev;
109111
struct regmap *regmap;
110112
unsigned int chip_id;
113+
const struct tps65086_regulator_config *reg_config;
111114

112115
/* IRQ Data */
113116
int irq;

0 commit comments

Comments
 (0)