Commit 58028762 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6

* 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/lrg/voltage-2.6: (22 commits)
  regulator: Remove default DEBUG define from TPS6586x
  regulator: tps6507x - add missing platform_set_drvdata in tps6507x_pmic_probe
  regulator: tps6586x - add regulator_unregister() in tps6586x_regulator_remove()
  mfd: max8998 - fix incorrect kfree(i2c) in i2c_driver probe callback handler
  regulator: lp3971 - remove unnecessary ret value checking in lp3971_i2c_write()
  regulator: max8660 - fix a memory leak in max8660_remove()
  regulator: max1586 - fix a memory leak in max1586_pmic_remove()
  regulator: Default GPIO controlled WM8994 regulators to disabled
  regulator: lp3971 - remove unnecessary ret value checking in lp3971_i2c_write()
  max8998: fix off-by-one value range checking
  regulator: tps6586x: fix millivolt return values and SM2 table
  regulator: tps6586x: add dependancy on MFD_TPS6585x
  regulator: add TPS6586X regulator driver
  regulator: MAX8998: set_voltage bugfix. ramp_up delay and min/max voltage
  regulator: add support for regulators on the ab8500 MFD
  ab8500-mfd: add regulator support to ab8500 mfd device
  tps65023: Allow registering similar TPS65021
  drivers: regulators: depend on MFD_MAX8998
  drivers: regulator: add Maxim 8998 driver
  ISL6271A voltage regulator support.
  ...
parents e83ddb33 120be663
...@@ -293,6 +293,16 @@ config MFD_MAX8925 ...@@ -293,6 +293,16 @@ config MFD_MAX8925
accessing the device, additional drivers must be enabled in order accessing the device, additional drivers must be enabled in order
to use the functionality of the device. to use the functionality of the device.
config MFD_MAX8998
bool "Maxim Semiconductor MAX8998 PMIC Support"
depends on I2C=y
select MFD_CORE
help
Say yes here to support for Maxim Semiconductor MAX8998. This is
a Power Management IC. This driver provies common support for
accessing the device, additional drivers must be enabled in order
to use the functionality of the device.
config MFD_WM8400 config MFD_WM8400
tristate "Support Wolfson Microelectronics WM8400" tristate "Support Wolfson Microelectronics WM8400"
select MFD_CORE select MFD_CORE
......
...@@ -58,6 +58,7 @@ obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o ...@@ -58,6 +58,7 @@ obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o
obj-$(CONFIG_PMIC_DA903X) += da903x.o obj-$(CONFIG_PMIC_DA903X) += da903x.o
max8925-objs := max8925-core.o max8925-i2c.o max8925-objs := max8925-core.o max8925-i2c.o
obj-$(CONFIG_MFD_MAX8925) += max8925.o obj-$(CONFIG_MFD_MAX8925) += max8925.o
obj-$(CONFIG_MFD_MAX8998) += max8998.o
pcf50633-objs := pcf50633-core.o pcf50633-irq.o pcf50633-objs := pcf50633-core.o pcf50633-irq.o
obj-$(CONFIG_MFD_PCF50633) += pcf50633.o obj-$(CONFIG_MFD_PCF50633) += pcf50633.o
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include <linux/platform_device.h> #include <linux/platform_device.h>
#include <linux/mfd/core.h> #include <linux/mfd/core.h>
#include <linux/mfd/ab8500.h> #include <linux/mfd/ab8500.h>
#include <linux/regulator/ab8500.h>
/* /*
* Interrupt register offsets * Interrupt register offsets
...@@ -352,6 +353,7 @@ static struct mfd_cell ab8500_devs[] = { ...@@ -352,6 +353,7 @@ static struct mfd_cell ab8500_devs[] = {
{ .name = "ab8500-audio", }, { .name = "ab8500-audio", },
{ .name = "ab8500-usb", }, { .name = "ab8500-usb", },
{ .name = "ab8500-pwm", }, { .name = "ab8500-pwm", },
{ .name = "ab8500-regulator", },
}; };
int __devinit ab8500_init(struct ab8500 *ab8500) int __devinit ab8500_init(struct ab8500 *ab8500)
...@@ -411,7 +413,7 @@ int __devinit ab8500_init(struct ab8500 *ab8500) ...@@ -411,7 +413,7 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
goto out_removeirq; goto out_removeirq;
} }
ret = mfd_add_devices(ab8500->dev, -1, ab8500_devs, ret = mfd_add_devices(ab8500->dev, 0, ab8500_devs,
ARRAY_SIZE(ab8500_devs), NULL, ARRAY_SIZE(ab8500_devs), NULL,
ab8500->irq_base); ab8500->irq_base);
if (ret) if (ret)
......
/*
* max8698.c - mfd core driver for the Maxim 8998
*
* Copyright (C) 2009-2010 Samsung Electronics
* Kyungmin Park <kyungmin.park@samsung.com>
* Marek Szyprowski <m.szyprowski@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/mutex.h>
#include <linux/mfd/core.h>
#include <linux/mfd/max8998.h>
#include <linux/mfd/max8998-private.h>
static struct mfd_cell max8998_devs[] = {
{
.name = "max8998-pmic",
}
};
static int max8998_i2c_device_read(struct max8998_dev *max8998, u8 reg, u8 *dest)
{
struct i2c_client *client = max8998->i2c_client;
int ret;
mutex_lock(&max8998->iolock);
ret = i2c_smbus_read_byte_data(client, reg);
mutex_unlock(&max8998->iolock);
if (ret < 0)
return ret;
ret &= 0xff;
*dest = ret;
return 0;
}
static int max8998_i2c_device_write(struct max8998_dev *max8998, u8 reg, u8 value)
{
struct i2c_client *client = max8998->i2c_client;
int ret;
mutex_lock(&max8998->iolock);
ret = i2c_smbus_write_byte_data(client, reg, value);
mutex_unlock(&max8998->iolock);
return ret;
}
static int max8998_i2c_device_update(struct max8998_dev *max8998, u8 reg,
u8 val, u8 mask)
{
struct i2c_client *client = max8998->i2c_client;
int ret;
mutex_lock(&max8998->iolock);
ret = i2c_smbus_read_byte_data(client, reg);
if (ret >= 0) {
u8 old_val = ret & 0xff;
u8 new_val = (val & mask) | (old_val & (~mask));
ret = i2c_smbus_write_byte_data(client, reg, new_val);
if (ret >= 0)
ret = 0;
}
mutex_unlock(&max8998->iolock);
return ret;
}
static int max8998_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct max8998_dev *max8998;
int ret = 0;
max8998 = kzalloc(sizeof(struct max8998_dev), GFP_KERNEL);
if (max8998 == NULL)
return -ENOMEM;
i2c_set_clientdata(i2c, max8998);
max8998->dev = &i2c->dev;
max8998->i2c_client = i2c;
max8998->dev_read = max8998_i2c_device_read;
max8998->dev_write = max8998_i2c_device_write;
max8998->dev_update = max8998_i2c_device_update;
mutex_init(&max8998->iolock);
ret = mfd_add_devices(max8998->dev, -1,
max8998_devs, ARRAY_SIZE(max8998_devs),
NULL, 0);
if (ret < 0)
goto err;
return ret;
err:
mfd_remove_devices(max8998->dev);
kfree(max8998);
return ret;
}
static int max8998_i2c_remove(struct i2c_client *i2c)
{
struct max8998_dev *max8998 = i2c_get_clientdata(i2c);
mfd_remove_devices(max8998->dev);
kfree(max8998);
return 0;
}
static const struct i2c_device_id max8998_i2c_id[] = {
{ "max8998", 0 },
{ }
};
MODULE_DEVICE_TABLE(i2c, max8998_i2c_id);
static struct i2c_driver max8998_i2c_driver = {
.driver = {
.name = "max8998",
.owner = THIS_MODULE,
},
.probe = max8998_i2c_probe,
.remove = max8998_i2c_remove,
.id_table = max8998_i2c_id,
};
static int __init max8998_i2c_init(void)
{
return i2c_add_driver(&max8998_i2c_driver);
}
/* init early so consumer devices can complete system boot */
subsys_initcall(max8998_i2c_init);
static void __exit max8998_i2c_exit(void)
{
i2c_del_driver(&max8998_i2c_driver);
}
module_exit(max8998_i2c_exit);
MODULE_DESCRIPTION("MAXIM 8998 multi-function core driver");
MODULE_AUTHOR("Kyungmin Park <kyungmin.park@samsung.com>");
MODULE_LICENSE("GPL");
...@@ -100,6 +100,14 @@ config REGULATOR_MAX8925 ...@@ -100,6 +100,14 @@ config REGULATOR_MAX8925
help help
Say y here to support the voltage regulaltor of Maxim MAX8925 PMIC. Say y here to support the voltage regulaltor of Maxim MAX8925 PMIC.
config REGULATOR_MAX8998
tristate "Maxim 8998 voltage regulator"
depends on MFD_MAX8998
help
This driver controls a Maxim 8998 voltage output regulator
via I2C bus. The provided regulator is suitable for S3C6410
and S5PC1XX chips to control VCC_CORE and VCC_USIM voltages.
config REGULATOR_TWL4030 config REGULATOR_TWL4030
bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC" bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC"
depends on TWL4030_CORE depends on TWL4030_CORE
...@@ -201,5 +209,31 @@ config REGULATOR_88PM8607 ...@@ -201,5 +209,31 @@ config REGULATOR_88PM8607
help help
This driver supports 88PM8607 voltage regulator chips. This driver supports 88PM8607 voltage regulator chips.
config REGULATOR_ISL6271A
tristate "Intersil ISL6271A Power regulator"
depends on I2C
help
This driver supports ISL6271A voltage regulator chip.
config REGULATOR_AD5398
tristate "Analog Devices AD5398/AD5821 regulators"
depends on I2C
help
This driver supports AD5398 and AD5821 current regulator chips.
If building into module, its name is ad5398.ko.
config REGULATOR_AB8500
bool "ST-Ericsson AB8500 Power Regulators"
depends on AB8500_CORE
help
This driver supports the regulators found on the ST-Ericsson mixed
signal AB8500 PMIC
config REGULATOR_TPS6586X
tristate "TI TPS6586X Power regulators"
depends on MFD_TPS6586X
help
This driver supports TPS6586X voltage regulator chips.
endif endif
...@@ -8,6 +8,7 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o ...@@ -8,6 +8,7 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o
obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
obj-$(CONFIG_REGULATOR_DUMMY) += dummy.o obj-$(CONFIG_REGULATOR_DUMMY) += dummy.o
obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
...@@ -16,12 +17,14 @@ obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o ...@@ -16,12 +17,14 @@ obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o obj-$(CONFIG_REGULATOR_MAX8660) += max8660.o
obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o obj-$(CONFIG_REGULATOR_MAX8925) += max8925-regulator.o
obj-$(CONFIG_REGULATOR_MAX8998) += max8998.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-dcdc.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-isink.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o obj-$(CONFIG_REGULATOR_WM8400) += wm8400-regulator.o
obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o obj-$(CONFIG_REGULATOR_WM8994) += wm8994-regulator.o
obj-$(CONFIG_REGULATOR_TPS6586X) += tps6586x-regulator.o
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o obj-$(CONFIG_REGULATOR_PCF50633) += pcf50633-regulator.o
obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
...@@ -31,5 +34,7 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o ...@@ -31,5 +34,7 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.o
obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
This diff is collapsed.
/*
* Voltage and current regulation for AD5398 and AD5821
*
* Copyright 2010 Analog Devices Inc.
*
* Enter bugs at http://blackfin.uclinux.org/
*
* Licensed under the GPL-2 or later.
*/
#include <linux/module.h>
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#define AD5398_CURRENT_EN_MASK 0x8000
struct ad5398_chip_info {
struct i2c_client *client;
int min_uA;
int max_uA;
unsigned int current_level;
unsigned int current_mask;
unsigned int current_offset;
struct regulator_dev rdev;
};
static int ad5398_calc_current(struct ad5398_chip_info *chip,
unsigned selector)
{
unsigned range_uA = chip->max_uA - chip->min_uA;
return chip->min_uA + (selector * range_uA / chip->current_level);
}
static int ad5398_read_reg(struct i2c_client *client, unsigned short *data)
{
unsigned short val;
int ret;
ret = i2c_master_recv(client, (char *)&val, 2);
if (ret < 0) {
dev_err(&client->dev, "I2C read error\n");
return ret;
}
*data = be16_to_cpu(val);
return ret;
}
static int ad5398_write_reg(struct i2c_client *client, const unsigned short data)
{
unsigned short val;
int ret;
val = cpu_to_be16(data);
ret = i2c_master_send(client, (char *)&val, 2);
if (ret < 0)
dev_err(&client->dev, "I2C write error\n");
return ret;
}
static int ad5398_get_current_limit(struct regulator_dev *rdev)
{
struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
struct i2c_client *client = chip->client;
unsigned short data;
int ret;
ret = ad5398_read_reg(client, &data);
if (ret < 0)
return ret;
ret = (data & chip->current_mask) >> chip->current_offset;
return ad5398_calc_current(chip, ret);
}
static int ad5398_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA)
{
struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
struct i2c_client *client = chip->client;
unsigned range_uA = chip->max_uA - chip->min_uA;
unsigned selector;
unsigned short data;
int ret;
if (min_uA > chip->max_uA || min_uA < chip->min_uA)
return -EINVAL;
if (max_uA > chip->max_uA || max_uA < chip->min_uA)
return -EINVAL;
selector = ((min_uA - chip->min_uA) * chip->current_level +
range_uA - 1) / range_uA;
if (ad5398_calc_current(chip, selector) > max_uA)
return -EINVAL;
dev_dbg(&client->dev, "changing current %dmA\n",
ad5398_calc_current(chip, selector) / 1000);
/* read chip enable bit */
ret = ad5398_read_reg(client, &data);
if (ret < 0)
return ret;
/* prepare register data */
selector = (selector << chip->current_offset) & chip->current_mask;
data = (unsigned short)selector | (data & AD5398_CURRENT_EN_MASK);
/* write the new current value back as well as enable bit */
ret = ad5398_write_reg(client, data);
return ret;
}
static int ad5398_is_enabled(struct regulator_dev *rdev)
{
struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
struct i2c_client *client = chip->client;
unsigned short data;
int ret;
ret = ad5398_read_reg(client, &data);
if (ret < 0)
return ret;
if (data & AD5398_CURRENT_EN_MASK)
return 1;
else
return 0;
}
static int ad5398_enable(struct regulator_dev *rdev)
{
struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
struct i2c_client *client = chip->client;
unsigned short data;
int ret;
ret = ad5398_read_reg(client, &data);
if (ret < 0)
return ret;
if (data & AD5398_CURRENT_EN_MASK)
return 0;
data |= AD5398_CURRENT_EN_MASK;
ret = ad5398_write_reg(client, data);
return ret;
}
static int ad5398_disable(struct regulator_dev *rdev)
{
struct ad5398_chip_info *chip = rdev_get_drvdata(rdev);
struct i2c_client *client = chip->client;
unsigned short data;
int ret;
ret = ad5398_read_reg(client, &data);
if (ret < 0)
return ret;
if (!(data & AD5398_CURRENT_EN_MASK))
return 0;
data &= ~AD5398_CURRENT_EN_MASK;
ret = ad5398_write_reg(client, data);
return ret;
}
static struct regulator_ops ad5398_ops = {
.get_current_limit = ad5398_get_current_limit,
.set_current_limit = ad5398_set_current_limit,
.enable = ad5398_enable,
.disable = ad5398_disable,
.is_enabled = ad5398_is_enabled,
};
static struct regulator_desc ad5398_reg = {
.name = "isink",
.id = 0,
.ops = &ad5398_ops,
.type = REGULATOR_CURRENT,
.owner = THIS_MODULE,
};
struct ad5398_current_data_format {
int current_bits;
int current_offset;
int min_uA;
int max_uA;
};
static const struct ad5398_current_data_format df_10_4_120 = {10, 4, 0, 120000};
static const struct i2c_device_id ad5398_id[] = {
{ "ad5398", (kernel_ulong_t)&df_10_4_120 },
{ "ad5821", (kernel_ulong_t)&df_10_4_120 },
{ }
};
MODULE_DEVICE_TABLE(i2c, ad5398_id);
static int __devinit ad5398_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct regulator_dev *rdev;
struct regulator_init_data *init_data = client->dev.platform_data;
struct ad5398_chip_info *chip;
const struct ad5398_current_data_format *df =
(struct ad5398_current_data_format *)id->driver_data;
int ret;
if (!init_data)
return -EINVAL;
chip = kzalloc(sizeof(*chip), GFP_KERNEL);
if (!chip)
return -ENOMEM;
chip->client = client;
chip->min_uA = df->min_uA;
chip->max_uA = df->max_uA;
chip->current_level = 1 << df->current_bits;
chip->current_offset = df->current_offset;
chip->current_mask = (chip->current_level - 1) << chip->current_offset;
rdev = regulator_register(&ad5398_reg, &client->dev, init_data, chip);
if (IS_ERR(rdev)) {
ret = PTR_ERR(rdev);
dev_err(&client->dev, "failed to register %s %s\n",
id->name, ad5398_reg.name);
goto err;
}
i2c_set_clientdata(client, chip);
dev_dbg(&client->dev, "%s regulator driver is registered.\n", id->name);
return 0;
err:
kfree(chip);
return ret;
}
static int __devexit ad5398_remove(struct i2c_client *client)
{
struct ad5398_chip_info *chip = i2c_get_clientdata(client);
regulator_unregister(&chip->rdev);
kfree(chip);
i2c_set_clientdata(client, NULL);
return 0;
}
static struct i2c_driver ad5398_driver = {
.probe = ad5398_probe,
.remove = __devexit_p(ad5398_remove),
.driver = {
.name = "ad5398",
},
.id_table = ad5398_id,
};
static int __init ad5398_init(void)
{
return i2c_add_driver(&ad5398_driver);
}
subsys_initcall(ad5398_init);
static void __exit ad5398_exit(void)
{
i2c_del_driver(&ad5398_driver);
}
module_exit(ad5398_exit);
MODULE_DESCRIPTION("AD5398 and AD5821 current regulator driver");
MODULE_AUTHOR("Sonic Zhang");
MODULE_LICENSE("GPL");
MODULE_ALIAS("i2c:ad5398-regulator");
/*
* isl6271a-regulator.c
*
* Support for Intersil ISL6271A voltage regulator
*
* Copyright (C) 2010 Marek Vasut <marek.vasut@gmail.com>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation version 2.
*
* This program is distributed "as is" WITHOUT ANY WARRANTY of any kind,
* whether express or implied; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* General Public License for more details.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/i2c.h>
#include <linux/delay.h>
#include <linux/slab.h>
#define ISL6271A_VOLTAGE_MIN 850000
#define ISL6271A_VOLTAGE_MAX 1600000
#define ISL6271A_VOLTAGE_STEP 50000
/* PMIC details */
struct isl_pmic {
struct i2c_client *client;
struct regulator_dev *rdev[3];
struct mutex mtx;
};
static int isl6271a_get_voltage(struct regulator_dev *dev)
{
struct isl_pmic *pmic = rdev_get_drvdata(dev);
int idx, data;
mutex_lock(&pmic->mtx);
idx = i2c_smbus_read_byte(pmic->client);
if (idx < 0) {
dev_err(&pmic->client->dev, "Error getting voltage\n");
data = idx;
goto out;
}
/* Convert the data from chip to microvolts */
data = ISL6271A_VOLTAGE_MIN + (ISL6271A_VOLTAGE_STEP * (idx & 0xf));
out:
mutex_unlock(&pmic->mtx);
return data;
}
static int isl6271a_set_voltage(struct regulator_dev *dev, int minuV, int maxuV)
{
struct isl_pmic *pmic = rdev_get_drvdata(dev);
int vsel, err, data;
if (minuV < ISL6271A_VOLTAGE_MIN || minuV > ISL6271A_VOLTAGE_MAX)
return -EINVAL;
if (maxuV < ISL6271A_VOLTAGE_MIN || maxuV > ISL6271A_VOLTAGE_MAX)
return -EINVAL;
/* Align to 50000 mV */
vsel = minuV - (minuV % ISL6271A_VOLTAGE_STEP);
/* If the result fell out of [minuV,maxuV] range, put it back */
if (vsel < minuV)
vsel += ISL6271A_VOLTAGE_STEP;
/* Convert the microvolts to data for the chip */
data = (vsel - ISL6271A_VOLTAGE_MIN) / ISL6271A_VOLTAGE_STEP;
mutex_lock(&pmic->mtx);
err = i2c_smbus_write_byte(pmic->client, data);
if (err < 0)
dev_err(&pmic->client->dev, "Error setting voltage\n");
mutex_unlock(&pmic->mtx);
return err;
}
static int isl6271a_list_voltage(struct regulator_dev *dev, unsigned selector)
{
return ISL6271A_VOLTAGE_MIN + (ISL6271A_VOLTAGE_STEP * selector);
}
static struct regulator_ops isl_core_ops = {
.get_voltage = isl6271a_get_voltage,
.set_voltage = isl6271a_set_voltage,
.list_voltage = isl6271a_list_voltage,
};
static int isl6271a_get_fixed_voltage(struct regulator_dev *dev)
{
int id = rdev_get_id(dev);
return (id == 1) ? 1100000 : 1300000;
}
static int isl6271a_list_fixed_voltage(struct regulator_dev *dev, unsigned selector)
{
int id = rdev_get_id(dev);
return (id == 1) ? 1100000 : 1300000;
}
static struct regulator_ops isl_fixed_ops = {
.get_voltage = isl6271a_get_fixed_voltage,
.list_voltage = isl6271a_list_fixed_voltage,
};
static struct regulator_desc isl_rd[] = {
{
.name = "Core Buck",
.id = 0,
.n_voltages = 16,
.ops = &isl_core_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO1",
.id = 1,
.n_voltages = 1,
.ops = &isl_fixed_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
}, {
.name = "LDO2",
.id = 2,
.n_voltages = 1,
.ops = &isl_fixed_ops,
.type = REGULATOR_VOLTAGE,
.owner = THIS_MODULE,
},
};
static int __devinit isl6271a_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct regulator_init_data *init_data = i2c->dev.platform_data;
struct isl_pmic *pmic;
int err, i;
if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
return -EIO;
if (!init_data) {
dev_err(&i2c->dev, "no platform data supplied\n");
return -EIO;
}
pmic = kzalloc(sizeof(struct isl_pmic), GFP_KERNEL);
if (!pmic)
return -ENOMEM;
pmic->client = i2c;
mutex_init(&pmic->mtx);
for (i = 0; i < 3; i++) {
pmic->rdev[i] = regulator_register(&isl_rd[0], &i2c->dev,
init_data, pmic);
if (IS_ERR(pmic->rdev[i])) {
dev_err(&i2c->dev, "failed to register %s\n", id->name);
err = PTR_ERR(pmic->rdev);
goto error;
}
}
i2c_set_clientdata(i2c, pmic);
return 0;
error:
while (--i >= 0)
regulator_unregister(pmic->rdev[i]);
kfree(pmic);
return err;
}
static int __devexit isl6271a_remove(struct i2c_client *i2c)
{
struct isl_pmic *pmic = i2c_get_clientdata(i2c);
int i;
i2c_set_clientdata(i2c, NULL);
for (i = 0; i < 3; i++)
regulator_unregister(pmic->rdev[i]);
kfree(pmic);
return 0;
}
static const struct i2c_device_id isl6271a_id[] = {
{.name = "isl6271a", 0 },
{ },
};
MODULE_DEVICE_TABLE(i2c, isl6271a_id);
static struct i2c_driver isl6271a_i2c_driver = {
.driver = {
.name = "isl6271a",
.owner = THIS_MODULE,
},
.probe = isl6271a_probe,
.remove = __devexit_p(isl6271a_remove),
.id_table = isl6271a_id,
};
static int __init isl6271a_init(void)
{
return i2c_add_driver(&isl6271a_i2c_driver);
}
static void __exit isl6271a_cleanup(void)
{
i2c_del_driver(&isl6271a_i2c_driver);
}
subsys_initcall(isl6271a_init);
module_exit(isl6271a_cleanup);
MODULE_AUTHOR("Marek Vasut <marek.vasut@gmail.com>");
MODULE_DESCRIPTION("Intersil ISL6271A voltage regulator driver");
MODULE_LICENSE("GPL v2");
...@@ -377,7 +377,7 @@ static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count, ...@@ -377,7 +377,7 @@ static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count,
if (count != 1) if (count != 1)
return -EIO; return -EIO;
ret = i2c_smbus_read_byte_data(i2c, reg); ret = i2c_smbus_read_byte_data(i2c, reg);
if (ret < 0 || count != 1) if (ret < 0)
return -EIO; return -EIO;
*dest = ret; *dest = ret;
...@@ -387,15 +387,9 @@ static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count, ...@@ -387,15 +387,9 @@ static int lp3971_i2c_read(struct i2c_client *i2c, char reg, int count,
static int lp3971_i2c_write(struct i2c_client *i2c, char reg, int count, static int lp3971_i2c_write(struct i2c_client *i2c, char reg, int count,
const u16 *src) const u16 *src)
{ {
int ret;
if (count != 1) if (count != 1)
return -EIO; return -EIO;
ret = i2c_smbus_write_byte_data(i2c, reg, *src); return i2c_smbus_write_byte_data(i2c, reg, *src);
if (ret >= 0)
return 0;
return ret;
} }
static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg) static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg)
......
...@@ -223,7 +223,7 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client, ...@@ -223,7 +223,7 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
} }
} }
i2c_set_clientdata(client, rdev); i2c_set_clientdata(client, max1586);
dev_info(&client->dev, "Maxim 1586 regulator driver loaded\n"); dev_info(&client->dev, "Maxim 1586 regulator driver loaded\n");
return 0; return 0;
...@@ -238,13 +238,13 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client, ...@@ -238,13 +238,13 @@ static int __devinit max1586_pmic_probe(struct i2c_client *client,
static int __devexit max1586_pmic_remove(struct i2c_client *client) static int __devexit max1586_pmic_remove(struct i2c_client *client)
{ {
struct regulator_dev **rdev = i2c_get_clientdata(client); struct max1586_data *max1586 = i2c_get_clientdata(client);
int i; int i;
for (i = 0; i <= MAX1586_V6; i++) for (i = 0; i <= MAX1586_V6; i++)
if (rdev[i]) if (max1586->rdev[i])
regulator_unregister(rdev[i]); regulator_unregister(max1586->rdev[i]);
kfree(rdev); kfree(max1586);
return 0; return 0;
} }
......
...@@ -450,7 +450,7 @@ static int __devinit max8660_probe(struct i2c_client *client, ...@@ -450,7 +450,7 @@ static int __devinit max8660_probe(struct i2c_client *client,
} }
} }
i2c_set_clientdata(client, rdev); i2c_set_clientdata(client, max8660);
dev_info(&client->dev, "Maxim 8660/8661 regulator driver loaded\n"); dev_info(&client->dev, "Maxim 8660/8661 regulator driver loaded\n");
return 0; return 0;
...@@ -465,13 +465,13 @@ static int __devinit max8660_probe(struct i2c_client *client, ...@@ -465,13 +465,13 @@ static int __devinit max8660_probe(struct i2c_client *client,
static int __devexit max8660_remove(struct i2c_client *client) static int __devexit max8660_remove(struct i2c_client *client)
{ {
struct regulator_dev **rdev = i2c_get_clientdata(client); struct max8660 *max8660 = i2c_get_clientdata(client);
int i; int i;
for (i = 0; i < MAX8660_V_END; i++) for (i = 0; i < MAX8660_V_END; i++)
if (rdev[i]) if (max8660->rdev[i])
regulator_unregister(rdev[i]); regulator_unregister(max8660->rdev[i]);
kfree(rdev); kfree(max8660);
return 0; return 0;
} }
......
This diff is collapsed.
...@@ -585,6 +585,8 @@ static const struct tps_info tps65023_regs[] = { ...@@ -585,6 +585,8 @@ static const struct tps_info tps65023_regs[] = {
static const struct i2c_device_id tps_65023_id[] = { static const struct i2c_device_id tps_65023_id[] = {
{.name = "tps65023", {.name = "tps65023",
.driver_data = (unsigned long) tps65023_regs,}, .driver_data = (unsigned long) tps65023_regs,},
{.name = "tps65021",
.driver_data = (unsigned long) tps65023_regs,},
{ }, { },
}; };
......
...@@ -614,6 +614,7 @@ int tps6507x_pmic_probe(struct platform_device *pdev) ...@@ -614,6 +614,7 @@ int tps6507x_pmic_probe(struct platform_device *pdev)
} }
tps6507x_dev->pmic = tps; tps6507x_dev->pmic = tps;
platform_set_drvdata(pdev, tps6507x_dev);
return 0; return 0;
......
This diff is collapsed.
...@@ -219,8 +219,6 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev) ...@@ -219,8 +219,6 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
ldo->wm8994 = wm8994; ldo->wm8994 = wm8994;
ldo->is_enabled = true;
if (pdata->ldo[id].enable && gpio_is_valid(pdata->ldo[id].enable)) { if (pdata->ldo[id].enable && gpio_is_valid(pdata->ldo[id].enable)) {
ldo->enable = pdata->ldo[id].enable; ldo->enable = pdata->ldo[id].enable;
...@@ -237,7 +235,8 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev) ...@@ -237,7 +235,8 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
ret); ret);
goto err_gpio; goto err_gpio;
} }
} } else
ldo->is_enabled = true;
ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &pdev->dev, ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &pdev->dev,
pdata->ldo[id].init_data, ldo); pdata->ldo[id].init_data, ldo);
......
...@@ -76,6 +76,8 @@ ...@@ -76,6 +76,8 @@
#define AB8500_NR_IRQS 104 #define AB8500_NR_IRQS 104
#define AB8500_NUM_IRQ_REGS 13 #define AB8500_NUM_IRQ_REGS 13
#define AB8500_NUM_REGULATORS 15
/** /**
* struct ab8500 - ab8500 internal structure * struct ab8500 - ab8500 internal structure
* @dev: parent device * @dev: parent device
...@@ -108,14 +110,18 @@ struct ab8500 { ...@@ -108,14 +110,18 @@ struct ab8500 {
u8 oldmask[AB8500_NUM_IRQ_REGS]; u8 oldmask[AB8500_NUM_IRQ_REGS];
}; };
struct regulator_init_data;
/** /**
* struct ab8500_platform_data - AB8500 platform data * struct ab8500_platform_data - AB8500 platform data
* @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used * @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used
* @init: board-specific initialization after detection of ab8500 * @init: board-specific initialization after detection of ab8500
* @regulator: machine-specific constraints for regulators
*/ */
struct ab8500_platform_data { struct ab8500_platform_data {
int irq_base; int irq_base;
void (*init) (struct ab8500 *); void (*init) (struct ab8500 *);
struct regulator_init_data *regulator[AB8500_NUM_REGULATORS];
}; };
extern int ab8500_write(struct ab8500 *a8500, u16 addr, u8 data); extern int ab8500_write(struct ab8500 *a8500, u16 addr, u8 data);
......
/*
* max8698.h - Voltage regulator driver for the Maxim 8998
*
* Copyright (C) 2009-2010 Samsung Electrnoics
* Kyungmin Park <kyungmin.park@samsung.com>
* Marek Szyprowski <m.szyprowski@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __LINUX_MFD_MAX8998_PRIV_H
#define __LINUX_MFD_MAX8998_PRIV_H
/* MAX 8998 registers */
enum {
MAX8998_REG_IRQ1,
MAX8998_REG_IRQ2,
MAX8998_REG_IRQ3,
MAX8998_REG_IRQ4,
MAX8998_REG_IRQM1,
MAX8998_REG_IRQM2,
MAX8998_REG_IRQM3,
MAX8998_REG_IRQM4,
MAX8998_REG_STATUS1,
MAX8998_REG_STATUS2,
MAX8998_REG_STATUSM1,
MAX8998_REG_STATUSM2,
MAX8998_REG_CHGR1,
MAX8998_REG_CHGR2,
MAX8998_REG_LDO_ACTIVE_DISCHARGE1,
MAX8998_REG_LDO_ACTIVE_DISCHARGE2,
MAX8998_REG_BUCK_ACTIVE_DISCHARGE3,
MAX8998_REG_ONOFF1,
MAX8998_REG_ONOFF2,
MAX8998_REG_ONOFF3,
MAX8998_REG_ONOFF4,
MAX8998_REG_BUCK1_DVSARM1,
MAX8998_REG_BUCK1_DVSARM2,
MAX8998_REG_BUCK1_DVSARM3,
MAX8998_REG_BUCK1_DVSARM4,
MAX8998_REG_BUCK2_DVSINT1,
MAX8998_REG_BUCK2_DVSINT2,
MAX8998_REG_BUCK3,
MAX8998_REG_BUCK4,
MAX8998_REG_LDO2_LDO3,
MAX8998_REG_LDO4,
MAX8998_REG_LDO5,
MAX8998_REG_LDO6,
MAX8998_REG_LDO7,
MAX8998_REG_LDO8_LDO9,
MAX8998_REG_LDO10_LDO11,
MAX8998_REG_LDO12,
MAX8998_REG_LDO13,
MAX8998_REG_LDO14,
MAX8998_REG_LDO15,
MAX8998_REG_LDO16,
MAX8998_REG_LDO17,
MAX8998_REG_BKCHR,
MAX8998_REG_LBCNFG1,
MAX8998_REG_LBCNFG2,
};
/**
* struct max8998_dev - max8998 master device for sub-drivers
* @dev: master device of the chip (can be used to access platform data)
* @i2c_client: i2c client private data
* @dev_read(): chip register read function
* @dev_write(): chip register write function
* @dev_update(): chip register update function
* @iolock: mutex for serializing io access
*/
struct max8998_dev {
struct device *dev;
struct i2c_client *i2c_client;
int (*dev_read)(struct max8998_dev *max8998, u8 reg, u8 *dest);
int (*dev_write)(struct max8998_dev *max8998, u8 reg, u8 val);
int (*dev_update)(struct max8998_dev *max8998, u8 reg, u8 val, u8 mask);
struct mutex iolock;
};
static inline int max8998_read_reg(struct max8998_dev *max8998, u8 reg,
u8 *value)
{
return max8998->dev_read(max8998, reg, value);
}
static inline int max8998_write_reg(struct max8998_dev *max8998, u8 reg,
u8 value)
{
return max8998->dev_write(max8998, reg, value);
}
static inline int max8998_update_reg(struct max8998_dev *max8998, u8 reg,
u8 value, u8 mask)
{
return max8998->dev_update(max8998, reg, value, mask);
}
#endif /* __LINUX_MFD_MAX8998_PRIV_H */
/*
* max8698.h - Voltage regulator driver for the Maxim 8998
*
* Copyright (C) 2009-2010 Samsung Electrnoics
* Kyungmin Park <kyungmin.park@samsung.com>
* Marek Szyprowski <m.szyprowski@samsung.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
#ifndef __LINUX_MFD_MAX8998_H
#define __LINUX_MFD_MAX8998_H
#include <linux/regulator/machine.h>
/* MAX 8998 regulator ids */
enum {
MAX8998_LDO2 = 2,
MAX8998_LDO3,
MAX8998_LDO4,
MAX8998_LDO5,
MAX8998_LDO6,
MAX8998_LDO7,
MAX8998_LDO8,
MAX8998_LDO9,
MAX8998_LDO10,
MAX8998_LDO11,
MAX8998_LDO12,
MAX8998_LDO13,
MAX8998_LDO14,
MAX8998_LDO15,
MAX8998_LDO16,
MAX8998_LDO17,
MAX8998_BUCK1,
MAX8998_BUCK2,
MAX8998_BUCK3,
MAX8998_BUCK4,
MAX8998_EN32KHZ_AP,
MAX8998_EN32KHZ_CP,
MAX8998_ENVICHG,
MAX8998_ESAFEOUT1,
MAX8998_ESAFEOUT2,
};
/**
* max8998_regulator_data - regulator data
* @id: regulator id
* @initdata: regulator init data (contraints, supplies, ...)
*/
struct max8998_regulator_data {
int id;
struct regulator_init_data *initdata;
};
/**
* struct max8998_board - packages regulator init data
* @num_regulators: number of regultors used
* @regulators: array of defined regulators
*/
struct max8998_platform_data {
int num_regulators;
struct max8998_regulator_data *regulators;
};
#endif /* __LINUX_MFD_MAX8998_H */
/*
* Copyright (C) ST-Ericsson SA 2010
*
* License Terms: GNU General Public License v2
*
* Author: Sundar Iyer <sundar.iyer@stericsson.com> for ST-Ericsson
*
*/
#ifndef __LINUX_MFD_AB8500_REGULATOR_H
#define __LINUX_MFD_AB8500_REGULATOR_H
/* AB8500 regulators */
#define AB8500_LDO_AUX1 0
#define AB8500_LDO_AUX2 1
#define AB8500_LDO_AUX3 2
#define AB8500_LDO_INTCORE 3
#define AB8500_LDO_TVOUT 4
#define AB8500_LDO_AUDIO 5
#define AB8500_LDO_ANAMIC1 6
#define AB8500_LDO_ANAMIC2 7
#define AB8500_LDO_DMIC 8
#define AB8500_LDO_ANA 9
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment