blob: 3465ac38bffede62ba5a76dfc84ef900337ba7d1 [file] [log] [blame]
Sundar R IYERc789ca22010-07-13 21:48:56 +05301/*
2 * Copyright (C) ST-Ericsson SA 2010
3 *
4 * License Terms: GNU General Public License v2
5 *
Bengt Jonssone1159e62010-12-10 11:08:44 +01006 * Authors: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
7 * Bengt Jonsson <bengt.g.jonsson@stericsson.com> for ST-Ericsson
Sundar R IYERc789ca22010-07-13 21:48:56 +05308 *
9 * AB8500 peripheral regulators
10 *
Bengt Jonssone1159e62010-12-10 11:08:44 +010011 * AB8500 supports the following regulators:
Bengt Jonssonea05ef32011-03-10 14:43:31 +010012 * VAUX1/2/3, VINTCORE, VTVOUT, VUSB, VAUDIO, VAMIC1/2, VDMIC, VANA
Sundar R IYERc789ca22010-07-13 21:48:56 +053013 */
14#include <linux/init.h>
15#include <linux/kernel.h>
Paul Gortmaker65602c32011-07-17 16:28:23 -040016#include <linux/module.h>
Sundar R IYERc789ca22010-07-13 21:48:56 +053017#include <linux/err.h>
18#include <linux/platform_device.h>
Mattias Wallin47c16972010-09-10 17:47:56 +020019#include <linux/mfd/abx500.h>
Linus Walleijee66e652011-12-02 14:16:33 +010020#include <linux/mfd/abx500/ab8500.h>
Lee Jones3a8334b2012-05-17 14:45:16 +010021#include <linux/of.h>
22#include <linux/regulator/of_regulator.h>
Sundar R IYERc789ca22010-07-13 21:48:56 +053023#include <linux/regulator/driver.h>
24#include <linux/regulator/machine.h>
25#include <linux/regulator/ab8500.h>
Lee Jones3a8334b2012-05-17 14:45:16 +010026#include <linux/slab.h>
Sundar R IYERc789ca22010-07-13 21:48:56 +053027
28/**
29 * struct ab8500_regulator_info - ab8500 regulator information
Bengt Jonssone1159e62010-12-10 11:08:44 +010030 * @dev: device pointer
Sundar R IYERc789ca22010-07-13 21:48:56 +053031 * @desc: regulator description
Sundar R IYERc789ca22010-07-13 21:48:56 +053032 * @regulator_dev: regulator device
Emeric Vigierbd28a152013-03-21 15:58:59 +000033 * @is_enabled: status of regulator (on/off)
Bengt Jonsson7ce46692013-03-21 15:59:00 +000034 * @load_lp_uA: maximum load in idle (low power) mode
Mattias Wallin47c16972010-09-10 17:47:56 +020035 * @update_bank: bank to control on/off
Sundar R IYERc789ca22010-07-13 21:48:56 +053036 * @update_reg: register to control on/off
Emeric Vigierbd28a152013-03-21 15:58:59 +000037 * @update_mask: mask to enable/disable and set mode of regulator
38 * @update_val: bits holding the regulator current mode
39 * @update_val_idle: bits to enable the regulator in idle (low power) mode
40 * @update_val_normal: bits to enable the regulator in normal (high power) mode
Mattias Wallin47c16972010-09-10 17:47:56 +020041 * @voltage_bank: bank to control regulator voltage
Sundar R IYERc789ca22010-07-13 21:48:56 +053042 * @voltage_reg: register to control regulator voltage
43 * @voltage_mask: mask to control regulator voltage
Linus Walleija0a70142012-08-20 18:41:35 +020044 * @voltage_shift: shift to control regulator voltage
Linus Walleij42ab6162011-03-17 13:25:02 +010045 * @delay: startup/set voltage delay in us
Sundar R IYERc789ca22010-07-13 21:48:56 +053046 */
47struct ab8500_regulator_info {
48 struct device *dev;
49 struct regulator_desc desc;
Sundar R IYERc789ca22010-07-13 21:48:56 +053050 struct regulator_dev *regulator;
Emeric Vigierbd28a152013-03-21 15:58:59 +000051 bool is_enabled;
Bengt Jonsson7ce46692013-03-21 15:59:00 +000052 int load_lp_uA;
Mattias Wallin47c16972010-09-10 17:47:56 +020053 u8 update_bank;
54 u8 update_reg;
Bengt Jonssone1159e62010-12-10 11:08:44 +010055 u8 update_mask;
Emeric Vigierbd28a152013-03-21 15:58:59 +000056 u8 update_val;
57 u8 update_val_idle;
58 u8 update_val_normal;
Mattias Wallin47c16972010-09-10 17:47:56 +020059 u8 voltage_bank;
60 u8 voltage_reg;
61 u8 voltage_mask;
Linus Walleija0a70142012-08-20 18:41:35 +020062 u8 voltage_shift;
Linus Walleij42ab6162011-03-17 13:25:02 +010063 unsigned int delay;
Sundar R IYERc789ca22010-07-13 21:48:56 +053064};
65
66/* voltage tables for the vauxn/vintcore supplies */
Axel Linec1cc4d2012-05-20 10:33:35 +080067static const unsigned int ldo_vauxn_voltages[] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +053068 1100000,
69 1200000,
70 1300000,
71 1400000,
72 1500000,
73 1800000,
74 1850000,
75 1900000,
76 2500000,
77 2650000,
78 2700000,
79 2750000,
80 2800000,
81 2900000,
82 3000000,
83 3300000,
84};
85
Axel Linec1cc4d2012-05-20 10:33:35 +080086static const unsigned int ldo_vaux3_voltages[] = {
Bengt Jonsson2b751512010-12-10 11:08:43 +010087 1200000,
88 1500000,
89 1800000,
90 2100000,
91 2500000,
92 2750000,
93 2790000,
94 2910000,
95};
96
Axel Linec1cc4d2012-05-20 10:33:35 +080097static const unsigned int ldo_vintcore_voltages[] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +053098 1200000,
99 1225000,
100 1250000,
101 1275000,
102 1300000,
103 1325000,
104 1350000,
105};
106
107static int ab8500_regulator_enable(struct regulator_dev *rdev)
108{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100109 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530110 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
111
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100112 if (info == NULL) {
113 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530114 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100115 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530116
Mattias Wallin47c16972010-09-10 17:47:56 +0200117 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonssone1159e62010-12-10 11:08:44 +0100118 info->update_bank, info->update_reg,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000119 info->update_mask, info->update_val);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530120 if (ret < 0)
121 dev_err(rdev_get_dev(rdev),
122 "couldn't set enable bits for regulator\n");
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100123
Emeric Vigierbd28a152013-03-21 15:58:59 +0000124 info->is_enabled = true;
125
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100126 dev_vdbg(rdev_get_dev(rdev),
127 "%s-enable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
128 info->desc.name, info->update_bank, info->update_reg,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000129 info->update_mask, info->update_val);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100130
Sundar R IYERc789ca22010-07-13 21:48:56 +0530131 return ret;
132}
133
134static int ab8500_regulator_disable(struct regulator_dev *rdev)
135{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100136 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530137 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
138
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100139 if (info == NULL) {
140 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530141 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100142 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530143
Mattias Wallin47c16972010-09-10 17:47:56 +0200144 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonssone1159e62010-12-10 11:08:44 +0100145 info->update_bank, info->update_reg,
146 info->update_mask, 0x0);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530147 if (ret < 0)
148 dev_err(rdev_get_dev(rdev),
149 "couldn't set disable bits for regulator\n");
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100150
Emeric Vigierbd28a152013-03-21 15:58:59 +0000151 info->is_enabled = false;
152
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100153 dev_vdbg(rdev_get_dev(rdev),
154 "%s-disable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
155 info->desc.name, info->update_bank, info->update_reg,
156 info->update_mask, 0x0);
157
Sundar R IYERc789ca22010-07-13 21:48:56 +0530158 return ret;
159}
160
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000161static unsigned int ab8500_regulator_get_optimum_mode(
162 struct regulator_dev *rdev, int input_uV,
163 int output_uV, int load_uA)
164{
165 unsigned int mode;
166
167 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
168
169 if (info == NULL) {
170 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
171 return -EINVAL;
172 }
173
174 if (load_uA <= info->load_lp_uA)
175 mode = REGULATOR_MODE_IDLE;
176 else
177 mode = REGULATOR_MODE_NORMAL;
178
179 return mode;
180}
181
Emeric Vigierbd28a152013-03-21 15:58:59 +0000182static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
183 unsigned int mode)
184{
185 int ret = 0;
186
187 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
188
189 if (info == NULL) {
190 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
191 return -EINVAL;
192 }
193
194 switch (mode) {
195 case REGULATOR_MODE_NORMAL:
196 info->update_val = info->update_val_normal;
197 break;
198 case REGULATOR_MODE_IDLE:
199 info->update_val = info->update_val_idle;
200 break;
201 default:
202 return -EINVAL;
203 }
204
205 if (info->is_enabled) {
206 ret = abx500_mask_and_set_register_interruptible(info->dev,
207 info->update_bank, info->update_reg,
208 info->update_mask, info->update_val);
209 if (ret < 0)
210 dev_err(rdev_get_dev(rdev),
211 "couldn't set regulator mode\n");
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000212
213 dev_vdbg(rdev_get_dev(rdev),
214 "%s-set_mode (bank, reg, mask, value): "
215 "0x%x, 0x%x, 0x%x, 0x%x\n",
216 info->desc.name, info->update_bank, info->update_reg,
217 info->update_mask, info->update_val);
Emeric Vigierbd28a152013-03-21 15:58:59 +0000218 }
219
220 return ret;
221}
222
223static unsigned int ab8500_regulator_get_mode(struct regulator_dev *rdev)
224{
225 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
226 int ret;
227
228 if (info == NULL) {
229 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
230 return -EINVAL;
231 }
232
233 if (info->update_val == info->update_val_normal)
234 ret = REGULATOR_MODE_NORMAL;
235 else if (info->update_val == info->update_val_idle)
236 ret = REGULATOR_MODE_IDLE;
237 else
238 ret = -EINVAL;
239
240 return ret;
241}
242
Sundar R IYERc789ca22010-07-13 21:48:56 +0530243static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
244{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100245 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530246 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100247 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530248
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100249 if (info == NULL) {
250 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530251 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100252 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530253
Mattias Wallin47c16972010-09-10 17:47:56 +0200254 ret = abx500_get_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100255 info->update_bank, info->update_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530256 if (ret < 0) {
257 dev_err(rdev_get_dev(rdev),
258 "couldn't read 0x%x register\n", info->update_reg);
259 return ret;
260 }
261
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100262 dev_vdbg(rdev_get_dev(rdev),
263 "%s-is_enabled (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
264 " 0x%x\n",
265 info->desc.name, info->update_bank, info->update_reg,
266 info->update_mask, regval);
267
268 if (regval & info->update_mask)
Emeric Vigierbd28a152013-03-21 15:58:59 +0000269 info->is_enabled = true;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530270 else
Emeric Vigierbd28a152013-03-21 15:58:59 +0000271 info->is_enabled = false;
272
273 return info->is_enabled;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530274}
275
Axel Lin3bf6e902012-02-24 17:15:45 +0800276static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530277{
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100278 int ret, val;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530279 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100280 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530281
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100282 if (info == NULL) {
283 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530284 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100285 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530286
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100287 ret = abx500_get_register_interruptible(info->dev,
288 info->voltage_bank, info->voltage_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530289 if (ret < 0) {
290 dev_err(rdev_get_dev(rdev),
291 "couldn't read voltage reg for regulator\n");
292 return ret;
293 }
294
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100295 dev_vdbg(rdev_get_dev(rdev),
Linus Walleija0a70142012-08-20 18:41:35 +0200296 "%s-get_voltage (bank, reg, mask, shift, value): "
297 "0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
298 info->desc.name, info->voltage_bank,
299 info->voltage_reg, info->voltage_mask,
300 info->voltage_shift, regval);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100301
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100302 val = regval & info->voltage_mask;
Linus Walleija0a70142012-08-20 18:41:35 +0200303 return val >> info->voltage_shift;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530304}
305
Axel Linae713d32012-03-20 09:51:08 +0800306static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
307 unsigned selector)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530308{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100309 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530310 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100311 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530312
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100313 if (info == NULL) {
314 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530315 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100316 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530317
Sundar R IYERc789ca22010-07-13 21:48:56 +0530318 /* set the registers for the request */
Linus Walleija0a70142012-08-20 18:41:35 +0200319 regval = (u8)selector << info->voltage_shift;
Mattias Wallin47c16972010-09-10 17:47:56 +0200320 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100321 info->voltage_bank, info->voltage_reg,
322 info->voltage_mask, regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530323 if (ret < 0)
324 dev_err(rdev_get_dev(rdev),
325 "couldn't set voltage reg for regulator\n");
326
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100327 dev_vdbg(rdev_get_dev(rdev),
328 "%s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
329 " 0x%x\n",
330 info->desc.name, info->voltage_bank, info->voltage_reg,
331 info->voltage_mask, regval);
332
Sundar R IYERc789ca22010-07-13 21:48:56 +0530333 return ret;
334}
335
Linus Walleij42ab6162011-03-17 13:25:02 +0100336static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
337 unsigned int old_sel,
338 unsigned int new_sel)
339{
340 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Linus Walleij42ab6162011-03-17 13:25:02 +0100341
Linus Walleij42ab6162011-03-17 13:25:02 +0100342 return info->delay;
343}
344
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000345static struct regulator_ops ab8500_regulator_volt_mode_ops = {
346 .enable = ab8500_regulator_enable,
347 .disable = ab8500_regulator_disable,
348 .is_enabled = ab8500_regulator_is_enabled,
349 .get_optimum_mode = ab8500_regulator_get_optimum_mode,
350 .set_mode = ab8500_regulator_set_mode,
351 .get_mode = ab8500_regulator_get_mode,
352 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
353 .set_voltage_sel = ab8500_regulator_set_voltage_sel,
354 .list_voltage = regulator_list_voltage_table,
355 .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530356};
357
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000358static struct regulator_ops ab8500_regulator_mode_ops = {
359 .enable = ab8500_regulator_enable,
360 .disable = ab8500_regulator_disable,
361 .is_enabled = ab8500_regulator_is_enabled,
362 .get_optimum_mode = ab8500_regulator_get_optimum_mode,
363 .set_mode = ab8500_regulator_set_mode,
364 .get_mode = ab8500_regulator_get_mode,
365 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
366 .list_voltage = regulator_list_voltage_table,
367 .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
368};
369
370static struct regulator_ops ab8500_regulator_ops = {
371 .enable = ab8500_regulator_enable,
372 .disable = ab8500_regulator_disable,
373 .is_enabled = ab8500_regulator_is_enabled,
374 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
375 .list_voltage = regulator_list_voltage_table,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530376};
377
Bengt Jonsson6909b452010-12-10 11:08:47 +0100378static struct ab8500_regulator_info
379 ab8500_regulator_info[AB8500_NUM_REGULATORS] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530380 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100381 * Variable Voltage Regulators
382 * name, min mV, max mV,
383 * update bank, reg, mask, enable val
Axel Linec1cc4d2012-05-20 10:33:35 +0800384 * volt bank, reg, mask
Sundar R IYERc789ca22010-07-13 21:48:56 +0530385 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100386 [AB8500_LDO_AUX1] = {
387 .desc = {
388 .name = "LDO-AUX1",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000389 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100390 .type = REGULATOR_VOLTAGE,
391 .id = AB8500_LDO_AUX1,
392 .owner = THIS_MODULE,
393 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800394 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100395 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000396 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100397 .update_bank = 0x04,
398 .update_reg = 0x09,
399 .update_mask = 0x03,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000400 .update_val = 0x01,
401 .update_val_idle = 0x03,
402 .update_val_normal = 0x01,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100403 .voltage_bank = 0x04,
404 .voltage_reg = 0x1f,
405 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100406 },
407 [AB8500_LDO_AUX2] = {
408 .desc = {
409 .name = "LDO-AUX2",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000410 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100411 .type = REGULATOR_VOLTAGE,
412 .id = AB8500_LDO_AUX2,
413 .owner = THIS_MODULE,
414 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800415 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100416 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000417 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100418 .update_bank = 0x04,
419 .update_reg = 0x09,
420 .update_mask = 0x0c,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000421 .update_val = 0x04,
422 .update_val_idle = 0x0c,
423 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100424 .voltage_bank = 0x04,
425 .voltage_reg = 0x20,
426 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100427 },
428 [AB8500_LDO_AUX3] = {
429 .desc = {
430 .name = "LDO-AUX3",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000431 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100432 .type = REGULATOR_VOLTAGE,
433 .id = AB8500_LDO_AUX3,
434 .owner = THIS_MODULE,
435 .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800436 .volt_table = ldo_vaux3_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100437 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000438 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100439 .update_bank = 0x04,
440 .update_reg = 0x0a,
441 .update_mask = 0x03,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000442 .update_val = 0x01,
443 .update_val_idle = 0x03,
444 .update_val_normal = 0x01,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100445 .voltage_bank = 0x04,
446 .voltage_reg = 0x21,
447 .voltage_mask = 0x07,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100448 },
449 [AB8500_LDO_INTCORE] = {
450 .desc = {
451 .name = "LDO-INTCORE",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000452 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100453 .type = REGULATOR_VOLTAGE,
454 .id = AB8500_LDO_INTCORE,
455 .owner = THIS_MODULE,
456 .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800457 .volt_table = ldo_vintcore_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100458 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000459 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100460 .update_bank = 0x03,
461 .update_reg = 0x80,
462 .update_mask = 0x44,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000463 .update_val = 0x04,
464 .update_val_idle = 0x44,
465 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100466 .voltage_bank = 0x03,
467 .voltage_reg = 0x80,
468 .voltage_mask = 0x38,
Linus Walleija0a70142012-08-20 18:41:35 +0200469 .voltage_shift = 3,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100470 },
Sundar R IYERc789ca22010-07-13 21:48:56 +0530471
472 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100473 * Fixed Voltage Regulators
474 * name, fixed mV,
475 * update bank, reg, mask, enable val
Sundar R IYERc789ca22010-07-13 21:48:56 +0530476 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100477 [AB8500_LDO_TVOUT] = {
478 .desc = {
479 .name = "LDO-TVOUT",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000480 .ops = &ab8500_regulator_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100481 .type = REGULATOR_VOLTAGE,
482 .id = AB8500_LDO_TVOUT,
483 .owner = THIS_MODULE,
484 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800485 .min_uV = 2000000,
Axel Lin7fee2af2012-08-07 22:21:23 +0800486 .enable_time = 10000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100487 },
Linus Walleij42ab6162011-03-17 13:25:02 +0100488 .delay = 10000,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000489 .load_lp_uA = 1000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100490 .update_bank = 0x03,
491 .update_reg = 0x80,
492 .update_mask = 0x82,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000493 .update_val = 0x02,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000494 .update_val_idle = 0x82,
495 .update_val_normal = 0x02,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100496 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100497 [AB8500_LDO_USB] = {
498 .desc = {
499 .name = "LDO-USB",
500 .ops = &ab8500_regulator_fixed_ops,
501 .type = REGULATOR_VOLTAGE,
502 .id = AB8500_LDO_USB,
503 .owner = THIS_MODULE,
504 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800505 .min_uV = 3300000,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100506 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100507 .update_bank = 0x03,
508 .update_reg = 0x82,
509 .update_mask = 0x03,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100510 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000511
512 /*
513 * Regulators with fixed voltage and normal mode
514 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100515 [AB8500_LDO_AUDIO] = {
516 .desc = {
517 .name = "LDO-AUDIO",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000518 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100519 .type = REGULATOR_VOLTAGE,
520 .id = AB8500_LDO_AUDIO,
521 .owner = THIS_MODULE,
522 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800523 .min_uV = 2000000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100524 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100525 .update_bank = 0x03,
526 .update_reg = 0x83,
527 .update_mask = 0x02,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000528 .update_val = 0x02,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100529 },
530 [AB8500_LDO_ANAMIC1] = {
531 .desc = {
532 .name = "LDO-ANAMIC1",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000533 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100534 .type = REGULATOR_VOLTAGE,
535 .id = AB8500_LDO_ANAMIC1,
536 .owner = THIS_MODULE,
537 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800538 .min_uV = 2050000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100539 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100540 .update_bank = 0x03,
541 .update_reg = 0x83,
542 .update_mask = 0x08,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000543 .update_val = 0x08,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100544 },
545 [AB8500_LDO_ANAMIC2] = {
546 .desc = {
547 .name = "LDO-ANAMIC2",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000548 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100549 .type = REGULATOR_VOLTAGE,
550 .id = AB8500_LDO_ANAMIC2,
551 .owner = THIS_MODULE,
552 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800553 .min_uV = 2050000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100554 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100555 .update_bank = 0x03,
556 .update_reg = 0x83,
557 .update_mask = 0x10,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000558 .update_val = 0x10,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100559 },
560 [AB8500_LDO_DMIC] = {
561 .desc = {
562 .name = "LDO-DMIC",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000563 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100564 .type = REGULATOR_VOLTAGE,
565 .id = AB8500_LDO_DMIC,
566 .owner = THIS_MODULE,
567 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800568 .min_uV = 1800000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100569 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100570 .update_bank = 0x03,
571 .update_reg = 0x83,
572 .update_mask = 0x04,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000573 .update_val = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100574 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000575
576 /*
577 * Regulators with fixed voltage and normal/idle modes
578 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100579 [AB8500_LDO_ANA] = {
580 .desc = {
581 .name = "LDO-ANA",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000582 .ops = &ab8500_regulator_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100583 .type = REGULATOR_VOLTAGE,
584 .id = AB8500_LDO_ANA,
585 .owner = THIS_MODULE,
586 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800587 .min_uV = 1200000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100588 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000589 .load_lp_uA = 1000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100590 .update_bank = 0x04,
591 .update_reg = 0x06,
592 .update_mask = 0x0c,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000593 .update_val = 0x04,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000594 .update_val_idle = 0x0c,
595 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100596 },
597
598
Sundar R IYERc789ca22010-07-13 21:48:56 +0530599};
600
Bengt Jonsson79568b942011-03-11 11:54:46 +0100601struct ab8500_reg_init {
602 u8 bank;
603 u8 addr;
604 u8 mask;
605};
606
607#define REG_INIT(_id, _bank, _addr, _mask) \
608 [_id] = { \
609 .bank = _bank, \
610 .addr = _addr, \
611 .mask = _mask, \
612 }
613
614static struct ab8500_reg_init ab8500_reg_init[] = {
615 /*
616 * 0x30, VanaRequestCtrl
Lee Jonesd79df322013-03-21 15:58:58 +0000617 * 0x0c, VpllRequestCtrl
Bengt Jonsson79568b942011-03-11 11:54:46 +0100618 * 0xc0, VextSupply1RequestCtrl
619 */
620 REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xfc),
621 /*
622 * 0x03, VextSupply2RequestCtrl
623 * 0x0c, VextSupply3RequestCtrl
624 * 0x30, Vaux1RequestCtrl
625 * 0xc0, Vaux2RequestCtrl
626 */
627 REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
628 /*
629 * 0x03, Vaux3RequestCtrl
630 * 0x04, SwHPReq
631 */
632 REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
633 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000634 * 0x01, Vsmps1SysClkReq1HPValid
635 * 0x02, Vsmps2SysClkReq1HPValid
636 * 0x04, Vsmps3SysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100637 * 0x08, VanaSysClkReq1HPValid
Lee Jonesd79df322013-03-21 15:58:58 +0000638 * 0x10, VpllSysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100639 * 0x20, Vaux1SysClkReq1HPValid
640 * 0x40, Vaux2SysClkReq1HPValid
641 * 0x80, Vaux3SysClkReq1HPValid
642 */
Lee Jonesd79df322013-03-21 15:58:58 +0000643 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100644 /*
645 * 0x10, VextSupply1SysClkReq1HPValid
646 * 0x20, VextSupply2SysClkReq1HPValid
647 * 0x40, VextSupply3SysClkReq1HPValid
648 */
649 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70),
650 /*
651 * 0x08, VanaHwHPReq1Valid
652 * 0x20, Vaux1HwHPReq1Valid
653 * 0x40, Vaux2HwHPReq1Valid
654 * 0x80, Vaux3HwHPReq1Valid
655 */
656 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8),
657 /*
658 * 0x01, VextSupply1HwHPReq1Valid
659 * 0x02, VextSupply2HwHPReq1Valid
660 * 0x04, VextSupply3HwHPReq1Valid
661 */
662 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07),
663 /*
664 * 0x08, VanaHwHPReq2Valid
665 * 0x20, Vaux1HwHPReq2Valid
666 * 0x40, Vaux2HwHPReq2Valid
667 * 0x80, Vaux3HwHPReq2Valid
668 */
669 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8),
670 /*
671 * 0x01, VextSupply1HwHPReq2Valid
672 * 0x02, VextSupply2HwHPReq2Valid
673 * 0x04, VextSupply3HwHPReq2Valid
674 */
675 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07),
676 /*
677 * 0x20, VanaSwHPReqValid
678 * 0x80, Vaux1SwHPReqValid
679 */
680 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0),
681 /*
682 * 0x01, Vaux2SwHPReqValid
683 * 0x02, Vaux3SwHPReqValid
684 * 0x04, VextSupply1SwHPReqValid
685 * 0x08, VextSupply2SwHPReqValid
686 * 0x10, VextSupply3SwHPReqValid
687 */
688 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f),
689 /*
690 * 0x02, SysClkReq2Valid1
691 * ...
692 * 0x80, SysClkReq8Valid1
693 */
694 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
695 /*
696 * 0x02, SysClkReq2Valid2
697 * ...
698 * 0x80, SysClkReq8Valid2
699 */
700 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
701 /*
702 * 0x02, VTVoutEna
703 * 0x04, Vintcore12Ena
704 * 0x38, Vintcore12Sel
705 * 0x40, Vintcore12LP
706 * 0x80, VTVoutLP
707 */
708 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
709 /*
710 * 0x02, VaudioEna
711 * 0x04, VdmicEna
712 * 0x08, Vamic1Ena
713 * 0x10, Vamic2Ena
714 */
715 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
716 /*
717 * 0x01, Vamic1_dzout
718 * 0x02, Vamic2_dzout
719 */
720 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
721 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000722 * 0x0c, VBBNRegu
723 * 0x03, VBBPRegu
724 * NOTE! PRCMU register
725 */
726 REG_INIT(AB8500_ARMREGU2, 0x04, 0x01, 0x0f),
727 /*
728 * 0x0c, VBBPSel1
729 * 0x03, VBBNSel1
730 * NOTE! PRCMU register
731 */
732 REG_INIT(AB8500_VBBSEL1, 0x04, 0x11, 0x0f),
733 /*
734 * 0x0c, VBBNSel2
735 * 0x03, VBBPSel2
736 * NOTE! PRCMU register
737 */
738 REG_INIT(AB8500_VBBSEL2, 0x04, 0x12, 0x0f),
739 /*
740 * 0x03, Vsmps1Regu
741 * 0x0c, Vsmps1SelCtrl
742 */
743 REG_INIT(AB8500_VSMPS1REGU, 0x04, 0x03, 0x0f),
744 /*
745 * 0x03, Vsmps2Regu
746 * 0x0c, Vsmps2SelCtrl
747 */
748 REG_INIT(AB8500_VSMPS2REGU, 0x04, 0x04, 0x0f),
749 /*
Bengt Jonsson79568b942011-03-11 11:54:46 +0100750 * 0x0c, VanaRegu
751 * 0x03, VpllRegu
752 */
753 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
754 /*
755 * 0x01, VrefDDREna
756 * 0x02, VrefDDRSleepMode
757 */
758 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
759 /*
760 * 0x03, VextSupply1Regu
761 * 0x0c, VextSupply2Regu
762 * 0x30, VextSupply3Regu
763 * 0x40, ExtSupply2Bypass
764 * 0x80, ExtSupply3Bypass
765 */
766 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
767 /*
768 * 0x03, Vaux1Regu
769 * 0x0c, Vaux2Regu
770 */
771 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
772 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000773 * 0x0c, Vrf1Regu
Bengt Jonsson79568b942011-03-11 11:54:46 +0100774 * 0x03, Vaux3Regu
775 */
Lee Jonesd79df322013-03-21 15:58:58 +0000776 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x0f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100777 /*
778 * 0x3f, Vsmps1Sel1
779 */
780 REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f),
781 /*
782 * 0x0f, Vaux1Sel
783 */
784 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
785 /*
786 * 0x0f, Vaux2Sel
787 */
788 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
789 /*
790 * 0x07, Vaux3Sel
791 */
792 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07),
793 /*
794 * 0x01, VextSupply12LP
795 */
796 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
797 /*
798 * 0x04, Vaux1Disch
799 * 0x08, Vaux2Disch
800 * 0x10, Vaux3Disch
801 * 0x20, Vintcore12Disch
802 * 0x40, VTVoutDisch
803 * 0x80, VaudioDisch
804 */
805 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc),
806 /*
807 * 0x02, VanaDisch
808 * 0x04, VdmicPullDownEna
809 * 0x10, VdmicDisch
810 */
811 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16),
812};
813
Bill Pembertona5023572012-11-19 13:22:22 -0500814static int
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100815ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value)
816{
817 int err;
818
819 if (value & ~ab8500_reg_init[id].mask) {
820 dev_err(&pdev->dev,
821 "Configuration error: value outside mask.\n");
822 return -EINVAL;
823 }
824
825 err = abx500_mask_and_set_register_interruptible(
826 &pdev->dev,
827 ab8500_reg_init[id].bank,
828 ab8500_reg_init[id].addr,
829 ab8500_reg_init[id].mask,
830 value);
831 if (err < 0) {
832 dev_err(&pdev->dev,
833 "Failed to initialize 0x%02x, 0x%02x.\n",
834 ab8500_reg_init[id].bank,
835 ab8500_reg_init[id].addr);
836 return err;
837 }
838
839 dev_vdbg(&pdev->dev,
840 "init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
841 ab8500_reg_init[id].bank,
842 ab8500_reg_init[id].addr,
843 ab8500_reg_init[id].mask,
844 value);
845
846 return 0;
847}
848
Bill Pembertona5023572012-11-19 13:22:22 -0500849static int ab8500_regulator_register(struct platform_device *pdev,
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100850 struct regulator_init_data *init_data,
851 int id,
852 struct device_node *np)
853{
854 struct ab8500_regulator_info *info = NULL;
855 struct regulator_config config = { };
856 int err;
857
858 /* assign per-regulator data */
859 info = &ab8500_regulator_info[id];
860 info->dev = &pdev->dev;
861
862 config.dev = &pdev->dev;
863 config.init_data = init_data;
864 config.driver_data = info;
865 config.of_node = np;
866
867 /* fix for hardware before ab8500v2.0 */
868 if (abx500_get_chip_id(info->dev) < 0x20) {
869 if (info->desc.id == AB8500_LDO_AUX3) {
870 info->desc.n_voltages =
871 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800872 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100873 info->voltage_mask = 0xf;
874 }
875 }
876
877 /* register regulator with framework */
878 info->regulator = regulator_register(&info->desc, &config);
879 if (IS_ERR(info->regulator)) {
880 err = PTR_ERR(info->regulator);
881 dev_err(&pdev->dev, "failed to register regulator %s\n",
882 info->desc.name);
883 /* when we fail, un-register all earlier regulators */
884 while (--id >= 0) {
885 info = &ab8500_regulator_info[id];
886 regulator_unregister(info->regulator);
887 }
888 return err;
889 }
890
891 return 0;
892}
893
Lee Jones3a8334b2012-05-17 14:45:16 +0100894static struct of_regulator_match ab8500_regulator_matches[] = {
Lee Jones7e715b92012-05-30 12:47:26 +0800895 { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, },
896 { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, },
897 { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, },
898 { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
899 { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, },
900 { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, },
901 { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, },
902 { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
903 { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
904 { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
905 { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
Lee Jones3a8334b2012-05-17 14:45:16 +0100906};
907
Bill Pembertona5023572012-11-19 13:22:22 -0500908static int
Lee Jones3a8334b2012-05-17 14:45:16 +0100909ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
910{
911 int err, i;
912
913 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
914 err = ab8500_regulator_register(
915 pdev, ab8500_regulator_matches[i].init_data,
916 i, ab8500_regulator_matches[i].of_node);
917 if (err)
918 return err;
919 }
920
921 return 0;
922}
923
Bill Pembertona5023572012-11-19 13:22:22 -0500924static int ab8500_regulator_probe(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530925{
926 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200927 struct ab8500_platform_data *pdata;
Lee Jones3a8334b2012-05-17 14:45:16 +0100928 struct device_node *np = pdev->dev.of_node;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530929 int i, err;
930
Lee Jones3a8334b2012-05-17 14:45:16 +0100931 if (np) {
932 err = of_regulator_match(&pdev->dev, np,
933 ab8500_regulator_matches,
934 ARRAY_SIZE(ab8500_regulator_matches));
935 if (err < 0) {
936 dev_err(&pdev->dev,
937 "Error parsing regulator init data: %d\n", err);
938 return err;
939 }
940
941 err = ab8500_regulator_of_probe(pdev, np);
942 return err;
943 }
944
Sundar R IYERc789ca22010-07-13 21:48:56 +0530945 if (!ab8500) {
946 dev_err(&pdev->dev, "null mfd parent\n");
947 return -EINVAL;
948 }
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200949 pdata = dev_get_platdata(ab8500->dev);
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100950 if (!pdata) {
951 dev_err(&pdev->dev, "null pdata\n");
952 return -EINVAL;
953 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530954
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100955 /* make sure the platform data has the correct size */
956 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100957 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100958 return -EINVAL;
959 }
960
Bengt Jonsson79568b942011-03-11 11:54:46 +0100961 /* initialize registers */
962 for (i = 0; i < pdata->num_regulator_reg_init; i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100963 int id, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100964
965 id = pdata->regulator_reg_init[i].id;
966 value = pdata->regulator_reg_init[i].value;
967
968 /* check for configuration errors */
969 if (id >= AB8500_NUM_REGULATOR_REGISTERS) {
970 dev_err(&pdev->dev,
971 "Configuration error: id outside range.\n");
972 return -EINVAL;
973 }
Bengt Jonsson79568b942011-03-11 11:54:46 +0100974
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100975 err = ab8500_regulator_init_registers(pdev, id, value);
976 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +0100977 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100978 }
979
Sundar R IYERc789ca22010-07-13 21:48:56 +0530980 /* register all regulators */
981 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100982 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
983 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530984 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530985 }
986
987 return 0;
988}
989
Bill Pemberton8dc995f2012-11-19 13:26:10 -0500990static int ab8500_regulator_remove(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530991{
992 int i;
993
994 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
995 struct ab8500_regulator_info *info = NULL;
996 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100997
998 dev_vdbg(rdev_get_dev(info->regulator),
999 "%s-remove\n", info->desc.name);
1000
Sundar R IYERc789ca22010-07-13 21:48:56 +05301001 regulator_unregister(info->regulator);
1002 }
1003
1004 return 0;
1005}
1006
1007static struct platform_driver ab8500_regulator_driver = {
1008 .probe = ab8500_regulator_probe,
Bill Pemberton5eb9f2b2012-11-19 13:20:42 -05001009 .remove = ab8500_regulator_remove,
Sundar R IYERc789ca22010-07-13 21:48:56 +05301010 .driver = {
1011 .name = "ab8500-regulator",
1012 .owner = THIS_MODULE,
Sundar R IYERc789ca22010-07-13 21:48:56 +05301013 },
1014};
1015
1016static int __init ab8500_regulator_init(void)
1017{
1018 int ret;
1019
1020 ret = platform_driver_register(&ab8500_regulator_driver);
1021 if (ret != 0)
1022 pr_err("Failed to register ab8500 regulator: %d\n", ret);
1023
1024 return ret;
1025}
1026subsys_initcall(ab8500_regulator_init);
1027
1028static void __exit ab8500_regulator_exit(void)
1029{
1030 platform_driver_unregister(&ab8500_regulator_driver);
1031}
1032module_exit(ab8500_regulator_exit);
1033
1034MODULE_LICENSE("GPL v2");
1035MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
1036MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
1037MODULE_ALIAS("platform:ab8500-regulator");