blob: 8807166eab7f94d61a90478800c092d2fd2182df [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
Mattias Wallin47c16972010-09-10 17:47:56 +020033 * @update_bank: bank to control on/off
Sundar R IYERc789ca22010-07-13 21:48:56 +053034 * @update_reg: register to control on/off
Bengt Jonssone1159e62010-12-10 11:08:44 +010035 * @update_mask: mask to enable/disable regulator
36 * @update_val_enable: bits to enable the regulator in normal (high power) mode
Mattias Wallin47c16972010-09-10 17:47:56 +020037 * @voltage_bank: bank to control regulator voltage
Sundar R IYERc789ca22010-07-13 21:48:56 +053038 * @voltage_reg: register to control regulator voltage
39 * @voltage_mask: mask to control regulator voltage
Linus Walleij42ab6162011-03-17 13:25:02 +010040 * @delay: startup/set voltage delay in us
Sundar R IYERc789ca22010-07-13 21:48:56 +053041 */
42struct ab8500_regulator_info {
43 struct device *dev;
44 struct regulator_desc desc;
Sundar R IYERc789ca22010-07-13 21:48:56 +053045 struct regulator_dev *regulator;
Mattias Wallin47c16972010-09-10 17:47:56 +020046 u8 update_bank;
47 u8 update_reg;
Bengt Jonssone1159e62010-12-10 11:08:44 +010048 u8 update_mask;
49 u8 update_val_enable;
Mattias Wallin47c16972010-09-10 17:47:56 +020050 u8 voltage_bank;
51 u8 voltage_reg;
52 u8 voltage_mask;
Linus Walleij42ab6162011-03-17 13:25:02 +010053 unsigned int delay;
Sundar R IYERc789ca22010-07-13 21:48:56 +053054};
55
56/* voltage tables for the vauxn/vintcore supplies */
Axel Linec1cc4d2012-05-20 10:33:35 +080057static const unsigned int ldo_vauxn_voltages[] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +053058 1100000,
59 1200000,
60 1300000,
61 1400000,
62 1500000,
63 1800000,
64 1850000,
65 1900000,
66 2500000,
67 2650000,
68 2700000,
69 2750000,
70 2800000,
71 2900000,
72 3000000,
73 3300000,
74};
75
Axel Linec1cc4d2012-05-20 10:33:35 +080076static const unsigned int ldo_vaux3_voltages[] = {
Bengt Jonsson2b751512010-12-10 11:08:43 +010077 1200000,
78 1500000,
79 1800000,
80 2100000,
81 2500000,
82 2750000,
83 2790000,
84 2910000,
85};
86
Axel Linec1cc4d2012-05-20 10:33:35 +080087static const unsigned int ldo_vintcore_voltages[] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +053088 1200000,
89 1225000,
90 1250000,
91 1275000,
92 1300000,
93 1325000,
94 1350000,
95};
96
97static int ab8500_regulator_enable(struct regulator_dev *rdev)
98{
Bengt Jonssonfc24b422010-12-10 11:08:45 +010099 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530100 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
101
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100102 if (info == NULL) {
103 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530104 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100105 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530106
Mattias Wallin47c16972010-09-10 17:47:56 +0200107 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonssone1159e62010-12-10 11:08:44 +0100108 info->update_bank, info->update_reg,
109 info->update_mask, info->update_val_enable);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530110 if (ret < 0)
111 dev_err(rdev_get_dev(rdev),
112 "couldn't set enable bits for regulator\n");
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100113
114 dev_vdbg(rdev_get_dev(rdev),
115 "%s-enable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
116 info->desc.name, info->update_bank, info->update_reg,
117 info->update_mask, info->update_val_enable);
118
Sundar R IYERc789ca22010-07-13 21:48:56 +0530119 return ret;
120}
121
122static int ab8500_regulator_disable(struct regulator_dev *rdev)
123{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100124 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530125 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
126
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100127 if (info == NULL) {
128 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530129 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100130 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530131
Mattias Wallin47c16972010-09-10 17:47:56 +0200132 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonssone1159e62010-12-10 11:08:44 +0100133 info->update_bank, info->update_reg,
134 info->update_mask, 0x0);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530135 if (ret < 0)
136 dev_err(rdev_get_dev(rdev),
137 "couldn't set disable bits for regulator\n");
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100138
139 dev_vdbg(rdev_get_dev(rdev),
140 "%s-disable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
141 info->desc.name, info->update_bank, info->update_reg,
142 info->update_mask, 0x0);
143
Sundar R IYERc789ca22010-07-13 21:48:56 +0530144 return ret;
145}
146
147static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
148{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100149 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530150 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100151 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530152
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100153 if (info == NULL) {
154 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530155 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100156 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530157
Mattias Wallin47c16972010-09-10 17:47:56 +0200158 ret = abx500_get_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100159 info->update_bank, info->update_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530160 if (ret < 0) {
161 dev_err(rdev_get_dev(rdev),
162 "couldn't read 0x%x register\n", info->update_reg);
163 return ret;
164 }
165
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100166 dev_vdbg(rdev_get_dev(rdev),
167 "%s-is_enabled (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
168 " 0x%x\n",
169 info->desc.name, info->update_bank, info->update_reg,
170 info->update_mask, regval);
171
172 if (regval & info->update_mask)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530173 return true;
174 else
175 return false;
176}
177
Axel Lin3bf6e902012-02-24 17:15:45 +0800178static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530179{
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100180 int ret, val;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530181 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100182 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530183
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100184 if (info == NULL) {
185 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530186 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100187 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530188
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100189 ret = abx500_get_register_interruptible(info->dev,
190 info->voltage_bank, info->voltage_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530191 if (ret < 0) {
192 dev_err(rdev_get_dev(rdev),
193 "couldn't read voltage reg for regulator\n");
194 return ret;
195 }
196
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100197 dev_vdbg(rdev_get_dev(rdev),
198 "%s-get_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
199 " 0x%x\n",
200 info->desc.name, info->voltage_bank, info->voltage_reg,
201 info->voltage_mask, regval);
202
Sundar R IYERc789ca22010-07-13 21:48:56 +0530203 /* vintcore has a different layout */
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100204 val = regval & info->voltage_mask;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100205 if (info->desc.id == AB8500_LDO_INTCORE)
Axel Lin3bf6e902012-02-24 17:15:45 +0800206 return val >> 0x3;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530207 else
Axel Lin3bf6e902012-02-24 17:15:45 +0800208 return val;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530209}
210
Axel Linae713d32012-03-20 09:51:08 +0800211static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
212 unsigned selector)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530213{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100214 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530215 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100216 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530217
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100218 if (info == NULL) {
219 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530220 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100221 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530222
Sundar R IYERc789ca22010-07-13 21:48:56 +0530223 /* set the registers for the request */
Axel Linae713d32012-03-20 09:51:08 +0800224 regval = (u8)selector;
Mattias Wallin47c16972010-09-10 17:47:56 +0200225 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100226 info->voltage_bank, info->voltage_reg,
227 info->voltage_mask, regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530228 if (ret < 0)
229 dev_err(rdev_get_dev(rdev),
230 "couldn't set voltage reg for regulator\n");
231
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100232 dev_vdbg(rdev_get_dev(rdev),
233 "%s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
234 " 0x%x\n",
235 info->desc.name, info->voltage_bank, info->voltage_reg,
236 info->voltage_mask, regval);
237
Sundar R IYERc789ca22010-07-13 21:48:56 +0530238 return ret;
239}
240
Linus Walleij42ab6162011-03-17 13:25:02 +0100241static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
242 unsigned int old_sel,
243 unsigned int new_sel)
244{
245 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Linus Walleij42ab6162011-03-17 13:25:02 +0100246
Linus Walleij42ab6162011-03-17 13:25:02 +0100247 return info->delay;
248}
249
Sundar R IYERc789ca22010-07-13 21:48:56 +0530250static struct regulator_ops ab8500_regulator_ops = {
251 .enable = ab8500_regulator_enable,
252 .disable = ab8500_regulator_disable,
253 .is_enabled = ab8500_regulator_is_enabled,
Axel Lin3bf6e902012-02-24 17:15:45 +0800254 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
Axel Linae713d32012-03-20 09:51:08 +0800255 .set_voltage_sel = ab8500_regulator_set_voltage_sel,
Axel Linec1cc4d2012-05-20 10:33:35 +0800256 .list_voltage = regulator_list_voltage_table,
Linus Walleij42ab6162011-03-17 13:25:02 +0100257 .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530258};
259
260static int ab8500_fixed_get_voltage(struct regulator_dev *rdev)
261{
Axel Lin7142e212012-06-08 10:27:49 +0800262 return rdev->desc->min_uV;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530263}
264
Bengt Jonsson6909b452010-12-10 11:08:47 +0100265static struct regulator_ops ab8500_regulator_fixed_ops = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530266 .enable = ab8500_regulator_enable,
267 .disable = ab8500_regulator_disable,
268 .is_enabled = ab8500_regulator_is_enabled,
269 .get_voltage = ab8500_fixed_get_voltage,
Axel Lin7142e212012-06-08 10:27:49 +0800270 .list_voltage = regulator_list_voltage_linear,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530271};
272
Bengt Jonsson6909b452010-12-10 11:08:47 +0100273static struct ab8500_regulator_info
274 ab8500_regulator_info[AB8500_NUM_REGULATORS] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530275 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100276 * Variable Voltage Regulators
277 * name, min mV, max mV,
278 * update bank, reg, mask, enable val
Axel Linec1cc4d2012-05-20 10:33:35 +0800279 * volt bank, reg, mask
Sundar R IYERc789ca22010-07-13 21:48:56 +0530280 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100281 [AB8500_LDO_AUX1] = {
282 .desc = {
283 .name = "LDO-AUX1",
284 .ops = &ab8500_regulator_ops,
285 .type = REGULATOR_VOLTAGE,
286 .id = AB8500_LDO_AUX1,
287 .owner = THIS_MODULE,
288 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800289 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100290 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100291 .update_bank = 0x04,
292 .update_reg = 0x09,
293 .update_mask = 0x03,
294 .update_val_enable = 0x01,
295 .voltage_bank = 0x04,
296 .voltage_reg = 0x1f,
297 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100298 },
299 [AB8500_LDO_AUX2] = {
300 .desc = {
301 .name = "LDO-AUX2",
302 .ops = &ab8500_regulator_ops,
303 .type = REGULATOR_VOLTAGE,
304 .id = AB8500_LDO_AUX2,
305 .owner = THIS_MODULE,
306 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800307 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100308 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100309 .update_bank = 0x04,
310 .update_reg = 0x09,
311 .update_mask = 0x0c,
312 .update_val_enable = 0x04,
313 .voltage_bank = 0x04,
314 .voltage_reg = 0x20,
315 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100316 },
317 [AB8500_LDO_AUX3] = {
318 .desc = {
319 .name = "LDO-AUX3",
320 .ops = &ab8500_regulator_ops,
321 .type = REGULATOR_VOLTAGE,
322 .id = AB8500_LDO_AUX3,
323 .owner = THIS_MODULE,
324 .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800325 .volt_table = ldo_vaux3_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100326 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100327 .update_bank = 0x04,
328 .update_reg = 0x0a,
329 .update_mask = 0x03,
330 .update_val_enable = 0x01,
331 .voltage_bank = 0x04,
332 .voltage_reg = 0x21,
333 .voltage_mask = 0x07,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100334 },
335 [AB8500_LDO_INTCORE] = {
336 .desc = {
337 .name = "LDO-INTCORE",
338 .ops = &ab8500_regulator_ops,
339 .type = REGULATOR_VOLTAGE,
340 .id = AB8500_LDO_INTCORE,
341 .owner = THIS_MODULE,
342 .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800343 .volt_table = ldo_vintcore_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100344 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100345 .update_bank = 0x03,
346 .update_reg = 0x80,
347 .update_mask = 0x44,
348 .update_val_enable = 0x04,
349 .voltage_bank = 0x03,
350 .voltage_reg = 0x80,
351 .voltage_mask = 0x38,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100352 },
Sundar R IYERc789ca22010-07-13 21:48:56 +0530353
354 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100355 * Fixed Voltage Regulators
356 * name, fixed mV,
357 * update bank, reg, mask, enable val
Sundar R IYERc789ca22010-07-13 21:48:56 +0530358 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100359 [AB8500_LDO_TVOUT] = {
360 .desc = {
361 .name = "LDO-TVOUT",
362 .ops = &ab8500_regulator_fixed_ops,
363 .type = REGULATOR_VOLTAGE,
364 .id = AB8500_LDO_TVOUT,
365 .owner = THIS_MODULE,
366 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800367 .min_uV = 2000000,
Axel Lin7fee2af2012-08-07 22:21:23 +0800368 .enable_time = 10000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100369 },
Linus Walleij42ab6162011-03-17 13:25:02 +0100370 .delay = 10000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100371 .update_bank = 0x03,
372 .update_reg = 0x80,
373 .update_mask = 0x82,
374 .update_val_enable = 0x02,
375 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100376 [AB8500_LDO_USB] = {
377 .desc = {
378 .name = "LDO-USB",
379 .ops = &ab8500_regulator_fixed_ops,
380 .type = REGULATOR_VOLTAGE,
381 .id = AB8500_LDO_USB,
382 .owner = THIS_MODULE,
383 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800384 .min_uV = 3300000,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100385 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100386 .update_bank = 0x03,
387 .update_reg = 0x82,
388 .update_mask = 0x03,
389 .update_val_enable = 0x01,
390 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100391 [AB8500_LDO_AUDIO] = {
392 .desc = {
393 .name = "LDO-AUDIO",
394 .ops = &ab8500_regulator_fixed_ops,
395 .type = REGULATOR_VOLTAGE,
396 .id = AB8500_LDO_AUDIO,
397 .owner = THIS_MODULE,
398 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800399 .min_uV = 2000000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100400 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100401 .update_bank = 0x03,
402 .update_reg = 0x83,
403 .update_mask = 0x02,
404 .update_val_enable = 0x02,
405 },
406 [AB8500_LDO_ANAMIC1] = {
407 .desc = {
408 .name = "LDO-ANAMIC1",
409 .ops = &ab8500_regulator_fixed_ops,
410 .type = REGULATOR_VOLTAGE,
411 .id = AB8500_LDO_ANAMIC1,
412 .owner = THIS_MODULE,
413 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800414 .min_uV = 2050000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100415 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100416 .update_bank = 0x03,
417 .update_reg = 0x83,
418 .update_mask = 0x08,
419 .update_val_enable = 0x08,
420 },
421 [AB8500_LDO_ANAMIC2] = {
422 .desc = {
423 .name = "LDO-ANAMIC2",
424 .ops = &ab8500_regulator_fixed_ops,
425 .type = REGULATOR_VOLTAGE,
426 .id = AB8500_LDO_ANAMIC2,
427 .owner = THIS_MODULE,
428 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800429 .min_uV = 2050000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100430 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100431 .update_bank = 0x03,
432 .update_reg = 0x83,
433 .update_mask = 0x10,
434 .update_val_enable = 0x10,
435 },
436 [AB8500_LDO_DMIC] = {
437 .desc = {
438 .name = "LDO-DMIC",
439 .ops = &ab8500_regulator_fixed_ops,
440 .type = REGULATOR_VOLTAGE,
441 .id = AB8500_LDO_DMIC,
442 .owner = THIS_MODULE,
443 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800444 .min_uV = 1800000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100445 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100446 .update_bank = 0x03,
447 .update_reg = 0x83,
448 .update_mask = 0x04,
449 .update_val_enable = 0x04,
450 },
451 [AB8500_LDO_ANA] = {
452 .desc = {
453 .name = "LDO-ANA",
454 .ops = &ab8500_regulator_fixed_ops,
455 .type = REGULATOR_VOLTAGE,
456 .id = AB8500_LDO_ANA,
457 .owner = THIS_MODULE,
458 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800459 .min_uV = 1200000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100460 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100461 .update_bank = 0x04,
462 .update_reg = 0x06,
463 .update_mask = 0x0c,
464 .update_val_enable = 0x04,
465 },
466
467
Sundar R IYERc789ca22010-07-13 21:48:56 +0530468};
469
Bengt Jonsson79568b942011-03-11 11:54:46 +0100470struct ab8500_reg_init {
471 u8 bank;
472 u8 addr;
473 u8 mask;
474};
475
476#define REG_INIT(_id, _bank, _addr, _mask) \
477 [_id] = { \
478 .bank = _bank, \
479 .addr = _addr, \
480 .mask = _mask, \
481 }
482
483static struct ab8500_reg_init ab8500_reg_init[] = {
484 /*
485 * 0x30, VanaRequestCtrl
486 * 0x0C, VpllRequestCtrl
487 * 0xc0, VextSupply1RequestCtrl
488 */
489 REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xfc),
490 /*
491 * 0x03, VextSupply2RequestCtrl
492 * 0x0c, VextSupply3RequestCtrl
493 * 0x30, Vaux1RequestCtrl
494 * 0xc0, Vaux2RequestCtrl
495 */
496 REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
497 /*
498 * 0x03, Vaux3RequestCtrl
499 * 0x04, SwHPReq
500 */
501 REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
502 /*
503 * 0x08, VanaSysClkReq1HPValid
504 * 0x20, Vaux1SysClkReq1HPValid
505 * 0x40, Vaux2SysClkReq1HPValid
506 * 0x80, Vaux3SysClkReq1HPValid
507 */
508 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8),
509 /*
510 * 0x10, VextSupply1SysClkReq1HPValid
511 * 0x20, VextSupply2SysClkReq1HPValid
512 * 0x40, VextSupply3SysClkReq1HPValid
513 */
514 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70),
515 /*
516 * 0x08, VanaHwHPReq1Valid
517 * 0x20, Vaux1HwHPReq1Valid
518 * 0x40, Vaux2HwHPReq1Valid
519 * 0x80, Vaux3HwHPReq1Valid
520 */
521 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8),
522 /*
523 * 0x01, VextSupply1HwHPReq1Valid
524 * 0x02, VextSupply2HwHPReq1Valid
525 * 0x04, VextSupply3HwHPReq1Valid
526 */
527 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07),
528 /*
529 * 0x08, VanaHwHPReq2Valid
530 * 0x20, Vaux1HwHPReq2Valid
531 * 0x40, Vaux2HwHPReq2Valid
532 * 0x80, Vaux3HwHPReq2Valid
533 */
534 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8),
535 /*
536 * 0x01, VextSupply1HwHPReq2Valid
537 * 0x02, VextSupply2HwHPReq2Valid
538 * 0x04, VextSupply3HwHPReq2Valid
539 */
540 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07),
541 /*
542 * 0x20, VanaSwHPReqValid
543 * 0x80, Vaux1SwHPReqValid
544 */
545 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0),
546 /*
547 * 0x01, Vaux2SwHPReqValid
548 * 0x02, Vaux3SwHPReqValid
549 * 0x04, VextSupply1SwHPReqValid
550 * 0x08, VextSupply2SwHPReqValid
551 * 0x10, VextSupply3SwHPReqValid
552 */
553 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f),
554 /*
555 * 0x02, SysClkReq2Valid1
556 * ...
557 * 0x80, SysClkReq8Valid1
558 */
559 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
560 /*
561 * 0x02, SysClkReq2Valid2
562 * ...
563 * 0x80, SysClkReq8Valid2
564 */
565 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
566 /*
567 * 0x02, VTVoutEna
568 * 0x04, Vintcore12Ena
569 * 0x38, Vintcore12Sel
570 * 0x40, Vintcore12LP
571 * 0x80, VTVoutLP
572 */
573 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
574 /*
575 * 0x02, VaudioEna
576 * 0x04, VdmicEna
577 * 0x08, Vamic1Ena
578 * 0x10, Vamic2Ena
579 */
580 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
581 /*
582 * 0x01, Vamic1_dzout
583 * 0x02, Vamic2_dzout
584 */
585 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
586 /*
587 * 0x0c, VanaRegu
588 * 0x03, VpllRegu
589 */
590 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
591 /*
592 * 0x01, VrefDDREna
593 * 0x02, VrefDDRSleepMode
594 */
595 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
596 /*
597 * 0x03, VextSupply1Regu
598 * 0x0c, VextSupply2Regu
599 * 0x30, VextSupply3Regu
600 * 0x40, ExtSupply2Bypass
601 * 0x80, ExtSupply3Bypass
602 */
603 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
604 /*
605 * 0x03, Vaux1Regu
606 * 0x0c, Vaux2Regu
607 */
608 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
609 /*
610 * 0x03, Vaux3Regu
611 */
612 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03),
613 /*
614 * 0x3f, Vsmps1Sel1
615 */
616 REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f),
617 /*
618 * 0x0f, Vaux1Sel
619 */
620 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
621 /*
622 * 0x0f, Vaux2Sel
623 */
624 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
625 /*
626 * 0x07, Vaux3Sel
627 */
628 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07),
629 /*
630 * 0x01, VextSupply12LP
631 */
632 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
633 /*
634 * 0x04, Vaux1Disch
635 * 0x08, Vaux2Disch
636 * 0x10, Vaux3Disch
637 * 0x20, Vintcore12Disch
638 * 0x40, VTVoutDisch
639 * 0x80, VaudioDisch
640 */
641 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc),
642 /*
643 * 0x02, VanaDisch
644 * 0x04, VdmicPullDownEna
645 * 0x10, VdmicDisch
646 */
647 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16),
648};
649
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100650static __devinit int
651ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value)
652{
653 int err;
654
655 if (value & ~ab8500_reg_init[id].mask) {
656 dev_err(&pdev->dev,
657 "Configuration error: value outside mask.\n");
658 return -EINVAL;
659 }
660
661 err = abx500_mask_and_set_register_interruptible(
662 &pdev->dev,
663 ab8500_reg_init[id].bank,
664 ab8500_reg_init[id].addr,
665 ab8500_reg_init[id].mask,
666 value);
667 if (err < 0) {
668 dev_err(&pdev->dev,
669 "Failed to initialize 0x%02x, 0x%02x.\n",
670 ab8500_reg_init[id].bank,
671 ab8500_reg_init[id].addr);
672 return err;
673 }
674
675 dev_vdbg(&pdev->dev,
676 "init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
677 ab8500_reg_init[id].bank,
678 ab8500_reg_init[id].addr,
679 ab8500_reg_init[id].mask,
680 value);
681
682 return 0;
683}
684
685static __devinit int ab8500_regulator_register(struct platform_device *pdev,
686 struct regulator_init_data *init_data,
687 int id,
688 struct device_node *np)
689{
690 struct ab8500_regulator_info *info = NULL;
691 struct regulator_config config = { };
692 int err;
693
694 /* assign per-regulator data */
695 info = &ab8500_regulator_info[id];
696 info->dev = &pdev->dev;
697
698 config.dev = &pdev->dev;
699 config.init_data = init_data;
700 config.driver_data = info;
701 config.of_node = np;
702
703 /* fix for hardware before ab8500v2.0 */
704 if (abx500_get_chip_id(info->dev) < 0x20) {
705 if (info->desc.id == AB8500_LDO_AUX3) {
706 info->desc.n_voltages =
707 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800708 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100709 info->voltage_mask = 0xf;
710 }
711 }
712
713 /* register regulator with framework */
714 info->regulator = regulator_register(&info->desc, &config);
715 if (IS_ERR(info->regulator)) {
716 err = PTR_ERR(info->regulator);
717 dev_err(&pdev->dev, "failed to register regulator %s\n",
718 info->desc.name);
719 /* when we fail, un-register all earlier regulators */
720 while (--id >= 0) {
721 info = &ab8500_regulator_info[id];
722 regulator_unregister(info->regulator);
723 }
724 return err;
725 }
726
727 return 0;
728}
729
Lee Jones3a8334b2012-05-17 14:45:16 +0100730static struct of_regulator_match ab8500_regulator_matches[] = {
Lee Jones7e715b92012-05-30 12:47:26 +0800731 { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, },
732 { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, },
733 { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, },
734 { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
735 { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, },
736 { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, },
737 { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, },
738 { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
739 { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
740 { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
741 { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
Lee Jones3a8334b2012-05-17 14:45:16 +0100742};
743
744static __devinit int
745ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
746{
747 int err, i;
748
749 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
750 err = ab8500_regulator_register(
751 pdev, ab8500_regulator_matches[i].init_data,
752 i, ab8500_regulator_matches[i].of_node);
753 if (err)
754 return err;
755 }
756
757 return 0;
758}
759
Sundar R IYERc789ca22010-07-13 21:48:56 +0530760static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
761{
762 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200763 struct ab8500_platform_data *pdata;
Lee Jones3a8334b2012-05-17 14:45:16 +0100764 struct device_node *np = pdev->dev.of_node;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530765 int i, err;
766
Lee Jones3a8334b2012-05-17 14:45:16 +0100767 if (np) {
768 err = of_regulator_match(&pdev->dev, np,
769 ab8500_regulator_matches,
770 ARRAY_SIZE(ab8500_regulator_matches));
771 if (err < 0) {
772 dev_err(&pdev->dev,
773 "Error parsing regulator init data: %d\n", err);
774 return err;
775 }
776
777 err = ab8500_regulator_of_probe(pdev, np);
778 return err;
779 }
780
Sundar R IYERc789ca22010-07-13 21:48:56 +0530781 if (!ab8500) {
782 dev_err(&pdev->dev, "null mfd parent\n");
783 return -EINVAL;
784 }
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200785 pdata = dev_get_platdata(ab8500->dev);
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100786 if (!pdata) {
787 dev_err(&pdev->dev, "null pdata\n");
788 return -EINVAL;
789 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530790
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100791 /* make sure the platform data has the correct size */
792 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100793 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100794 return -EINVAL;
795 }
796
Bengt Jonsson79568b942011-03-11 11:54:46 +0100797 /* initialize registers */
798 for (i = 0; i < pdata->num_regulator_reg_init; i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100799 int id, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100800
801 id = pdata->regulator_reg_init[i].id;
802 value = pdata->regulator_reg_init[i].value;
803
804 /* check for configuration errors */
805 if (id >= AB8500_NUM_REGULATOR_REGISTERS) {
806 dev_err(&pdev->dev,
807 "Configuration error: id outside range.\n");
808 return -EINVAL;
809 }
Bengt Jonsson79568b942011-03-11 11:54:46 +0100810
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100811 err = ab8500_regulator_init_registers(pdev, id, value);
812 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +0100813 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100814 }
815
Sundar R IYERc789ca22010-07-13 21:48:56 +0530816 /* register all regulators */
817 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100818 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
819 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530820 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530821 }
822
823 return 0;
824}
825
826static __devexit int ab8500_regulator_remove(struct platform_device *pdev)
827{
828 int i;
829
830 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
831 struct ab8500_regulator_info *info = NULL;
832 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100833
834 dev_vdbg(rdev_get_dev(info->regulator),
835 "%s-remove\n", info->desc.name);
836
Sundar R IYERc789ca22010-07-13 21:48:56 +0530837 regulator_unregister(info->regulator);
838 }
839
840 return 0;
841}
842
843static struct platform_driver ab8500_regulator_driver = {
844 .probe = ab8500_regulator_probe,
845 .remove = __devexit_p(ab8500_regulator_remove),
846 .driver = {
847 .name = "ab8500-regulator",
848 .owner = THIS_MODULE,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530849 },
850};
851
852static int __init ab8500_regulator_init(void)
853{
854 int ret;
855
856 ret = platform_driver_register(&ab8500_regulator_driver);
857 if (ret != 0)
858 pr_err("Failed to register ab8500 regulator: %d\n", ret);
859
860 return ret;
861}
862subsys_initcall(ab8500_regulator_init);
863
864static void __exit ab8500_regulator_exit(void)
865{
866 platform_driver_unregister(&ab8500_regulator_driver);
867}
868module_exit(ab8500_regulator_exit);
869
870MODULE_LICENSE("GPL v2");
871MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
872MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
873MODULE_ALIAS("platform:ab8500-regulator");