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
accessing the device, additional drivers must be enabled in order
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
tristate "Support Wolfson Microelectronics WM8400"
select MFD_CORE
......
......@@ -58,6 +58,7 @@ obj-$(CONFIG_UCB1400_CORE) += ucb1400_core.o
obj-$(CONFIG_PMIC_DA903X) += da903x.o
max8925-objs := max8925-core.o max8925-i2c.o
obj-$(CONFIG_MFD_MAX8925) += max8925.o
obj-$(CONFIG_MFD_MAX8998) += max8998.o
pcf50633-objs := pcf50633-core.o pcf50633-irq.o
obj-$(CONFIG_MFD_PCF50633) += pcf50633.o
......
......@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include <linux/mfd/core.h>
#include <linux/mfd/ab8500.h>
#include <linux/regulator/ab8500.h>
/*
* Interrupt register offsets
......@@ -352,6 +353,7 @@ static struct mfd_cell ab8500_devs[] = {
{ .name = "ab8500-audio", },
{ .name = "ab8500-usb", },
{ .name = "ab8500-pwm", },
{ .name = "ab8500-regulator", },
};
int __devinit ab8500_init(struct ab8500 *ab8500)
......@@ -411,7 +413,7 @@ int __devinit ab8500_init(struct ab8500 *ab8500)
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,
ab8500->irq_base);
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
help
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
bool "TI TWL4030/TWL5030/TWL6030/TPS695x0 PMIC"
depends on TWL4030_CORE
......@@ -201,5 +209,31 @@ config REGULATOR_88PM8607
help
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
......@@ -8,6 +8,7 @@ obj-$(CONFIG_REGULATOR_FIXED_VOLTAGE) += fixed.o
obj-$(CONFIG_REGULATOR_VIRTUAL_CONSUMER) += virtual.o
obj-$(CONFIG_REGULATOR_USERSPACE_CONSUMER) += userspace-consumer.o
obj-$(CONFIG_REGULATOR_AD5398) += ad5398.o
obj-$(CONFIG_REGULATOR_BQ24022) += bq24022.o
obj-$(CONFIG_REGULATOR_DUMMY) += dummy.o
obj-$(CONFIG_REGULATOR_LP3971) += lp3971.o
......@@ -16,12 +17,14 @@ obj-$(CONFIG_REGULATOR_TWL4030) += twl-regulator.o
obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
obj-$(CONFIG_REGULATOR_MAX8660) += max8660.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-isink.o
obj-$(CONFIG_REGULATOR_WM831X) += wm831x-ldo.o
obj-$(CONFIG_REGULATOR_WM8350) += wm8350-regulator.o
obj-$(CONFIG_REGULATOR_WM8400) += wm8400-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_PCF50633) += pcf50633-regulator.o
obj-$(CONFIG_REGULATOR_PCAP) += pcap-regulator.o
......@@ -31,5 +34,7 @@ obj-$(CONFIG_REGULATOR_AB3100) += ab3100.o
obj-$(CONFIG_REGULATOR_TPS65023) += tps65023-regulator.o
obj-$(CONFIG_REGULATOR_TPS6507X) += tps6507x-regulator.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
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,
if (count != 1)
return -EIO;
ret = i2c_smbus_read_byte_data(i2c, reg);
if (ret < 0 || count != 1)
if (ret < 0)
return -EIO;
*dest = ret;
......@@ -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,
const u16 *src)
{
int ret;
if (count != 1)
return -EIO;
ret = i2c_smbus_write_byte_data(i2c, reg, *src);
if (ret >= 0)
return 0;
return ret;
return i2c_smbus_write_byte_data(i2c, reg, *src);
}
static u8 lp3971_reg_read(struct lp3971 *lp3971, u8 reg)
......
......@@ -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");
return 0;
......@@ -238,13 +238,13 @@ static int __devinit max1586_pmic_probe(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;
for (i = 0; i <= MAX1586_V6; i++)
if (rdev[i])
regulator_unregister(rdev[i]);
kfree(rdev);
if (max1586->rdev[i])
regulator_unregister(max1586->rdev[i]);
kfree(max1586);
return 0;
}
......
......@@ -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");
return 0;
......@@ -465,13 +465,13 @@ static int __devinit max8660_probe(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;
for (i = 0; i < MAX8660_V_END; i++)
if (rdev[i])
regulator_unregister(rdev[i]);
kfree(rdev);
if (max8660->rdev[i])
regulator_unregister(max8660->rdev[i]);
kfree(max8660);
return 0;
}
......
This diff is collapsed.
......@@ -585,6 +585,8 @@ static const struct tps_info tps65023_regs[] = {
static const struct i2c_device_id tps_65023_id[] = {
{.name = "tps65023",
.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)
}
tps6507x_dev->pmic = tps;
platform_set_drvdata(pdev, tps6507x_dev);
return 0;
......
This diff is collapsed.
......@@ -219,8 +219,6 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
ldo->wm8994 = wm8994;
ldo->is_enabled = true;
if (pdata->ldo[id].enable && gpio_is_valid(pdata->ldo[id].enable)) {
ldo->enable = pdata->ldo[id].enable;
......@@ -237,7 +235,8 @@ static __devinit int wm8994_ldo_probe(struct platform_device *pdev)
ret);
goto err_gpio;
}
}
} else
ldo->is_enabled = true;
ldo->regulator = regulator_register(&wm8994_ldo_desc[id], &pdev->dev,
pdata->ldo[id].init_data, ldo);
......
......@@ -76,6 +76,8 @@
#define AB8500_NR_IRQS 104
#define AB8500_NUM_IRQ_REGS 13
#define AB8500_NUM_REGULATORS 15
/**
* struct ab8500 - ab8500 internal structure
* @dev: parent device
......@@ -108,14 +110,18 @@ struct ab8500 {
u8 oldmask[AB8500_NUM_IRQ_REGS];
};
struct regulator_init_data;
/**
* struct ab8500_platform_data - AB8500 platform data
* @irq_base: start of AB8500 IRQs, AB8500_NR_IRQS will be used
* @init: board-specific initialization after detection of ab8500
* @regulator: machine-specific constraints for regulators
*/
struct ab8500_platform_data {
int irq_base;
void (*init) (struct ab8500 *);
struct regulator_init_data *regulator[AB8500_NUM_REGULATORS];
};
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