1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * PCAP2 Regulator Driver
5 * Copyright (c) 2009 Daniel Ribeiro <drwyrm@gmail.com>
8 #include <linux/kernel.h>
9 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/err.h>
12 #include <linux/platform_device.h>
13 #include <linux/regulator/driver.h>
14 #include <linux/regulator/machine.h>
15 #include <linux/mfd/ezx-pcap.h>
17 static const unsigned int V1_table
[] = {
18 2775000, 1275000, 1600000, 1725000, 1825000, 1925000, 2075000, 2275000,
21 static const unsigned int V2_table
[] = {
25 static const unsigned int V3_table
[] = {
26 1075000, 1275000, 1550000, 1725000, 1876000, 1950000, 2075000, 2275000,
29 static const unsigned int V4_table
[] = {
30 1275000, 1550000, 1725000, 1875000, 1950000, 2075000, 2275000, 2775000,
33 static const unsigned int V5_table
[] = {
34 1875000, 2275000, 2475000, 2775000,
37 static const unsigned int V6_table
[] = {
41 static const unsigned int V7_table
[] = {
45 #define V8_table V4_table
47 static const unsigned int V9_table
[] = {
48 1575000, 1875000, 2475000, 2775000,
51 static const unsigned int V10_table
[] = {
55 static const unsigned int VAUX1_table
[] = {
56 1875000, 2475000, 2775000, 3000000,
59 #define VAUX2_table VAUX1_table
61 static const unsigned int VAUX3_table
[] = {
62 1200000, 1200000, 1200000, 1200000, 1400000, 1600000, 1800000, 2000000,
63 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000, 3600000,
66 static const unsigned int VAUX4_table
[] = {
67 1800000, 1800000, 3000000, 5000000,
70 static const unsigned int VSIM_table
[] = {
74 static const unsigned int VSIM2_table
[] = {
78 static const unsigned int VVIB_table
[] = {
79 1300000, 1800000, 2000000, 3000000,
82 static const unsigned int SW1_table
[] = {
83 900000, 950000, 1000000, 1050000, 1100000, 1150000, 1200000, 1250000,
84 1300000, 1350000, 1400000, 1450000, 1500000, 1600000, 1875000, 2250000,
87 #define SW2_table SW1_table
89 static const unsigned int SW3_table
[] = {
90 4000000, 4500000, 5000000, 5500000,
93 struct pcap_regulator
{
103 #define VREG_INFO(_vreg, _reg, _en, _index, _stby, _lowpwr) \
112 static struct pcap_regulator vreg_table
[] = {
113 VREG_INFO(V1
, PCAP_REG_VREG1
, 1, 2, 18, 0),
114 VREG_INFO(V2
, PCAP_REG_VREG1
, 5, 6, 19, 22),
115 VREG_INFO(V3
, PCAP_REG_VREG1
, 7, 8, 20, 23),
116 VREG_INFO(V4
, PCAP_REG_VREG1
, 11, 12, 21, 24),
117 /* V5 STBY and LOWPWR are on PCAP_REG_VREG2 */
118 VREG_INFO(V5
, PCAP_REG_VREG1
, 15, 16, 12, 19),
120 VREG_INFO(V6
, PCAP_REG_VREG2
, 1, 2, 14, 20),
121 VREG_INFO(V7
, PCAP_REG_VREG2
, 3, 4, 15, 21),
122 VREG_INFO(V8
, PCAP_REG_VREG2
, 5, 6, 16, 22),
123 VREG_INFO(V9
, PCAP_REG_VREG2
, 9, 10, 17, 23),
124 VREG_INFO(V10
, PCAP_REG_VREG2
, 10, NA
, 18, 24),
126 VREG_INFO(VAUX1
, PCAP_REG_AUXVREG
, 1, 2, 22, 23),
127 /* VAUX2 ... VSIM2 STBY and LOWPWR are on PCAP_REG_LOWPWR */
128 VREG_INFO(VAUX2
, PCAP_REG_AUXVREG
, 4, 5, 0, 1),
129 VREG_INFO(VAUX3
, PCAP_REG_AUXVREG
, 7, 8, 2, 3),
130 VREG_INFO(VAUX4
, PCAP_REG_AUXVREG
, 12, 13, 4, 5),
131 VREG_INFO(VSIM
, PCAP_REG_AUXVREG
, 17, 18, NA
, 6),
132 VREG_INFO(VSIM2
, PCAP_REG_AUXVREG
, 16, NA
, NA
, 7),
133 VREG_INFO(VVIB
, PCAP_REG_AUXVREG
, 19, 20, NA
, NA
),
135 VREG_INFO(SW1
, PCAP_REG_SWCTRL
, 1, 2, NA
, NA
),
136 VREG_INFO(SW2
, PCAP_REG_SWCTRL
, 6, 7, NA
, NA
),
137 /* SW3 STBY is on PCAP_REG_AUXVREG */
138 VREG_INFO(SW3
, PCAP_REG_SWCTRL
, 11, 12, 24, NA
),
140 /* SWxS used to control SWx voltage on standby */
141 /* VREG_INFO(SW1S, PCAP_REG_LOWPWR, NA, 12, NA, NA),
142 VREG_INFO(SW2S, PCAP_REG_LOWPWR, NA, 20, NA, NA), */
145 static int pcap_regulator_set_voltage_sel(struct regulator_dev
*rdev
,
148 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
149 void *pcap
= rdev_get_drvdata(rdev
);
151 /* the regulator doesn't support voltage switching */
152 if (rdev
->desc
->n_voltages
== 1)
155 return ezx_pcap_set_bits(pcap
, vreg
->reg
,
156 (rdev
->desc
->n_voltages
- 1) << vreg
->index
,
157 selector
<< vreg
->index
);
160 static int pcap_regulator_get_voltage_sel(struct regulator_dev
*rdev
)
162 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
163 void *pcap
= rdev_get_drvdata(rdev
);
166 if (rdev
->desc
->n_voltages
== 1)
169 ezx_pcap_read(pcap
, vreg
->reg
, &tmp
);
170 tmp
= ((tmp
>> vreg
->index
) & (rdev
->desc
->n_voltages
- 1));
174 static int pcap_regulator_enable(struct regulator_dev
*rdev
)
176 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
177 void *pcap
= rdev_get_drvdata(rdev
);
182 return ezx_pcap_set_bits(pcap
, vreg
->reg
, 1 << vreg
->en
, 1 << vreg
->en
);
185 static int pcap_regulator_disable(struct regulator_dev
*rdev
)
187 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
188 void *pcap
= rdev_get_drvdata(rdev
);
193 return ezx_pcap_set_bits(pcap
, vreg
->reg
, 1 << vreg
->en
, 0);
196 static int pcap_regulator_is_enabled(struct regulator_dev
*rdev
)
198 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
199 void *pcap
= rdev_get_drvdata(rdev
);
205 ezx_pcap_read(pcap
, vreg
->reg
, &tmp
);
206 return (tmp
>> vreg
->en
) & 1;
209 static const struct regulator_ops pcap_regulator_ops
= {
210 .list_voltage
= regulator_list_voltage_table
,
211 .set_voltage_sel
= pcap_regulator_set_voltage_sel
,
212 .get_voltage_sel
= pcap_regulator_get_voltage_sel
,
213 .enable
= pcap_regulator_enable
,
214 .disable
= pcap_regulator_disable
,
215 .is_enabled
= pcap_regulator_is_enabled
,
218 #define VREG(_vreg) \
222 .n_voltages = ARRAY_SIZE(_vreg##_table), \
223 .volt_table = _vreg##_table, \
224 .ops = &pcap_regulator_ops, \
225 .type = REGULATOR_VOLTAGE, \
226 .owner = THIS_MODULE, \
229 static const struct regulator_desc pcap_regulators
[] = {
230 VREG(V1
), VREG(V2
), VREG(V3
), VREG(V4
), VREG(V5
), VREG(V6
), VREG(V7
),
231 VREG(V8
), VREG(V9
), VREG(V10
), VREG(VAUX1
), VREG(VAUX2
), VREG(VAUX3
),
232 VREG(VAUX4
), VREG(VSIM
), VREG(VSIM2
), VREG(VVIB
), VREG(SW1
), VREG(SW2
),
235 static int pcap_regulator_probe(struct platform_device
*pdev
)
237 struct regulator_dev
*rdev
;
238 void *pcap
= dev_get_drvdata(pdev
->dev
.parent
);
239 struct regulator_config config
= { };
241 config
.dev
= &pdev
->dev
;
242 config
.init_data
= dev_get_platdata(&pdev
->dev
);
243 config
.driver_data
= pcap
;
245 rdev
= devm_regulator_register(&pdev
->dev
, &pcap_regulators
[pdev
->id
],
248 return PTR_ERR(rdev
);
250 platform_set_drvdata(pdev
, rdev
);
255 static struct platform_driver pcap_regulator_driver
= {
257 .name
= "pcap-regulator",
259 .probe
= pcap_regulator_probe
,
262 static int __init
pcap_regulator_init(void)
264 return platform_driver_register(&pcap_regulator_driver
);
267 static void __exit
pcap_regulator_exit(void)
269 platform_driver_unregister(&pcap_regulator_driver
);
272 subsys_initcall(pcap_regulator_init
);
273 module_exit(pcap_regulator_exit
);
275 MODULE_AUTHOR("Daniel Ribeiro <drwyrm@gmail.com>");
276 MODULE_DESCRIPTION("PCAP2 Regulator Driver");
277 MODULE_LICENSE("GPL");