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 unsigned int V1_table
[] = {
22 2775000, 1275000, 1600000, 1725000, 1825000, 1925000, 2075000, 2275000,
25 static const unsigned int V2_table
[] = {
29 static const unsigned int V3_table
[] = {
30 1075000, 1275000, 1550000, 1725000, 1876000, 1950000, 2075000, 2275000,
33 static const unsigned int V4_table
[] = {
34 1275000, 1550000, 1725000, 1875000, 1950000, 2075000, 2275000, 2775000,
37 static const unsigned int V5_table
[] = {
38 1875000, 2275000, 2475000, 2775000,
41 static const unsigned int V6_table
[] = {
45 static const unsigned int V7_table
[] = {
49 #define V8_table V4_table
51 static const unsigned int V9_table
[] = {
52 1575000, 1875000, 2475000, 2775000,
55 static const unsigned int V10_table
[] = {
59 static const unsigned int VAUX1_table
[] = {
60 1875000, 2475000, 2775000, 3000000,
63 #define VAUX2_table VAUX1_table
65 static const unsigned int VAUX3_table
[] = {
66 1200000, 1200000, 1200000, 1200000, 1400000, 1600000, 1800000, 2000000,
67 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000, 3600000,
70 static const unsigned int VAUX4_table
[] = {
71 1800000, 1800000, 3000000, 5000000,
74 static const unsigned int VSIM_table
[] = {
78 static const unsigned int VSIM2_table
[] = {
82 static const unsigned int VVIB_table
[] = {
83 1300000, 1800000, 2000000, 3000000,
86 static const unsigned int SW1_table
[] = {
87 900000, 950000, 1000000, 1050000, 1100000, 1150000, 1200000, 1250000,
88 1300000, 1350000, 1400000, 1450000, 1500000, 1600000, 1875000, 2250000,
91 #define SW2_table SW1_table
93 static const unsigned int SW3_table
[] = {
94 4000000, 4500000, 5000000, 5500000,
97 struct pcap_regulator
{
107 #define VREG_INFO(_vreg, _reg, _en, _index, _stby, _lowpwr) \
116 static struct pcap_regulator vreg_table
[] = {
117 VREG_INFO(V1
, PCAP_REG_VREG1
, 1, 2, 18, 0),
118 VREG_INFO(V2
, PCAP_REG_VREG1
, 5, 6, 19, 22),
119 VREG_INFO(V3
, PCAP_REG_VREG1
, 7, 8, 20, 23),
120 VREG_INFO(V4
, PCAP_REG_VREG1
, 11, 12, 21, 24),
121 /* V5 STBY and LOWPWR are on PCAP_REG_VREG2 */
122 VREG_INFO(V5
, PCAP_REG_VREG1
, 15, 16, 12, 19),
124 VREG_INFO(V6
, PCAP_REG_VREG2
, 1, 2, 14, 20),
125 VREG_INFO(V7
, PCAP_REG_VREG2
, 3, 4, 15, 21),
126 VREG_INFO(V8
, PCAP_REG_VREG2
, 5, 6, 16, 22),
127 VREG_INFO(V9
, PCAP_REG_VREG2
, 9, 10, 17, 23),
128 VREG_INFO(V10
, PCAP_REG_VREG2
, 10, NA
, 18, 24),
130 VREG_INFO(VAUX1
, PCAP_REG_AUXVREG
, 1, 2, 22, 23),
131 /* VAUX2 ... VSIM2 STBY and LOWPWR are on PCAP_REG_LOWPWR */
132 VREG_INFO(VAUX2
, PCAP_REG_AUXVREG
, 4, 5, 0, 1),
133 VREG_INFO(VAUX3
, PCAP_REG_AUXVREG
, 7, 8, 2, 3),
134 VREG_INFO(VAUX4
, PCAP_REG_AUXVREG
, 12, 13, 4, 5),
135 VREG_INFO(VSIM
, PCAP_REG_AUXVREG
, 17, 18, NA
, 6),
136 VREG_INFO(VSIM2
, PCAP_REG_AUXVREG
, 16, NA
, NA
, 7),
137 VREG_INFO(VVIB
, PCAP_REG_AUXVREG
, 19, 20, NA
, NA
),
139 VREG_INFO(SW1
, PCAP_REG_SWCTRL
, 1, 2, NA
, NA
),
140 VREG_INFO(SW2
, PCAP_REG_SWCTRL
, 6, 7, NA
, NA
),
141 /* SW3 STBY is on PCAP_REG_AUXVREG */
142 VREG_INFO(SW3
, PCAP_REG_SWCTRL
, 11, 12, 24, NA
),
144 /* SWxS used to control SWx voltage on standby */
145 /* VREG_INFO(SW1S, PCAP_REG_LOWPWR, NA, 12, NA, NA),
146 VREG_INFO(SW2S, PCAP_REG_LOWPWR, NA, 20, NA, NA), */
149 static int pcap_regulator_set_voltage_sel(struct regulator_dev
*rdev
,
152 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
153 void *pcap
= rdev_get_drvdata(rdev
);
155 /* the regulator doesn't support voltage switching */
156 if (rdev
->desc
->n_voltages
== 1)
159 return ezx_pcap_set_bits(pcap
, vreg
->reg
,
160 (rdev
->desc
->n_voltages
- 1) << vreg
->index
,
161 selector
<< vreg
->index
);
164 static int pcap_regulator_get_voltage_sel(struct regulator_dev
*rdev
)
166 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
167 void *pcap
= rdev_get_drvdata(rdev
);
170 if (rdev
->desc
->n_voltages
== 1)
173 ezx_pcap_read(pcap
, vreg
->reg
, &tmp
);
174 tmp
= ((tmp
>> vreg
->index
) & (rdev
->desc
->n_voltages
- 1));
178 static int pcap_regulator_enable(struct regulator_dev
*rdev
)
180 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
181 void *pcap
= rdev_get_drvdata(rdev
);
186 return ezx_pcap_set_bits(pcap
, vreg
->reg
, 1 << vreg
->en
, 1 << vreg
->en
);
189 static int pcap_regulator_disable(struct regulator_dev
*rdev
)
191 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
192 void *pcap
= rdev_get_drvdata(rdev
);
197 return ezx_pcap_set_bits(pcap
, vreg
->reg
, 1 << vreg
->en
, 0);
200 static int pcap_regulator_is_enabled(struct regulator_dev
*rdev
)
202 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
203 void *pcap
= rdev_get_drvdata(rdev
);
209 ezx_pcap_read(pcap
, vreg
->reg
, &tmp
);
210 return (tmp
>> vreg
->en
) & 1;
213 static struct regulator_ops pcap_regulator_ops
= {
214 .list_voltage
= regulator_list_voltage_table
,
215 .set_voltage_sel
= pcap_regulator_set_voltage_sel
,
216 .get_voltage_sel
= pcap_regulator_get_voltage_sel
,
217 .enable
= pcap_regulator_enable
,
218 .disable
= pcap_regulator_disable
,
219 .is_enabled
= pcap_regulator_is_enabled
,
222 #define VREG(_vreg) \
226 .n_voltages = ARRAY_SIZE(_vreg##_table), \
227 .volt_table = _vreg##_table, \
228 .ops = &pcap_regulator_ops, \
229 .type = REGULATOR_VOLTAGE, \
230 .owner = THIS_MODULE, \
233 static const struct regulator_desc pcap_regulators
[] = {
234 VREG(V1
), VREG(V2
), VREG(V3
), VREG(V4
), VREG(V5
), VREG(V6
), VREG(V7
),
235 VREG(V8
), VREG(V9
), VREG(V10
), VREG(VAUX1
), VREG(VAUX2
), VREG(VAUX3
),
236 VREG(VAUX4
), VREG(VSIM
), VREG(VSIM2
), VREG(VVIB
), VREG(SW1
), VREG(SW2
),
239 static int __devinit
pcap_regulator_probe(struct platform_device
*pdev
)
241 struct regulator_dev
*rdev
;
242 void *pcap
= dev_get_drvdata(pdev
->dev
.parent
);
243 struct regulator_config config
= { };
245 config
.dev
= &pdev
->dev
;
246 config
.init_data
= pdev
->dev
.platform_data
;
247 config
.driver_data
= pcap
;
249 rdev
= regulator_register(&pcap_regulators
[pdev
->id
], &config
);
251 return PTR_ERR(rdev
);
253 platform_set_drvdata(pdev
, rdev
);
258 static int __devexit
pcap_regulator_remove(struct platform_device
*pdev
)
260 struct regulator_dev
*rdev
= platform_get_drvdata(pdev
);
262 regulator_unregister(rdev
);
263 platform_set_drvdata(pdev
, NULL
);
268 static struct platform_driver pcap_regulator_driver
= {
270 .name
= "pcap-regulator",
271 .owner
= THIS_MODULE
,
273 .probe
= pcap_regulator_probe
,
274 .remove
= __devexit_p(pcap_regulator_remove
),
277 static int __init
pcap_regulator_init(void)
279 return platform_driver_register(&pcap_regulator_driver
);
282 static void __exit
pcap_regulator_exit(void)
284 platform_driver_unregister(&pcap_regulator_driver
);
287 subsys_initcall(pcap_regulator_init
);
288 module_exit(pcap_regulator_exit
);
290 MODULE_AUTHOR("Daniel Ribeiro <drwyrm@gmail.com>");
291 MODULE_DESCRIPTION("PCAP2 Regulator Driver");
292 MODULE_LICENSE("GPL");