blob: c931c7c0ad1b4de2970ac56ca5e0d95e3b0fc614 [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)
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
Bengt Jonssone1159e62010-12-10 11:08:44 +010037 * @update_mask: mask to enable/disable regulator
38 * @update_val_enable: bits to enable the regulator in normal (high power) mode
Mattias Wallin47c16972010-09-10 17:47:56 +020039 * @voltage_bank: bank to control regulator voltage
Sundar R IYERc789ca22010-07-13 21:48:56 +053040 * @voltage_reg: register to control regulator voltage
41 * @voltage_mask: mask to control regulator voltage
Linus Walleij42ab6162011-03-17 13:25:02 +010042 * @delay: startup/set voltage delay in us
Sundar R IYERc789ca22010-07-13 21:48:56 +053043 */
44struct ab8500_regulator_info {
45 struct device *dev;
46 struct regulator_desc desc;
Sundar R IYERc789ca22010-07-13 21:48:56 +053047 struct regulator_dev *regulator;
48 int max_uV;
49 int min_uV;
Mattias Wallin47c16972010-09-10 17:47:56 +020050 u8 update_bank;
51 u8 update_reg;
Bengt Jonssone1159e62010-12-10 11:08:44 +010052 u8 update_mask;
53 u8 update_val_enable;
Mattias Wallin47c16972010-09-10 17:47:56 +020054 u8 voltage_bank;
55 u8 voltage_reg;
56 u8 voltage_mask;
Linus Walleij42ab6162011-03-17 13:25:02 +010057 unsigned int delay;
Sundar R IYERc789ca22010-07-13 21:48:56 +053058};
59
60/* voltage tables for the vauxn/vintcore supplies */
Axel Linec1cc4d2012-05-20 10:33:35 +080061static const unsigned int ldo_vauxn_voltages[] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +053062 1100000,
63 1200000,
64 1300000,
65 1400000,
66 1500000,
67 1800000,
68 1850000,
69 1900000,
70 2500000,
71 2650000,
72 2700000,
73 2750000,
74 2800000,
75 2900000,
76 3000000,
77 3300000,
78};
79
Axel Linec1cc4d2012-05-20 10:33:35 +080080static const unsigned int ldo_vaux3_voltages[] = {
Bengt Jonsson2b751512010-12-10 11:08:43 +010081 1200000,
82 1500000,
83 1800000,
84 2100000,
85 2500000,
86 2750000,
87 2790000,
88 2910000,
89};
90
Axel Linec1cc4d2012-05-20 10:33:35 +080091static const unsigned int ldo_vintcore_voltages[] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +053092 1200000,
93 1225000,
94 1250000,
95 1275000,
96 1300000,
97 1325000,
98 1350000,
99};
100
101static int ab8500_regulator_enable(struct regulator_dev *rdev)
102{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100103 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530104 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
105
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100106 if (info == NULL) {
107 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530108 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100109 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530110
Mattias Wallin47c16972010-09-10 17:47:56 +0200111 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonssone1159e62010-12-10 11:08:44 +0100112 info->update_bank, info->update_reg,
113 info->update_mask, info->update_val_enable);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530114 if (ret < 0)
115 dev_err(rdev_get_dev(rdev),
116 "couldn't set enable bits for regulator\n");
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100117
118 dev_vdbg(rdev_get_dev(rdev),
119 "%s-enable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
120 info->desc.name, info->update_bank, info->update_reg,
121 info->update_mask, info->update_val_enable);
122
Sundar R IYERc789ca22010-07-13 21:48:56 +0530123 return ret;
124}
125
126static int ab8500_regulator_disable(struct regulator_dev *rdev)
127{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100128 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530129 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
130
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100131 if (info == NULL) {
132 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530133 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100134 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530135
Mattias Wallin47c16972010-09-10 17:47:56 +0200136 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonssone1159e62010-12-10 11:08:44 +0100137 info->update_bank, info->update_reg,
138 info->update_mask, 0x0);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530139 if (ret < 0)
140 dev_err(rdev_get_dev(rdev),
141 "couldn't set disable bits for regulator\n");
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100142
143 dev_vdbg(rdev_get_dev(rdev),
144 "%s-disable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
145 info->desc.name, info->update_bank, info->update_reg,
146 info->update_mask, 0x0);
147
Sundar R IYERc789ca22010-07-13 21:48:56 +0530148 return ret;
149}
150
151static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
152{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100153 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530154 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100155 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530156
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100157 if (info == NULL) {
158 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530159 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100160 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530161
Mattias Wallin47c16972010-09-10 17:47:56 +0200162 ret = abx500_get_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100163 info->update_bank, info->update_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530164 if (ret < 0) {
165 dev_err(rdev_get_dev(rdev),
166 "couldn't read 0x%x register\n", info->update_reg);
167 return ret;
168 }
169
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100170 dev_vdbg(rdev_get_dev(rdev),
171 "%s-is_enabled (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
172 " 0x%x\n",
173 info->desc.name, info->update_bank, info->update_reg,
174 info->update_mask, regval);
175
176 if (regval & info->update_mask)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530177 return true;
178 else
179 return false;
180}
181
Axel Lin3bf6e902012-02-24 17:15:45 +0800182static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530183{
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100184 int ret, val;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530185 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100186 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530187
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100188 if (info == NULL) {
189 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530190 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100191 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530192
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100193 ret = abx500_get_register_interruptible(info->dev,
194 info->voltage_bank, info->voltage_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530195 if (ret < 0) {
196 dev_err(rdev_get_dev(rdev),
197 "couldn't read voltage reg for regulator\n");
198 return ret;
199 }
200
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100201 dev_vdbg(rdev_get_dev(rdev),
202 "%s-get_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
203 " 0x%x\n",
204 info->desc.name, info->voltage_bank, info->voltage_reg,
205 info->voltage_mask, regval);
206
Sundar R IYERc789ca22010-07-13 21:48:56 +0530207 /* vintcore has a different layout */
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100208 val = regval & info->voltage_mask;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100209 if (info->desc.id == AB8500_LDO_INTCORE)
Axel Lin3bf6e902012-02-24 17:15:45 +0800210 return val >> 0x3;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530211 else
Axel Lin3bf6e902012-02-24 17:15:45 +0800212 return val;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530213}
214
Axel Linae713d32012-03-20 09:51:08 +0800215static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
216 unsigned selector)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530217{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100218 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530219 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100220 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530221
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100222 if (info == NULL) {
223 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530224 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100225 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530226
Sundar R IYERc789ca22010-07-13 21:48:56 +0530227 /* set the registers for the request */
Axel Linae713d32012-03-20 09:51:08 +0800228 regval = (u8)selector;
Mattias Wallin47c16972010-09-10 17:47:56 +0200229 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100230 info->voltage_bank, info->voltage_reg,
231 info->voltage_mask, regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530232 if (ret < 0)
233 dev_err(rdev_get_dev(rdev),
234 "couldn't set voltage reg for regulator\n");
235
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100236 dev_vdbg(rdev_get_dev(rdev),
237 "%s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
238 " 0x%x\n",
239 info->desc.name, info->voltage_bank, info->voltage_reg,
240 info->voltage_mask, regval);
241
Sundar R IYERc789ca22010-07-13 21:48:56 +0530242 return ret;
243}
244
Linus Walleij42ab6162011-03-17 13:25:02 +0100245static int ab8500_regulator_enable_time(struct regulator_dev *rdev)
246{
247 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
248
249 return info->delay;
250}
251
252static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
253 unsigned int old_sel,
254 unsigned int new_sel)
255{
256 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Linus Walleij42ab6162011-03-17 13:25:02 +0100257
Linus Walleij42ab6162011-03-17 13:25:02 +0100258 return info->delay;
259}
260
Sundar R IYERc789ca22010-07-13 21:48:56 +0530261static struct regulator_ops ab8500_regulator_ops = {
262 .enable = ab8500_regulator_enable,
263 .disable = ab8500_regulator_disable,
264 .is_enabled = ab8500_regulator_is_enabled,
Axel Lin3bf6e902012-02-24 17:15:45 +0800265 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
Axel Linae713d32012-03-20 09:51:08 +0800266 .set_voltage_sel = ab8500_regulator_set_voltage_sel,
Axel Linec1cc4d2012-05-20 10:33:35 +0800267 .list_voltage = regulator_list_voltage_table,
Linus Walleij42ab6162011-03-17 13:25:02 +0100268 .enable_time = ab8500_regulator_enable_time,
269 .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530270};
271
272static int ab8500_fixed_get_voltage(struct regulator_dev *rdev)
273{
Axel Lin7142e212012-06-08 10:27:49 +0800274 return rdev->desc->min_uV;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530275}
276
Bengt Jonsson6909b452010-12-10 11:08:47 +0100277static struct regulator_ops ab8500_regulator_fixed_ops = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530278 .enable = ab8500_regulator_enable,
279 .disable = ab8500_regulator_disable,
280 .is_enabled = ab8500_regulator_is_enabled,
281 .get_voltage = ab8500_fixed_get_voltage,
Axel Lin7142e212012-06-08 10:27:49 +0800282 .list_voltage = regulator_list_voltage_linear,
Linus Walleij42ab6162011-03-17 13:25:02 +0100283 .enable_time = ab8500_regulator_enable_time,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530284};
285
Bengt Jonsson6909b452010-12-10 11:08:47 +0100286static struct ab8500_regulator_info
287 ab8500_regulator_info[AB8500_NUM_REGULATORS] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530288 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100289 * Variable Voltage Regulators
290 * name, min mV, max mV,
291 * update bank, reg, mask, enable val
Axel Linec1cc4d2012-05-20 10:33:35 +0800292 * volt bank, reg, mask
Sundar R IYERc789ca22010-07-13 21:48:56 +0530293 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100294 [AB8500_LDO_AUX1] = {
295 .desc = {
296 .name = "LDO-AUX1",
297 .ops = &ab8500_regulator_ops,
298 .type = REGULATOR_VOLTAGE,
299 .id = AB8500_LDO_AUX1,
300 .owner = THIS_MODULE,
301 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800302 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100303 },
304 .min_uV = 1100000,
305 .max_uV = 3300000,
306 .update_bank = 0x04,
307 .update_reg = 0x09,
308 .update_mask = 0x03,
309 .update_val_enable = 0x01,
310 .voltage_bank = 0x04,
311 .voltage_reg = 0x1f,
312 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100313 },
314 [AB8500_LDO_AUX2] = {
315 .desc = {
316 .name = "LDO-AUX2",
317 .ops = &ab8500_regulator_ops,
318 .type = REGULATOR_VOLTAGE,
319 .id = AB8500_LDO_AUX2,
320 .owner = THIS_MODULE,
321 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800322 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100323 },
324 .min_uV = 1100000,
325 .max_uV = 3300000,
326 .update_bank = 0x04,
327 .update_reg = 0x09,
328 .update_mask = 0x0c,
329 .update_val_enable = 0x04,
330 .voltage_bank = 0x04,
331 .voltage_reg = 0x20,
332 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100333 },
334 [AB8500_LDO_AUX3] = {
335 .desc = {
336 .name = "LDO-AUX3",
337 .ops = &ab8500_regulator_ops,
338 .type = REGULATOR_VOLTAGE,
339 .id = AB8500_LDO_AUX3,
340 .owner = THIS_MODULE,
341 .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800342 .volt_table = ldo_vaux3_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100343 },
344 .min_uV = 1100000,
345 .max_uV = 3300000,
346 .update_bank = 0x04,
347 .update_reg = 0x0a,
348 .update_mask = 0x03,
349 .update_val_enable = 0x01,
350 .voltage_bank = 0x04,
351 .voltage_reg = 0x21,
352 .voltage_mask = 0x07,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100353 },
354 [AB8500_LDO_INTCORE] = {
355 .desc = {
356 .name = "LDO-INTCORE",
357 .ops = &ab8500_regulator_ops,
358 .type = REGULATOR_VOLTAGE,
359 .id = AB8500_LDO_INTCORE,
360 .owner = THIS_MODULE,
361 .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800362 .volt_table = ldo_vintcore_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100363 },
364 .min_uV = 1100000,
365 .max_uV = 3300000,
366 .update_bank = 0x03,
367 .update_reg = 0x80,
368 .update_mask = 0x44,
369 .update_val_enable = 0x04,
370 .voltage_bank = 0x03,
371 .voltage_reg = 0x80,
372 .voltage_mask = 0x38,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100373 },
Sundar R IYERc789ca22010-07-13 21:48:56 +0530374
375 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100376 * Fixed Voltage Regulators
377 * name, fixed mV,
378 * update bank, reg, mask, enable val
Sundar R IYERc789ca22010-07-13 21:48:56 +0530379 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100380 [AB8500_LDO_TVOUT] = {
381 .desc = {
382 .name = "LDO-TVOUT",
383 .ops = &ab8500_regulator_fixed_ops,
384 .type = REGULATOR_VOLTAGE,
385 .id = AB8500_LDO_TVOUT,
386 .owner = THIS_MODULE,
387 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800388 .min_uV = 2000000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100389 },
Linus Walleij42ab6162011-03-17 13:25:02 +0100390 .delay = 10000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100391 .update_bank = 0x03,
392 .update_reg = 0x80,
393 .update_mask = 0x82,
394 .update_val_enable = 0x02,
395 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100396 [AB8500_LDO_USB] = {
397 .desc = {
398 .name = "LDO-USB",
399 .ops = &ab8500_regulator_fixed_ops,
400 .type = REGULATOR_VOLTAGE,
401 .id = AB8500_LDO_USB,
402 .owner = THIS_MODULE,
403 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800404 .min_uV = 3300000,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100405 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100406 .update_bank = 0x03,
407 .update_reg = 0x82,
408 .update_mask = 0x03,
409 .update_val_enable = 0x01,
410 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100411 [AB8500_LDO_AUDIO] = {
412 .desc = {
413 .name = "LDO-AUDIO",
414 .ops = &ab8500_regulator_fixed_ops,
415 .type = REGULATOR_VOLTAGE,
416 .id = AB8500_LDO_AUDIO,
417 .owner = THIS_MODULE,
418 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800419 .min_uV = 2000000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100420 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100421 .update_bank = 0x03,
422 .update_reg = 0x83,
423 .update_mask = 0x02,
424 .update_val_enable = 0x02,
425 },
426 [AB8500_LDO_ANAMIC1] = {
427 .desc = {
428 .name = "LDO-ANAMIC1",
429 .ops = &ab8500_regulator_fixed_ops,
430 .type = REGULATOR_VOLTAGE,
431 .id = AB8500_LDO_ANAMIC1,
432 .owner = THIS_MODULE,
433 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800434 .min_uV = 2050000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100435 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100436 .update_bank = 0x03,
437 .update_reg = 0x83,
438 .update_mask = 0x08,
439 .update_val_enable = 0x08,
440 },
441 [AB8500_LDO_ANAMIC2] = {
442 .desc = {
443 .name = "LDO-ANAMIC2",
444 .ops = &ab8500_regulator_fixed_ops,
445 .type = REGULATOR_VOLTAGE,
446 .id = AB8500_LDO_ANAMIC2,
447 .owner = THIS_MODULE,
448 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800449 .min_uV = 2050000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100450 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100451 .update_bank = 0x03,
452 .update_reg = 0x83,
453 .update_mask = 0x10,
454 .update_val_enable = 0x10,
455 },
456 [AB8500_LDO_DMIC] = {
457 .desc = {
458 .name = "LDO-DMIC",
459 .ops = &ab8500_regulator_fixed_ops,
460 .type = REGULATOR_VOLTAGE,
461 .id = AB8500_LDO_DMIC,
462 .owner = THIS_MODULE,
463 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800464 .min_uV = 1800000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100465 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100466 .update_bank = 0x03,
467 .update_reg = 0x83,
468 .update_mask = 0x04,
469 .update_val_enable = 0x04,
470 },
471 [AB8500_LDO_ANA] = {
472 .desc = {
473 .name = "LDO-ANA",
474 .ops = &ab8500_regulator_fixed_ops,
475 .type = REGULATOR_VOLTAGE,
476 .id = AB8500_LDO_ANA,
477 .owner = THIS_MODULE,
478 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800479 .min_uV = 1200000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100480 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100481 .update_bank = 0x04,
482 .update_reg = 0x06,
483 .update_mask = 0x0c,
484 .update_val_enable = 0x04,
485 },
486
487
Sundar R IYERc789ca22010-07-13 21:48:56 +0530488};
489
Bengt Jonsson79568b92011-03-11 11:54:46 +0100490struct ab8500_reg_init {
491 u8 bank;
492 u8 addr;
493 u8 mask;
494};
495
496#define REG_INIT(_id, _bank, _addr, _mask) \
497 [_id] = { \
498 .bank = _bank, \
499 .addr = _addr, \
500 .mask = _mask, \
501 }
502
503static struct ab8500_reg_init ab8500_reg_init[] = {
504 /*
505 * 0x30, VanaRequestCtrl
506 * 0x0C, VpllRequestCtrl
507 * 0xc0, VextSupply1RequestCtrl
508 */
509 REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xfc),
510 /*
511 * 0x03, VextSupply2RequestCtrl
512 * 0x0c, VextSupply3RequestCtrl
513 * 0x30, Vaux1RequestCtrl
514 * 0xc0, Vaux2RequestCtrl
515 */
516 REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
517 /*
518 * 0x03, Vaux3RequestCtrl
519 * 0x04, SwHPReq
520 */
521 REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
522 /*
523 * 0x08, VanaSysClkReq1HPValid
524 * 0x20, Vaux1SysClkReq1HPValid
525 * 0x40, Vaux2SysClkReq1HPValid
526 * 0x80, Vaux3SysClkReq1HPValid
527 */
528 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8),
529 /*
530 * 0x10, VextSupply1SysClkReq1HPValid
531 * 0x20, VextSupply2SysClkReq1HPValid
532 * 0x40, VextSupply3SysClkReq1HPValid
533 */
534 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70),
535 /*
536 * 0x08, VanaHwHPReq1Valid
537 * 0x20, Vaux1HwHPReq1Valid
538 * 0x40, Vaux2HwHPReq1Valid
539 * 0x80, Vaux3HwHPReq1Valid
540 */
541 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8),
542 /*
543 * 0x01, VextSupply1HwHPReq1Valid
544 * 0x02, VextSupply2HwHPReq1Valid
545 * 0x04, VextSupply3HwHPReq1Valid
546 */
547 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07),
548 /*
549 * 0x08, VanaHwHPReq2Valid
550 * 0x20, Vaux1HwHPReq2Valid
551 * 0x40, Vaux2HwHPReq2Valid
552 * 0x80, Vaux3HwHPReq2Valid
553 */
554 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8),
555 /*
556 * 0x01, VextSupply1HwHPReq2Valid
557 * 0x02, VextSupply2HwHPReq2Valid
558 * 0x04, VextSupply3HwHPReq2Valid
559 */
560 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07),
561 /*
562 * 0x20, VanaSwHPReqValid
563 * 0x80, Vaux1SwHPReqValid
564 */
565 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0),
566 /*
567 * 0x01, Vaux2SwHPReqValid
568 * 0x02, Vaux3SwHPReqValid
569 * 0x04, VextSupply1SwHPReqValid
570 * 0x08, VextSupply2SwHPReqValid
571 * 0x10, VextSupply3SwHPReqValid
572 */
573 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f),
574 /*
575 * 0x02, SysClkReq2Valid1
576 * ...
577 * 0x80, SysClkReq8Valid1
578 */
579 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
580 /*
581 * 0x02, SysClkReq2Valid2
582 * ...
583 * 0x80, SysClkReq8Valid2
584 */
585 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
586 /*
587 * 0x02, VTVoutEna
588 * 0x04, Vintcore12Ena
589 * 0x38, Vintcore12Sel
590 * 0x40, Vintcore12LP
591 * 0x80, VTVoutLP
592 */
593 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
594 /*
595 * 0x02, VaudioEna
596 * 0x04, VdmicEna
597 * 0x08, Vamic1Ena
598 * 0x10, Vamic2Ena
599 */
600 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
601 /*
602 * 0x01, Vamic1_dzout
603 * 0x02, Vamic2_dzout
604 */
605 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
606 /*
607 * 0x0c, VanaRegu
608 * 0x03, VpllRegu
609 */
610 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
611 /*
612 * 0x01, VrefDDREna
613 * 0x02, VrefDDRSleepMode
614 */
615 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
616 /*
617 * 0x03, VextSupply1Regu
618 * 0x0c, VextSupply2Regu
619 * 0x30, VextSupply3Regu
620 * 0x40, ExtSupply2Bypass
621 * 0x80, ExtSupply3Bypass
622 */
623 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
624 /*
625 * 0x03, Vaux1Regu
626 * 0x0c, Vaux2Regu
627 */
628 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
629 /*
630 * 0x03, Vaux3Regu
631 */
632 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03),
633 /*
634 * 0x3f, Vsmps1Sel1
635 */
636 REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f),
637 /*
638 * 0x0f, Vaux1Sel
639 */
640 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
641 /*
642 * 0x0f, Vaux2Sel
643 */
644 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
645 /*
646 * 0x07, Vaux3Sel
647 */
648 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07),
649 /*
650 * 0x01, VextSupply12LP
651 */
652 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
653 /*
654 * 0x04, Vaux1Disch
655 * 0x08, Vaux2Disch
656 * 0x10, Vaux3Disch
657 * 0x20, Vintcore12Disch
658 * 0x40, VTVoutDisch
659 * 0x80, VaudioDisch
660 */
661 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc),
662 /*
663 * 0x02, VanaDisch
664 * 0x04, VdmicPullDownEna
665 * 0x10, VdmicDisch
666 */
667 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16),
668};
669
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100670static __devinit int
671ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value)
672{
673 int err;
674
675 if (value & ~ab8500_reg_init[id].mask) {
676 dev_err(&pdev->dev,
677 "Configuration error: value outside mask.\n");
678 return -EINVAL;
679 }
680
681 err = abx500_mask_and_set_register_interruptible(
682 &pdev->dev,
683 ab8500_reg_init[id].bank,
684 ab8500_reg_init[id].addr,
685 ab8500_reg_init[id].mask,
686 value);
687 if (err < 0) {
688 dev_err(&pdev->dev,
689 "Failed to initialize 0x%02x, 0x%02x.\n",
690 ab8500_reg_init[id].bank,
691 ab8500_reg_init[id].addr);
692 return err;
693 }
694
695 dev_vdbg(&pdev->dev,
696 "init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
697 ab8500_reg_init[id].bank,
698 ab8500_reg_init[id].addr,
699 ab8500_reg_init[id].mask,
700 value);
701
702 return 0;
703}
704
705static __devinit int ab8500_regulator_register(struct platform_device *pdev,
706 struct regulator_init_data *init_data,
707 int id,
708 struct device_node *np)
709{
710 struct ab8500_regulator_info *info = NULL;
711 struct regulator_config config = { };
712 int err;
713
714 /* assign per-regulator data */
715 info = &ab8500_regulator_info[id];
716 info->dev = &pdev->dev;
717
718 config.dev = &pdev->dev;
719 config.init_data = init_data;
720 config.driver_data = info;
721 config.of_node = np;
722
723 /* fix for hardware before ab8500v2.0 */
724 if (abx500_get_chip_id(info->dev) < 0x20) {
725 if (info->desc.id == AB8500_LDO_AUX3) {
726 info->desc.n_voltages =
727 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800728 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100729 info->voltage_mask = 0xf;
730 }
731 }
732
733 /* register regulator with framework */
734 info->regulator = regulator_register(&info->desc, &config);
735 if (IS_ERR(info->regulator)) {
736 err = PTR_ERR(info->regulator);
737 dev_err(&pdev->dev, "failed to register regulator %s\n",
738 info->desc.name);
739 /* when we fail, un-register all earlier regulators */
740 while (--id >= 0) {
741 info = &ab8500_regulator_info[id];
742 regulator_unregister(info->regulator);
743 }
744 return err;
745 }
746
747 return 0;
748}
749
Lee Jones3a8334b2012-05-17 14:45:16 +0100750static struct of_regulator_match ab8500_regulator_matches[] = {
Lee Jones7e715b92012-05-30 12:47:26 +0800751 { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, },
752 { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, },
753 { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, },
754 { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
755 { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, },
756 { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, },
757 { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, },
758 { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
759 { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
760 { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
761 { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
Lee Jones3a8334b2012-05-17 14:45:16 +0100762};
763
764static __devinit int
765ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
766{
767 int err, i;
768
769 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
770 err = ab8500_regulator_register(
771 pdev, ab8500_regulator_matches[i].init_data,
772 i, ab8500_regulator_matches[i].of_node);
773 if (err)
774 return err;
775 }
776
777 return 0;
778}
779
Sundar R IYERc789ca22010-07-13 21:48:56 +0530780static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
781{
782 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200783 struct ab8500_platform_data *pdata;
Lee Jones3a8334b2012-05-17 14:45:16 +0100784 struct device_node *np = pdev->dev.of_node;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530785 int i, err;
786
Lee Jones3a8334b2012-05-17 14:45:16 +0100787 if (np) {
788 err = of_regulator_match(&pdev->dev, np,
789 ab8500_regulator_matches,
790 ARRAY_SIZE(ab8500_regulator_matches));
791 if (err < 0) {
792 dev_err(&pdev->dev,
793 "Error parsing regulator init data: %d\n", err);
794 return err;
795 }
796
797 err = ab8500_regulator_of_probe(pdev, np);
798 return err;
799 }
800
Sundar R IYERc789ca22010-07-13 21:48:56 +0530801 if (!ab8500) {
802 dev_err(&pdev->dev, "null mfd parent\n");
803 return -EINVAL;
804 }
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200805 pdata = dev_get_platdata(ab8500->dev);
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100806 if (!pdata) {
807 dev_err(&pdev->dev, "null pdata\n");
808 return -EINVAL;
809 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530810
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100811 /* make sure the platform data has the correct size */
812 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b92011-03-11 11:54:46 +0100813 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100814 return -EINVAL;
815 }
816
Bengt Jonsson79568b92011-03-11 11:54:46 +0100817 /* initialize registers */
818 for (i = 0; i < pdata->num_regulator_reg_init; i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100819 int id, value;
Bengt Jonsson79568b92011-03-11 11:54:46 +0100820
821 id = pdata->regulator_reg_init[i].id;
822 value = pdata->regulator_reg_init[i].value;
823
824 /* check for configuration errors */
825 if (id >= AB8500_NUM_REGULATOR_REGISTERS) {
826 dev_err(&pdev->dev,
827 "Configuration error: id outside range.\n");
828 return -EINVAL;
829 }
Bengt Jonsson79568b92011-03-11 11:54:46 +0100830
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100831 err = ab8500_regulator_init_registers(pdev, id, value);
832 if (err < 0)
Bengt Jonsson79568b92011-03-11 11:54:46 +0100833 return err;
Bengt Jonsson79568b92011-03-11 11:54:46 +0100834 }
835
Sundar R IYERc789ca22010-07-13 21:48:56 +0530836 /* register all regulators */
837 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100838 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
839 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530840 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530841 }
842
843 return 0;
844}
845
846static __devexit int ab8500_regulator_remove(struct platform_device *pdev)
847{
848 int i;
849
850 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
851 struct ab8500_regulator_info *info = NULL;
852 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100853
854 dev_vdbg(rdev_get_dev(info->regulator),
855 "%s-remove\n", info->desc.name);
856
Sundar R IYERc789ca22010-07-13 21:48:56 +0530857 regulator_unregister(info->regulator);
858 }
859
860 return 0;
861}
862
Lee Jones3a8334b2012-05-17 14:45:16 +0100863static const struct of_device_id ab8500_regulator_match[] = {
864 { .compatible = "stericsson,ab8500-regulator", },
865 {}
866};
867
Sundar R IYERc789ca22010-07-13 21:48:56 +0530868static struct platform_driver ab8500_regulator_driver = {
869 .probe = ab8500_regulator_probe,
870 .remove = __devexit_p(ab8500_regulator_remove),
871 .driver = {
872 .name = "ab8500-regulator",
873 .owner = THIS_MODULE,
Lee Jones3a8334b2012-05-17 14:45:16 +0100874 .of_match_table = ab8500_regulator_match,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530875 },
876};
877
878static int __init ab8500_regulator_init(void)
879{
880 int ret;
881
882 ret = platform_driver_register(&ab8500_regulator_driver);
883 if (ret != 0)
884 pr_err("Failed to register ab8500 regulator: %d\n", ret);
885
886 return ret;
887}
888subsys_initcall(ab8500_regulator_init);
889
890static void __exit ab8500_regulator_exit(void)
891{
892 platform_driver_unregister(&ab8500_regulator_driver);
893}
894module_exit(ab8500_regulator_exit);
895
896MODULE_LICENSE("GPL v2");
897MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
898MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
899MODULE_ALIAS("platform:ab8500-regulator");