blob: 919d9fa9605e801aebc4c4b4373d08dc8b0e8084 [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 * 0x30, VanaRequestCtrl
Bengt Jonsson79568b942011-03-11 11:54:46 +0100617 * 0xc0, VextSupply1RequestCtrl
618 */
Lee Jones43a59112013-03-21 15:59:15 +0000619 REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xf0),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100620 /*
621 * 0x03, VextSupply2RequestCtrl
622 * 0x0c, VextSupply3RequestCtrl
623 * 0x30, Vaux1RequestCtrl
624 * 0xc0, Vaux2RequestCtrl
625 */
626 REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
627 /*
628 * 0x03, Vaux3RequestCtrl
629 * 0x04, SwHPReq
630 */
631 REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
632 /*
633 * 0x08, VanaSysClkReq1HPValid
634 * 0x20, Vaux1SysClkReq1HPValid
635 * 0x40, Vaux2SysClkReq1HPValid
636 * 0x80, Vaux3SysClkReq1HPValid
637 */
Lee Jones43a59112013-03-21 15:59:15 +0000638 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100639 /*
640 * 0x10, VextSupply1SysClkReq1HPValid
641 * 0x20, VextSupply2SysClkReq1HPValid
642 * 0x40, VextSupply3SysClkReq1HPValid
643 */
Lee Jones43a59112013-03-21 15:59:15 +0000644 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100645 /*
646 * 0x08, VanaHwHPReq1Valid
647 * 0x20, Vaux1HwHPReq1Valid
648 * 0x40, Vaux2HwHPReq1Valid
649 * 0x80, Vaux3HwHPReq1Valid
650 */
Lee Jones43a59112013-03-21 15:59:15 +0000651 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100652 /*
653 * 0x01, VextSupply1HwHPReq1Valid
654 * 0x02, VextSupply2HwHPReq1Valid
655 * 0x04, VextSupply3HwHPReq1Valid
656 */
Lee Jones43a59112013-03-21 15:59:15 +0000657 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100658 /*
659 * 0x08, VanaHwHPReq2Valid
660 * 0x20, Vaux1HwHPReq2Valid
661 * 0x40, Vaux2HwHPReq2Valid
662 * 0x80, Vaux3HwHPReq2Valid
663 */
Lee Jones43a59112013-03-21 15:59:15 +0000664 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100665 /*
666 * 0x01, VextSupply1HwHPReq2Valid
667 * 0x02, VextSupply2HwHPReq2Valid
668 * 0x04, VextSupply3HwHPReq2Valid
669 */
Lee Jones43a59112013-03-21 15:59:15 +0000670 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100671 /*
672 * 0x20, VanaSwHPReqValid
673 * 0x80, Vaux1SwHPReqValid
674 */
Lee Jones43a59112013-03-21 15:59:15 +0000675 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100676 /*
677 * 0x01, Vaux2SwHPReqValid
678 * 0x02, Vaux3SwHPReqValid
679 * 0x04, VextSupply1SwHPReqValid
680 * 0x08, VextSupply2SwHPReqValid
681 * 0x10, VextSupply3SwHPReqValid
682 */
Lee Jones43a59112013-03-21 15:59:15 +0000683 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100684 /*
685 * 0x02, SysClkReq2Valid1
Lee Jones43a59112013-03-21 15:59:15 +0000686 * 0x04, SysClkReq3Valid1
687 * 0x08, SysClkReq4Valid1
688 * 0x10, SysClkReq5Valid1
689 * 0x20, SysClkReq6Valid1
690 * 0x40, SysClkReq7Valid1
Bengt Jonsson79568b942011-03-11 11:54:46 +0100691 * 0x80, SysClkReq8Valid1
692 */
693 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
694 /*
695 * 0x02, SysClkReq2Valid2
Lee Jones43a59112013-03-21 15:59:15 +0000696 * 0x04, SysClkReq3Valid2
697 * 0x08, SysClkReq4Valid2
698 * 0x10, SysClkReq5Valid2
699 * 0x20, SysClkReq6Valid2
700 * 0x40, SysClkReq7Valid2
Bengt Jonsson79568b942011-03-11 11:54:46 +0100701 * 0x80, SysClkReq8Valid2
702 */
703 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
704 /*
705 * 0x02, VTVoutEna
706 * 0x04, Vintcore12Ena
707 * 0x38, Vintcore12Sel
708 * 0x40, Vintcore12LP
709 * 0x80, VTVoutLP
710 */
711 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
712 /*
713 * 0x02, VaudioEna
714 * 0x04, VdmicEna
715 * 0x08, Vamic1Ena
716 * 0x10, Vamic2Ena
717 */
718 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
719 /*
720 * 0x01, Vamic1_dzout
721 * 0x02, Vamic2_dzout
722 */
723 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
724 /*
Lee Jones43a59112013-03-21 15:59:15 +0000725 * 0x03, VpllRegu (NOTE! PRCMU register bits)
Lee Jones33bc8f42013-03-21 15:59:02 +0000726 * 0x0c, VanaRegu
Bengt Jonsson79568b942011-03-11 11:54:46 +0100727 */
728 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
729 /*
730 * 0x01, VrefDDREna
731 * 0x02, VrefDDRSleepMode
732 */
733 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
734 /*
735 * 0x03, VextSupply1Regu
736 * 0x0c, VextSupply2Regu
737 * 0x30, VextSupply3Regu
738 * 0x40, ExtSupply2Bypass
739 * 0x80, ExtSupply3Bypass
740 */
741 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
742 /*
743 * 0x03, Vaux1Regu
744 * 0x0c, Vaux2Regu
745 */
746 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
747 /*
748 * 0x03, Vaux3Regu
749 */
Lee Jones43a59112013-03-21 15:59:15 +0000750 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100751 /*
752 * 0x0f, Vaux1Sel
753 */
754 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
755 /*
756 * 0x0f, Vaux2Sel
757 */
758 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
759 /*
760 * 0x07, Vaux3Sel
761 */
Lee Jones43a59112013-03-21 15:59:15 +0000762 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100763 /*
764 * 0x01, VextSupply12LP
765 */
766 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
767 /*
768 * 0x04, Vaux1Disch
769 * 0x08, Vaux2Disch
770 * 0x10, Vaux3Disch
771 * 0x20, Vintcore12Disch
772 * 0x40, VTVoutDisch
773 * 0x80, VaudioDisch
774 */
Lee Jones43a59112013-03-21 15:59:15 +0000775 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100776 /*
777 * 0x02, VanaDisch
778 * 0x04, VdmicPullDownEna
779 * 0x10, VdmicDisch
780 */
Lee Jones43a59112013-03-21 15:59:15 +0000781 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100782};
783
Lee Jones3c1b8432013-03-21 15:59:01 +0000784static int ab8500_regulator_init_registers(struct platform_device *pdev,
785 int id, int mask, int value)
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100786{
787 int err;
788
Lee Jones3c1b8432013-03-21 15:59:01 +0000789 BUG_ON(value & ~mask);
790 BUG_ON(mask & ~ab8500_reg_init[id].mask);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100791
Lee Jones3c1b8432013-03-21 15:59:01 +0000792 /* initialize register */
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100793 err = abx500_mask_and_set_register_interruptible(
794 &pdev->dev,
795 ab8500_reg_init[id].bank,
796 ab8500_reg_init[id].addr,
Lee Jones3c1b8432013-03-21 15:59:01 +0000797 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100798 if (err < 0) {
799 dev_err(&pdev->dev,
800 "Failed to initialize 0x%02x, 0x%02x.\n",
801 ab8500_reg_init[id].bank,
802 ab8500_reg_init[id].addr);
803 return err;
804 }
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100805 dev_vdbg(&pdev->dev,
Lee Jones3c1b8432013-03-21 15:59:01 +0000806 " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
807 ab8500_reg_init[id].bank,
808 ab8500_reg_init[id].addr,
809 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100810
811 return 0;
812}
813
Bill Pembertona5023572012-11-19 13:22:22 -0500814static int ab8500_regulator_register(struct platform_device *pdev,
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100815 struct regulator_init_data *init_data,
816 int id,
817 struct device_node *np)
818{
819 struct ab8500_regulator_info *info = NULL;
820 struct regulator_config config = { };
821 int err;
822
823 /* assign per-regulator data */
824 info = &ab8500_regulator_info[id];
825 info->dev = &pdev->dev;
826
827 config.dev = &pdev->dev;
828 config.init_data = init_data;
829 config.driver_data = info;
830 config.of_node = np;
831
832 /* fix for hardware before ab8500v2.0 */
833 if (abx500_get_chip_id(info->dev) < 0x20) {
834 if (info->desc.id == AB8500_LDO_AUX3) {
835 info->desc.n_voltages =
836 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800837 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100838 info->voltage_mask = 0xf;
839 }
840 }
841
842 /* register regulator with framework */
843 info->regulator = regulator_register(&info->desc, &config);
844 if (IS_ERR(info->regulator)) {
845 err = PTR_ERR(info->regulator);
846 dev_err(&pdev->dev, "failed to register regulator %s\n",
847 info->desc.name);
848 /* when we fail, un-register all earlier regulators */
849 while (--id >= 0) {
850 info = &ab8500_regulator_info[id];
851 regulator_unregister(info->regulator);
852 }
853 return err;
854 }
855
856 return 0;
857}
858
Lee Jones3a8334b2012-05-17 14:45:16 +0100859static struct of_regulator_match ab8500_regulator_matches[] = {
Lee Jones7e715b92012-05-30 12:47:26 +0800860 { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, },
861 { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, },
862 { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, },
863 { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
864 { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, },
865 { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, },
866 { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, },
867 { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
868 { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
869 { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
870 { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
Lee Jones3a8334b2012-05-17 14:45:16 +0100871};
872
Bill Pembertona5023572012-11-19 13:22:22 -0500873static int
Lee Jones3a8334b2012-05-17 14:45:16 +0100874ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
875{
876 int err, i;
877
878 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
879 err = ab8500_regulator_register(
880 pdev, ab8500_regulator_matches[i].init_data,
881 i, ab8500_regulator_matches[i].of_node);
882 if (err)
883 return err;
884 }
885
886 return 0;
887}
888
Bill Pembertona5023572012-11-19 13:22:22 -0500889static int ab8500_regulator_probe(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530890{
891 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Lee Jones3a8334b2012-05-17 14:45:16 +0100892 struct device_node *np = pdev->dev.of_node;
Bengt Jonsson732805a2013-03-21 15:59:03 +0000893 struct ab8500_platform_data *ppdata;
894 struct ab8500_regulator_platform_data *pdata;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530895 int i, err;
896
Lee Jones3a8334b2012-05-17 14:45:16 +0100897 if (np) {
898 err = of_regulator_match(&pdev->dev, np,
899 ab8500_regulator_matches,
900 ARRAY_SIZE(ab8500_regulator_matches));
901 if (err < 0) {
902 dev_err(&pdev->dev,
903 "Error parsing regulator init data: %d\n", err);
904 return err;
905 }
906
907 err = ab8500_regulator_of_probe(pdev, np);
908 return err;
909 }
910
Sundar R IYERc789ca22010-07-13 21:48:56 +0530911 if (!ab8500) {
912 dev_err(&pdev->dev, "null mfd parent\n");
913 return -EINVAL;
914 }
Bengt Jonsson732805a2013-03-21 15:59:03 +0000915
916 ppdata = dev_get_platdata(ab8500->dev);
917 if (!ppdata) {
918 dev_err(&pdev->dev, "null parent pdata\n");
919 return -EINVAL;
920 }
921
922 pdata = ppdata->regulator;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100923 if (!pdata) {
924 dev_err(&pdev->dev, "null pdata\n");
925 return -EINVAL;
926 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530927
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100928 /* make sure the platform data has the correct size */
929 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100930 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100931 return -EINVAL;
932 }
933
Bengt Jonsson79568b942011-03-11 11:54:46 +0100934 /* initialize registers */
Bengt Jonsson732805a2013-03-21 15:59:03 +0000935 for (i = 0; i < pdata->num_reg_init; i++) {
Lee Jones3c1b8432013-03-21 15:59:01 +0000936 int id, mask, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100937
Bengt Jonsson732805a2013-03-21 15:59:03 +0000938 id = pdata->reg_init[i].id;
939 mask = pdata->reg_init[i].mask;
940 value = pdata->reg_init[i].value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100941
942 /* check for configuration errors */
Lee Jones3c1b8432013-03-21 15:59:01 +0000943 BUG_ON(id >= AB8500_NUM_REGULATOR_REGISTERS);
Bengt Jonsson79568b942011-03-11 11:54:46 +0100944
Lee Jones3c1b8432013-03-21 15:59:01 +0000945 err = ab8500_regulator_init_registers(pdev, id, mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100946 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +0100947 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100948 }
949
Sundar R IYERc789ca22010-07-13 21:48:56 +0530950 /* register all regulators */
951 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100952 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
953 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530954 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530955 }
956
957 return 0;
958}
959
Bill Pemberton8dc995f2012-11-19 13:26:10 -0500960static int ab8500_regulator_remove(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530961{
962 int i;
963
964 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
965 struct ab8500_regulator_info *info = NULL;
966 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100967
968 dev_vdbg(rdev_get_dev(info->regulator),
969 "%s-remove\n", info->desc.name);
970
Sundar R IYERc789ca22010-07-13 21:48:56 +0530971 regulator_unregister(info->regulator);
972 }
973
974 return 0;
975}
976
977static struct platform_driver ab8500_regulator_driver = {
978 .probe = ab8500_regulator_probe,
Bill Pemberton5eb9f2b2012-11-19 13:20:42 -0500979 .remove = ab8500_regulator_remove,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530980 .driver = {
981 .name = "ab8500-regulator",
982 .owner = THIS_MODULE,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530983 },
984};
985
986static int __init ab8500_regulator_init(void)
987{
988 int ret;
989
990 ret = platform_driver_register(&ab8500_regulator_driver);
991 if (ret != 0)
992 pr_err("Failed to register ab8500 regulator: %d\n", ret);
993
994 return ret;
995}
996subsys_initcall(ab8500_regulator_init);
997
998static void __exit ab8500_regulator_exit(void)
999{
1000 platform_driver_unregister(&ab8500_regulator_driver);
1001}
1002module_exit(ab8500_regulator_exit);
1003
1004MODULE_LICENSE("GPL v2");
1005MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
Bengt Jonsson732805a2013-03-21 15:59:03 +00001006MODULE_AUTHOR("Bengt Jonsson <bengt.g.jonsson@stericsson.com>");
Sundar R IYERc789ca22010-07-13 21:48:56 +05301007MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
1008MODULE_ALIAS("platform:ab8500-regulator");