blob: 4d9d556a47ccd138728a9d8fd3cf9e26c6000159 [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 Walleija0a70142012-08-20 18:41:35 +020040 * @voltage_shift: shift to control regulator voltage
Linus Walleij42ab6162011-03-17 13:25:02 +010041 * @delay: startup/set voltage delay in us
Sundar R IYERc789ca22010-07-13 21:48:56 +053042 */
43struct ab8500_regulator_info {
44 struct device *dev;
45 struct regulator_desc desc;
Sundar R IYERc789ca22010-07-13 21:48:56 +053046 struct regulator_dev *regulator;
Mattias Wallin47c16972010-09-10 17:47:56 +020047 u8 update_bank;
48 u8 update_reg;
Bengt Jonssone1159e62010-12-10 11:08:44 +010049 u8 update_mask;
50 u8 update_val_enable;
Mattias Wallin47c16972010-09-10 17:47:56 +020051 u8 voltage_bank;
52 u8 voltage_reg;
53 u8 voltage_mask;
Linus Walleija0a70142012-08-20 18:41:35 +020054 u8 voltage_shift;
Linus Walleij42ab6162011-03-17 13:25:02 +010055 unsigned int delay;
Sundar R IYERc789ca22010-07-13 21:48:56 +053056};
57
58/* voltage tables for the vauxn/vintcore supplies */
Axel Linec1cc4d2012-05-20 10:33:35 +080059static const unsigned int ldo_vauxn_voltages[] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +053060 1100000,
61 1200000,
62 1300000,
63 1400000,
64 1500000,
65 1800000,
66 1850000,
67 1900000,
68 2500000,
69 2650000,
70 2700000,
71 2750000,
72 2800000,
73 2900000,
74 3000000,
75 3300000,
76};
77
Axel Linec1cc4d2012-05-20 10:33:35 +080078static const unsigned int ldo_vaux3_voltages[] = {
Bengt Jonsson2b751512010-12-10 11:08:43 +010079 1200000,
80 1500000,
81 1800000,
82 2100000,
83 2500000,
84 2750000,
85 2790000,
86 2910000,
87};
88
Axel Linec1cc4d2012-05-20 10:33:35 +080089static const unsigned int ldo_vintcore_voltages[] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +053090 1200000,
91 1225000,
92 1250000,
93 1275000,
94 1300000,
95 1325000,
96 1350000,
97};
98
99static int ab8500_regulator_enable(struct regulator_dev *rdev)
100{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100101 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530102 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
103
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100104 if (info == NULL) {
105 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530106 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100107 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530108
Mattias Wallin47c16972010-09-10 17:47:56 +0200109 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonssone1159e62010-12-10 11:08:44 +0100110 info->update_bank, info->update_reg,
111 info->update_mask, info->update_val_enable);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530112 if (ret < 0)
113 dev_err(rdev_get_dev(rdev),
114 "couldn't set enable bits for regulator\n");
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100115
116 dev_vdbg(rdev_get_dev(rdev),
117 "%s-enable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
118 info->desc.name, info->update_bank, info->update_reg,
119 info->update_mask, info->update_val_enable);
120
Sundar R IYERc789ca22010-07-13 21:48:56 +0530121 return ret;
122}
123
124static int ab8500_regulator_disable(struct regulator_dev *rdev)
125{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100126 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530127 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
128
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100129 if (info == NULL) {
130 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530131 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100132 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530133
Mattias Wallin47c16972010-09-10 17:47:56 +0200134 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonssone1159e62010-12-10 11:08:44 +0100135 info->update_bank, info->update_reg,
136 info->update_mask, 0x0);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530137 if (ret < 0)
138 dev_err(rdev_get_dev(rdev),
139 "couldn't set disable bits for regulator\n");
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100140
141 dev_vdbg(rdev_get_dev(rdev),
142 "%s-disable (bank, reg, mask, value): 0x%x, 0x%x, 0x%x, 0x%x\n",
143 info->desc.name, info->update_bank, info->update_reg,
144 info->update_mask, 0x0);
145
Sundar R IYERc789ca22010-07-13 21:48:56 +0530146 return ret;
147}
148
149static int ab8500_regulator_is_enabled(struct regulator_dev *rdev)
150{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100151 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530152 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100153 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530154
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100155 if (info == NULL) {
156 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530157 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100158 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530159
Mattias Wallin47c16972010-09-10 17:47:56 +0200160 ret = abx500_get_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100161 info->update_bank, info->update_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530162 if (ret < 0) {
163 dev_err(rdev_get_dev(rdev),
164 "couldn't read 0x%x register\n", info->update_reg);
165 return ret;
166 }
167
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100168 dev_vdbg(rdev_get_dev(rdev),
169 "%s-is_enabled (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
170 " 0x%x\n",
171 info->desc.name, info->update_bank, info->update_reg,
172 info->update_mask, regval);
173
174 if (regval & info->update_mask)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530175 return true;
176 else
177 return false;
178}
179
Axel Lin3bf6e902012-02-24 17:15:45 +0800180static int ab8500_regulator_get_voltage_sel(struct regulator_dev *rdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530181{
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100182 int ret, val;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530183 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100184 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530185
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100186 if (info == NULL) {
187 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530188 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100189 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530190
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100191 ret = abx500_get_register_interruptible(info->dev,
192 info->voltage_bank, info->voltage_reg, &regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530193 if (ret < 0) {
194 dev_err(rdev_get_dev(rdev),
195 "couldn't read voltage reg for regulator\n");
196 return ret;
197 }
198
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100199 dev_vdbg(rdev_get_dev(rdev),
Linus Walleija0a70142012-08-20 18:41:35 +0200200 "%s-get_voltage (bank, reg, mask, shift, value): "
201 "0x%x, 0x%x, 0x%x, 0x%x, 0x%x\n",
202 info->desc.name, info->voltage_bank,
203 info->voltage_reg, info->voltage_mask,
204 info->voltage_shift, regval);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100205
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100206 val = regval & info->voltage_mask;
Linus Walleija0a70142012-08-20 18:41:35 +0200207 return val >> info->voltage_shift;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530208}
209
Axel Linae713d32012-03-20 09:51:08 +0800210static int ab8500_regulator_set_voltage_sel(struct regulator_dev *rdev,
211 unsigned selector)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530212{
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100213 int ret;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530214 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100215 u8 regval;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530216
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100217 if (info == NULL) {
218 dev_err(rdev_get_dev(rdev), "regulator info null pointer\n");
Sundar R IYERc789ca22010-07-13 21:48:56 +0530219 return -EINVAL;
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100220 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530221
Sundar R IYERc789ca22010-07-13 21:48:56 +0530222 /* set the registers for the request */
Linus Walleija0a70142012-08-20 18:41:35 +0200223 regval = (u8)selector << info->voltage_shift;
Mattias Wallin47c16972010-09-10 17:47:56 +0200224 ret = abx500_mask_and_set_register_interruptible(info->dev,
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100225 info->voltage_bank, info->voltage_reg,
226 info->voltage_mask, regval);
Sundar R IYERc789ca22010-07-13 21:48:56 +0530227 if (ret < 0)
228 dev_err(rdev_get_dev(rdev),
229 "couldn't set voltage reg for regulator\n");
230
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100231 dev_vdbg(rdev_get_dev(rdev),
232 "%s-set_voltage (bank, reg, mask, value): 0x%x, 0x%x, 0x%x,"
233 " 0x%x\n",
234 info->desc.name, info->voltage_bank, info->voltage_reg,
235 info->voltage_mask, regval);
236
Sundar R IYERc789ca22010-07-13 21:48:56 +0530237 return ret;
238}
239
Linus Walleij42ab6162011-03-17 13:25:02 +0100240static int ab8500_regulator_set_voltage_time_sel(struct regulator_dev *rdev,
241 unsigned int old_sel,
242 unsigned int new_sel)
243{
244 struct ab8500_regulator_info *info = rdev_get_drvdata(rdev);
Linus Walleij42ab6162011-03-17 13:25:02 +0100245
Linus Walleij42ab6162011-03-17 13:25:02 +0100246 return info->delay;
247}
248
Sundar R IYERc789ca22010-07-13 21:48:56 +0530249static struct regulator_ops ab8500_regulator_ops = {
250 .enable = ab8500_regulator_enable,
251 .disable = ab8500_regulator_disable,
252 .is_enabled = ab8500_regulator_is_enabled,
Axel Lin3bf6e902012-02-24 17:15:45 +0800253 .get_voltage_sel = ab8500_regulator_get_voltage_sel,
Axel Linae713d32012-03-20 09:51:08 +0800254 .set_voltage_sel = ab8500_regulator_set_voltage_sel,
Axel Linec1cc4d2012-05-20 10:33:35 +0800255 .list_voltage = regulator_list_voltage_table,
Linus Walleij42ab6162011-03-17 13:25:02 +0100256 .set_voltage_time_sel = ab8500_regulator_set_voltage_time_sel,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530257};
258
Bengt Jonsson6909b452010-12-10 11:08:47 +0100259static struct regulator_ops ab8500_regulator_fixed_ops = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530260 .enable = ab8500_regulator_enable,
261 .disable = ab8500_regulator_disable,
262 .is_enabled = ab8500_regulator_is_enabled,
Axel Lin7142e212012-06-08 10:27:49 +0800263 .list_voltage = regulator_list_voltage_linear,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530264};
265
Bengt Jonsson6909b452010-12-10 11:08:47 +0100266static struct ab8500_regulator_info
267 ab8500_regulator_info[AB8500_NUM_REGULATORS] = {
Sundar R IYERc789ca22010-07-13 21:48:56 +0530268 /*
Bengt Jonssone1159e62010-12-10 11:08:44 +0100269 * Variable Voltage Regulators
270 * name, min mV, max mV,
271 * update bank, reg, mask, enable val
Axel Linec1cc4d2012-05-20 10:33:35 +0800272 * volt bank, reg, mask
Sundar R IYERc789ca22010-07-13 21:48:56 +0530273 */
Bengt Jonsson6909b452010-12-10 11:08:47 +0100274 [AB8500_LDO_AUX1] = {
275 .desc = {
276 .name = "LDO-AUX1",
277 .ops = &ab8500_regulator_ops,
278 .type = REGULATOR_VOLTAGE,
279 .id = AB8500_LDO_AUX1,
280 .owner = THIS_MODULE,
281 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800282 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100283 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100284 .update_bank = 0x04,
285 .update_reg = 0x09,
286 .update_mask = 0x03,
287 .update_val_enable = 0x01,
288 .voltage_bank = 0x04,
289 .voltage_reg = 0x1f,
290 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100291 },
292 [AB8500_LDO_AUX2] = {
293 .desc = {
294 .name = "LDO-AUX2",
295 .ops = &ab8500_regulator_ops,
296 .type = REGULATOR_VOLTAGE,
297 .id = AB8500_LDO_AUX2,
298 .owner = THIS_MODULE,
299 .n_voltages = ARRAY_SIZE(ldo_vauxn_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800300 .volt_table = ldo_vauxn_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100301 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100302 .update_bank = 0x04,
303 .update_reg = 0x09,
304 .update_mask = 0x0c,
305 .update_val_enable = 0x04,
306 .voltage_bank = 0x04,
307 .voltage_reg = 0x20,
308 .voltage_mask = 0x0f,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100309 },
310 [AB8500_LDO_AUX3] = {
311 .desc = {
312 .name = "LDO-AUX3",
313 .ops = &ab8500_regulator_ops,
314 .type = REGULATOR_VOLTAGE,
315 .id = AB8500_LDO_AUX3,
316 .owner = THIS_MODULE,
317 .n_voltages = ARRAY_SIZE(ldo_vaux3_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800318 .volt_table = ldo_vaux3_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100319 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100320 .update_bank = 0x04,
321 .update_reg = 0x0a,
322 .update_mask = 0x03,
323 .update_val_enable = 0x01,
324 .voltage_bank = 0x04,
325 .voltage_reg = 0x21,
326 .voltage_mask = 0x07,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100327 },
328 [AB8500_LDO_INTCORE] = {
329 .desc = {
330 .name = "LDO-INTCORE",
331 .ops = &ab8500_regulator_ops,
332 .type = REGULATOR_VOLTAGE,
333 .id = AB8500_LDO_INTCORE,
334 .owner = THIS_MODULE,
335 .n_voltages = ARRAY_SIZE(ldo_vintcore_voltages),
Axel Linec1cc4d2012-05-20 10:33:35 +0800336 .volt_table = ldo_vintcore_voltages,
Bengt Jonsson6909b452010-12-10 11:08:47 +0100337 },
Bengt Jonsson6909b452010-12-10 11:08:47 +0100338 .update_bank = 0x03,
339 .update_reg = 0x80,
340 .update_mask = 0x44,
341 .update_val_enable = 0x04,
342 .voltage_bank = 0x03,
343 .voltage_reg = 0x80,
344 .voltage_mask = 0x38,
Linus Walleija0a70142012-08-20 18:41:35 +0200345 .voltage_shift = 3,
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
Lee Jonesd79df322013-03-21 15:58:58 +0000480 * 0x0c, VpllRequestCtrl
Bengt Jonsson79568b942011-03-11 11:54:46 +0100481 * 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 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000497 * 0x01, Vsmps1SysClkReq1HPValid
498 * 0x02, Vsmps2SysClkReq1HPValid
499 * 0x04, Vsmps3SysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100500 * 0x08, VanaSysClkReq1HPValid
Lee Jonesd79df322013-03-21 15:58:58 +0000501 * 0x10, VpllSysClkReq1HPValid
Bengt Jonsson79568b942011-03-11 11:54:46 +0100502 * 0x20, Vaux1SysClkReq1HPValid
503 * 0x40, Vaux2SysClkReq1HPValid
504 * 0x80, Vaux3SysClkReq1HPValid
505 */
Lee Jonesd79df322013-03-21 15:58:58 +0000506 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID1, 0x03, 0x07, 0xff),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100507 /*
508 * 0x10, VextSupply1SysClkReq1HPValid
509 * 0x20, VextSupply2SysClkReq1HPValid
510 * 0x40, VextSupply3SysClkReq1HPValid
511 */
512 REG_INIT(AB8500_REGUSYSCLKREQ1HPVALID2, 0x03, 0x08, 0x70),
513 /*
514 * 0x08, VanaHwHPReq1Valid
515 * 0x20, Vaux1HwHPReq1Valid
516 * 0x40, Vaux2HwHPReq1Valid
517 * 0x80, Vaux3HwHPReq1Valid
518 */
519 REG_INIT(AB8500_REGUHWHPREQ1VALID1, 0x03, 0x09, 0xe8),
520 /*
521 * 0x01, VextSupply1HwHPReq1Valid
522 * 0x02, VextSupply2HwHPReq1Valid
523 * 0x04, VextSupply3HwHPReq1Valid
524 */
525 REG_INIT(AB8500_REGUHWHPREQ1VALID2, 0x03, 0x0a, 0x07),
526 /*
527 * 0x08, VanaHwHPReq2Valid
528 * 0x20, Vaux1HwHPReq2Valid
529 * 0x40, Vaux2HwHPReq2Valid
530 * 0x80, Vaux3HwHPReq2Valid
531 */
532 REG_INIT(AB8500_REGUHWHPREQ2VALID1, 0x03, 0x0b, 0xe8),
533 /*
534 * 0x01, VextSupply1HwHPReq2Valid
535 * 0x02, VextSupply2HwHPReq2Valid
536 * 0x04, VextSupply3HwHPReq2Valid
537 */
538 REG_INIT(AB8500_REGUHWHPREQ2VALID2, 0x03, 0x0c, 0x07),
539 /*
540 * 0x20, VanaSwHPReqValid
541 * 0x80, Vaux1SwHPReqValid
542 */
543 REG_INIT(AB8500_REGUSWHPREQVALID1, 0x03, 0x0d, 0xa0),
544 /*
545 * 0x01, Vaux2SwHPReqValid
546 * 0x02, Vaux3SwHPReqValid
547 * 0x04, VextSupply1SwHPReqValid
548 * 0x08, VextSupply2SwHPReqValid
549 * 0x10, VextSupply3SwHPReqValid
550 */
551 REG_INIT(AB8500_REGUSWHPREQVALID2, 0x03, 0x0e, 0x1f),
552 /*
553 * 0x02, SysClkReq2Valid1
554 * ...
555 * 0x80, SysClkReq8Valid1
556 */
557 REG_INIT(AB8500_REGUSYSCLKREQVALID1, 0x03, 0x0f, 0xfe),
558 /*
559 * 0x02, SysClkReq2Valid2
560 * ...
561 * 0x80, SysClkReq8Valid2
562 */
563 REG_INIT(AB8500_REGUSYSCLKREQVALID2, 0x03, 0x10, 0xfe),
564 /*
565 * 0x02, VTVoutEna
566 * 0x04, Vintcore12Ena
567 * 0x38, Vintcore12Sel
568 * 0x40, Vintcore12LP
569 * 0x80, VTVoutLP
570 */
571 REG_INIT(AB8500_REGUMISC1, 0x03, 0x80, 0xfe),
572 /*
573 * 0x02, VaudioEna
574 * 0x04, VdmicEna
575 * 0x08, Vamic1Ena
576 * 0x10, Vamic2Ena
577 */
578 REG_INIT(AB8500_VAUDIOSUPPLY, 0x03, 0x83, 0x1e),
579 /*
580 * 0x01, Vamic1_dzout
581 * 0x02, Vamic2_dzout
582 */
583 REG_INIT(AB8500_REGUCTRL1VAMIC, 0x03, 0x84, 0x03),
584 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000585 * 0x0c, VBBNRegu
586 * 0x03, VBBPRegu
587 * NOTE! PRCMU register
588 */
589 REG_INIT(AB8500_ARMREGU2, 0x04, 0x01, 0x0f),
590 /*
591 * 0x0c, VBBPSel1
592 * 0x03, VBBNSel1
593 * NOTE! PRCMU register
594 */
595 REG_INIT(AB8500_VBBSEL1, 0x04, 0x11, 0x0f),
596 /*
597 * 0x0c, VBBNSel2
598 * 0x03, VBBPSel2
599 * NOTE! PRCMU register
600 */
601 REG_INIT(AB8500_VBBSEL2, 0x04, 0x12, 0x0f),
602 /*
603 * 0x03, Vsmps1Regu
604 * 0x0c, Vsmps1SelCtrl
605 */
606 REG_INIT(AB8500_VSMPS1REGU, 0x04, 0x03, 0x0f),
607 /*
608 * 0x03, Vsmps2Regu
609 * 0x0c, Vsmps2SelCtrl
610 */
611 REG_INIT(AB8500_VSMPS2REGU, 0x04, 0x04, 0x0f),
612 /*
Bengt Jonsson79568b942011-03-11 11:54:46 +0100613 * 0x0c, VanaRegu
614 * 0x03, VpllRegu
615 */
616 REG_INIT(AB8500_VPLLVANAREGU, 0x04, 0x06, 0x0f),
617 /*
618 * 0x01, VrefDDREna
619 * 0x02, VrefDDRSleepMode
620 */
621 REG_INIT(AB8500_VREFDDR, 0x04, 0x07, 0x03),
622 /*
623 * 0x03, VextSupply1Regu
624 * 0x0c, VextSupply2Regu
625 * 0x30, VextSupply3Regu
626 * 0x40, ExtSupply2Bypass
627 * 0x80, ExtSupply3Bypass
628 */
629 REG_INIT(AB8500_EXTSUPPLYREGU, 0x04, 0x08, 0xff),
630 /*
631 * 0x03, Vaux1Regu
632 * 0x0c, Vaux2Regu
633 */
634 REG_INIT(AB8500_VAUX12REGU, 0x04, 0x09, 0x0f),
635 /*
Lee Jonesd79df322013-03-21 15:58:58 +0000636 * 0x0c, Vrf1Regu
Bengt Jonsson79568b942011-03-11 11:54:46 +0100637 * 0x03, Vaux3Regu
638 */
Lee Jonesd79df322013-03-21 15:58:58 +0000639 REG_INIT(AB8500_VRF1VAUX3REGU, 0x04, 0x0a, 0x0f),
Bengt Jonsson79568b942011-03-11 11:54:46 +0100640 /*
641 * 0x3f, Vsmps1Sel1
642 */
643 REG_INIT(AB8500_VSMPS1SEL1, 0x04, 0x13, 0x3f),
644 /*
645 * 0x0f, Vaux1Sel
646 */
647 REG_INIT(AB8500_VAUX1SEL, 0x04, 0x1f, 0x0f),
648 /*
649 * 0x0f, Vaux2Sel
650 */
651 REG_INIT(AB8500_VAUX2SEL, 0x04, 0x20, 0x0f),
652 /*
653 * 0x07, Vaux3Sel
654 */
655 REG_INIT(AB8500_VRF1VAUX3SEL, 0x04, 0x21, 0x07),
656 /*
657 * 0x01, VextSupply12LP
658 */
659 REG_INIT(AB8500_REGUCTRL2SPARE, 0x04, 0x22, 0x01),
660 /*
661 * 0x04, Vaux1Disch
662 * 0x08, Vaux2Disch
663 * 0x10, Vaux3Disch
664 * 0x20, Vintcore12Disch
665 * 0x40, VTVoutDisch
666 * 0x80, VaudioDisch
667 */
668 REG_INIT(AB8500_REGUCTRLDISCH, 0x04, 0x43, 0xfc),
669 /*
670 * 0x02, VanaDisch
671 * 0x04, VdmicPullDownEna
672 * 0x10, VdmicDisch
673 */
674 REG_INIT(AB8500_REGUCTRLDISCH2, 0x04, 0x44, 0x16),
675};
676
Bill Pembertona5023572012-11-19 13:22:22 -0500677static int
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100678ab8500_regulator_init_registers(struct platform_device *pdev, int id, int value)
679{
680 int err;
681
682 if (value & ~ab8500_reg_init[id].mask) {
683 dev_err(&pdev->dev,
684 "Configuration error: value outside mask.\n");
685 return -EINVAL;
686 }
687
688 err = abx500_mask_and_set_register_interruptible(
689 &pdev->dev,
690 ab8500_reg_init[id].bank,
691 ab8500_reg_init[id].addr,
692 ab8500_reg_init[id].mask,
693 value);
694 if (err < 0) {
695 dev_err(&pdev->dev,
696 "Failed to initialize 0x%02x, 0x%02x.\n",
697 ab8500_reg_init[id].bank,
698 ab8500_reg_init[id].addr);
699 return err;
700 }
701
702 dev_vdbg(&pdev->dev,
703 "init: 0x%02x, 0x%02x, 0x%02x, 0x%02x\n",
704 ab8500_reg_init[id].bank,
705 ab8500_reg_init[id].addr,
706 ab8500_reg_init[id].mask,
707 value);
708
709 return 0;
710}
711
Bill Pembertona5023572012-11-19 13:22:22 -0500712static int ab8500_regulator_register(struct platform_device *pdev,
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100713 struct regulator_init_data *init_data,
714 int id,
715 struct device_node *np)
716{
717 struct ab8500_regulator_info *info = NULL;
718 struct regulator_config config = { };
719 int err;
720
721 /* assign per-regulator data */
722 info = &ab8500_regulator_info[id];
723 info->dev = &pdev->dev;
724
725 config.dev = &pdev->dev;
726 config.init_data = init_data;
727 config.driver_data = info;
728 config.of_node = np;
729
730 /* fix for hardware before ab8500v2.0 */
731 if (abx500_get_chip_id(info->dev) < 0x20) {
732 if (info->desc.id == AB8500_LDO_AUX3) {
733 info->desc.n_voltages =
734 ARRAY_SIZE(ldo_vauxn_voltages);
Axel Linec1cc4d2012-05-20 10:33:35 +0800735 info->desc.volt_table = ldo_vauxn_voltages;
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100736 info->voltage_mask = 0xf;
737 }
738 }
739
740 /* register regulator with framework */
741 info->regulator = regulator_register(&info->desc, &config);
742 if (IS_ERR(info->regulator)) {
743 err = PTR_ERR(info->regulator);
744 dev_err(&pdev->dev, "failed to register regulator %s\n",
745 info->desc.name);
746 /* when we fail, un-register all earlier regulators */
747 while (--id >= 0) {
748 info = &ab8500_regulator_info[id];
749 regulator_unregister(info->regulator);
750 }
751 return err;
752 }
753
754 return 0;
755}
756
Lee Jones3a8334b2012-05-17 14:45:16 +0100757static struct of_regulator_match ab8500_regulator_matches[] = {
Lee Jones7e715b92012-05-30 12:47:26 +0800758 { .name = "ab8500_ldo_aux1", .driver_data = (void *) AB8500_LDO_AUX1, },
759 { .name = "ab8500_ldo_aux2", .driver_data = (void *) AB8500_LDO_AUX2, },
760 { .name = "ab8500_ldo_aux3", .driver_data = (void *) AB8500_LDO_AUX3, },
761 { .name = "ab8500_ldo_intcore", .driver_data = (void *) AB8500_LDO_INTCORE, },
762 { .name = "ab8500_ldo_tvout", .driver_data = (void *) AB8500_LDO_TVOUT, },
763 { .name = "ab8500_ldo_usb", .driver_data = (void *) AB8500_LDO_USB, },
764 { .name = "ab8500_ldo_audio", .driver_data = (void *) AB8500_LDO_AUDIO, },
765 { .name = "ab8500_ldo_anamic1", .driver_data = (void *) AB8500_LDO_ANAMIC1, },
766 { .name = "ab8500_ldo_amamic2", .driver_data = (void *) AB8500_LDO_ANAMIC2, },
767 { .name = "ab8500_ldo_dmic", .driver_data = (void *) AB8500_LDO_DMIC, },
768 { .name = "ab8500_ldo_ana", .driver_data = (void *) AB8500_LDO_ANA, },
Lee Jones3a8334b2012-05-17 14:45:16 +0100769};
770
Bill Pembertona5023572012-11-19 13:22:22 -0500771static int
Lee Jones3a8334b2012-05-17 14:45:16 +0100772ab8500_regulator_of_probe(struct platform_device *pdev, struct device_node *np)
773{
774 int err, i;
775
776 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
777 err = ab8500_regulator_register(
778 pdev, ab8500_regulator_matches[i].init_data,
779 i, ab8500_regulator_matches[i].of_node);
780 if (err)
781 return err;
782 }
783
784 return 0;
785}
786
Bill Pembertona5023572012-11-19 13:22:22 -0500787static int ab8500_regulator_probe(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530788{
789 struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent);
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200790 struct ab8500_platform_data *pdata;
Lee Jones3a8334b2012-05-17 14:45:16 +0100791 struct device_node *np = pdev->dev.of_node;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530792 int i, err;
793
Lee Jones3a8334b2012-05-17 14:45:16 +0100794 if (np) {
795 err = of_regulator_match(&pdev->dev, np,
796 ab8500_regulator_matches,
797 ARRAY_SIZE(ab8500_regulator_matches));
798 if (err < 0) {
799 dev_err(&pdev->dev,
800 "Error parsing regulator init data: %d\n", err);
801 return err;
802 }
803
804 err = ab8500_regulator_of_probe(pdev, np);
805 return err;
806 }
807
Sundar R IYERc789ca22010-07-13 21:48:56 +0530808 if (!ab8500) {
809 dev_err(&pdev->dev, "null mfd parent\n");
810 return -EINVAL;
811 }
Dan Carpenteraf54dec2010-08-14 11:03:16 +0200812 pdata = dev_get_platdata(ab8500->dev);
Bengt Jonssonfc24b422010-12-10 11:08:45 +0100813 if (!pdata) {
814 dev_err(&pdev->dev, "null pdata\n");
815 return -EINVAL;
816 }
Sundar R IYERc789ca22010-07-13 21:48:56 +0530817
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100818 /* make sure the platform data has the correct size */
819 if (pdata->num_regulator != ARRAY_SIZE(ab8500_regulator_info)) {
Bengt Jonsson79568b942011-03-11 11:54:46 +0100820 dev_err(&pdev->dev, "Configuration error: size mismatch.\n");
Bengt Jonssoncb189b02010-12-10 11:08:40 +0100821 return -EINVAL;
822 }
823
Bengt Jonsson79568b942011-03-11 11:54:46 +0100824 /* initialize registers */
825 for (i = 0; i < pdata->num_regulator_reg_init; i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100826 int id, value;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100827
828 id = pdata->regulator_reg_init[i].id;
829 value = pdata->regulator_reg_init[i].value;
830
831 /* check for configuration errors */
832 if (id >= AB8500_NUM_REGULATOR_REGISTERS) {
833 dev_err(&pdev->dev,
834 "Configuration error: id outside range.\n");
835 return -EINVAL;
836 }
Bengt Jonsson79568b942011-03-11 11:54:46 +0100837
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100838 err = ab8500_regulator_init_registers(pdev, id, value);
839 if (err < 0)
Bengt Jonsson79568b942011-03-11 11:54:46 +0100840 return err;
Bengt Jonsson79568b942011-03-11 11:54:46 +0100841 }
842
Sundar R IYERc789ca22010-07-13 21:48:56 +0530843 /* register all regulators */
844 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100845 err = ab8500_regulator_register(pdev, &pdata->regulator[i], i, NULL);
846 if (err < 0)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530847 return err;
Sundar R IYERc789ca22010-07-13 21:48:56 +0530848 }
849
850 return 0;
851}
852
Bill Pemberton8dc995f2012-11-19 13:26:10 -0500853static int ab8500_regulator_remove(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530854{
855 int i;
856
857 for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) {
858 struct ab8500_regulator_info *info = NULL;
859 info = &ab8500_regulator_info[i];
Bengt Jonsson09aefa12010-12-10 11:08:46 +0100860
861 dev_vdbg(rdev_get_dev(info->regulator),
862 "%s-remove\n", info->desc.name);
863
Sundar R IYERc789ca22010-07-13 21:48:56 +0530864 regulator_unregister(info->regulator);
865 }
866
867 return 0;
868}
869
870static struct platform_driver ab8500_regulator_driver = {
871 .probe = ab8500_regulator_probe,
Bill Pemberton5eb9f2b2012-11-19 13:20:42 -0500872 .remove = ab8500_regulator_remove,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530873 .driver = {
874 .name = "ab8500-regulator",
875 .owner = THIS_MODULE,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530876 },
877};
878
879static int __init ab8500_regulator_init(void)
880{
881 int ret;
882
883 ret = platform_driver_register(&ab8500_regulator_driver);
884 if (ret != 0)
885 pr_err("Failed to register ab8500 regulator: %d\n", ret);
886
887 return ret;
888}
889subsys_initcall(ab8500_regulator_init);
890
891static void __exit ab8500_regulator_exit(void)
892{
893 platform_driver_unregister(&ab8500_regulator_driver);
894}
895module_exit(ab8500_regulator_exit);
896
897MODULE_LICENSE("GPL v2");
898MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>");
899MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC");
900MODULE_ALIAS("platform:ab8500-regulator");