blob: 4a70323377d336034c68c53d0ec1cbb92616b4d3 [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,
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,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100419 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000420 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100421 .update_bank = 0x04,
422 .update_reg = 0x09,
423 .update_mask = 0x0c,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000424 .update_val = 0x04,
425 .update_val_idle = 0x0c,
426 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100427 .voltage_bank = 0x04,
428 .voltage_reg = 0x20,
429 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100430 },
431 [AB8500_LDO_AUX3] = {
432 .desc = {
433 .name = "LDO-AUX3",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000434 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100435 .type = REGULATOR_VOLTAGE,
436 .id = AB8500_LDO_AUX3,
437 .owner = THIS_MODULE,
438 .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800439 .volt_table = ldo_vaux3_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100440 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000441 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100442 .update_bank = 0x04,
443 .update_reg = 0x0a,
444 .update_mask = 0x03,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000445 .update_val = 0x01,
446 .update_val_idle = 0x03,
447 .update_val_normal = 0x01,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100448 .voltage_bank = 0x04,
449 .voltage_reg = 0x21,
450 .voltage_mask = 0x07,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100451 },
452 [AB8500_LDO_INTCORE] = {
453 .desc = {
454 .name = "LDO-INTCORE",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000455 .ops = &ab8500_regulator_volt_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100456 .type = REGULATOR_VOLTAGE,
457 .id = AB8500_LDO_INTCORE,
458 .owner = THIS_MODULE,
459 .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800460 .volt_table = ldo_vintcore_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100461 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000462 .load_lp_uA = 5000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100463 .update_bank = 0x03,
464 .update_reg = 0x80,
465 .update_mask = 0x44,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000466 .update_val = 0x04,
467 .update_val_idle = 0x44,
468 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100469 .voltage_bank = 0x03,
470 .voltage_reg = 0x80,
471 .voltage_mask = 0x38,
Linus Walleija0a70142012-08-20 18:41:35 +0200472 .voltage_shift = 3,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100473 },
Sundar R IYERc789ca22010-07-13 21:48:56 +0530474
475 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100476 * Fixed Voltage Regulators
477 * name, fixed mV,
478 * update bank, reg, mask, enable val
Sundar R IYERc789ca22010-07-13 21:48:56 +0530479 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100480 [AB8500_LDO_TVOUT] = {
481 .desc = {
482 .name = "LDO-TVOUT",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000483 .ops = &ab8500_regulator_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100484 .type = REGULATOR_VOLTAGE,
485 .id = AB8500_LDO_TVOUT,
486 .owner = THIS_MODULE,
487 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800488 .min_uV = 2000000,
Axel Lin7fee2af2012-08-07 22:21:23 +0800489 .enable_time = 10000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100490 },
Linus Walleij42ab6162011-03-17 13:25:02 +0100491 .delay = 10000,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000492 .load_lp_uA = 1000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100493 .update_bank = 0x03,
494 .update_reg = 0x80,
495 .update_mask = 0x82,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000496 .update_val = 0x02,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000497 .update_val_idle = 0x82,
498 .update_val_normal = 0x02,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100499 },
Axel Lin328a5362013-03-25 14:53:50 +0800500
501 /*
502 * Regulators with fixed voltage and normal mode
503 */
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100504 [AB8500_LDO_USB] = {
505 .desc = {
506 .name = "LDO-USB",
Axel Lin328a5362013-03-25 14:53:50 +0800507 .ops = &ab8500_regulator_ops,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100508 .type = REGULATOR_VOLTAGE,
509 .id = AB8500_LDO_USB,
510 .owner = THIS_MODULE,
511 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800512 .min_uV = 3300000,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100513 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100514 .update_bank = 0x03,
515 .update_reg = 0x82,
516 .update_mask = 0x03,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100517 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100518 [AB8500_LDO_AUDIO] = {
519 .desc = {
520 .name = "LDO-AUDIO",
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_AUDIO,
524 .owner = THIS_MODULE,
525 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800526 .min_uV = 2000000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100527 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100528 .update_bank = 0x03,
529 .update_reg = 0x83,
530 .update_mask = 0x02,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000531 .update_val = 0x02,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100532 },
533 [AB8500_LDO_ANAMIC1] = {
534 .desc = {
535 .name = "LDO-ANAMIC1",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000536 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100537 .type = REGULATOR_VOLTAGE,
538 .id = AB8500_LDO_ANAMIC1,
539 .owner = THIS_MODULE,
540 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800541 .min_uV = 2050000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100542 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100543 .update_bank = 0x03,
544 .update_reg = 0x83,
545 .update_mask = 0x08,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000546 .update_val = 0x08,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100547 },
548 [AB8500_LDO_ANAMIC2] = {
549 .desc = {
550 .name = "LDO-ANAMIC2",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000551 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100552 .type = REGULATOR_VOLTAGE,
553 .id = AB8500_LDO_ANAMIC2,
554 .owner = THIS_MODULE,
555 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800556 .min_uV = 2050000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100557 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100558 .update_bank = 0x03,
559 .update_reg = 0x83,
560 .update_mask = 0x10,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000561 .update_val = 0x10,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100562 },
563 [AB8500_LDO_DMIC] = {
564 .desc = {
565 .name = "LDO-DMIC",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000566 .ops = &ab8500_regulator_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100567 .type = REGULATOR_VOLTAGE,
568 .id = AB8500_LDO_DMIC,
569 .owner = THIS_MODULE,
570 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800571 .min_uV = 1800000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100572 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100573 .update_bank = 0x03,
574 .update_reg = 0x83,
575 .update_mask = 0x04,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000576 .update_val = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100577 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000578
579 /*
580 * Regulators with fixed voltage and normal/idle modes
581 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100582 [AB8500_LDO_ANA] = {
583 .desc = {
584 .name = "LDO-ANA",
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000585 .ops = &ab8500_regulator_mode_ops,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100586 .type = REGULATOR_VOLTAGE,
587 .id = AB8500_LDO_ANA,
588 .owner = THIS_MODULE,
589 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800590 .min_uV = 1200000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100591 },
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000592 .load_lp_uA = 1000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100593 .update_bank = 0x04,
594 .update_reg = 0x06,
595 .update_mask = 0x0c,
Emeric Vigierbd28a152013-03-21 15:58:59 +0000596 .update_val = 0x04,
Bengt Jonsson7ce46692013-03-21 15:59:00 +0000597 .update_val_idle = 0x0c,
598 .update_val_normal = 0x04,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100599 },
600
601
Sundar R IYERc789ca22010-07-13 21:48:56 +0530602};
603
Bengt Jonsson79568b942011-03-11 11:54:46 +0100604struct ab8500_reg_init {
605 u8 bank;
606 u8 addr;
607 u8 mask;
608};
609
610#define REG_INIT(_id, _bank, _addr, _mask) \
611 [_id] = { \
612 .bank = _bank, \
613 .addr = _addr, \
614 .mask = _mask, \
615 }
616
617static struct ab8500_reg_init ab8500_reg_init[] = {
618 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000619 * 0x03, VarmRequestCtrl
620 * 0x0c, VapeRequestCtrl
621 * 0x30, Vsmps1RequestCtrl
622 * 0xc0, Vsmps2RequestCtrl
623 */
624 REG_INIT(AB8500_REGUREQUESTCTRL1, 0x03, 0x03, 0xff),
625 /*
626 * 0x03, Vsmps3RequestCtrl
Lee Jonesd79df322013-03-21 15:58:58 +0000627 * 0x0c, VpllRequestCtrl
Lee Jones33bc8f42013-03-21 15:59:02 +0000628 * 0x30, VanaRequestCtrl
Bengt Jonsson79568b942011-03-11 11:54:46 +0100629 * 0xc0, VextSupply1RequestCtrl
630 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000631 REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100632 /*
633 * 0x03, VextSupply2RequestCtrl
634 * 0x0c, VextSupply3RequestCtrl
635 * 0x30, Vaux1RequestCtrl
636 * 0xc0, Vaux2RequestCtrl
637 */
638 REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
639 /*
640 * 0x03, Vaux3RequestCtrl
641 * 0x04, SwHPReq
642 */
643 REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
644 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000645 * 0x01, Vsmps1SysClkReq1HPValid
646 * 0x02, Vsmps2SysClkReq1HPValid
647 * 0x04, Vsmps3SysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100648 * 0x08, VanaSysClkReq1HPValid
Lee Jonesd79df322013-03-21 15:58:58 +0000649 * 0x10, VpllSysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100650 * 0x20, Vaux1SysClkReq1HPValid
651 * 0x40, Vaux2SysClkReq1HPValid
652 * 0x80, Vaux3SysClkReq1HPValid
653 */
Lee Jonesd79df322013-03-21 15:58:58 +0000654 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100655 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000656 * 0x01, VapeSysClkReq1HPValid
657 * 0x02, VarmSysClkReq1HPValid
658 * 0x04, VbbSysClkReq1HPValid
659 * 0x08, VmodSysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100660 * 0x10, VextSupply1SysClkReq1HPValid
661 * 0x20, VextSupply2SysClkReq1HPValid
662 * 0x40, VextSupply3SysClkReq1HPValid
663 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000664 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x7f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100665 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000666 * 0x01, Vsmps1HwHPReq1Valid
667 * 0x02, Vsmps2HwHPReq1Valid
668 * 0x04, Vsmps3HwHPReq1Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100669 * 0x08, VanaHwHPReq1Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000670 * 0x10, VpllHwHPReq1Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100671 * 0x20, Vaux1HwHPReq1Valid
672 * 0x40, Vaux2HwHPReq1Valid
673 * 0x80, Vaux3HwHPReq1Valid
674 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000675 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100676 /*
677 * 0x01, VextSupply1HwHPReq1Valid
678 * 0x02, VextSupply2HwHPReq1Valid
679 * 0x04, VextSupply3HwHPReq1Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000680 * 0x08, VmodHwHPReq1Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100681 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000682 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x0f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100683 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000684 * 0x01, Vsmps1HwHPReq2Valid
685 * 0x02, Vsmps2HwHPReq2Valid
686 * 0x03, Vsmps3HwHPReq2Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100687 * 0x08, VanaHwHPReq2Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000688 * 0x10, VpllHwHPReq2Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100689 * 0x20, Vaux1HwHPReq2Valid
690 * 0x40, Vaux2HwHPReq2Valid
691 * 0x80, Vaux3HwHPReq2Valid
692 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000693 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100694 /*
695 * 0x01, VextSupply1HwHPReq2Valid
696 * 0x02, VextSupply2HwHPReq2Valid
697 * 0x04, VextSupply3HwHPReq2Valid
Lee Jones33bc8f42013-03-21 15:59:02 +0000698 * 0x08, VmodHwHPReq2Valid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100699 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000700 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x0f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100701 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000702 * 0x01, VapeSwHPReqValid
703 * 0x02, VarmSwHPReqValid
704 * 0x04, Vsmps1SwHPReqValid
705 * 0x08, Vsmps2SwHPReqValid
706 * 0x10, Vsmps3SwHPReqValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100707 * 0x20, VanaSwHPReqValid
Lee Jones33bc8f42013-03-21 15:59:02 +0000708 * 0x40, VpllSwHPReqValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100709 * 0x80, Vaux1SwHPReqValid
710 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000711 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100712 /*
713 * 0x01, Vaux2SwHPReqValid
714 * 0x02, Vaux3SwHPReqValid
715 * 0x04, VextSupply1SwHPReqValid
716 * 0x08, VextSupply2SwHPReqValid
717 * 0x10, VextSupply3SwHPReqValid
Lee Jones33bc8f42013-03-21 15:59:02 +0000718 * 0x20, VmodSwHPReqValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100719 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000720 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x3f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100721 /*
722 * 0x02, SysClkReq2Valid1
723 * ...
724 * 0x80, SysClkReq8Valid1
725 */
726 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
727 /*
728 * 0x02, SysClkReq2Valid2
729 * ...
730 * 0x80, SysClkReq8Valid2
731 */
732 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
733 /*
734 * 0x02, VTVoutEna
735 * 0x04, Vintcore12Ena
736 * 0x38, Vintcore12Sel
737 * 0x40, Vintcore12LP
738 * 0x80, VTVoutLP
739 */
740 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
741 /*
742 * 0x02, VaudioEna
743 * 0x04, VdmicEna
744 * 0x08, Vamic1Ena
745 * 0x10, Vamic2Ena
746 */
747 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
748 /*
749 * 0x01, Vamic1_dzout
750 * 0x02, Vamic2_dzout
751 */
752 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
753 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000754 * 0x03, Vsmps1Regu
755 * 0x0c, Vsmps1SelCtrl
Lee Jones33bc8f42013-03-21 15:59:02 +0000756 * 0x10, Vsmps1AutoMode
757 * 0x20, Vsmps1PWMMode
Lee Jonesd79df322013-03-21 15:58:58 +0000758 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000759 REG_INIT(AB8500_VSMPS1REGU, 0x04, 0x03, 0x3f),
Lee Jonesd79df322013-03-21 15:58:58 +0000760 /*
761 * 0x03, Vsmps2Regu
762 * 0x0c, Vsmps2SelCtrl
Lee Jones33bc8f42013-03-21 15:59:02 +0000763 * 0x10, Vsmps2AutoMode
764 * 0x20, Vsmps2PWMMode
Lee Jonesd79df322013-03-21 15:58:58 +0000765 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000766 REG_INIT(AB8500_VSMPS2REGU, 0x04, 0x04, 0x3f),
Lee Jonesd79df322013-03-21 15:58:58 +0000767 /*
Bengt Jonsson79568b942011-03-11 11:54:46 +0100768 * 0x03, VpllRegu
Lee Jones33bc8f42013-03-21 15:59:02 +0000769 * 0x0c, VanaRegu
Bengt Jonsson79568b942011-03-11 11:54:46 +0100770 */
771 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
772 /*
773 * 0x01, VrefDDREna
774 * 0x02, VrefDDRSleepMode
775 */
776 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
777 /*
778 * 0x03, VextSupply1Regu
779 * 0x0c, VextSupply2Regu
780 * 0x30, VextSupply3Regu
781 * 0x40, ExtSupply2Bypass
782 * 0x80, ExtSupply3Bypass
783 */
784 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
785 /*
786 * 0x03, Vaux1Regu
787 * 0x0c, Vaux2Regu
788 */
789 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
790 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000791 * 0x0c, Vrf1Regu
Bengt Jonsson79568b942011-03-11 11:54:46 +0100792 * 0x03, Vaux3Regu
793 */
Lee Jonesd79df322013-03-21 15:58:58 +0000794 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x0f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100795 /*
796 * 0x3f, Vsmps1Sel1
797 */
798 REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f),
799 /*
800 * 0x0f, Vaux1Sel
801 */
802 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
803 /*
804 * 0x0f, Vaux2Sel
805 */
806 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
807 /*
808 * 0x07, Vaux3Sel
Lee Jones33bc8f42013-03-21 15:59:02 +0000809 * 0x30, Vrf1Sel
Bengt Jonsson79568b942011-03-11 11:54:46 +0100810 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000811 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x37),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100812 /*
813 * 0x01, VextSupply12LP
814 */
815 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
816 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000817 * 0x01, VpllDisch
818 * 0x02, Vrf1Disch
Bengt Jonsson79568b942011-03-11 11:54:46 +0100819 * 0x04, Vaux1Disch
820 * 0x08, Vaux2Disch
821 * 0x10, Vaux3Disch
822 * 0x20, Vintcore12Disch
823 * 0x40, VTVoutDisch
824 * 0x80, VaudioDisch
825 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000826 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100827 /*
Lee Jones33bc8f42013-03-21 15:59:02 +0000828 * 0x01, VsimDisch
Bengt Jonsson79568b942011-03-11 11:54:46 +0100829 * 0x02, VanaDisch
830 * 0x04, VdmicPullDownEna
Lee Jones33bc8f42013-03-21 15:59:02 +0000831 * 0x08, VpllPullDownEna
Bengt Jonsson79568b942011-03-11 11:54:46 +0100832 * 0x10, VdmicDisch
833 */
Lee Jones33bc8f42013-03-21 15:59:02 +0000834 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x1f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100835};
836
Lee Jones3c1b8432013-03-21 15:59:01 +0000837static int ab8500_regulator_init_registers(struct platform_device *pdev,
838 int id, int mask, int value)
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100839{
840 int err;
841
Lee Jones3c1b8432013-03-21 15:59:01 +0000842 BUG_ON(value & ~mask);
843 BUG_ON(mask & ~ab8500_reg_init[id].mask);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100844
Lee Jones3c1b8432013-03-21 15:59:01 +0000845 /* initialize register */
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100846 err = abx500_mask_and_set_register_interruptible(
847 &pdev->dev,
848 ab8500_reg_init[id].bank,
849 ab8500_reg_init[id].addr,
Lee Jones3c1b8432013-03-21 15:59:01 +0000850 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100851 if (err < 0) {
852 dev_err(&pdev->dev,
853 "Failed to initialize 0x%02x, 0x%02x.\n",
854 ab8500_reg_init[id].bank,
855 ab8500_reg_init[id].addr);
856 return err;
857 }
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100858 dev_vdbg(&pdev->dev,
Lee Jones3c1b8432013-03-21 15:59:01 +0000859 " init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
860 ab8500_reg_init[id].bank,
861 ab8500_reg_init[id].addr,
862 mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100863
864 return 0;
865}
866
Bill Pembertona5023572012-11-19 13:22:22 -0500867static int ab8500_regulator_register(struct platform_device *pdev,
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100868 struct regulator_init_data *init_data,
869 int id,
870 struct device_node *np)
871{
872 struct ab8500_regulator_info *info = NULL;
873 struct regulator_config config = { };
874 int err;
875
876 /* assign per-regulator data */
877 info = &ab8500_regulator_info[id];
878 info->dev = &pdev->dev;
879
880 config.dev = &pdev->dev;
881 config.init_data = init_data;
882 config.driver_data = info;
883 config.of_node = np;
884
885 /* fix for hardware before ab8500v2.0 */
886 if (abx500_get_chip_id(info->dev) < 0x20) {
887 if (info->desc.id == AB8500_LDO_AUX3) {
888 info->desc.n_voltages =
889 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800890 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100891 info->voltage_mask = 0xf;
892 }
893 }
894
895 /* register regulator with framework */
896 info->regulator = regulator_register(&info->desc, &config);
897 if (IS_ERR(info->regulator)) {
898 err = PTR_ERR(info->regulator);
899 dev_err(&pdev->dev, "failed to register regulator %s\n",
900 info->desc.name);
901 /* when we fail, un-register all earlier regulators */
902 while (--id >= 0) {
903 info = &ab8500_regulator_info[id];
904 regulator_unregister(info->regulator);
905 }
906 return err;
907 }
908
909 return 0;
910}
911
Lee Jones3a8334b2012-05-17 14:45:16 +0100912static struct of_regulator_match ab8500_regulator_matches[] = {
Lee Jones7e715b92012-05-30 12:47:26 +0800913 { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, },
914 { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, },
915 { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, },
916 { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
917 { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, },
918 { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, },
919 { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, },
920 { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
921 { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
922 { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
923 { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
Lee Jones3a8334b2012-05-17 14:45:16 +0100924};
925
Bill Pembertona5023572012-11-19 13:22:22 -0500926static int
Lee Jones3a8334b2012-05-17 14:45:16 +0100927ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
928{
929 int err, i;
930
931 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
932 err = ab8500_regulator_register(
933 pdev, ab8500_regulator_matches[i].init_data,
934 i, ab8500_regulator_matches[i].of_node);
935 if (err)
936 return err;
937 }
938
939 return 0;
940}
941
Bill Pembertona5023572012-11-19 13:22:22 -0500942static int ab8500_regulator_probe(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530943{
944 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Lee Jones3a8334b2012-05-17 14:45:16 +0100945 struct device_node *np = pdev->dev.of_node;
Bengt Jonsson732805a2013-03-21 15:59:03 +0000946 struct ab8500_platform_data *ppdata;
947 struct ab8500_regulator_platform_data *pdata;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530948 int i, err;
949
Lee Jones3a8334b2012-05-17 14:45:16 +0100950 if (np) {
951 err = of_regulator_match(&pdev->dev, np,
952 ab8500_regulator_matches,
953 ARRAY_SIZE(ab8500_regulator_matches));
954 if (err < 0) {
955 dev_err(&pdev->dev,
956 "Error parsing regulator init data: %d\n", err);
957 return err;
958 }
959
960 err = ab8500_regulator_of_probe(pdev, np);
961 return err;
962 }
963
Sundar R IYERc789ca22010-07-13 21:48:56 +0530964 if (!ab8500) {
965 dev_err(&pdev->dev, "null mfd parent\n");
966 return -EINVAL;
967 }
Bengt Jonsson732805a2013-03-21 15:59:03 +0000968
969 ppdata = dev_get_platdata(ab8500->dev);
970 if (!ppdata) {
971 dev_err(&pdev->dev, "null parent pdata\n");
972 return -EINVAL;
973 }
974
975 pdata = ppdata->regulator;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100976 if (!pdata) {
977 dev_err(&pdev->dev, "null pdata\n");
978 return -EINVAL;
979 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530980
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100981 /* make sure the platform data has the correct size */
982 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100983 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100984 return -EINVAL;
985 }
986
Bengt Jonsson79568b942011-03-11 11:54:46 +0100987 /* initialize registers */
Bengt Jonsson732805a2013-03-21 15:59:03 +0000988 for (i = 0; i < pdata->num_reg_init; i++) {
Lee Jones3c1b8432013-03-21 15:59:01 +0000989 int id, mask, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100990
Bengt Jonsson732805a2013-03-21 15:59:03 +0000991 id = pdata->reg_init[i].id;
992 mask = pdata->reg_init[i].mask;
993 value = pdata->reg_init[i].value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100994
995 /* check for configuration errors */
Lee Jones3c1b8432013-03-21 15:59:01 +0000996 BUG_ON(id >= AB8500_NUM_REGULATOR_REGISTERS);
Bengt Jonsson79568b942011-03-11 11:54:46 +0100997
Lee Jones3c1b8432013-03-21 15:59:01 +0000998 err = ab8500_regulator_init_registers(pdev, id, mask, value);
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100999 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +01001000 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +01001001 }
1002
Sundar R IYERc789ca22010-07-13 21:48:56 +05301003 /* register all regulators */
1004 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +01001005 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
1006 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +05301007 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +05301008 }
1009
1010 return 0;
1011}
1012
Bill Pemberton8dc995f2012-11-19 13:26:10 -05001013static int ab8500_regulator_remove(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +05301014{
1015 int i;
1016
1017 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
1018 struct ab8500_regulator_info *info = NULL;
1019 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +01001020
1021 dev_vdbg(rdev_get_dev(info->regulator),
1022 "%s-remove\n", info->desc.name);
1023
Sundar R IYERc789ca22010-07-13 21:48:56 +05301024 regulator_unregister(info->regulator);
1025 }
1026
1027 return 0;
1028}
1029
1030static struct platform_driver ab8500_regulator_driver = {
1031 .probe = ab8500_regulator_probe,
Bill Pemberton5eb9f2b2012-11-19 13:20:42 -05001032 .remove = ab8500_regulator_remove,
Sundar R IYERc789ca22010-07-13 21:48:56 +05301033 .driver = {
1034 .name = "ab8500-regulator",
1035 .owner = THIS_MODULE,
Sundar R IYERc789ca22010-07-13 21:48:56 +05301036 },
1037};
1038
1039static int __init ab8500_regulator_init(void)
1040{
1041 int ret;
1042
1043 ret = platform_driver_register(&ab8500_regulator_driver);
1044 if (ret != 0)
1045 pr_err("Failed to register ab8500 regulator: %d\n", ret);
1046
1047 return ret;
1048}
1049subsys_initcall(ab8500_regulator_init);
1050
1051static void __exit ab8500_regulator_exit(void)
1052{
1053 platform_driver_unregister(&ab8500_regulator_driver);
1054}
1055module_exit(ab8500_regulator_exit);
1056
1057MODULE_LICENSE("GPL v2");
1058MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
Bengt Jonsson732805a2013-03-21 15:59:03 +00001059MODULE_AUTHOR("Bengt Jonsson <bengt.g.jonsson@stericsson.com>");
Sundar R IYERc789ca22010-07-13 21:48:56 +05301060MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
1061MODULE_ALIAS("platform:ab8500-regulator");