blob: 7ccd7fedea91e069de7f4f8b647fe9720f4dd43b [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,
Lee Jonesb54969a2013-03-28 16:11:10 +0000777 struct ab8500_reg_init *reg_init,
Lee Jones3c1b8432013-03-21 15:59:01 +0000778 int id, int mask, int value)
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100779{
780 int err;
781
Lee Jones3c1b8432013-03-21 15:59:01 +0000782 BUG_ON(value & ~mask);
Lee Jonesb54969a2013-03-28 16:11:10 +0000783 BUG_ON(mask & ~reg_init[id].mask);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100784
Lee Jones3c1b8432013-03-21 15:59:01 +0000785 /* initialize register */
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100786 err = abx500_mask_and_set_register_interruptible(
787 &pdev->dev,
Lee Jonesb54969a2013-03-28 16:11:10 +0000788 reg_init[id].bank,
789 reg_init[id].addr,
Lee Jones3c1b8432013-03-21 15:59:01 +0000790 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100791 if (err < 0) {
792 dev_err(&pdev->dev,
793 "Failed to initialize 0x%02x, 0x%02x.\n",
Lee Jonesb54969a2013-03-28 16:11:10 +0000794 reg_init[id].bank,
795 reg_init[id].addr);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100796 return err;
797 }
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100798 dev_vdbg(&pdev->dev,
Lee Jones3c1b8432013-03-21 15:59:01 +0000799 " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
Lee Jonesb54969a2013-03-28 16:11:10 +0000800 reg_init[id].bank,
801 reg_init[id].addr,
Lee Jones3c1b8432013-03-21 15:59:01 +0000802 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100803
804 return 0;
805}
806
Bill Pembertona5023572012-11-19 13:22:22 -0500807static int ab8500_regulator_register(struct platform_device *pdev,
Lee Jonesb54969a2013-03-28 16:11:10 +0000808 struct regulator_init_data *init_data,
809 struct ab8500_regulator_info *regulator_info,
810 int id, struct device_node *np)
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100811{
812 struct ab8500_regulator_info *info = NULL;
813 struct regulator_config config = { };
814 int err;
815
816 /* assign per-regulator data */
Lee Jonesb54969a2013-03-28 16:11:10 +0000817 info = &regulator_info[id];
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100818 info->dev = &pdev->dev;
819
820 config.dev = &pdev->dev;
821 config.init_data = init_data;
822 config.driver_data = info;
823 config.of_node = np;
824
825 /* fix for hardware before ab8500v2.0 */
826 if (abx500_get_chip_id(info->dev) < 0x20) {
827 if (info->desc.id == AB8500_LDO_AUX3) {
828 info->desc.n_voltages =
829 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800830 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100831 info->voltage_mask = 0xf;
832 }
833 }
834
835 /* register regulator with framework */
836 info->regulator = regulator_register(&info->desc, &config);
837 if (IS_ERR(info->regulator)) {
838 err = PTR_ERR(info->regulator);
839 dev_err(&pdev->dev, "failed to register regulator %s\n",
840 info->desc.name);
841 /* when we fail, un-register all earlier regulators */
842 while (--id >= 0) {
Lee Jonesb54969a2013-03-28 16:11:10 +0000843 info = &regulator_info[id];
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100844 regulator_unregister(info->regulator);
845 }
846 return err;
847 }
848
849 return 0;
850}
851
Lee Jonesb54969a2013-03-28 16:11:10 +0000852static struct of_regulator_match ab8500_regulator_match[] = {
Lee Jones7e715b92012-05-30 12:47:26 +0800853 { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, },
854 { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, },
855 { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, },
856 { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
857 { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, },
Lee Jones7e715b92012-05-30 12:47:26 +0800858 { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, },
859 { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
860 { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
861 { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
862 { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
Lee Jones3a8334b2012-05-17 14:45:16 +0100863};
864
Bill Pembertona5023572012-11-19 13:22:22 -0500865static int
Lee Jonesb54969a2013-03-28 16:11:10 +0000866ab8500_regulator_of_probe(struct platform_device *pdev,
867 struct ab8500_regulator_info *regulator_info,
868 int regulator_info_size,
869 struct of_regulator_match *match,
870 struct device_node *np)
Lee Jones3a8334b2012-05-17 14:45:16 +0100871{
872 int err, i;
873
Lee Jonesb54969a2013-03-28 16:11:10 +0000874 for (i = 0; i < regulator_info_size; i++) {
Lee Jones3a8334b2012-05-17 14:45:16 +0100875 err = ab8500_regulator_register(
Lee Jonesb54969a2013-03-28 16:11:10 +0000876 pdev, match[i].init_data, regulator_info,
877 i, match[i].of_node);
Lee Jones3a8334b2012-05-17 14:45:16 +0100878 if (err)
879 return err;
880 }
881
882 return 0;
883}
884
Bill Pembertona5023572012-11-19 13:22:22 -0500885static int ab8500_regulator_probe(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530886{
887 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Lee Jones3a8334b2012-05-17 14:45:16 +0100888 struct device_node *np = pdev->dev.of_node;
Lee Jonesb54969a2013-03-28 16:11:10 +0000889 struct of_regulator_match *match;
Bengt Jonsson732805a2013-03-21 15:59:03 +0000890 struct ab8500_platform_data *ppdata;
891 struct ab8500_regulator_platform_data *pdata;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530892 int i, err;
Lee Jonesb54969a2013-03-28 16:11:10 +0000893 struct ab8500_regulator_info *regulator_info;
894 int regulator_info_size;
895 struct ab8500_reg_init *reg_init;
896 int reg_init_size;
897
898 regulator_info = ab8500_regulator_info;
899 regulator_info_size = ARRAY_SIZE(ab8500_regulator_info);
900 reg_init = ab8500_reg_init;
901 reg_init_size = AB8500_NUM_REGULATOR_REGISTERS;
902 match = ab8500_regulator_match;
903 match_size = ARRAY_SIZE(ab8500_regulator_match)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530904
Lee Jones3a8334b2012-05-17 14:45:16 +0100905 if (np) {
Lee Jonesb54969a2013-03-28 16:11:10 +0000906 err = of_regulator_match(&pdev->dev, np, match, match_size);
Lee Jones3a8334b2012-05-17 14:45:16 +0100907 if (err < 0) {
908 dev_err(&pdev->dev,
909 "Error parsing regulator init data: %d\n", err);
910 return err;
911 }
912
Lee Jonesb54969a2013-03-28 16:11:10 +0000913 err = ab8500_regulator_of_probe(pdev, regulator_info,
914 regulator_info_size, match, np);
Lee Jones3a8334b2012-05-17 14:45:16 +0100915 return err;
916 }
917
Sundar R IYERc789ca22010-07-13 21:48:56 +0530918 if (!ab8500) {
919 dev_err(&pdev->dev, "null mfd parent\n");
920 return -EINVAL;
921 }
Bengt Jonsson732805a2013-03-21 15:59:03 +0000922
923 ppdata = dev_get_platdata(ab8500->dev);
924 if (!ppdata) {
925 dev_err(&pdev->dev, "null parent pdata\n");
926 return -EINVAL;
927 }
928
929 pdata = ppdata->regulator;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100930 if (!pdata) {
931 dev_err(&pdev->dev, "null pdata\n");
932 return -EINVAL;
933 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530934
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100935 /* make sure the platform data has the correct size */
Lee Jonesb54969a2013-03-28 16:11:10 +0000936 if (pdata->num_regulator != regulator_info_size) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100937 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100938 return -EINVAL;
939 }
940
Lee Jonesda0b0c42013-03-28 16:11:09 +0000941 /* initialize debug (initial state is recorded with this call) */
942 err = ab8500_regulator_debug_init(pdev);
943 if (err)
944 return err;
945
Bengt Jonsson79568b942011-03-11 11:54:46 +0100946 /* initialize registers */
Bengt Jonsson732805a2013-03-21 15:59:03 +0000947 for (i = 0; i < pdata->num_reg_init; i++) {
Lee Jones3c1b8432013-03-21 15:59:01 +0000948 int id, mask, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100949
Bengt Jonsson732805a2013-03-21 15:59:03 +0000950 id = pdata->reg_init[i].id;
951 mask = pdata->reg_init[i].mask;
952 value = pdata->reg_init[i].value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100953
954 /* check for configuration errors */
Lee Jones3c1b8432013-03-21 15:59:01 +0000955 BUG_ON(id >= AB8500_NUM_REGULATOR_REGISTERS);
Bengt Jonsson79568b942011-03-11 11:54:46 +0100956
Lee Jonesb54969a2013-03-28 16:11:10 +0000957 err = ab8500_regulator_init_registers(pdev, reg_init, id, mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100958 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +0100959 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100960 }
961
Lee Jonesd1a82002013-03-28 16:11:01 +0000962 /* register external regulators (before Vaux1, 2 and 3) */
963 err = ab8500_ext_regulator_init(pdev);
964 if (err)
965 return err;
966
Sundar R IYERc789ca22010-07-13 21:48:56 +0530967 /* register all regulators */
Lee Jonesb54969a2013-03-28 16:11:10 +0000968 for (i = 0; i < regulator_info_size; i++) {
969 err = ab8500_regulator_register(pdev, &pdata->regulator[i],
970 regulator_info, i, NULL);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100971 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530972 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530973 }
974
975 return 0;
976}
977
Bill Pemberton8dc995f2012-11-19 13:26:10 -0500978static int ab8500_regulator_remove(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530979{
Lee Jonesd1a82002013-03-28 16:11:01 +0000980 int i, err;
Lee Jonesb54969a2013-03-28 16:11:10 +0000981 struct ab8500_regulator_info *regulator_info;
982 int regulator_info_size;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530983
Lee Jonesb54969a2013-03-28 16:11:10 +0000984 regulator_info = ab8500_regulator_info;
985 regulator_info_size = ARRAY_SIZE(ab8500_regulator_info);
986
987 for (i = 0; i < regulator_info_size; i++) {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530988 struct ab8500_regulator_info *info = NULL;
Lee Jonesb54969a2013-03-28 16:11:10 +0000989 info = &regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100990
991 dev_vdbg(rdev_get_dev(info->regulator),
992 "%s-remove\n", info->desc.name);
993
Sundar R IYERc789ca22010-07-13 21:48:56 +0530994 regulator_unregister(info->regulator);
995 }
996
Lee Jonesd1a82002013-03-28 16:11:01 +0000997 /* remove external regulators (after Vaux1, 2 and 3) */
998 err = ab8500_ext_regulator_exit(pdev);
999 if (err)
1000 return err;
1001
Lee Jonesda0b0c42013-03-28 16:11:09 +00001002 /* remove regulator debug */
1003 err = ab8500_regulator_debug_exit(pdev);
1004 if (err)
1005 return err;
1006
Sundar R IYERc789ca22010-07-13 21:48:56 +05301007 return 0;
1008}
1009
1010static struct platform_driver ab8500_regulator_driver = {
1011 .probe = ab8500_regulator_probe,
Bill Pemberton5eb9f2b2012-11-19 13:20:42 -05001012 .remove = ab8500_regulator_remove,
Sundar R IYERc789ca22010-07-13 21:48:56 +05301013 .driver = {
1014 .name = "ab8500-regulator",
1015 .owner = THIS_MODULE,
Sundar R IYERc789ca22010-07-13 21:48:56 +05301016 },
1017};
1018
1019static int __init ab8500_regulator_init(void)
1020{
1021 int ret;
1022
1023 ret = platform_driver_register(&ab8500_regulator_driver);
1024 if (ret != 0)
1025 pr_err("Failed to register ab8500 regulator: %d\n", ret);
1026
1027 return ret;
1028}
1029subsys_initcall(ab8500_regulator_init);
1030
1031static void __exit ab8500_regulator_exit(void)
1032{
1033 platform_driver_unregister(&ab8500_regulator_driver);
1034}
1035module_exit(ab8500_regulator_exit);
1036
1037MODULE_LICENSE("GPL v2");
1038MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
Bengt Jonsson732805a2013-03-21 15:59:03 +00001039MODULE_AUTHOR("Bengt Jonsson <bengt.g.jonsson@stericsson.com>");
Sundar R IYERc789ca22010-07-13 21:48:56 +05301040MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
1041MODULE_ALIAS("platform:ab8500-regulator");