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(struct regulator_dev
*rdev
,
154 int min_uV
, int max_uV
)
156 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
157 void *pcap
= rdev_get_drvdata(rdev
);
161 /* the regulator doesn't support voltage switching */
162 if (vreg
->n_voltages
== 1)
165 for (i
= 0; i
< vreg
->n_voltages
; i
++) {
166 /* For V1 the first is not the best match */
167 if (i
== 0 && rdev_get_id(rdev
) == V1
)
169 else if (i
+ 1 == vreg
->n_voltages
&& rdev_get_id(rdev
) == V1
)
172 uV
= vreg
->voltage_table
[i
] * 1000;
173 if (min_uV
<= uV
&& uV
<= max_uV
)
174 return ezx_pcap_set_bits(pcap
, vreg
->reg
,
175 (vreg
->n_voltages
- 1) << vreg
->index
,
178 if (i
== 0 && rdev_get_id(rdev
) == V1
)
179 i
= vreg
->n_voltages
- 1;
182 /* the requested voltage range is not supported by this regulator */
186 static int pcap_regulator_get_voltage(struct regulator_dev
*rdev
)
188 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
189 void *pcap
= rdev_get_drvdata(rdev
);
193 if (vreg
->n_voltages
== 1)
194 return vreg
->voltage_table
[0] * 1000;
196 ezx_pcap_read(pcap
, vreg
->reg
, &tmp
);
197 tmp
= ((tmp
>> vreg
->index
) & (vreg
->n_voltages
- 1));
198 mV
= vreg
->voltage_table
[tmp
];
203 static int pcap_regulator_enable(struct regulator_dev
*rdev
)
205 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
206 void *pcap
= rdev_get_drvdata(rdev
);
211 return ezx_pcap_set_bits(pcap
, vreg
->reg
, 1 << vreg
->en
, 1 << vreg
->en
);
214 static int pcap_regulator_disable(struct regulator_dev
*rdev
)
216 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
217 void *pcap
= rdev_get_drvdata(rdev
);
222 return ezx_pcap_set_bits(pcap
, vreg
->reg
, 1 << vreg
->en
, 0);
225 static int pcap_regulator_is_enabled(struct regulator_dev
*rdev
)
227 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
228 void *pcap
= rdev_get_drvdata(rdev
);
234 ezx_pcap_read(pcap
, vreg
->reg
, &tmp
);
235 return (tmp
>> vreg
->en
) & 1;
238 static int pcap_regulator_list_voltage(struct regulator_dev
*rdev
,
241 struct pcap_regulator
*vreg
= &vreg_table
[rdev_get_id(rdev
)];
243 return vreg
->voltage_table
[index
] * 1000;
246 static struct regulator_ops pcap_regulator_ops
= {
247 .list_voltage
= pcap_regulator_list_voltage
,
248 .set_voltage
= pcap_regulator_set_voltage
,
249 .get_voltage
= pcap_regulator_get_voltage
,
250 .enable
= pcap_regulator_enable
,
251 .disable
= pcap_regulator_disable
,
252 .is_enabled
= pcap_regulator_is_enabled
,
255 #define VREG(_vreg) \
259 .n_voltages = ARRAY_SIZE(_vreg##_table), \
260 .ops = &pcap_regulator_ops, \
261 .type = REGULATOR_VOLTAGE, \
262 .owner = THIS_MODULE, \
265 static struct regulator_desc pcap_regulators
[] = {
266 VREG(V1
), VREG(V2
), VREG(V3
), VREG(V4
), VREG(V5
), VREG(V6
), VREG(V7
),
267 VREG(V8
), VREG(V9
), VREG(V10
), VREG(VAUX1
), VREG(VAUX2
), VREG(VAUX3
),
268 VREG(VAUX4
), VREG(VSIM
), VREG(VSIM2
), VREG(VVIB
), VREG(SW1
), VREG(SW2
),
271 static int __devinit
pcap_regulator_probe(struct platform_device
*pdev
)
273 struct regulator_dev
*rdev
;
274 void *pcap
= dev_get_drvdata(pdev
->dev
.parent
);
276 rdev
= regulator_register(&pcap_regulators
[pdev
->id
], &pdev
->dev
,
277 pdev
->dev
.platform_data
, pcap
);
279 return PTR_ERR(rdev
);
281 platform_set_drvdata(pdev
, rdev
);
286 static int __devexit
pcap_regulator_remove(struct platform_device
*pdev
)
288 struct regulator_dev
*rdev
= platform_get_drvdata(pdev
);
290 regulator_unregister(rdev
);
295 static struct platform_driver pcap_regulator_driver
= {
297 .name
= "pcap-regulator",
299 .probe
= pcap_regulator_probe
,
300 .remove
= __devexit_p(pcap_regulator_remove
),
303 static int __init
pcap_regulator_init(void)
305 return platform_driver_register(&pcap_regulator_driver
);
308 static void __exit
pcap_regulator_exit(void)
310 platform_driver_unregister(&pcap_regulator_driver
);
313 subsys_initcall(pcap_regulator_init
);
314 module_exit(pcap_regulator_exit
);
316 MODULE_AUTHOR("Daniel Ribeiro <drwyrm@gmail.com>");
317 MODULE_DESCRIPTION("PCAP2 Regulator Driver");
318 MODULE_LICENSE("GPL");