13c910ecbSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
2811b7006SBeniamino Galvani /*
3811b7006SBeniamino Galvani * Regulator driver for Ricoh RN5T618 PMIC
4811b7006SBeniamino Galvani *
5811b7006SBeniamino Galvani * Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
6811b7006SBeniamino Galvani */
7811b7006SBeniamino Galvani
8811b7006SBeniamino Galvani #include <linux/mfd/rn5t618.h>
9811b7006SBeniamino Galvani #include <linux/module.h>
10811b7006SBeniamino Galvani #include <linux/of.h>
11811b7006SBeniamino Galvani #include <linux/platform_device.h>
12811b7006SBeniamino Galvani #include <linux/regmap.h>
13811b7006SBeniamino Galvani #include <linux/regulator/driver.h>
14811b7006SBeniamino Galvani #include <linux/regulator/of_regulator.h>
15811b7006SBeniamino Galvani
16243842b8SBhumika Goyal static const struct regulator_ops rn5t618_reg_ops = {
17811b7006SBeniamino Galvani .enable = regulator_enable_regmap,
18811b7006SBeniamino Galvani .disable = regulator_disable_regmap,
19811b7006SBeniamino Galvani .is_enabled = regulator_is_enabled_regmap,
20811b7006SBeniamino Galvani .set_voltage_sel = regulator_set_voltage_sel_regmap,
21811b7006SBeniamino Galvani .get_voltage_sel = regulator_get_voltage_sel_regmap,
22811b7006SBeniamino Galvani .list_voltage = regulator_list_voltage_linear,
23811b7006SBeniamino Galvani };
24811b7006SBeniamino Galvani
25811b7006SBeniamino Galvani #define REG(rid, ereg, emask, vreg, vmask, min, max, step) \
26d824c7a8SLeonard Crestez { \
27811b7006SBeniamino Galvani .name = #rid, \
289075cceaSBeniamino Galvani .of_match = of_match_ptr(#rid), \
299075cceaSBeniamino Galvani .regulators_node = of_match_ptr("regulators"), \
30811b7006SBeniamino Galvani .id = RN5T618_##rid, \
31811b7006SBeniamino Galvani .type = REGULATOR_VOLTAGE, \
32811b7006SBeniamino Galvani .owner = THIS_MODULE, \
33811b7006SBeniamino Galvani .ops = &rn5t618_reg_ops, \
34811b7006SBeniamino Galvani .n_voltages = ((max) - (min)) / (step) + 1, \
35811b7006SBeniamino Galvani .min_uV = (min), \
36811b7006SBeniamino Galvani .uV_step = (step), \
37811b7006SBeniamino Galvani .enable_reg = RN5T618_##ereg, \
38811b7006SBeniamino Galvani .enable_mask = (emask), \
39811b7006SBeniamino Galvani .vsel_reg = RN5T618_##vreg, \
40811b7006SBeniamino Galvani .vsel_mask = (vmask), \
41811b7006SBeniamino Galvani }
42811b7006SBeniamino Galvani
43c2293856SAxel Lin static const struct regulator_desc rn5t567_regulators[] = {
44ed6d362dSStefan Agner /* DCDC */
45ed6d362dSStefan Agner REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500),
46ed6d362dSStefan Agner REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500),
47ed6d362dSStefan Agner REG(DCDC3, DC3CTL, BIT(0), DC3DAC, 0xff, 600000, 3500000, 12500),
48ed6d362dSStefan Agner REG(DCDC4, DC4CTL, BIT(0), DC4DAC, 0xff, 600000, 3500000, 12500),
49ed6d362dSStefan Agner /* LDO */
50ed6d362dSStefan Agner REG(LDO1, LDOEN1, BIT(0), LDO1DAC, 0x7f, 900000, 3500000, 25000),
51ed6d362dSStefan Agner REG(LDO2, LDOEN1, BIT(1), LDO2DAC, 0x7f, 900000, 3500000, 25000),
52ed6d362dSStefan Agner REG(LDO3, LDOEN1, BIT(2), LDO3DAC, 0x7f, 600000, 3500000, 25000),
53ed6d362dSStefan Agner REG(LDO4, LDOEN1, BIT(3), LDO4DAC, 0x7f, 900000, 3500000, 25000),
54ed6d362dSStefan Agner REG(LDO5, LDOEN1, BIT(4), LDO5DAC, 0x7f, 900000, 3500000, 25000),
55ed6d362dSStefan Agner /* LDO RTC */
56ed6d362dSStefan Agner REG(LDORTC1, LDOEN2, BIT(4), LDORTCDAC, 0x7f, 1200000, 3500000, 25000),
57ed6d362dSStefan Agner REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000),
58ed6d362dSStefan Agner };
59ed6d362dSStefan Agner
60c2293856SAxel Lin static const struct regulator_desc rn5t618_regulators[] = {
61811b7006SBeniamino Galvani /* DCDC */
62811b7006SBeniamino Galvani REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500),
63811b7006SBeniamino Galvani REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500),
64811b7006SBeniamino Galvani REG(DCDC3, DC3CTL, BIT(0), DC3DAC, 0xff, 600000, 3500000, 12500),
65811b7006SBeniamino Galvani /* LDO */
66811b7006SBeniamino Galvani REG(LDO1, LDOEN1, BIT(0), LDO1DAC, 0x7f, 900000, 3500000, 25000),
67811b7006SBeniamino Galvani REG(LDO2, LDOEN1, BIT(1), LDO2DAC, 0x7f, 900000, 3500000, 25000),
68811b7006SBeniamino Galvani REG(LDO3, LDOEN1, BIT(2), LDO3DAC, 0x7f, 600000, 3500000, 25000),
69811b7006SBeniamino Galvani REG(LDO4, LDOEN1, BIT(3), LDO4DAC, 0x7f, 900000, 3500000, 25000),
70811b7006SBeniamino Galvani REG(LDO5, LDOEN1, BIT(4), LDO5DAC, 0x7f, 900000, 3500000, 25000),
71811b7006SBeniamino Galvani /* LDO RTC */
72811b7006SBeniamino Galvani REG(LDORTC1, LDOEN2, BIT(4), LDORTCDAC, 0x7f, 1700000, 3500000, 25000),
73811b7006SBeniamino Galvani REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000),
74811b7006SBeniamino Galvani };
75811b7006SBeniamino Galvani
76c2293856SAxel Lin static const struct regulator_desc rc5t619_regulators[] = {
7783b2a3c2SPierre-Hugues Husson /* DCDC */
7883b2a3c2SPierre-Hugues Husson REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500),
7983b2a3c2SPierre-Hugues Husson REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500),
8083b2a3c2SPierre-Hugues Husson REG(DCDC3, DC3CTL, BIT(0), DC3DAC, 0xff, 600000, 3500000, 12500),
8183b2a3c2SPierre-Hugues Husson REG(DCDC4, DC4CTL, BIT(0), DC4DAC, 0xff, 600000, 3500000, 12500),
8283b2a3c2SPierre-Hugues Husson REG(DCDC5, DC5CTL, BIT(0), DC5DAC, 0xff, 600000, 3500000, 12500),
8383b2a3c2SPierre-Hugues Husson /* LDO */
8483b2a3c2SPierre-Hugues Husson REG(LDO1, LDOEN1, BIT(0), LDO1DAC, 0x7f, 900000, 3500000, 25000),
8583b2a3c2SPierre-Hugues Husson REG(LDO2, LDOEN1, BIT(1), LDO2DAC, 0x7f, 900000, 3500000, 25000),
8683b2a3c2SPierre-Hugues Husson REG(LDO3, LDOEN1, BIT(2), LDO3DAC, 0x7f, 900000, 3500000, 25000),
8783b2a3c2SPierre-Hugues Husson REG(LDO4, LDOEN1, BIT(3), LDO4DAC, 0x7f, 900000, 3500000, 25000),
8883b2a3c2SPierre-Hugues Husson REG(LDO5, LDOEN1, BIT(4), LDO5DAC, 0x7f, 600000, 3500000, 25000),
8983b2a3c2SPierre-Hugues Husson REG(LDO6, LDOEN1, BIT(5), LDO6DAC, 0x7f, 600000, 3500000, 25000),
9083b2a3c2SPierre-Hugues Husson REG(LDO7, LDOEN1, BIT(6), LDO7DAC, 0x7f, 900000, 3500000, 25000),
9183b2a3c2SPierre-Hugues Husson REG(LDO8, LDOEN1, BIT(7), LDO8DAC, 0x7f, 900000, 3500000, 25000),
9283b2a3c2SPierre-Hugues Husson REG(LDO9, LDOEN2, BIT(0), LDO9DAC, 0x7f, 900000, 3500000, 25000),
933f1a9e63SAndreas Kemnade REG(LDO10, LDOEN2, BIT(1), LDO10DAC, 0x7f, 900000, 3500000, 25000),
9483b2a3c2SPierre-Hugues Husson /* LDO RTC */
9583b2a3c2SPierre-Hugues Husson REG(LDORTC1, LDOEN2, BIT(4), LDORTCDAC, 0x7f, 1700000, 3500000, 25000),
9683b2a3c2SPierre-Hugues Husson REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000),
9783b2a3c2SPierre-Hugues Husson };
9883b2a3c2SPierre-Hugues Husson
rn5t618_regulator_probe(struct platform_device * pdev)99811b7006SBeniamino Galvani static int rn5t618_regulator_probe(struct platform_device *pdev)
100811b7006SBeniamino Galvani {
101811b7006SBeniamino Galvani struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent);
102811b7006SBeniamino Galvani struct regulator_config config = { };
103811b7006SBeniamino Galvani struct regulator_dev *rdev;
104c2293856SAxel Lin const struct regulator_desc *regulators;
1059075cceaSBeniamino Galvani int i;
10683b2a3c2SPierre-Hugues Husson int num_regulators = 0;
107811b7006SBeniamino Galvani
108ed6d362dSStefan Agner switch (rn5t618->variant) {
109ed6d362dSStefan Agner case RN5T567:
110ed6d362dSStefan Agner regulators = rn5t567_regulators;
11183b2a3c2SPierre-Hugues Husson num_regulators = ARRAY_SIZE(rn5t567_regulators);
112ed6d362dSStefan Agner break;
113ed6d362dSStefan Agner case RN5T618:
114ed6d362dSStefan Agner regulators = rn5t618_regulators;
11583b2a3c2SPierre-Hugues Husson num_regulators = ARRAY_SIZE(rn5t618_regulators);
11683b2a3c2SPierre-Hugues Husson break;
11783b2a3c2SPierre-Hugues Husson case RC5T619:
11883b2a3c2SPierre-Hugues Husson regulators = rc5t619_regulators;
11983b2a3c2SPierre-Hugues Husson num_regulators = ARRAY_SIZE(rc5t619_regulators);
120ed6d362dSStefan Agner break;
121ed6d362dSStefan Agner default:
122ed6d362dSStefan Agner return -EINVAL;
123ed6d362dSStefan Agner }
124ed6d362dSStefan Agner
1259075cceaSBeniamino Galvani config.dev = pdev->dev.parent;
126811b7006SBeniamino Galvani config.regmap = rn5t618->regmap;
127811b7006SBeniamino Galvani
12883b2a3c2SPierre-Hugues Husson for (i = 0; i < num_regulators; i++) {
129811b7006SBeniamino Galvani rdev = devm_regulator_register(&pdev->dev,
130ed6d362dSStefan Agner ®ulators[i],
131811b7006SBeniamino Galvani &config);
132811b7006SBeniamino Galvani if (IS_ERR(rdev)) {
133811b7006SBeniamino Galvani dev_err(&pdev->dev, "failed to register %s regulator\n",
134ed6d362dSStefan Agner regulators[i].name);
135811b7006SBeniamino Galvani return PTR_ERR(rdev);
136811b7006SBeniamino Galvani }
137811b7006SBeniamino Galvani }
138811b7006SBeniamino Galvani
139811b7006SBeniamino Galvani return 0;
140811b7006SBeniamino Galvani }
141811b7006SBeniamino Galvani
142811b7006SBeniamino Galvani static struct platform_driver rn5t618_regulator_driver = {
143811b7006SBeniamino Galvani .probe = rn5t618_regulator_probe,
144811b7006SBeniamino Galvani .driver = {
145811b7006SBeniamino Galvani .name = "rn5t618-regulator",
146*259b93b2SDouglas Anderson .probe_type = PROBE_PREFER_ASYNCHRONOUS,
147811b7006SBeniamino Galvani },
148811b7006SBeniamino Galvani };
149811b7006SBeniamino Galvani
150811b7006SBeniamino Galvani module_platform_driver(rn5t618_regulator_driver);
151811b7006SBeniamino Galvani
15262a1923cSAndreas Kemnade MODULE_ALIAS("platform:rn5t618-regulator");
153811b7006SBeniamino Galvani MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
154811b7006SBeniamino Galvani MODULE_DESCRIPTION("RN5T618 regulator driver");
155811b7006SBeniamino Galvani MODULE_LICENSE("GPL v2");
156