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>
28 static int mc13xxx_regulator_enable(struct regulator_dev
*rdev
)
30 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
31 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
32 int id
= rdev_get_id(rdev
);
35 dev_dbg(rdev_get_dev(rdev
), "%s id: %d\n", __func__
, id
);
37 mc13xxx_lock(priv
->mc13xxx
);
38 ret
= mc13xxx_reg_rmw(priv
->mc13xxx
, mc13xxx_regulators
[id
].reg
,
39 mc13xxx_regulators
[id
].enable_bit
,
40 mc13xxx_regulators
[id
].enable_bit
);
41 mc13xxx_unlock(priv
->mc13xxx
);
46 static int mc13xxx_regulator_disable(struct regulator_dev
*rdev
)
48 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
49 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
50 int id
= rdev_get_id(rdev
);
53 dev_dbg(rdev_get_dev(rdev
), "%s id: %d\n", __func__
, id
);
55 mc13xxx_lock(priv
->mc13xxx
);
56 ret
= mc13xxx_reg_rmw(priv
->mc13xxx
, mc13xxx_regulators
[id
].reg
,
57 mc13xxx_regulators
[id
].enable_bit
, 0);
58 mc13xxx_unlock(priv
->mc13xxx
);
63 static int mc13xxx_regulator_is_enabled(struct regulator_dev
*rdev
)
65 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
66 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
67 int ret
, id
= rdev_get_id(rdev
);
70 mc13xxx_lock(priv
->mc13xxx
);
71 ret
= mc13xxx_reg_read(priv
->mc13xxx
, mc13xxx_regulators
[id
].reg
, &val
);
72 mc13xxx_unlock(priv
->mc13xxx
);
77 return (val
& mc13xxx_regulators
[id
].enable_bit
) != 0;
80 int mc13xxx_regulator_list_voltage(struct regulator_dev
*rdev
,
83 int id
= rdev_get_id(rdev
);
84 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
85 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
87 if (selector
>= mc13xxx_regulators
[id
].desc
.n_voltages
)
90 return mc13xxx_regulators
[id
].voltages
[selector
];
92 EXPORT_SYMBOL_GPL(mc13xxx_regulator_list_voltage
);
94 int mc13xxx_get_best_voltage_index(struct regulator_dev
*rdev
,
95 int min_uV
, int max_uV
)
97 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
98 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
99 int reg_id
= rdev_get_id(rdev
);
105 * Locate the minimum voltage fitting the criteria on
106 * this regulator. The switchable voltages are not
107 * in strict falling order so we need to check them
108 * all for the best match.
112 for (i
= 0; i
< mc13xxx_regulators
[reg_id
].desc
.n_voltages
; i
++) {
113 if (mc13xxx_regulators
[reg_id
].voltages
[i
] >= min_uV
&&
114 mc13xxx_regulators
[reg_id
].voltages
[i
] < bestmatch
) {
115 bestmatch
= mc13xxx_regulators
[reg_id
].voltages
[i
];
120 if (bestindex
< 0 || bestmatch
> max_uV
) {
121 dev_warn(&rdev
->dev
, "no possible value for %d<=x<=%d uV\n",
127 EXPORT_SYMBOL_GPL(mc13xxx_get_best_voltage_index
);
129 static int mc13xxx_regulator_set_voltage(struct regulator_dev
*rdev
, int min_uV
,
130 int max_uV
, unsigned *selector
)
132 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
133 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
134 int value
, id
= rdev_get_id(rdev
);
137 dev_dbg(rdev_get_dev(rdev
), "%s id: %d min_uV: %d max_uV: %d\n",
138 __func__
, id
, min_uV
, max_uV
);
140 /* Find the best index */
141 value
= mc13xxx_get_best_voltage_index(rdev
, min_uV
, max_uV
);
142 dev_dbg(rdev_get_dev(rdev
), "%s best value: %d\n", __func__
, value
);
146 mc13xxx_lock(priv
->mc13xxx
);
147 ret
= mc13xxx_reg_rmw(priv
->mc13xxx
, mc13xxx_regulators
[id
].vsel_reg
,
148 mc13xxx_regulators
[id
].vsel_mask
,
149 value
<< mc13xxx_regulators
[id
].vsel_shift
);
150 mc13xxx_unlock(priv
->mc13xxx
);
155 static int mc13xxx_regulator_get_voltage(struct regulator_dev
*rdev
)
157 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
158 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
159 int ret
, id
= rdev_get_id(rdev
);
162 dev_dbg(rdev_get_dev(rdev
), "%s id: %d\n", __func__
, id
);
164 mc13xxx_lock(priv
->mc13xxx
);
165 ret
= mc13xxx_reg_read(priv
->mc13xxx
,
166 mc13xxx_regulators
[id
].vsel_reg
, &val
);
167 mc13xxx_unlock(priv
->mc13xxx
);
172 val
= (val
& mc13xxx_regulators
[id
].vsel_mask
)
173 >> mc13xxx_regulators
[id
].vsel_shift
;
175 dev_dbg(rdev_get_dev(rdev
), "%s id: %d val: %d\n", __func__
, id
, val
);
177 BUG_ON(val
>= mc13xxx_regulators
[id
].desc
.n_voltages
);
179 return mc13xxx_regulators
[id
].voltages
[val
];
182 struct regulator_ops mc13xxx_regulator_ops
= {
183 .enable
= mc13xxx_regulator_enable
,
184 .disable
= mc13xxx_regulator_disable
,
185 .is_enabled
= mc13xxx_regulator_is_enabled
,
186 .list_voltage
= mc13xxx_regulator_list_voltage
,
187 .set_voltage
= mc13xxx_regulator_set_voltage
,
188 .get_voltage
= mc13xxx_regulator_get_voltage
,
190 EXPORT_SYMBOL_GPL(mc13xxx_regulator_ops
);
192 int mc13xxx_fixed_regulator_set_voltage(struct regulator_dev
*rdev
, int min_uV
,
193 int max_uV
, unsigned *selector
)
195 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
196 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
197 int id
= rdev_get_id(rdev
);
199 dev_dbg(rdev_get_dev(rdev
), "%s id: %d min_uV: %d max_uV: %d\n",
200 __func__
, id
, min_uV
, max_uV
);
202 if (min_uV
>= mc13xxx_regulators
[id
].voltages
[0] &&
203 max_uV
<= mc13xxx_regulators
[id
].voltages
[0])
208 EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_set_voltage
);
210 int mc13xxx_fixed_regulator_get_voltage(struct regulator_dev
*rdev
)
212 struct mc13xxx_regulator_priv
*priv
= rdev_get_drvdata(rdev
);
213 struct mc13xxx_regulator
*mc13xxx_regulators
= priv
->mc13xxx_regulators
;
214 int id
= rdev_get_id(rdev
);
216 dev_dbg(rdev_get_dev(rdev
), "%s id: %d\n", __func__
, id
);
218 return mc13xxx_regulators
[id
].voltages
[0];
220 EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_get_voltage
);
222 struct regulator_ops mc13xxx_fixed_regulator_ops
= {
223 .enable
= mc13xxx_regulator_enable
,
224 .disable
= mc13xxx_regulator_disable
,
225 .is_enabled
= mc13xxx_regulator_is_enabled
,
226 .list_voltage
= mc13xxx_regulator_list_voltage
,
227 .set_voltage
= mc13xxx_fixed_regulator_set_voltage
,
228 .get_voltage
= mc13xxx_fixed_regulator_get_voltage
,
230 EXPORT_SYMBOL_GPL(mc13xxx_fixed_regulator_ops
);
232 int mc13xxx_sw_regulator_is_enabled(struct regulator_dev
*rdev
)
236 EXPORT_SYMBOL_GPL(mc13xxx_sw_regulator_is_enabled
);
238 MODULE_LICENSE("GPL v2");
239 MODULE_AUTHOR("Yong Shen <yong.shen@linaro.org>");
240 MODULE_DESCRIPTION("Regulator Driver for Freescale MC13xxx PMIC");
241 MODULE_ALIAS("mc13xxx-regulator-core");