blob: bf34c4cd6631dae9a2156753629720436da8756d [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,
Lee Jonescc40dc22013-03-21 15:59:41 +0000458 .update_val = 0x44,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000459 .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 },
491 [AB8500_LDO_AUDIO] = {
492 .desc = {
493 .name = "LDO-AUDIO",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000494 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100495 .type = REGULATOR_VOLTAGE,
496 .id = AB8500_LDO_AUDIO,
497 .owner = THIS_MODULE,
498 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800499 .min_uV = 2000000,
Axel Lin530158b2013-03-27 17:47:22 +0800500 .enable_time = 140,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100501 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100502 .update_bank = 0x03,
503 .update_reg = 0x83,
504 .update_mask = 0x02,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000505 .update_val = 0x02,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100506 },
507 [AB8500_LDO_ANAMIC1] = {
508 .desc = {
509 .name = "LDO-ANAMIC1",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000510 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100511 .type = REGULATOR_VOLTAGE,
512 .id = AB8500_LDO_ANAMIC1,
513 .owner = THIS_MODULE,
514 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800515 .min_uV = 2050000,
Axel Lin530158b2013-03-27 17:47:22 +0800516 .enable_time = 500,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100517 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100518 .update_bank = 0x03,
519 .update_reg = 0x83,
520 .update_mask = 0x08,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000521 .update_val = 0x08,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100522 },
523 [AB8500_LDO_ANAMIC2] = {
524 .desc = {
525 .name = "LDO-ANAMIC2",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000526 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100527 .type = REGULATOR_VOLTAGE,
528 .id = AB8500_LDO_ANAMIC2,
529 .owner = THIS_MODULE,
530 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800531 .min_uV = 2050000,
Axel Lin530158b2013-03-27 17:47:22 +0800532 .enable_time = 500,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100533 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100534 .update_bank = 0x03,
535 .update_reg = 0x83,
536 .update_mask = 0x10,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000537 .update_val = 0x10,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100538 },
539 [AB8500_LDO_DMIC] = {
540 .desc = {
541 .name = "LDO-DMIC",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000542 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100543 .type = REGULATOR_VOLTAGE,
544 .id = AB8500_LDO_DMIC,
545 .owner = THIS_MODULE,
546 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800547 .min_uV = 1800000,
Axel Lin530158b2013-03-27 17:47:22 +0800548 .enable_time = 420,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100549 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100550 .update_bank = 0x03,
551 .update_reg = 0x83,
552 .update_mask = 0x04,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000553 .update_val = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100554 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000555
556 /*
557 * Regulators with fixed voltage and normal/idle modes
558 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100559 [AB8500_LDO_ANA] = {
560 .desc = {
561 .name = "LDO-ANA",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000562 .ops = &ab8500_regulator_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100563 .type = REGULATOR_VOLTAGE,
564 .id = AB8500_LDO_ANA,
565 .owner = THIS_MODULE,
566 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800567 .min_uV = 1200000,
Axel Lin530158b2013-03-27 17:47:22 +0800568 .enable_time = 140,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100569 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000570 .load_lp_uA = 1000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100571 .update_bank = 0x04,
572 .update_reg = 0x06,
573 .update_mask = 0x0c,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000574 .update_val = 0x04,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000575 .update_val_idle = 0x0c,
576 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100577 },
578
579
Sundar R IYERc789ca22010-07-13 21:48:56 +0530580};
581
Bengt Jonsson79568b942011-03-11 11:54:46 +0100582struct ab8500_reg_init {
583 u8 bank;
584 u8 addr;
585 u8 mask;
586};
587
588#define REG_INIT(_id, _bank, _addr, _mask) \
589 [_id] = { \
590 .bank = _bank, \
591 .addr = _addr, \
592 .mask = _mask, \
593 }
594
595static struct ab8500_reg_init ab8500_reg_init[] = {
596 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000597 * 0x30, VanaRequestCtrl
Bengt Jonsson79568b942011-03-11 11:54:46 +0100598 * 0xc0, VextSupply1RequestCtrl
599 */
Lee Jones43a59112013-03-21 15:59:15 +0000600 REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xf0),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100601 /*
602 * 0x03, VextSupply2RequestCtrl
603 * 0x0c, VextSupply3RequestCtrl
604 * 0x30, Vaux1RequestCtrl
605 * 0xc0, Vaux2RequestCtrl
606 */
607 REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
608 /*
609 * 0x03, Vaux3RequestCtrl
610 * 0x04, SwHPReq
611 */
612 REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
613 /*
614 * 0x08, VanaSysClkReq1HPValid
615 * 0x20, Vaux1SysClkReq1HPValid
616 * 0x40, Vaux2SysClkReq1HPValid
617 * 0x80, Vaux3SysClkReq1HPValid
618 */
Lee Jones43a59112013-03-21 15:59:15 +0000619 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100620 /*
621 * 0x10, VextSupply1SysClkReq1HPValid
622 * 0x20, VextSupply2SysClkReq1HPValid
623 * 0x40, VextSupply3SysClkReq1HPValid
624 */
Lee Jones43a59112013-03-21 15:59:15 +0000625 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100626 /*
627 * 0x08, VanaHwHPReq1Valid
628 * 0x20, Vaux1HwHPReq1Valid
629 * 0x40, Vaux2HwHPReq1Valid
630 * 0x80, Vaux3HwHPReq1Valid
631 */
Lee Jones43a59112013-03-21 15:59:15 +0000632 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100633 /*
634 * 0x01, VextSupply1HwHPReq1Valid
635 * 0x02, VextSupply2HwHPReq1Valid
636 * 0x04, VextSupply3HwHPReq1Valid
637 */
Lee Jones43a59112013-03-21 15:59:15 +0000638 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100639 /*
640 * 0x08, VanaHwHPReq2Valid
641 * 0x20, Vaux1HwHPReq2Valid
642 * 0x40, Vaux2HwHPReq2Valid
643 * 0x80, Vaux3HwHPReq2Valid
644 */
Lee Jones43a59112013-03-21 15:59:15 +0000645 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100646 /*
647 * 0x01, VextSupply1HwHPReq2Valid
648 * 0x02, VextSupply2HwHPReq2Valid
649 * 0x04, VextSupply3HwHPReq2Valid
650 */
Lee Jones43a59112013-03-21 15:59:15 +0000651 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100652 /*
653 * 0x20, VanaSwHPReqValid
654 * 0x80, Vaux1SwHPReqValid
655 */
Lee Jones43a59112013-03-21 15:59:15 +0000656 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100657 /*
658 * 0x01, Vaux2SwHPReqValid
659 * 0x02, Vaux3SwHPReqValid
660 * 0x04, VextSupply1SwHPReqValid
661 * 0x08, VextSupply2SwHPReqValid
662 * 0x10, VextSupply3SwHPReqValid
663 */
Lee Jones43a59112013-03-21 15:59:15 +0000664 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100665 /*
666 * 0x02, SysClkReq2Valid1
Lee Jones43a59112013-03-21 15:59:15 +0000667 * 0x04, SysClkReq3Valid1
668 * 0x08, SysClkReq4Valid1
669 * 0x10, SysClkReq5Valid1
670 * 0x20, SysClkReq6Valid1
671 * 0x40, SysClkReq7Valid1
Bengt Jonsson79568b942011-03-11 11:54:46 +0100672 * 0x80, SysClkReq8Valid1
673 */
674 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
675 /*
676 * 0x02, SysClkReq2Valid2
Lee Jones43a59112013-03-21 15:59:15 +0000677 * 0x04, SysClkReq3Valid2
678 * 0x08, SysClkReq4Valid2
679 * 0x10, SysClkReq5Valid2
680 * 0x20, SysClkReq6Valid2
681 * 0x40, SysClkReq7Valid2
Bengt Jonsson79568b942011-03-11 11:54:46 +0100682 * 0x80, SysClkReq8Valid2
683 */
684 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
685 /*
686 * 0x02, VTVoutEna
687 * 0x04, Vintcore12Ena
688 * 0x38, Vintcore12Sel
689 * 0x40, Vintcore12LP
690 * 0x80, VTVoutLP
691 */
692 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
693 /*
694 * 0x02, VaudioEna
695 * 0x04, VdmicEna
696 * 0x08, Vamic1Ena
697 * 0x10, Vamic2Ena
698 */
699 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
700 /*
701 * 0x01, Vamic1_dzout
702 * 0x02, Vamic2_dzout
703 */
704 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
705 /*
Lee Jones43a59112013-03-21 15:59:15 +0000706 * 0x03, VpllRegu (NOTE! PRCMU register bits)
Lee Jones33bc8f42013-03-21 15:59:02 +0000707 * 0x0c, VanaRegu
Bengt Jonsson79568b942011-03-11 11:54:46 +0100708 */
709 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
710 /*
711 * 0x01, VrefDDREna
712 * 0x02, VrefDDRSleepMode
713 */
714 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
715 /*
716 * 0x03, VextSupply1Regu
717 * 0x0c, VextSupply2Regu
718 * 0x30, VextSupply3Regu
719 * 0x40, ExtSupply2Bypass
720 * 0x80, ExtSupply3Bypass
721 */
722 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
723 /*
724 * 0x03, Vaux1Regu
725 * 0x0c, Vaux2Regu
726 */
727 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
728 /*
729 * 0x03, Vaux3Regu
730 */
Lee Jones43a59112013-03-21 15:59:15 +0000731 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100732 /*
733 * 0x0f, Vaux1Sel
734 */
735 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
736 /*
737 * 0x0f, Vaux2Sel
738 */
739 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
740 /*
741 * 0x07, Vaux3Sel
742 */
Lee Jones43a59112013-03-21 15:59:15 +0000743 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100744 /*
745 * 0x01, VextSupply12LP
746 */
747 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
748 /*
749 * 0x04, Vaux1Disch
750 * 0x08, Vaux2Disch
751 * 0x10, Vaux3Disch
752 * 0x20, Vintcore12Disch
753 * 0x40, VTVoutDisch
754 * 0x80, VaudioDisch
755 */
Lee Jones43a59112013-03-21 15:59:15 +0000756 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100757 /*
758 * 0x02, VanaDisch
759 * 0x04, VdmicPullDownEna
760 * 0x10, VdmicDisch
761 */
Lee Jones43a59112013-03-21 15:59:15 +0000762 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100763};
764
Lee Jones3c1b8432013-03-21 15:59:01 +0000765static int ab8500_regulator_init_registers(struct platform_device *pdev,
766 int id, int mask, int value)
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100767{
768 int err;
769
Lee Jones3c1b8432013-03-21 15:59:01 +0000770 BUG_ON(value & ~mask);
771 BUG_ON(mask & ~ab8500_reg_init[id].mask);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100772
Lee Jones3c1b8432013-03-21 15:59:01 +0000773 /* initialize register */
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100774 err = abx500_mask_and_set_register_interruptible(
775 &pdev->dev,
776 ab8500_reg_init[id].bank,
777 ab8500_reg_init[id].addr,
Lee Jones3c1b8432013-03-21 15:59:01 +0000778 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100779 if (err < 0) {
780 dev_err(&pdev->dev,
781 "Failed to initialize 0x%02x, 0x%02x.\n",
782 ab8500_reg_init[id].bank,
783 ab8500_reg_init[id].addr);
784 return err;
785 }
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100786 dev_vdbg(&pdev->dev,
Lee Jones3c1b8432013-03-21 15:59:01 +0000787 " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
788 ab8500_reg_init[id].bank,
789 ab8500_reg_init[id].addr,
790 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100791
792 return 0;
793}
794
Bill Pembertona5023572012-11-19 13:22:22 -0500795static int ab8500_regulator_register(struct platform_device *pdev,
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100796 struct regulator_init_data *init_data,
797 int id,
798 struct device_node *np)
799{
800 struct ab8500_regulator_info *info = NULL;
801 struct regulator_config config = { };
802 int err;
803
804 /* assign per-regulator data */
805 info = &ab8500_regulator_info[id];
806 info->dev = &pdev->dev;
807
808 config.dev = &pdev->dev;
809 config.init_data = init_data;
810 config.driver_data = info;
811 config.of_node = np;
812
813 /* fix for hardware before ab8500v2.0 */
814 if (abx500_get_chip_id(info->dev) < 0x20) {
815 if (info->desc.id == AB8500_LDO_AUX3) {
816 info->desc.n_voltages =
817 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800818 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100819 info->voltage_mask = 0xf;
820 }
821 }
822
823 /* register regulator with framework */
824 info->regulator = regulator_register(&info->desc, &config);
825 if (IS_ERR(info->regulator)) {
826 err = PTR_ERR(info->regulator);
827 dev_err(&pdev->dev, "failed to register regulator %s\n",
828 info->desc.name);
829 /* when we fail, un-register all earlier regulators */
830 while (--id >= 0) {
831 info = &ab8500_regulator_info[id];
832 regulator_unregister(info->regulator);
833 }
834 return err;
835 }
836
837 return 0;
838}
839
Lee Jones3a8334b2012-05-17 14:45:16 +0100840static struct of_regulator_match ab8500_regulator_matches[] = {
Lee Jones7e715b92012-05-30 12:47:26 +0800841 { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, },
842 { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, },
843 { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, },
844 { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
845 { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, },
Lee Jones7e715b92012-05-30 12:47:26 +0800846 { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, },
847 { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
848 { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
849 { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
850 { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
Lee Jones3a8334b2012-05-17 14:45:16 +0100851};
852
Bill Pembertona5023572012-11-19 13:22:22 -0500853static int
Lee Jones3a8334b2012-05-17 14:45:16 +0100854ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
855{
856 int err, i;
857
858 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
859 err = ab8500_regulator_register(
860 pdev, ab8500_regulator_matches[i].init_data,
861 i, ab8500_regulator_matches[i].of_node);
862 if (err)
863 return err;
864 }
865
866 return 0;
867}
868
Bill Pembertona5023572012-11-19 13:22:22 -0500869static int ab8500_regulator_probe(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530870{
871 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Lee Jones3a8334b2012-05-17 14:45:16 +0100872 struct device_node *np = pdev->dev.of_node;
Bengt Jonsson732805a2013-03-21 15:59:03 +0000873 struct ab8500_platform_data *ppdata;
874 struct ab8500_regulator_platform_data *pdata;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530875 int i, err;
876
Lee Jones3a8334b2012-05-17 14:45:16 +0100877 if (np) {
878 err = of_regulator_match(&pdev->dev, np,
879 ab8500_regulator_matches,
880 ARRAY_SIZE(ab8500_regulator_matches));
881 if (err < 0) {
882 dev_err(&pdev->dev,
883 "Error parsing regulator init data: %d\n", err);
884 return err;
885 }
886
887 err = ab8500_regulator_of_probe(pdev, np);
888 return err;
889 }
890
Sundar R IYERc789ca22010-07-13 21:48:56 +0530891 if (!ab8500) {
892 dev_err(&pdev->dev, "null mfd parent\n");
893 return -EINVAL;
894 }
Bengt Jonsson732805a2013-03-21 15:59:03 +0000895
896 ppdata = dev_get_platdata(ab8500->dev);
897 if (!ppdata) {
898 dev_err(&pdev->dev, "null parent pdata\n");
899 return -EINVAL;
900 }
901
902 pdata = ppdata->regulator;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100903 if (!pdata) {
904 dev_err(&pdev->dev, "null pdata\n");
905 return -EINVAL;
906 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530907
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100908 /* make sure the platform data has the correct size */
909 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100910 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100911 return -EINVAL;
912 }
913
Lee Jonesda0b0c42013-03-28 16:11:09 +0000914 /* initialize debug (initial state is recorded with this call) */
915 err = ab8500_regulator_debug_init(pdev);
916 if (err)
917 return err;
918
Bengt Jonsson79568b942011-03-11 11:54:46 +0100919 /* initialize registers */
Bengt Jonsson732805a2013-03-21 15:59:03 +0000920 for (i = 0; i < pdata->num_reg_init; i++) {
Lee Jones3c1b8432013-03-21 15:59:01 +0000921 int id, mask, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100922
Bengt Jonsson732805a2013-03-21 15:59:03 +0000923 id = pdata->reg_init[i].id;
924 mask = pdata->reg_init[i].mask;
925 value = pdata->reg_init[i].value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100926
927 /* check for configuration errors */
Lee Jones3c1b8432013-03-21 15:59:01 +0000928 BUG_ON(id >= AB8500_NUM_REGULATOR_REGISTERS);
Bengt Jonsson79568b942011-03-11 11:54:46 +0100929
Lee Jones3c1b8432013-03-21 15:59:01 +0000930 err = ab8500_regulator_init_registers(pdev, id, mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100931 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +0100932 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100933 }
934
Lee Jonesd1a82002013-03-28 16:11:01 +0000935 /* register external regulators (before Vaux1, 2 and 3) */
936 err = ab8500_ext_regulator_init(pdev);
937 if (err)
938 return err;
939
Sundar R IYERc789ca22010-07-13 21:48:56 +0530940 /* register all regulators */
941 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100942 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
943 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530944 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530945 }
946
947 return 0;
948}
949
Bill Pemberton8dc995f2012-11-19 13:26:10 -0500950static int ab8500_regulator_remove(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530951{
Lee Jonesd1a82002013-03-28 16:11:01 +0000952 int i, err;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530953
954 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
955 struct ab8500_regulator_info *info = NULL;
956 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100957
958 dev_vdbg(rdev_get_dev(info->regulator),
959 "%s-remove\n", info->desc.name);
960
Sundar R IYERc789ca22010-07-13 21:48:56 +0530961 regulator_unregister(info->regulator);
962 }
963
Lee Jonesd1a82002013-03-28 16:11:01 +0000964 /* remove external regulators (after Vaux1, 2 and 3) */
965 err = ab8500_ext_regulator_exit(pdev);
966 if (err)
967 return err;
968
Lee Jonesda0b0c42013-03-28 16:11:09 +0000969 /* remove regulator debug */
970 err = ab8500_regulator_debug_exit(pdev);
971 if (err)
972 return err;
973
Sundar R IYERc789ca22010-07-13 21:48:56 +0530974 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");