diff options
-rw-r--r-- | drivers/mfd/Kconfig | 10 | ||||
-rw-r--r-- | drivers/mfd/Makefile | 1 | ||||
-rw-r--r-- | drivers/mfd/ab8500-core.c | 4 | ||||
-rw-r--r-- | drivers/mfd/max8998.c | 158 | ||||
-rw-r--r-- | drivers/regulator/Kconfig | 34 | ||||
-rw-r--r-- | drivers/regulator/Makefile | 5 | ||||
-rw-r--r-- | drivers/regulator/ab8500.c | 427 | ||||
-rw-r--r-- | drivers/regulator/ad5398.c | 288 | ||||
-rw-r--r-- | drivers/regulator/isl6271a-regulator.c | 236 | ||||
-rw-r--r-- | drivers/regulator/lp3971.c | 10 | ||||
-rw-r--r-- | drivers/regulator/max1586.c | 10 | ||||
-rw-r--r-- | drivers/regulator/max8660.c | 10 | ||||
-rw-r--r-- | drivers/regulator/max8998.c | 635 | ||||
-rw-r--r-- | drivers/regulator/tps65023-regulator.c | 2 | ||||
-rw-r--r-- | drivers/regulator/tps6507x-regulator.c | 1 | ||||
-rw-r--r-- | drivers/regulator/tps6586x-regulator.c | 396 | ||||
-rw-r--r-- | drivers/regulator/wm8994-regulator.c | 5 | ||||
-rw-r--r-- | include/linux/mfd/ab8500.h | 6 | ||||
-rw-r--r-- | include/linux/mfd/max8998-private.h | 112 | ||||
-rw-r--r-- | include/linux/mfd/max8998.h | 78 | ||||
-rw-r--r-- | include/linux/regulator/ab8500.h | 25 |
21 files changed, 2431 insertions, 22 deletions
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index d75909e7cf2f..db51ea1c6082 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig | |||
@@ -293,6 +293,16 @@ config MFD_MAX8925 | |||
293 | accessing the device, additional drivers must be enabled in order | 293 | accessing the device, additional drivers must be enabled in order |
294 | to use the functionality of the device. | 294 | to use the functionality of the device. |
295 | 295 | ||
296 | config MFD_MAX8998 | ||
297 | bool "Maxim Semiconductor MAX8998 PMIC Support" | ||
298 | depends on I2C=y | ||
299 | select MFD_CORE | ||
300 | help | ||
301 | Say yes here to support for Maxim Semiconductor MAX8998. This is | ||
302 | a Power Management IC. This driver provies common support for | ||
303 | accessing the device, additional drivers must be enabled in order | ||
304 | to use the functionality of the device. | ||
305 | |||
296 | config MFD_WM8400 | 306 | config MFD_WM8400 |
297 | tristate "Support Wolfson Microelectronics WM8400" | 307 | tristate "Support Wolfson Microelectronics WM8400" |
298 | select MFD_CORE | 308 | select MFD_CORE |
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 1e48d7e3e884..feaeeaeeddb7 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile | |||
@@ -58,6 +58,7 @@ obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o | |||
58 | obj-$(CONFIG_PMIC_DA903X) += da903x.o | 58 | obj-$(CONFIG_PMIC_DA903X) += da903x.o |
59 | max8925-objs := max8925-core.o max8925-i2c.o | 59 | max8925-objs := max8925-core.o max8925-i2c.o |
60 | obj-$(CONFIG_MFD_MAX8925) += max8925.o | 60 | obj-$(CONFIG_MFD_MAX8925) += max8925.o |
61 | obj-$(CONFIG_MFD_MAX8998) += max8998.o | ||
61 | 62 | ||
62 | pcf50633-objs := pcf50633-core.o pcf50633-irq.o | 63 | pcf50633-objs := pcf50633-core.o pcf50633-irq.o |
63 | obj-$(CONFIG_MFD_PCF50633) += pcf50633.o | 64 | obj-$(CONFIG_MFD_PCF50633) += pcf50633.o |
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c index f3d26fa9c34d..defa786dee34 100644 --- a/drivers/mfd/ab8500-core.c +++ b/drivers/mfd/ab8500-core.c | |||
@@ -16,6 +16,7 @@ | |||
16 | #include <linux/platform_device.h> | 16 | #include <linux/platform_device.h> |
17 | #include <linux/mfd/core.h> | 17 | #include <linux/mfd/core.h> |
18 | #include <linux/mfd/ab8500.h> | 18 | #include <linux/mfd/ab8500.h> |
19 | #include <linux/regulator/ab8500.h> | ||
19 | 20 | ||
20 | /* | 21 | /* |
21 | * Interrupt register offsets | 22 | * Interrupt register offsets |
@@ -352,6 +353,7 @@ static struct mfd_cell ab8500_devs[] = { | |||
352 | { .name = "ab8500-audio", }, | 353 | { .name = "ab8500-audio", }, |
353 | { .name = "ab8500-usb", }, | 354 | { .name = "ab8500-usb", }, |
354 | { .name = "ab8500-pwm", }, | 355 | { .name = "ab8500-pwm", }, |
356 | { .name = "ab8500-regulator", }, | ||
355 | }; | 357 | }; |
356 | 358 | ||
357 | int __devinit ab8500_init(struct ab8500 *ab8500) | 359 | int __devinit ab8500_init(struct ab8500 *ab8500) |
@@ -411,7 +413,7 @@ int __devinit ab8500_init(struct ab8500 *ab8500) | |||
411 | goto out_removeirq; | 413 | goto out_removeirq; |
412 | } | 414 | } |
413 | 415 | ||
414 | ret = mfd_add_devices(ab8500->dev, -1, ab8500_devs, | 416 | ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs, |
415 | ARRAY_SIZE(ab8500_devs), NULL, | 417 | ARRAY_SIZE(ab8500_devs), NULL, |
416 | ab8500->irq_base); | 418 | ab8500->irq_base); |
417 | if (ret) | 419 | if (ret) |
diff --git a/drivers/mfd/max8998.c b/drivers/mfd/max8998.c new file mode 100644 index 000000000000..73e6f5c4efc9 --- /dev/null +++ b/drivers/mfd/max8998.c | |||
@@ -0,0 +1,158 @@ | |||
1 | /* | ||
2 | * max8698.c - mfd core driver for the Maxim 8998 | ||
3 | * | ||
4 | * Copyright (C) 2009-2010 Samsung Electronics | ||
5 | * Kyungmin Park <kyungmin.park@samsung.com> | ||
6 | * Marek Szyprowski <m.szyprowski@samsung.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/moduleparam.h> | ||
25 | #include <linux/init.h> | ||
26 | #include <linux/slab.h> | ||
27 | #include <linux/i2c.h> | ||
28 | #include <linux/mutex.h> | ||
29 | #include <linux/mfd/core.h> | ||
30 | #include <linux/mfd/max8998.h> | ||
31 | #include <linux/mfd/max8998-private.h> | ||
32 | |||
33 | static struct mfd_cell max8998_devs[] = { | ||
34 | { | ||
35 | .name = "max8998-pmic", | ||
36 | } | ||
37 | }; | ||
38 | |||
39 | static int max8998_i2c_device_read(struct max8998_dev *max8998, u8 reg, u8 *dest) | ||
40 | { | ||
41 | struct i2c_client *client = max8998->i2c_client; | ||
42 | int ret; | ||
43 | |||
44 | mutex_lock(&max8998->iolock); | ||
45 | ret = i2c_smbus_read_byte_data(client, reg); | ||
46 | mutex_unlock(&max8998->iolock); | ||
47 | if (ret < 0) | ||
48 | return ret; | ||
49 | |||
50 | ret &= 0xff; | ||
51 | *dest = ret; | ||
52 | return 0; | ||
53 | } | ||
54 | |||
55 | static int max8998_i2c_device_write(struct max8998_dev *max8998, u8 reg, u8 value) | ||
56 | { | ||
57 | struct i2c_client *client = max8998->i2c_client; | ||
58 | int ret; | ||
59 | |||
60 | mutex_lock(&max8998->iolock); | ||
61 | ret = i2c_smbus_write_byte_data(client, reg, value); | ||
62 | mutex_unlock(&max8998->iolock); | ||
63 | return ret; | ||
64 | } | ||
65 | |||
66 | static int max8998_i2c_device_update(struct max8998_dev *max8998, u8 reg, | ||
67 | u8 val, u8 mask) | ||
68 | { | ||
69 | struct i2c_client *client = max8998->i2c_client; | ||
70 | int ret; | ||
71 | |||
72 | mutex_lock(&max8998->iolock); | ||
73 | ret = i2c_smbus_read_byte_data(client, reg); | ||
74 | if (ret >= 0) { | ||
75 | u8 old_val = ret & 0xff; | ||
76 | u8 new_val = (val & mask) | (old_val & (~mask)); | ||
77 | ret = i2c_smbus_write_byte_data(client, reg, new_val); | ||
78 | if (ret >= 0) | ||
79 | ret = 0; | ||
80 | } | ||
81 | mutex_unlock(&max8998->iolock); | ||
82 | return ret; | ||
83 | } | ||
84 | |||
85 | static int max8998_i2c_probe(struct i2c_client *i2c, | ||
86 | const struct i2c_device_id *id) | ||
87 | { | ||
88 | struct max8998_dev *max8998; | ||
89 | int ret = 0; | ||
90 | |||
91 | max8998 = kzalloc(sizeof(struct max8998_dev), GFP_KERNEL); | ||
92 | if (max8998 == NULL) | ||
93 | return -ENOMEM; | ||
94 | |||
95 | i2c_set_clientdata(i2c, max8998); | ||
96 | max8998->dev = &i2c->dev; | ||
97 | max8998->i2c_client = i2c; | ||
98 | max8998->dev_read = max8998_i2c_device_read; | ||
99 | max8998->dev_write = max8998_i2c_device_write; | ||
100 | max8998->dev_update = max8998_i2c_device_update; | ||
101 | mutex_init(&max8998->iolock); | ||
102 | |||
103 | ret = mfd_add_devices(max8998->dev, -1, | ||
104 | max8998_devs, ARRAY_SIZE(max8998_devs), | ||
105 | NULL, 0); | ||
106 | if (ret < 0) | ||
107 | goto err; | ||
108 | |||
109 | return ret; | ||
110 | |||
111 | err: | ||
112 | mfd_remove_devices(max8998->dev); | ||
113 | kfree(max8998); | ||
114 | return ret; | ||
115 | } | ||
116 | |||
117 | static int max8998_i2c_remove(struct i2c_client *i2c) | ||
118 | { | ||
119 | struct max8998_dev *max8998 = i2c_get_clientdata(i2c); | ||
120 | |||
121 | mfd_remove_devices(max8998->dev); | ||
122 | kfree(max8998); | ||
123 | |||
124 | return 0; | ||
125 | } | ||
126 | |||
127 | static const struct i2c_device_id max8998_i2c_id[] = { | ||
128 | { "max8998", 0 }, | ||
129 | { } | ||
130 | }; | ||
131 | MODULE_DEVICE_TABLE(i2c, max8998_i2c_id); | ||
132 | |||
133 | static struct i2c_driver max8998_i2c_driver = { | ||
134 | .driver = { | ||
135 | .name = "max8998", | ||
136 | .owner = THIS_MODULE, | ||
137 | }, | ||
138 | .probe = max8998_i2c_probe, | ||
139 | .remove = max8998_i2c_remove, | ||
140 | .id_table = max8998_i2c_id, | ||
141 | }; | ||
142 | |||
143 | static int __init max8998_i2c_init(void) | ||
144 | { | ||
145 | return i2c_add_driver(&max8998_i2c_driver); | ||
146 | } | ||
147 | /* init early so consumer devices can complete system boot */ | ||
148 | subsys_initcall(max8998_i2c_init); | ||
149 | |||
150 | static void __exit max8998_i2c_exit(void) | ||
151 | { | ||
152 | i2c_del_driver(&max8998_i2c_driver); | ||
153 | } | ||
154 | module_exit(max8998_i2c_exit); | ||
155 | |||
156 | MODULE_DESCRIPTION("MAXIM 8998 multi-function core driver"); | ||
157 | MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>"); | ||
158 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig index 04f2e085116a..172951bf23a4 100644 --- a/drivers/regulator/Kconfig +++ b/drivers/regulator/Kconfig | |||
@@ -100,6 +100,14 @@ config REGULATOR_MAX8925 | |||
100 | help | 100 | help |
101 | Say y here to support the voltage regulaltor of Maxim MAX8925 PMIC. | 101 | Say y here to support the voltage regulaltor of Maxim MAX8925 PMIC. |
102 | 102 | ||
103 | config REGULATOR_MAX8998 | ||
104 | tristate "Maxim 8998 voltage regulator" | ||
105 | depends on MFD_MAX8998 | ||
106 | help | ||
107 | This driver controls a Maxim 8998 voltage output regulator | ||
108 | via I2C bus. The provided regulator is suitable for S3C6410 | ||
109 | and S5PC1XX chips to control VCC_CORE and VCC_USIM voltages. | ||
110 | |||
103 | config REGULATOR_TWL4030 | 111 | config REGULATOR_TWL4030 |
104 | bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC" | 112 | bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC" |
105 | depends on TWL4030_CORE | 113 | depends on TWL4030_CORE |
@@ -201,5 +209,31 @@ config REGULATOR_88PM8607 | |||
201 | help | 209 | help |
202 | This driver supports 88PM8607 voltage regulator chips. | 210 | This driver supports 88PM8607 voltage regulator chips. |
203 | 211 | ||
212 | config REGULATOR_ISL6271A | ||
213 | tristate "Intersil ISL6271A Power regulator" | ||
214 | depends on I2C | ||
215 | help | ||
216 | This driver supports ISL6271A voltage regulator chip. | ||
217 | |||
218 | config REGULATOR_AD5398 | ||
219 | tristate "Analog Devices AD5398/AD5821 regulators" | ||
220 | depends on I2C | ||
221 | help | ||
222 | This driver supports AD5398 and AD5821 current regulator chips. | ||
223 | If building into module, its name is ad5398.ko. | ||
224 | |||
225 | config REGULATOR_AB8500 | ||
226 | bool "ST-Ericsson AB8500 Power Regulators" | ||
227 | depends on AB8500_CORE | ||
228 | help | ||
229 | This driver supports the regulators found on the ST-Ericsson mixed | ||
230 | signal AB8500 PMIC | ||
231 | |||
232 | config REGULATOR_TPS6586X | ||
233 | tristate "TI TPS6586X Power regulators" | ||
234 | depends on MFD_TPS6586X | ||
235 | help | ||
236 | This driver supports TPS6586X voltage regulator chips. | ||
237 | |||
204 | endif | 238 | endif |
205 | 239 | ||
diff --git a/drivers/regulator/Makefile b/drivers/regulator/Makefile index 4e7feece22d5..8285fd832e16 100644 --- a/drivers/regulator/Makefile +++ b/drivers/regulator/Makefile | |||
@@ -8,6 +8,7 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o | |||
8 | obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o | 8 | obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o |
9 | obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o | 9 | obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o |
10 | 10 | ||
11 | obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o | ||
11 | obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o | 12 | obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o |
12 | obj-$(CONFIG_REGULATOR_DUMMY) += dummy.o | 13 | obj-$(CONFIG_REGULATOR_DUMMY) += dummy.o |
13 | obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o | 14 | obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o |
@@ -16,12 +17,14 @@ obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o | |||
16 | obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o | 17 | obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o |
17 | obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o | 18 | obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o |
18 | obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o | 19 | obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o |
20 | obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o | ||
19 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o | 21 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o |
20 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o | 22 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o |
21 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o | 23 | obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o |
22 | obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o | 24 | obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o |
23 | obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o | 25 | obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o |
24 | obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o | 26 | obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o |
27 | obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o | ||
25 | obj-$(CONFIG_REGULATOR_DA903X) += da903x.o | 28 | obj-$(CONFIG_REGULATOR_DA903X) += da903x.o |
26 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o | 29 | obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o |
27 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o | 30 | obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o |
@@ -31,5 +34,7 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o | |||
31 | obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o | 34 | obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o |
32 | obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o | 35 | obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o |
33 | obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o | 36 | obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o |
37 | obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o | ||
38 | obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o | ||
34 | 39 | ||
35 | ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG | 40 | ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG |
diff --git a/drivers/regulator/ab8500.c b/drivers/regulator/ab8500.c new file mode 100644 index 000000000000..dc3f1a491675 --- /dev/null +++ b/drivers/regulator/ab8500.c | |||
@@ -0,0 +1,427 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * | ||
6 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson | ||
7 | * | ||
8 | * AB8500 peripheral regulators | ||
9 | * | ||
10 | * AB8500 supports the following regulators, | ||
11 | * LDOs - VAUDIO, VANAMIC2/2, VDIGMIC, VINTCORE12, VTVOUT, | ||
12 | * VAUX1/2/3, VANA | ||
13 | * | ||
14 | * for DB8500 cut 1.0 and previous versions of the silicon, all accesses | ||
15 | * to registers are through the DB8500 SPI. In cut 1.1 onwards, these | ||
16 | * accesses are through the DB8500 PRCMU I2C | ||
17 | * | ||
18 | */ | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/kernel.h> | ||
21 | #include <linux/err.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/mfd/ab8500.h> | ||
24 | #include <linux/regulator/driver.h> | ||
25 | #include <linux/regulator/machine.h> | ||
26 | #include <linux/regulator/ab8500.h> | ||
27 | |||
28 | /** | ||
29 | * struct ab8500_regulator_info - ab8500 regulator information | ||
30 | * @desc: regulator description | ||
31 | * @ab8500: ab8500 parent | ||
32 | * @regulator_dev: regulator device | ||
33 | * @max_uV: maximum voltage (for variable voltage supplies) | ||
34 | * @min_uV: minimum voltage (for variable voltage supplies) | ||
35 | * @fixed_uV: typical voltage (for fixed voltage supplies) | ||
36 | * @update_reg: register to control on/off | ||
37 | * @mask: mask to enable/disable regulator | ||
38 | * @enable: bits to enable the regulator in normal(high power) mode | ||
39 | * @voltage_reg: register to control regulator voltage | ||
40 | * @voltage_mask: mask to control regulator voltage | ||
41 | * @supported_voltages: supported voltage table | ||
42 | * @voltages_len: number of supported voltages for the regulator | ||
43 | */ | ||
44 | struct ab8500_regulator_info { | ||
45 | struct device *dev; | ||
46 | struct regulator_desc desc; | ||
47 | struct ab8500 *ab8500; | ||
48 | struct regulator_dev *regulator; | ||
49 | int max_uV; | ||
50 | int min_uV; | ||
51 | int fixed_uV; | ||
52 | int update_reg; | ||
53 | int mask; | ||
54 | int enable; | ||
55 | int voltage_reg; | ||
56 | int voltage_mask; | ||
57 | int const *supported_voltages; | ||
58 | int voltages_len; | ||
59 | }; | ||
60 | |||
61 | /* voltage tables for the vauxn/vintcore supplies */ | ||
62 | static const int ldo_vauxn_voltages[] = { | ||
63 | 1100000, | ||
64 | 1200000, | ||
65 | 1300000, | ||
66 | 1400000, | ||
67 | 1500000, | ||
68 | 1800000, | ||
69 | 1850000, | ||
70 | 1900000, | ||
71 | 2500000, | ||
72 | 2650000, | ||
73 | 2700000, | ||
74 | 2750000, | ||
75 | 2800000, | ||
76 | 2900000, | ||
77 | 3000000, | ||
78 | 3300000, | ||
79 | }; | ||
80 | |||
81 | static const int ldo_vintcore_voltages[] = { | ||
82 | 1200000, | ||
83 | 1225000, | ||
84 | 1250000, | ||
85 | 1275000, | ||
86 | 1300000, | ||
87 | 1325000, | ||
88 | 1350000, | ||
89 | }; | ||
90 | |||
91 | static int ab8500_regulator_enable(struct regulator_dev *rdev) | ||
92 | { | ||
93 | int regulator_id, ret; | ||
94 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | ||
95 | |||
96 | regulator_id = rdev_get_id(rdev); | ||
97 | if (regulator_id >= AB8500_NUM_REGULATORS) | ||
98 | return -EINVAL; | ||
99 | |||
100 | ret = ab8500_set_bits(info->ab8500, info->update_reg, | ||
101 | info->mask, info->enable); | ||
102 | if (ret < 0) | ||
103 | dev_err(rdev_get_dev(rdev), | ||
104 | "couldn't set enable bits for regulator\n"); | ||
105 | return ret; | ||
106 | } | ||
107 | |||
108 | static int ab8500_regulator_disable(struct regulator_dev *rdev) | ||
109 | { | ||
110 | int regulator_id, ret; | ||
111 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | ||
112 | |||
113 | regulator_id = rdev_get_id(rdev); | ||
114 | if (regulator_id >= AB8500_NUM_REGULATORS) | ||
115 | return -EINVAL; | ||
116 | |||
117 | ret = ab8500_set_bits(info->ab8500, info->update_reg, | ||
118 | info->mask, 0x0); | ||
119 | if (ret < 0) | ||
120 | dev_err(rdev_get_dev(rdev), | ||
121 | "couldn't set disable bits for regulator\n"); | ||
122 | return ret; | ||
123 | } | ||
124 | |||
125 | static int ab8500_regulator_is_enabled(struct regulator_dev *rdev) | ||
126 | { | ||
127 | int regulator_id, ret; | ||
128 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | ||
129 | |||
130 | regulator_id = rdev_get_id(rdev); | ||
131 | if (regulator_id >= AB8500_NUM_REGULATORS) | ||
132 | return -EINVAL; | ||
133 | |||
134 | ret = ab8500_read(info->ab8500, info->update_reg); | ||
135 | if (ret < 0) { | ||
136 | dev_err(rdev_get_dev(rdev), | ||
137 | "couldn't read 0x%x register\n", info->update_reg); | ||
138 | return ret; | ||
139 | } | ||
140 | |||
141 | if (ret & info->mask) | ||
142 | return true; | ||
143 | else | ||
144 | return false; | ||
145 | } | ||
146 | |||
147 | static int ab8500_list_voltage(struct regulator_dev *rdev, unsigned selector) | ||
148 | { | ||
149 | int regulator_id; | ||
150 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | ||
151 | |||
152 | regulator_id = rdev_get_id(rdev); | ||
153 | if (regulator_id >= AB8500_NUM_REGULATORS) | ||
154 | return -EINVAL; | ||
155 | |||
156 | /* return the uV for the fixed regulators */ | ||
157 | if (info->fixed_uV) | ||
158 | return info->fixed_uV; | ||
159 | |||
160 | if (selector > info->voltages_len) | ||
161 | return -EINVAL; | ||
162 | |||
163 | return info->supported_voltages[selector]; | ||
164 | } | ||
165 | |||
166 | static int ab8500_regulator_get_voltage(struct regulator_dev *rdev) | ||
167 | { | ||
168 | int regulator_id, ret, val; | ||
169 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | ||
170 | |||
171 | regulator_id = rdev_get_id(rdev); | ||
172 | if (regulator_id >= AB8500_NUM_REGULATORS) | ||
173 | return -EINVAL; | ||
174 | |||
175 | ret = ab8500_read(info->ab8500, info->voltage_reg); | ||
176 | if (ret < 0) { | ||
177 | dev_err(rdev_get_dev(rdev), | ||
178 | "couldn't read voltage reg for regulator\n"); | ||
179 | return ret; | ||
180 | } | ||
181 | |||
182 | /* vintcore has a different layout */ | ||
183 | val = ret & info->voltage_mask; | ||
184 | if (regulator_id == AB8500_LDO_INTCORE) | ||
185 | ret = info->supported_voltages[val >> 0x3]; | ||
186 | else | ||
187 | ret = info->supported_voltages[val]; | ||
188 | |||
189 | return ret; | ||
190 | } | ||
191 | |||
192 | static int ab8500_get_best_voltage_index(struct regulator_dev *rdev, | ||
193 | int min_uV, int max_uV) | ||
194 | { | ||
195 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | ||
196 | int i; | ||
197 | |||
198 | /* check the supported voltage */ | ||
199 | for (i = 0; i < info->voltages_len; i++) { | ||
200 | if ((info->supported_voltages[i] >= min_uV) && | ||
201 | (info->supported_voltages[i] <= max_uV)) | ||
202 | return i; | ||
203 | } | ||
204 | |||
205 | return -EINVAL; | ||
206 | } | ||
207 | |||
208 | static int ab8500_regulator_set_voltage(struct regulator_dev *rdev, | ||
209 | int min_uV, int max_uV) | ||
210 | { | ||
211 | int regulator_id, ret; | ||
212 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | ||
213 | |||
214 | regulator_id = rdev_get_id(rdev); | ||
215 | if (regulator_id >= AB8500_NUM_REGULATORS) | ||
216 | return -EINVAL; | ||
217 | |||
218 | /* get the appropriate voltages within the range */ | ||
219 | ret = ab8500_get_best_voltage_index(rdev, min_uV, max_uV); | ||
220 | if (ret < 0) { | ||
221 | dev_err(rdev_get_dev(rdev), | ||
222 | "couldn't get best voltage for regulator\n"); | ||
223 | return ret; | ||
224 | } | ||
225 | |||
226 | /* set the registers for the request */ | ||
227 | ret = ab8500_set_bits(info->ab8500, info->voltage_reg, | ||
228 | info->voltage_mask, ret); | ||
229 | if (ret < 0) | ||
230 | dev_err(rdev_get_dev(rdev), | ||
231 | "couldn't set voltage reg for regulator\n"); | ||
232 | |||
233 | return ret; | ||
234 | } | ||
235 | |||
236 | static struct regulator_ops ab8500_regulator_ops = { | ||
237 | .enable = ab8500_regulator_enable, | ||
238 | .disable = ab8500_regulator_disable, | ||
239 | .is_enabled = ab8500_regulator_is_enabled, | ||
240 | .get_voltage = ab8500_regulator_get_voltage, | ||
241 | .set_voltage = ab8500_regulator_set_voltage, | ||
242 | .list_voltage = ab8500_list_voltage, | ||
243 | }; | ||
244 | |||
245 | static int ab8500_fixed_get_voltage(struct regulator_dev *rdev) | ||
246 | { | ||
247 | int regulator_id; | ||
248 | struct ab8500_regulator_info *info = rdev_get_drvdata(rdev); | ||
249 | |||
250 | regulator_id = rdev_get_id(rdev); | ||
251 | if (regulator_id >= AB8500_NUM_REGULATORS) | ||
252 | return -EINVAL; | ||
253 | |||
254 | return info->fixed_uV; | ||
255 | } | ||
256 | |||
257 | static struct regulator_ops ab8500_ldo_fixed_ops = { | ||
258 | .enable = ab8500_regulator_enable, | ||
259 | .disable = ab8500_regulator_disable, | ||
260 | .is_enabled = ab8500_regulator_is_enabled, | ||
261 | .get_voltage = ab8500_fixed_get_voltage, | ||
262 | .list_voltage = ab8500_list_voltage, | ||
263 | }; | ||
264 | |||
265 | #define AB8500_LDO(_id, min, max, reg, reg_mask, reg_enable, \ | ||
266 | volt_reg, volt_mask, voltages, \ | ||
267 | len_volts) \ | ||
268 | { \ | ||
269 | .desc = { \ | ||
270 | .name = "LDO-" #_id, \ | ||
271 | .ops = &ab8500_regulator_ops, \ | ||
272 | .type = REGULATOR_VOLTAGE, \ | ||
273 | .id = AB8500_LDO_##_id, \ | ||
274 | .owner = THIS_MODULE, \ | ||
275 | }, \ | ||
276 | .min_uV = (min) * 1000, \ | ||
277 | .max_uV = (max) * 1000, \ | ||
278 | .update_reg = reg, \ | ||
279 | .mask = reg_mask, \ | ||
280 | .enable = reg_enable, \ | ||
281 | .voltage_reg = volt_reg, \ | ||
282 | .voltage_mask = volt_mask, \ | ||
283 | .supported_voltages = voltages, \ | ||
284 | .voltages_len = len_volts, \ | ||
285 | .fixed_uV = 0, \ | ||
286 | } | ||
287 | |||
288 | #define AB8500_FIXED_LDO(_id, fixed, reg, reg_mask, \ | ||
289 | reg_enable) \ | ||
290 | { \ | ||
291 | .desc = { \ | ||
292 | .name = "LDO-" #_id, \ | ||
293 | .ops = &ab8500_ldo_fixed_ops, \ | ||
294 | .type = REGULATOR_VOLTAGE, \ | ||
295 | .id = AB8500_LDO_##_id, \ | ||
296 | .owner = THIS_MODULE, \ | ||
297 | }, \ | ||
298 | .fixed_uV = fixed * 1000, \ | ||
299 | .update_reg = reg, \ | ||
300 | .mask = reg_mask, \ | ||
301 | .enable = reg_enable, \ | ||
302 | } | ||
303 | |||
304 | static struct ab8500_regulator_info ab8500_regulator_info[] = { | ||
305 | /* | ||
306 | * Variable Voltage LDOs | ||
307 | * name, min uV, max uV, ctrl reg, reg mask, enable mask, | ||
308 | * volt ctrl reg, volt ctrl mask, volt table, num supported volts | ||
309 | */ | ||
310 | AB8500_LDO(AUX1, 1100, 3300, 0x0409, 0x3, 0x1, 0x041f, 0xf, | ||
311 | ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)), | ||
312 | AB8500_LDO(AUX2, 1100, 3300, 0x0409, 0xc, 0x4, 0x0420, 0xf, | ||
313 | ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)), | ||
314 | AB8500_LDO(AUX3, 1100, 3300, 0x040a, 0x3, 0x1, 0x0421, 0xf, | ||
315 | ldo_vauxn_voltages, ARRAY_SIZE(ldo_vauxn_voltages)), | ||
316 | AB8500_LDO(INTCORE, 1100, 3300, 0x0380, 0x4, 0x4, 0x0380, 0x38, | ||
317 | ldo_vintcore_voltages, ARRAY_SIZE(ldo_vintcore_voltages)), | ||
318 | |||
319 | /* | ||
320 | * Fixed Voltage LDOs | ||
321 | * name, o/p uV, ctrl reg, enable, disable | ||
322 | */ | ||
323 | AB8500_FIXED_LDO(TVOUT, 2000, 0x0380, 0x2, 0x2), | ||
324 | AB8500_FIXED_LDO(AUDIO, 2000, 0x0383, 0x2, 0x2), | ||
325 | AB8500_FIXED_LDO(ANAMIC1, 2050, 0x0383, 0x4, 0x4), | ||
326 | AB8500_FIXED_LDO(ANAMIC2, 2050, 0x0383, 0x8, 0x8), | ||
327 | AB8500_FIXED_LDO(DMIC, 1800, 0x0383, 0x10, 0x10), | ||
328 | AB8500_FIXED_LDO(ANA, 1200, 0x0383, 0xc, 0x4), | ||
329 | }; | ||
330 | |||
331 | static inline struct ab8500_regulator_info *find_regulator_info(int id) | ||
332 | { | ||
333 | struct ab8500_regulator_info *info; | ||
334 | int i; | ||
335 | |||
336 | for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { | ||
337 | info = &ab8500_regulator_info[i]; | ||
338 | if (info->desc.id == id) | ||
339 | return info; | ||
340 | } | ||
341 | return NULL; | ||
342 | } | ||
343 | |||
344 | static __devinit int ab8500_regulator_probe(struct platform_device *pdev) | ||
345 | { | ||
346 | struct ab8500 *ab8500 = dev_get_drvdata(pdev->dev.parent); | ||
347 | struct ab8500_platform_data *pdata = dev_get_platdata(ab8500->dev); | ||
348 | int i, err; | ||
349 | |||
350 | if (!ab8500) { | ||
351 | dev_err(&pdev->dev, "null mfd parent\n"); | ||
352 | return -EINVAL; | ||
353 | } | ||
354 | |||
355 | /* register all regulators */ | ||
356 | for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { | ||
357 | struct ab8500_regulator_info *info = NULL; | ||
358 | |||
359 | /* assign per-regulator data */ | ||
360 | info = &ab8500_regulator_info[i]; | ||
361 | info->dev = &pdev->dev; | ||
362 | info->ab8500 = ab8500; | ||
363 | |||
364 | info->regulator = regulator_register(&info->desc, &pdev->dev, | ||
365 | pdata->regulator[i], info); | ||
366 | if (IS_ERR(info->regulator)) { | ||
367 | err = PTR_ERR(info->regulator); | ||
368 | dev_err(&pdev->dev, "failed to register regulator %s\n", | ||
369 | info->desc.name); | ||
370 | /* when we fail, un-register all earlier regulators */ | ||
371 | i--; | ||
372 | while (i > 0) { | ||
373 | info = &ab8500_regulator_info[i]; | ||
374 | regulator_unregister(info->regulator); | ||
375 | i--; | ||
376 | } | ||
377 | return err; | ||
378 | } | ||
379 | } | ||
380 | |||
381 | return 0; | ||
382 | } | ||
383 | |||
384 | static __devexit int ab8500_regulator_remove(struct platform_device *pdev) | ||
385 | { | ||
386 | int i; | ||
387 | |||
388 | for (i = 0; i < ARRAY_SIZE(ab8500_regulator_info); i++) { | ||
389 | struct ab8500_regulator_info *info = NULL; | ||
390 | info = &ab8500_regulator_info[i]; | ||
391 | regulator_unregister(info->regulator); | ||
392 | } | ||
393 | |||
394 | return 0; | ||
395 | } | ||
396 | |||
397 | static struct platform_driver ab8500_regulator_driver = { | ||
398 | .probe = ab8500_regulator_probe, | ||
399 | .remove = __devexit_p(ab8500_regulator_remove), | ||
400 | .driver = { | ||
401 | .name = "ab8500-regulator", | ||
402 | .owner = THIS_MODULE, | ||
403 | }, | ||
404 | }; | ||
405 | |||
406 | static int __init ab8500_regulator_init(void) | ||
407 | { | ||
408 | int ret; | ||
409 | |||
410 | ret = platform_driver_register(&ab8500_regulator_driver); | ||
411 | if (ret != 0) | ||
412 | pr_err("Failed to register ab8500 regulator: %d\n", ret); | ||
413 | |||
414 | return ret; | ||
415 | } | ||
416 | subsys_initcall(ab8500_regulator_init); | ||
417 | |||
418 | static void __exit ab8500_regulator_exit(void) | ||
419 | { | ||
420 | platform_driver_unregister(&ab8500_regulator_driver); | ||
421 | } | ||
422 | module_exit(ab8500_regulator_exit); | ||
423 | |||
424 | MODULE_LICENSE("GPL v2"); | ||
425 | MODULE_AUTHOR("Sundar Iyer <sundar.iyer@stericsson.com>"); | ||
426 | MODULE_DESCRIPTION("Regulator Driver for ST-Ericsson AB8500 Mixed-Sig PMIC"); | ||
427 | MODULE_ALIAS("platform:ab8500-regulator"); | ||
diff --git a/drivers/regulator/ad5398.c b/drivers/regulator/ad5398.c new file mode 100644 index 000000000000..d59d2f2314af --- /dev/null +++ b/drivers/regulator/ad5398.c | |||
@@ -0,0 +1,288 @@ | |||
1 | /* | ||
2 | * Voltage and current regulation for AD5398 and AD5821 | ||
3 | * | ||
4 | * Copyright 2010 Analog Devices Inc. | ||
5 | * | ||
6 | * Enter bugs at http://blackfin.uclinux.org/ | ||
7 | * | ||
8 | * Licensed under the GPL-2 or later. | ||
9 | */ | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/err.h> | ||
13 | #include <linux/i2c.h> | ||
14 | #include <linux/slab.h> | ||
15 | #include <linux/platform_device.h> | ||
16 | #include <linux/regulator/driver.h> | ||
17 | #include <linux/regulator/machine.h> | ||
18 | |||
19 | #define AD5398_CURRENT_EN_MASK 0x8000 | ||
20 | |||
21 | struct ad5398_chip_info { | ||
22 | struct i2c_client *client; | ||
23 | int min_uA; | ||
24 | int max_uA; | ||
25 | unsigned int current_level; | ||
26 | unsigned int current_mask; | ||
27 | unsigned int current_offset; | ||
28 | struct regulator_dev rdev; | ||
29 | }; | ||
30 | |||
31 | static int ad5398_calc_current(struct ad5398_chip_info *chip, | ||
32 | unsigned selector) | ||
33 | { | ||
34 | unsigned range_uA = chip->max_uA - chip->min_uA; | ||
35 | |||
36 | return chip->min_uA + (selector * range_uA / chip->current_level); | ||
37 | } | ||
38 | |||
39 | static int ad5398_read_reg(struct i2c_client *client, unsigned short *data) | ||
40 | { | ||
41 | unsigned short val; | ||
42 | int ret; | ||
43 | |||
44 | ret = i2c_master_recv(client, (char *)&val, 2); | ||
45 | if (ret < 0) { | ||
46 | dev_err(&client->dev, "I2C read error\n"); | ||
47 | return ret; | ||
48 | } | ||
49 | *data = be16_to_cpu(val); | ||
50 | |||
51 | return ret; | ||
52 | } | ||
53 | |||
54 | static int ad5398_write_reg(struct i2c_client *client, const unsigned short data) | ||
55 | { | ||
56 | unsigned short val; | ||
57 | int ret; | ||
58 | |||
59 | val = cpu_to_be16(data); | ||
60 | ret = i2c_master_send(client, (char *)&val, 2); | ||
61 | if (ret < 0) | ||
62 | dev_err(&client->dev, "I2C write error\n"); | ||
63 | |||
64 | return ret; | ||
65 | } | ||
66 | |||
67 | static int ad5398_get_current_limit(struct regulator_dev *rdev) | ||
68 | { | ||
69 | struct ad5398_chip_info *chip = rdev_get_drvdata(rdev); | ||
70 | struct i2c_client *client = chip->client; | ||
71 | unsigned short data; | ||
72 | int ret; | ||
73 | |||
74 | ret = ad5398_read_reg(client, &data); | ||
75 | if (ret < 0) | ||
76 | return ret; | ||
77 | |||
78 | ret = (data & chip->current_mask) >> chip->current_offset; | ||
79 | |||
80 | return ad5398_calc_current(chip, ret); | ||
81 | } | ||
82 | |||
83 | static int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA) | ||
84 | { | ||
85 | struct ad5398_chip_info *chip = rdev_get_drvdata(rdev); | ||
86 | struct i2c_client *client = chip->client; | ||
87 | unsigned range_uA = chip->max_uA - chip->min_uA; | ||
88 | unsigned selector; | ||
89 | unsigned short data; | ||
90 | int ret; | ||
91 | |||
92 | if (min_uA > chip->max_uA || min_uA < chip->min_uA) | ||
93 | return -EINVAL; | ||
94 | if (max_uA > chip->max_uA || max_uA < chip->min_uA) | ||
95 | return -EINVAL; | ||
96 | |||
97 | selector = ((min_uA - chip->min_uA) * chip->current_level + | ||
98 | range_uA - 1) / range_uA; | ||
99 | if (ad5398_calc_current(chip, selector) > max_uA) | ||
100 | return -EINVAL; | ||
101 | |||
102 | dev_dbg(&client->dev, "changing current %dmA\n", | ||
103 | ad5398_calc_current(chip, selector) / 1000); | ||
104 | |||
105 | /* read chip enable bit */ | ||
106 | ret = ad5398_read_reg(client, &data); | ||
107 | if (ret < 0) | ||
108 | return ret; | ||
109 | |||
110 | /* prepare register data */ | ||
111 | selector = (selector << chip->current_offset) & chip->current_mask; | ||
112 | data = (unsigned short)selector | (data & AD5398_CURRENT_EN_MASK); | ||
113 | |||
114 | /* write the new current value back as well as enable bit */ | ||
115 | ret = ad5398_write_reg(client, data); | ||
116 | |||
117 | return ret; | ||
118 | } | ||
119 | |||
120 | static int ad5398_is_enabled(struct regulator_dev *rdev) | ||
121 | { | ||
122 | struct ad5398_chip_info *chip = rdev_get_drvdata(rdev); | ||
123 | struct i2c_client *client = chip->client; | ||
124 | unsigned short data; | ||
125 | int ret; | ||
126 | |||
127 | ret = ad5398_read_reg(client, &data); | ||
128 | if (ret < 0) | ||
129 | return ret; | ||
130 | |||
131 | if (data & AD5398_CURRENT_EN_MASK) | ||
132 | return 1; | ||
133 | else | ||
134 | return 0; | ||
135 | } | ||
136 | |||
137 | static int ad5398_enable(struct regulator_dev *rdev) | ||
138 | { | ||
139 | struct ad5398_chip_info *chip = rdev_get_drvdata(rdev); | ||
140 | struct i2c_client *client = chip->client; | ||
141 | unsigned short data; | ||
142 | int ret; | ||
143 | |||
144 | ret = ad5398_read_reg(client, &data); | ||
145 | if (ret < 0) | ||
146 | return ret; | ||
147 | |||
148 | if (data & AD5398_CURRENT_EN_MASK) | ||
149 | return 0; | ||
150 | |||
151 | data |= AD5398_CURRENT_EN_MASK; | ||
152 | |||
153 | ret = ad5398_write_reg(client, data); | ||
154 | |||
155 | return ret; | ||
156 | } | ||
157 | |||
158 | static int ad5398_disable(struct regulator_dev *rdev) | ||
159 | { | ||
160 | struct ad5398_chip_info *chip = rdev_get_drvdata(rdev); | ||
161 | struct i2c_client *client = chip->client; | ||
162 | unsigned short data; | ||
163 | int ret; | ||
164 | |||
165 | ret = ad5398_read_reg(client, &data); | ||
166 | if (ret < 0) | ||
167 | return ret; | ||
168 | |||
169 | if (!(data & AD5398_CURRENT_EN_MASK)) | ||
170 | return 0; | ||
171 | |||
172 | data &= ~AD5398_CURRENT_EN_MASK; | ||
173 | |||
174 | ret = ad5398_write_reg(client, data); | ||
175 | |||
176 | return ret; | ||
177 | } | ||
178 | |||
179 | static struct regulator_ops ad5398_ops = { | ||
180 | .get_current_limit = ad5398_get_current_limit, | ||
181 | .set_current_limit = ad5398_set_current_limit, | ||
182 | .enable = ad5398_enable, | ||
183 | .disable = ad5398_disable, | ||
184 | .is_enabled = ad5398_is_enabled, | ||
185 | }; | ||
186 | |||
187 | static struct regulator_desc ad5398_reg = { | ||
188 | .name = "isink", | ||
189 | .id = 0, | ||
190 | .ops = &ad5398_ops, | ||
191 | .type = REGULATOR_CURRENT, | ||
192 | .owner = THIS_MODULE, | ||
193 | }; | ||
194 | |||
195 | struct ad5398_current_data_format { | ||
196 | int current_bits; | ||
197 | int current_offset; | ||
198 | int min_uA; | ||
199 | int max_uA; | ||
200 | }; | ||
201 | |||
202 | static const struct ad5398_current_data_format df_10_4_120 = {10, 4, 0, 120000}; | ||
203 | |||
204 | static const struct i2c_device_id ad5398_id[] = { | ||
205 | { "ad5398", (kernel_ulong_t)&df_10_4_120 }, | ||
206 | { "ad5821", (kernel_ulong_t)&df_10_4_120 }, | ||
207 | { } | ||
208 | }; | ||
209 | MODULE_DEVICE_TABLE(i2c, ad5398_id); | ||
210 | |||
211 | static int __devinit ad5398_probe(struct i2c_client *client, | ||
212 | const struct i2c_device_id *id) | ||
213 | { | ||
214 | struct regulator_dev *rdev; | ||
215 | struct regulator_init_data *init_data = client->dev.platform_data; | ||
216 | struct ad5398_chip_info *chip; | ||
217 | const struct ad5398_current_data_format *df = | ||
218 | (struct ad5398_current_data_format *)id->driver_data; | ||
219 | int ret; | ||
220 | |||
221 | if (!init_data) | ||
222 | return -EINVAL; | ||
223 | |||
224 | chip = kzalloc(sizeof(*chip), GFP_KERNEL); | ||
225 | if (!chip) | ||
226 | return -ENOMEM; | ||
227 | |||
228 | chip->client = client; | ||
229 | |||
230 | chip->min_uA = df->min_uA; | ||
231 | chip->max_uA = df->max_uA; | ||
232 | chip->current_level = 1 << df->current_bits; | ||
233 | chip->current_offset = df->current_offset; | ||
234 | chip->current_mask = (chip->current_level - 1) << chip->current_offset; | ||
235 | |||
236 | rdev = regulator_register(&ad5398_reg, &client->dev, init_data, chip); | ||
237 | if (IS_ERR(rdev)) { | ||
238 | ret = PTR_ERR(rdev); | ||
239 | dev_err(&client->dev, "failed to register %s %s\n", | ||
240 | id->name, ad5398_reg.name); | ||
241 | goto err; | ||
242 | } | ||
243 | |||
244 | i2c_set_clientdata(client, chip); | ||
245 | dev_dbg(&client->dev, "%s regulator driver is registered.\n", id->name); | ||
246 | return 0; | ||
247 | |||
248 | err: | ||
249 | kfree(chip); | ||
250 | return ret; | ||
251 | } | ||
252 | |||
253 | static int __devexit ad5398_remove(struct i2c_client *client) | ||
254 | { | ||
255 | struct ad5398_chip_info *chip = i2c_get_clientdata(client); | ||
256 | |||
257 | regulator_unregister(&chip->rdev); | ||
258 | kfree(chip); | ||
259 | i2c_set_clientdata(client, NULL); | ||
260 | |||
261 | return 0; | ||
262 | } | ||
263 | |||
264 | static struct i2c_driver ad5398_driver = { | ||
265 | .probe = ad5398_probe, | ||
266 | .remove = __devexit_p(ad5398_remove), | ||
267 | .driver = { | ||
268 | .name = "ad5398", | ||
269 | }, | ||
270 | .id_table = ad5398_id, | ||
271 | }; | ||
272 | |||
273 | static int __init ad5398_init(void) | ||
274 | { | ||
275 | return i2c_add_driver(&ad5398_driver); | ||
276 | } | ||
277 | subsys_initcall(ad5398_init); | ||
278 | |||
279 | static void __exit ad5398_exit(void) | ||
280 | { | ||
281 | i2c_del_driver(&ad5398_driver); | ||
282 | } | ||
283 | module_exit(ad5398_exit); | ||
284 | |||
285 | MODULE_DESCRIPTION("AD5398 and AD5821 current regulator driver"); | ||
286 | MODULE_AUTHOR("Sonic Zhang"); | ||
287 | MODULE_LICENSE("GPL"); | ||
288 | MODULE_ALIAS("i2c:ad5398-regulator"); | ||
diff --git a/drivers/regulator/isl6271a-regulator.c b/drivers/regulator/isl6271a-regulator.c new file mode 100644 index 000000000000..e49d2bd393f2 --- /dev/null +++ b/drivers/regulator/isl6271a-regulator.c | |||
@@ -0,0 +1,236 @@ | |||
1 | /* | ||
2 | * isl6271a-regulator.c | ||
3 | * | ||
4 | * Support for Intersil ISL6271A voltage regulator | ||
5 | * | ||
6 | * Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License as | ||
10 | * published by the Free Software Foundation version 2. | ||
11 | * | ||
12 | * This program is distributed "as is" WITHOUT ANY WARRANTY of any kind, | ||
13 | * whether express or implied; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
15 | * General Public License for more details. | ||
16 | */ | ||
17 | |||
18 | #include <linux/kernel.h> | ||
19 | #include <linux/module.h> | ||
20 | #include <linux/init.h> | ||
21 | #include <linux/err.h> | ||
22 | #include <linux/platform_device.h> | ||
23 | #include <linux/regulator/driver.h> | ||
24 | #include <linux/i2c.h> | ||
25 | #include <linux/delay.h> | ||
26 | #include <linux/slab.h> | ||
27 | |||
28 | #define ISL6271A_VOLTAGE_MIN 850000 | ||
29 | #define ISL6271A_VOLTAGE_MAX 1600000 | ||
30 | #define ISL6271A_VOLTAGE_STEP 50000 | ||
31 | |||
32 | /* PMIC details */ | ||
33 | struct isl_pmic { | ||
34 | struct i2c_client *client; | ||
35 | struct regulator_dev *rdev[3]; | ||
36 | struct mutex mtx; | ||
37 | }; | ||
38 | |||
39 | static int isl6271a_get_voltage(struct regulator_dev *dev) | ||
40 | { | ||
41 | struct isl_pmic *pmic = rdev_get_drvdata(dev); | ||
42 | int idx, data; | ||
43 | |||
44 | mutex_lock(&pmic->mtx); | ||
45 | |||
46 | idx = i2c_smbus_read_byte(pmic->client); | ||
47 | if (idx < 0) { | ||
48 | dev_err(&pmic->client->dev, "Error getting voltage\n"); | ||
49 | data = idx; | ||
50 | goto out; | ||
51 | } | ||
52 | |||
53 | /* Convert the data from chip to microvolts */ | ||
54 | data = ISL6271A_VOLTAGE_MIN + (ISL6271A_VOLTAGE_STEP * (idx & 0xf)); | ||
55 | |||
56 | out: | ||
57 | mutex_unlock(&pmic->mtx); | ||
58 | return data; | ||
59 | } | ||
60 | |||
61 | static int isl6271a_set_voltage(struct regulator_dev *dev, int minuV, int maxuV) | ||
62 | { | ||
63 | struct isl_pmic *pmic = rdev_get_drvdata(dev); | ||
64 | int vsel, err, data; | ||
65 | |||
66 | if (minuV < ISL6271A_VOLTAGE_MIN || minuV > ISL6271A_VOLTAGE_MAX) | ||
67 | return -EINVAL; | ||
68 | if (maxuV < ISL6271A_VOLTAGE_MIN || maxuV > ISL6271A_VOLTAGE_MAX) | ||
69 | return -EINVAL; | ||
70 | |||
71 | /* Align to 50000 mV */ | ||
72 | vsel = minuV - (minuV % ISL6271A_VOLTAGE_STEP); | ||
73 | |||
74 | /* If the result fell out of [minuV,maxuV] range, put it back */ | ||
75 | if (vsel < minuV) | ||
76 | vsel += ISL6271A_VOLTAGE_STEP; | ||
77 | |||
78 | /* Convert the microvolts to data for the chip */ | ||
79 | data = (vsel - ISL6271A_VOLTAGE_MIN) / ISL6271A_VOLTAGE_STEP; | ||
80 | |||
81 | mutex_lock(&pmic->mtx); | ||
82 | |||
83 | err = i2c_smbus_write_byte(pmic->client, data); | ||
84 | if (err < 0) | ||
85 | dev_err(&pmic->client->dev, "Error setting voltage\n"); | ||
86 | |||
87 | mutex_unlock(&pmic->mtx); | ||
88 | return err; | ||
89 | } | ||
90 | |||
91 | static int isl6271a_list_voltage(struct regulator_dev *dev, unsigned selector) | ||
92 | { | ||
93 | return ISL6271A_VOLTAGE_MIN + (ISL6271A_VOLTAGE_STEP * selector); | ||
94 | } | ||
95 | |||
96 | static struct regulator_ops isl_core_ops = { | ||
97 | .get_voltage = isl6271a_get_voltage, | ||
98 | .set_voltage = isl6271a_set_voltage, | ||
99 | .list_voltage = isl6271a_list_voltage, | ||
100 | }; | ||
101 | |||
102 | static int isl6271a_get_fixed_voltage(struct regulator_dev *dev) | ||
103 | { | ||
104 | int id = rdev_get_id(dev); | ||
105 | return (id == 1) ? 1100000 : 1300000; | ||
106 | } | ||
107 | |||
108 | static int isl6271a_list_fixed_voltage(struct regulator_dev *dev, unsigned selector) | ||
109 | { | ||
110 | int id = rdev_get_id(dev); | ||
111 | return (id == 1) ? 1100000 : 1300000; | ||
112 | } | ||
113 | |||
114 | static struct regulator_ops isl_fixed_ops = { | ||
115 | .get_voltage = isl6271a_get_fixed_voltage, | ||
116 | .list_voltage = isl6271a_list_fixed_voltage, | ||
117 | }; | ||
118 | |||
119 | static struct regulator_desc isl_rd[] = { | ||
120 | { | ||
121 | .name = "Core Buck", | ||
122 | .id = 0, | ||
123 | .n_voltages = 16, | ||
124 | .ops = &isl_core_ops, | ||
125 | .type = REGULATOR_VOLTAGE, | ||
126 | .owner = THIS_MODULE, | ||
127 | }, { | ||
128 | .name = "LDO1", | ||
129 | .id = 1, | ||
130 | .n_voltages = 1, | ||
131 | .ops = &isl_fixed_ops, | ||
132 | .type = REGULATOR_VOLTAGE, | ||
133 | .owner = THIS_MODULE, | ||
134 | }, { | ||
135 | .name = "LDO2", | ||
136 | .id = 2, | ||
137 | .n_voltages = 1, | ||
138 | .ops = &isl_fixed_ops, | ||
139 | .type = REGULATOR_VOLTAGE, | ||
140 | .owner = THIS_MODULE, | ||
141 | }, | ||
142 | }; | ||
143 | |||
144 | static int __devinit isl6271a_probe(struct i2c_client *i2c, | ||
145 | const struct i2c_device_id *id) | ||
146 | { | ||
147 | struct regulator_init_data *init_data = i2c->dev.platform_data; | ||
148 | struct isl_pmic *pmic; | ||
149 | int err, i; | ||
150 | |||
151 | if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA)) | ||
152 | return -EIO; | ||
153 | |||
154 | if (!init_data) { | ||
155 | dev_err(&i2c->dev, "no platform data supplied\n"); | ||
156 | return -EIO; | ||
157 | } | ||
158 | |||
159 | pmic = kzalloc(sizeof(struct isl_pmic), GFP_KERNEL); | ||
160 | if (!pmic) | ||
161 | return -ENOMEM; | ||
162 | |||
163 | pmic->client = i2c; | ||
164 | |||
165 | mutex_init(&pmic->mtx); | ||
166 | |||
167 | for (i = 0; i < 3; i++) { | ||
168 | pmic->rdev[i] = regulator_register(&isl_rd[0], &i2c->dev, | ||
169 | init_data, pmic); | ||
170 | if (IS_ERR(pmic->rdev[i])) { | ||
171 | dev_err(&i2c->dev, "failed to register %s\n", id->name); | ||
172 | err = PTR_ERR(pmic->rdev); | ||
173 | goto error; | ||
174 | } | ||
175 | } | ||
176 | |||
177 | i2c_set_clientdata(i2c, pmic); | ||
178 | |||
179 | return 0; | ||
180 | |||
181 | error: | ||
182 | while (--i >= 0) | ||
183 | regulator_unregister(pmic->rdev[i]); | ||
184 | |||
185 | kfree(pmic); | ||
186 | return err; | ||
187 | } | ||
188 | |||
189 | static int __devexit isl6271a_remove(struct i2c_client *i2c) | ||
190 | { | ||
191 | struct isl_pmic *pmic = i2c_get_clientdata(i2c); | ||
192 | int i; | ||
193 | |||
194 | i2c_set_clientdata(i2c, NULL); | ||
195 | |||
196 | for (i = 0; i < 3; i++) | ||
197 | regulator_unregister(pmic->rdev[i]); | ||
198 | |||
199 | kfree(pmic); | ||
200 | |||
201 | return 0; | ||
202 | } | ||
203 | |||
204 | static const struct i2c_device_id isl6271a_id[] = { | ||
205 | {.name = "isl6271a", 0 }, | ||
206 | { }, | ||
207 | }; | ||
208 | |||
209 | MODULE_DEVICE_TABLE(i2c, isl6271a_id); | ||
210 | |||
211 | static struct i2c_driver isl6271a_i2c_driver = { | ||
212 | .driver = { | ||
213 | .name = "isl6271a", | ||
214 | .owner = THIS_MODULE, | ||
215 | }, | ||
216 | .probe = isl6271a_probe, | ||
217 | .remove = __devexit_p(isl6271a_remove), | ||
218 | .id_table = isl6271a_id, | ||
219 | }; | ||
220 | |||
221 | static int __init isl6271a_init(void) | ||
222 | { | ||
223 | return i2c_add_driver(&isl6271a_i2c_driver); | ||
224 | } | ||
225 | |||
226 | static void __exit isl6271a_cleanup(void) | ||
227 | { | ||
228 | i2c_del_driver(&isl6271a_i2c_driver); | ||
229 | } | ||
230 | |||
231 | subsys_initcall(isl6271a_init); | ||
232 | module_exit(isl6271a_cleanup); | ||
233 | |||
234 | MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>"); | ||
235 | MODULE_DESCRIPTION("Intersil ISL6271A voltage regulator driver"); | ||
236 | MODULE_LICENSE("GPL v2"); | ||
diff --git a/drivers/regulator/lp3971.c b/drivers/regulator/lp3971.c index 8ae3732eb24b..3bb82b624e19 100644 --- a/drivers/regulator/lp3971.c +++ b/drivers/regulator/lp3971.c | |||
@@ -377,7 +377,7 @@ static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count, | |||
377 | if (count != 1) | 377 | if (count != 1) |
378 | return -EIO; | 378 | return -EIO; |
379 | ret = i2c_smbus_read_byte_data(i2c, reg); | 379 | ret = i2c_smbus_read_byte_data(i2c, reg); |
380 | if (ret < 0 || count != 1) | 380 | if (ret < 0) |
381 | return -EIO; | 381 | return -EIO; |
382 | 382 | ||
383 | *dest = ret; | 383 | *dest = ret; |
@@ -387,15 +387,9 @@ static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count, | |||
387 | static int lp3971_i2c_write(struct i2c_client *i2c, char reg, int count, | 387 | static int lp3971_i2c_write(struct i2c_client *i2c, char reg, int count, |
388 | const u16 *src) | 388 | const u16 *src) |
389 | { | 389 | { |
390 | int ret; | ||
391 | |||
392 | if (count != 1) | 390 | if (count != 1) |
393 | return -EIO; | 391 | return -EIO; |
394 | ret = i2c_smbus_write_byte_data(i2c, reg, *src); | 392 | return i2c_smbus_write_byte_data(i2c, reg, *src); |
395 | if (ret >= 0) | ||
396 | return 0; | ||
397 | |||
398 | return ret; | ||
399 | } | 393 | } |
400 | 394 | ||
401 | static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg) | 395 | static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg) |
diff --git a/drivers/regulator/max1586.c b/drivers/regulator/max1586.c index 2b54d9d75f11..8867c2710a6d 100644 --- a/drivers/regulator/max1586.c +++ b/drivers/regulator/max1586.c | |||
@@ -223,7 +223,7 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client, | |||
223 | } | 223 | } |
224 | } | 224 | } |
225 | 225 | ||
226 | i2c_set_clientdata(client, rdev); | 226 | i2c_set_clientdata(client, max1586); |
227 | dev_info(&client->dev, "Maxim 1586 regulator driver loaded\n"); | 227 | dev_info(&client->dev, "Maxim 1586 regulator driver loaded\n"); |
228 | return 0; | 228 | return 0; |
229 | 229 | ||
@@ -238,13 +238,13 @@ out: | |||
238 | 238 | ||
239 | static int __devexit max1586_pmic_remove(struct i2c_client *client) | 239 | static int __devexit max1586_pmic_remove(struct i2c_client *client) |
240 | { | 240 | { |
241 | struct regulator_dev **rdev = i2c_get_clientdata(client); | 241 | struct max1586_data *max1586 = i2c_get_clientdata(client); |
242 | int i; | 242 | int i; |
243 | 243 | ||
244 | for (i = 0; i <= MAX1586_V6; i++) | 244 | for (i = 0; i <= MAX1586_V6; i++) |
245 | if (rdev[i]) | 245 | if (max1586->rdev[i]) |
246 | regulator_unregister(rdev[i]); | 246 | regulator_unregister(max1586->rdev[i]); |
247 | kfree(rdev); | 247 | kfree(max1586); |
248 | 248 | ||
249 | return 0; | 249 | return 0; |
250 | } | 250 | } |
diff --git a/drivers/regulator/max8660.c b/drivers/regulator/max8660.c index d97220efae5a..c570e6eb0db2 100644 --- a/drivers/regulator/max8660.c +++ b/drivers/regulator/max8660.c | |||
@@ -450,7 +450,7 @@ static int __devinit max8660_probe(struct i2c_client *client, | |||
450 | } | 450 | } |
451 | } | 451 | } |
452 | 452 | ||
453 | i2c_set_clientdata(client, rdev); | 453 | i2c_set_clientdata(client, max8660); |
454 | dev_info(&client->dev, "Maxim 8660/8661 regulator driver loaded\n"); | 454 | dev_info(&client->dev, "Maxim 8660/8661 regulator driver loaded\n"); |
455 | return 0; | 455 | return 0; |
456 | 456 | ||
@@ -465,13 +465,13 @@ out: | |||
465 | 465 | ||
466 | static int __devexit max8660_remove(struct i2c_client *client) | 466 | static int __devexit max8660_remove(struct i2c_client *client) |
467 | { | 467 | { |
468 | struct regulator_dev **rdev = i2c_get_clientdata(client); | 468 | struct max8660 *max8660 = i2c_get_clientdata(client); |
469 | int i; | 469 | int i; |
470 | 470 | ||
471 | for (i = 0; i < MAX8660_V_END; i++) | 471 | for (i = 0; i < MAX8660_V_END; i++) |
472 | if (rdev[i]) | 472 | if (max8660->rdev[i]) |
473 | regulator_unregister(rdev[i]); | 473 | regulator_unregister(max8660->rdev[i]); |
474 | kfree(rdev); | 474 | kfree(max8660); |
475 | 475 | ||
476 | return 0; | 476 | return 0; |
477 | } | 477 | } |
diff --git a/drivers/regulator/max8998.c b/drivers/regulator/max8998.c new file mode 100644 index 000000000000..ab67298799f9 --- /dev/null +++ b/drivers/regulator/max8998.c | |||
@@ -0,0 +1,635 @@ | |||
1 | /* | ||
2 | * max8998.c - Voltage regulator driver for the Maxim 8998 | ||
3 | * | ||
4 | * Copyright (C) 2009-2010 Samsung Electronics | ||
5 | * Kyungmin Park <kyungmin.park@samsung.com> | ||
6 | * Marek Szyprowski <m.szyprowski@samsung.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/init.h> | ||
25 | #include <linux/i2c.h> | ||
26 | #include <linux/err.h> | ||
27 | #include <linux/gpio.h> | ||
28 | #include <linux/slab.h> | ||
29 | #include <linux/interrupt.h> | ||
30 | #include <linux/mutex.h> | ||
31 | #include <linux/delay.h> | ||
32 | #include <linux/platform_device.h> | ||
33 | #include <linux/regulator/driver.h> | ||
34 | #include <linux/mfd/max8998.h> | ||
35 | #include <linux/mfd/max8998-private.h> | ||
36 | |||
37 | struct max8998_data { | ||
38 | struct device *dev; | ||
39 | struct max8998_dev *iodev; | ||
40 | int num_regulators; | ||
41 | struct regulator_dev **rdev; | ||
42 | }; | ||
43 | |||
44 | struct voltage_map_desc { | ||
45 | int min; | ||
46 | int max; | ||
47 | int step; | ||
48 | }; | ||
49 | |||
50 | /* Voltage maps */ | ||
51 | static const struct voltage_map_desc ldo23_voltage_map_desc = { | ||
52 | .min = 800, .step = 50, .max = 1300, | ||
53 | }; | ||
54 | static const struct voltage_map_desc ldo456711_voltage_map_desc = { | ||
55 | .min = 1600, .step = 100, .max = 3600, | ||
56 | }; | ||
57 | static const struct voltage_map_desc ldo8_voltage_map_desc = { | ||
58 | .min = 3000, .step = 100, .max = 3600, | ||
59 | }; | ||
60 | static const struct voltage_map_desc ldo9_voltage_map_desc = { | ||
61 | .min = 2800, .step = 100, .max = 3100, | ||
62 | }; | ||
63 | static const struct voltage_map_desc ldo10_voltage_map_desc = { | ||
64 | .min = 950, .step = 50, .max = 1300, | ||
65 | }; | ||
66 | static const struct voltage_map_desc ldo1213_voltage_map_desc = { | ||
67 | .min = 800, .step = 100, .max = 3300, | ||
68 | }; | ||
69 | static const struct voltage_map_desc ldo1415_voltage_map_desc = { | ||
70 | .min = 1200, .step = 100, .max = 3300, | ||
71 | }; | ||
72 | static const struct voltage_map_desc ldo1617_voltage_map_desc = { | ||
73 | .min = 1600, .step = 100, .max = 3600, | ||
74 | }; | ||
75 | static const struct voltage_map_desc buck12_voltage_map_desc = { | ||
76 | .min = 750, .step = 25, .max = 1525, | ||
77 | }; | ||
78 | static const struct voltage_map_desc buck3_voltage_map_desc = { | ||
79 | .min = 1600, .step = 100, .max = 3600, | ||
80 | }; | ||
81 | static const struct voltage_map_desc buck4_voltage_map_desc = { | ||
82 | .min = 800, .step = 100, .max = 2300, | ||
83 | }; | ||
84 | |||
85 | static const struct voltage_map_desc *ldo_voltage_map[] = { | ||
86 | NULL, | ||
87 | NULL, | ||
88 | &ldo23_voltage_map_desc, /* LDO2 */ | ||
89 | &ldo23_voltage_map_desc, /* LDO3 */ | ||
90 | &ldo456711_voltage_map_desc, /* LDO4 */ | ||
91 | &ldo456711_voltage_map_desc, /* LDO5 */ | ||
92 | &ldo456711_voltage_map_desc, /* LDO6 */ | ||
93 | &ldo456711_voltage_map_desc, /* LDO7 */ | ||
94 | &ldo8_voltage_map_desc, /* LDO8 */ | ||
95 | &ldo9_voltage_map_desc, /* LDO9 */ | ||
96 | &ldo10_voltage_map_desc, /* LDO10 */ | ||
97 | &ldo456711_voltage_map_desc, /* LDO11 */ | ||
98 | &ldo1213_voltage_map_desc, /* LDO12 */ | ||
99 | &ldo1213_voltage_map_desc, /* LDO13 */ | ||
100 | &ldo1415_voltage_map_desc, /* LDO14 */ | ||
101 | &ldo1415_voltage_map_desc, /* LDO15 */ | ||
102 | &ldo1617_voltage_map_desc, /* LDO16 */ | ||
103 | &ldo1617_voltage_map_desc, /* LDO17 */ | ||
104 | &buck12_voltage_map_desc, /* BUCK1 */ | ||
105 | &buck12_voltage_map_desc, /* BUCK2 */ | ||
106 | &buck3_voltage_map_desc, /* BUCK3 */ | ||
107 | &buck4_voltage_map_desc, /* BUCK4 */ | ||
108 | }; | ||
109 | |||
110 | static inline int max8998_get_ldo(struct regulator_dev *rdev) | ||
111 | { | ||
112 | return rdev_get_id(rdev); | ||
113 | } | ||
114 | |||
115 | static int max8998_list_voltage(struct regulator_dev *rdev, | ||
116 | unsigned int selector) | ||
117 | { | ||
118 | const struct voltage_map_desc *desc; | ||
119 | int ldo = max8998_get_ldo(rdev); | ||
120 | int val; | ||
121 | |||
122 | if (ldo >= ARRAY_SIZE(ldo_voltage_map)) | ||
123 | return -EINVAL; | ||
124 | |||
125 | desc = ldo_voltage_map[ldo]; | ||
126 | if (desc == NULL) | ||
127 | return -EINVAL; | ||
128 | |||
129 | val = desc->min + desc->step * selector; | ||
130 | if (val > desc->max) | ||
131 | return -EINVAL; | ||
132 | |||
133 | return val * 1000; | ||
134 | } | ||
135 | |||
136 | static int max8998_get_enable_register(struct regulator_dev *rdev, | ||
137 | int *reg, int *shift) | ||
138 | { | ||
139 | int ldo = max8998_get_ldo(rdev); | ||
140 | |||
141 | switch (ldo) { | ||
142 | case MAX8998_LDO2 ... MAX8998_LDO5: | ||
143 | *reg = MAX8998_REG_ONOFF1; | ||
144 | *shift = 3 - (ldo - MAX8998_LDO2); | ||
145 | break; | ||
146 | case MAX8998_LDO6 ... MAX8998_LDO13: | ||
147 | *reg = MAX8998_REG_ONOFF2; | ||
148 | *shift = 7 - (ldo - MAX8998_LDO6); | ||
149 | break; | ||
150 | case MAX8998_LDO14 ... MAX8998_LDO17: | ||
151 | *reg = MAX8998_REG_ONOFF3; | ||
152 | *shift = 7 - (ldo - MAX8998_LDO14); | ||
153 | break; | ||
154 | case MAX8998_BUCK1 ... MAX8998_BUCK4: | ||
155 | *reg = MAX8998_REG_ONOFF1; | ||
156 | *shift = 7 - (ldo - MAX8998_BUCK1); | ||
157 | break; | ||
158 | case MAX8998_EN32KHZ_AP ... MAX8998_ENVICHG: | ||
159 | *reg = MAX8998_REG_ONOFF4; | ||
160 | *shift = 7 - (ldo - MAX8998_EN32KHZ_AP); | ||
161 | break; | ||
162 | case MAX8998_ESAFEOUT1 ... MAX8998_ESAFEOUT2: | ||
163 | *reg = MAX8998_REG_CHGR2; | ||
164 | *shift = 7 - (ldo - MAX8998_ESAFEOUT1); | ||
165 | break; | ||
166 | default: | ||
167 | return -EINVAL; | ||
168 | } | ||
169 | |||
170 | return 0; | ||
171 | } | ||
172 | |||
173 | static int max8998_ldo_is_enabled(struct regulator_dev *rdev) | ||
174 | { | ||
175 | struct max8998_data *max8998 = rdev_get_drvdata(rdev); | ||
176 | int ret, reg, shift = 8; | ||
177 | u8 val; | ||
178 | |||
179 | ret = max8998_get_enable_register(rdev, ®, &shift); | ||
180 | if (ret) | ||
181 | return ret; | ||
182 | |||
183 | ret = max8998_read_reg(max8998->iodev, reg, &val); | ||
184 | if (ret) | ||
185 | return ret; | ||
186 | |||
187 | return val & (1 << shift); | ||
188 | } | ||
189 | |||
190 | static int max8998_ldo_enable(struct regulator_dev *rdev) | ||
191 | { | ||
192 | struct max8998_data *max8998 = rdev_get_drvdata(rdev); | ||
193 | int reg, shift = 8, ret; | ||
194 | |||
195 | ret = max8998_get_enable_register(rdev, ®, &shift); | ||
196 | if (ret) | ||
197 | return ret; | ||
198 | |||
199 | return max8998_update_reg(max8998->iodev, reg, 1<<shift, 1<<shift); | ||
200 | } | ||
201 | |||
202 | static int max8998_ldo_disable(struct regulator_dev *rdev) | ||
203 | { | ||
204 | struct max8998_data *max8998 = rdev_get_drvdata(rdev); | ||
205 | int reg, shift = 8, ret; | ||
206 | |||
207 | ret = max8998_get_enable_register(rdev, ®, &shift); | ||
208 | if (ret) | ||
209 | return ret; | ||
210 | |||
211 | return max8998_update_reg(max8998->iodev, reg, 0, 1<<shift); | ||
212 | } | ||
213 | |||
214 | static int max8998_get_voltage_register(struct regulator_dev *rdev, | ||
215 | int *_reg, int *_shift, int *_mask) | ||
216 | { | ||
217 | int ldo = max8998_get_ldo(rdev); | ||
218 | int reg, shift = 0, mask = 0xff; | ||
219 | |||
220 | switch (ldo) { | ||
221 | case MAX8998_LDO2 ... MAX8998_LDO3: | ||
222 | reg = MAX8998_REG_LDO2_LDO3; | ||
223 | mask = 0xf; | ||
224 | if (ldo == MAX8998_LDO2) | ||
225 | shift = 4; | ||
226 | else | ||
227 | shift = 0; | ||
228 | break; | ||
229 | case MAX8998_LDO4 ... MAX8998_LDO7: | ||
230 | reg = MAX8998_REG_LDO4 + (ldo - MAX8998_LDO4); | ||
231 | break; | ||
232 | case MAX8998_LDO8 ... MAX8998_LDO9: | ||
233 | reg = MAX8998_REG_LDO8_LDO9; | ||
234 | mask = 0xf; | ||
235 | if (ldo == MAX8998_LDO8) | ||
236 | shift = 4; | ||
237 | else | ||
238 | shift = 0; | ||
239 | break; | ||
240 | case MAX8998_LDO10 ... MAX8998_LDO11: | ||
241 | reg = MAX8998_REG_LDO10_LDO11; | ||
242 | if (ldo == MAX8998_LDO10) { | ||
243 | shift = 5; | ||
244 | mask = 0x7; | ||
245 | } else { | ||
246 | shift = 0; | ||
247 | mask = 0x1f; | ||
248 | } | ||
249 | break; | ||
250 | case MAX8998_LDO12 ... MAX8998_LDO17: | ||
251 | reg = MAX8998_REG_LDO12 + (ldo - MAX8998_LDO12); | ||
252 | break; | ||
253 | case MAX8998_BUCK1: | ||
254 | reg = MAX8998_REG_BUCK1_DVSARM1; | ||
255 | break; | ||
256 | case MAX8998_BUCK2: | ||
257 | reg = MAX8998_REG_BUCK2_DVSINT1; | ||
258 | break; | ||
259 | case MAX8998_BUCK3: | ||
260 | reg = MAX8998_REG_BUCK3; | ||
261 | break; | ||
262 | case MAX8998_BUCK4: | ||
263 | reg = MAX8998_REG_BUCK4; | ||
264 | break; | ||
265 | default: | ||
266 | return -EINVAL; | ||
267 | } | ||
268 | |||
269 | *_reg = reg; | ||
270 | *_shift = shift; | ||
271 | *_mask = mask; | ||
272 | |||
273 | return 0; | ||
274 | } | ||
275 | |||
276 | static int max8998_get_voltage(struct regulator_dev *rdev) | ||
277 | { | ||
278 | struct max8998_data *max8998 = rdev_get_drvdata(rdev); | ||
279 | int reg, shift = 0, mask, ret; | ||
280 | u8 val; | ||
281 | |||
282 | ret = max8998_get_voltage_register(rdev, ®, &shift, &mask); | ||
283 | if (ret) | ||
284 | return ret; | ||
285 | |||
286 | ret = max8998_read_reg(max8998->iodev, reg, &val); | ||
287 | if (ret) | ||
288 | return ret; | ||
289 | |||
290 | val >>= shift; | ||
291 | val &= mask; | ||
292 | |||
293 | return max8998_list_voltage(rdev, val); | ||
294 | } | ||
295 | |||
296 | static int max8998_set_voltage(struct regulator_dev *rdev, | ||
297 | int min_uV, int max_uV) | ||
298 | { | ||
299 | struct max8998_data *max8998 = rdev_get_drvdata(rdev); | ||
300 | int min_vol = min_uV / 1000, max_vol = max_uV / 1000; | ||
301 | int previous_vol = 0; | ||
302 | const struct voltage_map_desc *desc; | ||
303 | int ldo = max8998_get_ldo(rdev); | ||
304 | int reg, shift = 0, mask, ret; | ||
305 | int i = 0; | ||
306 | u8 val; | ||
307 | bool en_ramp = false; | ||
308 | |||
309 | if (ldo >= ARRAY_SIZE(ldo_voltage_map)) | ||
310 | return -EINVAL; | ||
311 | |||
312 | desc = ldo_voltage_map[ldo]; | ||
313 | if (desc == NULL) | ||
314 | return -EINVAL; | ||
315 | |||
316 | if (max_vol < desc->min || min_vol > desc->max) | ||
317 | return -EINVAL; | ||
318 | |||
319 | while (desc->min + desc->step*i < min_vol && | ||
320 | desc->min + desc->step*i < desc->max) | ||
321 | i++; | ||
322 | |||
323 | if (desc->min + desc->step*i > max_vol) | ||
324 | return -EINVAL; | ||
325 | |||
326 | ret = max8998_get_voltage_register(rdev, ®, &shift, &mask); | ||
327 | if (ret) | ||
328 | return ret; | ||
329 | |||
330 | /* wait for RAMP_UP_DELAY if rdev is BUCK1/2 and | ||
331 | * ENRAMP is ON */ | ||
332 | if (ldo == MAX8998_BUCK1 || ldo == MAX8998_BUCK2) { | ||
333 | max8998_read_reg(max8998->iodev, MAX8998_REG_ONOFF4, &val); | ||
334 | if (val & (1 << 4)) { | ||
335 | en_ramp = true; | ||
336 | previous_vol = max8998_get_voltage(rdev); | ||
337 | } | ||
338 | } | ||
339 | |||
340 | ret = max8998_update_reg(max8998->iodev, reg, i<<shift, mask<<shift); | ||
341 | |||
342 | if (en_ramp == true) { | ||
343 | int difference = desc->min + desc->step*i - previous_vol/1000; | ||
344 | if (difference > 0) | ||
345 | udelay(difference / ((val & 0x0f) + 1)); | ||
346 | } | ||
347 | |||
348 | return ret; | ||
349 | } | ||
350 | |||
351 | static struct regulator_ops max8998_ldo_ops = { | ||
352 | .list_voltage = max8998_list_voltage, | ||
353 | .is_enabled = max8998_ldo_is_enabled, | ||
354 | .enable = max8998_ldo_enable, | ||
355 | .disable = max8998_ldo_disable, | ||
356 | .get_voltage = max8998_get_voltage, | ||
357 | .set_voltage = max8998_set_voltage, | ||
358 | .set_suspend_enable = max8998_ldo_enable, | ||
359 | .set_suspend_disable = max8998_ldo_disable, | ||
360 | }; | ||
361 | |||
362 | static struct regulator_ops max8998_buck_ops = { | ||
363 | .list_voltage = max8998_list_voltage, | ||
364 | .is_enabled = max8998_ldo_is_enabled, | ||
365 | .enable = max8998_ldo_enable, | ||
366 | .disable = max8998_ldo_disable, | ||
367 | .get_voltage = max8998_get_voltage, | ||
368 | .set_voltage = max8998_set_voltage, | ||
369 | .set_suspend_enable = max8998_ldo_enable, | ||
370 | .set_suspend_disable = max8998_ldo_disable, | ||
371 | }; | ||
372 | |||
373 | static struct regulator_ops max8998_others_ops = { | ||
374 | .is_enabled = max8998_ldo_is_enabled, | ||
375 | .enable = max8998_ldo_enable, | ||
376 | .disable = max8998_ldo_disable, | ||
377 | .set_suspend_enable = max8998_ldo_enable, | ||
378 | .set_suspend_disable = max8998_ldo_disable, | ||
379 | }; | ||
380 | |||
381 | static struct regulator_desc regulators[] = { | ||
382 | { | ||
383 | .name = "LDO2", | ||
384 | .id = MAX8998_LDO2, | ||
385 | .ops = &max8998_ldo_ops, | ||
386 | .type = REGULATOR_VOLTAGE, | ||
387 | .owner = THIS_MODULE, | ||
388 | }, { | ||
389 | .name = "LDO3", | ||
390 | .id = MAX8998_LDO3, | ||
391 | .ops = &max8998_ldo_ops, | ||
392 | .type = REGULATOR_VOLTAGE, | ||
393 | .owner = THIS_MODULE, | ||
394 | }, { | ||
395 | .name = "LDO4", | ||
396 | .id = MAX8998_LDO4, | ||
397 | .ops = &max8998_ldo_ops, | ||
398 | .type = REGULATOR_VOLTAGE, | ||
399 | .owner = THIS_MODULE, | ||
400 | }, { | ||
401 | .name = "LDO5", | ||
402 | .id = MAX8998_LDO5, | ||
403 | .ops = &max8998_ldo_ops, | ||
404 | .type = REGULATOR_VOLTAGE, | ||
405 | .owner = THIS_MODULE, | ||
406 | }, { | ||
407 | .name = "LDO6", | ||
408 | .id = MAX8998_LDO6, | ||
409 | .ops = &max8998_ldo_ops, | ||
410 | .type = REGULATOR_VOLTAGE, | ||
411 | .owner = THIS_MODULE, | ||
412 | }, { | ||
413 | .name = "LDO7", | ||
414 | .id = MAX8998_LDO7, | ||
415 | .ops = &max8998_ldo_ops, | ||
416 | .type = REGULATOR_VOLTAGE, | ||
417 | .owner = THIS_MODULE, | ||
418 | }, { | ||
419 | .name = "LDO8", | ||
420 | .id = MAX8998_LDO8, | ||
421 | .ops = &max8998_ldo_ops, | ||
422 | .type = REGULATOR_VOLTAGE, | ||
423 | .owner = THIS_MODULE, | ||
424 | }, { | ||
425 | .name = "LDO9", | ||
426 | .id = MAX8998_LDO9, | ||
427 | .ops = &max8998_ldo_ops, | ||
428 | .type = REGULATOR_VOLTAGE, | ||
429 | .owner = THIS_MODULE, | ||
430 | }, { | ||
431 | .name = "LDO10", | ||
432 | .id = MAX8998_LDO10, | ||
433 | .ops = &max8998_ldo_ops, | ||
434 | .type = REGULATOR_VOLTAGE, | ||
435 | .owner = THIS_MODULE, | ||
436 | }, { | ||
437 | .name = "LDO11", | ||
438 | .id = MAX8998_LDO11, | ||
439 | .ops = &max8998_ldo_ops, | ||
440 | .type = REGULATOR_VOLTAGE, | ||
441 | .owner = THIS_MODULE, | ||
442 | }, { | ||
443 | .name = "LDO12", | ||
444 | .id = MAX8998_LDO12, | ||
445 | .ops = &max8998_ldo_ops, | ||
446 | .type = REGULATOR_VOLTAGE, | ||
447 | .owner = THIS_MODULE, | ||
448 | }, { | ||
449 | .name = "LDO13", | ||
450 | .id = MAX8998_LDO13, | ||
451 | .ops = &max8998_ldo_ops, | ||
452 | .type = REGULATOR_VOLTAGE, | ||
453 | .owner = THIS_MODULE, | ||
454 | }, { | ||
455 | .name = "LDO14", | ||
456 | .id = MAX8998_LDO14, | ||
457 | .ops = &max8998_ldo_ops, | ||
458 | .type = REGULATOR_VOLTAGE, | ||
459 | .owner = THIS_MODULE, | ||
460 | }, { | ||
461 | .name = "LDO15", | ||
462 | .id = MAX8998_LDO15, | ||
463 | .ops = &max8998_ldo_ops, | ||
464 | .type = REGULATOR_VOLTAGE, | ||
465 | .owner = THIS_MODULE, | ||
466 | }, { | ||
467 | .name = "LDO16", | ||
468 | .id = MAX8998_LDO16, | ||
469 | .ops = &max8998_ldo_ops, | ||
470 | .type = REGULATOR_VOLTAGE, | ||
471 | .owner = THIS_MODULE, | ||
472 | }, { | ||
473 | .name = "LDO17", | ||
474 | .id = MAX8998_LDO17, | ||
475 | .ops = &max8998_ldo_ops, | ||
476 | .type = REGULATOR_VOLTAGE, | ||
477 | .owner = THIS_MODULE, | ||
478 | }, { | ||
479 | .name = "BUCK1", | ||
480 | .id = MAX8998_BUCK1, | ||
481 | .ops = &max8998_buck_ops, | ||
482 | .type = REGULATOR_VOLTAGE, | ||
483 | .owner = THIS_MODULE, | ||
484 | }, { | ||
485 | .name = "BUCK2", | ||
486 | .id = MAX8998_BUCK2, | ||
487 | .ops = &max8998_buck_ops, | ||
488 | .type = REGULATOR_VOLTAGE, | ||
489 | .owner = THIS_MODULE, | ||
490 | }, { | ||
491 | .name = "BUCK3", | ||
492 | .id = MAX8998_BUCK3, | ||
493 | .ops = &max8998_buck_ops, | ||
494 | .type = REGULATOR_VOLTAGE, | ||
495 | .owner = THIS_MODULE, | ||
496 | }, { | ||
497 | .name = "BUCK4", | ||
498 | .id = MAX8998_BUCK4, | ||
499 | .ops = &max8998_buck_ops, | ||
500 | .type = REGULATOR_VOLTAGE, | ||
501 | .owner = THIS_MODULE, | ||
502 | }, { | ||
503 | .name = "EN32KHz AP", | ||
504 | .id = MAX8998_EN32KHZ_AP, | ||
505 | .ops = &max8998_others_ops, | ||
506 | .type = REGULATOR_VOLTAGE, | ||
507 | .owner = THIS_MODULE, | ||
508 | }, { | ||
509 | .name = "EN32KHz CP", | ||
510 | .id = MAX8998_EN32KHZ_CP, | ||
511 | .ops = &max8998_others_ops, | ||
512 | .type = REGULATOR_VOLTAGE, | ||
513 | .owner = THIS_MODULE, | ||
514 | }, { | ||
515 | .name = "ENVICHG", | ||
516 | .id = MAX8998_ENVICHG, | ||
517 | .ops = &max8998_others_ops, | ||
518 | .type = REGULATOR_VOLTAGE, | ||
519 | .owner = THIS_MODULE, | ||
520 | }, { | ||
521 | .name = "ESAFEOUT1", | ||
522 | .id = MAX8998_ESAFEOUT1, | ||
523 | .ops = &max8998_others_ops, | ||
524 | .type = REGULATOR_VOLTAGE, | ||
525 | .owner = THIS_MODULE, | ||
526 | }, { | ||
527 | .name = "ESAFEOUT2", | ||
528 | .id = MAX8998_ESAFEOUT2, | ||
529 | .ops = &max8998_others_ops, | ||
530 | .type = REGULATOR_VOLTAGE, | ||
531 | .owner = THIS_MODULE, | ||
532 | } | ||
533 | }; | ||
534 | |||
535 | static __devinit int max8998_pmic_probe(struct platform_device *pdev) | ||
536 | { | ||
537 | struct max8998_dev *iodev = dev_get_drvdata(pdev->dev.parent); | ||
538 | struct max8998_platform_data *pdata = dev_get_platdata(iodev->dev); | ||
539 | struct regulator_dev **rdev; | ||
540 | struct max8998_data *max8998; | ||
541 | int i, ret, size; | ||
542 | |||
543 | if (!pdata) { | ||
544 | dev_err(pdev->dev.parent, "No platform init data supplied\n"); | ||
545 | return -ENODEV; | ||
546 | } | ||
547 | |||
548 | max8998 = kzalloc(sizeof(struct max8998_data), GFP_KERNEL); | ||
549 | if (!max8998) | ||
550 | return -ENOMEM; | ||
551 | |||
552 | size = sizeof(struct regulator_dev *) * (pdata->num_regulators + 1); | ||
553 | max8998->rdev = kzalloc(size, GFP_KERNEL); | ||
554 | if (!max8998->rdev) { | ||
555 | kfree(max8998); | ||
556 | return -ENOMEM; | ||
557 | } | ||
558 | |||
559 | rdev = max8998->rdev; | ||
560 | max8998->iodev = iodev; | ||
561 | platform_set_drvdata(pdev, max8998); | ||
562 | |||
563 | for (i = 0; i < pdata->num_regulators; i++) { | ||
564 | const struct voltage_map_desc *desc; | ||
565 | int id = pdata->regulators[i].id; | ||
566 | int index = id - MAX8998_LDO2; | ||
567 | |||
568 | desc = ldo_voltage_map[id]; | ||
569 | if (desc && regulators[index].ops != &max8998_others_ops) { | ||
570 | int count = (desc->max - desc->min) / desc->step + 1; | ||
571 | regulators[index].n_voltages = count; | ||
572 | } | ||
573 | rdev[i] = regulator_register(®ulators[index], max8998->dev, | ||
574 | pdata->regulators[i].initdata, max8998); | ||
575 | if (IS_ERR(rdev[i])) { | ||
576 | ret = PTR_ERR(rdev[i]); | ||
577 | dev_err(max8998->dev, "regulator init failed\n"); | ||
578 | rdev[i] = NULL; | ||
579 | goto err; | ||
580 | } | ||
581 | } | ||
582 | |||
583 | |||
584 | return 0; | ||
585 | err: | ||
586 | for (i = 0; i <= max8998->num_regulators; i++) | ||
587 | if (rdev[i]) | ||
588 | regulator_unregister(rdev[i]); | ||
589 | |||
590 | kfree(max8998->rdev); | ||
591 | kfree(max8998); | ||
592 | |||
593 | return ret; | ||
594 | } | ||
595 | |||
596 | static int __devexit max8998_pmic_remove(struct platform_device *pdev) | ||
597 | { | ||
598 | struct max8998_data *max8998 = platform_get_drvdata(pdev); | ||
599 | struct regulator_dev **rdev = max8998->rdev; | ||
600 | int i; | ||
601 | |||
602 | for (i = 0; i <= max8998->num_regulators; i++) | ||
603 | if (rdev[i]) | ||
604 | regulator_unregister(rdev[i]); | ||
605 | |||
606 | kfree(max8998->rdev); | ||
607 | kfree(max8998); | ||
608 | |||
609 | return 0; | ||
610 | } | ||
611 | |||
612 | static struct platform_driver max8998_pmic_driver = { | ||
613 | .driver = { | ||
614 | .name = "max8998-pmic", | ||
615 | .owner = THIS_MODULE, | ||
616 | }, | ||
617 | .probe = max8998_pmic_probe, | ||
618 | .remove = __devexit_p(max8998_pmic_remove), | ||
619 | }; | ||
620 | |||
621 | static int __init max8998_pmic_init(void) | ||
622 | { | ||
623 | return platform_driver_register(&max8998_pmic_driver); | ||
624 | } | ||
625 | subsys_initcall(max8998_pmic_init); | ||
626 | |||
627 | static void __exit max8998_pmic_cleanup(void) | ||
628 | { | ||
629 | platform_driver_unregister(&max8998_pmic_driver); | ||
630 | } | ||
631 | module_exit(max8998_pmic_cleanup); | ||
632 | |||
633 | MODULE_DESCRIPTION("MAXIM 8998 voltage regulator driver"); | ||
634 | MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>"); | ||
635 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/regulator/tps65023-regulator.c b/drivers/regulator/tps65023-regulator.c index f50afc9f287a..cd6d4fc9d74f 100644 --- a/drivers/regulator/tps65023-regulator.c +++ b/drivers/regulator/tps65023-regulator.c | |||
@@ -585,6 +585,8 @@ static const struct tps_info tps65023_regs[] = { | |||
585 | static const struct i2c_device_id tps_65023_id[] = { | 585 | static const struct i2c_device_id tps_65023_id[] = { |
586 | {.name = "tps65023", | 586 | {.name = "tps65023", |
587 | .driver_data = (unsigned long) tps65023_regs,}, | 587 | .driver_data = (unsigned long) tps65023_regs,}, |
588 | {.name = "tps65021", | ||
589 | .driver_data = (unsigned long) tps65023_regs,}, | ||
588 | { }, | 590 | { }, |
589 | }; | 591 | }; |
590 | 592 | ||
diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index 8152d65220f5..c239f42aa4a3 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c | |||
@@ -614,6 +614,7 @@ int tps6507x_pmic_probe(struct platform_device *pdev) | |||
614 | } | 614 | } |
615 | 615 | ||
616 | tps6507x_dev->pmic = tps; | 616 | tps6507x_dev->pmic = tps; |
617 | platform_set_drvdata(pdev, tps6507x_dev); | ||
617 | 618 | ||
618 | return 0; | 619 | return 0; |
619 | 620 | ||
diff --git a/drivers/regulator/tps6586x-regulator.c b/drivers/regulator/tps6586x-regulator.c new file mode 100644 index 000000000000..8cff1413a147 --- /dev/null +++ b/drivers/regulator/tps6586x-regulator.c | |||
@@ -0,0 +1,396 @@ | |||
1 | /* | ||
2 | * Regulator driver for TI TPS6586x | ||
3 | * | ||
4 | * Copyright (C) 2010 Compulab Ltd. | ||
5 | * Author: Mike Rapoport <mike@compulab.co.il> | ||
6 | * | ||
7 | * Based on da903x | ||
8 | * Copyright (C) 2006-2008 Marvell International Ltd. | ||
9 | * Copyright (C) 2008 Compulab Ltd. | ||
10 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | ||
12 | * it under the terms of the GNU General Public License version 2 as | ||
13 | * published by the Free Software Foundation. | ||
14 | */ | ||
15 | |||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <linux/platform_device.h> | ||
21 | #include <linux/regulator/driver.h> | ||
22 | #include <linux/regulator/machine.h> | ||
23 | #include <linux/mfd/tps6586x.h> | ||
24 | |||
25 | /* supply control and voltage setting */ | ||
26 | #define TPS6586X_SUPPLYENA 0x10 | ||
27 | #define TPS6586X_SUPPLYENB 0x11 | ||
28 | #define TPS6586X_SUPPLYENC 0x12 | ||
29 | #define TPS6586X_SUPPLYEND 0x13 | ||
30 | #define TPS6586X_SUPPLYENE 0x14 | ||
31 | #define TPS6586X_VCC1 0x20 | ||
32 | #define TPS6586X_VCC2 0x21 | ||
33 | #define TPS6586X_SM1V1 0x23 | ||
34 | #define TPS6586X_SM1V2 0x24 | ||
35 | #define TPS6586X_SM1SL 0x25 | ||
36 | #define TPS6586X_SM0V1 0x26 | ||
37 | #define TPS6586X_SM0V2 0x27 | ||
38 | #define TPS6586X_SM0SL 0x28 | ||
39 | #define TPS6586X_LDO2AV1 0x29 | ||
40 | #define TPS6586X_LDO2AV2 0x2A | ||
41 | #define TPS6586X_LDO2BV1 0x2F | ||
42 | #define TPS6586X_LDO2BV2 0x30 | ||
43 | #define TPS6586X_LDO4V1 0x32 | ||
44 | #define TPS6586X_LDO4V2 0x33 | ||
45 | |||
46 | /* converter settings */ | ||
47 | #define TPS6586X_SUPPLYV1 0x41 | ||
48 | #define TPS6586X_SUPPLYV2 0x42 | ||
49 | #define TPS6586X_SUPPLYV3 0x43 | ||
50 | #define TPS6586X_SUPPLYV4 0x44 | ||
51 | #define TPS6586X_SUPPLYV5 0x45 | ||
52 | #define TPS6586X_SUPPLYV6 0x46 | ||
53 | #define TPS6586X_SMODE1 0x47 | ||
54 | #define TPS6586X_SMODE2 0x48 | ||
55 | |||
56 | struct tps6586x_regulator { | ||
57 | struct regulator_desc desc; | ||
58 | |||
59 | int volt_reg; | ||
60 | int volt_shift; | ||
61 | int volt_nbits; | ||
62 | int enable_bit[2]; | ||
63 | int enable_reg[2]; | ||
64 | |||
65 | int *voltages; | ||
66 | |||
67 | /* for DVM regulators */ | ||
68 | int go_reg; | ||
69 | int go_bit; | ||
70 | }; | ||
71 | |||
72 | static inline struct device *to_tps6586x_dev(struct regulator_dev *rdev) | ||
73 | { | ||
74 | return rdev_get_dev(rdev)->parent->parent; | ||
75 | } | ||
76 | |||
77 | static int tps6586x_ldo_list_voltage(struct regulator_dev *rdev, | ||
78 | unsigned selector) | ||
79 | { | ||
80 | struct tps6586x_regulator *info = rdev_get_drvdata(rdev); | ||
81 | |||
82 | return info->voltages[selector] * 1000; | ||
83 | } | ||
84 | |||
85 | |||
86 | static int __tps6586x_ldo_set_voltage(struct device *parent, | ||
87 | struct tps6586x_regulator *ri, | ||
88 | int min_uV, int max_uV) | ||
89 | { | ||
90 | int val, uV; | ||
91 | uint8_t mask; | ||
92 | |||
93 | for (val = 0; val < ri->desc.n_voltages; val++) { | ||
94 | uV = ri->voltages[val] * 1000; | ||
95 | |||
96 | /* LDO0 has minimal voltage 1.2 rather than 1.25 */ | ||
97 | if (ri->desc.id == TPS6586X_ID_LDO_0 && val == 0) | ||
98 | uV -= 50 * 1000; | ||
99 | |||
100 | /* use the first in-range value */ | ||
101 | if (min_uV <= uV && uV <= max_uV) { | ||
102 | |||
103 | val <<= ri->volt_shift; | ||
104 | mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift; | ||
105 | |||
106 | return tps6586x_update(parent, ri->volt_reg, val, mask); | ||
107 | } | ||
108 | } | ||
109 | |||
110 | return -EINVAL; | ||
111 | } | ||
112 | |||
113 | static int tps6586x_ldo_set_voltage(struct regulator_dev *rdev, | ||
114 | int min_uV, int max_uV) | ||
115 | { | ||
116 | struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); | ||
117 | struct device *parent = to_tps6586x_dev(rdev); | ||
118 | |||
119 | return __tps6586x_ldo_set_voltage(parent, ri, min_uV, max_uV); | ||
120 | } | ||
121 | |||
122 | static int tps6586x_ldo_get_voltage(struct regulator_dev *rdev) | ||
123 | { | ||
124 | struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); | ||
125 | struct device *parent = to_tps6586x_dev(rdev); | ||
126 | uint8_t val, mask; | ||
127 | int ret; | ||
128 | |||
129 | ret = tps6586x_read(parent, ri->volt_reg, &val); | ||
130 | if (ret) | ||
131 | return ret; | ||
132 | |||
133 | mask = ((1 << ri->volt_nbits) - 1) << ri->volt_shift; | ||
134 | val = (val & mask) >> ri->volt_shift; | ||
135 | |||
136 | if (val > ri->desc.n_voltages) | ||
137 | BUG(); | ||
138 | |||
139 | return ri->voltages[val] * 1000; | ||
140 | } | ||
141 | |||
142 | static int tps6586x_dvm_set_voltage(struct regulator_dev *rdev, | ||
143 | int min_uV, int max_uV) | ||
144 | { | ||
145 | struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); | ||
146 | struct device *parent = to_tps6586x_dev(rdev); | ||
147 | int ret; | ||
148 | |||
149 | ret = __tps6586x_ldo_set_voltage(parent, ri, min_uV, max_uV); | ||
150 | if (ret) | ||
151 | return ret; | ||
152 | |||
153 | return tps6586x_set_bits(parent, ri->go_reg, ri->go_bit); | ||
154 | } | ||
155 | |||
156 | static int tps6586x_regulator_enable(struct regulator_dev *rdev) | ||
157 | { | ||
158 | struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); | ||
159 | struct device *parent = to_tps6586x_dev(rdev); | ||
160 | |||
161 | return tps6586x_set_bits(parent, ri->enable_reg[0], | ||
162 | 1 << ri->enable_bit[0]); | ||
163 | } | ||
164 | |||
165 | static int tps6586x_regulator_disable(struct regulator_dev *rdev) | ||
166 | { | ||
167 | struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); | ||
168 | struct device *parent = to_tps6586x_dev(rdev); | ||
169 | |||
170 | return tps6586x_clr_bits(parent, ri->enable_reg[0], | ||
171 | 1 << ri->enable_bit[0]); | ||
172 | } | ||
173 | |||
174 | static int tps6586x_regulator_is_enabled(struct regulator_dev *rdev) | ||
175 | { | ||
176 | struct tps6586x_regulator *ri = rdev_get_drvdata(rdev); | ||
177 | struct device *parent = to_tps6586x_dev(rdev); | ||
178 | uint8_t reg_val; | ||
179 | int ret; | ||
180 | |||
181 | ret = tps6586x_read(parent, ri->enable_reg[0], ®_val); | ||
182 | if (ret) | ||
183 | return ret; | ||
184 | |||
185 | return !!(reg_val & (1 << ri->enable_bit[0])); | ||
186 | } | ||
187 | |||
188 | static struct regulator_ops tps6586x_regulator_ldo_ops = { | ||
189 | .list_voltage = tps6586x_ldo_list_voltage, | ||
190 | .get_voltage = tps6586x_ldo_get_voltage, | ||
191 | .set_voltage = tps6586x_ldo_set_voltage, | ||
192 | |||
193 | .is_enabled = tps6586x_regulator_is_enabled, | ||
194 | .enable = tps6586x_regulator_enable, | ||
195 | .disable = tps6586x_regulator_disable, | ||
196 | }; | ||
197 | |||
198 | static struct regulator_ops tps6586x_regulator_dvm_ops = { | ||
199 | .list_voltage = tps6586x_ldo_list_voltage, | ||
200 | .get_voltage = tps6586x_ldo_get_voltage, | ||
201 | .set_voltage = tps6586x_dvm_set_voltage, | ||
202 | |||
203 | .is_enabled = tps6586x_regulator_is_enabled, | ||
204 | .enable = tps6586x_regulator_enable, | ||
205 | .disable = tps6586x_regulator_disable, | ||
206 | }; | ||
207 | |||
208 | static int tps6586x_ldo_voltages[] = { | ||
209 | 1250, 1500, 1800, 2500, 2700, 2850, 3100, 3300, | ||
210 | }; | ||
211 | |||
212 | static int tps6586x_ldo4_voltages[] = { | ||
213 | 1700, 1725, 1750, 1775, 1800, 1825, 1850, 1875, | ||
214 | 1900, 1925, 1950, 1975, 2000, 2025, 2050, 2075, | ||
215 | 2100, 2125, 2150, 2175, 2200, 2225, 2250, 2275, | ||
216 | 2300, 2325, 2350, 2375, 2400, 2425, 2450, 2475, | ||
217 | }; | ||
218 | |||
219 | static int tps6586x_sm2_voltages[] = { | ||
220 | 3000, 3050, 3100, 3150, 3200, 3250, 3300, 3350, | ||
221 | 3400, 3450, 3500, 3550, 3600, 3650, 3700, 3750, | ||
222 | 3800, 3850, 3900, 3950, 4000, 4050, 4100, 4150, | ||
223 | 4200, 4250, 4300, 4350, 4400, 4450, 4500, 4550, | ||
224 | }; | ||
225 | |||
226 | static int tps6586x_dvm_voltages[] = { | ||
227 | 725, 750, 775, 800, 825, 850, 875, 900, | ||
228 | 925, 950, 975, 1000, 1025, 1050, 1075, 1100, | ||
229 | 1125, 1150, 1175, 1200, 1225, 1250, 1275, 1300, | ||
230 | 1325, 1350, 1375, 1400, 1425, 1450, 1475, 1500, | ||
231 | }; | ||
232 | |||
233 | #define TPS6586X_REGULATOR(_id, vdata, _ops, vreg, shift, nbits, \ | ||
234 | ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ | ||
235 | { \ | ||
236 | .desc = { \ | ||
237 | .name = "REG-" #_id, \ | ||
238 | .ops = &tps6586x_regulator_##_ops, \ | ||
239 | .type = REGULATOR_VOLTAGE, \ | ||
240 | .id = TPS6586X_ID_##_id, \ | ||
241 | .n_voltages = ARRAY_SIZE(tps6586x_##vdata##_voltages), \ | ||
242 | .owner = THIS_MODULE, \ | ||
243 | }, \ | ||
244 | .volt_reg = TPS6586X_##vreg, \ | ||
245 | .volt_shift = (shift), \ | ||
246 | .volt_nbits = (nbits), \ | ||
247 | .enable_reg[0] = TPS6586X_SUPPLY##ereg0, \ | ||
248 | .enable_bit[0] = (ebit0), \ | ||
249 | .enable_reg[1] = TPS6586X_SUPPLY##ereg1, \ | ||
250 | .enable_bit[1] = (ebit1), \ | ||
251 | .voltages = tps6586x_##vdata##_voltages, \ | ||
252 | } | ||
253 | |||
254 | #define TPS6586X_LDO(_id, vdata, vreg, shift, nbits, \ | ||
255 | ereg0, ebit0, ereg1, ebit1) \ | ||
256 | TPS6586X_REGULATOR(_id, vdata, ldo_ops, vreg, shift, nbits, \ | ||
257 | ereg0, ebit0, ereg1, ebit1, 0, 0) | ||
258 | |||
259 | #define TPS6586X_DVM(_id, vdata, vreg, shift, nbits, \ | ||
260 | ereg0, ebit0, ereg1, ebit1, goreg, gobit) \ | ||
261 | TPS6586X_REGULATOR(_id, vdata, dvm_ops, vreg, shift, nbits, \ | ||
262 | ereg0, ebit0, ereg1, ebit1, goreg, gobit) | ||
263 | |||
264 | static struct tps6586x_regulator tps6586x_regulator[] = { | ||
265 | TPS6586X_LDO(LDO_0, ldo, SUPPLYV1, 5, 3, ENC, 0, END, 0), | ||
266 | TPS6586X_LDO(LDO_3, ldo, SUPPLYV4, 0, 3, ENC, 2, END, 2), | ||
267 | TPS6586X_LDO(LDO_5, ldo, SUPPLYV6, 0, 3, ENE, 6, ENE, 6), | ||
268 | TPS6586X_LDO(LDO_6, ldo, SUPPLYV3, 0, 3, ENC, 4, END, 4), | ||
269 | TPS6586X_LDO(LDO_7, ldo, SUPPLYV3, 3, 3, ENC, 5, END, 5), | ||
270 | TPS6586X_LDO(LDO_8, ldo, SUPPLYV1, 5, 3, ENC, 6, END, 6), | ||
271 | TPS6586X_LDO(LDO_9, ldo, SUPPLYV6, 3, 3, ENE, 7, ENE, 7), | ||
272 | TPS6586X_LDO(LDO_RTC, ldo, SUPPLYV4, 3, 3, ENE, 7, ENE, 7), | ||
273 | TPS6586X_LDO(LDO_1, dvm, SUPPLYV1, 0, 5, ENC, 1, END, 1), | ||
274 | TPS6586X_LDO(SM_2, sm2, SUPPLYV2, 0, 5, ENC, 1, END, 1), | ||
275 | |||
276 | TPS6586X_DVM(LDO_2, dvm, LDO2BV1, 0, 5, ENA, 3, ENB, 3, VCC2, 6), | ||
277 | TPS6586X_DVM(LDO_4, ldo4, LDO4V1, 0, 5, ENC, 3, END, 3, VCC1, 6), | ||
278 | TPS6586X_DVM(SM_0, dvm, SM0V1, 0, 5, ENA, 1, ENB, 1, VCC1, 2), | ||
279 | TPS6586X_DVM(SM_1, dvm, SM1V1, 0, 5, ENA, 0, ENB, 0, VCC1, 0), | ||
280 | }; | ||
281 | |||
282 | /* | ||
283 | * TPS6586X has 2 enable bits that are OR'ed to determine the actual | ||
284 | * regulator state. Clearing one of this bits allows switching | ||
285 | * regulator on and of with single register write. | ||
286 | */ | ||
287 | static inline int tps6586x_regulator_preinit(struct device *parent, | ||
288 | struct tps6586x_regulator *ri) | ||
289 | { | ||
290 | uint8_t val1, val2; | ||
291 | int ret; | ||
292 | |||
293 | ret = tps6586x_read(parent, ri->enable_reg[0], &val1); | ||
294 | if (ret) | ||
295 | return ret; | ||
296 | |||
297 | ret = tps6586x_read(parent, ri->enable_reg[1], &val2); | ||
298 | if (ret) | ||
299 | return ret; | ||
300 | |||
301 | if (!(val2 & ri->enable_bit[1])) | ||
302 | return 0; | ||
303 | |||
304 | /* | ||
305 | * The regulator is on, but it's enabled with the bit we don't | ||
306 | * want to use, so we switch the enable bits | ||
307 | */ | ||
308 | if (!(val1 & ri->enable_bit[0])) { | ||
309 | ret = tps6586x_set_bits(parent, ri->enable_reg[0], | ||
310 | 1 << ri->enable_bit[0]); | ||
311 | if (ret) | ||
312 | return ret; | ||
313 | } | ||
314 | |||
315 | return tps6586x_clr_bits(parent, ri->enable_reg[1], | ||
316 | 1 << ri->enable_bit[1]); | ||
317 | } | ||
318 | |||
319 | static inline struct tps6586x_regulator *find_regulator_info(int id) | ||
320 | { | ||
321 | struct tps6586x_regulator *ri; | ||
322 | int i; | ||
323 | |||
324 | for (i = 0; i < ARRAY_SIZE(tps6586x_regulator); i++) { | ||
325 | ri = &tps6586x_regulator[i]; | ||
326 | if (ri->desc.id == id) | ||
327 | return ri; | ||
328 | } | ||
329 | return NULL; | ||
330 | } | ||
331 | |||
332 | static int __devinit tps6586x_regulator_probe(struct platform_device *pdev) | ||
333 | { | ||
334 | struct tps6586x_regulator *ri = NULL; | ||
335 | struct regulator_dev *rdev; | ||
336 | int id = pdev->id; | ||
337 | int err; | ||
338 | |||
339 | dev_dbg(&pdev->dev, "Probing reulator %d\n", id); | ||
340 | |||
341 | ri = find_regulator_info(id); | ||
342 | if (ri == NULL) { | ||
343 | dev_err(&pdev->dev, "invalid regulator ID specified\n"); | ||
344 | return -EINVAL; | ||
345 | } | ||
346 | |||
347 | err = tps6586x_regulator_preinit(pdev->dev.parent, ri); | ||
348 | if (err) | ||
349 | return err; | ||
350 | |||
351 | rdev = regulator_register(&ri->desc, &pdev->dev, | ||
352 | pdev->dev.platform_data, ri); | ||
353 | if (IS_ERR(rdev)) { | ||
354 | dev_err(&pdev->dev, "failed to register regulator %s\n", | ||
355 | ri->desc.name); | ||
356 | return PTR_ERR(rdev); | ||
357 | } | ||
358 | |||
359 | platform_set_drvdata(pdev, rdev); | ||
360 | |||
361 | return 0; | ||
362 | } | ||
363 | |||
364 | static int __devexit tps6586x_regulator_remove(struct platform_device *pdev) | ||
365 | { | ||
366 | struct regulator_dev *rdev = platform_get_drvdata(pdev); | ||
367 | |||
368 | regulator_unregister(rdev); | ||
369 | return 0; | ||
370 | } | ||
371 | |||
372 | static struct platform_driver tps6586x_regulator_driver = { | ||
373 | .driver = { | ||
374 | .name = "tps6586x-regulator", | ||
375 | .owner = THIS_MODULE, | ||
376 | }, | ||
377 | .probe = tps6586x_regulator_probe, | ||
378 | .remove = __devexit_p(tps6586x_regulator_remove), | ||
379 | }; | ||
380 | |||
381 | static int __init tps6586x_regulator_init(void) | ||
382 | { | ||
383 | return platform_driver_register(&tps6586x_regulator_driver); | ||
384 | } | ||
385 | subsys_initcall(tps6586x_regulator_init); | ||
386 | |||
387 | static void __exit tps6586x_regulator_exit(void) | ||
388 | { | ||
389 | platform_driver_unregister(&tps6586x_regulator_driver); | ||
390 | } | ||
391 | module_exit(tps6586x_regulator_exit); | ||
392 | |||
393 | MODULE_LICENSE("GPL"); | ||
394 | MODULE_AUTHOR("Mike Rapoport <mike@compulab.co.il>"); | ||
395 | MODULE_DESCRIPTION("Regulator Driver for TI TPS6586X PMIC"); | ||
396 | MODULE_ALIAS("platform:tps6586x-regulator"); | ||
diff --git a/drivers/regulator/wm8994-regulator.c b/drivers/regulator/wm8994-regulator.c index 5a1dc8a24d35..03713bc66e4a 100644 --- a/drivers/regulator/wm8994-regulator.c +++ b/drivers/regulator/wm8994-regulator.c | |||
@@ -219,8 +219,6 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev) | |||
219 | 219 | ||
220 | ldo->wm8994 = wm8994; | 220 | ldo->wm8994 = wm8994; |
221 | 221 | ||
222 | ldo->is_enabled = true; | ||
223 | |||
224 | if (pdata->ldo[id].enable && gpio_is_valid(pdata->ldo[id].enable)) { | 222 | if (pdata->ldo[id].enable && gpio_is_valid(pdata->ldo[id].enable)) { |
225 | ldo->enable = pdata->ldo[id].enable; | 223 | ldo->enable = pdata->ldo[id].enable; |
226 | 224 | ||
@@ -237,7 +235,8 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev) | |||
237 | ret); | 235 | ret); |
238 | goto err_gpio; | 236 | goto err_gpio; |
239 | } | 237 | } |
240 | } | 238 | } else |
239 | ldo->is_enabled = true; | ||
241 | 240 | ||
242 | ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &pdev->dev, | 241 | ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &pdev->dev, |
243 | pdata->ldo[id].init_data, ldo); | 242 | pdata->ldo[id].init_data, ldo); |
diff --git a/include/linux/mfd/ab8500.h b/include/linux/mfd/ab8500.h index b63ff3ba3351..f5cec4500f38 100644 --- a/include/linux/mfd/ab8500.h +++ b/include/linux/mfd/ab8500.h | |||
@@ -76,6 +76,8 @@ | |||
76 | #define AB8500_NR_IRQS 104 | 76 | #define AB8500_NR_IRQS 104 |
77 | #define AB8500_NUM_IRQ_REGS 13 | 77 | #define AB8500_NUM_IRQ_REGS 13 |
78 | 78 | ||
79 | #define AB8500_NUM_REGULATORS 15 | ||
80 | |||
79 | /** | 81 | /** |
80 | * struct ab8500 - ab8500 internal structure | 82 | * struct ab8500 - ab8500 internal structure |
81 | * @dev: parent device | 83 | * @dev: parent device |
@@ -108,14 +110,18 @@ struct ab8500 { | |||
108 | u8 oldmask[AB8500_NUM_IRQ_REGS]; | 110 | u8 oldmask[AB8500_NUM_IRQ_REGS]; |
109 | }; | 111 | }; |
110 | 112 | ||
113 | struct regulator_init_data; | ||
114 | |||
111 | /** | 115 | /** |
112 | * struct ab8500_platform_data - AB8500 platform data | 116 | * struct ab8500_platform_data - AB8500 platform data |
113 | * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used | 117 | * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used |
114 | * @init: board-specific initialization after detection of ab8500 | 118 | * @init: board-specific initialization after detection of ab8500 |
119 | * @regulator: machine-specific constraints for regulators | ||
115 | */ | 120 | */ |
116 | struct ab8500_platform_data { | 121 | struct ab8500_platform_data { |
117 | int irq_base; | 122 | int irq_base; |
118 | void (*init) (struct ab8500 *); | 123 | void (*init) (struct ab8500 *); |
124 | struct regulator_init_data *regulator[AB8500_NUM_REGULATORS]; | ||
119 | }; | 125 | }; |
120 | 126 | ||
121 | extern int ab8500_write(struct ab8500 *a8500, u16 addr, u8 data); | 127 | extern int ab8500_write(struct ab8500 *a8500, u16 addr, u8 data); |
diff --git a/include/linux/mfd/max8998-private.h b/include/linux/mfd/max8998-private.h new file mode 100644 index 000000000000..6dc75b3e2d33 --- /dev/null +++ b/include/linux/mfd/max8998-private.h | |||
@@ -0,0 +1,112 @@ | |||
1 | /* | ||
2 | * max8698.h - Voltage regulator driver for the Maxim 8998 | ||
3 | * | ||
4 | * Copyright (C) 2009-2010 Samsung Electrnoics | ||
5 | * Kyungmin Park <kyungmin.park@samsung.com> | ||
6 | * Marek Szyprowski <m.szyprowski@samsung.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #ifndef __LINUX_MFD_MAX8998_PRIV_H | ||
24 | #define __LINUX_MFD_MAX8998_PRIV_H | ||
25 | |||
26 | /* MAX 8998 registers */ | ||
27 | enum { | ||
28 | MAX8998_REG_IRQ1, | ||
29 | MAX8998_REG_IRQ2, | ||
30 | MAX8998_REG_IRQ3, | ||
31 | MAX8998_REG_IRQ4, | ||
32 | MAX8998_REG_IRQM1, | ||
33 | MAX8998_REG_IRQM2, | ||
34 | MAX8998_REG_IRQM3, | ||
35 | MAX8998_REG_IRQM4, | ||
36 | MAX8998_REG_STATUS1, | ||
37 | MAX8998_REG_STATUS2, | ||
38 | MAX8998_REG_STATUSM1, | ||
39 | MAX8998_REG_STATUSM2, | ||
40 | MAX8998_REG_CHGR1, | ||
41 | MAX8998_REG_CHGR2, | ||
42 | MAX8998_REG_LDO_ACTIVE_DISCHARGE1, | ||
43 | MAX8998_REG_LDO_ACTIVE_DISCHARGE2, | ||
44 | MAX8998_REG_BUCK_ACTIVE_DISCHARGE3, | ||
45 | MAX8998_REG_ONOFF1, | ||
46 | MAX8998_REG_ONOFF2, | ||
47 | MAX8998_REG_ONOFF3, | ||
48 | MAX8998_REG_ONOFF4, | ||
49 | MAX8998_REG_BUCK1_DVSARM1, | ||
50 | MAX8998_REG_BUCK1_DVSARM2, | ||
51 | MAX8998_REG_BUCK1_DVSARM3, | ||
52 | MAX8998_REG_BUCK1_DVSARM4, | ||
53 | MAX8998_REG_BUCK2_DVSINT1, | ||
54 | MAX8998_REG_BUCK2_DVSINT2, | ||
55 | MAX8998_REG_BUCK3, | ||
56 | MAX8998_REG_BUCK4, | ||
57 | MAX8998_REG_LDO2_LDO3, | ||
58 | MAX8998_REG_LDO4, | ||
59 | MAX8998_REG_LDO5, | ||
60 | MAX8998_REG_LDO6, | ||
61 | MAX8998_REG_LDO7, | ||
62 | MAX8998_REG_LDO8_LDO9, | ||
63 | MAX8998_REG_LDO10_LDO11, | ||
64 | MAX8998_REG_LDO12, | ||
65 | MAX8998_REG_LDO13, | ||
66 | MAX8998_REG_LDO14, | ||
67 | MAX8998_REG_LDO15, | ||
68 | MAX8998_REG_LDO16, | ||
69 | MAX8998_REG_LDO17, | ||
70 | MAX8998_REG_BKCHR, | ||
71 | MAX8998_REG_LBCNFG1, | ||
72 | MAX8998_REG_LBCNFG2, | ||
73 | }; | ||
74 | |||
75 | /** | ||
76 | * struct max8998_dev - max8998 master device for sub-drivers | ||
77 | * @dev: master device of the chip (can be used to access platform data) | ||
78 | * @i2c_client: i2c client private data | ||
79 | * @dev_read(): chip register read function | ||
80 | * @dev_write(): chip register write function | ||
81 | * @dev_update(): chip register update function | ||
82 | * @iolock: mutex for serializing io access | ||
83 | */ | ||
84 | |||
85 | struct max8998_dev { | ||
86 | struct device *dev; | ||
87 | struct i2c_client *i2c_client; | ||
88 | int (*dev_read)(struct max8998_dev *max8998, u8 reg, u8 *dest); | ||
89 | int (*dev_write)(struct max8998_dev *max8998, u8 reg, u8 val); | ||
90 | int (*dev_update)(struct max8998_dev *max8998, u8 reg, u8 val, u8 mask); | ||
91 | struct mutex iolock; | ||
92 | }; | ||
93 | |||
94 | static inline int max8998_read_reg(struct max8998_dev *max8998, u8 reg, | ||
95 | u8 *value) | ||
96 | { | ||
97 | return max8998->dev_read(max8998, reg, value); | ||
98 | } | ||
99 | |||
100 | static inline int max8998_write_reg(struct max8998_dev *max8998, u8 reg, | ||
101 | u8 value) | ||
102 | { | ||
103 | return max8998->dev_write(max8998, reg, value); | ||
104 | } | ||
105 | |||
106 | static inline int max8998_update_reg(struct max8998_dev *max8998, u8 reg, | ||
107 | u8 value, u8 mask) | ||
108 | { | ||
109 | return max8998->dev_update(max8998, reg, value, mask); | ||
110 | } | ||
111 | |||
112 | #endif /* __LINUX_MFD_MAX8998_PRIV_H */ | ||
diff --git a/include/linux/mfd/max8998.h b/include/linux/mfd/max8998.h new file mode 100644 index 000000000000..1d3601a2d853 --- /dev/null +++ b/include/linux/mfd/max8998.h | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * max8698.h - Voltage regulator driver for the Maxim 8998 | ||
3 | * | ||
4 | * Copyright (C) 2009-2010 Samsung Electrnoics | ||
5 | * Kyungmin Park <kyungmin.park@samsung.com> | ||
6 | * Marek Szyprowski <m.szyprowski@samsung.com> | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify | ||
9 | * it under the terms of the GNU General Public License as published by | ||
10 | * the Free Software Foundation; either version 2 of the License, or | ||
11 | * (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU General Public License | ||
19 | * along with this program; if not, write to the Free Software | ||
20 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
21 | */ | ||
22 | |||
23 | #ifndef __LINUX_MFD_MAX8998_H | ||
24 | #define __LINUX_MFD_MAX8998_H | ||
25 | |||
26 | #include <linux/regulator/machine.h> | ||
27 | |||
28 | /* MAX 8998 regulator ids */ | ||
29 | enum { | ||
30 | MAX8998_LDO2 = 2, | ||
31 | MAX8998_LDO3, | ||
32 | MAX8998_LDO4, | ||
33 | MAX8998_LDO5, | ||
34 | MAX8998_LDO6, | ||
35 | MAX8998_LDO7, | ||
36 | MAX8998_LDO8, | ||
37 | MAX8998_LDO9, | ||
38 | MAX8998_LDO10, | ||
39 | MAX8998_LDO11, | ||
40 | MAX8998_LDO12, | ||
41 | MAX8998_LDO13, | ||
42 | MAX8998_LDO14, | ||
43 | MAX8998_LDO15, | ||
44 | MAX8998_LDO16, | ||
45 | MAX8998_LDO17, | ||
46 | MAX8998_BUCK1, | ||
47 | MAX8998_BUCK2, | ||
48 | MAX8998_BUCK3, | ||
49 | MAX8998_BUCK4, | ||
50 | MAX8998_EN32KHZ_AP, | ||
51 | MAX8998_EN32KHZ_CP, | ||
52 | MAX8998_ENVICHG, | ||
53 | MAX8998_ESAFEOUT1, | ||
54 | MAX8998_ESAFEOUT2, | ||
55 | }; | ||
56 | |||
57 | /** | ||
58 | * max8998_regulator_data - regulator data | ||
59 | * @id: regulator id | ||
60 | * @initdata: regulator init data (contraints, supplies, ...) | ||
61 | */ | ||
62 | struct max8998_regulator_data { | ||
63 | int id; | ||
64 | struct regulator_init_data *initdata; | ||
65 | }; | ||
66 | |||
67 | /** | ||
68 | * struct max8998_board - packages regulator init data | ||
69 | * @num_regulators: number of regultors used | ||
70 | * @regulators: array of defined regulators | ||
71 | */ | ||
72 | |||
73 | struct max8998_platform_data { | ||
74 | int num_regulators; | ||
75 | struct max8998_regulator_data *regulators; | ||
76 | }; | ||
77 | |||
78 | #endif /* __LINUX_MFD_MAX8998_H */ | ||
diff --git a/include/linux/regulator/ab8500.h b/include/linux/regulator/ab8500.h new file mode 100644 index 000000000000..f509877c2ed4 --- /dev/null +++ b/include/linux/regulator/ab8500.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * Copyright (C) ST-Ericsson SA 2010 | ||
3 | * | ||
4 | * License Terms: GNU General Public License v2 | ||
5 | * | ||
6 | * Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #ifndef __LINUX_MFD_AB8500_REGULATOR_H | ||
11 | #define __LINUX_MFD_AB8500_REGULATOR_H | ||
12 | |||
13 | /* AB8500 regulators */ | ||
14 | #define AB8500_LDO_AUX1 0 | ||
15 | #define AB8500_LDO_AUX2 1 | ||
16 | #define AB8500_LDO_AUX3 2 | ||
17 | #define AB8500_LDO_INTCORE 3 | ||
18 | #define AB8500_LDO_TVOUT 4 | ||
19 | #define AB8500_LDO_AUDIO 5 | ||
20 | #define AB8500_LDO_ANAMIC1 6 | ||
21 | #define AB8500_LDO_ANAMIC2 7 | ||
22 | #define AB8500_LDO_DMIC 8 | ||
23 | #define AB8500_LDO_ANA 9 | ||
24 | |||
25 | #endif | ||