Skip to content

Commit ebf652b

Browse files
robimarkobroonie
authored andcommitted
regulator: add IPQ4019 SDHCI VQMMC LDO driver
This introduces the IPQ4019 VQMMC LDO driver needed for the SD/EMMC driver I/O level operation. This will enable introducing SD/EMMC support for the built-in controller. Signed-off-by: Mantas Pucka <[email protected]> Signed-off-by: Robert Marko <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Mark Brown <[email protected]>
1 parent 77e2959 commit ebf652b

File tree

3 files changed

+119
-0
lines changed

3 files changed

+119
-0
lines changed

drivers/regulator/Kconfig

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,13 @@ config REGULATOR_VEXPRESS
11101110
This driver provides support for voltage regulators available
11111111
on the ARM Ltd's Versatile Express platform.
11121112

1113+
config REGULATOR_VQMMC_IPQ4019
1114+
tristate "IPQ4019 VQMMC SD LDO regulator support"
1115+
depends on ARCH_QCOM
1116+
help
1117+
This driver provides support for the VQMMC LDO I/0
1118+
voltage regulator of the IPQ4019 SD/EMMC controller.
1119+
11131120
config REGULATOR_WM831X
11141121
tristate "Wolfson Microelectronics WM831x PMIC regulators"
11151122
depends on MFD_WM831X

drivers/regulator/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o twl6030-regulator.o
135135
obj-$(CONFIG_REGULATOR_UNIPHIER) += uniphier-regulator.o
136136
obj-$(CONFIG_REGULATOR_VCTRL) += vctrl-regulator.o
137137
obj-$(CONFIG_REGULATOR_VEXPRESS) += vexpress-regulator.o
138+
obj-$(CONFIG_REGULATOR_VQMMC_IPQ4019) += vqmmc-ipq4019-regulator.o
138139
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
139140
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
140141
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
// SPDX-License-Identifier: GPL-2.0+
2+
//
3+
// Copyright (c) 2019 Mantas Pucka <[email protected]>
4+
// Copyright (c) 2019 Robert Marko <[email protected]>
5+
//
6+
// Driver for IPQ4019 SD/MMC controller's I/O LDO voltage regulator
7+
8+
#include <linux/io.h>
9+
#include <linux/module.h>
10+
#include <linux/of.h>
11+
#include <linux/platform_device.h>
12+
#include <linux/regmap.h>
13+
#include <linux/regulator/driver.h>
14+
#include <linux/regulator/machine.h>
15+
#include <linux/regulator/of_regulator.h>
16+
17+
static const unsigned int ipq4019_vmmc_voltages[] = {
18+
1500000, 1800000, 2500000, 3000000,
19+
};
20+
21+
static struct regulator_ops ipq4019_regulator_voltage_ops = {
22+
.list_voltage = regulator_list_voltage_table,
23+
.get_voltage_sel = regulator_get_voltage_sel_regmap,
24+
.set_voltage_sel = regulator_set_voltage_sel_regmap,
25+
};
26+
27+
static struct regulator_desc vmmc_regulator = {
28+
.name = "vmmcq",
29+
.ops = &ipq4019_regulator_voltage_ops,
30+
.type = REGULATOR_VOLTAGE,
31+
.owner = THIS_MODULE,
32+
.volt_table = ipq4019_vmmc_voltages,
33+
.n_voltages = ARRAY_SIZE(ipq4019_vmmc_voltages),
34+
.vsel_reg = 0,
35+
.vsel_mask = 0x3,
36+
};
37+
38+
const struct regmap_config ipq4019_vmmcq_regmap_config = {
39+
.reg_bits = 32,
40+
.reg_stride = 4,
41+
.val_bits = 32,
42+
};
43+
44+
static int ipq4019_regulator_probe(struct platform_device *pdev)
45+
{
46+
struct device *dev = &pdev->dev;
47+
struct regulator_init_data *init_data;
48+
struct regulator_config cfg = {};
49+
struct regulator_dev *rdev;
50+
struct resource *res;
51+
struct regmap *rmap;
52+
void __iomem *base;
53+
54+
init_data = of_get_regulator_init_data(dev, dev->of_node,
55+
&vmmc_regulator);
56+
if (!init_data)
57+
return -EINVAL;
58+
59+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
60+
base = devm_ioremap_resource(dev, res);
61+
if (IS_ERR(base))
62+
return PTR_ERR(base);
63+
64+
rmap = devm_regmap_init_mmio(dev, base, &ipq4019_vmmcq_regmap_config);
65+
if (IS_ERR(rmap))
66+
return PTR_ERR(rmap);
67+
68+
cfg.dev = dev;
69+
cfg.init_data = init_data;
70+
cfg.of_node = dev->of_node;
71+
cfg.regmap = rmap;
72+
73+
rdev = devm_regulator_register(dev, &vmmc_regulator, &cfg);
74+
if (IS_ERR(rdev)) {
75+
dev_err(dev, "Failed to register regulator: %ld\n",
76+
PTR_ERR(rdev));
77+
return PTR_ERR(rdev);
78+
}
79+
platform_set_drvdata(pdev, rdev);
80+
81+
return 0;
82+
}
83+
84+
static int ipq4019_regulator_remove(struct platform_device *pdev)
85+
{
86+
struct regulator_dev *rdev = platform_get_drvdata(pdev);
87+
88+
regulator_unregister(rdev);
89+
90+
return 0;
91+
}
92+
93+
static const struct of_device_id regulator_ipq4019_of_match[] = {
94+
{ .compatible = "qcom,vqmmc-ipq4019-regulator", },
95+
{},
96+
};
97+
98+
static struct platform_driver ipq4019_regulator_driver = {
99+
.probe = ipq4019_regulator_probe,
100+
.remove = ipq4019_regulator_remove,
101+
.driver = {
102+
.name = "vqmmc-ipq4019-regulator",
103+
.owner = THIS_MODULE,
104+
.of_match_table = of_match_ptr(regulator_ipq4019_of_match),
105+
},
106+
};
107+
module_platform_driver(ipq4019_regulator_driver);
108+
109+
MODULE_LICENSE("GPL");
110+
MODULE_AUTHOR("Mantas Pucka <[email protected]>");
111+
MODULE_DESCRIPTION("IPQ4019 VQMMC voltage regulator");

0 commit comments

Comments
 (0)