2 * PCAP2 Regulator Driver
4 * Copyright (c) 2009 Daniel Ribeiro <drwyrm@gmail.com>
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
12 #include <linux/kernel.h>
13 #include <linux/module.h>
14 #include <linux/init.h>
15 #include <linux/err.h>
16 #include <linux/platform_device.h>
17 #include <linux/regulator/driver.h>
18 #include <linux/regulator/machine.h>
19 #include <linux/mfd/ezx-pcap.h>
21 static const u16 V1_table
[] = {
22 2775, 1275, 1600, 1725, 1825, 1925, 2075, 2275,
25 static const u16 V2_table
[] = {
29 static const u16 V3_table
[] = {
30 1075, 1275, 1550, 1725, 1876, 1950, 2075, 2275,
33 static const u16 V4_table
[] = {
34 1275, 1550, 1725, 1875, 1950, 2075, 2275, 2775,
37 static const u16 V5_table
[] = {
38 1875, 2275, 2475, 2775,
41 static const u16 V6_table
[] = {
45 static const u16 V7_table
[] = {
49 #define V8_table V4_table
51 static const u16 V9_table
[] = {
52 1575, 1875, 2475, 2775,
55 static const u16 V10_table
[] = {
59 static const u16 VAUX1_table
[] = {
60 1875, 2475, 2775, 3000,
63 #define VAUX2_table VAUX1_table
65 static const u16 VAUX3_table
[] = {
66 1200, 1200, 1200, 1200, 1400, 1600, 1800, 2000,
67 2200, 2400, 2600, 2800, 3000, 3200, 3400, 3600,
70 static const u16 VAUX4_table
[] = {
71 1800, 1800, 3000, 5000,
74 static const u16 VSIM_table
[] = {
78 static const u16 VSIM2_table
[] = {
82 static const u16 VVIB_table
[] = {
83 1300, 1800, 2000, 3000,
86 static const u16 SW1_table
[] = {
87 900, 950, 1000, 1050, 1100, 1150, 1200, 1250,
88 1300, 1350, 1400, 1450, 1500, 1600, 1875, 2250,
91 #define SW2_table SW1_table
93 static const u16 SW3_table
[] = {
94 4000, 4500, 5000, 5500,
97 struct pcap_regulator
{
104 const u16
*voltage_table
;
109 #define VREG_INFO(_vreg, _reg, _en, _index, _stby, _lowpwr) \
116 .n_voltages = ARRAY_SIZE(_vreg##_table), \
117 .voltage_table = _vreg##_table, \
120 static struct pcap_regulator vreg_table
[] = {
121 VREG_INFO(V1
, PCAP_REG_VREG1
, 1, 2, 18, 0),
122 VREG_INFO(V2
, PCAP_REG_VREG1
, 5, 6, 19, 22),
123 VREG_INFO(V3
, PCAP_REG_VREG1
, 7, 8, 20, 23),
124 VREG_INFO(V4
, PCAP_REG_VREG1
, 11, 12, 21, 24),
125 /* V5 STBY and LOWPWR are on PCAP_REG_VREG2 */
126 VREG_INFO(V5
, PCAP_REG_VREG1
, 15, 16, 12, 19),
128 VREG_INFO(V6
, PCAP_REG_VREG2
, 1, 2, 14, 20),
129 VREG_INFO(V7
, PCAP_REG_VREG2
, 3, 4, 15, 21),
130 VREG_INFO(V8
, PCAP_REG_VREG2
, 5, 6, 16, 22),
131 VREG_INFO(V9
, PCAP_REG_VREG2
, 9, 10, 17, 23),
132 VREG_INFO(V10
, PCAP_REG_VREG2
, 10, NA
, 18, 24),
134 VREG_INFO(VAUX1
, PCAP_REG_AUXVREG
, 1, 2, 22, 23),
135 /* VAUX2 ... VSIM2 STBY and LOWPWR are on PCAP_REG_LOWPWR */
136 VREG_INFO(VAUX2
, PCAP_REG_AUXVREG
, 4, 5, 0, 1),
137 VREG_INFO(VAUX3
, PCAP_REG_AUXVREG
, 7, 8, 2, 3),
138 VREG_INFO(VAUX4
, PCAP_REG_AUXVREG
, 12, 13, 4, 5),
139 VREG_INFO(VSIM
, PCAP_REG_AUXVREG
, 17, 18, NA
, 6),
140 VREG_INFO(VSIM2
, PCAP_REG_AUXVREG
, 16, NA
, NA
, 7),
141 VREG_INFO(VVIB
, PCAP_REG_AUXVREG
, 19, 20, NA
, NA
),
143 VREG_INFO(SW1
, PCAP_REG_SWCTRL
, 1, 2, NA
, NA
),
144 VREG_INFO(SW2
, PCAP_REG_SWCTRL
, 6, 7, NA
, NA
),
145 /* SW3 STBY is on PCAP_REG_AUXVREG */
146 VREG_INFO(SW3
, PCAP_REG_SWCTRL
, 11, 12, 24, NA
),
148 /* SWxS used to control SWx voltage on standby */
149 /* VREG_INFO(SW1S, PCAP_REG_LOWPWR, NA, 12, NA, NA),
150 VREG_INFO(SW2S, PCAP_REG_LOWPWR, NA, 20, NA, NA), */
153 static int pcap_regulator_set_voltage_sel(struct regulator_dev
*rdev
,
156 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
157 void *pcap
= rdev_get_drvdata(rdev
);
159 /* the regulator doesn't support voltage switching */
160 if (vreg
->n_voltages
== 1)
163 return ezx_pcap_set_bits(pcap
, vreg
->reg
,
164 (vreg
->n_voltages
- 1) << vreg
->index
,
165 selector
<< vreg
->index
);
168 static int pcap_regulator_get_voltage_sel(struct regulator_dev
*rdev
)
170 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
171 void *pcap
= rdev_get_drvdata(rdev
);
174 if (vreg
->n_voltages
== 1)
177 ezx_pcap_read(pcap
, vreg
->reg
, &tmp
);
178 tmp
= ((tmp
>> vreg
->index
) & (vreg
->n_voltages
- 1));
182 static int pcap_regulator_enable(struct regulator_dev
*rdev
)
184 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
185 void *pcap
= rdev_get_drvdata(rdev
);
190 return ezx_pcap_set_bits(pcap
, vreg
->reg
, 1 << vreg
->en
, 1 << vreg
->en
);
193 static int pcap_regulator_disable(struct regulator_dev
*rdev
)
195 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
196 void *pcap
= rdev_get_drvdata(rdev
);
201 return ezx_pcap_set_bits(pcap
, vreg
->reg
, 1 << vreg
->en
, 0);
204 static int pcap_regulator_is_enabled(struct regulator_dev
*rdev
)
206 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
207 void *pcap
= rdev_get_drvdata(rdev
);
213 ezx_pcap_read(pcap
, vreg
->reg
, &tmp
);
214 return (tmp
>> vreg
->en
) & 1;
217 static int pcap_regulator_list_voltage(struct regulator_dev
*rdev
,
220 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
222 return vreg
->voltage_table
[index
] * 1000;
225 static struct regulator_ops pcap_regulator_ops
= {
226 .list_voltage
= pcap_regulator_list_voltage
,
227 .set_voltage_sel
= pcap_regulator_set_voltage_sel
,
228 .get_voltage_sel
= pcap_regulator_get_voltage_sel
,
229 .enable
= pcap_regulator_enable
,
230 .disable
= pcap_regulator_disable
,
231 .is_enabled
= pcap_regulator_is_enabled
,
234 #define VREG(_vreg) \
238 .n_voltages = ARRAY_SIZE(_vreg##_table), \
239 .ops = &pcap_regulator_ops, \
240 .type = REGULATOR_VOLTAGE, \
241 .owner = THIS_MODULE, \
244 static const struct regulator_desc pcap_regulators
[] = {
245 VREG(V1
), VREG(V2
), VREG(V3
), VREG(V4
), VREG(V5
), VREG(V6
), VREG(V7
),
246 VREG(V8
), VREG(V9
), VREG(V10
), VREG(VAUX1
), VREG(VAUX2
), VREG(VAUX3
),
247 VREG(VAUX4
), VREG(VSIM
), VREG(VSIM2
), VREG(VVIB
), VREG(SW1
), VREG(SW2
),
250 static int __devinit
pcap_regulator_probe(struct platform_device
*pdev
)
252 struct regulator_dev
*rdev
;
253 void *pcap
= dev_get_drvdata(pdev
->dev
.parent
);
254 struct regulator_config config
= { };
256 config
.dev
= &pdev
->dev
;
257 config
.init_data
= pdev
->dev
.platform_data
;
258 config
.driver_data
= pcap
;
260 rdev
= regulator_register(&pcap_regulators
[pdev
->id
], &config
);
262 return PTR_ERR(rdev
);
264 platform_set_drvdata(pdev
, rdev
);
269 static int __devexit
pcap_regulator_remove(struct platform_device
*pdev
)
271 struct regulator_dev
*rdev
= platform_get_drvdata(pdev
);
273 regulator_unregister(rdev
);
274 platform_set_drvdata(pdev
, NULL
);
279 static struct platform_driver pcap_regulator_driver
= {
281 .name
= "pcap-regulator",
282 .owner
= THIS_MODULE
,
284 .probe
= pcap_regulator_probe
,
285 .remove
= __devexit_p(pcap_regulator_remove
),
288 static int __init
pcap_regulator_init(void)
290 return platform_driver_register(&pcap_regulator_driver
);
293 static void __exit
pcap_regulator_exit(void)
295 platform_driver_unregister(&pcap_regulator_driver
);
298 subsys_initcall(pcap_regulator_init
);
299 module_exit(pcap_regulator_exit
);
301 MODULE_AUTHOR("Daniel Ribeiro <drwyrm@gmail.com>");
302 MODULE_DESCRIPTION("PCAP2 Regulator Driver");
303 MODULE_LICENSE("GPL");