2 * Regulator Driver for Freescale MC13xxx PMIC
4 * Copyright 2010 Yong Shen <yong.shen@linaro.org>
6 * Based on mc13783 regulator driver :
7 * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de>
8 * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com>
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation.
14 * Regs infos taken from mc13xxx drivers from freescale and mc13xxx.pdf file
18 #include <linux/mfd/mc13xxx.h>
19 #include <linux/regulator/machine.h>
20 #include <linux/regulator/driver.h>
21 #include <linux/platform_device.h>
22 #include <linux/kernel.h>
23 #include <linux/slab.h>
24 #include <linux/init.h>
25 #include <linux/err.h>
26 #include <linux/module.h>
29 static int mc13xxx_regulator_enable(struct regulator_dev
*rdev
)
31 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
32 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
33 int id
= rdev_get_id(rdev
);
36 dev_dbg(rdev_get_dev(rdev
), "%s id: %d\n", __func__
, id
);
38 mc13xxx_lock(priv
->mc13xxx
);
39 ret
= mc13xxx_reg_rmw(priv
->mc13xxx
, mc13xxx_regulators
[id
].reg
,
40 mc13xxx_regulators
[id
].enable_bit
,
41 mc13xxx_regulators
[id
].enable_bit
);
42 mc13xxx_unlock(priv
->mc13xxx
);
47 static int mc13xxx_regulator_disable(struct regulator_dev
*rdev
)
49 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
50 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
51 int id
= rdev_get_id(rdev
);
54 dev_dbg(rdev_get_dev(rdev
), "%s id: %d\n", __func__
, id
);
56 mc13xxx_lock(priv
->mc13xxx
);
57 ret
= mc13xxx_reg_rmw(priv
->mc13xxx
, mc13xxx_regulators
[id
].reg
,
58 mc13xxx_regulators
[id
].enable_bit
, 0);
59 mc13xxx_unlock(priv
->mc13xxx
);
64 static int mc13xxx_regulator_is_enabled(struct regulator_dev
*rdev
)
66 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
67 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
68 int ret
, id
= rdev_get_id(rdev
);
71 mc13xxx_lock(priv
->mc13xxx
);
72 ret
= mc13xxx_reg_read(priv
->mc13xxx
, mc13xxx_regulators
[id
].reg
, &val
);
73 mc13xxx_unlock(priv
->mc13xxx
);
78 return (val
& mc13xxx_regulators
[id
].enable_bit
) != 0;
81 int mc13xxx_regulator_list_voltage(struct regulator_dev
*rdev
,
84 int id
= rdev_get_id(rdev
);
85 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
86 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
88 if (selector
>= mc13xxx_regulators
[id
].desc
.n_voltages
)
91 return mc13xxx_regulators
[id
].voltages
[selector
];
93 EXPORT_SYMBOL_GPL(mc13xxx_regulator_list_voltage
);
95 int mc13xxx_get_best_voltage_index(struct regulator_dev
*rdev
,
96 int min_uV
, int max_uV
)
98 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
99 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
100 int reg_id
= rdev_get_id(rdev
);
106 * Locate the minimum voltage fitting the criteria on
107 * this regulator. The switchable voltages are not
108 * in strict falling order so we need to check them
109 * all for the best match.
113 for (i
= 0; i
< mc13xxx_regulators
[reg_id
].desc
.n_voltages
; i
++) {
114 if (mc13xxx_regulators
[reg_id
].voltages
[i
] >= min_uV
&&
115 mc13xxx_regulators
[reg_id
].voltages
[i
] < bestmatch
) {
116 bestmatch
= mc13xxx_regulators
[reg_id
].voltages
[i
];
121 if (bestindex
< 0 || bestmatch
> max_uV
) {
122 dev_warn(&rdev
->dev
, "no possible value for %d<=x<=%d uV\n",
128 EXPORT_SYMBOL_GPL(mc13xxx_get_best_voltage_index
);
130 static int mc13xxx_regulator_set_voltage(struct regulator_dev
*rdev
, int min_uV
,
131 int max_uV
, unsigned *selector
)
133 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
134 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
135 int value
, id
= rdev_get_id(rdev
);
138 dev_dbg(rdev_get_dev(rdev
), "%s id: %d min_uV: %d max_uV: %d\n",
139 __func__
, id
, min_uV
, max_uV
);
141 /* Find the best index */
142 value
= mc13xxx_get_best_voltage_index(rdev
, min_uV
, max_uV
);
143 dev_dbg(rdev_get_dev(rdev
), "%s best value: %d\n", __func__
, value
);
147 mc13xxx_lock(priv
->mc13xxx
);
148 ret
= mc13xxx_reg_rmw(priv
->mc13xxx
, mc13xxx_regulators
[id
].vsel_reg
,
149 mc13xxx_regulators
[id
].vsel_mask
,
150 value
<< mc13xxx_regulators
[id
].vsel_shift
);
151 mc13xxx_unlock(priv
->mc13xxx
);
156 static int mc13xxx_regulator_get_voltage(struct regulator_dev
*rdev
)
158 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
159 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
160 int ret
, id
= rdev_get_id(rdev
);
163 dev_dbg(rdev_get_dev(rdev
), "%s id: %d\n", __func__
, id
);
165 mc13xxx_lock(priv
->mc13xxx
);
166 ret
= mc13xxx_reg_read(priv
->mc13xxx
,
167 mc13xxx_regulators
[id
].vsel_reg
, &val
);
168 mc13xxx_unlock(priv
->mc13xxx
);
173 val
= (val
& mc13xxx_regulators
[id
].vsel_mask
)
174 >> mc13xxx_regulators
[id
].vsel_shift
;
176 dev_dbg(rdev_get_dev(rdev
), "%s id: %d val: %d\n", __func__
, id
, val
);
178 BUG_ON(val
>= mc13xxx_regulators
[id
].desc
.n_voltages
);
180 return mc13xxx_regulators
[id
].voltages
[val
];
183 struct regulator_ops mc13xxx_regulator_ops
= {
184 .enable
= mc13xxx_regulator_enable
,
185 .disable
= mc13xxx_regulator_disable
,
186 .is_enabled
= mc13xxx_regulator_is_enabled
,
187 .list_voltage
= mc13xxx_regulator_list_voltage
,
188 .set_voltage
= mc13xxx_regulator_set_voltage
,
189 .get_voltage
= mc13xxx_regulator_get_voltage
,
191 EXPORT_SYMBOL_GPL(mc13xxx_regulator_ops
);
193 int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev
*rdev
, int min_uV
,
194 int max_uV
, unsigned *selector
)
196 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
197 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
198 int id
= rdev_get_id(rdev
);
200 dev_dbg(rdev_get_dev(rdev
), "%s id: %d min_uV: %d max_uV: %d\n",
201 __func__
, id
, min_uV
, max_uV
);
203 if (min_uV
>= mc13xxx_regulators
[id
].voltages
[0] &&
204 max_uV
<= mc13xxx_regulators
[id
].voltages
[0])
209 EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_set_voltage
);
211 int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev
*rdev
)
213 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
214 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
215 int id
= rdev_get_id(rdev
);
217 dev_dbg(rdev_get_dev(rdev
), "%s id: %d\n", __func__
, id
);
219 return mc13xxx_regulators
[id
].voltages
[0];
221 EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_get_voltage
);
223 struct regulator_ops mc13xxx_fixed_regulator_ops
= {
224 .enable
= mc13xxx_regulator_enable
,
225 .disable
= mc13xxx_regulator_disable
,
226 .is_enabled
= mc13xxx_regulator_is_enabled
,
227 .list_voltage
= mc13xxx_regulator_list_voltage
,
228 .set_voltage
= mc13xxx_fixed_regulator_set_voltage
,
229 .get_voltage
= mc13xxx_fixed_regulator_get_voltage
,
231 EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_ops
);
233 int mc13xxx_sw_regulator_is_enabled(struct regulator_dev
*rdev
)
237 EXPORT_SYMBOL_GPL(mc13xxx_sw_regulator_is_enabled
);
239 MODULE_LICENSE("GPL v2");
240 MODULE_AUTHOR("Yong Shen <yong.shen@linaro.org>");
241 MODULE_DESCRIPTION("Regulator Driver for Freescale MC13xxx PMIC");
242 MODULE_ALIAS("mc13xxx-regulator-core");