blob: c884a5c4b4735b776dc14580bf7e0055c108cfba [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
Bengt Jonsson6909b452010-12-10 11:08:47 +0100260static struct regulator_ops ab8500_regulator_fixed_ops = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530261 .enable = ab8500_regulator_enable,
262 .disable = ab8500_regulator_disable,
263 .is_enabled = ab8500_regulator_is_enabled,
Axel Lin7142e212012-06-08 10:27:49 +0800264 .list_voltage = regulator_list_voltage_linear,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530265};
266
Bengt Jonsson6909b452010-12-10 11:08:47 +0100267static struct ab8500_regulator_info
268 ab8500_regulator_info[AB8500_NUM_REGULATORS] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530269 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100270 * Variable Voltage Regulators
271 * name, min mV, max mV,
272 * update bank, reg, mask, enable val
Axel Linec1cc4d2012-05-20 10:33:35 +0800273 * volt bank, reg, mask
Sundar R IYERc789ca22010-07-13 21:48:56 +0530274 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100275 [AB8500_LDO_AUX1] = {
276 .desc = {
277 .name = "LDO-AUX1",
278 .ops = &ab8500_regulator_ops,
279 .type = REGULATOR_VOLTAGE,
280 .id = AB8500_LDO_AUX1,
281 .owner = THIS_MODULE,
282 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800283 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100284 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100285 .update_bank = 0x04,
286 .update_reg = 0x09,
287 .update_mask = 0x03,
288 .update_val_enable = 0x01,
289 .voltage_bank = 0x04,
290 .voltage_reg = 0x1f,
291 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100292 },
293 [AB8500_LDO_AUX2] = {
294 .desc = {
295 .name = "LDO-AUX2",
296 .ops = &ab8500_regulator_ops,
297 .type = REGULATOR_VOLTAGE,
298 .id = AB8500_LDO_AUX2,
299 .owner = THIS_MODULE,
300 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800301 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100302 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100303 .update_bank = 0x04,
304 .update_reg = 0x09,
305 .update_mask = 0x0c,
306 .update_val_enable = 0x04,
307 .voltage_bank = 0x04,
308 .voltage_reg = 0x20,
309 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100310 },
311 [AB8500_LDO_AUX3] = {
312 .desc = {
313 .name = "LDO-AUX3",
314 .ops = &ab8500_regulator_ops,
315 .type = REGULATOR_VOLTAGE,
316 .id = AB8500_LDO_AUX3,
317 .owner = THIS_MODULE,
318 .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800319 .volt_table = ldo_vaux3_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100320 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100321 .update_bank = 0x04,
322 .update_reg = 0x0a,
323 .update_mask = 0x03,
324 .update_val_enable = 0x01,
325 .voltage_bank = 0x04,
326 .voltage_reg = 0x21,
327 .voltage_mask = 0x07,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100328 },
329 [AB8500_LDO_INTCORE] = {
330 .desc = {
331 .name = "LDO-INTCORE",
332 .ops = &ab8500_regulator_ops,
333 .type = REGULATOR_VOLTAGE,
334 .id = AB8500_LDO_INTCORE,
335 .owner = THIS_MODULE,
336 .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800337 .volt_table = ldo_vintcore_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100338 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100339 .update_bank = 0x03,
340 .update_reg = 0x80,
341 .update_mask = 0x44,
342 .update_val_enable = 0x04,
343 .voltage_bank = 0x03,
344 .voltage_reg = 0x80,
345 .voltage_mask = 0x38,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100346 },
Sundar R IYERc789ca22010-07-13 21:48:56 +0530347
348 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100349 * Fixed Voltage Regulators
350 * name, fixed mV,
351 * update bank, reg, mask, enable val
Sundar R IYERc789ca22010-07-13 21:48:56 +0530352 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100353 [AB8500_LDO_TVOUT] = {
354 .desc = {
355 .name = "LDO-TVOUT",
356 .ops = &ab8500_regulator_fixed_ops,
357 .type = REGULATOR_VOLTAGE,
358 .id = AB8500_LDO_TVOUT,
359 .owner = THIS_MODULE,
360 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800361 .min_uV = 2000000,
Axel Lin7fee2af2012-08-07 22:21:23 +0800362 .enable_time = 10000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100363 },
Linus Walleij42ab6162011-03-17 13:25:02 +0100364 .delay = 10000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100365 .update_bank = 0x03,
366 .update_reg = 0x80,
367 .update_mask = 0x82,
368 .update_val_enable = 0x02,
369 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100370 [AB8500_LDO_USB] = {
371 .desc = {
372 .name = "LDO-USB",
373 .ops = &ab8500_regulator_fixed_ops,
374 .type = REGULATOR_VOLTAGE,
375 .id = AB8500_LDO_USB,
376 .owner = THIS_MODULE,
377 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800378 .min_uV = 3300000,
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100379 },
Bengt Jonssonea05ef32011-03-10 14:43:31 +0100380 .update_bank = 0x03,
381 .update_reg = 0x82,
382 .update_mask = 0x03,
383 .update_val_enable = 0x01,
384 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100385 [AB8500_LDO_AUDIO] = {
386 .desc = {
387 .name = "LDO-AUDIO",
388 .ops = &ab8500_regulator_fixed_ops,
389 .type = REGULATOR_VOLTAGE,
390 .id = AB8500_LDO_AUDIO,
391 .owner = THIS_MODULE,
392 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800393 .min_uV = 2000000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100394 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100395 .update_bank = 0x03,
396 .update_reg = 0x83,
397 .update_mask = 0x02,
398 .update_val_enable = 0x02,
399 },
400 [AB8500_LDO_ANAMIC1] = {
401 .desc = {
402 .name = "LDO-ANAMIC1",
403 .ops = &ab8500_regulator_fixed_ops,
404 .type = REGULATOR_VOLTAGE,
405 .id = AB8500_LDO_ANAMIC1,
406 .owner = THIS_MODULE,
407 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800408 .min_uV = 2050000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100409 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100410 .update_bank = 0x03,
411 .update_reg = 0x83,
412 .update_mask = 0x08,
413 .update_val_enable = 0x08,
414 },
415 [AB8500_LDO_ANAMIC2] = {
416 .desc = {
417 .name = "LDO-ANAMIC2",
418 .ops = &ab8500_regulator_fixed_ops,
419 .type = REGULATOR_VOLTAGE,
420 .id = AB8500_LDO_ANAMIC2,
421 .owner = THIS_MODULE,
422 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800423 .min_uV = 2050000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100424 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100425 .update_bank = 0x03,
426 .update_reg = 0x83,
427 .update_mask = 0x10,
428 .update_val_enable = 0x10,
429 },
430 [AB8500_LDO_DMIC] = {
431 .desc = {
432 .name = "LDO-DMIC",
433 .ops = &ab8500_regulator_fixed_ops,
434 .type = REGULATOR_VOLTAGE,
435 .id = AB8500_LDO_DMIC,
436 .owner = THIS_MODULE,
437 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800438 .min_uV = 1800000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100439 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100440 .update_bank = 0x03,
441 .update_reg = 0x83,
442 .update_mask = 0x04,
443 .update_val_enable = 0x04,
444 },
445 [AB8500_LDO_ANA] = {
446 .desc = {
447 .name = "LDO-ANA",
448 .ops = &ab8500_regulator_fixed_ops,
449 .type = REGULATOR_VOLTAGE,
450 .id = AB8500_LDO_ANA,
451 .owner = THIS_MODULE,
452 .n_voltages = 1,
Axel Lin7142e212012-06-08 10:27:49 +0800453 .min_uV = 1200000,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100454 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100455 .update_bank = 0x04,
456 .update_reg = 0x06,
457 .update_mask = 0x0c,
458 .update_val_enable = 0x04,
459 },
460
461
Sundar R IYERc789ca22010-07-13 21:48:56 +0530462};
463
Bengt Jonsson79568b942011-03-11 11:54:46 +0100464struct ab8500_reg_init {
465 u8 bank;
466 u8 addr;
467 u8 mask;
468};
469
470#define REG_INIT(_id, _bank, _addr, _mask) \
471 [_id] = { \
472 .bank = _bank, \
473 .addr = _addr, \
474 .mask = _mask, \
475 }
476
477static struct ab8500_reg_init ab8500_reg_init[] = {
478 /*
479 * 0x30, VanaRequestCtrl
480 * 0x0C, VpllRequestCtrl
481 * 0xc0, VextSupply1RequestCtrl
482 */
483 REG_INIT(AB8500_REGUREQUESTCTRL2, 0x03, 0x04, 0xfc),
484 /*
485 * 0x03, VextSupply2RequestCtrl
486 * 0x0c, VextSupply3RequestCtrl
487 * 0x30, Vaux1RequestCtrl
488 * 0xc0, Vaux2RequestCtrl
489 */
490 REG_INIT(AB8500_REGUREQUESTCTRL3, 0x03, 0x05, 0xff),
491 /*
492 * 0x03, Vaux3RequestCtrl
493 * 0x04, SwHPReq
494 */
495 REG_INIT(AB8500_REGUREQUESTCTRL4, 0x03, 0x06, 0x07),
496 /*
497 * 0x08, VanaSysClkReq1HPValid
498 * 0x20, Vaux1SysClkReq1HPValid
499 * 0x40, Vaux2SysClkReq1HPValid
500 * 0x80, Vaux3SysClkReq1HPValid
501 */
502 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xe8),
503 /*
504 * 0x10, VextSupply1SysClkReq1HPValid
505 * 0x20, VextSupply2SysClkReq1HPValid
506 * 0x40, VextSupply3SysClkReq1HPValid
507 */
508 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70),
509 /*
510 * 0x08, VanaHwHPReq1Valid
511 * 0x20, Vaux1HwHPReq1Valid
512 * 0x40, Vaux2HwHPReq1Valid
513 * 0x80, Vaux3HwHPReq1Valid
514 */
515 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8),
516 /*
517 * 0x01, VextSupply1HwHPReq1Valid
518 * 0x02, VextSupply2HwHPReq1Valid
519 * 0x04, VextSupply3HwHPReq1Valid
520 */
521 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07),
522 /*
523 * 0x08, VanaHwHPReq2Valid
524 * 0x20, Vaux1HwHPReq2Valid
525 * 0x40, Vaux2HwHPReq2Valid
526 * 0x80, Vaux3HwHPReq2Valid
527 */
528 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8),
529 /*
530 * 0x01, VextSupply1HwHPReq2Valid
531 * 0x02, VextSupply2HwHPReq2Valid
532 * 0x04, VextSupply3HwHPReq2Valid
533 */
534 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07),
535 /*
536 * 0x20, VanaSwHPReqValid
537 * 0x80, Vaux1SwHPReqValid
538 */
539 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0),
540 /*
541 * 0x01, Vaux2SwHPReqValid
542 * 0x02, Vaux3SwHPReqValid
543 * 0x04, VextSupply1SwHPReqValid
544 * 0x08, VextSupply2SwHPReqValid
545 * 0x10, VextSupply3SwHPReqValid
546 */
547 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f),
548 /*
549 * 0x02, SysClkReq2Valid1
550 * ...
551 * 0x80, SysClkReq8Valid1
552 */
553 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
554 /*
555 * 0x02, SysClkReq2Valid2
556 * ...
557 * 0x80, SysClkReq8Valid2
558 */
559 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
560 /*
561 * 0x02, VTVoutEna
562 * 0x04, Vintcore12Ena
563 * 0x38, Vintcore12Sel
564 * 0x40, Vintcore12LP
565 * 0x80, VTVoutLP
566 */
567 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
568 /*
569 * 0x02, VaudioEna
570 * 0x04, VdmicEna
571 * 0x08, Vamic1Ena
572 * 0x10, Vamic2Ena
573 */
574 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
575 /*
576 * 0x01, Vamic1_dzout
577 * 0x02, Vamic2_dzout
578 */
579 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
580 /*
581 * 0x0c, VanaRegu
582 * 0x03, VpllRegu
583 */
584 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
585 /*
586 * 0x01, VrefDDREna
587 * 0x02, VrefDDRSleepMode
588 */
589 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
590 /*
591 * 0x03, VextSupply1Regu
592 * 0x0c, VextSupply2Regu
593 * 0x30, VextSupply3Regu
594 * 0x40, ExtSupply2Bypass
595 * 0x80, ExtSupply3Bypass
596 */
597 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
598 /*
599 * 0x03, Vaux1Regu
600 * 0x0c, Vaux2Regu
601 */
602 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
603 /*
604 * 0x03, Vaux3Regu
605 */
606 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x03),
607 /*
608 * 0x3f, Vsmps1Sel1
609 */
610 REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f),
611 /*
612 * 0x0f, Vaux1Sel
613 */
614 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
615 /*
616 * 0x0f, Vaux2Sel
617 */
618 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
619 /*
620 * 0x07, Vaux3Sel
621 */
622 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07),
623 /*
624 * 0x01, VextSupply12LP
625 */
626 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
627 /*
628 * 0x04, Vaux1Disch
629 * 0x08, Vaux2Disch
630 * 0x10, Vaux3Disch
631 * 0x20, Vintcore12Disch
632 * 0x40, VTVoutDisch
633 * 0x80, VaudioDisch
634 */
635 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc),
636 /*
637 * 0x02, VanaDisch
638 * 0x04, VdmicPullDownEna
639 * 0x10, VdmicDisch
640 */
641 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16),
642};
643
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100644static __devinit int
645ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value)
646{
647 int err;
648
649 if (value & ~ab8500_reg_init[id].mask) {
650 dev_err(&pdev->dev,
651 "Configuration error: value outside mask.\n");
652 return -EINVAL;
653 }
654
655 err = abx500_mask_and_set_register_interruptible(
656 &pdev->dev,
657 ab8500_reg_init[id].bank,
658 ab8500_reg_init[id].addr,
659 ab8500_reg_init[id].mask,
660 value);
661 if (err < 0) {
662 dev_err(&pdev->dev,
663 "Failed to initialize 0x%02x, 0x%02x.\n",
664 ab8500_reg_init[id].bank,
665 ab8500_reg_init[id].addr);
666 return err;
667 }
668
669 dev_vdbg(&pdev->dev,
670 "init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
671 ab8500_reg_init[id].bank,
672 ab8500_reg_init[id].addr,
673 ab8500_reg_init[id].mask,
674 value);
675
676 return 0;
677}
678
679static __devinit int ab8500_regulator_register(struct platform_device *pdev,
680 struct regulator_init_data *init_data,
681 int id,
682 struct device_node *np)
683{
684 struct ab8500_regulator_info *info = NULL;
685 struct regulator_config config = { };
686 int err;
687
688 /* assign per-regulator data */
689 info = &ab8500_regulator_info[id];
690 info->dev = &pdev->dev;
691
692 config.dev = &pdev->dev;
693 config.init_data = init_data;
694 config.driver_data = info;
695 config.of_node = np;
696
697 /* fix for hardware before ab8500v2.0 */
698 if (abx500_get_chip_id(info->dev) < 0x20) {
699 if (info->desc.id == AB8500_LDO_AUX3) {
700 info->desc.n_voltages =
701 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800702 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100703 info->voltage_mask = 0xf;
704 }
705 }
706
707 /* register regulator with framework */
708 info->regulator = regulator_register(&info->desc, &config);
709 if (IS_ERR(info->regulator)) {
710 err = PTR_ERR(info->regulator);
711 dev_err(&pdev->dev, "failed to register regulator %s\n",
712 info->desc.name);
713 /* when we fail, un-register all earlier regulators */
714 while (--id >= 0) {
715 info = &ab8500_regulator_info[id];
716 regulator_unregister(info->regulator);
717 }
718 return err;
719 }
720
721 return 0;
722}
723
Lee Jones3a8334b2012-05-17 14:45:16 +0100724static struct of_regulator_match ab8500_regulator_matches[] = {
Lee Jones7e715b92012-05-30 12:47:26 +0800725 { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, },
726 { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, },
727 { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, },
728 { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
729 { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, },
730 { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, },
731 { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, },
732 { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
733 { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
734 { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
735 { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
Lee Jones3a8334b2012-05-17 14:45:16 +0100736};
737
738static __devinit int
739ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
740{
741 int err, i;
742
743 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
744 err = ab8500_regulator_register(
745 pdev, ab8500_regulator_matches[i].init_data,
746 i, ab8500_regulator_matches[i].of_node);
747 if (err)
748 return err;
749 }
750
751 return 0;
752}
753
Sundar R IYERc789ca22010-07-13 21:48:56 +0530754static __devinit int ab8500_regulator_probe(struct platform_device *pdev)
755{
756 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200757 struct ab8500_platform_data *pdata;
Lee Jones3a8334b2012-05-17 14:45:16 +0100758 struct device_node *np = pdev->dev.of_node;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530759 int i, err;
760
Lee Jones3a8334b2012-05-17 14:45:16 +0100761 if (np) {
762 err = of_regulator_match(&pdev->dev, np,
763 ab8500_regulator_matches,
764 ARRAY_SIZE(ab8500_regulator_matches));
765 if (err < 0) {
766 dev_err(&pdev->dev,
767 "Error parsing regulator init data: %d\n", err);
768 return err;
769 }
770
771 err = ab8500_regulator_of_probe(pdev, np);
772 return err;
773 }
774
Sundar R IYERc789ca22010-07-13 21:48:56 +0530775 if (!ab8500) {
776 dev_err(&pdev->dev, "null mfd parent\n");
777 return -EINVAL;
778 }
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200779 pdata = dev_get_platdata(ab8500->dev);
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100780 if (!pdata) {
781 dev_err(&pdev->dev, "null pdata\n");
782 return -EINVAL;
783 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530784
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100785 /* make sure the platform data has the correct size */
786 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100787 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100788 return -EINVAL;
789 }
790
Bengt Jonsson79568b942011-03-11 11:54:46 +0100791 /* initialize registers */
792 for (i = 0; i < pdata->num_regulator_reg_init; i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100793 int id, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100794
795 id = pdata->regulator_reg_init[i].id;
796 value = pdata->regulator_reg_init[i].value;
797
798 /* check for configuration errors */
799 if (id >= AB8500_NUM_REGULATOR_REGISTERS) {
800 dev_err(&pdev->dev,
801 "Configuration error: id outside range.\n");
802 return -EINVAL;
803 }
Bengt Jonsson79568b942011-03-11 11:54:46 +0100804
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100805 err = ab8500_regulator_init_registers(pdev, id, value);
806 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +0100807 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100808 }
809
Sundar R IYERc789ca22010-07-13 21:48:56 +0530810 /* register all regulators */
811 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100812 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
813 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530814 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530815 }
816
817 return 0;
818}
819
820static __devexit int ab8500_regulator_remove(struct platform_device *pdev)
821{
822 int i;
823
824 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
825 struct ab8500_regulator_info *info = NULL;
826 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100827
828 dev_vdbg(rdev_get_dev(info->regulator),
829 "%s-remove\n", info->desc.name);
830
Sundar R IYERc789ca22010-07-13 21:48:56 +0530831 regulator_unregister(info->regulator);
832 }
833
834 return 0;
835}
836
837static struct platform_driver ab8500_regulator_driver = {
838 .probe = ab8500_regulator_probe,
839 .remove = __devexit_p(ab8500_regulator_remove),
840 .driver = {
841 .name = "ab8500-regulator",
842 .owner = THIS_MODULE,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530843 },
844};
845
846static int __init ab8500_regulator_init(void)
847{
848 int ret;
849
850 ret = platform_driver_register(&ab8500_regulator_driver);
851 if (ret != 0)
852 pr_err("Failed to register ab8500 regulator: %d\n", ret);
853
854 return ret;
855}
856subsys_initcall(ab8500_regulator_init);
857
858static void __exit ab8500_regulator_exit(void)
859{
860 platform_driver_unregister(&ab8500_regulator_driver);
861}
862module_exit(ab8500_regulator_exit);
863
864MODULE_LICENSE("GPL v2");
865MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
866MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
867MODULE_ALIAS("platform:ab8500-regulator");