blob: da883e661b3889bb0bb2177e94647277ee8fb9e4 [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
33 * @max_uV: maximum voltage (for variable voltage supplies)
34 * @min_uV: minimum voltage (for variable voltage supplies)
35 * @fixed_uV: typical voltage (for fixed voltage supplies)
Mattias Wallin47c16972010-09-10 17:47:56 +020036 * @update_bank: bank to control on/off
Sundar R IYERc789ca22010-07-13 21:48:56 +053037 * @update_reg: register to control on/off
Bengt Jonssone1159e62010-12-10 11:08:44 +010038 * @update_mask: mask to enable/disable regulator
39 * @update_val_enable: bits to enable the regulator in normal (high power) mode
Mattias Wallin47c16972010-09-10 17:47:56 +020040 * @voltage_bank: bank to control regulator voltage
Sundar R IYERc789ca22010-07-13 21:48:56 +053041 * @voltage_reg: register to control regulator voltage
42 * @voltage_mask: mask to control regulator voltage
Linus Walleij42ab6162011-03-17 13:25:02 +010043 * @delay: startup/set voltage delay in us
Sundar R IYERc789ca22010-07-13 21:48:56 +053044 */
45struct ab8500_regulator_info {
46 struct device *dev;
47 struct regulator_desc desc;
Sundar R IYERc789ca22010-07-13 21:48:56 +053048 struct regulator_dev *regulator;
49 int max_uV;
50 int min_uV;
51 int fixed_uV;
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;
55 u8 update_val_enable;
Mattias Wallin47c16972010-09-10 17:47:56 +020056 u8 voltage_bank;
57 u8 voltage_reg;
58 u8 voltage_mask;
Linus Walleij42ab6162011-03-17 13:25:02 +010059 unsigned int delay;
Sundar R IYERc789ca22010-07-13 21:48:56 +053060};
61
62/* voltage tables for the vauxn/vintcore supplies */
Axel Linec1cc4d2012-05-20 10:33:35 +080063static const unsigned int ldo_vauxn_voltages[] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +053064 1100000,
65 1200000,
66 1300000,
67 1400000,
68 1500000,
69 1800000,
70 1850000,
71 1900000,
72 2500000,
73 2650000,
74 2700000,
75 2750000,
76 2800000,
77 2900000,
78 3000000,
79 3300000,
80};
81
Axel Linec1cc4d2012-05-20 10:33:35 +080082static const unsigned int ldo_vaux3_voltages[] = {
Bengt Jonsson2b751512010-12-10 11:08:43 +010083 1200000,
84 1500000,
85 1800000,
86 2100000,
87 2500000,
88 2750000,
89 2790000,
90 2910000,
91};
92
Axel Linec1cc4d2012-05-20 10:33:35 +080093static const unsigned int ldo_vintcore_voltages[] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +053094 1200000,
95 1225000,
96 1250000,
97 1275000,
98 1300000,
99 1325000,
100 1350000,
101};
102
103static int ab8500_regulator_enable(struct regulator_dev *rdev)
104{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100105 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530106 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
107
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100108 if (info == NULL) {
109 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530110 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100111 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530112
Mattias Wallin47c16972010-09-10 17:47:56 +0200113 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonssone1159e62010-12-10 11:08:44 +0100114 info->update_bank, info->update_reg,
115 info->update_mask, info->update_val_enable);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530116 if (ret < 0)
117 dev_err(rdev_get_dev(rdev),
118 "couldn't set enable bits for regulator\n");
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100119
120 dev_vdbg(rdev_get_dev(rdev),
121 "%s-enable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
122 info->desc.name, info->update_bank, info->update_reg,
123 info->update_mask, info->update_val_enable);
124
Sundar R IYERc789ca22010-07-13 21:48:56 +0530125 return ret;
126}
127
128static int ab8500_regulator_disable(struct regulator_dev *rdev)
129{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100130 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530131 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
132
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100133 if (info == NULL) {
134 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530135 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100136 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530137
Mattias Wallin47c16972010-09-10 17:47:56 +0200138 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonssone1159e62010-12-10 11:08:44 +0100139 info->update_bank, info->update_reg,
140 info->update_mask, 0x0);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530141 if (ret < 0)
142 dev_err(rdev_get_dev(rdev),
143 "couldn't set disable bits for regulator\n");
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100144
145 dev_vdbg(rdev_get_dev(rdev),
146 "%s-disable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
147 info->desc.name, info->update_bank, info->update_reg,
148 info->update_mask, 0x0);
149
Sundar R IYERc789ca22010-07-13 21:48:56 +0530150 return ret;
151}
152
153static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
154{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100155 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530156 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100157 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530158
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100159 if (info == NULL) {
160 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530161 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100162 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530163
Mattias Wallin47c16972010-09-10 17:47:56 +0200164 ret = abx500_get_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100165 info->update_bank, info->update_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530166 if (ret < 0) {
167 dev_err(rdev_get_dev(rdev),
168 "couldn't read 0x%x register\n", info->update_reg);
169 return ret;
170 }
171
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100172 dev_vdbg(rdev_get_dev(rdev),
173 "%s-is_enabled (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
174 " 0x%x\n",
175 info->desc.name, info->update_bank, info->update_reg,
176 info->update_mask, regval);
177
178 if (regval & info->update_mask)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530179 return true;
180 else
181 return false;
182}
183
Axel Lin3bf6e902012-02-24 17:15:45 +0800184static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530185{
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100186 int ret, val;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530187 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100188 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530189
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100190 if (info == NULL) {
191 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530192 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100193 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530194
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100195 ret = abx500_get_register_interruptible(info->dev,
196 info->voltage_bank, info->voltage_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530197 if (ret < 0) {
198 dev_err(rdev_get_dev(rdev),
199 "couldn't read voltage reg for regulator\n");
200 return ret;
201 }
202
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100203 dev_vdbg(rdev_get_dev(rdev),
204 "%s-get_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
205 " 0x%x\n",
206 info->desc.name, info->voltage_bank, info->voltage_reg,
207 info->voltage_mask, regval);
208
Sundar R IYERc789ca22010-07-13 21:48:56 +0530209 /* vintcore has a different layout */
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100210 val = regval & info->voltage_mask;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100211 if (info->desc.id == AB8500_LDO_INTCORE)
Axel Lin3bf6e902012-02-24 17:15:45 +0800212 return val >> 0x3;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530213 else
Axel Lin3bf6e902012-02-24 17:15:45 +0800214 return val;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530215}
216
Axel Linae713d32012-03-20 09:51:08 +0800217static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
218 unsigned selector)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530219{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100220 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530221 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100222 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530223
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100224 if (info == NULL) {
225 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530226 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100227 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530228
Sundar R IYERc789ca22010-07-13 21:48:56 +0530229 /* set the registers for the request */
Axel Linae713d32012-03-20 09:51:08 +0800230 regval = (u8)selector;
Mattias Wallin47c16972010-09-10 17:47:56 +0200231 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100232 info->voltage_bank, info->voltage_reg,
233 info->voltage_mask, regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530234 if (ret < 0)
235 dev_err(rdev_get_dev(rdev),
236 "couldn't set voltage reg for regulator\n");
237
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100238 dev_vdbg(rdev_get_dev(rdev),
239 "%s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
240 " 0x%x\n",
241 info->desc.name, info->voltage_bank, info->voltage_reg,
242 info->voltage_mask, regval);
243
Sundar R IYERc789ca22010-07-13 21:48:56 +0530244 return ret;
245}
246
Linus Walleij42ab6162011-03-17 13:25:02 +0100247static int ab8500_regulator_enable_time(struct regulator_dev *rdev)
248{
249 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
250
251 return info->delay;
252}
253
254static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
255 unsigned int old_sel,
256 unsigned int new_sel)
257{
258 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
259 int ret;
260
261 /* If the regulator isn't on, it won't take time here */
262 ret = ab8500_regulator_is_enabled(rdev);
263 if (ret < 0)
264 return ret;
265 if (!ret)
266 return 0;
267 return info->delay;
268}
269
Sundar R IYERc789ca22010-07-13 21:48:56 +0530270static struct regulator_ops ab8500_regulator_ops = {
271 .enable = ab8500_regulator_enable,
272 .disable = ab8500_regulator_disable,
273 .is_enabled = ab8500_regulator_is_enabled,
Axel Lin3bf6e902012-02-24 17:15:45 +0800274 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
Axel Linae713d32012-03-20 09:51:08 +0800275 .set_voltage_sel = ab8500_regulator_set_voltage_sel,
Axel Linec1cc4d2012-05-20 10:33:35 +0800276 .list_voltage = regulator_list_voltage_table,
Linus Walleij42ab6162011-03-17 13:25:02 +0100277 .enable_time = ab8500_regulator_enable_time,
278 .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530279};
280
Axel Linec1cc4d2012-05-20 10:33:35 +0800281static int ab8500_fixed_list_voltage(struct regulator_dev *rdev,
282 unsigned selector)
283{
284 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
285
286 if (info == NULL) {
287 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
288 return -EINVAL;
289 }
290
291 return info->fixed_uV;
292}
293
Sundar R IYERc789ca22010-07-13 21:48:56 +0530294static int ab8500_fixed_get_voltage(struct regulator_dev *rdev)
295{
Sundar R IYERc789ca22010-07-13 21:48:56 +0530296 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
297
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100298 if (info == NULL) {
299 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530300 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100301 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530302
303 return info->fixed_uV;
304}
305
Bengt Jonsson6909b452010-12-10 11:08:47 +0100306static struct regulator_ops ab8500_regulator_fixed_ops = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530307 .enable = ab8500_regulator_enable,
308 .disable = ab8500_regulator_disable,
309 .is_enabled = ab8500_regulator_is_enabled,
310 .get_voltage = ab8500_fixed_get_voltage,
Axel Linec1cc4d2012-05-20 10:33:35 +0800311 .list_voltage = ab8500_fixed_list_voltage,
Linus Walleij42ab6162011-03-17 13:25:02 +0100312 .enable_time = ab8500_regulator_enable_time,
313 .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530314};
315
Bengt Jonsson6909b452010-12-10 11:08:47 +0100316static struct ab8500_regulator_info
317 ab8500_regulator_info[AB8500_NUM_REGULATORS] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530318 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100319 * Variable Voltage Regulators
320 * name, min mV, max mV,
321 * update bank, reg, mask, enable val
Axel Linec1cc4d2012-05-20 10:33:35 +0800322 * volt bank, reg, mask
Sundar R IYERc789ca22010-07-13 21:48:56 +0530323 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100324 [AB8500_LDO_AUX1] = {
325 .desc = {
326 .name = "LDO-AUX1",
327 .ops = &ab8500_regulator_ops,
328 .type = REGULATOR_VOLTAGE,
329 .id = AB8500_LDO_AUX1,
330 .owner = THIS_MODULE,
331 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800332 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100333 },
334 .min_uV = 1100000,
335 .max_uV = 3300000,
336 .update_bank = 0x04,
337 .update_reg = 0x09,
338 .update_mask = 0x03,
339 .update_val_enable = 0x01,
340 .voltage_bank = 0x04,
341 .voltage_reg = 0x1f,
342 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100343 },
344 [AB8500_LDO_AUX2] = {
345 .desc = {
346 .name = "LDO-AUX2",
347 .ops = &ab8500_regulator_ops,
348 .type = REGULATOR_VOLTAGE,
349 .id = AB8500_LDO_AUX2,
350 .owner = THIS_MODULE,
351 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800352 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100353 },
354 .min_uV = 1100000,
355 .max_uV = 3300000,
356 .update_bank = 0x04,
357 .update_reg = 0x09,
358 .update_mask = 0x0c,
359 .update_val_enable = 0x04,
360 .voltage_bank = 0x04,
361 .voltage_reg = 0x20,
362 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100363 },
364 [AB8500_LDO_AUX3] = {
365 .desc = {
366 .name = "LDO-AUX3",
367 .ops = &ab8500_regulator_ops,
368 .type = REGULATOR_VOLTAGE,
369 .id = AB8500_LDO_AUX3,
370 .owner = THIS_MODULE,
371 .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800372 .volt_table = ldo_vaux3_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100373 },
374 .min_uV = 1100000,
375 .max_uV = 3300000,
376 .update_bank = 0x04,
377 .update_reg = 0x0a,
378 .update_mask = 0x03,
379 .update_val_enable = 0x01,
380 .voltage_bank = 0x04,
381 .voltage_reg = 0x21,
382 .voltage_mask = 0x07,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100383 },
384 [AB8500_LDO_INTCORE] = {
385 .desc = {
386 .name = "LDO-INTCORE",
387 .ops = &ab8500_regulator_ops,
388 .type = REGULATOR_VOLTAGE,
389 .id = AB8500_LDO_INTCORE,
390 .owner = THIS_MODULE,
391 .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800392 .volt_table = ldo_vintcore_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100393 },
394 .min_uV = 1100000,
395 .max_uV = 3300000,
396 .update_bank = 0x03,
397 .update_reg = 0x80,
398 .update_mask = 0x44,
399 .update_val_enable = 0x04,
400 .voltage_bank = 0x03,
401 .voltage_reg = 0x80,
402 .voltage_mask = 0x38,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100403 },
Sundar R IYERc789ca22010-07-13 21:48:56 +0530404
405 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100406 * Fixed Voltage Regulators
407 * name, fixed mV,
408 * update bank, reg, mask, enable val
Sundar R IYERc789ca22010-07-13 21:48:56 +0530409 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100410 [AB8500_LDO_TVOUT] = {
411 .desc = {
412 .name = "LDO-TVOUT",
413 .ops = &ab8500_regulator_fixed_ops,
414 .type = REGULATOR_VOLTAGE,
415 .id = AB8500_LDO_TVOUT,
416 .owner = THIS_MODULE,
417 .n_voltages = 1,
418 },
Linus Walleij42ab6162011-03-17 13:25:02 +0100419 .delay = 10000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100420 .fixed_uV = 2000000,
421 .update_bank = 0x03,
422 .update_reg = 0x80,
423 .update_mask = 0x82,
424 .update_val_enable = 0x02,
425 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100426 [AB8500_LDO_USB] = {
427 .desc = {
428 .name = "LDO-USB",
429 .ops = &ab8500_regulator_fixed_ops,
430 .type = REGULATOR_VOLTAGE,
431 .id = AB8500_LDO_USB,
432 .owner = THIS_MODULE,
433 .n_voltages = 1,
434 },
435 .fixed_uV = 3300000,
436 .update_bank = 0x03,
437 .update_reg = 0x82,
438 .update_mask = 0x03,
439 .update_val_enable = 0x01,
440 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100441 [AB8500_LDO_AUDIO] = {
442 .desc = {
443 .name = "LDO-AUDIO",
444 .ops = &ab8500_regulator_fixed_ops,
445 .type = REGULATOR_VOLTAGE,
446 .id = AB8500_LDO_AUDIO,
447 .owner = THIS_MODULE,
448 .n_voltages = 1,
449 },
450 .fixed_uV = 2000000,
451 .update_bank = 0x03,
452 .update_reg = 0x83,
453 .update_mask = 0x02,
454 .update_val_enable = 0x02,
455 },
456 [AB8500_LDO_ANAMIC1] = {
457 .desc = {
458 .name = "LDO-ANAMIC1",
459 .ops = &ab8500_regulator_fixed_ops,
460 .type = REGULATOR_VOLTAGE,
461 .id = AB8500_LDO_ANAMIC1,
462 .owner = THIS_MODULE,
463 .n_voltages = 1,
464 },
465 .fixed_uV = 2050000,
466 .update_bank = 0x03,
467 .update_reg = 0x83,
468 .update_mask = 0x08,
469 .update_val_enable = 0x08,
470 },
471 [AB8500_LDO_ANAMIC2] = {
472 .desc = {
473 .name = "LDO-ANAMIC2",
474 .ops = &ab8500_regulator_fixed_ops,
475 .type = REGULATOR_VOLTAGE,
476 .id = AB8500_LDO_ANAMIC2,
477 .owner = THIS_MODULE,
478 .n_voltages = 1,
479 },
480 .fixed_uV = 2050000,
481 .update_bank = 0x03,
482 .update_reg = 0x83,
483 .update_mask = 0x10,
484 .update_val_enable = 0x10,
485 },
486 [AB8500_LDO_DMIC] = {
487 .desc = {
488 .name = "LDO-DMIC",
489 .ops = &ab8500_regulator_fixed_ops,
490 .type = REGULATOR_VOLTAGE,
491 .id = AB8500_LDO_DMIC,
492 .owner = THIS_MODULE,
493 .n_voltages = 1,
494 },
495 .fixed_uV = 1800000,
496 .update_bank = 0x03,
497 .update_reg = 0x83,
498 .update_mask = 0x04,
499 .update_val_enable = 0x04,
500 },
501 [AB8500_LDO_ANA] = {
502 .desc = {
503 .name = "LDO-ANA",
504 .ops = &ab8500_regulator_fixed_ops,
505 .type = REGULATOR_VOLTAGE,
506 .id = AB8500_LDO_ANA,
507 .owner = THIS_MODULE,
508 .n_voltages = 1,
509 },
510 .fixed_uV = 1200000,
511 .update_bank = 0x04,
512 .update_reg = 0x06,
513 .update_mask = 0x0c,
514 .update_val_enable = 0x04,
515 },
516
517
Sundar R IYERc789ca22010-07-13 21:48:56 +0530518};
519
Bengt Jonsson79568b942011-03-11 11:54:46 +0100520struct ab8500_reg_init {
521 u8 bank;
522 u8 addr;
523 u8 mask;
524};
525
526#define REG_INIT(_id, _bank, _addr, _mask) \
527 [_id] = { \
528 .bank = _bank, \
529 .addr = _addr, \
530 .mask = _mask, \
531 }
532
533static struct ab8500_reg_init ab8500_reg_init[] = {
534 /*
535 * 0x30, VanaRequestCtrl
536 * 0x0C, VpllRequestCtrl
537 * 0xc0, VextSupply1RequestCtrl
538 */
539 REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xfc),
540 /*
541 * 0x03, VextSupply2RequestCtrl
542 * 0x0c, VextSupply3RequestCtrl
543 * 0x30, Vaux1RequestCtrl
544 * 0xc0, Vaux2RequestCtrl
545 */
546 REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
547 /*
548 * 0x03, Vaux3RequestCtrl
549 * 0x04, SwHPReq
550 */
551 REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
552 /*
553 * 0x08, VanaSysClkReq1HPValid
554 * 0x20, Vaux1SysClkReq1HPValid
555 * 0x40, Vaux2SysClkReq1HPValid
556 * 0x80, Vaux3SysClkReq1HPValid
557 */
558 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8),
559 /*
560 * 0x10, VextSupply1SysClkReq1HPValid
561 * 0x20, VextSupply2SysClkReq1HPValid
562 * 0x40, VextSupply3SysClkReq1HPValid
563 */
564 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70),
565 /*
566 * 0x08, VanaHwHPReq1Valid
567 * 0x20, Vaux1HwHPReq1Valid
568 * 0x40, Vaux2HwHPReq1Valid
569 * 0x80, Vaux3HwHPReq1Valid
570 */
571 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8),
572 /*
573 * 0x01, VextSupply1HwHPReq1Valid
574 * 0x02, VextSupply2HwHPReq1Valid
575 * 0x04, VextSupply3HwHPReq1Valid
576 */
577 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07),
578 /*
579 * 0x08, VanaHwHPReq2Valid
580 * 0x20, Vaux1HwHPReq2Valid
581 * 0x40, Vaux2HwHPReq2Valid
582 * 0x80, Vaux3HwHPReq2Valid
583 */
584 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8),
585 /*
586 * 0x01, VextSupply1HwHPReq2Valid
587 * 0x02, VextSupply2HwHPReq2Valid
588 * 0x04, VextSupply3HwHPReq2Valid
589 */
590 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07),
591 /*
592 * 0x20, VanaSwHPReqValid
593 * 0x80, Vaux1SwHPReqValid
594 */
595 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0),
596 /*
597 * 0x01, Vaux2SwHPReqValid
598 * 0x02, Vaux3SwHPReqValid
599 * 0x04, VextSupply1SwHPReqValid
600 * 0x08, VextSupply2SwHPReqValid
601 * 0x10, VextSupply3SwHPReqValid
602 */
603 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f),
604 /*
605 * 0x02, SysClkReq2Valid1
606 * ...
607 * 0x80, SysClkReq8Valid1
608 */
609 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
610 /*
611 * 0x02, SysClkReq2Valid2
612 * ...
613 * 0x80, SysClkReq8Valid2
614 */
615 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
616 /*
617 * 0x02, VTVoutEna
618 * 0x04, Vintcore12Ena
619 * 0x38, Vintcore12Sel
620 * 0x40, Vintcore12LP
621 * 0x80, VTVoutLP
622 */
623 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
624 /*
625 * 0x02, VaudioEna
626 * 0x04, VdmicEna
627 * 0x08, Vamic1Ena
628 * 0x10, Vamic2Ena
629 */
630 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
631 /*
632 * 0x01, Vamic1_dzout
633 * 0x02, Vamic2_dzout
634 */
635 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
636 /*
637 * 0x0c, VanaRegu
638 * 0x03, VpllRegu
639 */
640 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
641 /*
642 * 0x01, VrefDDREna
643 * 0x02, VrefDDRSleepMode
644 */
645 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
646 /*
647 * 0x03, VextSupply1Regu
648 * 0x0c, VextSupply2Regu
649 * 0x30, VextSupply3Regu
650 * 0x40, ExtSupply2Bypass
651 * 0x80, ExtSupply3Bypass
652 */
653 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
654 /*
655 * 0x03, Vaux1Regu
656 * 0x0c, Vaux2Regu
657 */
658 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
659 /*
660 * 0x03, Vaux3Regu
661 */
662 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03),
663 /*
664 * 0x3f, Vsmps1Sel1
665 */
666 REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f),
667 /*
668 * 0x0f, Vaux1Sel
669 */
670 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
671 /*
672 * 0x0f, Vaux2Sel
673 */
674 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
675 /*
676 * 0x07, Vaux3Sel
677 */
678 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07),
679 /*
680 * 0x01, VextSupply12LP
681 */
682 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
683 /*
684 * 0x04, Vaux1Disch
685 * 0x08, Vaux2Disch
686 * 0x10, Vaux3Disch
687 * 0x20, Vintcore12Disch
688 * 0x40, VTVoutDisch
689 * 0x80, VaudioDisch
690 */
691 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc),
692 /*
693 * 0x02, VanaDisch
694 * 0x04, VdmicPullDownEna
695 * 0x10, VdmicDisch
696 */
697 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16),
698};
699
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100700static __devinit int
701ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value)
702{
703 int err;
704
705 if (value & ~ab8500_reg_init[id].mask) {
706 dev_err(&pdev->dev,
707 "Configuration error: value outside mask.\n");
708 return -EINVAL;
709 }
710
711 err = abx500_mask_and_set_register_interruptible(
712 &pdev->dev,
713 ab8500_reg_init[id].bank,
714 ab8500_reg_init[id].addr,
715 ab8500_reg_init[id].mask,
716 value);
717 if (err < 0) {
718 dev_err(&pdev->dev,
719 "Failed to initialize 0x%02x, 0x%02x.\n",
720 ab8500_reg_init[id].bank,
721 ab8500_reg_init[id].addr);
722 return err;
723 }
724
725 dev_vdbg(&pdev->dev,
726 "init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
727 ab8500_reg_init[id].bank,
728 ab8500_reg_init[id].addr,
729 ab8500_reg_init[id].mask,
730 value);
731
732 return 0;
733}
734
735static __devinit int ab8500_regulator_register(struct platform_device *pdev,
736 struct regulator_init_data *init_data,
737 int id,
738 struct device_node *np)
739{
740 struct ab8500_regulator_info *info = NULL;
741 struct regulator_config config = { };
742 int err;
743
744 /* assign per-regulator data */
745 info = &ab8500_regulator_info[id];
746 info->dev = &pdev->dev;
747
748 config.dev = &pdev->dev;
749 config.init_data = init_data;
750 config.driver_data = info;
751 config.of_node = np;
752
753 /* fix for hardware before ab8500v2.0 */
754 if (abx500_get_chip_id(info->dev) < 0x20) {
755 if (info->desc.id == AB8500_LDO_AUX3) {
756 info->desc.n_voltages =
757 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800758 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100759 info->voltage_mask = 0xf;
760 }
761 }
762
763 /* register regulator with framework */
764 info->regulator = regulator_register(&info->desc, &config);
765 if (IS_ERR(info->regulator)) {
766 err = PTR_ERR(info->regulator);
767 dev_err(&pdev->dev, "failed to register regulator %s\n",
768 info->desc.name);
769 /* when we fail, un-register all earlier regulators */
770 while (--id >= 0) {
771 info = &ab8500_regulator_info[id];
772 regulator_unregister(info->regulator);
773 }
774 return err;
775 }
776
777 return 0;
778}
779
Lee Jones3a8334b2012-05-17 14:45:16 +0100780static struct of_regulator_match ab8500_regulator_matches[] = {
781 { .name = "LDO-AUX1", .driver_data = (void *) AB8500_LDO_AUX1, },
782 { .name = "LDO-AUX2", .driver_data = (void *) AB8500_LDO_AUX2, },
783 { .name = "LDO-AUX3", .driver_data = (void *) AB8500_LDO_AUX3, },
784 { .name = "LDO-INTCORE", .driver_data = (void *) AB8500_LDO_INTCORE, },
785 { .name = "LDO-TVOUT", .driver_data = (void *) AB8500_LDO_TVOUT, },
786 { .name = "LDO-USB", .driver_data = (void *) AB8500_LDO_USB, },
787 { .name = "LDO-AUDIO", .driver_data = (void *) AB8500_LDO_AUDIO, },
788 { .name = "LDO-ANAMIC1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
789 { .name = "LDO-ANAMIC2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
790 { .name = "LDO-DMIC", .driver_data = (void *) AB8500_LDO_DMIC, },
791 { .name = "LDO-ANA", .driver_data = (void *) AB8500_LDO_ANA, },
792};
793
794static __devinit int
795ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
796{
797 int err, i;
798
799 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
800 err = ab8500_regulator_register(
801 pdev, ab8500_regulator_matches[i].init_data,
802 i, ab8500_regulator_matches[i].of_node);
803 if (err)
804 return err;
805 }
806
807 return 0;
808}
809
Sundar R IYERc789ca22010-07-13 21:48:56 +0530810static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
811{
812 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200813 struct ab8500_platform_data *pdata;
Lee Jones3a8334b2012-05-17 14:45:16 +0100814 struct device_node *np = pdev->dev.of_node;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530815 int i, err;
816
Lee Jones3a8334b2012-05-17 14:45:16 +0100817 if (np) {
818 err = of_regulator_match(&pdev->dev, np,
819 ab8500_regulator_matches,
820 ARRAY_SIZE(ab8500_regulator_matches));
821 if (err < 0) {
822 dev_err(&pdev->dev,
823 "Error parsing regulator init data: %d\n", err);
824 return err;
825 }
826
827 err = ab8500_regulator_of_probe(pdev, np);
828 return err;
829 }
830
Sundar R IYERc789ca22010-07-13 21:48:56 +0530831 if (!ab8500) {
832 dev_err(&pdev->dev, "null mfd parent\n");
833 return -EINVAL;
834 }
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200835 pdata = dev_get_platdata(ab8500->dev);
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100836 if (!pdata) {
837 dev_err(&pdev->dev, "null pdata\n");
838 return -EINVAL;
839 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530840
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100841 /* make sure the platform data has the correct size */
842 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100843 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100844 return -EINVAL;
845 }
846
Bengt Jonsson79568b942011-03-11 11:54:46 +0100847 /* initialize registers */
848 for (i = 0; i < pdata->num_regulator_reg_init; i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100849 int id, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100850
851 id = pdata->regulator_reg_init[i].id;
852 value = pdata->regulator_reg_init[i].value;
853
854 /* check for configuration errors */
855 if (id >= AB8500_NUM_REGULATOR_REGISTERS) {
856 dev_err(&pdev->dev,
857 "Configuration error: id outside range.\n");
858 return -EINVAL;
859 }
Bengt Jonsson79568b942011-03-11 11:54:46 +0100860
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100861 err = ab8500_regulator_init_registers(pdev, id, value);
862 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +0100863 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100864 }
865
Sundar R IYERc789ca22010-07-13 21:48:56 +0530866 /* register all regulators */
867 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100868 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
869 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530870 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530871 }
872
873 return 0;
874}
875
876static __devexit int ab8500_regulator_remove(struct platform_device *pdev)
877{
878 int i;
879
880 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
881 struct ab8500_regulator_info *info = NULL;
882 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100883
884 dev_vdbg(rdev_get_dev(info->regulator),
885 "%s-remove\n", info->desc.name);
886
Sundar R IYERc789ca22010-07-13 21:48:56 +0530887 regulator_unregister(info->regulator);
888 }
889
890 return 0;
891}
892
Lee Jones3a8334b2012-05-17 14:45:16 +0100893static const struct of_device_id ab8500_regulator_match[] = {
894 { .compatible = "stericsson,ab8500-regulator", },
895 {}
896};
897
Sundar R IYERc789ca22010-07-13 21:48:56 +0530898static struct platform_driver ab8500_regulator_driver = {
899 .probe = ab8500_regulator_probe,
900 .remove = __devexit_p(ab8500_regulator_remove),
901 .driver = {
902 .name = "ab8500-regulator",
903 .owner = THIS_MODULE,
Lee Jones3a8334b2012-05-17 14:45:16 +0100904 .of_match_table = ab8500_regulator_match,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530905 },
906};
907
908static int __init ab8500_regulator_init(void)
909{
910 int ret;
911
912 ret = platform_driver_register(&ab8500_regulator_driver);
913 if (ret != 0)
914 pr_err("Failed to register ab8500 regulator: %d\n", ret);
915
916 return ret;
917}
918subsys_initcall(ab8500_regulator_init);
919
920static void __exit ab8500_regulator_exit(void)
921{
922 platform_driver_unregister(&ab8500_regulator_driver);
923}
924module_exit(ab8500_regulator_exit);
925
926MODULE_LICENSE("GPL v2");
927MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
928MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
929MODULE_ALIAS("platform:ab8500-regulator");