blob: 09014f38a9481f8afb630ce8a5c5fdb513100380 [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
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
Bill Pembertona5023572012-11-19 13:22:22 -0500644static int
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100645ab8500_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
Bill Pembertona5023572012-11-19 13:22:22 -0500679static int ab8500_regulator_register(struct platform_device *pdev,
Lee Jonesa7ac1d92012-05-17 14:45:14 +0100680 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
Bill Pembertona5023572012-11-19 13:22:22 -0500738static int
Lee Jones3a8334b2012-05-17 14:45:16 +0100739ab8500_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
Bill Pembertona5023572012-11-19 13:22:22 -0500754static int ab8500_regulator_probe(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530755{
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
Bill Pemberton8dc995f2012-11-19 13:26:10 -0500820static int ab8500_regulator_remove(struct platform_device *pdev)
Sundar R IYERc789ca22010-07-13 21:48:56 +0530821{
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,
Bill Pemberton5eb9f2b2012-11-19 13:20:42 -0500839 .remove = ab8500_regulator_remove,
Sundar R IYERc789ca22010-07-13 21:48:56 +0530840 .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");