blob: c7784c4bff4f3d24b953035a984eb16bab000c75 [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 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000616 * 0x03, VarmRequestCtrl
617 * 0x0c, VapeRequestCtrl
618 * 0x30, Vsmps1RequestCtrl
619 * 0xc0, Vsmps2RequestCtrl
620 */
621 REG_INIT(AB8500_REGUREQUESTCTRL1, 0x03, 0x03, 0xff),
622 /*
623 * 0x03, Vsmps3RequestCtrl
Lee Jonesd79df322013-03-21 15:58:58 +0000624 * 0x0c, VpllRequestCtrl
Lee Jones33bc8f42013-03-21 15:59:02 +0000625 * 0x30, VanaRequestCtrl
Bengt Jonsson79568b942011-03-11 11:54:46 +0100626 * 0xc0, VextSupply1RequestCtrl
627 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000628 REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100629 /*
630 * 0x03, VextSupply2RequestCtrl
631 * 0x0c, VextSupply3RequestCtrl
632 * 0x30, Vaux1RequestCtrl
633 * 0xc0, Vaux2RequestCtrl
634 */
635 REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
636 /*
637 * 0x03, Vaux3RequestCtrl
638 * 0x04, SwHPReq
639 */
640 REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
641 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000642 * 0x01, Vsmps1SysClkReq1HPValid
643 * 0x02, Vsmps2SysClkReq1HPValid
644 * 0x04, Vsmps3SysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100645 * 0x08, VanaSysClkReq1HPValid
Lee Jonesd79df322013-03-21 15:58:58 +0000646 * 0x10, VpllSysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100647 * 0x20, Vaux1SysClkReq1HPValid
648 * 0x40, Vaux2SysClkReq1HPValid
649 * 0x80, Vaux3SysClkReq1HPValid
650 */
Lee Jonesd79df322013-03-21 15:58:58 +0000651 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100652 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000653 * 0x01, VapeSysClkReq1HPValid
654 * 0x02, VarmSysClkReq1HPValid
655 * 0x04, VbbSysClkReq1HPValid
656 * 0x08, VmodSysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100657 * 0x10, VextSupply1SysClkReq1HPValid
658 * 0x20, VextSupply2SysClkReq1HPValid
659 * 0x40, VextSupply3SysClkReq1HPValid
660 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000661 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x7f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100662 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000663 * 0x01, Vsmps1HwHPReq1Valid
664 * 0x02, Vsmps2HwHPReq1Valid
665 * 0x04, Vsmps3HwHPReq1Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100666 * 0x08, VanaHwHPReq1Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000667 * 0x10, VpllHwHPReq1Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100668 * 0x20, Vaux1HwHPReq1Valid
669 * 0x40, Vaux2HwHPReq1Valid
670 * 0x80, Vaux3HwHPReq1Valid
671 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000672 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100673 /*
674 * 0x01, VextSupply1HwHPReq1Valid
675 * 0x02, VextSupply2HwHPReq1Valid
676 * 0x04, VextSupply3HwHPReq1Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000677 * 0x08, VmodHwHPReq1Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100678 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000679 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x0f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100680 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000681 * 0x01, Vsmps1HwHPReq2Valid
682 * 0x02, Vsmps2HwHPReq2Valid
683 * 0x03, Vsmps3HwHPReq2Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100684 * 0x08, VanaHwHPReq2Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000685 * 0x10, VpllHwHPReq2Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100686 * 0x20, Vaux1HwHPReq2Valid
687 * 0x40, Vaux2HwHPReq2Valid
688 * 0x80, Vaux3HwHPReq2Valid
689 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000690 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100691 /*
692 * 0x01, VextSupply1HwHPReq2Valid
693 * 0x02, VextSupply2HwHPReq2Valid
694 * 0x04, VextSupply3HwHPReq2Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000695 * 0x08, VmodHwHPReq2Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100696 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000697 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x0f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100698 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000699 * 0x01, VapeSwHPReqValid
700 * 0x02, VarmSwHPReqValid
701 * 0x04, Vsmps1SwHPReqValid
702 * 0x08, Vsmps2SwHPReqValid
703 * 0x10, Vsmps3SwHPReqValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100704 * 0x20, VanaSwHPReqValid
Lee Jones33bc8f42013-03-21 15:59:02 +0000705 * 0x40, VpllSwHPReqValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100706 * 0x80, Vaux1SwHPReqValid
707 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000708 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100709 /*
710 * 0x01, Vaux2SwHPReqValid
711 * 0x02, Vaux3SwHPReqValid
712 * 0x04, VextSupply1SwHPReqValid
713 * 0x08, VextSupply2SwHPReqValid
714 * 0x10, VextSupply3SwHPReqValid
Lee Jones33bc8f42013-03-21 15:59:02 +0000715 * 0x20, VmodSwHPReqValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100716 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000717 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x3f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100718 /*
719 * 0x02, SysClkReq2Valid1
720 * ...
721 * 0x80, SysClkReq8Valid1
722 */
723 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
724 /*
725 * 0x02, SysClkReq2Valid2
726 * ...
727 * 0x80, SysClkReq8Valid2
728 */
729 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
730 /*
731 * 0x02, VTVoutEna
732 * 0x04, Vintcore12Ena
733 * 0x38, Vintcore12Sel
734 * 0x40, Vintcore12LP
735 * 0x80, VTVoutLP
736 */
737 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
738 /*
739 * 0x02, VaudioEna
740 * 0x04, VdmicEna
741 * 0x08, Vamic1Ena
742 * 0x10, Vamic2Ena
743 */
744 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
745 /*
746 * 0x01, Vamic1_dzout
747 * 0x02, Vamic2_dzout
748 */
749 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
750 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000751 * 0x03, Vsmps1Regu
752 * 0x0c, Vsmps1SelCtrl
Lee Jones33bc8f42013-03-21 15:59:02 +0000753 * 0x10, Vsmps1AutoMode
754 * 0x20, Vsmps1PWMMode
Lee Jonesd79df322013-03-21 15:58:58 +0000755 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000756 REG_INIT(AB8500_VSMPS1REGU, 0x04, 0x03, 0x3f),
Lee Jonesd79df322013-03-21 15:58:58 +0000757 /*
758 * 0x03, Vsmps2Regu
759 * 0x0c, Vsmps2SelCtrl
Lee Jones33bc8f42013-03-21 15:59:02 +0000760 * 0x10, Vsmps2AutoMode
761 * 0x20, Vsmps2PWMMode
Lee Jonesd79df322013-03-21 15:58:58 +0000762 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000763 REG_INIT(AB8500_VSMPS2REGU, 0x04, 0x04, 0x3f),
Lee Jonesd79df322013-03-21 15:58:58 +0000764 /*
Bengt Jonsson79568b942011-03-11 11:54:46 +0100765 * 0x03, VpllRegu
Lee Jones33bc8f42013-03-21 15:59:02 +0000766 * 0x0c, VanaRegu
Bengt Jonsson79568b942011-03-11 11:54:46 +0100767 */
768 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
769 /*
770 * 0x01, VrefDDREna
771 * 0x02, VrefDDRSleepMode
772 */
773 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
774 /*
775 * 0x03, VextSupply1Regu
776 * 0x0c, VextSupply2Regu
777 * 0x30, VextSupply3Regu
778 * 0x40, ExtSupply2Bypass
779 * 0x80, ExtSupply3Bypass
780 */
781 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
782 /*
783 * 0x03, Vaux1Regu
784 * 0x0c, Vaux2Regu
785 */
786 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
787 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000788 * 0x0c, Vrf1Regu
Bengt Jonsson79568b942011-03-11 11:54:46 +0100789 * 0x03, Vaux3Regu
790 */
Lee Jonesd79df322013-03-21 15:58:58 +0000791 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x0f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100792 /*
793 * 0x3f, Vsmps1Sel1
794 */
795 REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f),
796 /*
797 * 0x0f, Vaux1Sel
798 */
799 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
800 /*
801 * 0x0f, Vaux2Sel
802 */
803 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
804 /*
805 * 0x07, Vaux3Sel
Lee Jones33bc8f42013-03-21 15:59:02 +0000806 * 0x30, Vrf1Sel
Bengt Jonsson79568b942011-03-11 11:54:46 +0100807 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000808 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x37),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100809 /*
810 * 0x01, VextSupply12LP
811 */
812 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
813 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000814 * 0x01, VpllDisch
815 * 0x02, Vrf1Disch
Bengt Jonsson79568b942011-03-11 11:54:46 +0100816 * 0x04, Vaux1Disch
817 * 0x08, Vaux2Disch
818 * 0x10, Vaux3Disch
819 * 0x20, Vintcore12Disch
820 * 0x40, VTVoutDisch
821 * 0x80, VaudioDisch
822 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000823 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100824 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000825 * 0x01, VsimDisch
Bengt Jonsson79568b942011-03-11 11:54:46 +0100826 * 0x02, VanaDisch
827 * 0x04, VdmicPullDownEna
Lee Jones33bc8f42013-03-21 15:59:02 +0000828 * 0x08, VpllPullDownEna
Bengt Jonsson79568b942011-03-11 11:54:46 +0100829 * 0x10, VdmicDisch
830 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000831 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x1f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100832};
833
Lee Jones3c1b8432013-03-21 15:59:01 +0000834static int ab8500_regulator_init_registers(struct platform_device *pdev,
835 int id, int mask, int value)
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100836{
837 int err;
838
Lee Jones3c1b8432013-03-21 15:59:01 +0000839 BUG_ON(value & ~mask);
840 BUG_ON(mask & ~ab8500_reg_init[id].mask);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100841
Lee Jones3c1b8432013-03-21 15:59:01 +0000842 /* initialize register */
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100843 err = abx500_mask_and_set_register_interruptible(
844 &pdev->dev,
845 ab8500_reg_init[id].bank,
846 ab8500_reg_init[id].addr,
Lee Jones3c1b8432013-03-21 15:59:01 +0000847 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100848 if (err < 0) {
849 dev_err(&pdev->dev,
850 "Failed to initialize 0x%02x, 0x%02x.\n",
851 ab8500_reg_init[id].bank,
852 ab8500_reg_init[id].addr);
853 return err;
854 }
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100855 dev_vdbg(&pdev->dev,
Lee Jones3c1b8432013-03-21 15:59:01 +0000856 " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
857 ab8500_reg_init[id].bank,
858 ab8500_reg_init[id].addr,
859 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100860
861 return 0;
862}
863
Bill Pembertona5023572012-11-19 13:22:22 -0500864static int ab8500_regulator_register(struct platform_device *pdev,
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100865 struct regulator_init_data *init_data,
866 int id,
867 struct device_node *np)
868{
869 struct ab8500_regulator_info *info = NULL;
870 struct regulator_config config = { };
871 int err;
872
873 /* assign per-regulator data */
874 info = &ab8500_regulator_info[id];
875 info->dev = &pdev->dev;
876
877 config.dev = &pdev->dev;
878 config.init_data = init_data;
879 config.driver_data = info;
880 config.of_node = np;
881
882 /* fix for hardware before ab8500v2.0 */
883 if (abx500_get_chip_id(info->dev) < 0x20) {
884 if (info->desc.id == AB8500_LDO_AUX3) {
885 info->desc.n_voltages =
886 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800887 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100888 info->voltage_mask = 0xf;
889 }
890 }
891
892 /* register regulator with framework */
893 info->regulator = regulator_register(&info->desc, &config);
894 if (IS_ERR(info->regulator)) {
895 err = PTR_ERR(info->regulator);
896 dev_err(&pdev->dev, "failed to register regulator %s\n",
897 info->desc.name);
898 /* when we fail, un-register all earlier regulators */
899 while (--id >= 0) {
900 info = &ab8500_regulator_info[id];
901 regulator_unregister(info->regulator);
902 }
903 return err;
904 }
905
906 return 0;
907}
908
Lee Jones3a8334b2012-05-17 14:45:16 +0100909static struct of_regulator_match ab8500_regulator_matches[] = {
Lee Jones7e715b92012-05-30 12:47:26 +0800910 { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, },
911 { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, },
912 { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, },
913 { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
914 { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, },
915 { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, },
916 { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, },
917 { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
918 { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
919 { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
920 { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
Lee Jones3a8334b2012-05-17 14:45:16 +0100921};
922
Bill Pembertona5023572012-11-19 13:22:22 -0500923static int
Lee Jones3a8334b2012-05-17 14:45:16 +0100924ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
925{
926 int err, i;
927
928 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
929 err = ab8500_regulator_register(
930 pdev, ab8500_regulator_matches[i].init_data,
931 i, ab8500_regulator_matches[i].of_node);
932 if (err)
933 return err;
934 }
935
936 return 0;
937}
938
Bill Pembertona5023572012-11-19 13:22:22 -0500939static int ab8500_regulator_probe(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530940{
941 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200942 struct ab8500_platform_data *pdata;
Lee Jones3a8334b2012-05-17 14:45:16 +0100943 struct device_node *np = pdev->dev.of_node;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530944 int i, err;
945
Lee Jones3a8334b2012-05-17 14:45:16 +0100946 if (np) {
947 err = of_regulator_match(&pdev->dev, np,
948 ab8500_regulator_matches,
949 ARRAY_SIZE(ab8500_regulator_matches));
950 if (err < 0) {
951 dev_err(&pdev->dev,
952 "Error parsing regulator init data: %d\n", err);
953 return err;
954 }
955
956 err = ab8500_regulator_of_probe(pdev, np);
957 return err;
958 }
959
Sundar R IYERc789ca22010-07-13 21:48:56 +0530960 if (!ab8500) {
961 dev_err(&pdev->dev, "null mfd parent\n");
962 return -EINVAL;
963 }
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200964 pdata = dev_get_platdata(ab8500->dev);
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100965 if (!pdata) {
966 dev_err(&pdev->dev, "null pdata\n");
967 return -EINVAL;
968 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530969
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100970 /* make sure the platform data has the correct size */
971 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100972 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100973 return -EINVAL;
974 }
975
Bengt Jonsson79568b942011-03-11 11:54:46 +0100976 /* initialize registers */
977 for (i = 0; i < pdata->num_regulator_reg_init; i++) {
Lee Jones3c1b8432013-03-21 15:59:01 +0000978 int id, mask, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100979
980 id = pdata->regulator_reg_init[i].id;
Lee Jones3c1b8432013-03-21 15:59:01 +0000981 mask = pdata->regulator_reg_init[i].mask;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100982 value = pdata->regulator_reg_init[i].value;
983
984 /* check for configuration errors */
Lee Jones3c1b8432013-03-21 15:59:01 +0000985 BUG_ON(id >= AB8500_NUM_REGULATOR_REGISTERS);
Bengt Jonsson79568b942011-03-11 11:54:46 +0100986
Lee Jones3c1b8432013-03-21 15:59:01 +0000987 err = ab8500_regulator_init_registers(pdev, id, mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100988 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +0100989 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100990 }
991
Sundar R IYERc789ca22010-07-13 21:48:56 +0530992 /* register all regulators */
993 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100994 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
995 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530996 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530997 }
998
999 return 0;
1000}
1001
Bill Pemberton8dc995f2012-11-19 13:26:10 -05001002static int ab8500_regulator_remove(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +05301003{
1004 int i;
1005
1006 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
1007 struct ab8500_regulator_info *info = NULL;
1008 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +01001009
1010 dev_vdbg(rdev_get_dev(info->regulator),
1011 "%s-remove\n", info->desc.name);
1012
Sundar R IYERc789ca22010-07-13 21:48:56 +05301013 regulator_unregister(info->regulator);
1014 }
1015
1016 return 0;
1017}
1018
1019static struct platform_driver ab8500_regulator_driver = {
1020 .probe = ab8500_regulator_probe,
Bill Pemberton5eb9f2b2012-11-19 13:20:42 -05001021 .remove = ab8500_regulator_remove,
Sundar R IYERc789ca22010-07-13 21:48:56 +05301022 .driver = {
1023 .name = "ab8500-regulator",
1024 .owner = THIS_MODULE,
Sundar R IYERc789ca22010-07-13 21:48:56 +05301025 },
1026};
1027
1028static int __init ab8500_regulator_init(void)
1029{
1030 int ret;
1031
1032 ret = platform_driver_register(&ab8500_regulator_driver);
1033 if (ret != 0)
1034 pr_err("Failed to register ab8500 regulator: %d\n", ret);
1035
1036 return ret;
1037}
1038subsys_initcall(ab8500_regulator_init);
1039
1040static void __exit ab8500_regulator_exit(void)
1041{
1042 platform_driver_unregister(&ab8500_regulator_driver);
1043}
1044module_exit(ab8500_regulator_exit);
1045
1046MODULE_LICENSE("GPL v2");
1047MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
1048MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
1049MODULE_ALIAS("platform:ab8500-regulator");