blob: f1453a66a0fd8cd1f5204f524765eae8fb5aedfb [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
Sundar R IYERc789ca22010-07-13 21:48:56 +053045 */
46struct ab8500_regulator_info {
47 struct device *dev;
48 struct regulator_desc desc;
Sundar R IYERc789ca22010-07-13 21:48:56 +053049 struct regulator_dev *regulator;
Emeric Vigierbd28a152013-03-21 15:58:59 +000050 bool is_enabled;
Bengt Jonsson7ce46692013-03-21 15:59:00 +000051 int load_lp_uA;
Mattias Wallin47c16972010-09-10 17:47:56 +020052 u8 update_bank;
53 u8 update_reg;
Bengt Jonssone1159e62010-12-10 11:08:44 +010054 u8 update_mask;
Emeric Vigierbd28a152013-03-21 15:58:59 +000055 u8 update_val;
56 u8 update_val_idle;
57 u8 update_val_normal;
Mattias Wallin47c16972010-09-10 17:47:56 +020058 u8 voltage_bank;
59 u8 voltage_reg;
60 u8 voltage_mask;
Linus Walleija0a70142012-08-20 18:41:35 +020061 u8 voltage_shift;
Sundar R IYERc789ca22010-07-13 21:48:56 +053062};
63
64/* voltage tables for the vauxn/vintcore supplies */
Axel Linec1cc4d2012-05-20 10:33:35 +080065static const unsigned int ldo_vauxn_voltages[] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +053066 1100000,
67 1200000,
68 1300000,
69 1400000,
70 1500000,
71 1800000,
72 1850000,
73 1900000,
74 2500000,
75 2650000,
76 2700000,
77 2750000,
78 2800000,
79 2900000,
80 3000000,
81 3300000,
82};
83
Axel Linec1cc4d2012-05-20 10:33:35 +080084static const unsigned int ldo_vaux3_voltages[] = {
Bengt Jonsson2b751512010-12-10 11:08:43 +010085 1200000,
86 1500000,
87 1800000,
88 2100000,
89 2500000,
90 2750000,
91 2790000,
92 2910000,
93};
94
Axel Linec1cc4d2012-05-20 10:33:35 +080095static const unsigned int ldo_vintcore_voltages[] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +053096 1200000,
97 1225000,
98 1250000,
99 1275000,
100 1300000,
101 1325000,
102 1350000,
103};
104
105static int ab8500_regulator_enable(struct regulator_dev *rdev)
106{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100107 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530108 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
109
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100110 if (info == NULL) {
111 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530112 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100113 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530114
Mattias Wallin47c16972010-09-10 17:47:56 +0200115 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonssone1159e62010-12-10 11:08:44 +0100116 info->update_bank, info->update_reg,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000117 info->update_mask, info->update_val);
Axel Linf71bf522013-03-26 16:13:14 +0800118 if (ret < 0) {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530119 dev_err(rdev_get_dev(rdev),
120 "couldn't set enable bits for regulator\n");
Axel Linf71bf522013-03-26 16:13:14 +0800121 return ret;
122 }
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);
Axel Linf71bf522013-03-26 16:13:14 +0800147 if (ret < 0) {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530148 dev_err(rdev_get_dev(rdev),
149 "couldn't set disable bits for regulator\n");
Axel Linf71bf522013-03-26 16:13:14 +0800150 return ret;
151 }
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100152
Emeric Vigierbd28a152013-03-21 15:58:59 +0000153 info->is_enabled = false;
154
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100155 dev_vdbg(rdev_get_dev(rdev),
156 "%s-disable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
157 info->desc.name, info->update_bank, info->update_reg,
158 info->update_mask, 0x0);
159
Sundar R IYERc789ca22010-07-13 21:48:56 +0530160 return ret;
161}
162
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000163static unsigned int ab8500_regulator_get_optimum_mode(
164 struct regulator_dev *rdev, int input_uV,
165 int output_uV, int load_uA)
166{
167 unsigned int mode;
168
169 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
170
171 if (info == NULL) {
172 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
173 return -EINVAL;
174 }
175
176 if (load_uA <= info->load_lp_uA)
177 mode = REGULATOR_MODE_IDLE;
178 else
179 mode = REGULATOR_MODE_NORMAL;
180
181 return mode;
182}
183
Emeric Vigierbd28a152013-03-21 15:58:59 +0000184static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
185 unsigned int mode)
186{
187 int ret = 0;
188
189 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
190
191 if (info == NULL) {
192 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
193 return -EINVAL;
194 }
195
196 switch (mode) {
197 case REGULATOR_MODE_NORMAL:
198 info->update_val = info->update_val_normal;
199 break;
200 case REGULATOR_MODE_IDLE:
201 info->update_val = info->update_val_idle;
202 break;
203 default:
204 return -EINVAL;
205 }
206
207 if (info->is_enabled) {
208 ret = abx500_mask_and_set_register_interruptible(info->dev,
209 info->update_bank, info->update_reg,
210 info->update_mask, info->update_val);
211 if (ret < 0)
212 dev_err(rdev_get_dev(rdev),
213 "couldn't set regulator mode\n");
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000214
215 dev_vdbg(rdev_get_dev(rdev),
216 "%s-set_mode (bank, reg, mask, value): "
217 "0x%x, 0x%x, 0x%x, 0x%x\n",
218 info->desc.name, info->update_bank, info->update_reg,
219 info->update_mask, info->update_val);
Emeric Vigierbd28a152013-03-21 15:58:59 +0000220 }
221
222 return ret;
223}
224
225static unsigned int ab8500_regulator_get_mode(struct regulator_dev *rdev)
226{
227 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
228 int ret;
229
230 if (info == NULL) {
231 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
232 return -EINVAL;
233 }
234
235 if (info->update_val == info->update_val_normal)
236 ret = REGULATOR_MODE_NORMAL;
237 else if (info->update_val == info->update_val_idle)
238 ret = REGULATOR_MODE_IDLE;
239 else
240 ret = -EINVAL;
241
242 return ret;
243}
244
Sundar R IYERc789ca22010-07-13 21:48:56 +0530245static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
246{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100247 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530248 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100249 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530250
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100251 if (info == NULL) {
252 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530253 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100254 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530255
Mattias Wallin47c16972010-09-10 17:47:56 +0200256 ret = abx500_get_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100257 info->update_bank, info->update_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530258 if (ret < 0) {
259 dev_err(rdev_get_dev(rdev),
260 "couldn't read 0x%x register\n", info->update_reg);
261 return ret;
262 }
263
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100264 dev_vdbg(rdev_get_dev(rdev),
265 "%s-is_enabled (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
266 " 0x%x\n",
267 info->desc.name, info->update_bank, info->update_reg,
268 info->update_mask, regval);
269
270 if (regval & info->update_mask)
Emeric Vigierbd28a152013-03-21 15:58:59 +0000271 info->is_enabled = true;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530272 else
Emeric Vigierbd28a152013-03-21 15:58:59 +0000273 info->is_enabled = false;
274
275 return info->is_enabled;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530276}
277
Axel Lin3bf6e902012-02-24 17:15:45 +0800278static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530279{
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100280 int ret, val;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530281 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100282 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530283
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100284 if (info == NULL) {
285 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530286 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100287 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530288
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100289 ret = abx500_get_register_interruptible(info->dev,
290 info->voltage_bank, info->voltage_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530291 if (ret < 0) {
292 dev_err(rdev_get_dev(rdev),
293 "couldn't read voltage reg for regulator\n");
294 return ret;
295 }
296
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100297 dev_vdbg(rdev_get_dev(rdev),
Linus Walleija0a70142012-08-20 18:41:35 +0200298 "%s-get_voltage (bank, reg, mask, shift, value): "
299 "0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
300 info->desc.name, info->voltage_bank,
301 info->voltage_reg, info->voltage_mask,
302 info->voltage_shift, regval);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100303
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100304 val = regval & info->voltage_mask;
Linus Walleija0a70142012-08-20 18:41:35 +0200305 return val >> info->voltage_shift;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530306}
307
Axel Linae713d32012-03-20 09:51:08 +0800308static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
309 unsigned selector)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530310{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100311 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530312 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100313 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530314
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100315 if (info == NULL) {
316 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530317 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100318 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530319
Sundar R IYERc789ca22010-07-13 21:48:56 +0530320 /* set the registers for the request */
Linus Walleija0a70142012-08-20 18:41:35 +0200321 regval = (u8)selector << info->voltage_shift;
Mattias Wallin47c16972010-09-10 17:47:56 +0200322 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100323 info->voltage_bank, info->voltage_reg,
324 info->voltage_mask, regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530325 if (ret < 0)
326 dev_err(rdev_get_dev(rdev),
327 "couldn't set voltage reg for regulator\n");
328
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100329 dev_vdbg(rdev_get_dev(rdev),
330 "%s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
331 " 0x%x\n",
332 info->desc.name, info->voltage_bank, info->voltage_reg,
333 info->voltage_mask, regval);
334
Sundar R IYERc789ca22010-07-13 21:48:56 +0530335 return ret;
336}
337
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000338static struct regulator_ops ab8500_regulator_volt_mode_ops = {
339 .enable = ab8500_regulator_enable,
340 .disable = ab8500_regulator_disable,
341 .is_enabled = ab8500_regulator_is_enabled,
342 .get_optimum_mode = ab8500_regulator_get_optimum_mode,
343 .set_mode = ab8500_regulator_set_mode,
344 .get_mode = ab8500_regulator_get_mode,
345 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
346 .set_voltage_sel = ab8500_regulator_set_voltage_sel,
347 .list_voltage = regulator_list_voltage_table,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530348};
349
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000350static struct regulator_ops ab8500_regulator_mode_ops = {
351 .enable = ab8500_regulator_enable,
352 .disable = ab8500_regulator_disable,
353 .is_enabled = ab8500_regulator_is_enabled,
354 .get_optimum_mode = ab8500_regulator_get_optimum_mode,
355 .set_mode = ab8500_regulator_set_mode,
356 .get_mode = ab8500_regulator_get_mode,
357 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
Axel Lin5689e832013-03-25 14:59:00 +0800358 .list_voltage = regulator_list_voltage_linear,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000359};
360
361static struct regulator_ops ab8500_regulator_ops = {
362 .enable = ab8500_regulator_enable,
363 .disable = ab8500_regulator_disable,
364 .is_enabled = ab8500_regulator_is_enabled,
365 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
Axel Lin5689e832013-03-25 14:59:00 +0800366 .list_voltage = regulator_list_voltage_linear,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530367};
368
Bengt Jonsson6909b452010-12-10 11:08:47 +0100369static struct ab8500_regulator_info
370 ab8500_regulator_info[AB8500_NUM_REGULATORS] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530371 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100372 * Variable Voltage Regulators
373 * name, min mV, max mV,
374 * update bank, reg, mask, enable val
Axel Linec1cc4d2012-05-20 10:33:35 +0800375 * volt bank, reg, mask
Sundar R IYERc789ca22010-07-13 21:48:56 +0530376 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100377 [AB8500_LDO_AUX1] = {
378 .desc = {
379 .name = "LDO-AUX1",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000380 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100381 .type = REGULATOR_VOLTAGE,
382 .id = AB8500_LDO_AUX1,
383 .owner = THIS_MODULE,
384 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800385 .volt_table = ldo_vauxn_voltages,
Axel Lin530158b2013-03-27 17:47:22 +0800386 .enable_time = 200,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100387 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000388 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100389 .update_bank = 0x04,
390 .update_reg = 0x09,
391 .update_mask = 0x03,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000392 .update_val = 0x01,
393 .update_val_idle = 0x03,
394 .update_val_normal = 0x01,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100395 .voltage_bank = 0x04,
396 .voltage_reg = 0x1f,
397 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100398 },
399 [AB8500_LDO_AUX2] = {
400 .desc = {
401 .name = "LDO-AUX2",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000402 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100403 .type = REGULATOR_VOLTAGE,
404 .id = AB8500_LDO_AUX2,
405 .owner = THIS_MODULE,
406 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800407 .volt_table = ldo_vauxn_voltages,
Axel Lin530158b2013-03-27 17:47:22 +0800408 .enable_time = 200,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100409 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000410 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100411 .update_bank = 0x04,
412 .update_reg = 0x09,
413 .update_mask = 0x0c,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000414 .update_val = 0x04,
415 .update_val_idle = 0x0c,
416 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100417 .voltage_bank = 0x04,
418 .voltage_reg = 0x20,
419 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100420 },
421 [AB8500_LDO_AUX3] = {
422 .desc = {
423 .name = "LDO-AUX3",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000424 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100425 .type = REGULATOR_VOLTAGE,
426 .id = AB8500_LDO_AUX3,
427 .owner = THIS_MODULE,
428 .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800429 .volt_table = ldo_vaux3_voltages,
Axel Lin530158b2013-03-27 17:47:22 +0800430 .enable_time = 450,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100431 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000432 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100433 .update_bank = 0x04,
434 .update_reg = 0x0a,
435 .update_mask = 0x03,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000436 .update_val = 0x01,
437 .update_val_idle = 0x03,
438 .update_val_normal = 0x01,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100439 .voltage_bank = 0x04,
440 .voltage_reg = 0x21,
441 .voltage_mask = 0x07,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100442 },
443 [AB8500_LDO_INTCORE] = {
444 .desc = {
445 .name = "LDO-INTCORE",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000446 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100447 .type = REGULATOR_VOLTAGE,
448 .id = AB8500_LDO_INTCORE,
449 .owner = THIS_MODULE,
450 .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800451 .volt_table = ldo_vintcore_voltages,
Axel Lin530158b2013-03-27 17:47:22 +0800452 .enable_time = 750,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100453 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000454 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100455 .update_bank = 0x03,
456 .update_reg = 0x80,
457 .update_mask = 0x44,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000458 .update_val = 0x04,
459 .update_val_idle = 0x44,
460 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100461 .voltage_bank = 0x03,
462 .voltage_reg = 0x80,
463 .voltage_mask = 0x38,
Linus Walleija0a70142012-08-20 18:41:35 +0200464 .voltage_shift = 3,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100465 },
Sundar R IYERc789ca22010-07-13 21:48:56 +0530466
467 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100468 * Fixed Voltage Regulators
469 * name, fixed mV,
470 * update bank, reg, mask, enable val
Sundar R IYERc789ca22010-07-13 21:48:56 +0530471 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100472 [AB8500_LDO_TVOUT] = {
473 .desc = {
474 .name = "LDO-TVOUT",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000475 .ops = &ab8500_regulator_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100476 .type = REGULATOR_VOLTAGE,
477 .id = AB8500_LDO_TVOUT,
478 .owner = THIS_MODULE,
479 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800480 .min_uV = 2000000,
Axel Lin7fee2af2012-08-07 22:21:23 +0800481 .enable_time = 10000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100482 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000483 .load_lp_uA = 1000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100484 .update_bank = 0x03,
485 .update_reg = 0x80,
486 .update_mask = 0x82,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000487 .update_val = 0x02,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000488 .update_val_idle = 0x82,
489 .update_val_normal = 0x02,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100490 },
Axel Lin328a5362013-03-25 14:53:50 +0800491
492 /*
493 * Regulators with fixed voltage and normal mode
494 */
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100495 [AB8500_LDO_USB] = {
496 .desc = {
497 .name = "LDO-USB",
Axel Lin328a5362013-03-25 14:53:50 +0800498 .ops = &ab8500_regulator_ops,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100499 .type = REGULATOR_VOLTAGE,
500 .id = AB8500_LDO_USB,
501 .owner = THIS_MODULE,
502 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800503 .min_uV = 3300000,
Axel Lin530158b2013-03-27 17:47:22 +0800504 .enable_time = 150,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100505 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100506 .update_bank = 0x03,
507 .update_reg = 0x82,
508 .update_mask = 0x03,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100509 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100510 [AB8500_LDO_AUDIO] = {
511 .desc = {
512 .name = "LDO-AUDIO",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000513 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100514 .type = REGULATOR_VOLTAGE,
515 .id = AB8500_LDO_AUDIO,
516 .owner = THIS_MODULE,
517 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800518 .min_uV = 2000000,
Axel Lin530158b2013-03-27 17:47:22 +0800519 .enable_time = 140,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100520 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100521 .update_bank = 0x03,
522 .update_reg = 0x83,
523 .update_mask = 0x02,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000524 .update_val = 0x02,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100525 },
526 [AB8500_LDO_ANAMIC1] = {
527 .desc = {
528 .name = "LDO-ANAMIC1",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000529 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100530 .type = REGULATOR_VOLTAGE,
531 .id = AB8500_LDO_ANAMIC1,
532 .owner = THIS_MODULE,
533 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800534 .min_uV = 2050000,
Axel Lin530158b2013-03-27 17:47:22 +0800535 .enable_time = 500,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100536 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100537 .update_bank = 0x03,
538 .update_reg = 0x83,
539 .update_mask = 0x08,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000540 .update_val = 0x08,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100541 },
542 [AB8500_LDO_ANAMIC2] = {
543 .desc = {
544 .name = "LDO-ANAMIC2",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000545 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100546 .type = REGULATOR_VOLTAGE,
547 .id = AB8500_LDO_ANAMIC2,
548 .owner = THIS_MODULE,
549 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800550 .min_uV = 2050000,
Axel Lin530158b2013-03-27 17:47:22 +0800551 .enable_time = 500,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100552 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100553 .update_bank = 0x03,
554 .update_reg = 0x83,
555 .update_mask = 0x10,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000556 .update_val = 0x10,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100557 },
558 [AB8500_LDO_DMIC] = {
559 .desc = {
560 .name = "LDO-DMIC",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000561 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100562 .type = REGULATOR_VOLTAGE,
563 .id = AB8500_LDO_DMIC,
564 .owner = THIS_MODULE,
565 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800566 .min_uV = 1800000,
Axel Lin530158b2013-03-27 17:47:22 +0800567 .enable_time = 420,
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,
Axel Lin530158b2013-03-27 17:47:22 +0800587 .enable_time = 140,
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);
Lee Jones3a8334b2012-05-17 14:45:16 +0100942 struct device_node *np = pdev->dev.of_node;
Bengt Jonsson732805a2013-03-21 15:59:03 +0000943 struct ab8500_platform_data *ppdata;
944 struct ab8500_regulator_platform_data *pdata;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530945 int i, err;
946
Lee Jones3a8334b2012-05-17 14:45:16 +0100947 if (np) {
948 err = of_regulator_match(&pdev->dev, np,
949 ab8500_regulator_matches,
950 ARRAY_SIZE(ab8500_regulator_matches));
951 if (err < 0) {
952 dev_err(&pdev->dev,
953 "Error parsing regulator init data: %d\n", err);
954 return err;
955 }
956
957 err = ab8500_regulator_of_probe(pdev, np);
958 return err;
959 }
960
Sundar R IYERc789ca22010-07-13 21:48:56 +0530961 if (!ab8500) {
962 dev_err(&pdev->dev, "null mfd parent\n");
963 return -EINVAL;
964 }
Bengt Jonsson732805a2013-03-21 15:59:03 +0000965
966 ppdata = dev_get_platdata(ab8500->dev);
967 if (!ppdata) {
968 dev_err(&pdev->dev, "null parent pdata\n");
969 return -EINVAL;
970 }
971
972 pdata = ppdata->regulator;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100973 if (!pdata) {
974 dev_err(&pdev->dev, "null pdata\n");
975 return -EINVAL;
976 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530977
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100978 /* make sure the platform data has the correct size */
979 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100980 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100981 return -EINVAL;
982 }
983
Bengt Jonsson79568b942011-03-11 11:54:46 +0100984 /* initialize registers */
Bengt Jonsson732805a2013-03-21 15:59:03 +0000985 for (i = 0; i < pdata->num_reg_init; i++) {
Lee Jones3c1b8432013-03-21 15:59:01 +0000986 int id, mask, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100987
Bengt Jonsson732805a2013-03-21 15:59:03 +0000988 id = pdata->reg_init[i].id;
989 mask = pdata->reg_init[i].mask;
990 value = pdata->reg_init[i].value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100991
992 /* check for configuration errors */
Lee Jones3c1b8432013-03-21 15:59:01 +0000993 BUG_ON(id >= AB8500_NUM_REGULATOR_REGISTERS);
Bengt Jonsson79568b942011-03-11 11:54:46 +0100994
Lee Jones3c1b8432013-03-21 15:59:01 +0000995 err = ab8500_regulator_init_registers(pdev, id, mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100996 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +0100997 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100998 }
999
Sundar R IYERc789ca22010-07-13 21:48:56 +05301000 /* register all regulators */
1001 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +01001002 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
1003 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +05301004 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +05301005 }
1006
1007 return 0;
1008}
1009
Bill Pemberton8dc995f2012-11-19 13:26:10 -05001010static int ab8500_regulator_remove(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +05301011{
1012 int i;
1013
1014 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
1015 struct ab8500_regulator_info *info = NULL;
1016 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +01001017
1018 dev_vdbg(rdev_get_dev(info->regulator),
1019 "%s-remove\n", info->desc.name);
1020
Sundar R IYERc789ca22010-07-13 21:48:56 +05301021 regulator_unregister(info->regulator);
1022 }
1023
1024 return 0;
1025}
1026
1027static struct platform_driver ab8500_regulator_driver = {
1028 .probe = ab8500_regulator_probe,
Bill Pemberton5eb9f2b2012-11-19 13:20:42 -05001029 .remove = ab8500_regulator_remove,
Sundar R IYERc789ca22010-07-13 21:48:56 +05301030 .driver = {
1031 .name = "ab8500-regulator",
1032 .owner = THIS_MODULE,
Sundar R IYERc789ca22010-07-13 21:48:56 +05301033 },
1034};
1035
1036static int __init ab8500_regulator_init(void)
1037{
1038 int ret;
1039
1040 ret = platform_driver_register(&ab8500_regulator_driver);
1041 if (ret != 0)
1042 pr_err("Failed to register ab8500 regulator: %d\n", ret);
1043
1044 return ret;
1045}
1046subsys_initcall(ab8500_regulator_init);
1047
1048static void __exit ab8500_regulator_exit(void)
1049{
1050 platform_driver_unregister(&ab8500_regulator_driver);
1051}
1052module_exit(ab8500_regulator_exit);
1053
1054MODULE_LICENSE("GPL v2");
1055MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
Bengt Jonsson732805a2013-03-21 15:59:03 +00001056MODULE_AUTHOR("Bengt Jonsson <bengt.g.jonsson@stericsson.com>");
Sundar R IYERc789ca22010-07-13 21:48:56 +05301057MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
1058MODULE_ALIAS("platform:ab8500-regulator");