blob: 12e274039ae1d8c2d18ffc2725ca3ad10cc0d506 [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,
Axel Lin5689e832013-03-25 14:59:00 +0800366 .list_voltage = regulator_list_voltage_linear,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000367};
368
369static struct regulator_ops ab8500_regulator_ops = {
370 .enable = ab8500_regulator_enable,
371 .disable = ab8500_regulator_disable,
372 .is_enabled = ab8500_regulator_is_enabled,
373 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
Axel Lin5689e832013-03-25 14:59:00 +0800374 .list_voltage = regulator_list_voltage_linear,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530375};
376
Bengt Jonsson6909b452010-12-10 11:08:47 +0100377static struct ab8500_regulator_info
378 ab8500_regulator_info[AB8500_NUM_REGULATORS] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530379 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100380 * Variable Voltage Regulators
381 * name, min mV, max mV,
382 * update bank, reg, mask, enable val
Axel Linec1cc4d2012-05-20 10:33:35 +0800383 * volt bank, reg, mask
Sundar R IYERc789ca22010-07-13 21:48:56 +0530384 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100385 [AB8500_LDO_AUX1] = {
386 .desc = {
387 .name = "LDO-AUX1",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000388 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100389 .type = REGULATOR_VOLTAGE,
390 .id = AB8500_LDO_AUX1,
391 .owner = THIS_MODULE,
392 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800393 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100394 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000395 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100396 .update_bank = 0x04,
397 .update_reg = 0x09,
398 .update_mask = 0x03,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000399 .update_val = 0x01,
400 .update_val_idle = 0x03,
401 .update_val_normal = 0x01,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100402 .voltage_bank = 0x04,
403 .voltage_reg = 0x1f,
404 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100405 },
406 [AB8500_LDO_AUX2] = {
407 .desc = {
408 .name = "LDO-AUX2",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000409 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100410 .type = REGULATOR_VOLTAGE,
411 .id = AB8500_LDO_AUX2,
412 .owner = THIS_MODULE,
413 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800414 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100415 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000416 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100417 .update_bank = 0x04,
418 .update_reg = 0x09,
419 .update_mask = 0x0c,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000420 .update_val = 0x04,
421 .update_val_idle = 0x0c,
422 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100423 .voltage_bank = 0x04,
424 .voltage_reg = 0x20,
425 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100426 },
427 [AB8500_LDO_AUX3] = {
428 .desc = {
429 .name = "LDO-AUX3",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000430 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100431 .type = REGULATOR_VOLTAGE,
432 .id = AB8500_LDO_AUX3,
433 .owner = THIS_MODULE,
434 .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800435 .volt_table = ldo_vaux3_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100436 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000437 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100438 .update_bank = 0x04,
439 .update_reg = 0x0a,
440 .update_mask = 0x03,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000441 .update_val = 0x01,
442 .update_val_idle = 0x03,
443 .update_val_normal = 0x01,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100444 .voltage_bank = 0x04,
445 .voltage_reg = 0x21,
446 .voltage_mask = 0x07,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100447 },
448 [AB8500_LDO_INTCORE] = {
449 .desc = {
450 .name = "LDO-INTCORE",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000451 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100452 .type = REGULATOR_VOLTAGE,
453 .id = AB8500_LDO_INTCORE,
454 .owner = THIS_MODULE,
455 .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800456 .volt_table = ldo_vintcore_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100457 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000458 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100459 .update_bank = 0x03,
460 .update_reg = 0x80,
461 .update_mask = 0x44,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000462 .update_val = 0x04,
463 .update_val_idle = 0x44,
464 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100465 .voltage_bank = 0x03,
466 .voltage_reg = 0x80,
467 .voltage_mask = 0x38,
Linus Walleija0a70142012-08-20 18:41:35 +0200468 .voltage_shift = 3,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100469 },
Sundar R IYERc789ca22010-07-13 21:48:56 +0530470
471 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100472 * Fixed Voltage Regulators
473 * name, fixed mV,
474 * update bank, reg, mask, enable val
Sundar R IYERc789ca22010-07-13 21:48:56 +0530475 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100476 [AB8500_LDO_TVOUT] = {
477 .desc = {
478 .name = "LDO-TVOUT",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000479 .ops = &ab8500_regulator_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100480 .type = REGULATOR_VOLTAGE,
481 .id = AB8500_LDO_TVOUT,
482 .owner = THIS_MODULE,
483 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800484 .min_uV = 2000000,
Axel Lin7fee2af2012-08-07 22:21:23 +0800485 .enable_time = 10000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100486 },
Linus Walleij42ab6162011-03-17 13:25:02 +0100487 .delay = 10000,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000488 .load_lp_uA = 1000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100489 .update_bank = 0x03,
490 .update_reg = 0x80,
491 .update_mask = 0x82,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000492 .update_val = 0x02,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000493 .update_val_idle = 0x82,
494 .update_val_normal = 0x02,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100495 },
Axel Lin328a5362013-03-25 14:53:50 +0800496
497 /*
498 * Regulators with fixed voltage and normal mode
499 */
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100500 [AB8500_LDO_USB] = {
501 .desc = {
502 .name = "LDO-USB",
Axel Lin328a5362013-03-25 14:53:50 +0800503 .ops = &ab8500_regulator_ops,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100504 .type = REGULATOR_VOLTAGE,
505 .id = AB8500_LDO_USB,
506 .owner = THIS_MODULE,
507 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800508 .min_uV = 3300000,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100509 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100510 .update_bank = 0x03,
511 .update_reg = 0x82,
512 .update_mask = 0x03,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100513 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100514 [AB8500_LDO_AUDIO] = {
515 .desc = {
516 .name = "LDO-AUDIO",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000517 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100518 .type = REGULATOR_VOLTAGE,
519 .id = AB8500_LDO_AUDIO,
520 .owner = THIS_MODULE,
521 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800522 .min_uV = 2000000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100523 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100524 .update_bank = 0x03,
525 .update_reg = 0x83,
526 .update_mask = 0x02,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000527 .update_val = 0x02,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100528 },
529 [AB8500_LDO_ANAMIC1] = {
530 .desc = {
531 .name = "LDO-ANAMIC1",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000532 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100533 .type = REGULATOR_VOLTAGE,
534 .id = AB8500_LDO_ANAMIC1,
535 .owner = THIS_MODULE,
536 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800537 .min_uV = 2050000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100538 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100539 .update_bank = 0x03,
540 .update_reg = 0x83,
541 .update_mask = 0x08,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000542 .update_val = 0x08,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100543 },
544 [AB8500_LDO_ANAMIC2] = {
545 .desc = {
546 .name = "LDO-ANAMIC2",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000547 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100548 .type = REGULATOR_VOLTAGE,
549 .id = AB8500_LDO_ANAMIC2,
550 .owner = THIS_MODULE,
551 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800552 .min_uV = 2050000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100553 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100554 .update_bank = 0x03,
555 .update_reg = 0x83,
556 .update_mask = 0x10,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000557 .update_val = 0x10,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100558 },
559 [AB8500_LDO_DMIC] = {
560 .desc = {
561 .name = "LDO-DMIC",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000562 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100563 .type = REGULATOR_VOLTAGE,
564 .id = AB8500_LDO_DMIC,
565 .owner = THIS_MODULE,
566 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800567 .min_uV = 1800000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100568 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100569 .update_bank = 0x03,
570 .update_reg = 0x83,
571 .update_mask = 0x04,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000572 .update_val = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100573 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000574
575 /*
576 * Regulators with fixed voltage and normal/idle modes
577 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100578 [AB8500_LDO_ANA] = {
579 .desc = {
580 .name = "LDO-ANA",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000581 .ops = &ab8500_regulator_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100582 .type = REGULATOR_VOLTAGE,
583 .id = AB8500_LDO_ANA,
584 .owner = THIS_MODULE,
585 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800586 .min_uV = 1200000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100587 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000588 .load_lp_uA = 1000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100589 .update_bank = 0x04,
590 .update_reg = 0x06,
591 .update_mask = 0x0c,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000592 .update_val = 0x04,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000593 .update_val_idle = 0x0c,
594 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100595 },
596
597
Sundar R IYERc789ca22010-07-13 21:48:56 +0530598};
599
Bengt Jonsson79568b942011-03-11 11:54:46 +0100600struct ab8500_reg_init {
601 u8 bank;
602 u8 addr;
603 u8 mask;
604};
605
606#define REG_INIT(_id, _bank, _addr, _mask) \
607 [_id] = { \
608 .bank = _bank, \
609 .addr = _addr, \
610 .mask = _mask, \
611 }
612
613static struct ab8500_reg_init ab8500_reg_init[] = {
614 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000615 * 0x03, VarmRequestCtrl
616 * 0x0c, VapeRequestCtrl
617 * 0x30, Vsmps1RequestCtrl
618 * 0xc0, Vsmps2RequestCtrl
619 */
620 REG_INIT(AB8500_REGUREQUESTCTRL1, 0x03, 0x03, 0xff),
621 /*
622 * 0x03, Vsmps3RequestCtrl
Lee Jonesd79df322013-03-21 15:58:58 +0000623 * 0x0c, VpllRequestCtrl
Lee Jones33bc8f42013-03-21 15:59:02 +0000624 * 0x30, VanaRequestCtrl
Bengt Jonsson79568b942011-03-11 11:54:46 +0100625 * 0xc0, VextSupply1RequestCtrl
626 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000627 REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100628 /*
629 * 0x03, VextSupply2RequestCtrl
630 * 0x0c, VextSupply3RequestCtrl
631 * 0x30, Vaux1RequestCtrl
632 * 0xc0, Vaux2RequestCtrl
633 */
634 REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
635 /*
636 * 0x03, Vaux3RequestCtrl
637 * 0x04, SwHPReq
638 */
639 REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
640 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000641 * 0x01, Vsmps1SysClkReq1HPValid
642 * 0x02, Vsmps2SysClkReq1HPValid
643 * 0x04, Vsmps3SysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100644 * 0x08, VanaSysClkReq1HPValid
Lee Jonesd79df322013-03-21 15:58:58 +0000645 * 0x10, VpllSysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100646 * 0x20, Vaux1SysClkReq1HPValid
647 * 0x40, Vaux2SysClkReq1HPValid
648 * 0x80, Vaux3SysClkReq1HPValid
649 */
Lee Jonesd79df322013-03-21 15:58:58 +0000650 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100651 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000652 * 0x01, VapeSysClkReq1HPValid
653 * 0x02, VarmSysClkReq1HPValid
654 * 0x04, VbbSysClkReq1HPValid
655 * 0x08, VmodSysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100656 * 0x10, VextSupply1SysClkReq1HPValid
657 * 0x20, VextSupply2SysClkReq1HPValid
658 * 0x40, VextSupply3SysClkReq1HPValid
659 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000660 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x7f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100661 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000662 * 0x01, Vsmps1HwHPReq1Valid
663 * 0x02, Vsmps2HwHPReq1Valid
664 * 0x04, Vsmps3HwHPReq1Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100665 * 0x08, VanaHwHPReq1Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000666 * 0x10, VpllHwHPReq1Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100667 * 0x20, Vaux1HwHPReq1Valid
668 * 0x40, Vaux2HwHPReq1Valid
669 * 0x80, Vaux3HwHPReq1Valid
670 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000671 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100672 /*
673 * 0x01, VextSupply1HwHPReq1Valid
674 * 0x02, VextSupply2HwHPReq1Valid
675 * 0x04, VextSupply3HwHPReq1Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000676 * 0x08, VmodHwHPReq1Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100677 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000678 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x0f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100679 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000680 * 0x01, Vsmps1HwHPReq2Valid
681 * 0x02, Vsmps2HwHPReq2Valid
682 * 0x03, Vsmps3HwHPReq2Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100683 * 0x08, VanaHwHPReq2Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000684 * 0x10, VpllHwHPReq2Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100685 * 0x20, Vaux1HwHPReq2Valid
686 * 0x40, Vaux2HwHPReq2Valid
687 * 0x80, Vaux3HwHPReq2Valid
688 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000689 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100690 /*
691 * 0x01, VextSupply1HwHPReq2Valid
692 * 0x02, VextSupply2HwHPReq2Valid
693 * 0x04, VextSupply3HwHPReq2Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000694 * 0x08, VmodHwHPReq2Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100695 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000696 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x0f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100697 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000698 * 0x01, VapeSwHPReqValid
699 * 0x02, VarmSwHPReqValid
700 * 0x04, Vsmps1SwHPReqValid
701 * 0x08, Vsmps2SwHPReqValid
702 * 0x10, Vsmps3SwHPReqValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100703 * 0x20, VanaSwHPReqValid
Lee Jones33bc8f42013-03-21 15:59:02 +0000704 * 0x40, VpllSwHPReqValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100705 * 0x80, Vaux1SwHPReqValid
706 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000707 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100708 /*
709 * 0x01, Vaux2SwHPReqValid
710 * 0x02, Vaux3SwHPReqValid
711 * 0x04, VextSupply1SwHPReqValid
712 * 0x08, VextSupply2SwHPReqValid
713 * 0x10, VextSupply3SwHPReqValid
Lee Jones33bc8f42013-03-21 15:59:02 +0000714 * 0x20, VmodSwHPReqValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100715 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000716 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x3f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100717 /*
718 * 0x02, SysClkReq2Valid1
719 * ...
720 * 0x80, SysClkReq8Valid1
721 */
722 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
723 /*
724 * 0x02, SysClkReq2Valid2
725 * ...
726 * 0x80, SysClkReq8Valid2
727 */
728 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
729 /*
730 * 0x02, VTVoutEna
731 * 0x04, Vintcore12Ena
732 * 0x38, Vintcore12Sel
733 * 0x40, Vintcore12LP
734 * 0x80, VTVoutLP
735 */
736 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
737 /*
738 * 0x02, VaudioEna
739 * 0x04, VdmicEna
740 * 0x08, Vamic1Ena
741 * 0x10, Vamic2Ena
742 */
743 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
744 /*
745 * 0x01, Vamic1_dzout
746 * 0x02, Vamic2_dzout
747 */
748 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
749 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000750 * 0x03, Vsmps1Regu
751 * 0x0c, Vsmps1SelCtrl
Lee Jones33bc8f42013-03-21 15:59:02 +0000752 * 0x10, Vsmps1AutoMode
753 * 0x20, Vsmps1PWMMode
Lee Jonesd79df322013-03-21 15:58:58 +0000754 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000755 REG_INIT(AB8500_VSMPS1REGU, 0x04, 0x03, 0x3f),
Lee Jonesd79df322013-03-21 15:58:58 +0000756 /*
757 * 0x03, Vsmps2Regu
758 * 0x0c, Vsmps2SelCtrl
Lee Jones33bc8f42013-03-21 15:59:02 +0000759 * 0x10, Vsmps2AutoMode
760 * 0x20, Vsmps2PWMMode
Lee Jonesd79df322013-03-21 15:58:58 +0000761 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000762 REG_INIT(AB8500_VSMPS2REGU, 0x04, 0x04, 0x3f),
Lee Jonesd79df322013-03-21 15:58:58 +0000763 /*
Bengt Jonsson79568b942011-03-11 11:54:46 +0100764 * 0x03, VpllRegu
Lee Jones33bc8f42013-03-21 15:59:02 +0000765 * 0x0c, VanaRegu
Bengt Jonsson79568b942011-03-11 11:54:46 +0100766 */
767 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
768 /*
769 * 0x01, VrefDDREna
770 * 0x02, VrefDDRSleepMode
771 */
772 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
773 /*
774 * 0x03, VextSupply1Regu
775 * 0x0c, VextSupply2Regu
776 * 0x30, VextSupply3Regu
777 * 0x40, ExtSupply2Bypass
778 * 0x80, ExtSupply3Bypass
779 */
780 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
781 /*
782 * 0x03, Vaux1Regu
783 * 0x0c, Vaux2Regu
784 */
785 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
786 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000787 * 0x0c, Vrf1Regu
Bengt Jonsson79568b942011-03-11 11:54:46 +0100788 * 0x03, Vaux3Regu
789 */
Lee Jonesd79df322013-03-21 15:58:58 +0000790 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x0f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100791 /*
792 * 0x3f, Vsmps1Sel1
793 */
794 REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f),
795 /*
796 * 0x0f, Vaux1Sel
797 */
798 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
799 /*
800 * 0x0f, Vaux2Sel
801 */
802 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
803 /*
804 * 0x07, Vaux3Sel
Lee Jones33bc8f42013-03-21 15:59:02 +0000805 * 0x30, Vrf1Sel
Bengt Jonsson79568b942011-03-11 11:54:46 +0100806 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000807 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x37),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100808 /*
809 * 0x01, VextSupply12LP
810 */
811 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
812 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000813 * 0x01, VpllDisch
814 * 0x02, Vrf1Disch
Bengt Jonsson79568b942011-03-11 11:54:46 +0100815 * 0x04, Vaux1Disch
816 * 0x08, Vaux2Disch
817 * 0x10, Vaux3Disch
818 * 0x20, Vintcore12Disch
819 * 0x40, VTVoutDisch
820 * 0x80, VaudioDisch
821 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000822 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100823 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000824 * 0x01, VsimDisch
Bengt Jonsson79568b942011-03-11 11:54:46 +0100825 * 0x02, VanaDisch
826 * 0x04, VdmicPullDownEna
Lee Jones33bc8f42013-03-21 15:59:02 +0000827 * 0x08, VpllPullDownEna
Bengt Jonsson79568b942011-03-11 11:54:46 +0100828 * 0x10, VdmicDisch
829 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000830 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x1f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100831};
832
Lee Jones3c1b8432013-03-21 15:59:01 +0000833static int ab8500_regulator_init_registers(struct platform_device *pdev,
834 int id, int mask, int value)
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100835{
836 int err;
837
Lee Jones3c1b8432013-03-21 15:59:01 +0000838 BUG_ON(value & ~mask);
839 BUG_ON(mask & ~ab8500_reg_init[id].mask);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100840
Lee Jones3c1b8432013-03-21 15:59:01 +0000841 /* initialize register */
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100842 err = abx500_mask_and_set_register_interruptible(
843 &pdev->dev,
844 ab8500_reg_init[id].bank,
845 ab8500_reg_init[id].addr,
Lee Jones3c1b8432013-03-21 15:59:01 +0000846 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100847 if (err < 0) {
848 dev_err(&pdev->dev,
849 "Failed to initialize 0x%02x, 0x%02x.\n",
850 ab8500_reg_init[id].bank,
851 ab8500_reg_init[id].addr);
852 return err;
853 }
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100854 dev_vdbg(&pdev->dev,
Lee Jones3c1b8432013-03-21 15:59:01 +0000855 " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
856 ab8500_reg_init[id].bank,
857 ab8500_reg_init[id].addr,
858 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100859
860 return 0;
861}
862
Bill Pembertona5023572012-11-19 13:22:22 -0500863static int ab8500_regulator_register(struct platform_device *pdev,
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100864 struct regulator_init_data *init_data,
865 int id,
866 struct device_node *np)
867{
868 struct ab8500_regulator_info *info = NULL;
869 struct regulator_config config = { };
870 int err;
871
872 /* assign per-regulator data */
873 info = &ab8500_regulator_info[id];
874 info->dev = &pdev->dev;
875
876 config.dev = &pdev->dev;
877 config.init_data = init_data;
878 config.driver_data = info;
879 config.of_node = np;
880
881 /* fix for hardware before ab8500v2.0 */
882 if (abx500_get_chip_id(info->dev) < 0x20) {
883 if (info->desc.id == AB8500_LDO_AUX3) {
884 info->desc.n_voltages =
885 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800886 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100887 info->voltage_mask = 0xf;
888 }
889 }
890
891 /* register regulator with framework */
892 info->regulator = regulator_register(&info->desc, &config);
893 if (IS_ERR(info->regulator)) {
894 err = PTR_ERR(info->regulator);
895 dev_err(&pdev->dev, "failed to register regulator %s\n",
896 info->desc.name);
897 /* when we fail, un-register all earlier regulators */
898 while (--id >= 0) {
899 info = &ab8500_regulator_info[id];
900 regulator_unregister(info->regulator);
901 }
902 return err;
903 }
904
905 return 0;
906}
907
Lee Jones3a8334b2012-05-17 14:45:16 +0100908static struct of_regulator_match ab8500_regulator_matches[] = {
Lee Jones7e715b92012-05-30 12:47:26 +0800909 { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, },
910 { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, },
911 { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, },
912 { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
913 { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, },
914 { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, },
915 { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, },
916 { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
917 { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
918 { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
919 { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
Lee Jones3a8334b2012-05-17 14:45:16 +0100920};
921
Bill Pembertona5023572012-11-19 13:22:22 -0500922static int
Lee Jones3a8334b2012-05-17 14:45:16 +0100923ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
924{
925 int err, i;
926
927 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
928 err = ab8500_regulator_register(
929 pdev, ab8500_regulator_matches[i].init_data,
930 i, ab8500_regulator_matches[i].of_node);
931 if (err)
932 return err;
933 }
934
935 return 0;
936}
937
Bill Pembertona5023572012-11-19 13:22:22 -0500938static int ab8500_regulator_probe(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530939{
940 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Lee Jones3a8334b2012-05-17 14:45:16 +0100941 struct device_node *np = pdev->dev.of_node;
Bengt Jonsson732805a2013-03-21 15:59:03 +0000942 struct ab8500_platform_data *ppdata;
943 struct ab8500_regulator_platform_data *pdata;
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 }
Bengt Jonsson732805a2013-03-21 15:59:03 +0000964
965 ppdata = dev_get_platdata(ab8500->dev);
966 if (!ppdata) {
967 dev_err(&pdev->dev, "null parent pdata\n");
968 return -EINVAL;
969 }
970
971 pdata = ppdata->regulator;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100972 if (!pdata) {
973 dev_err(&pdev->dev, "null pdata\n");
974 return -EINVAL;
975 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530976
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100977 /* make sure the platform data has the correct size */
978 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100979 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100980 return -EINVAL;
981 }
982
Bengt Jonsson79568b942011-03-11 11:54:46 +0100983 /* initialize registers */
Bengt Jonsson732805a2013-03-21 15:59:03 +0000984 for (i = 0; i < pdata->num_reg_init; i++) {
Lee Jones3c1b8432013-03-21 15:59:01 +0000985 int id, mask, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100986
Bengt Jonsson732805a2013-03-21 15:59:03 +0000987 id = pdata->reg_init[i].id;
988 mask = pdata->reg_init[i].mask;
989 value = pdata->reg_init[i].value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100990
991 /* check for configuration errors */
Lee Jones3c1b8432013-03-21 15:59:01 +0000992 BUG_ON(id >= AB8500_NUM_REGULATOR_REGISTERS);
Bengt Jonsson79568b942011-03-11 11:54:46 +0100993
Lee Jones3c1b8432013-03-21 15:59:01 +0000994 err = ab8500_regulator_init_registers(pdev, id, mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100995 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +0100996 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100997 }
998
Sundar R IYERc789ca22010-07-13 21:48:56 +0530999 /* register all regulators */
1000 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +01001001 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
1002 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +05301003 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +05301004 }
1005
1006 return 0;
1007}
1008
Bill Pemberton8dc995f2012-11-19 13:26:10 -05001009static int ab8500_regulator_remove(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +05301010{
1011 int i;
1012
1013 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
1014 struct ab8500_regulator_info *info = NULL;
1015 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +01001016
1017 dev_vdbg(rdev_get_dev(info->regulator),
1018 "%s-remove\n", info->desc.name);
1019
Sundar R IYERc789ca22010-07-13 21:48:56 +05301020 regulator_unregister(info->regulator);
1021 }
1022
1023 return 0;
1024}
1025
1026static struct platform_driver ab8500_regulator_driver = {
1027 .probe = ab8500_regulator_probe,
Bill Pemberton5eb9f2b2012-11-19 13:20:42 -05001028 .remove = ab8500_regulator_remove,
Sundar R IYERc789ca22010-07-13 21:48:56 +05301029 .driver = {
1030 .name = "ab8500-regulator",
1031 .owner = THIS_MODULE,
Sundar R IYERc789ca22010-07-13 21:48:56 +05301032 },
1033};
1034
1035static int __init ab8500_regulator_init(void)
1036{
1037 int ret;
1038
1039 ret = platform_driver_register(&ab8500_regulator_driver);
1040 if (ret != 0)
1041 pr_err("Failed to register ab8500 regulator: %d\n", ret);
1042
1043 return ret;
1044}
1045subsys_initcall(ab8500_regulator_init);
1046
1047static void __exit ab8500_regulator_exit(void)
1048{
1049 platform_driver_unregister(&ab8500_regulator_driver);
1050}
1051module_exit(ab8500_regulator_exit);
1052
1053MODULE_LICENSE("GPL v2");
1054MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
Bengt Jonsson732805a2013-03-21 15:59:03 +00001055MODULE_AUTHOR("Bengt Jonsson <bengt.g.jonsson@stericsson.com>");
Sundar R IYERc789ca22010-07-13 21:48:56 +05301056MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
1057MODULE_ALIAS("platform:ab8500-regulator");