blob: d9443b9b384a8799436a0c3135f093fad6b16c22 [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
Linus Walleij42ab6162011-03-17 13:25:02 +010045 * @delay: startup/set voltage delay in us
Sundar R IYERc789ca22010-07-13 21:48:56 +053046 */
47struct ab8500_regulator_info {
48 struct device *dev;
49 struct regulator_desc desc;
Sundar R IYERc789ca22010-07-13 21:48:56 +053050 struct regulator_dev *regulator;
Emeric Vigierbd28a152013-03-21 15:58:59 +000051 bool is_enabled;
Bengt Jonsson7ce46692013-03-21 15:59:00 +000052 int load_lp_uA;
Mattias Wallin47c16972010-09-10 17:47:56 +020053 u8 update_bank;
54 u8 update_reg;
Bengt Jonssone1159e62010-12-10 11:08:44 +010055 u8 update_mask;
Emeric Vigierbd28a152013-03-21 15:58:59 +000056 u8 update_val;
57 u8 update_val_idle;
58 u8 update_val_normal;
Mattias Wallin47c16972010-09-10 17:47:56 +020059 u8 voltage_bank;
60 u8 voltage_reg;
61 u8 voltage_mask;
Linus Walleija0a70142012-08-20 18:41:35 +020062 u8 voltage_shift;
Linus Walleij42ab6162011-03-17 13:25:02 +010063 unsigned int delay;
Sundar R IYERc789ca22010-07-13 21:48:56 +053064};
65
66/* voltage tables for the vauxn/vintcore supplies */
Axel Linec1cc4d2012-05-20 10:33:35 +080067static const unsigned int ldo_vauxn_voltages[] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +053068 1100000,
69 1200000,
70 1300000,
71 1400000,
72 1500000,
73 1800000,
74 1850000,
75 1900000,
76 2500000,
77 2650000,
78 2700000,
79 2750000,
80 2800000,
81 2900000,
82 3000000,
83 3300000,
84};
85
Axel Linec1cc4d2012-05-20 10:33:35 +080086static const unsigned int ldo_vaux3_voltages[] = {
Bengt Jonsson2b751512010-12-10 11:08:43 +010087 1200000,
88 1500000,
89 1800000,
90 2100000,
91 2500000,
92 2750000,
93 2790000,
94 2910000,
95};
96
Axel Linec1cc4d2012-05-20 10:33:35 +080097static const unsigned int ldo_vintcore_voltages[] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +053098 1200000,
99 1225000,
100 1250000,
101 1275000,
102 1300000,
103 1325000,
104 1350000,
105};
106
107static int ab8500_regulator_enable(struct regulator_dev *rdev)
108{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100109 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530110 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
111
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100112 if (info == NULL) {
113 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530114 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100115 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530116
Mattias Wallin47c16972010-09-10 17:47:56 +0200117 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonssone1159e62010-12-10 11:08:44 +0100118 info->update_bank, info->update_reg,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000119 info->update_mask, info->update_val);
Axel Linf71bf522013-03-26 16:13:14 +0800120 if (ret < 0) {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530121 dev_err(rdev_get_dev(rdev),
122 "couldn't set enable bits for regulator\n");
Axel Linf71bf522013-03-26 16:13:14 +0800123 return ret;
124 }
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100125
Emeric Vigierbd28a152013-03-21 15:58:59 +0000126 info->is_enabled = true;
127
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100128 dev_vdbg(rdev_get_dev(rdev),
129 "%s-enable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
130 info->desc.name, info->update_bank, info->update_reg,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000131 info->update_mask, info->update_val);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100132
Sundar R IYERc789ca22010-07-13 21:48:56 +0530133 return ret;
134}
135
136static int ab8500_regulator_disable(struct regulator_dev *rdev)
137{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100138 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530139 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
140
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100141 if (info == NULL) {
142 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530143 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100144 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530145
Mattias Wallin47c16972010-09-10 17:47:56 +0200146 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonssone1159e62010-12-10 11:08:44 +0100147 info->update_bank, info->update_reg,
148 info->update_mask, 0x0);
Axel Linf71bf522013-03-26 16:13:14 +0800149 if (ret < 0) {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530150 dev_err(rdev_get_dev(rdev),
151 "couldn't set disable bits for regulator\n");
Axel Linf71bf522013-03-26 16:13:14 +0800152 return ret;
153 }
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100154
Emeric Vigierbd28a152013-03-21 15:58:59 +0000155 info->is_enabled = false;
156
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100157 dev_vdbg(rdev_get_dev(rdev),
158 "%s-disable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
159 info->desc.name, info->update_bank, info->update_reg,
160 info->update_mask, 0x0);
161
Sundar R IYERc789ca22010-07-13 21:48:56 +0530162 return ret;
163}
164
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000165static unsigned int ab8500_regulator_get_optimum_mode(
166 struct regulator_dev *rdev, int input_uV,
167 int output_uV, int load_uA)
168{
169 unsigned int mode;
170
171 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
172
173 if (info == NULL) {
174 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
175 return -EINVAL;
176 }
177
178 if (load_uA <= info->load_lp_uA)
179 mode = REGULATOR_MODE_IDLE;
180 else
181 mode = REGULATOR_MODE_NORMAL;
182
183 return mode;
184}
185
Emeric Vigierbd28a152013-03-21 15:58:59 +0000186static int ab8500_regulator_set_mode(struct regulator_dev *rdev,
187 unsigned int mode)
188{
189 int ret = 0;
190
191 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
192
193 if (info == NULL) {
194 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
195 return -EINVAL;
196 }
197
198 switch (mode) {
199 case REGULATOR_MODE_NORMAL:
200 info->update_val = info->update_val_normal;
201 break;
202 case REGULATOR_MODE_IDLE:
203 info->update_val = info->update_val_idle;
204 break;
205 default:
206 return -EINVAL;
207 }
208
209 if (info->is_enabled) {
210 ret = abx500_mask_and_set_register_interruptible(info->dev,
211 info->update_bank, info->update_reg,
212 info->update_mask, info->update_val);
213 if (ret < 0)
214 dev_err(rdev_get_dev(rdev),
215 "couldn't set regulator mode\n");
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000216
217 dev_vdbg(rdev_get_dev(rdev),
218 "%s-set_mode (bank, reg, mask, value): "
219 "0x%x, 0x%x, 0x%x, 0x%x\n",
220 info->desc.name, info->update_bank, info->update_reg,
221 info->update_mask, info->update_val);
Emeric Vigierbd28a152013-03-21 15:58:59 +0000222 }
223
224 return ret;
225}
226
227static unsigned int ab8500_regulator_get_mode(struct regulator_dev *rdev)
228{
229 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
230 int ret;
231
232 if (info == NULL) {
233 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
234 return -EINVAL;
235 }
236
237 if (info->update_val == info->update_val_normal)
238 ret = REGULATOR_MODE_NORMAL;
239 else if (info->update_val == info->update_val_idle)
240 ret = REGULATOR_MODE_IDLE;
241 else
242 ret = -EINVAL;
243
244 return ret;
245}
246
Sundar R IYERc789ca22010-07-13 21:48:56 +0530247static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
248{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100249 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530250 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100251 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530252
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100253 if (info == NULL) {
254 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530255 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100256 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530257
Mattias Wallin47c16972010-09-10 17:47:56 +0200258 ret = abx500_get_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100259 info->update_bank, info->update_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530260 if (ret < 0) {
261 dev_err(rdev_get_dev(rdev),
262 "couldn't read 0x%x register\n", info->update_reg);
263 return ret;
264 }
265
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100266 dev_vdbg(rdev_get_dev(rdev),
267 "%s-is_enabled (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
268 " 0x%x\n",
269 info->desc.name, info->update_bank, info->update_reg,
270 info->update_mask, regval);
271
272 if (regval & info->update_mask)
Emeric Vigierbd28a152013-03-21 15:58:59 +0000273 info->is_enabled = true;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530274 else
Emeric Vigierbd28a152013-03-21 15:58:59 +0000275 info->is_enabled = false;
276
277 return info->is_enabled;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530278}
279
Axel Lin3bf6e902012-02-24 17:15:45 +0800280static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530281{
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100282 int ret, val;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530283 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100284 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530285
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100286 if (info == NULL) {
287 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530288 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100289 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530290
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100291 ret = abx500_get_register_interruptible(info->dev,
292 info->voltage_bank, info->voltage_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530293 if (ret < 0) {
294 dev_err(rdev_get_dev(rdev),
295 "couldn't read voltage reg for regulator\n");
296 return ret;
297 }
298
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100299 dev_vdbg(rdev_get_dev(rdev),
Linus Walleija0a70142012-08-20 18:41:35 +0200300 "%s-get_voltage (bank, reg, mask, shift, value): "
301 "0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
302 info->desc.name, info->voltage_bank,
303 info->voltage_reg, info->voltage_mask,
304 info->voltage_shift, regval);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100305
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100306 val = regval & info->voltage_mask;
Linus Walleija0a70142012-08-20 18:41:35 +0200307 return val >> info->voltage_shift;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530308}
309
Axel Linae713d32012-03-20 09:51:08 +0800310static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
311 unsigned selector)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530312{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100313 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530314 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100315 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530316
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100317 if (info == NULL) {
318 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530319 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100320 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530321
Sundar R IYERc789ca22010-07-13 21:48:56 +0530322 /* set the registers for the request */
Linus Walleija0a70142012-08-20 18:41:35 +0200323 regval = (u8)selector << info->voltage_shift;
Mattias Wallin47c16972010-09-10 17:47:56 +0200324 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100325 info->voltage_bank, info->voltage_reg,
326 info->voltage_mask, regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530327 if (ret < 0)
328 dev_err(rdev_get_dev(rdev),
329 "couldn't set voltage reg for regulator\n");
330
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100331 dev_vdbg(rdev_get_dev(rdev),
332 "%s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
333 " 0x%x\n",
334 info->desc.name, info->voltage_bank, info->voltage_reg,
335 info->voltage_mask, regval);
336
Sundar R IYERc789ca22010-07-13 21:48:56 +0530337 return ret;
338}
339
Linus Walleij42ab6162011-03-17 13:25:02 +0100340static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
341 unsigned int old_sel,
342 unsigned int new_sel)
343{
344 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Linus Walleij42ab6162011-03-17 13:25:02 +0100345
Linus Walleij42ab6162011-03-17 13:25:02 +0100346 return info->delay;
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,
359 .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530360};
361
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000362static struct regulator_ops ab8500_regulator_mode_ops = {
363 .enable = ab8500_regulator_enable,
364 .disable = ab8500_regulator_disable,
365 .is_enabled = ab8500_regulator_is_enabled,
366 .get_optimum_mode = ab8500_regulator_get_optimum_mode,
367 .set_mode = ab8500_regulator_set_mode,
368 .get_mode = ab8500_regulator_get_mode,
369 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
Axel Lin5689e832013-03-25 14:59:00 +0800370 .list_voltage = regulator_list_voltage_linear,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000371};
372
373static struct regulator_ops ab8500_regulator_ops = {
374 .enable = ab8500_regulator_enable,
375 .disable = ab8500_regulator_disable,
376 .is_enabled = ab8500_regulator_is_enabled,
377 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
Axel Lin5689e832013-03-25 14:59:00 +0800378 .list_voltage = regulator_list_voltage_linear,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530379};
380
Bengt Jonsson6909b452010-12-10 11:08:47 +0100381static struct ab8500_regulator_info
382 ab8500_regulator_info[AB8500_NUM_REGULATORS] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530383 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100384 * Variable Voltage Regulators
385 * name, min mV, max mV,
386 * update bank, reg, mask, enable val
Axel Linec1cc4d2012-05-20 10:33:35 +0800387 * volt bank, reg, mask
Sundar R IYERc789ca22010-07-13 21:48:56 +0530388 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100389 [AB8500_LDO_AUX1] = {
390 .desc = {
391 .name = "LDO-AUX1",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000392 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100393 .type = REGULATOR_VOLTAGE,
394 .id = AB8500_LDO_AUX1,
395 .owner = THIS_MODULE,
396 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800397 .volt_table = ldo_vauxn_voltages,
Axel Lin530158b2013-03-27 17:47:22 +0800398 .enable_time = 200,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100399 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000400 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100401 .update_bank = 0x04,
402 .update_reg = 0x09,
403 .update_mask = 0x03,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000404 .update_val = 0x01,
405 .update_val_idle = 0x03,
406 .update_val_normal = 0x01,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100407 .voltage_bank = 0x04,
408 .voltage_reg = 0x1f,
409 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100410 },
411 [AB8500_LDO_AUX2] = {
412 .desc = {
413 .name = "LDO-AUX2",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000414 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100415 .type = REGULATOR_VOLTAGE,
416 .id = AB8500_LDO_AUX2,
417 .owner = THIS_MODULE,
418 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800419 .volt_table = ldo_vauxn_voltages,
Axel Lin530158b2013-03-27 17:47:22 +0800420 .enable_time = 200,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100421 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000422 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100423 .update_bank = 0x04,
424 .update_reg = 0x09,
425 .update_mask = 0x0c,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000426 .update_val = 0x04,
427 .update_val_idle = 0x0c,
428 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100429 .voltage_bank = 0x04,
430 .voltage_reg = 0x20,
431 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100432 },
433 [AB8500_LDO_AUX3] = {
434 .desc = {
435 .name = "LDO-AUX3",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000436 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100437 .type = REGULATOR_VOLTAGE,
438 .id = AB8500_LDO_AUX3,
439 .owner = THIS_MODULE,
440 .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800441 .volt_table = ldo_vaux3_voltages,
Axel Lin530158b2013-03-27 17:47:22 +0800442 .enable_time = 450,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100443 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000444 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100445 .update_bank = 0x04,
446 .update_reg = 0x0a,
447 .update_mask = 0x03,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000448 .update_val = 0x01,
449 .update_val_idle = 0x03,
450 .update_val_normal = 0x01,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100451 .voltage_bank = 0x04,
452 .voltage_reg = 0x21,
453 .voltage_mask = 0x07,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100454 },
455 [AB8500_LDO_INTCORE] = {
456 .desc = {
457 .name = "LDO-INTCORE",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000458 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100459 .type = REGULATOR_VOLTAGE,
460 .id = AB8500_LDO_INTCORE,
461 .owner = THIS_MODULE,
462 .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800463 .volt_table = ldo_vintcore_voltages,
Axel Lin530158b2013-03-27 17:47:22 +0800464 .enable_time = 750,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100465 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000466 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100467 .update_bank = 0x03,
468 .update_reg = 0x80,
469 .update_mask = 0x44,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000470 .update_val = 0x04,
471 .update_val_idle = 0x44,
472 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100473 .voltage_bank = 0x03,
474 .voltage_reg = 0x80,
475 .voltage_mask = 0x38,
Linus Walleija0a70142012-08-20 18:41:35 +0200476 .voltage_shift = 3,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100477 },
Sundar R IYERc789ca22010-07-13 21:48:56 +0530478
479 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100480 * Fixed Voltage Regulators
481 * name, fixed mV,
482 * update bank, reg, mask, enable val
Sundar R IYERc789ca22010-07-13 21:48:56 +0530483 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100484 [AB8500_LDO_TVOUT] = {
485 .desc = {
486 .name = "LDO-TVOUT",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000487 .ops = &ab8500_regulator_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100488 .type = REGULATOR_VOLTAGE,
489 .id = AB8500_LDO_TVOUT,
490 .owner = THIS_MODULE,
491 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800492 .min_uV = 2000000,
Axel Lin7fee2af2012-08-07 22:21:23 +0800493 .enable_time = 10000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100494 },
Linus Walleij42ab6162011-03-17 13:25:02 +0100495 .delay = 10000,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000496 .load_lp_uA = 1000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100497 .update_bank = 0x03,
498 .update_reg = 0x80,
499 .update_mask = 0x82,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000500 .update_val = 0x02,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000501 .update_val_idle = 0x82,
502 .update_val_normal = 0x02,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100503 },
Axel Lin328a5362013-03-25 14:53:50 +0800504
505 /*
506 * Regulators with fixed voltage and normal mode
507 */
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100508 [AB8500_LDO_USB] = {
509 .desc = {
510 .name = "LDO-USB",
Axel Lin328a5362013-03-25 14:53:50 +0800511 .ops = &ab8500_regulator_ops,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100512 .type = REGULATOR_VOLTAGE,
513 .id = AB8500_LDO_USB,
514 .owner = THIS_MODULE,
515 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800516 .min_uV = 3300000,
Axel Lin530158b2013-03-27 17:47:22 +0800517 .enable_time = 150,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100518 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100519 .update_bank = 0x03,
520 .update_reg = 0x82,
521 .update_mask = 0x03,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100522 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100523 [AB8500_LDO_AUDIO] = {
524 .desc = {
525 .name = "LDO-AUDIO",
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_AUDIO,
529 .owner = THIS_MODULE,
530 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800531 .min_uV = 2000000,
Axel Lin530158b2013-03-27 17:47:22 +0800532 .enable_time = 140,
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 = 0x02,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000537 .update_val = 0x02,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100538 },
539 [AB8500_LDO_ANAMIC1] = {
540 .desc = {
541 .name = "LDO-ANAMIC1",
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_ANAMIC1,
545 .owner = THIS_MODULE,
546 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800547 .min_uV = 2050000,
Axel Lin530158b2013-03-27 17:47:22 +0800548 .enable_time = 500,
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 = 0x08,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000553 .update_val = 0x08,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100554 },
555 [AB8500_LDO_ANAMIC2] = {
556 .desc = {
557 .name = "LDO-ANAMIC2",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000558 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100559 .type = REGULATOR_VOLTAGE,
560 .id = AB8500_LDO_ANAMIC2,
561 .owner = THIS_MODULE,
562 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800563 .min_uV = 2050000,
Axel Lin530158b2013-03-27 17:47:22 +0800564 .enable_time = 500,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100565 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100566 .update_bank = 0x03,
567 .update_reg = 0x83,
568 .update_mask = 0x10,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000569 .update_val = 0x10,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100570 },
571 [AB8500_LDO_DMIC] = {
572 .desc = {
573 .name = "LDO-DMIC",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000574 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100575 .type = REGULATOR_VOLTAGE,
576 .id = AB8500_LDO_DMIC,
577 .owner = THIS_MODULE,
578 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800579 .min_uV = 1800000,
Axel Lin530158b2013-03-27 17:47:22 +0800580 .enable_time = 420,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100581 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100582 .update_bank = 0x03,
583 .update_reg = 0x83,
584 .update_mask = 0x04,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000585 .update_val = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100586 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000587
588 /*
589 * Regulators with fixed voltage and normal/idle modes
590 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100591 [AB8500_LDO_ANA] = {
592 .desc = {
593 .name = "LDO-ANA",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000594 .ops = &ab8500_regulator_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100595 .type = REGULATOR_VOLTAGE,
596 .id = AB8500_LDO_ANA,
597 .owner = THIS_MODULE,
598 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800599 .min_uV = 1200000,
Axel Lin530158b2013-03-27 17:47:22 +0800600 .enable_time = 140,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100601 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000602 .load_lp_uA = 1000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100603 .update_bank = 0x04,
604 .update_reg = 0x06,
605 .update_mask = 0x0c,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000606 .update_val = 0x04,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000607 .update_val_idle = 0x0c,
608 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100609 },
610
611
Sundar R IYERc789ca22010-07-13 21:48:56 +0530612};
613
Bengt Jonsson79568b942011-03-11 11:54:46 +0100614struct ab8500_reg_init {
615 u8 bank;
616 u8 addr;
617 u8 mask;
618};
619
620#define REG_INIT(_id, _bank, _addr, _mask) \
621 [_id] = { \
622 .bank = _bank, \
623 .addr = _addr, \
624 .mask = _mask, \
625 }
626
627static struct ab8500_reg_init ab8500_reg_init[] = {
628 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000629 * 0x03, VarmRequestCtrl
630 * 0x0c, VapeRequestCtrl
631 * 0x30, Vsmps1RequestCtrl
632 * 0xc0, Vsmps2RequestCtrl
633 */
634 REG_INIT(AB8500_REGUREQUESTCTRL1, 0x03, 0x03, 0xff),
635 /*
636 * 0x03, Vsmps3RequestCtrl
Lee Jonesd79df322013-03-21 15:58:58 +0000637 * 0x0c, VpllRequestCtrl
Lee Jones33bc8f42013-03-21 15:59:02 +0000638 * 0x30, VanaRequestCtrl
Bengt Jonsson79568b942011-03-11 11:54:46 +0100639 * 0xc0, VextSupply1RequestCtrl
640 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000641 REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100642 /*
643 * 0x03, VextSupply2RequestCtrl
644 * 0x0c, VextSupply3RequestCtrl
645 * 0x30, Vaux1RequestCtrl
646 * 0xc0, Vaux2RequestCtrl
647 */
648 REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
649 /*
650 * 0x03, Vaux3RequestCtrl
651 * 0x04, SwHPReq
652 */
653 REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
654 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000655 * 0x01, Vsmps1SysClkReq1HPValid
656 * 0x02, Vsmps2SysClkReq1HPValid
657 * 0x04, Vsmps3SysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100658 * 0x08, VanaSysClkReq1HPValid
Lee Jonesd79df322013-03-21 15:58:58 +0000659 * 0x10, VpllSysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100660 * 0x20, Vaux1SysClkReq1HPValid
661 * 0x40, Vaux2SysClkReq1HPValid
662 * 0x80, Vaux3SysClkReq1HPValid
663 */
Lee Jonesd79df322013-03-21 15:58:58 +0000664 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100665 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000666 * 0x01, VapeSysClkReq1HPValid
667 * 0x02, VarmSysClkReq1HPValid
668 * 0x04, VbbSysClkReq1HPValid
669 * 0x08, VmodSysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100670 * 0x10, VextSupply1SysClkReq1HPValid
671 * 0x20, VextSupply2SysClkReq1HPValid
672 * 0x40, VextSupply3SysClkReq1HPValid
673 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000674 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x7f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100675 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000676 * 0x01, Vsmps1HwHPReq1Valid
677 * 0x02, Vsmps2HwHPReq1Valid
678 * 0x04, Vsmps3HwHPReq1Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100679 * 0x08, VanaHwHPReq1Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000680 * 0x10, VpllHwHPReq1Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100681 * 0x20, Vaux1HwHPReq1Valid
682 * 0x40, Vaux2HwHPReq1Valid
683 * 0x80, Vaux3HwHPReq1Valid
684 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000685 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100686 /*
687 * 0x01, VextSupply1HwHPReq1Valid
688 * 0x02, VextSupply2HwHPReq1Valid
689 * 0x04, VextSupply3HwHPReq1Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000690 * 0x08, VmodHwHPReq1Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100691 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000692 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x0f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100693 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000694 * 0x01, Vsmps1HwHPReq2Valid
695 * 0x02, Vsmps2HwHPReq2Valid
696 * 0x03, Vsmps3HwHPReq2Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100697 * 0x08, VanaHwHPReq2Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000698 * 0x10, VpllHwHPReq2Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100699 * 0x20, Vaux1HwHPReq2Valid
700 * 0x40, Vaux2HwHPReq2Valid
701 * 0x80, Vaux3HwHPReq2Valid
702 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000703 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100704 /*
705 * 0x01, VextSupply1HwHPReq2Valid
706 * 0x02, VextSupply2HwHPReq2Valid
707 * 0x04, VextSupply3HwHPReq2Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000708 * 0x08, VmodHwHPReq2Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100709 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000710 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x0f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100711 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000712 * 0x01, VapeSwHPReqValid
713 * 0x02, VarmSwHPReqValid
714 * 0x04, Vsmps1SwHPReqValid
715 * 0x08, Vsmps2SwHPReqValid
716 * 0x10, Vsmps3SwHPReqValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100717 * 0x20, VanaSwHPReqValid
Lee Jones33bc8f42013-03-21 15:59:02 +0000718 * 0x40, VpllSwHPReqValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100719 * 0x80, Vaux1SwHPReqValid
720 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000721 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100722 /*
723 * 0x01, Vaux2SwHPReqValid
724 * 0x02, Vaux3SwHPReqValid
725 * 0x04, VextSupply1SwHPReqValid
726 * 0x08, VextSupply2SwHPReqValid
727 * 0x10, VextSupply3SwHPReqValid
Lee Jones33bc8f42013-03-21 15:59:02 +0000728 * 0x20, VmodSwHPReqValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100729 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000730 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x3f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100731 /*
732 * 0x02, SysClkReq2Valid1
733 * ...
734 * 0x80, SysClkReq8Valid1
735 */
736 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
737 /*
738 * 0x02, SysClkReq2Valid2
739 * ...
740 * 0x80, SysClkReq8Valid2
741 */
742 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
743 /*
744 * 0x02, VTVoutEna
745 * 0x04, Vintcore12Ena
746 * 0x38, Vintcore12Sel
747 * 0x40, Vintcore12LP
748 * 0x80, VTVoutLP
749 */
750 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
751 /*
752 * 0x02, VaudioEna
753 * 0x04, VdmicEna
754 * 0x08, Vamic1Ena
755 * 0x10, Vamic2Ena
756 */
757 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
758 /*
759 * 0x01, Vamic1_dzout
760 * 0x02, Vamic2_dzout
761 */
762 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
763 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000764 * 0x03, Vsmps1Regu
765 * 0x0c, Vsmps1SelCtrl
Lee Jones33bc8f42013-03-21 15:59:02 +0000766 * 0x10, Vsmps1AutoMode
767 * 0x20, Vsmps1PWMMode
Lee Jonesd79df322013-03-21 15:58:58 +0000768 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000769 REG_INIT(AB8500_VSMPS1REGU, 0x04, 0x03, 0x3f),
Lee Jonesd79df322013-03-21 15:58:58 +0000770 /*
771 * 0x03, Vsmps2Regu
772 * 0x0c, Vsmps2SelCtrl
Lee Jones33bc8f42013-03-21 15:59:02 +0000773 * 0x10, Vsmps2AutoMode
774 * 0x20, Vsmps2PWMMode
Lee Jonesd79df322013-03-21 15:58:58 +0000775 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000776 REG_INIT(AB8500_VSMPS2REGU, 0x04, 0x04, 0x3f),
Lee Jonesd79df322013-03-21 15:58:58 +0000777 /*
Bengt Jonsson79568b942011-03-11 11:54:46 +0100778 * 0x03, VpllRegu
Lee Jones33bc8f42013-03-21 15:59:02 +0000779 * 0x0c, VanaRegu
Bengt Jonsson79568b942011-03-11 11:54:46 +0100780 */
781 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
782 /*
783 * 0x01, VrefDDREna
784 * 0x02, VrefDDRSleepMode
785 */
786 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
787 /*
788 * 0x03, VextSupply1Regu
789 * 0x0c, VextSupply2Regu
790 * 0x30, VextSupply3Regu
791 * 0x40, ExtSupply2Bypass
792 * 0x80, ExtSupply3Bypass
793 */
794 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
795 /*
796 * 0x03, Vaux1Regu
797 * 0x0c, Vaux2Regu
798 */
799 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
800 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000801 * 0x0c, Vrf1Regu
Bengt Jonsson79568b942011-03-11 11:54:46 +0100802 * 0x03, Vaux3Regu
803 */
Lee Jonesd79df322013-03-21 15:58:58 +0000804 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x0f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100805 /*
806 * 0x3f, Vsmps1Sel1
807 */
808 REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f),
809 /*
810 * 0x0f, Vaux1Sel
811 */
812 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
813 /*
814 * 0x0f, Vaux2Sel
815 */
816 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
817 /*
818 * 0x07, Vaux3Sel
Lee Jones33bc8f42013-03-21 15:59:02 +0000819 * 0x30, Vrf1Sel
Bengt Jonsson79568b942011-03-11 11:54:46 +0100820 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000821 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x37),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100822 /*
823 * 0x01, VextSupply12LP
824 */
825 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
826 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000827 * 0x01, VpllDisch
828 * 0x02, Vrf1Disch
Bengt Jonsson79568b942011-03-11 11:54:46 +0100829 * 0x04, Vaux1Disch
830 * 0x08, Vaux2Disch
831 * 0x10, Vaux3Disch
832 * 0x20, Vintcore12Disch
833 * 0x40, VTVoutDisch
834 * 0x80, VaudioDisch
835 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000836 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100837 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000838 * 0x01, VsimDisch
Bengt Jonsson79568b942011-03-11 11:54:46 +0100839 * 0x02, VanaDisch
840 * 0x04, VdmicPullDownEna
Lee Jones33bc8f42013-03-21 15:59:02 +0000841 * 0x08, VpllPullDownEna
Bengt Jonsson79568b942011-03-11 11:54:46 +0100842 * 0x10, VdmicDisch
843 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000844 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x1f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100845};
846
Lee Jones3c1b8432013-03-21 15:59:01 +0000847static int ab8500_regulator_init_registers(struct platform_device *pdev,
848 int id, int mask, int value)
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100849{
850 int err;
851
Lee Jones3c1b8432013-03-21 15:59:01 +0000852 BUG_ON(value & ~mask);
853 BUG_ON(mask & ~ab8500_reg_init[id].mask);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100854
Lee Jones3c1b8432013-03-21 15:59:01 +0000855 /* initialize register */
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100856 err = abx500_mask_and_set_register_interruptible(
857 &pdev->dev,
858 ab8500_reg_init[id].bank,
859 ab8500_reg_init[id].addr,
Lee Jones3c1b8432013-03-21 15:59:01 +0000860 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100861 if (err < 0) {
862 dev_err(&pdev->dev,
863 "Failed to initialize 0x%02x, 0x%02x.\n",
864 ab8500_reg_init[id].bank,
865 ab8500_reg_init[id].addr);
866 return err;
867 }
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100868 dev_vdbg(&pdev->dev,
Lee Jones3c1b8432013-03-21 15:59:01 +0000869 " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
870 ab8500_reg_init[id].bank,
871 ab8500_reg_init[id].addr,
872 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100873
874 return 0;
875}
876
Bill Pembertona5023572012-11-19 13:22:22 -0500877static int ab8500_regulator_register(struct platform_device *pdev,
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100878 struct regulator_init_data *init_data,
879 int id,
880 struct device_node *np)
881{
882 struct ab8500_regulator_info *info = NULL;
883 struct regulator_config config = { };
884 int err;
885
886 /* assign per-regulator data */
887 info = &ab8500_regulator_info[id];
888 info->dev = &pdev->dev;
889
890 config.dev = &pdev->dev;
891 config.init_data = init_data;
892 config.driver_data = info;
893 config.of_node = np;
894
895 /* fix for hardware before ab8500v2.0 */
896 if (abx500_get_chip_id(info->dev) < 0x20) {
897 if (info->desc.id == AB8500_LDO_AUX3) {
898 info->desc.n_voltages =
899 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800900 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100901 info->voltage_mask = 0xf;
902 }
903 }
904
905 /* register regulator with framework */
906 info->regulator = regulator_register(&info->desc, &config);
907 if (IS_ERR(info->regulator)) {
908 err = PTR_ERR(info->regulator);
909 dev_err(&pdev->dev, "failed to register regulator %s\n",
910 info->desc.name);
911 /* when we fail, un-register all earlier regulators */
912 while (--id >= 0) {
913 info = &ab8500_regulator_info[id];
914 regulator_unregister(info->regulator);
915 }
916 return err;
917 }
918
919 return 0;
920}
921
Lee Jones3a8334b2012-05-17 14:45:16 +0100922static struct of_regulator_match ab8500_regulator_matches[] = {
Lee Jones7e715b92012-05-30 12:47:26 +0800923 { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, },
924 { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, },
925 { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, },
926 { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
927 { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, },
928 { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, },
929 { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, },
930 { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
931 { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
932 { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
933 { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
Lee Jones3a8334b2012-05-17 14:45:16 +0100934};
935
Bill Pembertona5023572012-11-19 13:22:22 -0500936static int
Lee Jones3a8334b2012-05-17 14:45:16 +0100937ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
938{
939 int err, i;
940
941 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
942 err = ab8500_regulator_register(
943 pdev, ab8500_regulator_matches[i].init_data,
944 i, ab8500_regulator_matches[i].of_node);
945 if (err)
946 return err;
947 }
948
949 return 0;
950}
951
Bill Pembertona5023572012-11-19 13:22:22 -0500952static int ab8500_regulator_probe(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530953{
954 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Lee Jones3a8334b2012-05-17 14:45:16 +0100955 struct device_node *np = pdev->dev.of_node;
Bengt Jonsson732805a2013-03-21 15:59:03 +0000956 struct ab8500_platform_data *ppdata;
957 struct ab8500_regulator_platform_data *pdata;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530958 int i, err;
959
Lee Jones3a8334b2012-05-17 14:45:16 +0100960 if (np) {
961 err = of_regulator_match(&pdev->dev, np,
962 ab8500_regulator_matches,
963 ARRAY_SIZE(ab8500_regulator_matches));
964 if (err < 0) {
965 dev_err(&pdev->dev,
966 "Error parsing regulator init data: %d\n", err);
967 return err;
968 }
969
970 err = ab8500_regulator_of_probe(pdev, np);
971 return err;
972 }
973
Sundar R IYERc789ca22010-07-13 21:48:56 +0530974 if (!ab8500) {
975 dev_err(&pdev->dev, "null mfd parent\n");
976 return -EINVAL;
977 }
Bengt Jonsson732805a2013-03-21 15:59:03 +0000978
979 ppdata = dev_get_platdata(ab8500->dev);
980 if (!ppdata) {
981 dev_err(&pdev->dev, "null parent pdata\n");
982 return -EINVAL;
983 }
984
985 pdata = ppdata->regulator;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100986 if (!pdata) {
987 dev_err(&pdev->dev, "null pdata\n");
988 return -EINVAL;
989 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530990
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100991 /* make sure the platform data has the correct size */
992 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100993 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100994 return -EINVAL;
995 }
996
Bengt Jonsson79568b942011-03-11 11:54:46 +0100997 /* initialize registers */
Bengt Jonsson732805a2013-03-21 15:59:03 +0000998 for (i = 0; i < pdata->num_reg_init; i++) {
Lee Jones3c1b8432013-03-21 15:59:01 +0000999 int id, mask, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +01001000
Bengt Jonsson732805a2013-03-21 15:59:03 +00001001 id = pdata->reg_init[i].id;
1002 mask = pdata->reg_init[i].mask;
1003 value = pdata->reg_init[i].value;
Bengt Jonsson79568b942011-03-11 11:54:46 +01001004
1005 /* check for configuration errors */
Lee Jones3c1b8432013-03-21 15:59:01 +00001006 BUG_ON(id >= AB8500_NUM_REGULATOR_REGISTERS);
Bengt Jonsson79568b942011-03-11 11:54:46 +01001007
Lee Jones3c1b8432013-03-21 15:59:01 +00001008 err = ab8500_regulator_init_registers(pdev, id, mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +01001009 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +01001010 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +01001011 }
1012
Sundar R IYERc789ca22010-07-13 21:48:56 +05301013 /* register all regulators */
1014 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +01001015 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
1016 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +05301017 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +05301018 }
1019
1020 return 0;
1021}
1022
Bill Pemberton8dc995f2012-11-19 13:26:10 -05001023static int ab8500_regulator_remove(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +05301024{
1025 int i;
1026
1027 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
1028 struct ab8500_regulator_info *info = NULL;
1029 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +01001030
1031 dev_vdbg(rdev_get_dev(info->regulator),
1032 "%s-remove\n", info->desc.name);
1033
Sundar R IYERc789ca22010-07-13 21:48:56 +05301034 regulator_unregister(info->regulator);
1035 }
1036
1037 return 0;
1038}
1039
1040static struct platform_driver ab8500_regulator_driver = {
1041 .probe = ab8500_regulator_probe,
Bill Pemberton5eb9f2b2012-11-19 13:20:42 -05001042 .remove = ab8500_regulator_remove,
Sundar R IYERc789ca22010-07-13 21:48:56 +05301043 .driver = {
1044 .name = "ab8500-regulator",
1045 .owner = THIS_MODULE,
Sundar R IYERc789ca22010-07-13 21:48:56 +05301046 },
1047};
1048
1049static int __init ab8500_regulator_init(void)
1050{
1051 int ret;
1052
1053 ret = platform_driver_register(&ab8500_regulator_driver);
1054 if (ret != 0)
1055 pr_err("Failed to register ab8500 regulator: %d\n", ret);
1056
1057 return ret;
1058}
1059subsys_initcall(ab8500_regulator_init);
1060
1061static void __exit ab8500_regulator_exit(void)
1062{
1063 platform_driver_unregister(&ab8500_regulator_driver);
1064}
1065module_exit(ab8500_regulator_exit);
1066
1067MODULE_LICENSE("GPL v2");
1068MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
Bengt Jonsson732805a2013-03-21 15:59:03 +00001069MODULE_AUTHOR("Bengt Jonsson <bengt.g.jonsson@stericsson.com>");
Sundar R IYERc789ca22010-07-13 21:48:56 +05301070MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
1071MODULE_ALIAS("platform:ab8500-regulator");