blob: c7b433a2a3a9f4932a69830e5a714e0789972ce0 [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{
Axel Lin742a7322013-03-28 17:23:00 +0800187 int ret;
188 u8 update_val;
Emeric Vigierbd28a152013-03-21 15:58:59 +0000189 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:
Axel Lin742a7322013-03-28 17:23:00 +0800198 update_val = info->update_val_normal;
Emeric Vigierbd28a152013-03-21 15:58:59 +0000199 break;
200 case REGULATOR_MODE_IDLE:
Axel Lin742a7322013-03-28 17:23:00 +0800201 update_val = info->update_val_idle;
Emeric Vigierbd28a152013-03-21 15:58:59 +0000202 break;
203 default:
204 return -EINVAL;
205 }
206
Axel Lin742a7322013-03-28 17:23:00 +0800207 /* ab8500 regulators share mode and enable in the same register bits.
208 off = 0b00
209 low power mode= 0b11
210 full powermode = 0b01
211 (HW control mode = 0b10)
212 Thus we don't write to the register when regulator is disabled.
213 */
Emeric Vigierbd28a152013-03-21 15:58:59 +0000214 if (info->is_enabled) {
215 ret = abx500_mask_and_set_register_interruptible(info->dev,
216 info->update_bank, info->update_reg,
Axel Lin742a7322013-03-28 17:23:00 +0800217 info->update_mask, update_val);
218 if (ret < 0) {
Emeric Vigierbd28a152013-03-21 15:58:59 +0000219 dev_err(rdev_get_dev(rdev),
220 "couldn't set regulator mode\n");
Axel Lin742a7322013-03-28 17:23:00 +0800221 return ret;
222 }
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000223
224 dev_vdbg(rdev_get_dev(rdev),
225 "%s-set_mode (bank, reg, mask, value): "
226 "0x%x, 0x%x, 0x%x, 0x%x\n",
227 info->desc.name, info->update_bank, info->update_reg,
Axel Lin742a7322013-03-28 17:23:00 +0800228 info->update_mask, update_val);
Emeric Vigierbd28a152013-03-21 15:58:59 +0000229 }
230
Axel Lin742a7322013-03-28 17:23:00 +0800231 info->update_val = update_val;
232
233 return 0;
Emeric Vigierbd28a152013-03-21 15:58:59 +0000234}
235
236static unsigned int ab8500_regulator_get_mode(struct regulator_dev *rdev)
237{
238 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
239 int ret;
240
241 if (info == NULL) {
242 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
243 return -EINVAL;
244 }
245
246 if (info->update_val == info->update_val_normal)
247 ret = REGULATOR_MODE_NORMAL;
248 else if (info->update_val == info->update_val_idle)
249 ret = REGULATOR_MODE_IDLE;
250 else
251 ret = -EINVAL;
252
253 return ret;
254}
255
Sundar R IYERc789ca22010-07-13 21:48:56 +0530256static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
257{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100258 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530259 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100260 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530261
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100262 if (info == NULL) {
263 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530264 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100265 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530266
Mattias Wallin47c16972010-09-10 17:47:56 +0200267 ret = abx500_get_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100268 info->update_bank, info->update_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530269 if (ret < 0) {
270 dev_err(rdev_get_dev(rdev),
271 "couldn't read 0x%x register\n", info->update_reg);
272 return ret;
273 }
274
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100275 dev_vdbg(rdev_get_dev(rdev),
276 "%s-is_enabled (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
277 " 0x%x\n",
278 info->desc.name, info->update_bank, info->update_reg,
279 info->update_mask, regval);
280
281 if (regval & info->update_mask)
Emeric Vigierbd28a152013-03-21 15:58:59 +0000282 info->is_enabled = true;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530283 else
Emeric Vigierbd28a152013-03-21 15:58:59 +0000284 info->is_enabled = false;
285
286 return info->is_enabled;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530287}
288
Axel Lin3bf6e902012-02-24 17:15:45 +0800289static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530290{
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100291 int ret, val;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530292 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100293 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530294
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100295 if (info == NULL) {
296 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530297 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100298 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530299
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100300 ret = abx500_get_register_interruptible(info->dev,
301 info->voltage_bank, info->voltage_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530302 if (ret < 0) {
303 dev_err(rdev_get_dev(rdev),
304 "couldn't read voltage reg for regulator\n");
305 return ret;
306 }
307
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100308 dev_vdbg(rdev_get_dev(rdev),
Linus Walleija0a70142012-08-20 18:41:35 +0200309 "%s-get_voltage (bank, reg, mask, shift, value): "
310 "0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
311 info->desc.name, info->voltage_bank,
312 info->voltage_reg, info->voltage_mask,
313 info->voltage_shift, regval);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100314
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100315 val = regval & info->voltage_mask;
Linus Walleija0a70142012-08-20 18:41:35 +0200316 return val >> info->voltage_shift;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530317}
318
Axel Linae713d32012-03-20 09:51:08 +0800319static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
320 unsigned selector)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530321{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100322 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530323 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100324 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530325
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100326 if (info == NULL) {
327 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530328 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100329 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530330
Sundar R IYERc789ca22010-07-13 21:48:56 +0530331 /* set the registers for the request */
Linus Walleija0a70142012-08-20 18:41:35 +0200332 regval = (u8)selector << info->voltage_shift;
Mattias Wallin47c16972010-09-10 17:47:56 +0200333 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100334 info->voltage_bank, info->voltage_reg,
335 info->voltage_mask, regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530336 if (ret < 0)
337 dev_err(rdev_get_dev(rdev),
338 "couldn't set voltage reg for regulator\n");
339
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100340 dev_vdbg(rdev_get_dev(rdev),
341 "%s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
342 " 0x%x\n",
343 info->desc.name, info->voltage_bank, info->voltage_reg,
344 info->voltage_mask, regval);
345
Sundar R IYERc789ca22010-07-13 21:48:56 +0530346 return ret;
347}
348
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000349static struct regulator_ops ab8500_regulator_volt_mode_ops = {
350 .enable = ab8500_regulator_enable,
351 .disable = ab8500_regulator_disable,
352 .is_enabled = ab8500_regulator_is_enabled,
353 .get_optimum_mode = ab8500_regulator_get_optimum_mode,
354 .set_mode = ab8500_regulator_set_mode,
355 .get_mode = ab8500_regulator_get_mode,
356 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
357 .set_voltage_sel = ab8500_regulator_set_voltage_sel,
358 .list_voltage = regulator_list_voltage_table,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530359};
360
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000361static struct regulator_ops ab8500_regulator_mode_ops = {
362 .enable = ab8500_regulator_enable,
363 .disable = ab8500_regulator_disable,
364 .is_enabled = ab8500_regulator_is_enabled,
365 .get_optimum_mode = ab8500_regulator_get_optimum_mode,
366 .set_mode = ab8500_regulator_set_mode,
367 .get_mode = ab8500_regulator_get_mode,
368 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
Axel Lin5689e832013-03-25 14:59:00 +0800369 .list_voltage = regulator_list_voltage_linear,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000370};
371
372static struct regulator_ops ab8500_regulator_ops = {
373 .enable = ab8500_regulator_enable,
374 .disable = ab8500_regulator_disable,
375 .is_enabled = ab8500_regulator_is_enabled,
376 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
Axel Lin5689e832013-03-25 14:59:00 +0800377 .list_voltage = regulator_list_voltage_linear,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530378};
379
Bengt Jonsson6909b452010-12-10 11:08:47 +0100380static struct ab8500_regulator_info
381 ab8500_regulator_info[AB8500_NUM_REGULATORS] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530382 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100383 * Variable Voltage Regulators
384 * name, min mV, max mV,
385 * update bank, reg, mask, enable val
Axel Linec1cc4d2012-05-20 10:33:35 +0800386 * volt bank, reg, mask
Sundar R IYERc789ca22010-07-13 21:48:56 +0530387 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100388 [AB8500_LDO_AUX1] = {
389 .desc = {
390 .name = "LDO-AUX1",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000391 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100392 .type = REGULATOR_VOLTAGE,
393 .id = AB8500_LDO_AUX1,
394 .owner = THIS_MODULE,
395 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800396 .volt_table = ldo_vauxn_voltages,
Axel Lin530158b2013-03-27 17:47:22 +0800397 .enable_time = 200,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100398 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000399 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100400 .update_bank = 0x04,
401 .update_reg = 0x09,
402 .update_mask = 0x03,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000403 .update_val = 0x01,
404 .update_val_idle = 0x03,
405 .update_val_normal = 0x01,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100406 .voltage_bank = 0x04,
407 .voltage_reg = 0x1f,
408 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100409 },
410 [AB8500_LDO_AUX2] = {
411 .desc = {
412 .name = "LDO-AUX2",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000413 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100414 .type = REGULATOR_VOLTAGE,
415 .id = AB8500_LDO_AUX2,
416 .owner = THIS_MODULE,
417 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800418 .volt_table = ldo_vauxn_voltages,
Axel Lin530158b2013-03-27 17:47:22 +0800419 .enable_time = 200,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100420 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000421 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100422 .update_bank = 0x04,
423 .update_reg = 0x09,
424 .update_mask = 0x0c,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000425 .update_val = 0x04,
426 .update_val_idle = 0x0c,
427 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100428 .voltage_bank = 0x04,
429 .voltage_reg = 0x20,
430 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100431 },
432 [AB8500_LDO_AUX3] = {
433 .desc = {
434 .name = "LDO-AUX3",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000435 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100436 .type = REGULATOR_VOLTAGE,
437 .id = AB8500_LDO_AUX3,
438 .owner = THIS_MODULE,
439 .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800440 .volt_table = ldo_vaux3_voltages,
Axel Lin530158b2013-03-27 17:47:22 +0800441 .enable_time = 450,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100442 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000443 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100444 .update_bank = 0x04,
445 .update_reg = 0x0a,
446 .update_mask = 0x03,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000447 .update_val = 0x01,
448 .update_val_idle = 0x03,
449 .update_val_normal = 0x01,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100450 .voltage_bank = 0x04,
451 .voltage_reg = 0x21,
452 .voltage_mask = 0x07,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100453 },
454 [AB8500_LDO_INTCORE] = {
455 .desc = {
456 .name = "LDO-INTCORE",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000457 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100458 .type = REGULATOR_VOLTAGE,
459 .id = AB8500_LDO_INTCORE,
460 .owner = THIS_MODULE,
461 .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800462 .volt_table = ldo_vintcore_voltages,
Axel Lin530158b2013-03-27 17:47:22 +0800463 .enable_time = 750,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100464 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000465 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100466 .update_bank = 0x03,
467 .update_reg = 0x80,
468 .update_mask = 0x44,
Lee Jonescc40dc22013-03-21 15:59:41 +0000469 .update_val = 0x44,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000470 .update_val_idle = 0x44,
471 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100472 .voltage_bank = 0x03,
473 .voltage_reg = 0x80,
474 .voltage_mask = 0x38,
Linus Walleija0a70142012-08-20 18:41:35 +0200475 .voltage_shift = 3,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100476 },
Sundar R IYERc789ca22010-07-13 21:48:56 +0530477
478 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100479 * Fixed Voltage Regulators
480 * name, fixed mV,
481 * update bank, reg, mask, enable val
Sundar R IYERc789ca22010-07-13 21:48:56 +0530482 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100483 [AB8500_LDO_TVOUT] = {
484 .desc = {
485 .name = "LDO-TVOUT",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000486 .ops = &ab8500_regulator_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100487 .type = REGULATOR_VOLTAGE,
488 .id = AB8500_LDO_TVOUT,
489 .owner = THIS_MODULE,
490 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800491 .min_uV = 2000000,
Axel Lin7fee2af2012-08-07 22:21:23 +0800492 .enable_time = 10000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100493 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000494 .load_lp_uA = 1000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100495 .update_bank = 0x03,
496 .update_reg = 0x80,
497 .update_mask = 0x82,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000498 .update_val = 0x02,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000499 .update_val_idle = 0x82,
500 .update_val_normal = 0x02,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100501 },
502 [AB8500_LDO_AUDIO] = {
503 .desc = {
504 .name = "LDO-AUDIO",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000505 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100506 .type = REGULATOR_VOLTAGE,
507 .id = AB8500_LDO_AUDIO,
508 .owner = THIS_MODULE,
509 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800510 .min_uV = 2000000,
Axel Lin530158b2013-03-27 17:47:22 +0800511 .enable_time = 140,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100512 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100513 .update_bank = 0x03,
514 .update_reg = 0x83,
515 .update_mask = 0x02,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000516 .update_val = 0x02,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100517 },
518 [AB8500_LDO_ANAMIC1] = {
519 .desc = {
520 .name = "LDO-ANAMIC1",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000521 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100522 .type = REGULATOR_VOLTAGE,
523 .id = AB8500_LDO_ANAMIC1,
524 .owner = THIS_MODULE,
525 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800526 .min_uV = 2050000,
Axel Lin530158b2013-03-27 17:47:22 +0800527 .enable_time = 500,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100528 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100529 .update_bank = 0x03,
530 .update_reg = 0x83,
531 .update_mask = 0x08,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000532 .update_val = 0x08,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100533 },
534 [AB8500_LDO_ANAMIC2] = {
535 .desc = {
536 .name = "LDO-ANAMIC2",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000537 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100538 .type = REGULATOR_VOLTAGE,
539 .id = AB8500_LDO_ANAMIC2,
540 .owner = THIS_MODULE,
541 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800542 .min_uV = 2050000,
Axel Lin530158b2013-03-27 17:47:22 +0800543 .enable_time = 500,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100544 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100545 .update_bank = 0x03,
546 .update_reg = 0x83,
547 .update_mask = 0x10,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000548 .update_val = 0x10,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100549 },
550 [AB8500_LDO_DMIC] = {
551 .desc = {
552 .name = "LDO-DMIC",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000553 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100554 .type = REGULATOR_VOLTAGE,
555 .id = AB8500_LDO_DMIC,
556 .owner = THIS_MODULE,
557 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800558 .min_uV = 1800000,
Axel Lin530158b2013-03-27 17:47:22 +0800559 .enable_time = 420,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100560 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100561 .update_bank = 0x03,
562 .update_reg = 0x83,
563 .update_mask = 0x04,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000564 .update_val = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100565 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000566
567 /*
568 * Regulators with fixed voltage and normal/idle modes
569 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100570 [AB8500_LDO_ANA] = {
571 .desc = {
572 .name = "LDO-ANA",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000573 .ops = &ab8500_regulator_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100574 .type = REGULATOR_VOLTAGE,
575 .id = AB8500_LDO_ANA,
576 .owner = THIS_MODULE,
577 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800578 .min_uV = 1200000,
Axel Lin530158b2013-03-27 17:47:22 +0800579 .enable_time = 140,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100580 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000581 .load_lp_uA = 1000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100582 .update_bank = 0x04,
583 .update_reg = 0x06,
584 .update_mask = 0x0c,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000585 .update_val = 0x04,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000586 .update_val_idle = 0x0c,
587 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100588 },
589
590
Sundar R IYERc789ca22010-07-13 21:48:56 +0530591};
592
Bengt Jonsson79568b942011-03-11 11:54:46 +0100593struct ab8500_reg_init {
594 u8 bank;
595 u8 addr;
596 u8 mask;
597};
598
599#define REG_INIT(_id, _bank, _addr, _mask) \
600 [_id] = { \
601 .bank = _bank, \
602 .addr = _addr, \
603 .mask = _mask, \
604 }
605
606static struct ab8500_reg_init ab8500_reg_init[] = {
607 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000608 * 0x30, VanaRequestCtrl
Bengt Jonsson79568b942011-03-11 11:54:46 +0100609 * 0xc0, VextSupply1RequestCtrl
610 */
Lee Jones43a59112013-03-21 15:59:15 +0000611 REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xf0),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100612 /*
613 * 0x03, VextSupply2RequestCtrl
614 * 0x0c, VextSupply3RequestCtrl
615 * 0x30, Vaux1RequestCtrl
616 * 0xc0, Vaux2RequestCtrl
617 */
618 REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
619 /*
620 * 0x03, Vaux3RequestCtrl
621 * 0x04, SwHPReq
622 */
623 REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
624 /*
625 * 0x08, VanaSysClkReq1HPValid
626 * 0x20, Vaux1SysClkReq1HPValid
627 * 0x40, Vaux2SysClkReq1HPValid
628 * 0x80, Vaux3SysClkReq1HPValid
629 */
Lee Jones43a59112013-03-21 15:59:15 +0000630 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100631 /*
632 * 0x10, VextSupply1SysClkReq1HPValid
633 * 0x20, VextSupply2SysClkReq1HPValid
634 * 0x40, VextSupply3SysClkReq1HPValid
635 */
Lee Jones43a59112013-03-21 15:59:15 +0000636 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100637 /*
638 * 0x08, VanaHwHPReq1Valid
639 * 0x20, Vaux1HwHPReq1Valid
640 * 0x40, Vaux2HwHPReq1Valid
641 * 0x80, Vaux3HwHPReq1Valid
642 */
Lee Jones43a59112013-03-21 15:59:15 +0000643 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100644 /*
645 * 0x01, VextSupply1HwHPReq1Valid
646 * 0x02, VextSupply2HwHPReq1Valid
647 * 0x04, VextSupply3HwHPReq1Valid
648 */
Lee Jones43a59112013-03-21 15:59:15 +0000649 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100650 /*
651 * 0x08, VanaHwHPReq2Valid
652 * 0x20, Vaux1HwHPReq2Valid
653 * 0x40, Vaux2HwHPReq2Valid
654 * 0x80, Vaux3HwHPReq2Valid
655 */
Lee Jones43a59112013-03-21 15:59:15 +0000656 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100657 /*
658 * 0x01, VextSupply1HwHPReq2Valid
659 * 0x02, VextSupply2HwHPReq2Valid
660 * 0x04, VextSupply3HwHPReq2Valid
661 */
Lee Jones43a59112013-03-21 15:59:15 +0000662 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100663 /*
664 * 0x20, VanaSwHPReqValid
665 * 0x80, Vaux1SwHPReqValid
666 */
Lee Jones43a59112013-03-21 15:59:15 +0000667 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100668 /*
669 * 0x01, Vaux2SwHPReqValid
670 * 0x02, Vaux3SwHPReqValid
671 * 0x04, VextSupply1SwHPReqValid
672 * 0x08, VextSupply2SwHPReqValid
673 * 0x10, VextSupply3SwHPReqValid
674 */
Lee Jones43a59112013-03-21 15:59:15 +0000675 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100676 /*
677 * 0x02, SysClkReq2Valid1
Lee Jones43a59112013-03-21 15:59:15 +0000678 * 0x04, SysClkReq3Valid1
679 * 0x08, SysClkReq4Valid1
680 * 0x10, SysClkReq5Valid1
681 * 0x20, SysClkReq6Valid1
682 * 0x40, SysClkReq7Valid1
Bengt Jonsson79568b942011-03-11 11:54:46 +0100683 * 0x80, SysClkReq8Valid1
684 */
685 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
686 /*
687 * 0x02, SysClkReq2Valid2
Lee Jones43a59112013-03-21 15:59:15 +0000688 * 0x04, SysClkReq3Valid2
689 * 0x08, SysClkReq4Valid2
690 * 0x10, SysClkReq5Valid2
691 * 0x20, SysClkReq6Valid2
692 * 0x40, SysClkReq7Valid2
Bengt Jonsson79568b942011-03-11 11:54:46 +0100693 * 0x80, SysClkReq8Valid2
694 */
695 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
696 /*
697 * 0x02, VTVoutEna
698 * 0x04, Vintcore12Ena
699 * 0x38, Vintcore12Sel
700 * 0x40, Vintcore12LP
701 * 0x80, VTVoutLP
702 */
703 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
704 /*
705 * 0x02, VaudioEna
706 * 0x04, VdmicEna
707 * 0x08, Vamic1Ena
708 * 0x10, Vamic2Ena
709 */
710 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
711 /*
712 * 0x01, Vamic1_dzout
713 * 0x02, Vamic2_dzout
714 */
715 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
716 /*
Lee Jones43a59112013-03-21 15:59:15 +0000717 * 0x03, VpllRegu (NOTE! PRCMU register bits)
Lee Jones33bc8f42013-03-21 15:59:02 +0000718 * 0x0c, VanaRegu
Bengt Jonsson79568b942011-03-11 11:54:46 +0100719 */
720 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
721 /*
722 * 0x01, VrefDDREna
723 * 0x02, VrefDDRSleepMode
724 */
725 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
726 /*
727 * 0x03, VextSupply1Regu
728 * 0x0c, VextSupply2Regu
729 * 0x30, VextSupply3Regu
730 * 0x40, ExtSupply2Bypass
731 * 0x80, ExtSupply3Bypass
732 */
733 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
734 /*
735 * 0x03, Vaux1Regu
736 * 0x0c, Vaux2Regu
737 */
738 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
739 /*
740 * 0x03, Vaux3Regu
741 */
Lee Jones43a59112013-03-21 15:59:15 +0000742 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100743 /*
744 * 0x0f, Vaux1Sel
745 */
746 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
747 /*
748 * 0x0f, Vaux2Sel
749 */
750 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
751 /*
752 * 0x07, Vaux3Sel
753 */
Lee Jones43a59112013-03-21 15:59:15 +0000754 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100755 /*
756 * 0x01, VextSupply12LP
757 */
758 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
759 /*
760 * 0x04, Vaux1Disch
761 * 0x08, Vaux2Disch
762 * 0x10, Vaux3Disch
763 * 0x20, Vintcore12Disch
764 * 0x40, VTVoutDisch
765 * 0x80, VaudioDisch
766 */
Lee Jones43a59112013-03-21 15:59:15 +0000767 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100768 /*
769 * 0x02, VanaDisch
770 * 0x04, VdmicPullDownEna
771 * 0x10, VdmicDisch
772 */
Lee Jones43a59112013-03-21 15:59:15 +0000773 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100774};
775
Lee Jones3c1b8432013-03-21 15:59:01 +0000776static int ab8500_regulator_init_registers(struct platform_device *pdev,
777 int id, int mask, int value)
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100778{
779 int err;
780
Lee Jones3c1b8432013-03-21 15:59:01 +0000781 BUG_ON(value & ~mask);
782 BUG_ON(mask & ~ab8500_reg_init[id].mask);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100783
Lee Jones3c1b8432013-03-21 15:59:01 +0000784 /* initialize register */
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100785 err = abx500_mask_and_set_register_interruptible(
786 &pdev->dev,
787 ab8500_reg_init[id].bank,
788 ab8500_reg_init[id].addr,
Lee Jones3c1b8432013-03-21 15:59:01 +0000789 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100790 if (err < 0) {
791 dev_err(&pdev->dev,
792 "Failed to initialize 0x%02x, 0x%02x.\n",
793 ab8500_reg_init[id].bank,
794 ab8500_reg_init[id].addr);
795 return err;
796 }
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100797 dev_vdbg(&pdev->dev,
Lee Jones3c1b8432013-03-21 15:59:01 +0000798 " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
799 ab8500_reg_init[id].bank,
800 ab8500_reg_init[id].addr,
801 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100802
803 return 0;
804}
805
Bill Pembertona5023572012-11-19 13:22:22 -0500806static int ab8500_regulator_register(struct platform_device *pdev,
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100807 struct regulator_init_data *init_data,
808 int id,
809 struct device_node *np)
810{
811 struct ab8500_regulator_info *info = NULL;
812 struct regulator_config config = { };
813 int err;
814
815 /* assign per-regulator data */
816 info = &ab8500_regulator_info[id];
817 info->dev = &pdev->dev;
818
819 config.dev = &pdev->dev;
820 config.init_data = init_data;
821 config.driver_data = info;
822 config.of_node = np;
823
824 /* fix for hardware before ab8500v2.0 */
825 if (abx500_get_chip_id(info->dev) < 0x20) {
826 if (info->desc.id == AB8500_LDO_AUX3) {
827 info->desc.n_voltages =
828 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800829 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100830 info->voltage_mask = 0xf;
831 }
832 }
833
834 /* register regulator with framework */
835 info->regulator = regulator_register(&info->desc, &config);
836 if (IS_ERR(info->regulator)) {
837 err = PTR_ERR(info->regulator);
838 dev_err(&pdev->dev, "failed to register regulator %s\n",
839 info->desc.name);
840 /* when we fail, un-register all earlier regulators */
841 while (--id >= 0) {
842 info = &ab8500_regulator_info[id];
843 regulator_unregister(info->regulator);
844 }
845 return err;
846 }
847
848 return 0;
849}
850
Lee Jones3a8334b2012-05-17 14:45:16 +0100851static struct of_regulator_match ab8500_regulator_matches[] = {
Lee Jones7e715b92012-05-30 12:47:26 +0800852 { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, },
853 { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, },
854 { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, },
855 { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
856 { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, },
Lee Jones7e715b92012-05-30 12:47:26 +0800857 { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, },
858 { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
859 { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
860 { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
861 { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
Lee Jones3a8334b2012-05-17 14:45:16 +0100862};
863
Bill Pembertona5023572012-11-19 13:22:22 -0500864static int
Lee Jones3a8334b2012-05-17 14:45:16 +0100865ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
866{
867 int err, i;
868
869 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
870 err = ab8500_regulator_register(
871 pdev, ab8500_regulator_matches[i].init_data,
872 i, ab8500_regulator_matches[i].of_node);
873 if (err)
874 return err;
875 }
876
877 return 0;
878}
879
Bill Pembertona5023572012-11-19 13:22:22 -0500880static int ab8500_regulator_probe(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530881{
882 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Lee Jones3a8334b2012-05-17 14:45:16 +0100883 struct device_node *np = pdev->dev.of_node;
Bengt Jonsson732805a2013-03-21 15:59:03 +0000884 struct ab8500_platform_data *ppdata;
885 struct ab8500_regulator_platform_data *pdata;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530886 int i, err;
887
Lee Jones3a8334b2012-05-17 14:45:16 +0100888 if (np) {
889 err = of_regulator_match(&pdev->dev, np,
890 ab8500_regulator_matches,
891 ARRAY_SIZE(ab8500_regulator_matches));
892 if (err < 0) {
893 dev_err(&pdev->dev,
894 "Error parsing regulator init data: %d\n", err);
895 return err;
896 }
897
898 err = ab8500_regulator_of_probe(pdev, np);
899 return err;
900 }
901
Sundar R IYERc789ca22010-07-13 21:48:56 +0530902 if (!ab8500) {
903 dev_err(&pdev->dev, "null mfd parent\n");
904 return -EINVAL;
905 }
Bengt Jonsson732805a2013-03-21 15:59:03 +0000906
907 ppdata = dev_get_platdata(ab8500->dev);
908 if (!ppdata) {
909 dev_err(&pdev->dev, "null parent pdata\n");
910 return -EINVAL;
911 }
912
913 pdata = ppdata->regulator;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100914 if (!pdata) {
915 dev_err(&pdev->dev, "null pdata\n");
916 return -EINVAL;
917 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530918
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100919 /* make sure the platform data has the correct size */
920 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100921 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100922 return -EINVAL;
923 }
924
Lee Jonesda0b0c42013-03-28 16:11:09 +0000925 /* initialize debug (initial state is recorded with this call) */
926 err = ab8500_regulator_debug_init(pdev);
927 if (err)
928 return err;
929
Bengt Jonsson79568b942011-03-11 11:54:46 +0100930 /* initialize registers */
Bengt Jonsson732805a2013-03-21 15:59:03 +0000931 for (i = 0; i < pdata->num_reg_init; i++) {
Lee Jones3c1b8432013-03-21 15:59:01 +0000932 int id, mask, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100933
Bengt Jonsson732805a2013-03-21 15:59:03 +0000934 id = pdata->reg_init[i].id;
935 mask = pdata->reg_init[i].mask;
936 value = pdata->reg_init[i].value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100937
938 /* check for configuration errors */
Lee Jones3c1b8432013-03-21 15:59:01 +0000939 BUG_ON(id >= AB8500_NUM_REGULATOR_REGISTERS);
Bengt Jonsson79568b942011-03-11 11:54:46 +0100940
Lee Jones3c1b8432013-03-21 15:59:01 +0000941 err = ab8500_regulator_init_registers(pdev, id, mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100942 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +0100943 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100944 }
945
Lee Jonesd1a82002013-03-28 16:11:01 +0000946 /* register external regulators (before Vaux1, 2 and 3) */
947 err = ab8500_ext_regulator_init(pdev);
948 if (err)
949 return err;
950
Sundar R IYERc789ca22010-07-13 21:48:56 +0530951 /* register all regulators */
952 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100953 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
954 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530955 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530956 }
957
958 return 0;
959}
960
Bill Pemberton8dc995f2012-11-19 13:26:10 -0500961static int ab8500_regulator_remove(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530962{
Lee Jonesd1a82002013-03-28 16:11:01 +0000963 int i, err;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530964
965 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
966 struct ab8500_regulator_info *info = NULL;
967 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100968
969 dev_vdbg(rdev_get_dev(info->regulator),
970 "%s-remove\n", info->desc.name);
971
Sundar R IYERc789ca22010-07-13 21:48:56 +0530972 regulator_unregister(info->regulator);
973 }
974
Lee Jonesd1a82002013-03-28 16:11:01 +0000975 /* remove external regulators (after Vaux1, 2 and 3) */
976 err = ab8500_ext_regulator_exit(pdev);
977 if (err)
978 return err;
979
Lee Jonesda0b0c42013-03-28 16:11:09 +0000980 /* remove regulator debug */
981 err = ab8500_regulator_debug_exit(pdev);
982 if (err)
983 return err;
984
Sundar R IYERc789ca22010-07-13 21:48:56 +0530985 return 0;
986}
987
988static struct platform_driver ab8500_regulator_driver = {
989 .probe = ab8500_regulator_probe,
Bill Pemberton5eb9f2b2012-11-19 13:20:42 -0500990 .remove = ab8500_regulator_remove,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530991 .driver = {
992 .name = "ab8500-regulator",
993 .owner = THIS_MODULE,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530994 },
995};
996
997static int __init ab8500_regulator_init(void)
998{
999 int ret;
1000
1001 ret = platform_driver_register(&ab8500_regulator_driver);
1002 if (ret != 0)
1003 pr_err("Failed to register ab8500 regulator: %d\n", ret);
1004
1005 return ret;
1006}
1007subsys_initcall(ab8500_regulator_init);
1008
1009static void __exit ab8500_regulator_exit(void)
1010{
1011 platform_driver_unregister(&ab8500_regulator_driver);
1012}
1013module_exit(ab8500_regulator_exit);
1014
1015MODULE_LICENSE("GPL v2");
1016MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
Bengt Jonsson732805a2013-03-21 15:59:03 +00001017MODULE_AUTHOR("Bengt Jonsson <bengt.g.jonsson@stericsson.com>");
Sundar R IYERc789ca22010-07-13 21:48:56 +05301018MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
1019MODULE_ALIAS("platform:ab8500-regulator");