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 | ||
