blob: 10f2f4d4d190254cfa9602aa19223984c38fa691 [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_enable_time(struct regulator_dev *rdev)
242{
243 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
244
245 return info->delay;
246}
247
248static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
249 unsigned int old_sel,
250 unsigned int new_sel)
251{
252 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Linus Walleij42ab6162011-03-17 13:25:02 +0100253
Linus Walleij42ab6162011-03-17 13:25:02 +0100254 return info->delay;
255}
256
Sundar R IYERc789ca22010-07-13 21:48:56 +0530257static struct regulator_ops ab8500_regulator_ops = {
258 .enable = ab8500_regulator_enable,
259 .disable = ab8500_regulator_disable,
260 .is_enabled = ab8500_regulator_is_enabled,
Axel Lin3bf6e902012-02-24 17:15:45 +0800261 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
Axel Linae713d32012-03-20 09:51:08 +0800262 .set_voltage_sel = ab8500_regulator_set_voltage_sel,
Axel Linec1cc4d2012-05-20 10:33:35 +0800263 .list_voltage = regulator_list_voltage_table,
Linus Walleij42ab6162011-03-17 13:25:02 +0100264 .enable_time = ab8500_regulator_enable_time,
265 .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530266};
267
268static int ab8500_fixed_get_voltage(struct regulator_dev *rdev)
269{
Axel Lin7142e212012-06-08 10:27:49 +0800270 return rdev->desc->min_uV;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530271}
272
Bengt Jonsson6909b452010-12-10 11:08:47 +0100273static struct regulator_ops ab8500_regulator_fixed_ops = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530274 .enable = ab8500_regulator_enable,
275 .disable = ab8500_regulator_disable,
276 .is_enabled = ab8500_regulator_is_enabled,
277 .get_voltage = ab8500_fixed_get_voltage,
Axel Lin7142e212012-06-08 10:27:49 +0800278 .list_voltage = regulator_list_voltage_linear,
Linus Walleij42ab6162011-03-17 13:25:02 +0100279 .enable_time = ab8500_regulator_enable_time,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530280};
281
Bengt Jonsson6909b452010-12-10 11:08:47 +0100282static struct ab8500_regulator_info
283 ab8500_regulator_info[AB8500_NUM_REGULATORS] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530284 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100285 * Variable Voltage Regulators
286 * name, min mV, max mV,
287 * update bank, reg, mask, enable val
Axel Linec1cc4d2012-05-20 10:33:35 +0800288 * volt bank, reg, mask
Sundar R IYERc789ca22010-07-13 21:48:56 +0530289 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100290 [AB8500_LDO_AUX1] = {
291 .desc = {
292 .name = "LDO-AUX1",
293 .ops = &ab8500_regulator_ops,
294 .type = REGULATOR_VOLTAGE,
295 .id = AB8500_LDO_AUX1,
296 .owner = THIS_MODULE,
297 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800298 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100299 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100300 .update_bank = 0x04,
301 .update_reg = 0x09,
302 .update_mask = 0x03,
303 .update_val_enable = 0x01,
304 .voltage_bank = 0x04,
305 .voltage_reg = 0x1f,
306 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100307 },
308 [AB8500_LDO_AUX2] = {
309 .desc = {
310 .name = "LDO-AUX2",
311 .ops = &ab8500_regulator_ops,
312 .type = REGULATOR_VOLTAGE,
313 .id = AB8500_LDO_AUX2,
314 .owner = THIS_MODULE,
315 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800316 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100317 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100318 .update_bank = 0x04,
319 .update_reg = 0x09,
320 .update_mask = 0x0c,
321 .update_val_enable = 0x04,
322 .voltage_bank = 0x04,
323 .voltage_reg = 0x20,
324 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100325 },
326 [AB8500_LDO_AUX3] = {
327 .desc = {
328 .name = "LDO-AUX3",
329 .ops = &ab8500_regulator_ops,
330 .type = REGULATOR_VOLTAGE,
331 .id = AB8500_LDO_AUX3,
332 .owner = THIS_MODULE,
333 .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800334 .volt_table = ldo_vaux3_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100335 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100336 .update_bank = 0x04,
337 .update_reg = 0x0a,
338 .update_mask = 0x03,
339 .update_val_enable = 0x01,
340 .voltage_bank = 0x04,
341 .voltage_reg = 0x21,
342 .voltage_mask = 0x07,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100343 },
344 [AB8500_LDO_INTCORE] = {
345 .desc = {
346 .name = "LDO-INTCORE",
347 .ops = &ab8500_regulator_ops,
348 .type = REGULATOR_VOLTAGE,
349 .id = AB8500_LDO_INTCORE,
350 .owner = THIS_MODULE,
351 .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800352 .volt_table = ldo_vintcore_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100353 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100354 .update_bank = 0x03,
355 .update_reg = 0x80,
356 .update_mask = 0x44,
357 .update_val_enable = 0x04,
358 .voltage_bank = 0x03,
359 .voltage_reg = 0x80,
360 .voltage_mask = 0x38,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100361 },
Sundar R IYERc789ca22010-07-13 21:48:56 +0530362
363 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100364 * Fixed Voltage Regulators
365 * name, fixed mV,
366 * update bank, reg, mask, enable val
Sundar R IYERc789ca22010-07-13 21:48:56 +0530367 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100368 [AB8500_LDO_TVOUT] = {
369 .desc = {
370 .name = "LDO-TVOUT",
371 .ops = &ab8500_regulator_fixed_ops,
372 .type = REGULATOR_VOLTAGE,
373 .id = AB8500_LDO_TVOUT,
374 .owner = THIS_MODULE,
375 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800376 .min_uV = 2000000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100377 },
Linus Walleij42ab6162011-03-17 13:25:02 +0100378 .delay = 10000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100379 .update_bank = 0x03,
380 .update_reg = 0x80,
381 .update_mask = 0x82,
382 .update_val_enable = 0x02,
383 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100384 [AB8500_LDO_USB] = {
385 .desc = {
386 .name = "LDO-USB",
387 .ops = &ab8500_regulator_fixed_ops,
388 .type = REGULATOR_VOLTAGE,
389 .id = AB8500_LDO_USB,
390 .owner = THIS_MODULE,
391 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800392 .min_uV = 3300000,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100393 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100394 .update_bank = 0x03,
395 .update_reg = 0x82,
396 .update_mask = 0x03,
397 .update_val_enable = 0x01,
398 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100399 [AB8500_LDO_AUDIO] = {
400 .desc = {
401 .name = "LDO-AUDIO",
402 .ops = &ab8500_regulator_fixed_ops,
403 .type = REGULATOR_VOLTAGE,
404 .id = AB8500_LDO_AUDIO,
405 .owner = THIS_MODULE,
406 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800407 .min_uV = 2000000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100408 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100409 .update_bank = 0x03,
410 .update_reg = 0x83,
411 .update_mask = 0x02,
412 .update_val_enable = 0x02,
413 },
414 [AB8500_LDO_ANAMIC1] = {
415 .desc = {
416 .name = "LDO-ANAMIC1",
417 .ops = &ab8500_regulator_fixed_ops,
418 .type = REGULATOR_VOLTAGE,
419 .id = AB8500_LDO_ANAMIC1,
420 .owner = THIS_MODULE,
421 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800422 .min_uV = 2050000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100423 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100424 .update_bank = 0x03,
425 .update_reg = 0x83,
426 .update_mask = 0x08,
427 .update_val_enable = 0x08,
428 },
429 [AB8500_LDO_ANAMIC2] = {
430 .desc = {
431 .name = "LDO-ANAMIC2",
432 .ops = &ab8500_regulator_fixed_ops,
433 .type = REGULATOR_VOLTAGE,
434 .id = AB8500_LDO_ANAMIC2,
435 .owner = THIS_MODULE,
436 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800437 .min_uV = 2050000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100438 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100439 .update_bank = 0x03,
440 .update_reg = 0x83,
441 .update_mask = 0x10,
442 .update_val_enable = 0x10,
443 },
444 [AB8500_LDO_DMIC] = {
445 .desc = {
446 .name = "LDO-DMIC",
447 .ops = &ab8500_regulator_fixed_ops,
448 .type = REGULATOR_VOLTAGE,
449 .id = AB8500_LDO_DMIC,
450 .owner = THIS_MODULE,
451 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800452 .min_uV = 1800000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100453 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100454 .update_bank = 0x03,
455 .update_reg = 0x83,
456 .update_mask = 0x04,
457 .update_val_enable = 0x04,
458 },
459 [AB8500_LDO_ANA] = {
460 .desc = {
461 .name = "LDO-ANA",
462 .ops = &ab8500_regulator_fixed_ops,
463 .type = REGULATOR_VOLTAGE,
464 .id = AB8500_LDO_ANA,
465 .owner = THIS_MODULE,
466 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800467 .min_uV = 1200000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100468 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100469 .update_bank = 0x04,
470 .update_reg = 0x06,
471 .update_mask = 0x0c,
472 .update_val_enable = 0x04,
473 },
474
475
Sundar R IYERc789ca22010-07-13 21:48:56 +0530476};
477
Bengt Jonsson79568b942011-03-11 11:54:46 +0100478struct ab8500_reg_init {
479 u8 bank;
480 u8 addr;
481 u8 mask;
482};
483
484#define REG_INIT(_id, _bank, _addr, _mask) \
485 [_id] = { \
486 .bank = _bank, \
487 .addr = _addr, \
488 .mask = _mask, \
489 }
490
491static struct ab8500_reg_init ab8500_reg_init[] = {
492 /*
493 * 0x30, VanaRequestCtrl
494 * 0x0C, VpllRequestCtrl
495 * 0xc0, VextSupply1RequestCtrl
496 */
497 REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xfc),
498 /*
499 * 0x03, VextSupply2RequestCtrl
500 * 0x0c, VextSupply3RequestCtrl
501 * 0x30, Vaux1RequestCtrl
502 * 0xc0, Vaux2RequestCtrl
503 */
504 REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
505 /*
506 * 0x03, Vaux3RequestCtrl
507 * 0x04, SwHPReq
508 */
509 REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
510 /*
511 * 0x08, VanaSysClkReq1HPValid
512 * 0x20, Vaux1SysClkReq1HPValid
513 * 0x40, Vaux2SysClkReq1HPValid
514 * 0x80, Vaux3SysClkReq1HPValid
515 */
516 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8),
517 /*
518 * 0x10, VextSupply1SysClkReq1HPValid
519 * 0x20, VextSupply2SysClkReq1HPValid
520 * 0x40, VextSupply3SysClkReq1HPValid
521 */
522 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70),
523 /*
524 * 0x08, VanaHwHPReq1Valid
525 * 0x20, Vaux1HwHPReq1Valid
526 * 0x40, Vaux2HwHPReq1Valid
527 * 0x80, Vaux3HwHPReq1Valid
528 */
529 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8),
530 /*
531 * 0x01, VextSupply1HwHPReq1Valid
532 * 0x02, VextSupply2HwHPReq1Valid
533 * 0x04, VextSupply3HwHPReq1Valid
534 */
535 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07),
536 /*
537 * 0x08, VanaHwHPReq2Valid
538 * 0x20, Vaux1HwHPReq2Valid
539 * 0x40, Vaux2HwHPReq2Valid
540 * 0x80, Vaux3HwHPReq2Valid
541 */
542 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8),
543 /*
544 * 0x01, VextSupply1HwHPReq2Valid
545 * 0x02, VextSupply2HwHPReq2Valid
546 * 0x04, VextSupply3HwHPReq2Valid
547 */
548 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07),
549 /*
550 * 0x20, VanaSwHPReqValid
551 * 0x80, Vaux1SwHPReqValid
552 */
553 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0),
554 /*
555 * 0x01, Vaux2SwHPReqValid
556 * 0x02, Vaux3SwHPReqValid
557 * 0x04, VextSupply1SwHPReqValid
558 * 0x08, VextSupply2SwHPReqValid
559 * 0x10, VextSupply3SwHPReqValid
560 */
561 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f),
562 /*
563 * 0x02, SysClkReq2Valid1
564 * ...
565 * 0x80, SysClkReq8Valid1
566 */
567 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
568 /*
569 * 0x02, SysClkReq2Valid2
570 * ...
571 * 0x80, SysClkReq8Valid2
572 */
573 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
574 /*
575 * 0x02, VTVoutEna
576 * 0x04, Vintcore12Ena
577 * 0x38, Vintcore12Sel
578 * 0x40, Vintcore12LP
579 * 0x80, VTVoutLP
580 */
581 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
582 /*
583 * 0x02, VaudioEna
584 * 0x04, VdmicEna
585 * 0x08, Vamic1Ena
586 * 0x10, Vamic2Ena
587 */
588 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
589 /*
590 * 0x01, Vamic1_dzout
591 * 0x02, Vamic2_dzout
592 */
593 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
594 /*
595 * 0x0c, VanaRegu
596 * 0x03, VpllRegu
597 */
598 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
599 /*
600 * 0x01, VrefDDREna
601 * 0x02, VrefDDRSleepMode
602 */
603 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
604 /*
605 * 0x03, VextSupply1Regu
606 * 0x0c, VextSupply2Regu
607 * 0x30, VextSupply3Regu
608 * 0x40, ExtSupply2Bypass
609 * 0x80, ExtSupply3Bypass
610 */
611 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
612 /*
613 * 0x03, Vaux1Regu
614 * 0x0c, Vaux2Regu
615 */
616 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
617 /*
618 * 0x03, Vaux3Regu
619 */
620 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03),
621 /*
622 * 0x3f, Vsmps1Sel1
623 */
624 REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f),
625 /*
626 * 0x0f, Vaux1Sel
627 */
628 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
629 /*
630 * 0x0f, Vaux2Sel
631 */
632 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
633 /*
634 * 0x07, Vaux3Sel
635 */
636 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07),
637 /*
638 * 0x01, VextSupply12LP
639 */
640 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
641 /*
642 * 0x04, Vaux1Disch
643 * 0x08, Vaux2Disch
644 * 0x10, Vaux3Disch
645 * 0x20, Vintcore12Disch
646 * 0x40, VTVoutDisch
647 * 0x80, VaudioDisch
648 */
649 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc),
650 /*
651 * 0x02, VanaDisch
652 * 0x04, VdmicPullDownEna
653 * 0x10, VdmicDisch
654 */
655 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16),
656};
657
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100658static __devinit int
659ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value)
660{
661 int err;
662
663 if (value & ~ab8500_reg_init[id].mask) {
664 dev_err(&pdev->dev,
665 "Configuration error: value outside mask.\n");
666 return -EINVAL;
667 }
668
669 err = abx500_mask_and_set_register_interruptible(
670 &pdev->dev,
671 ab8500_reg_init[id].bank,
672 ab8500_reg_init[id].addr,
673 ab8500_reg_init[id].mask,
674 value);
675 if (err < 0) {
676 dev_err(&pdev->dev,
677 "Failed to initialize 0x%02x, 0x%02x.\n",
678 ab8500_reg_init[id].bank,
679 ab8500_reg_init[id].addr);
680 return err;
681 }
682
683 dev_vdbg(&pdev->dev,
684 "init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
685 ab8500_reg_init[id].bank,
686 ab8500_reg_init[id].addr,
687 ab8500_reg_init[id].mask,
688 value);
689
690 return 0;
691}
692
693static __devinit int ab8500_regulator_register(struct platform_device *pdev,
694 struct regulator_init_data *init_data,
695 int id,
696 struct device_node *np)
697{
698 struct ab8500_regulator_info *info = NULL;
699 struct regulator_config config = { };
700 int err;
701
702 /* assign per-regulator data */
703 info = &ab8500_regulator_info[id];
704 info->dev = &pdev->dev;
705
706 config.dev = &pdev->dev;
707 config.init_data = init_data;
708 config.driver_data = info;
709 config.of_node = np;
710
711 /* fix for hardware before ab8500v2.0 */
712 if (abx500_get_chip_id(info->dev) < 0x20) {
713 if (info->desc.id == AB8500_LDO_AUX3) {
714 info->desc.n_voltages =
715 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800716 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100717 info->voltage_mask = 0xf;
718 }
719 }
720
721 /* register regulator with framework */
722 info->regulator = regulator_register(&info->desc, &config);
723 if (IS_ERR(info->regulator)) {
724 err = PTR_ERR(info->regulator);
725 dev_err(&pdev->dev, "failed to register regulator %s\n",
726 info->desc.name);
727 /* when we fail, un-register all earlier regulators */
728 while (--id >= 0) {
729 info = &ab8500_regulator_info[id];
730 regulator_unregister(info->regulator);
731 }
732 return err;
733 }
734
735 return 0;
736}
737
Lee Jones3a8334b2012-05-17 14:45:16 +0100738static struct of_regulator_match ab8500_regulator_matches[] = {
Lee Jones7e715b92012-05-30 12:47:26 +0800739 { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, },
740 { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, },
741 { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, },
742 { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
743 { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, },
744 { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, },
745 { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, },
746 { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
747 { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
748 { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
749 { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
Lee Jones3a8334b2012-05-17 14:45:16 +0100750};
751
752static __devinit int
753ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
754{
755 int err, i;
756
757 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
758 err = ab8500_regulator_register(
759 pdev, ab8500_regulator_matches[i].init_data,
760 i, ab8500_regulator_matches[i].of_node);
761 if (err)
762 return err;
763 }
764
765 return 0;
766}
767
Sundar R IYERc789ca22010-07-13 21:48:56 +0530768static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
769{
770 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200771 struct ab8500_platform_data *pdata;
Lee Jones3a8334b2012-05-17 14:45:16 +0100772 struct device_node *np = pdev->dev.of_node;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530773 int i, err;
774
Lee Jones3a8334b2012-05-17 14:45:16 +0100775 if (np) {
776 err = of_regulator_match(&pdev->dev, np,
777 ab8500_regulator_matches,
778 ARRAY_SIZE(ab8500_regulator_matches));
779 if (err < 0) {
780 dev_err(&pdev->dev,
781 "Error parsing regulator init data: %d\n", err);
782 return err;
783 }
784
785 err = ab8500_regulator_of_probe(pdev, np);
786 return err;
787 }
788
Sundar R IYERc789ca22010-07-13 21:48:56 +0530789 if (!ab8500) {
790 dev_err(&pdev->dev, "null mfd parent\n");
791 return -EINVAL;
792 }
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200793 pdata = dev_get_platdata(ab8500->dev);
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100794 if (!pdata) {
795 dev_err(&pdev->dev, "null pdata\n");
796 return -EINVAL;
797 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530798
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100799 /* make sure the platform data has the correct size */
800 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100801 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100802 return -EINVAL;
803 }
804
Bengt Jonsson79568b942011-03-11 11:54:46 +0100805 /* initialize registers */
806 for (i = 0; i < pdata->num_regulator_reg_init; i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100807 int id, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100808
809 id = pdata->regulator_reg_init[i].id;
810 value = pdata->regulator_reg_init[i].value;
811
812 /* check for configuration errors */
813 if (id >= AB8500_NUM_REGULATOR_REGISTERS) {
814 dev_err(&pdev->dev,
815 "Configuration error: id outside range.\n");
816 return -EINVAL;
817 }
Bengt Jonsson79568b942011-03-11 11:54:46 +0100818
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100819 err = ab8500_regulator_init_registers(pdev, id, value);
820 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +0100821 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100822 }
823
Sundar R IYERc789ca22010-07-13 21:48:56 +0530824 /* register all regulators */
825 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100826 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
827 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530828 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530829 }
830
831 return 0;
832}
833
834static __devexit int ab8500_regulator_remove(struct platform_device *pdev)
835{
836 int i;
837
838 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
839 struct ab8500_regulator_info *info = NULL;
840 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100841
842 dev_vdbg(rdev_get_dev(info->regulator),
843 "%s-remove\n", info->desc.name);
844
Sundar R IYERc789ca22010-07-13 21:48:56 +0530845 regulator_unregister(info->regulator);
846 }
847
848 return 0;
849}
850
851static struct platform_driver ab8500_regulator_driver = {
852 .probe = ab8500_regulator_probe,
853 .remove = __devexit_p(ab8500_regulator_remove),
854 .driver = {
855 .name = "ab8500-regulator",
856 .owner = THIS_MODULE,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530857 },
858};
859
860static int __init ab8500_regulator_init(void)
861{
862 int ret;
863
864 ret = platform_driver_register(&ab8500_regulator_driver);
865 if (ret != 0)
866 pr_err("Failed to register ab8500 regulator: %d\n", ret);
867
868 return ret;
869}
870subsys_initcall(ab8500_regulator_init);
871
872static void __exit ab8500_regulator_exit(void)
873{
874 platform_driver_unregister(&ab8500_regulator_driver);
875}
876module_exit(ab8500_regulator_exit);
877
878MODULE_LICENSE("GPL v2");
879MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
880MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
881MODULE_ALIAS("platform:ab8500-regulator");