blob: 290c289a653d4b863732b7a887fd15e8c7ef1c3c [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);
Linus Walleij42ab6162011-03-17 13:25:02 +0100259
Linus Walleij42ab6162011-03-17 13:25:02 +0100260 return info->delay;
261}
262
Sundar R IYERc789ca22010-07-13 21:48:56 +0530263static struct regulator_ops ab8500_regulator_ops = {
264 .enable = ab8500_regulator_enable,
265 .disable = ab8500_regulator_disable,
266 .is_enabled = ab8500_regulator_is_enabled,
Axel Lin3bf6e902012-02-24 17:15:45 +0800267 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
Axel Linae713d32012-03-20 09:51:08 +0800268 .set_voltage_sel = ab8500_regulator_set_voltage_sel,
Axel Linec1cc4d2012-05-20 10:33:35 +0800269 .list_voltage = regulator_list_voltage_table,
Linus Walleij42ab6162011-03-17 13:25:02 +0100270 .enable_time = ab8500_regulator_enable_time,
271 .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530272};
273
Axel Linec1cc4d2012-05-20 10:33:35 +0800274static int ab8500_fixed_list_voltage(struct regulator_dev *rdev,
275 unsigned selector)
276{
277 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
278
279 if (info == NULL) {
280 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
281 return -EINVAL;
282 }
283
284 return info->fixed_uV;
285}
286
Sundar R IYERc789ca22010-07-13 21:48:56 +0530287static int ab8500_fixed_get_voltage(struct regulator_dev *rdev)
288{
Sundar R IYERc789ca22010-07-13 21:48:56 +0530289 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
290
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100291 if (info == NULL) {
292 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530293 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100294 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530295
296 return info->fixed_uV;
297}
298
Bengt Jonsson6909b452010-12-10 11:08:47 +0100299static struct regulator_ops ab8500_regulator_fixed_ops = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530300 .enable = ab8500_regulator_enable,
301 .disable = ab8500_regulator_disable,
302 .is_enabled = ab8500_regulator_is_enabled,
303 .get_voltage = ab8500_fixed_get_voltage,
Axel Linec1cc4d2012-05-20 10:33:35 +0800304 .list_voltage = ab8500_fixed_list_voltage,
Linus Walleij42ab6162011-03-17 13:25:02 +0100305 .enable_time = ab8500_regulator_enable_time,
306 .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530307};
308
Bengt Jonsson6909b452010-12-10 11:08:47 +0100309static struct ab8500_regulator_info
310 ab8500_regulator_info[AB8500_NUM_REGULATORS] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530311 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100312 * Variable Voltage Regulators
313 * name, min mV, max mV,
314 * update bank, reg, mask, enable val
Axel Linec1cc4d2012-05-20 10:33:35 +0800315 * volt bank, reg, mask
Sundar R IYERc789ca22010-07-13 21:48:56 +0530316 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100317 [AB8500_LDO_AUX1] = {
318 .desc = {
319 .name = "LDO-AUX1",
320 .ops = &ab8500_regulator_ops,
321 .type = REGULATOR_VOLTAGE,
322 .id = AB8500_LDO_AUX1,
323 .owner = THIS_MODULE,
324 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800325 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100326 },
327 .min_uV = 1100000,
328 .max_uV = 3300000,
329 .update_bank = 0x04,
330 .update_reg = 0x09,
331 .update_mask = 0x03,
332 .update_val_enable = 0x01,
333 .voltage_bank = 0x04,
334 .voltage_reg = 0x1f,
335 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100336 },
337 [AB8500_LDO_AUX2] = {
338 .desc = {
339 .name = "LDO-AUX2",
340 .ops = &ab8500_regulator_ops,
341 .type = REGULATOR_VOLTAGE,
342 .id = AB8500_LDO_AUX2,
343 .owner = THIS_MODULE,
344 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800345 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100346 },
347 .min_uV = 1100000,
348 .max_uV = 3300000,
349 .update_bank = 0x04,
350 .update_reg = 0x09,
351 .update_mask = 0x0c,
352 .update_val_enable = 0x04,
353 .voltage_bank = 0x04,
354 .voltage_reg = 0x20,
355 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100356 },
357 [AB8500_LDO_AUX3] = {
358 .desc = {
359 .name = "LDO-AUX3",
360 .ops = &ab8500_regulator_ops,
361 .type = REGULATOR_VOLTAGE,
362 .id = AB8500_LDO_AUX3,
363 .owner = THIS_MODULE,
364 .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800365 .volt_table = ldo_vaux3_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100366 },
367 .min_uV = 1100000,
368 .max_uV = 3300000,
369 .update_bank = 0x04,
370 .update_reg = 0x0a,
371 .update_mask = 0x03,
372 .update_val_enable = 0x01,
373 .voltage_bank = 0x04,
374 .voltage_reg = 0x21,
375 .voltage_mask = 0x07,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100376 },
377 [AB8500_LDO_INTCORE] = {
378 .desc = {
379 .name = "LDO-INTCORE",
380 .ops = &ab8500_regulator_ops,
381 .type = REGULATOR_VOLTAGE,
382 .id = AB8500_LDO_INTCORE,
383 .owner = THIS_MODULE,
384 .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800385 .volt_table = ldo_vintcore_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100386 },
387 .min_uV = 1100000,
388 .max_uV = 3300000,
389 .update_bank = 0x03,
390 .update_reg = 0x80,
391 .update_mask = 0x44,
392 .update_val_enable = 0x04,
393 .voltage_bank = 0x03,
394 .voltage_reg = 0x80,
395 .voltage_mask = 0x38,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100396 },
Sundar R IYERc789ca22010-07-13 21:48:56 +0530397
398 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100399 * Fixed Voltage Regulators
400 * name, fixed mV,
401 * update bank, reg, mask, enable val
Sundar R IYERc789ca22010-07-13 21:48:56 +0530402 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100403 [AB8500_LDO_TVOUT] = {
404 .desc = {
405 .name = "LDO-TVOUT",
406 .ops = &ab8500_regulator_fixed_ops,
407 .type = REGULATOR_VOLTAGE,
408 .id = AB8500_LDO_TVOUT,
409 .owner = THIS_MODULE,
410 .n_voltages = 1,
411 },
Linus Walleij42ab6162011-03-17 13:25:02 +0100412 .delay = 10000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100413 .fixed_uV = 2000000,
414 .update_bank = 0x03,
415 .update_reg = 0x80,
416 .update_mask = 0x82,
417 .update_val_enable = 0x02,
418 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100419 [AB8500_LDO_USB] = {
420 .desc = {
421 .name = "LDO-USB",
422 .ops = &ab8500_regulator_fixed_ops,
423 .type = REGULATOR_VOLTAGE,
424 .id = AB8500_LDO_USB,
425 .owner = THIS_MODULE,
426 .n_voltages = 1,
427 },
428 .fixed_uV = 3300000,
429 .update_bank = 0x03,
430 .update_reg = 0x82,
431 .update_mask = 0x03,
432 .update_val_enable = 0x01,
433 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100434 [AB8500_LDO_AUDIO] = {
435 .desc = {
436 .name = "LDO-AUDIO",
437 .ops = &ab8500_regulator_fixed_ops,
438 .type = REGULATOR_VOLTAGE,
439 .id = AB8500_LDO_AUDIO,
440 .owner = THIS_MODULE,
441 .n_voltages = 1,
442 },
443 .fixed_uV = 2000000,
444 .update_bank = 0x03,
445 .update_reg = 0x83,
446 .update_mask = 0x02,
447 .update_val_enable = 0x02,
448 },
449 [AB8500_LDO_ANAMIC1] = {
450 .desc = {
451 .name = "LDO-ANAMIC1",
452 .ops = &ab8500_regulator_fixed_ops,
453 .type = REGULATOR_VOLTAGE,
454 .id = AB8500_LDO_ANAMIC1,
455 .owner = THIS_MODULE,
456 .n_voltages = 1,
457 },
458 .fixed_uV = 2050000,
459 .update_bank = 0x03,
460 .update_reg = 0x83,
461 .update_mask = 0x08,
462 .update_val_enable = 0x08,
463 },
464 [AB8500_LDO_ANAMIC2] = {
465 .desc = {
466 .name = "LDO-ANAMIC2",
467 .ops = &ab8500_regulator_fixed_ops,
468 .type = REGULATOR_VOLTAGE,
469 .id = AB8500_LDO_ANAMIC2,
470 .owner = THIS_MODULE,
471 .n_voltages = 1,
472 },
473 .fixed_uV = 2050000,
474 .update_bank = 0x03,
475 .update_reg = 0x83,
476 .update_mask = 0x10,
477 .update_val_enable = 0x10,
478 },
479 [AB8500_LDO_DMIC] = {
480 .desc = {
481 .name = "LDO-DMIC",
482 .ops = &ab8500_regulator_fixed_ops,
483 .type = REGULATOR_VOLTAGE,
484 .id = AB8500_LDO_DMIC,
485 .owner = THIS_MODULE,
486 .n_voltages = 1,
487 },
488 .fixed_uV = 1800000,
489 .update_bank = 0x03,
490 .update_reg = 0x83,
491 .update_mask = 0x04,
492 .update_val_enable = 0x04,
493 },
494 [AB8500_LDO_ANA] = {
495 .desc = {
496 .name = "LDO-ANA",
497 .ops = &ab8500_regulator_fixed_ops,
498 .type = REGULATOR_VOLTAGE,
499 .id = AB8500_LDO_ANA,
500 .owner = THIS_MODULE,
501 .n_voltages = 1,
502 },
503 .fixed_uV = 1200000,
504 .update_bank = 0x04,
505 .update_reg = 0x06,
506 .update_mask = 0x0c,
507 .update_val_enable = 0x04,
508 },
509
510
Sundar R IYERc789ca22010-07-13 21:48:56 +0530511};
512
Bengt Jonsson79568b942011-03-11 11:54:46 +0100513struct ab8500_reg_init {
514 u8 bank;
515 u8 addr;
516 u8 mask;
517};
518
519#define REG_INIT(_id, _bank, _addr, _mask) \
520 [_id] = { \
521 .bank = _bank, \
522 .addr = _addr, \
523 .mask = _mask, \
524 }
525
526static struct ab8500_reg_init ab8500_reg_init[] = {
527 /*
528 * 0x30, VanaRequestCtrl
529 * 0x0C, VpllRequestCtrl
530 * 0xc0, VextSupply1RequestCtrl
531 */
532 REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xfc),
533 /*
534 * 0x03, VextSupply2RequestCtrl
535 * 0x0c, VextSupply3RequestCtrl
536 * 0x30, Vaux1RequestCtrl
537 * 0xc0, Vaux2RequestCtrl
538 */
539 REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
540 /*
541 * 0x03, Vaux3RequestCtrl
542 * 0x04, SwHPReq
543 */
544 REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
545 /*
546 * 0x08, VanaSysClkReq1HPValid
547 * 0x20, Vaux1SysClkReq1HPValid
548 * 0x40, Vaux2SysClkReq1HPValid
549 * 0x80, Vaux3SysClkReq1HPValid
550 */
551 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8),
552 /*
553 * 0x10, VextSupply1SysClkReq1HPValid
554 * 0x20, VextSupply2SysClkReq1HPValid
555 * 0x40, VextSupply3SysClkReq1HPValid
556 */
557 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70),
558 /*
559 * 0x08, VanaHwHPReq1Valid
560 * 0x20, Vaux1HwHPReq1Valid
561 * 0x40, Vaux2HwHPReq1Valid
562 * 0x80, Vaux3HwHPReq1Valid
563 */
564 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8),
565 /*
566 * 0x01, VextSupply1HwHPReq1Valid
567 * 0x02, VextSupply2HwHPReq1Valid
568 * 0x04, VextSupply3HwHPReq1Valid
569 */
570 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07),
571 /*
572 * 0x08, VanaHwHPReq2Valid
573 * 0x20, Vaux1HwHPReq2Valid
574 * 0x40, Vaux2HwHPReq2Valid
575 * 0x80, Vaux3HwHPReq2Valid
576 */
577 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8),
578 /*
579 * 0x01, VextSupply1HwHPReq2Valid
580 * 0x02, VextSupply2HwHPReq2Valid
581 * 0x04, VextSupply3HwHPReq2Valid
582 */
583 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07),
584 /*
585 * 0x20, VanaSwHPReqValid
586 * 0x80, Vaux1SwHPReqValid
587 */
588 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0),
589 /*
590 * 0x01, Vaux2SwHPReqValid
591 * 0x02, Vaux3SwHPReqValid
592 * 0x04, VextSupply1SwHPReqValid
593 * 0x08, VextSupply2SwHPReqValid
594 * 0x10, VextSupply3SwHPReqValid
595 */
596 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f),
597 /*
598 * 0x02, SysClkReq2Valid1
599 * ...
600 * 0x80, SysClkReq8Valid1
601 */
602 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
603 /*
604 * 0x02, SysClkReq2Valid2
605 * ...
606 * 0x80, SysClkReq8Valid2
607 */
608 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
609 /*
610 * 0x02, VTVoutEna
611 * 0x04, Vintcore12Ena
612 * 0x38, Vintcore12Sel
613 * 0x40, Vintcore12LP
614 * 0x80, VTVoutLP
615 */
616 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
617 /*
618 * 0x02, VaudioEna
619 * 0x04, VdmicEna
620 * 0x08, Vamic1Ena
621 * 0x10, Vamic2Ena
622 */
623 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
624 /*
625 * 0x01, Vamic1_dzout
626 * 0x02, Vamic2_dzout
627 */
628 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
629 /*
630 * 0x0c, VanaRegu
631 * 0x03, VpllRegu
632 */
633 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
634 /*
635 * 0x01, VrefDDREna
636 * 0x02, VrefDDRSleepMode
637 */
638 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
639 /*
640 * 0x03, VextSupply1Regu
641 * 0x0c, VextSupply2Regu
642 * 0x30, VextSupply3Regu
643 * 0x40, ExtSupply2Bypass
644 * 0x80, ExtSupply3Bypass
645 */
646 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
647 /*
648 * 0x03, Vaux1Regu
649 * 0x0c, Vaux2Regu
650 */
651 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
652 /*
653 * 0x03, Vaux3Regu
654 */
655 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03),
656 /*
657 * 0x3f, Vsmps1Sel1
658 */
659 REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f),
660 /*
661 * 0x0f, Vaux1Sel
662 */
663 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
664 /*
665 * 0x0f, Vaux2Sel
666 */
667 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
668 /*
669 * 0x07, Vaux3Sel
670 */
671 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07),
672 /*
673 * 0x01, VextSupply12LP
674 */
675 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
676 /*
677 * 0x04, Vaux1Disch
678 * 0x08, Vaux2Disch
679 * 0x10, Vaux3Disch
680 * 0x20, Vintcore12Disch
681 * 0x40, VTVoutDisch
682 * 0x80, VaudioDisch
683 */
684 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc),
685 /*
686 * 0x02, VanaDisch
687 * 0x04, VdmicPullDownEna
688 * 0x10, VdmicDisch
689 */
690 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16),
691};
692
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100693static __devinit int
694ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value)
695{
696 int err;
697
698 if (value & ~ab8500_reg_init[id].mask) {
699 dev_err(&pdev->dev,
700 "Configuration error: value outside mask.\n");
701 return -EINVAL;
702 }
703
704 err = abx500_mask_and_set_register_interruptible(
705 &pdev->dev,
706 ab8500_reg_init[id].bank,
707 ab8500_reg_init[id].addr,
708 ab8500_reg_init[id].mask,
709 value);
710 if (err < 0) {
711 dev_err(&pdev->dev,
712 "Failed to initialize 0x%02x, 0x%02x.\n",
713 ab8500_reg_init[id].bank,
714 ab8500_reg_init[id].addr);
715 return err;
716 }
717
718 dev_vdbg(&pdev->dev,
719 "init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
720 ab8500_reg_init[id].bank,
721 ab8500_reg_init[id].addr,
722 ab8500_reg_init[id].mask,
723 value);
724
725 return 0;
726}
727
728static __devinit int ab8500_regulator_register(struct platform_device *pdev,
729 struct regulator_init_data *init_data,
730 int id,
731 struct device_node *np)
732{
733 struct ab8500_regulator_info *info = NULL;
734 struct regulator_config config = { };
735 int err;
736
737 /* assign per-regulator data */
738 info = &ab8500_regulator_info[id];
739 info->dev = &pdev->dev;
740
741 config.dev = &pdev->dev;
742 config.init_data = init_data;
743 config.driver_data = info;
744 config.of_node = np;
745
746 /* fix for hardware before ab8500v2.0 */
747 if (abx500_get_chip_id(info->dev) < 0x20) {
748 if (info->desc.id == AB8500_LDO_AUX3) {
749 info->desc.n_voltages =
750 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800751 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100752 info->voltage_mask = 0xf;
753 }
754 }
755
756 /* register regulator with framework */
757 info->regulator = regulator_register(&info->desc, &config);
758 if (IS_ERR(info->regulator)) {
759 err = PTR_ERR(info->regulator);
760 dev_err(&pdev->dev, "failed to register regulator %s\n",
761 info->desc.name);
762 /* when we fail, un-register all earlier regulators */
763 while (--id >= 0) {
764 info = &ab8500_regulator_info[id];
765 regulator_unregister(info->regulator);
766 }
767 return err;
768 }
769
770 return 0;
771}
772
Lee Jones3a8334b2012-05-17 14:45:16 +0100773static struct of_regulator_match ab8500_regulator_matches[] = {
Lee Jones7e715b952012-05-30 12:47:26 +0800774 { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, },
775 { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, },
776 { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, },
777 { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
778 { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, },
779 { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, },
780 { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, },
781 { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
782 { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
783 { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
784 { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
Lee Jones3a8334b2012-05-17 14:45:16 +0100785};
786
787static __devinit int
788ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
789{
790 int err, i;
791
792 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
793 err = ab8500_regulator_register(
794 pdev, ab8500_regulator_matches[i].init_data,
795 i, ab8500_regulator_matches[i].of_node);
796 if (err)
797 return err;
798 }
799
800 return 0;
801}
802
Sundar R IYERc789ca22010-07-13 21:48:56 +0530803static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
804{
805 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200806 struct ab8500_platform_data *pdata;
Lee Jones3a8334b2012-05-17 14:45:16 +0100807 struct device_node *np = pdev->dev.of_node;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530808 int i, err;
809
Lee Jones3a8334b2012-05-17 14:45:16 +0100810 if (np) {
811 err = of_regulator_match(&pdev->dev, np,
812 ab8500_regulator_matches,
813 ARRAY_SIZE(ab8500_regulator_matches));
814 if (err < 0) {
815 dev_err(&pdev->dev,
816 "Error parsing regulator init data: %d\n", err);
817 return err;
818 }
819
820 err = ab8500_regulator_of_probe(pdev, np);
821 return err;
822 }
823
Sundar R IYERc789ca22010-07-13 21:48:56 +0530824 if (!ab8500) {
825 dev_err(&pdev->dev, "null mfd parent\n");
826 return -EINVAL;
827 }
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200828 pdata = dev_get_platdata(ab8500->dev);
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100829 if (!pdata) {
830 dev_err(&pdev->dev, "null pdata\n");
831 return -EINVAL;
832 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530833
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100834 /* make sure the platform data has the correct size */
835 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100836 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100837 return -EINVAL;
838 }
839
Bengt Jonsson79568b942011-03-11 11:54:46 +0100840 /* initialize registers */
841 for (i = 0; i < pdata->num_regulator_reg_init; i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100842 int id, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100843
844 id = pdata->regulator_reg_init[i].id;
845 value = pdata->regulator_reg_init[i].value;
846
847 /* check for configuration errors */
848 if (id >= AB8500_NUM_REGULATOR_REGISTERS) {
849 dev_err(&pdev->dev,
850 "Configuration error: id outside range.\n");
851 return -EINVAL;
852 }
Bengt Jonsson79568b942011-03-11 11:54:46 +0100853
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100854 err = ab8500_regulator_init_registers(pdev, id, value);
855 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +0100856 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100857 }
858
Sundar R IYERc789ca22010-07-13 21:48:56 +0530859 /* register all regulators */
860 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100861 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
862 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530863 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530864 }
865
866 return 0;
867}
868
869static __devexit int ab8500_regulator_remove(struct platform_device *pdev)
870{
871 int i;
872
873 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
874 struct ab8500_regulator_info *info = NULL;
875 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100876
877 dev_vdbg(rdev_get_dev(info->regulator),
878 "%s-remove\n", info->desc.name);
879
Sundar R IYERc789ca22010-07-13 21:48:56 +0530880 regulator_unregister(info->regulator);
881 }
882
883 return 0;
884}
885
Lee Jones3a8334b2012-05-17 14:45:16 +0100886static const struct of_device_id ab8500_regulator_match[] = {
887 { .compatible = "stericsson,ab8500-regulator", },
888 {}
889};
890
Sundar R IYERc789ca22010-07-13 21:48:56 +0530891static struct platform_driver ab8500_regulator_driver = {
892 .probe = ab8500_regulator_probe,
893 .remove = __devexit_p(ab8500_regulator_remove),
894 .driver = {
895 .name = "ab8500-regulator",
896 .owner = THIS_MODULE,
Lee Jones3a8334b2012-05-17 14:45:16 +0100897 .of_match_table = ab8500_regulator_match,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530898 },
899};
900
901static int __init ab8500_regulator_init(void)
902{
903 int ret;
904
905 ret = platform_driver_register(&ab8500_regulator_driver);
906 if (ret != 0)
907 pr_err("Failed to register ab8500 regulator: %d\n", ret);
908
909 return ret;
910}
911subsys_initcall(ab8500_regulator_init);
912
913static void __exit ab8500_regulator_exit(void)
914{
915 platform_driver_unregister(&ab8500_regulator_driver);
916}
917module_exit(ab8500_regulator_exit);
918
919MODULE_LICENSE("GPL v2");
920MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
921MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
922MODULE_ALIAS("platform:ab8500-regulator");