aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/regulator/ricoh583-regulator.c
diff options
context:
space:
mode:
authorJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
committerJonathan Herman <hermanjl@cs.unc.edu>2013-01-22 10:38:37 -0500
commitfcc9d2e5a6c89d22b8b773a64fb4ad21ac318446 (patch)
treea57612d1888735a2ec7972891b68c1ac5ec8faea /drivers/regulator/ricoh583-regulator.c
parent8dea78da5cee153b8af9c07a2745f6c55057fe12 (diff)
Added missing tegra files.HEADmaster
Diffstat (limited to 'drivers/regulator/ricoh583-regulator.c')
-rw-r--r--drivers/regulator/ricoh583-regulator.c412
1 files changed, 412 insertions, 0 deletions
diff --git a/drivers/regulator/ricoh583-regulator.c b/drivers/regulator/ricoh583-regulator.c
new file mode 100644
index 00000000000..867ffe629ed
--- /dev/null
+++ b/drivers/regulator/ricoh583-regulator.c
@@ -0,0 +1,412 @@
1/*
2 * drivers/regulator/ricoh583-regulator.c
3 *
4 * Regulator driver for RICOH583 power management chip.
5 *
6 * Copyright (C) 2011 NVIDIA Corporation
7 *
8 * Copyright (C) 2011 RICOH COMPANY,LTD
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
18 * more details.
19 *
20 * You should have received a copy of the GNU General Public License along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
23 *
24 */
25
26/*#define DEBUG 1*/
27/*#define VERBOSE_DEBUG 1*/
28#include <linux/module.h>
29#include <linux/delay.h>
30#include <linux/init.h>
31#include <linux/slab.h>
32#include <linux/err.h>
33#include <linux/platform_device.h>
34#include <linux/regulator/driver.h>
35#include <linux/regulator/machine.h>
36#include <linux/mfd/ricoh583.h>
37#include <linux/regulator/ricoh583-regulator.h>
38
39struct ricoh583_regulator {
40 int id;
41 int deepsleep_id;
42 /* Regulator register address.*/
43 u8 reg_en_reg;
44 u8 en_bit;
45 u8 reg_disc_reg;
46 u8 disc_bit;
47 u8 vout_reg;
48 u8 vout_mask;
49 u8 vout_reg_cache;
50 u8 deepsleep_reg;
51
52 /* chip constraints on regulator behavior */
53 int min_uV;
54 int max_uV;
55 int step_uV;
56 int nsteps;
57
58 /* regulator specific turn-on delay */
59 u16 delay;
60
61 /* used by regulator core */
62 struct regulator_desc desc;
63
64 /* Device */
65 struct device *dev;
66};
67
68
69static inline struct device *to_ricoh583_dev(struct regulator_dev *rdev)
70{
71 return rdev_get_dev(rdev)->parent->parent;
72}
73
74static int ricoh583_regulator_enable_time(struct regulator_dev *rdev)
75{
76 struct ricoh583_regulator *ri = rdev_get_drvdata(rdev);
77
78 return ri->delay;
79}
80
81static int ricoh583_reg_is_enabled(struct regulator_dev *rdev)
82{
83 struct ricoh583_regulator *ri = rdev_get_drvdata(rdev);
84 struct device *parent = to_ricoh583_dev(rdev);
85 uint8_t control;
86 int ret;
87
88 ret = ricoh583_read(parent, ri->reg_en_reg, &control);
89 if (ret < 0) {
90 dev_err(&rdev->dev, "Error in reading the control register\n");
91 return ret;
92 }
93 return (((control >> ri->en_bit) & 1) == 1);
94}
95
96static int ricoh583_reg_enable(struct regulator_dev *rdev)
97{
98 struct ricoh583_regulator *ri = rdev_get_drvdata(rdev);
99 struct device *parent = to_ricoh583_dev(rdev);
100 int ret;
101
102 ret = ricoh583_set_bits(parent, ri->reg_en_reg, (1 << ri->en_bit));
103 if (ret < 0) {
104 dev_err(&rdev->dev, "Error in updating the STATE register\n");
105 return ret;
106 }
107 udelay(ri->delay);
108 return ret;
109}
110
111static int ricoh583_reg_disable(struct regulator_dev *rdev)
112{
113 struct ricoh583_regulator *ri = rdev_get_drvdata(rdev);
114 struct device *parent = to_ricoh583_dev(rdev);
115 int ret;
116
117 ret = ricoh583_clr_bits(parent, ri->reg_en_reg, (1 << ri->en_bit));
118 if (ret < 0)
119 dev_err(&rdev->dev, "Error in updating the STATE register\n");
120
121 return ret;
122}
123
124static int ricoh583_list_voltage(struct regulator_dev *rdev, unsigned index)
125{
126 struct ricoh583_regulator *ri = rdev_get_drvdata(rdev);
127
128 return ri->min_uV + (ri->step_uV * index);
129}
130
131static int __ricoh583_set_ds_voltage(struct device *parent,
132 struct ricoh583_regulator *ri, int min_uV, int max_uV)
133{
134 int vsel;
135 int ret;
136
137 if ((min_uV < ri->min_uV) || (max_uV > ri->max_uV))
138 return -EDOM;
139
140 vsel = (min_uV - ri->min_uV + ri->step_uV - 1)/ri->step_uV;
141 if (vsel > ri->nsteps)
142 return -EDOM;
143
144 ret = ricoh583_update(parent, ri->deepsleep_reg, vsel, ri->vout_mask);
145 if (ret < 0)
146 dev_err(ri->dev, "Error in writing the deepsleep register\n");
147 return ret;
148}
149
150static int __ricoh583_set_voltage(struct device *parent,
151 struct ricoh583_regulator *ri, int min_uV, int max_uV,
152 unsigned *selector)
153{
154 int vsel;
155 int ret;
156 uint8_t vout_val;
157
158 if ((min_uV < ri->min_uV) || (max_uV > ri->max_uV))
159 return -EDOM;
160
161 vsel = (min_uV - ri->min_uV + ri->step_uV - 1)/ri->step_uV;
162 if (vsel > ri->nsteps)
163 return -EDOM;
164
165 if (selector)
166 *selector = vsel;
167
168 vout_val = (ri->vout_reg_cache & ~ri->vout_mask) |
169 (vsel & ri->vout_mask);
170 ret = ricoh583_write(parent, ri->vout_reg, vout_val);
171 if (ret < 0)
172 dev_err(ri->dev, "Error in writing the Voltage register\n");
173 else
174 ri->vout_reg_cache = vout_val;
175
176 return ret;
177}
178
179static int ricoh583_set_voltage(struct regulator_dev *rdev,
180 int min_uV, int max_uV, unsigned *selector)
181{
182 struct ricoh583_regulator *ri = rdev_get_drvdata(rdev);
183 struct device *parent = to_ricoh583_dev(rdev);
184
185 return __ricoh583_set_voltage(parent, ri, min_uV, max_uV, selector);
186}
187
188static int ricoh583_get_voltage(struct regulator_dev *rdev)
189{
190 struct ricoh583_regulator *ri = rdev_get_drvdata(rdev);
191 uint8_t vsel;
192
193 vsel = ri->vout_reg_cache & ri->vout_mask;
194 return ri->min_uV + vsel * ri->step_uV;
195}
196
197static struct regulator_ops ricoh583_ops = {
198 .list_voltage = ricoh583_list_voltage,
199 .set_voltage = ricoh583_set_voltage,
200 .get_voltage = ricoh583_get_voltage,
201 .enable = ricoh583_reg_enable,
202 .disable = ricoh583_reg_disable,
203 .is_enabled = ricoh583_reg_is_enabled,
204 .enable_time = ricoh583_regulator_enable_time,
205};
206
207#define RICOH583_REG(_id, _en_reg, _en_bit, _disc_reg, _disc_bit, _vout_reg, \
208 _vout_mask, _ds_reg, _min_mv, _max_mv, _step_uV, _nsteps, \
209 _ops, _delay) \
210{ \
211 .reg_en_reg = _en_reg, \
212 .en_bit = _en_bit, \
213 .reg_disc_reg = _disc_reg, \
214 .disc_bit = _disc_bit, \
215 .vout_reg = _vout_reg, \
216 .vout_mask = _vout_mask, \
217 .deepsleep_reg = _ds_reg, \
218 .min_uV = _min_mv * 1000, \
219 .max_uV = _max_mv * 1000, \
220 .step_uV = _step_uV, \
221 .nsteps = _nsteps, \
222 .delay = _delay, \
223 .id = RICOH583_ID_##_id, \
224 .deepsleep_id = RICOH583_DS_##_id, \
225 .desc = { \
226 .name = ricoh583_rails(_id), \
227 .id = RICOH583_ID_##_id, \
228 .n_voltages = _nsteps, \
229 .ops = &_ops, \
230 .type = REGULATOR_VOLTAGE, \
231 .owner = THIS_MODULE, \
232 }, \
233}
234
235static struct ricoh583_regulator ricoh583_regulator[] = {
236 RICOH583_REG(DC0, 0x30, 0, 0x30, 1, 0x31, 0x7F, 0x60,
237 700, 1500, 12500, 0x41, ricoh583_ops, 500),
238 RICOH583_REG(DC1, 0x34, 0, 0x34, 1, 0x35, 0x7F, 0x61,
239 700, 1500, 12500, 0x41, ricoh583_ops, 500),
240 RICOH583_REG(DC2, 0x38, 0, 0x38, 1, 0x39, 0x7F, 0x62,
241 900, 2400, 12500, 0x79, ricoh583_ops, 500),
242 RICOH583_REG(DC3, 0x3C, 0, 0x3C, 1, 0x3D, 0x7F, 0x63,
243 900, 2400, 12500, 0x79, ricoh583_ops, 500),
244 RICOH583_REG(LDO0, 0x51, 0, 0x53, 0, 0x54, 0x7F, 0x64,
245 900, 3400, 25000, 0x65, ricoh583_ops, 500),
246 RICOH583_REG(LDO1, 0x51, 1, 0x53, 1, 0x55, 0x7F, 0x65,
247 900, 3400, 25000, 0x65, ricoh583_ops, 500),
248 RICOH583_REG(LDO2, 0x51, 2, 0x53, 2, 0x56, 0x7F, 0x66,
249 900, 3400, 25000, 0x65, ricoh583_ops, 500),
250 RICOH583_REG(LDO3, 0x51, 3, 0x53, 3, 0x57, 0x7F, 0x67,
251 900, 3400, 25000, 0x65, ricoh583_ops, 500),
252 RICOH583_REG(LDO4, 0x51, 4, 0x53, 4, 0x58, 0x3F, 0x68,
253 750, 1500, 12500, 0x3D, ricoh583_ops, 500),
254 RICOH583_REG(LDO5, 0x51, 5, 0x53, 5, 0x59, 0x7F, 0x69,
255 900, 3400, 25000, 0x65, ricoh583_ops, 500),
256 RICOH583_REG(LDO6, 0x51, 6, 0x53, 6, 0x5A, 0x7F, 0x6A,
257 900, 3400, 25000, 0x65, ricoh583_ops, 500),
258 RICOH583_REG(LDO7, 0x51, 7, 0x53, 7, 0x5B, 0x7F, 0x6B,
259 900, 3400, 25000, 0x65, ricoh583_ops, 500),
260 RICOH583_REG(LDO8, 0x50, 0, 0x52, 0, 0x5C, 0x7F, 0x6C,
261 900, 3400, 25000, 0x65, ricoh583_ops, 500),
262 RICOH583_REG(LDO9, 0x50, 1, 0x52, 1, 0x5D, 0x7F, 0x6D,
263 900, 3400, 25000, 0x65, ricoh583_ops, 500),
264};
265static inline struct ricoh583_regulator *find_regulator_info(int id)
266{
267 struct ricoh583_regulator *ri;
268 int i;
269
270 for (i = 0; i < ARRAY_SIZE(ricoh583_regulator); i++) {
271 ri = &ricoh583_regulator[i];
272 if (ri->desc.id == id)
273 return ri;
274 }
275 return NULL;
276}
277
278static int ricoh583_regulator_preinit(struct device *parent,
279 struct ricoh583_regulator *ri,
280 struct ricoh583_regulator_platform_data *ricoh583_pdata)
281{
282 int ret = 0;
283
284 if (ri->deepsleep_id != RICOH583_DS_NONE) {
285 ret = ricoh583_ext_power_req_config(parent, ri->deepsleep_id,
286 ricoh583_pdata->ext_pwr_req,
287 ricoh583_pdata->deepsleep_slots);
288 if (ret < 0)
289 return ret;
290 }
291
292 if (!ricoh583_pdata->init_apply)
293 return 0;
294
295 if (ricoh583_pdata->deepsleep_uV) {
296 ret = __ricoh583_set_ds_voltage(parent, ri,
297 ricoh583_pdata->deepsleep_uV,
298 ricoh583_pdata->deepsleep_uV);
299 if (ret < 0) {
300 dev_err(ri->dev, "Not able to initialize ds voltage %d"
301 " for rail %d err %d\n",
302 ricoh583_pdata->deepsleep_uV, ri->desc.id, ret);
303 return ret;
304 }
305 }
306
307 if (ricoh583_pdata->init_uV >= 0) {
308 ret = __ricoh583_set_voltage(parent, ri,
309 ricoh583_pdata->init_uV,
310 ricoh583_pdata->init_uV, 0);
311 if (ret < 0) {
312 dev_err(ri->dev, "Not able to initialize voltage %d "
313 "for rail %d err %d\n", ricoh583_pdata->init_uV,
314 ri->desc.id, ret);
315 return ret;
316 }
317 }
318
319 if (ricoh583_pdata->init_enable)
320 ret = ricoh583_set_bits(parent, ri->reg_en_reg,
321 (1 << ri->en_bit));
322 else
323 ret = ricoh583_clr_bits(parent, ri->reg_en_reg,
324 (1 << ri->en_bit));
325 if (ret < 0)
326 dev_err(ri->dev, "Not able to %s rail %d err %d\n",
327 (ricoh583_pdata->init_enable) ? "enable" : "disable",
328 ri->desc.id, ret);
329
330 return ret;
331}
332
333static inline int ricoh583_cache_regulator_register(struct device *parent,
334 struct ricoh583_regulator *ri)
335{
336 ri->vout_reg_cache = 0;
337 return ricoh583_read(parent, ri->vout_reg, &ri->vout_reg_cache);
338}
339
340static int __devinit ricoh583_regulator_probe(struct platform_device *pdev)
341{
342 struct ricoh583_regulator *ri = NULL;
343 struct regulator_dev *rdev;
344 struct ricoh583_regulator_platform_data *tps_pdata;
345 int id = pdev->id;
346 int err;
347
348 dev_dbg(&pdev->dev, "Probing reulator %d\n", id);
349
350 ri = find_regulator_info(id);
351 if (ri == NULL) {
352 dev_err(&pdev->dev, "invalid regulator ID specified\n");
353 return -EINVAL;
354 }
355 tps_pdata = pdev->dev.platform_data;
356 ri->dev = &pdev->dev;
357
358 err = ricoh583_cache_regulator_register(pdev->dev.parent, ri);
359 if (err) {
360 dev_err(&pdev->dev, "Fail in caching register\n");
361 return err;
362 }
363
364 err = ricoh583_regulator_preinit(pdev->dev.parent, ri, tps_pdata);
365 if (err) {
366 dev_err(&pdev->dev, "Fail in pre-initialisation\n");
367 return err;
368 }
369 rdev = regulator_register(&ri->desc, &pdev->dev,
370 &tps_pdata->regulator, ri);
371 if (IS_ERR_OR_NULL(rdev)) {
372 dev_err(&pdev->dev, "failed to register regulator %s\n",
373 ri->desc.name);
374 return PTR_ERR(rdev);
375 }
376
377 platform_set_drvdata(pdev, rdev);
378 return 0;
379}
380
381static int __devexit ricoh583_regulator_remove(struct platform_device *pdev)
382{
383 struct regulator_dev *rdev = platform_get_drvdata(pdev);
384
385 regulator_unregister(rdev);
386 return 0;
387}
388
389static struct platform_driver ricoh583_regulator_driver = {
390 .driver = {
391 .name = "ricoh583-regulator",
392 .owner = THIS_MODULE,
393 },
394 .probe = ricoh583_regulator_probe,
395 .remove = __devexit_p(ricoh583_regulator_remove),
396};
397
398static int __init ricoh583_regulator_init(void)
399{
400 return platform_driver_register(&ricoh583_regulator_driver);
401}
402subsys_initcall(ricoh583_regulator_init);
403
404static void __exit ricoh583_regulator_exit(void)
405{
406 platform_driver_unregister(&ricoh583_regulator_driver);
407}
408module_exit(ricoh583_regulator_exit);
409
410MODULE_DESCRIPTION("RICOH583 regulator driver");
411MODULE_ALIAS("platform:ricoh583-regulator");
412MODULE_LICENSE("GPL");