Skip to content

Commit adcee07

Browse files
committed
- power: regulator: Add support for NPCM8xx
2 parents e1befc8 + dbedf4a commit adcee07

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed

drivers/power/regulator/Kconfig

+8
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,14 @@ config DM_REGULATOR_MAX77686
128128
features for REGULATOR MAX77686. The driver implements get/set api for:
129129
value, enable and mode.
130130

131+
config DM_REGULATOR_NPCM8XX
132+
bool "Enable Driver Model for NPCM8xx voltage supply"
133+
depends on DM_REGULATOR && ARCH_NPCM8XX
134+
help
135+
Enable support for configuring voltage supply on NPCM8XX SoC. The
136+
voltage supplies support two voltage levels and the driver implements
137+
get/set api for setting the value.
138+
131139
config DM_REGULATOR_FAN53555
132140
bool "Enable Driver Model for REGULATOR FAN53555"
133141
depends on DM_PMIC_FAN53555

drivers/power/regulator/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ obj-$(CONFIG_REGULATOR_ACT8846) += act8846.o
99
obj-$(CONFIG_REGULATOR_AS3722) += as3722_regulator.o
1010
obj-$(CONFIG_$(SPL_)DM_REGULATOR_DA9063) += da9063.o
1111
obj-$(CONFIG_DM_REGULATOR_MAX77686) += max77686.o
12+
obj-$(CONFIG_DM_REGULATOR_NPCM8XX) += npcm8xx_regulator.o
1213
obj-$(CONFIG_$(SPL_)DM_PMIC_PFUZE100) += pfuze100.o
1314
obj-$(CONFIG_$(SPL_)DM_REGULATOR_BD71837) += bd71837.o
1415
obj-$(CONFIG_$(SPL_)DM_REGULATOR_PCA9450) += pca9450.o
+132
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
/*
3+
* Copyright (c) 2022 Nuvoton Technology Corp.
4+
*/
5+
6+
#include <common.h>
7+
#include <dm.h>
8+
#include <asm/io.h>
9+
#include <dm/device_compat.h>
10+
#include <power/regulator.h>
11+
12+
#define REG_VSRCR 0xf08000e8 /* Voltage Supply Control Register */
13+
14+
/* Supported voltage levels (uV) */
15+
static const u32 volts_type1[] = { 3300000, 1800000 };
16+
static const u32 volts_type2[] = { 1000000, 1800000 };
17+
#define VOLT_LEV0 0
18+
#define VOLT_LEV1 1
19+
20+
struct volt_supply {
21+
char *name;
22+
const u32 *volts;
23+
u32 reg_shift; /* Register bit offset for setting voltage */
24+
};
25+
26+
static const struct volt_supply npcm8xx_volt_supps[] = {
27+
{"v1", volts_type1, 0},
28+
{"v2", volts_type1, 1},
29+
{"v3", volts_type1, 2},
30+
{"v4", volts_type1, 3},
31+
{"v5", volts_type1, 4},
32+
{"v6", volts_type1, 5},
33+
{"v7", volts_type1, 6},
34+
{"v8", volts_type1, 7},
35+
{"v9", volts_type1, 8},
36+
{"v10", volts_type1, 9},
37+
{"v11", volts_type2, 10},
38+
{"v12", volts_type1, 11},
39+
{"v13", volts_type1, 12},
40+
{"v14", volts_type2, 13},
41+
{"vsif", volts_type1, 14},
42+
{"vr2", volts_type1, 30},
43+
};
44+
45+
static const struct volt_supply *npcm8xx_volt_supply_get(const char *name)
46+
{
47+
int i;
48+
49+
for (i = 0; i < ARRAY_SIZE(npcm8xx_volt_supps); i++) {
50+
if (!strcmp(npcm8xx_volt_supps[i].name, name))
51+
return &npcm8xx_volt_supps[i];
52+
}
53+
54+
return NULL;
55+
}
56+
57+
static int npcm8xx_regulator_set_value(struct udevice *dev, int uV)
58+
{
59+
struct dm_regulator_uclass_plat *uc_pdata;
60+
const struct volt_supply *supp;
61+
u32 val, level;
62+
63+
uc_pdata = dev_get_uclass_plat(dev);
64+
if (!uc_pdata)
65+
return -ENXIO;
66+
67+
dev_dbg(dev, "%s set_value: %d\n", uc_pdata->name, uV);
68+
supp = npcm8xx_volt_supply_get(uc_pdata->name);
69+
if (!supp)
70+
return -ENOENT;
71+
72+
if (uV == supp->volts[VOLT_LEV0])
73+
level = VOLT_LEV0;
74+
else if (uV == supp->volts[VOLT_LEV1])
75+
level = VOLT_LEV1;
76+
else
77+
return -EINVAL;
78+
79+
/* Set voltage level */
80+
val = readl(REG_VSRCR);
81+
val &= ~BIT(supp->reg_shift);
82+
val |= level << supp->reg_shift;
83+
writel(val, REG_VSRCR);
84+
85+
return 0;
86+
}
87+
88+
static int npcm8xx_regulator_get_value(struct udevice *dev)
89+
{
90+
struct dm_regulator_uclass_plat *uc_pdata;
91+
const struct volt_supply *supp;
92+
u32 val;
93+
94+
uc_pdata = dev_get_uclass_plat(dev);
95+
if (!uc_pdata)
96+
return -ENXIO;
97+
98+
supp = npcm8xx_volt_supply_get(uc_pdata->name);
99+
if (!supp)
100+
return -ENOENT;
101+
102+
val = readl(REG_VSRCR) & BIT(supp->reg_shift);
103+
104+
dev_dbg(dev, "%s get_value: %d\n", uc_pdata->name,
105+
val ? supp->volts[VOLT_LEV1] : supp->volts[VOLT_LEV0]);
106+
107+
return val ? supp->volts[VOLT_LEV1] : supp->volts[VOLT_LEV0];
108+
}
109+
110+
static int npcm8xx_regulator_set_enable(struct udevice *dev, bool enable)
111+
{
112+
/* Always on */
113+
return 0;
114+
}
115+
116+
static const struct dm_regulator_ops npcm8xx_regulator_ops = {
117+
.set_value = npcm8xx_regulator_set_value,
118+
.get_value = npcm8xx_regulator_get_value,
119+
.set_enable = npcm8xx_regulator_set_enable,
120+
};
121+
122+
static const struct udevice_id npcm8xx_regulator_ids[] = {
123+
{ .compatible = "regulator-npcm845" },
124+
{ },
125+
};
126+
127+
U_BOOT_DRIVER(regulator_npcm8xx) = {
128+
.name = "regulator_npcm845",
129+
.id = UCLASS_REGULATOR,
130+
.ops = &npcm8xx_regulator_ops,
131+
.of_match = npcm8xx_regulator_ids,
132+
};

0 commit comments

Comments
 (0)