]>
Commit | Line | Data |
---|---|---|
295c08bc SH |
1 | /* |
2 | * Regulator Driver for Freescale MC13783 PMIC | |
3 | * | |
4 | * Copyright (C) 2008 Sascha Hauer, Pengutronix <s.hauer@pengutronix.de> | |
1bd588fd | 5 | * Copyright 2009 Alberto Panizzo <maramaopercheseimorto@gmail.com> |
295c08bc SH |
6 | * |
7 | * This program is free software; you can redistribute it and/or modify | |
8 | * it under the terms of the GNU General Public License version 2 as | |
9 | * published by the Free Software Foundation. | |
10 | */ | |
11 | ||
a10099bc | 12 | #include <linux/mfd/mc13783.h> |
295c08bc SH |
13 | #include <linux/regulator/machine.h> |
14 | #include <linux/regulator/driver.h> | |
15 | #include <linux/platform_device.h> | |
295c08bc SH |
16 | #include <linux/kernel.h> |
17 | #include <linux/init.h> | |
18 | #include <linux/err.h> | |
19 | ||
a10099bc UKK |
20 | #define MC13783_REG_SWITCHERS5 29 |
21 | #define MC13783_REG_SWITCHERS5_SW3EN (1 << 20) | |
1bd588fd AP |
22 | #define MC13783_REG_SWITCHERS5_SW3VSEL 18 |
23 | #define MC13783_REG_SWITCHERS5_SW3VSEL_M (3 << 18) | |
24 | ||
25 | #define MC13783_REG_REGULATORSETTING0 30 | |
26 | #define MC13783_REG_REGULATORSETTING0_VIOLOVSEL 2 | |
27 | #define MC13783_REG_REGULATORSETTING0_VDIGVSEL 4 | |
28 | #define MC13783_REG_REGULATORSETTING0_VGENVSEL 6 | |
29 | #define MC13783_REG_REGULATORSETTING0_VRFDIGVSEL 9 | |
30 | #define MC13783_REG_REGULATORSETTING0_VRFREFVSEL 11 | |
31 | #define MC13783_REG_REGULATORSETTING0_VRFCPVSEL 13 | |
32 | #define MC13783_REG_REGULATORSETTING0_VSIMVSEL 14 | |
33 | #define MC13783_REG_REGULATORSETTING0_VESIMVSEL 15 | |
34 | #define MC13783_REG_REGULATORSETTING0_VCAMVSEL 16 | |
35 | ||
36 | #define MC13783_REG_REGULATORSETTING0_VIOLOVSEL_M (3 << 2) | |
37 | #define MC13783_REG_REGULATORSETTING0_VDIGVSEL_M (3 << 4) | |
38 | #define MC13783_REG_REGULATORSETTING0_VGENVSEL_M (7 << 6) | |
39 | #define MC13783_REG_REGULATORSETTING0_VRFDIGVSEL_M (3 << 9) | |
40 | #define MC13783_REG_REGULATORSETTING0_VRFREFVSEL_M (3 << 11) | |
41 | #define MC13783_REG_REGULATORSETTING0_VRFCPVSEL_M (1 << 13) | |
42 | #define MC13783_REG_REGULATORSETTING0_VSIMVSEL_M (1 << 14) | |
43 | #define MC13783_REG_REGULATORSETTING0_VESIMVSEL_M (1 << 15) | |
44 | #define MC13783_REG_REGULATORSETTING0_VCAMVSEL_M (7 << 16) | |
45 | ||
46 | #define MC13783_REG_REGULATORSETTING1 31 | |
47 | #define MC13783_REG_REGULATORSETTING1_VVIBVSEL 0 | |
48 | #define MC13783_REG_REGULATORSETTING1_VRF1VSEL 2 | |
49 | #define MC13783_REG_REGULATORSETTING1_VRF2VSEL 4 | |
50 | #define MC13783_REG_REGULATORSETTING1_VMMC1VSEL 6 | |
51 | #define MC13783_REG_REGULATORSETTING1_VMMC2VSEL 9 | |
52 | ||
53 | #define MC13783_REG_REGULATORSETTING1_VVIBVSEL_M (3 << 0) | |
54 | #define MC13783_REG_REGULATORSETTING1_VRF1VSEL_M (3 << 2) | |
55 | #define MC13783_REG_REGULATORSETTING1_VRF2VSEL_M (3 << 4) | |
56 | #define MC13783_REG_REGULATORSETTING1_VMMC1VSEL_M (7 << 6) | |
57 | #define MC13783_REG_REGULATORSETTING1_VMMC2VSEL_M (7 << 9) | |
a10099bc UKK |
58 | |
59 | #define MC13783_REG_REGULATORMODE0 32 | |
60 | #define MC13783_REG_REGULATORMODE0_VAUDIOEN (1 << 0) | |
61 | #define MC13783_REG_REGULATORMODE0_VIOHIEN (1 << 3) | |
62 | #define MC13783_REG_REGULATORMODE0_VIOLOEN (1 << 6) | |
63 | #define MC13783_REG_REGULATORMODE0_VDIGEN (1 << 9) | |
64 | #define MC13783_REG_REGULATORMODE0_VGENEN (1 << 12) | |
65 | #define MC13783_REG_REGULATORMODE0_VRFDIGEN (1 << 15) | |
66 | #define MC13783_REG_REGULATORMODE0_VRFREFEN (1 << 18) | |
67 | #define MC13783_REG_REGULATORMODE0_VRFCPEN (1 << 21) | |
68 | ||
69 | #define MC13783_REG_REGULATORMODE1 33 | |
70 | #define MC13783_REG_REGULATORMODE1_VSIMEN (1 << 0) | |
71 | #define MC13783_REG_REGULATORMODE1_VESIMEN (1 << 3) | |
72 | #define MC13783_REG_REGULATORMODE1_VCAMEN (1 << 6) | |
73 | #define MC13783_REG_REGULATORMODE1_VRFBGEN (1 << 9) | |
74 | #define MC13783_REG_REGULATORMODE1_VVIBEN (1 << 11) | |
75 | #define MC13783_REG_REGULATORMODE1_VRF1EN (1 << 12) | |
76 | #define MC13783_REG_REGULATORMODE1_VRF2EN (1 << 15) | |
77 | #define MC13783_REG_REGULATORMODE1_VMMC1EN (1 << 18) | |
78 | #define MC13783_REG_REGULATORMODE1_VMMC2EN (1 << 21) | |
79 | ||
80 | #define MC13783_REG_POWERMISC 34 | |
81 | #define MC13783_REG_POWERMISC_GPO1EN (1 << 6) | |
82 | #define MC13783_REG_POWERMISC_GPO2EN (1 << 8) | |
83 | #define MC13783_REG_POWERMISC_GPO3EN (1 << 10) | |
84 | #define MC13783_REG_POWERMISC_GPO4EN (1 << 12) | |
85 | ||
295c08bc SH |
86 | struct mc13783_regulator { |
87 | struct regulator_desc desc; | |
88 | int reg; | |
89 | int enable_bit; | |
1bd588fd AP |
90 | int vsel_reg; |
91 | int vsel_shift; | |
92 | int vsel_mask; | |
93 | int const *voltages; | |
94 | }; | |
95 | ||
96 | /* Voltage Values */ | |
97 | static const int const mc13783_sw3_val[] = { | |
98 | 5000000, 5000000, 5000000, 5500000, | |
99 | }; | |
100 | ||
101 | static const int const mc13783_vaudio_val[] = { | |
102 | 2775000, | |
103 | }; | |
104 | ||
105 | static const int const mc13783_viohi_val[] = { | |
106 | 2775000, | |
107 | }; | |
108 | ||
109 | static const int const mc13783_violo_val[] = { | |
110 | 1200000, 1300000, 1500000, 1800000, | |
111 | }; | |
112 | ||
113 | static const int const mc13783_vdig_val[] = { | |
114 | 1200000, 1300000, 1500000, 1800000, | |
115 | }; | |
116 | ||
117 | static const int const mc13783_vgen_val[] = { | |
118 | 1200000, 1300000, 1500000, 1800000, | |
119 | 1100000, 2000000, 2775000, 2400000, | |
120 | }; | |
121 | ||
122 | static const int const mc13783_vrfdig_val[] = { | |
123 | 1200000, 1500000, 1800000, 1875000, | |
124 | }; | |
125 | ||
126 | static const int const mc13783_vrfref_val[] = { | |
127 | 2475000, 2600000, 2700000, 2775000, | |
128 | }; | |
129 | ||
130 | static const int const mc13783_vrfcp_val[] = { | |
131 | 2700000, 2775000, | |
132 | }; | |
133 | ||
134 | static const int const mc13783_vsim_val[] = { | |
135 | 1800000, 2900000, 3000000, | |
136 | }; | |
137 | ||
138 | static const int const mc13783_vesim_val[] = { | |
139 | 1800000, 2900000, | |
140 | }; | |
141 | ||
142 | static const int const mc13783_vcam_val[] = { | |
143 | 1500000, 1800000, 2500000, 2550000, | |
144 | 2600000, 2750000, 2800000, 3000000, | |
145 | }; | |
146 | ||
147 | static const int const mc13783_vrfbg_val[] = { | |
148 | 1250000, | |
149 | }; | |
150 | ||
151 | static const int const mc13783_vvib_val[] = { | |
152 | 1300000, 1800000, 2000000, 3000000, | |
153 | }; | |
154 | ||
155 | static const int const mc13783_vmmc_val[] = { | |
156 | 1600000, 1800000, 2000000, 2600000, | |
157 | 2700000, 2800000, 2900000, 3000000, | |
158 | }; | |
159 | ||
160 | static const int const mc13783_vrf_val[] = { | |
161 | 1500000, 1875000, 2700000, 2775000, | |
295c08bc SH |
162 | }; |
163 | ||
164 | static struct regulator_ops mc13783_regulator_ops; | |
1bd588fd AP |
165 | static struct regulator_ops mc13783_fixed_regulator_ops; |
166 | ||
167 | #define MC13783_DEFINE(prefix, _name, _reg, _vsel_reg, _voltages) \ | |
168 | [MC13783_ ## prefix ## _ ## _name] = { \ | |
169 | .desc = { \ | |
170 | .name = #prefix "_" #_name, \ | |
171 | .n_voltages = ARRAY_SIZE(_voltages), \ | |
172 | .ops = &mc13783_regulator_ops, \ | |
173 | .type = REGULATOR_VOLTAGE, \ | |
174 | .id = MC13783_ ## prefix ## _ ## _name, \ | |
175 | .owner = THIS_MODULE, \ | |
176 | }, \ | |
177 | .reg = MC13783_REG_ ## _reg, \ | |
178 | .enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN, \ | |
179 | .vsel_reg = MC13783_REG_ ## _vsel_reg, \ | |
180 | .vsel_shift = MC13783_REG_ ## _vsel_reg ## _ ## _name ## VSEL,\ | |
181 | .vsel_mask = MC13783_REG_ ## _vsel_reg ## _ ## _name ## VSEL_M,\ | |
182 | .voltages = _voltages, \ | |
183 | } | |
295c08bc | 184 | |
1bd588fd AP |
185 | #define MC13783_FIXED_DEFINE(prefix, _name, _reg, _voltages) \ |
186 | [MC13783_ ## prefix ## _ ## _name] = { \ | |
187 | .desc = { \ | |
188 | .name = #prefix "_" #_name, \ | |
189 | .n_voltages = ARRAY_SIZE(_voltages), \ | |
190 | .ops = &mc13783_fixed_regulator_ops, \ | |
191 | .type = REGULATOR_VOLTAGE, \ | |
192 | .id = MC13783_ ## prefix ## _ ## _name, \ | |
193 | .owner = THIS_MODULE, \ | |
194 | }, \ | |
195 | .reg = MC13783_REG_ ## _reg, \ | |
196 | .enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN, \ | |
197 | .voltages = _voltages, \ | |
198 | } | |
199 | ||
200 | #define MC13783_GPO_DEFINE(prefix, _name, _reg) \ | |
a10099bc UKK |
201 | [MC13783_ ## prefix ## _ ## _name] = { \ |
202 | .desc = { \ | |
203 | .name = #prefix "_" #_name, \ | |
204 | .ops = &mc13783_regulator_ops, \ | |
205 | .type = REGULATOR_VOLTAGE, \ | |
206 | .id = MC13783_ ## prefix ## _ ## _name, \ | |
207 | .owner = THIS_MODULE, \ | |
208 | }, \ | |
209 | .reg = MC13783_REG_ ## _reg, \ | |
210 | .enable_bit = MC13783_REG_ ## _reg ## _ ## _name ## EN, \ | |
211 | } | |
212 | ||
1bd588fd AP |
213 | #define MC13783_DEFINE_SW(_name, _reg, _vsel_reg, _voltages) \ |
214 | MC13783_DEFINE(SW, _name, _reg, _vsel_reg, _voltages) | |
215 | #define MC13783_DEFINE_REGU(_name, _reg, _vsel_reg, _voltages) \ | |
216 | MC13783_DEFINE(REGU, _name, _reg, _vsel_reg, _voltages) | |
a10099bc | 217 | |
295c08bc | 218 | static struct mc13783_regulator mc13783_regulators[] = { |
1bd588fd AP |
219 | MC13783_DEFINE_SW(SW3, SWITCHERS5, SWITCHERS5, mc13783_sw3_val), |
220 | ||
221 | MC13783_FIXED_DEFINE(REGU, VAUDIO, REGULATORMODE0, mc13783_vaudio_val), | |
222 | MC13783_FIXED_DEFINE(REGU, VIOHI, REGULATORMODE0, mc13783_viohi_val), | |
223 | MC13783_DEFINE_REGU(VIOLO, REGULATORMODE0, REGULATORSETTING0, \ | |
224 | mc13783_violo_val), | |
225 | MC13783_DEFINE_REGU(VDIG, REGULATORMODE0, REGULATORSETTING0, \ | |
226 | mc13783_vdig_val), | |
227 | MC13783_DEFINE_REGU(VGEN, REGULATORMODE0, REGULATORSETTING0, \ | |
228 | mc13783_vgen_val), | |
229 | MC13783_DEFINE_REGU(VRFDIG, REGULATORMODE0, REGULATORSETTING0, \ | |
230 | mc13783_vrfdig_val), | |
231 | MC13783_DEFINE_REGU(VRFREF, REGULATORMODE0, REGULATORSETTING0, \ | |
232 | mc13783_vrfref_val), | |
233 | MC13783_DEFINE_REGU(VRFCP, REGULATORMODE0, REGULATORSETTING0, \ | |
234 | mc13783_vrfcp_val), | |
235 | MC13783_DEFINE_REGU(VSIM, REGULATORMODE1, REGULATORSETTING0, \ | |
236 | mc13783_vsim_val), | |
237 | MC13783_DEFINE_REGU(VESIM, REGULATORMODE1, REGULATORSETTING0, \ | |
238 | mc13783_vesim_val), | |
239 | MC13783_DEFINE_REGU(VCAM, REGULATORMODE1, REGULATORSETTING0, \ | |
240 | mc13783_vcam_val), | |
241 | MC13783_FIXED_DEFINE(REGU, VRFBG, REGULATORMODE1, mc13783_vrfbg_val), | |
242 | MC13783_DEFINE_REGU(VVIB, REGULATORMODE1, REGULATORSETTING1, \ | |
243 | mc13783_vvib_val), | |
244 | MC13783_DEFINE_REGU(VRF1, REGULATORMODE1, REGULATORSETTING1, \ | |
245 | mc13783_vrf_val), | |
246 | MC13783_DEFINE_REGU(VRF2, REGULATORMODE1, REGULATORSETTING1, \ | |
247 | mc13783_vrf_val), | |
248 | MC13783_DEFINE_REGU(VMMC1, REGULATORMODE1, REGULATORSETTING1, \ | |
249 | mc13783_vmmc_val), | |
250 | MC13783_DEFINE_REGU(VMMC2, REGULATORMODE1, REGULATORSETTING1, \ | |
251 | mc13783_vmmc_val), | |
252 | MC13783_GPO_DEFINE(REGU, GPO1, POWERMISC), | |
253 | MC13783_GPO_DEFINE(REGU, GPO2, POWERMISC), | |
254 | MC13783_GPO_DEFINE(REGU, GPO3, POWERMISC), | |
255 | MC13783_GPO_DEFINE(REGU, GPO4, POWERMISC), | |
295c08bc SH |
256 | }; |
257 | ||
a10099bc | 258 | struct mc13783_regulator_priv { |
295c08bc | 259 | struct mc13783 *mc13783; |
a10099bc | 260 | struct regulator_dev *regulators[]; |
295c08bc SH |
261 | }; |
262 | ||
a10099bc | 263 | static int mc13783_regulator_enable(struct regulator_dev *rdev) |
295c08bc | 264 | { |
a10099bc | 265 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); |
295c08bc | 266 | int id = rdev_get_id(rdev); |
a10099bc | 267 | int ret; |
295c08bc SH |
268 | |
269 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | |
270 | ||
a10099bc UKK |
271 | mc13783_lock(priv->mc13783); |
272 | ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].reg, | |
295c08bc SH |
273 | mc13783_regulators[id].enable_bit, |
274 | mc13783_regulators[id].enable_bit); | |
a10099bc UKK |
275 | mc13783_unlock(priv->mc13783); |
276 | ||
277 | return ret; | |
295c08bc SH |
278 | } |
279 | ||
a10099bc | 280 | static int mc13783_regulator_disable(struct regulator_dev *rdev) |
295c08bc | 281 | { |
a10099bc | 282 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); |
295c08bc | 283 | int id = rdev_get_id(rdev); |
a10099bc | 284 | int ret; |
295c08bc SH |
285 | |
286 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | |
287 | ||
a10099bc UKK |
288 | mc13783_lock(priv->mc13783); |
289 | ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].reg, | |
295c08bc | 290 | mc13783_regulators[id].enable_bit, 0); |
a10099bc UKK |
291 | mc13783_unlock(priv->mc13783); |
292 | ||
293 | return ret; | |
295c08bc SH |
294 | } |
295 | ||
a10099bc | 296 | static int mc13783_regulator_is_enabled(struct regulator_dev *rdev) |
295c08bc | 297 | { |
a10099bc | 298 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); |
295c08bc SH |
299 | int ret, id = rdev_get_id(rdev); |
300 | unsigned int val; | |
301 | ||
a10099bc | 302 | mc13783_lock(priv->mc13783); |
295c08bc | 303 | ret = mc13783_reg_read(priv->mc13783, mc13783_regulators[id].reg, &val); |
a10099bc UKK |
304 | mc13783_unlock(priv->mc13783); |
305 | ||
295c08bc SH |
306 | if (ret) |
307 | return ret; | |
308 | ||
309 | return (val & mc13783_regulators[id].enable_bit) != 0; | |
310 | } | |
311 | ||
1bd588fd AP |
312 | static int mc13783_regulator_list_voltage(struct regulator_dev *rdev, |
313 | unsigned selector) | |
314 | { | |
315 | int id = rdev_get_id(rdev); | |
316 | ||
317 | if (selector >= mc13783_regulators[id].desc.n_voltages) | |
318 | return -EINVAL; | |
319 | ||
320 | return mc13783_regulators[id].voltages[selector]; | |
321 | } | |
322 | ||
323 | static int mc13783_get_best_voltage_index(struct regulator_dev *rdev, | |
324 | int min_uV, int max_uV) | |
325 | { | |
326 | int reg_id = rdev_get_id(rdev); | |
327 | int i; | |
328 | int bestmatch; | |
329 | int bestindex; | |
330 | ||
331 | /* | |
332 | * Locate the minimum voltage fitting the criteria on | |
333 | * this regulator. The switchable voltages are not | |
334 | * in strict falling order so we need to check them | |
335 | * all for the best match. | |
336 | */ | |
337 | bestmatch = INT_MAX; | |
338 | bestindex = -1; | |
339 | for (i = 0; i < mc13783_regulators[reg_id].desc.n_voltages; i++) { | |
340 | if (mc13783_regulators[reg_id].voltages[i] >= min_uV && | |
341 | mc13783_regulators[reg_id].voltages[i] < bestmatch) { | |
342 | bestmatch = mc13783_regulators[reg_id].voltages[i]; | |
343 | bestindex = i; | |
344 | } | |
345 | } | |
346 | ||
347 | if (bestindex < 0 || bestmatch > max_uV) { | |
348 | dev_warn(&rdev->dev, "no possible value for %d<=x<=%d uV\n", | |
349 | min_uV, max_uV); | |
350 | return -EINVAL; | |
351 | } | |
352 | return bestindex; | |
353 | } | |
354 | ||
355 | static int mc13783_regulator_set_voltage(struct regulator_dev *rdev, | |
356 | int min_uV, int max_uV) | |
357 | { | |
358 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); | |
359 | int value, id = rdev_get_id(rdev); | |
360 | int ret; | |
361 | ||
362 | dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", | |
363 | __func__, id, min_uV, max_uV); | |
364 | ||
365 | /* Find the best index */ | |
366 | value = mc13783_get_best_voltage_index(rdev, min_uV, max_uV); | |
367 | dev_dbg(rdev_get_dev(rdev), "%s best value: %d \n", __func__, value); | |
368 | if (value < 0) | |
369 | return value; | |
370 | ||
371 | mc13783_lock(priv->mc13783); | |
372 | ret = mc13783_reg_rmw(priv->mc13783, mc13783_regulators[id].vsel_reg, | |
373 | mc13783_regulators[id].vsel_mask, | |
374 | value << mc13783_regulators[id].vsel_shift); | |
375 | mc13783_unlock(priv->mc13783); | |
376 | ||
377 | return ret; | |
378 | } | |
379 | ||
380 | static int mc13783_regulator_get_voltage(struct regulator_dev *rdev) | |
381 | { | |
382 | struct mc13783_regulator_priv *priv = rdev_get_drvdata(rdev); | |
383 | int ret, id = rdev_get_id(rdev); | |
384 | unsigned int val; | |
385 | ||
386 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | |
387 | ||
388 | mc13783_lock(priv->mc13783); | |
389 | ret = mc13783_reg_read(priv->mc13783, | |
390 | mc13783_regulators[id].vsel_reg, &val); | |
391 | mc13783_unlock(priv->mc13783); | |
392 | ||
393 | if (ret) | |
394 | return ret; | |
395 | ||
396 | val = (val & mc13783_regulators[id].vsel_mask) | |
397 | >> mc13783_regulators[id].vsel_shift; | |
398 | ||
399 | dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val); | |
400 | ||
401 | BUG_ON(val < 0 || val > mc13783_regulators[id].desc.n_voltages); | |
402 | ||
403 | return mc13783_regulators[id].voltages[val]; | |
404 | } | |
405 | ||
295c08bc | 406 | static struct regulator_ops mc13783_regulator_ops = { |
a10099bc UKK |
407 | .enable = mc13783_regulator_enable, |
408 | .disable = mc13783_regulator_disable, | |
409 | .is_enabled = mc13783_regulator_is_enabled, | |
1bd588fd AP |
410 | .list_voltage = mc13783_regulator_list_voltage, |
411 | .set_voltage = mc13783_regulator_set_voltage, | |
412 | .get_voltage = mc13783_regulator_get_voltage, | |
413 | }; | |
414 | ||
415 | static int mc13783_fixed_regulator_set_voltage(struct regulator_dev *rdev, | |
416 | int min_uV, int max_uV) | |
417 | { | |
418 | int id = rdev_get_id(rdev); | |
419 | ||
420 | dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", | |
421 | __func__, id, min_uV, max_uV); | |
422 | ||
423 | if (min_uV > mc13783_regulators[id].voltages[0] && | |
424 | max_uV < mc13783_regulators[id].voltages[0]) | |
425 | return 0; | |
426 | else | |
427 | return -EINVAL; | |
428 | } | |
429 | ||
430 | static int mc13783_fixed_regulator_get_voltage(struct regulator_dev *rdev) | |
431 | { | |
432 | int id = rdev_get_id(rdev); | |
433 | ||
434 | dev_dbg(rdev_get_dev(rdev), "%s id: %d\n", __func__, id); | |
435 | ||
436 | return mc13783_regulators[id].voltages[0]; | |
437 | } | |
438 | ||
439 | static struct regulator_ops mc13783_fixed_regulator_ops = { | |
440 | .enable = mc13783_regulator_enable, | |
441 | .disable = mc13783_regulator_disable, | |
442 | .is_enabled = mc13783_regulator_is_enabled, | |
443 | .list_voltage = mc13783_regulator_list_voltage, | |
444 | .set_voltage = mc13783_fixed_regulator_set_voltage, | |
445 | .get_voltage = mc13783_fixed_regulator_get_voltage, | |
295c08bc SH |
446 | }; |
447 | ||
448 | static int __devinit mc13783_regulator_probe(struct platform_device *pdev) | |
449 | { | |
a10099bc | 450 | struct mc13783_regulator_priv *priv; |
295c08bc | 451 | struct mc13783 *mc13783 = dev_get_drvdata(pdev->dev.parent); |
a10099bc UKK |
452 | struct mc13783_regulator_platform_data *pdata = |
453 | dev_get_platdata(&pdev->dev); | |
295c08bc SH |
454 | struct mc13783_regulator_init_data *init_data; |
455 | int i, ret; | |
456 | ||
457 | dev_dbg(&pdev->dev, "mc13783_regulator_probe id %d\n", pdev->id); | |
458 | ||
a10099bc UKK |
459 | priv = kzalloc(sizeof(*priv) + |
460 | pdata->num_regulators * sizeof(priv->regulators[0]), | |
295c08bc SH |
461 | GFP_KERNEL); |
462 | if (!priv) | |
463 | return -ENOMEM; | |
464 | ||
465 | priv->mc13783 = mc13783; | |
466 | ||
a10099bc UKK |
467 | for (i = 0; i < pdata->num_regulators; i++) { |
468 | init_data = &pdata->regulators[i]; | |
295c08bc SH |
469 | priv->regulators[i] = regulator_register( |
470 | &mc13783_regulators[init_data->id].desc, | |
471 | &pdev->dev, init_data->init_data, priv); | |
472 | ||
473 | if (IS_ERR(priv->regulators[i])) { | |
474 | dev_err(&pdev->dev, "failed to register regulator %s\n", | |
475 | mc13783_regulators[i].desc.name); | |
476 | ret = PTR_ERR(priv->regulators[i]); | |
477 | goto err; | |
478 | } | |
479 | } | |
480 | ||
481 | platform_set_drvdata(pdev, priv); | |
482 | ||
483 | return 0; | |
484 | err: | |
485 | while (--i >= 0) | |
486 | regulator_unregister(priv->regulators[i]); | |
487 | ||
488 | kfree(priv); | |
489 | ||
490 | return ret; | |
491 | } | |
492 | ||
493 | static int __devexit mc13783_regulator_remove(struct platform_device *pdev) | |
494 | { | |
a10099bc UKK |
495 | struct mc13783_regulator_priv *priv = platform_get_drvdata(pdev); |
496 | struct mc13783_regulator_platform_data *pdata = | |
497 | dev_get_platdata(&pdev->dev); | |
295c08bc SH |
498 | int i; |
499 | ||
a10099bc | 500 | for (i = 0; i < pdata->num_regulators; i++) |
295c08bc SH |
501 | regulator_unregister(priv->regulators[i]); |
502 | ||
503 | return 0; | |
504 | } | |
505 | ||
506 | static struct platform_driver mc13783_regulator_driver = { | |
507 | .driver = { | |
508 | .name = "mc13783-regulator", | |
509 | .owner = THIS_MODULE, | |
510 | }, | |
511 | .remove = __devexit_p(mc13783_regulator_remove), | |
735eb93a | 512 | .probe = mc13783_regulator_probe, |
295c08bc SH |
513 | }; |
514 | ||
515 | static int __init mc13783_regulator_init(void) | |
516 | { | |
735eb93a | 517 | return platform_driver_register(&mc13783_regulator_driver); |
295c08bc SH |
518 | } |
519 | subsys_initcall(mc13783_regulator_init); | |
520 | ||
521 | static void __exit mc13783_regulator_exit(void) | |
522 | { | |
523 | platform_driver_unregister(&mc13783_regulator_driver); | |
524 | } | |
525 | module_exit(mc13783_regulator_exit); | |
526 | ||
a10099bc | 527 | MODULE_LICENSE("GPL v2"); |
295c08bc SH |
528 | MODULE_AUTHOR("Sascha Hauer <s.hauer@pengutronix.de"); |
529 | MODULE_DESCRIPTION("Regulator Driver for Freescale MC13783 PMIC"); | |
530 | MODULE_ALIAS("platform:mc13783-regulator"); |