Commit f7fc06e3 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: (42 commits)
  regulator: Fix _regulator_get_voltage if get_voltage callback is NULL
  USB: TWL6025 allow different regulator name
  REGULATOR: TWL6025: add support to twl-regulator
  regulator: twl6030: do not write to _GRP for regulator disable
  regulator: twl6030: do not write to _GRP for regulator enable
  TPS65911: Comparator: Add comparator driver
  TPS65911: Add support for added GPIO lines
  GPIO: TPS65910: Move driver to drivers/gpio/
  TPS65911: Add new irq definitions
  regulator: tps65911: Add new chip version
  MFD: TPS65910: Add support for TPS65911 device
  regulator: Fix off-by-one value range checking for mc13xxx_regulator_get_voltage
  regulator: mc13892: Fix voltage unit in test case.
  regulator: Remove MAX8997_REG_BUCK1DVS/MAX8997_REG_BUCK2DVS/MAX8997_REG_BUCK5DVS macros
  mfd: Fix off-by-one value range checking for tps65910_i2c_write
  regulator: Only apply voltage constraints from consumers that set them
  regulator: If we can't configure optimum mode we're always in the best one
  regulator: max8997: remove useless code
  regulator: Fix memory leak in max8998_pmic_probe failure path
  regulator: Fix desc_id for tps65023/6507x/65910
  ...
parents ea0ca3a8 cb220d16
...@@ -53,11 +53,11 @@ static struct regulator_init_data regulator1_data = { ...@@ -53,11 +53,11 @@ static struct regulator_init_data regulator1_data = {
Regulator-1 supplies power to Regulator-2. This relationship must be registered Regulator-1 supplies power to Regulator-2. This relationship must be registered
with the core so that Regulator-1 is also enabled when Consumer A enables its with the core so that Regulator-1 is also enabled when Consumer A enables its
supply (Regulator-2). The supply regulator is set by the supply_regulator_dev supply (Regulator-2). The supply regulator is set by the supply_regulator
field below:- field below:-
static struct regulator_init_data regulator2_data = { static struct regulator_init_data regulator2_data = {
.supply_regulator_dev = &platform_regulator1_device.dev, .supply_regulator = "regulator_name",
.constraints = { .constraints = {
.min_uV = 1800000, .min_uV = 1800000,
.max_uV = 2000000, .max_uV = 2000000,
......
...@@ -424,4 +424,11 @@ config AB8500_GPIO ...@@ -424,4 +424,11 @@ config AB8500_GPIO
depends on AB8500_CORE && BROKEN depends on AB8500_CORE && BROKEN
help help
Select this to enable the AB8500 IC GPIO driver Select this to enable the AB8500 IC GPIO driver
config GPIO_TPS65910
bool "TPS65910 GPIO"
depends on MFD_TPS65910
help
Select this option to enable GPIO driver for the TPS65910
chip family.
endif endif
...@@ -40,3 +40,4 @@ obj-$(CONFIG_GPIO_SX150X) += sx150x.o ...@@ -40,3 +40,4 @@ obj-$(CONFIG_GPIO_SX150X) += sx150x.o
obj-$(CONFIG_GPIO_VX855) += vx855_gpio.o obj-$(CONFIG_GPIO_VX855) += vx855_gpio.o
obj-$(CONFIG_GPIO_ML_IOH) += ml_ioh_gpio.o obj-$(CONFIG_GPIO_ML_IOH) += ml_ioh_gpio.o
obj-$(CONFIG_AB8500_GPIO) += ab8500-gpio.o obj-$(CONFIG_AB8500_GPIO) += ab8500-gpio.o
obj-$(CONFIG_GPIO_TPS65910) += tps65910-gpio.o
/*
* tps65910-gpio.c -- TI TPS6591x
*
* Copyright 2010 Texas Instruments Inc.
*
* Author: Graeme Gregory <gg@slimlogic.co.uk>
* Author: Jorge Eduardo Candelaria jedu@slimlogic.co.uk>
*
* 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.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/errno.h>
#include <linux/gpio.h>
#include <linux/i2c.h>
#include <linux/mfd/tps65910.h>
static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset)
{
struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio);
uint8_t val;
tps65910->read(tps65910, TPS65910_GPIO0 + offset, 1, &val);
if (val & GPIO_STS_MASK)
return 1;
return 0;
}
static void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset,
int value)
{
struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio);
if (value)
tps65910_set_bits(tps65910, TPS65910_GPIO0 + offset,
GPIO_SET_MASK);
else
tps65910_clear_bits(tps65910, TPS65910_GPIO0 + offset,
GPIO_SET_MASK);
}
static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset,
int value)
{
struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio);
/* Set the initial value */
tps65910_gpio_set(gc, 0, value);
return tps65910_set_bits(tps65910, TPS65910_GPIO0 + offset,
GPIO_CFG_MASK);
}
static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset)
{
struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio);
return tps65910_clear_bits(tps65910, TPS65910_GPIO0 + offset,
GPIO_CFG_MASK);
}
void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base)
{
int ret;
if (!gpio_base)
return;
tps65910->gpio.owner = THIS_MODULE;
tps65910->gpio.label = tps65910->i2c_client->name;
tps65910->gpio.dev = tps65910->dev;
tps65910->gpio.base = gpio_base;
switch(tps65910_chip_id(tps65910)) {
case TPS65910:
tps65910->gpio.ngpio = 6;
case TPS65911:
tps65910->gpio.ngpio = 9;
default:
return;
}
tps65910->gpio.can_sleep = 1;
tps65910->gpio.direction_input = tps65910_gpio_input;
tps65910->gpio.direction_output = tps65910_gpio_output;
tps65910->gpio.set = tps65910_gpio_set;
tps65910->gpio.get = tps65910_gpio_get;
ret = gpiochip_add(&tps65910->gpio);
if (ret)
dev_warn(tps65910->dev, "GPIO registration failed: %d\n", ret);
}
...@@ -719,6 +719,15 @@ config MFD_PM8XXX_IRQ ...@@ -719,6 +719,15 @@ config MFD_PM8XXX_IRQ
This is required to use certain other PM 8xxx features, such as GPIO This is required to use certain other PM 8xxx features, such as GPIO
and MPP. and MPP.
config MFD_TPS65910
bool "TPS65910 Power Management chip"
depends on I2C=y
select MFD_CORE
select GPIO_TPS65910
help
if you say yes here you get support for the TPS65910 series of
Power Management chips.
endif # MFD_SUPPORT endif # MFD_SUPPORT
menu "Multimedia Capabilities Port drivers" menu "Multimedia Capabilities Port drivers"
......
...@@ -93,3 +93,4 @@ obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o ...@@ -93,3 +93,4 @@ obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o
obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o
obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o
obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
obj-$(CONFIG_MFD_TPS65910) += tps65910.o tps65910-irq.o
/*
* tps65910-irq.c -- TI TPS6591x
*
* Copyright 2010 Texas Instruments Inc.
*
* Author: Graeme Gregory <gg@slimlogic.co.uk>
* Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>
*
* 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.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/bug.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/mfd/tps65910.h>
static inline int irq_to_tps65910_irq(struct tps65910 *tps65910,
int irq)
{
return (irq - tps65910->irq_base);
}
/*
* This is a threaded IRQ handler so can access I2C/SPI. Since all
* interrupts are clear on read the IRQ line will be reasserted and
* the physical IRQ will be handled again if another interrupt is
* asserted while we run - in the normal course of events this is a
* rare occurrence so we save I2C/SPI reads. We're also assuming that
* it's rare to get lots of interrupts firing simultaneously so try to
* minimise I/O.
*/
static irqreturn_t tps65910_irq(int irq, void *irq_data)
{
struct tps65910 *tps65910 = irq_data;
u32 irq_sts;
u32 irq_mask;
u8 reg;
int i;
tps65910->read(tps65910, TPS65910_INT_STS, 1, &reg);
irq_sts = reg;
tps65910->read(tps65910, TPS65910_INT_STS2, 1, &reg);
irq_sts |= reg << 8;
switch (tps65910_chip_id(tps65910)) {
case TPS65911:
tps65910->read(tps65910, TPS65910_INT_STS3, 1, &reg);
irq_sts |= reg << 16;
}
tps65910->read(tps65910, TPS65910_INT_MSK, 1, &reg);
irq_mask = reg;
tps65910->read(tps65910, TPS65910_INT_MSK2, 1, &reg);
irq_mask |= reg << 8;
switch (tps65910_chip_id(tps65910)) {
case TPS65911:
tps65910->read(tps65910, TPS65910_INT_MSK3, 1, &reg);
irq_mask |= reg << 16;
}
irq_sts &= ~irq_mask;
if (!irq_sts)
return IRQ_NONE;
for (i = 0; i < tps65910->irq_num; i++) {
if (!(irq_sts & (1 << i)))
continue;
handle_nested_irq(tps65910->irq_base + i);
}
/* Write the STS register back to clear IRQs we handled */
reg = irq_sts & 0xFF;
irq_sts >>= 8;
tps65910->write(tps65910, TPS65910_INT_STS, 1, &reg);
reg = irq_sts & 0xFF;
tps65910->write(tps65910, TPS65910_INT_STS2, 1, &reg);
switch (tps65910_chip_id(tps65910)) {
case TPS65911:
reg = irq_sts >> 8;
tps65910->write(tps65910, TPS65910_INT_STS3, 1, &reg);
}
return IRQ_HANDLED;
}
static void tps65910_irq_lock(struct irq_data *data)
{
struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
mutex_lock(&tps65910->irq_lock);
}
static void tps65910_irq_sync_unlock(struct irq_data *data)
{
struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
u32 reg_mask;
u8 reg;
tps65910->read(tps65910, TPS65910_INT_MSK, 1, &reg);
reg_mask = reg;
tps65910->read(tps65910, TPS65910_INT_MSK2, 1, &reg);
reg_mask |= reg << 8;
switch (tps65910_chip_id(tps65910)) {
case TPS65911:
tps65910->read(tps65910, TPS65910_INT_MSK3, 1, &reg);
reg_mask |= reg << 16;
}
if (tps65910->irq_mask != reg_mask) {
reg = tps65910->irq_mask & 0xFF;
tps65910->write(tps65910, TPS65910_INT_MSK, 1, &reg);
reg = tps65910->irq_mask >> 8 & 0xFF;
tps65910->write(tps65910, TPS65910_INT_MSK2, 1, &reg);
switch (tps65910_chip_id(tps65910)) {
case TPS65911:
reg = tps65910->irq_mask >> 16;
tps65910->write(tps65910, TPS65910_INT_MSK3, 1, &reg);
}
}
mutex_unlock(&tps65910->irq_lock);
}
static void tps65910_irq_enable(struct irq_data *data)
{
struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
tps65910->irq_mask &= ~( 1 << irq_to_tps65910_irq(tps65910, data->irq));
}
static void tps65910_irq_disable(struct irq_data *data)
{
struct tps65910 *tps65910 = irq_data_get_irq_chip_data(data);
tps65910->irq_mask |= ( 1 << irq_to_tps65910_irq(tps65910, data->irq));
}
static struct irq_chip tps65910_irq_chip = {
.name = "tps65910",
.irq_bus_lock = tps65910_irq_lock,
.irq_bus_sync_unlock = tps65910_irq_sync_unlock,
.irq_disable = tps65910_irq_disable,
.irq_enable = tps65910_irq_enable,
};
int tps65910_irq_init(struct tps65910 *tps65910, int irq,
struct tps65910_platform_data *pdata)
{
int ret, cur_irq;
int flags = IRQF_ONESHOT;
if (!irq) {
dev_warn(tps65910->dev, "No interrupt support, no core IRQ\n");
return -EINVAL;
}
if (!pdata || !pdata->irq_base) {
dev_warn(tps65910->dev, "No interrupt support, no IRQ base\n");
return -EINVAL;
}
tps65910->irq_mask = 0xFFFFFF;
mutex_init(&tps65910->irq_lock);
tps65910->chip_irq = irq;
tps65910->irq_base = pdata->irq_base;
switch (tps65910_chip_id(tps65910)) {
case TPS65910:
tps65910->irq_num = TPS65910_NUM_IRQ;
case TPS65911:
tps65910->irq_num = TPS65911_NUM_IRQ;
}
/* Register with genirq */
for (cur_irq = tps65910->irq_base;
cur_irq < tps65910->irq_num + tps65910->irq_base;
cur_irq++) {
irq_set_chip_data(cur_irq, tps65910);
irq_set_chip_and_handler(cur_irq, &tps65910_irq_chip,
handle_edge_irq);
irq_set_nested_thread(cur_irq, 1);
/* ARM needs us to explicitly flag the IRQ as valid
* and will set them noprobe when we do so. */
#ifdef CONFIG_ARM
set_irq_flags(cur_irq, IRQF_VALID);
#else
irq_set_noprobe(cur_irq);
#endif
}
ret = request_threaded_irq(irq, NULL, tps65910_irq, flags,
"tps65910", tps65910);
irq_set_irq_type(irq, IRQ_TYPE_LEVEL_LOW);
if (ret != 0)
dev_err(tps65910->dev, "Failed to request IRQ: %d\n", ret);
return ret;
}
int tps65910_irq_exit(struct tps65910 *tps65910)
{
free_irq(tps65910->chip_irq, tps65910);
return 0;
}
/*
* tps65910.c -- TI TPS6591x
*
* Copyright 2010 Texas Instruments Inc.
*
* Author: Graeme Gregory <gg@slimlogic.co.uk>
* Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>
*
* 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.
*
*/
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/i2c.h>
#include <linux/gpio.h>
#include <linux/mfd/core.h>
#include <linux/mfd/tps65910.h>
static struct mfd_cell tps65910s[] = {
{
.name = "tps65910-pmic",
},
{
.name = "tps65910-rtc",
},
{
.name = "tps65910-power",
},
};
static int tps65910_i2c_read(struct tps65910 *tps65910, u8 reg,
int bytes, void *dest)
{
struct i2c_client *i2c = tps65910->i2c_client;
struct i2c_msg xfer[2];
int ret;
/* Write register */
xfer[0].addr = i2c->addr;
xfer[0].flags = 0;
xfer[0].len = 1;
xfer[0].buf = &reg;
/* Read data */
xfer[1].addr = i2c->addr;
xfer[1].flags = I2C_M_RD;
xfer[1].len = bytes;
xfer[1].buf = dest;
ret = i2c_transfer(i2c->adapter, xfer, 2);
if (ret == 2)
ret = 0;
else if (ret >= 0)
ret = -EIO;
return ret;
}
static int tps65910_i2c_write(struct tps65910 *tps65910, u8 reg,
int bytes, void *src)
{
struct i2c_client *i2c = tps65910->i2c_client;
/* we add 1 byte for device register */
u8 msg[TPS65910_MAX_REGISTER + 1];
int ret;
if (bytes > TPS65910_MAX_REGISTER)
return -EINVAL;
msg[0] = reg;
memcpy(&msg[1], src, bytes);
ret = i2c_master_send(i2c, msg, bytes + 1);
if (ret < 0)
return ret;
if (ret != bytes + 1)
return -EIO;
return 0;
}
int tps65910_set_bits(struct tps65910 *tps65910, u8 reg, u8 mask)
{
u8 data;
int err;
mutex_lock(&tps65910->io_mutex);
err = tps65910_i2c_read(tps65910, reg, 1, &data);
if (err) {
dev_err(tps65910->dev, "read from reg %x failed\n", reg);
goto out;
}
data |= mask;
err = tps65910_i2c_write(tps65910, reg, 1, &data);
if (err)
dev_err(tps65910->dev, "write to reg %x failed\n", reg);
out:
mutex_unlock(&tps65910->io_mutex);
return err;
}
EXPORT_SYMBOL_GPL(tps65910_set_bits);
int tps65910_clear_bits(struct tps65910 *tps65910, u8 reg, u8 mask)
{
u8 data;
int err;
mutex_lock(&tps65910->io_mutex);
err = tps65910_i2c_read(tps65910, reg, 1, &data);
if (err) {
dev_err(tps65910->dev, "read from reg %x failed\n", reg);
goto out;
}
data &= mask;
err = tps65910_i2c_write(tps65910, reg, 1, &data);
if (err)
dev_err(tps65910->dev, "write to reg %x failed\n", reg);
out:
mutex_unlock(&tps65910->io_mutex);
return err;
}
EXPORT_SYMBOL_GPL(tps65910_clear_bits);
static int tps65910_i2c_probe(struct i2c_client *i2c,
const struct i2c_device_id *id)
{
struct tps65910 *tps65910;
struct tps65910_board *pmic_plat_data;
struct tps65910_platform_data *init_data;
int ret = 0;
pmic_plat_data = dev_get_platdata(&i2c->dev);
if (!pmic_plat_data)
return -EINVAL;
init_data = kzalloc(sizeof(struct tps65910_platform_data), GFP_KERNEL);
if (init_data == NULL)
return -ENOMEM;
init_data->irq = pmic_plat_data->irq;
init_data->irq_base = pmic_plat_data->irq;
tps65910 = kzalloc(sizeof(struct tps65910), GFP_KERNEL);
if (tps65910 == NULL)
return -ENOMEM;
i2c_set_clientdata(i2c, tps65910);
tps65910->dev = &i2c->dev;
tps65910->i2c_client = i2c;
tps65910->id = id->driver_data;
tps65910->read = tps65910_i2c_read;
tps65910->write = tps65910_i2c_write;
mutex_init(&tps65910->io_mutex);
ret = mfd_add_devices(tps65910->dev, -1,
tps65910s, ARRAY_SIZE(tps65910s),
NULL, 0);
if (ret < 0)
goto err;
tps65910_gpio_init(tps65910, pmic_plat_data->gpio_base);
ret = tps65910_irq_init(tps65910, init_data->irq, init_data);
if (ret < 0)
goto err;
return ret;
err:
mfd_remove_devices(tps65910->dev);
kfree(tps65910);
return ret;
}
static int tps65910_i2c_remove(struct i2c_client *i2c)
{
struct tps65910 *tps65910 = i2c_get_clientdata(i2c);
mfd_remove_devices(tps65910->dev);
kfree(tps65910);
return 0;
}
static const struct i2c_device_id tps65910_i2c_id[] = {
{ "tps65910", TPS65910 },
{ "tps65911", TPS65911 },
{ }
};
MODULE_DEVICE_TABLE(i2c, tps65910_i2c_id);
static struct i2c_driver tps65910_i2c_driver = {
.driver = {
.name = "tps65910",
.owner = THIS_MODULE,
},
.probe = tps65910_i2c_probe,
.remove = tps65910_i2c_remove,
.id_table = tps65910_i2c_id,
};
static int __init tps65910_i2c_init(void)
{
return i2c_add_driver(&tps65910_i2c_driver);
}
/* init early so consumer devices can complete system boot */
subsys_initcall(tps65910_i2c_init);
static void __exit tps65910_i2c_exit(void)
{
i2c_del_driver(&tps65910_i2c_driver);
}
module_exit(tps65910_i2c_exit);
MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
MODULE_AUTHOR("Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>");
MODULE_DESCRIPTION("TPS6591x chip family multi-function driver");
MODULE_LICENSE("GPL");
/*
* tps65910.c -- TI TPS6591x
*
* Copyright 2010 Texas Instruments Inc.
*
* Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>
*
* 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.
*
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/err.h>
#include <linux/platform_device.h>
#include <linux/debugfs.h>
#include <linux/gpio.h>
#include <linux/mfd/tps65910.h>
#define COMP 0
#define COMP1 1
#define COMP2 2
/* Comparator 1 voltage selection table in milivolts */
static const u16 COMP_VSEL_TABLE[] = {
0, 2500, 2500, 2500, 2500, 2550, 2600, 2650,
2700, 2750, 2800, 2850, 2900, 2950, 3000, 3050,
3100, 3150, 3200, 3250, 3300, 3350, 3400, 3450,
3500,
};
struct comparator {
const char *name;
int reg;
int uV_max;
const u16 *vsel_table;
};
static struct comparator tps_comparators[] = {
{
.name = "COMP1",
.reg = TPS65911_VMBCH,
.uV_max = 3500,
.vsel_table = COMP_VSEL_TABLE,
},
{
.name = "COMP2",
.reg = TPS65911_VMBCH2,
.uV_max = 3500,
.vsel_table = COMP_VSEL_TABLE,
},
};
static int comp_threshold_set(struct tps65910 *tps65910, int id, int voltage)
{
struct comparator tps_comp = tps_comparators[id];
int curr_voltage = 0;
int ret;
u8 index = 0, val;
if (id == COMP)
return 0;
while (curr_voltage < tps_comp.uV_max) {
curr_voltage = tps_comp.vsel_table[index];
if (curr_voltage >= voltage)
break;
else if (curr_voltage < voltage)
index ++;
}
if (curr_voltage > tps_comp.uV_max)
return -EINVAL;
val = index << 1;
ret = tps65910->write(tps65910, tps_comp.reg, 1, &val);
return ret;
}
static int comp_threshold_get(struct tps65910 *tps65910, int id)
{
struct comparator tps_comp = tps_comparators[id];
int ret;
u8 val;
if (id == COMP)
return 0;
ret = tps65910->read(tps65910, tps_comp.reg, 1, &val);
if (ret < 0)
return ret;
val >>= 1;
return tps_comp.vsel_table[val];
}
static ssize_t comp_threshold_show(struct device *dev,
struct device_attribute *attr, char *buf)
{
struct tps65910 *tps65910 = dev_get_drvdata(dev->parent);
struct attribute comp_attr = attr->attr;
int id, uVolt;
if (!strcmp(comp_attr.name, "comp1_threshold"))
id = COMP1;
else if (!strcmp(comp_attr.name, "comp2_threshold"))
id = COMP2;
else
return -EINVAL;
uVolt = comp_threshold_get(tps65910, id);
return sprintf(buf, "%d\n", uVolt);
}
static DEVICE_ATTR(comp1_threshold, S_IRUGO, comp_threshold_show, NULL);
static DEVICE_ATTR(comp2_threshold, S_IRUGO, comp_threshold_show, NULL);
static __devinit int tps65911_comparator_probe(struct platform_device *pdev)
{
struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
struct tps65910_platform_data *pdata = dev_get_platdata(tps65910->dev);
int ret;
ret = comp_threshold_set(tps65910, COMP1, pdata->vmbch_threshold);
if (ret < 0) {
dev_err(&pdev->dev, "cannot set COMP1 threshold\n");
return ret;
}
ret = comp_threshold_set(tps65910, COMP2, pdata->vmbch2_threshold);
if (ret < 0) {
dev_err(&pdev->dev, "cannot set COMP2 theshold\n");
return ret;
}
/* Create sysfs entry */
ret = device_create_file(&pdev->dev, &dev_attr_comp1_threshold);
if (ret < 0)
dev_err(&pdev->dev, "failed to add COMP1 sysfs file\n");
ret = device_create_file(&pdev->dev, &dev_attr_comp2_threshold);
if (ret < 0)
dev_err(&pdev->dev, "failed to add COMP2 sysfs file\n");
return ret;
}
static __devexit int tps65911_comparator_remove(struct platform_device *pdev)
{
struct tps65910 *tps65910;
tps65910 = dev_get_drvdata(pdev->dev.parent);
return 0;
}
static struct platform_driver tps65911_comparator_driver = {
.driver = {
.name = "tps65911-comparator",
.owner = THIS_MODULE,
},
.probe = tps65911_comparator_probe,
.remove = __devexit_p(tps65911_comparator_remove),
};
static int __init tps65911_comparator_init(void)
{
return platform_driver_register(&tps65911_comparator_driver);
}
subsys_initcall(tps65911_comparator_init);
static void __exit tps65911_comparator_exit(void)
{
platform_driver_unregister(&tps65911_comparator_driver);
}
module_exit(tps65911_comparator_exit);
MODULE_AUTHOR("Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>");
MODULE_DESCRIPTION("TPS65911 comparator driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:tps65911-comparator");
...@@ -297,5 +297,11 @@ config REGULATOR_TPS6524X ...@@ -297,5 +297,11 @@ config REGULATOR_TPS6524X
serial interface currently supported on the sequencer serial serial interface currently supported on the sequencer serial
port controller. port controller.
config REGULATOR_TPS65910
tristate "TI TPS65910 Power Regulator"
depends on MFD_TPS65910
help
This driver supports TPS65910 voltage regulator chips.
endif endif
...@@ -42,5 +42,6 @@ obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o ...@@ -42,5 +42,6 @@ obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o
obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
...@@ -158,6 +158,13 @@ static int regulator_check_consumers(struct regulator_dev *rdev, ...@@ -158,6 +158,13 @@ static int regulator_check_consumers(struct regulator_dev *rdev,
struct regulator *regulator; struct regulator *regulator;
list_for_each_entry(regulator, &rdev->consumer_list, list) { list_for_each_entry(regulator, &rdev->consumer_list, list) {
/*
* Assume consumers that didn't say anything are OK
* with anything in the constraint range.
*/
if (!regulator->min_uV && !regulator->max_uV)
continue;
if (*max_uV > regulator->max_uV) if (*max_uV > regulator->max_uV)
*max_uV = regulator->max_uV; *max_uV = regulator->max_uV;
if (*min_uV < regulator->min_uV) if (*min_uV < regulator->min_uV)
...@@ -197,9 +204,9 @@ static int regulator_check_current_limit(struct regulator_dev *rdev, ...@@ -197,9 +204,9 @@ static int regulator_check_current_limit(struct regulator_dev *rdev,
} }
/* operating mode constraint check */ /* operating mode constraint check */
static int regulator_check_mode(struct regulator_dev *rdev, int mode) static int regulator_mode_constrain(struct regulator_dev *rdev, int *mode)
{ {
switch (mode) { switch (*mode) {
case REGULATOR_MODE_FAST: case REGULATOR_MODE_FAST:
case REGULATOR_MODE_NORMAL: case REGULATOR_MODE_NORMAL:
case REGULATOR_MODE_IDLE: case REGULATOR_MODE_IDLE:
...@@ -217,11 +224,17 @@ static int regulator_check_mode(struct regulator_dev *rdev, int mode) ...@@ -217,11 +224,17 @@ static int regulator_check_mode(struct regulator_dev *rdev, int mode)
rdev_err(rdev, "operation not allowed\n"); rdev_err(rdev, "operation not allowed\n");
return -EPERM; return -EPERM;
} }
if (!(rdev->constraints->valid_modes_mask & mode)) {
rdev_err(rdev, "invalid mode %x\n", mode); /* The modes are bitmasks, the most power hungry modes having
return -EINVAL; * the lowest values. If the requested mode isn't supported
} * try higher modes. */
while (*mode) {
if (rdev->constraints->valid_modes_mask & *mode)
return 0; return 0;
*mode /= 2;
}
return -EINVAL;
} }
/* dynamic regulator mode switching constraint check */ /* dynamic regulator mode switching constraint check */
...@@ -612,7 +625,7 @@ static void drms_uA_update(struct regulator_dev *rdev) ...@@ -612,7 +625,7 @@ static void drms_uA_update(struct regulator_dev *rdev)
output_uV, current_uA); output_uV, current_uA);
/* check the new mode is allowed */ /* check the new mode is allowed */
err = regulator_check_mode(rdev, mode); err = regulator_mode_constrain(rdev, &mode);
if (err == 0) if (err == 0)
rdev->desc->ops->set_mode(rdev, mode); rdev->desc->ops->set_mode(rdev, mode);
} }
...@@ -718,6 +731,10 @@ static void print_constraints(struct regulator_dev *rdev) ...@@ -718,6 +731,10 @@ static void print_constraints(struct regulator_dev *rdev)
count += sprintf(buf + count, "at %d mV ", ret / 1000); count += sprintf(buf + count, "at %d mV ", ret / 1000);
} }
if (constraints->uV_offset)
count += sprintf(buf, "%dmV offset ",
constraints->uV_offset / 1000);
if (constraints->min_uA && constraints->max_uA) { if (constraints->min_uA && constraints->max_uA) {
if (constraints->min_uA == constraints->max_uA) if (constraints->min_uA == constraints->max_uA)
count += sprintf(buf + count, "%d mA ", count += sprintf(buf + count, "%d mA ",
...@@ -1498,13 +1515,14 @@ static int _regulator_force_disable(struct regulator_dev *rdev, ...@@ -1498,13 +1515,14 @@ static int _regulator_force_disable(struct regulator_dev *rdev,
*/ */
int regulator_force_disable(struct regulator *regulator) int regulator_force_disable(struct regulator *regulator)
{ {
struct regulator_dev *rdev = regulator->rdev;
struct regulator_dev *supply_rdev = NULL; struct regulator_dev *supply_rdev = NULL;
int ret; int ret;
mutex_lock(&regulator->rdev->mutex); mutex_lock(&rdev->mutex);
regulator->uA_load = 0; regulator->uA_load = 0;
ret = _regulator_force_disable(regulator->rdev, &supply_rdev); ret = _regulator_force_disable(rdev, &supply_rdev);
mutex_unlock(&regulator->rdev->mutex); mutex_unlock(&rdev->mutex);
if (supply_rdev) if (supply_rdev)
regulator_disable(get_device_regulator(rdev_get_dev(supply_rdev))); regulator_disable(get_device_regulator(rdev_get_dev(supply_rdev)));
...@@ -1634,6 +1652,9 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev, ...@@ -1634,6 +1652,9 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV); trace_regulator_set_voltage(rdev_get_name(rdev), min_uV, max_uV);
min_uV += rdev->constraints->uV_offset;
max_uV += rdev->constraints->uV_offset;
if (rdev->desc->ops->set_voltage) { if (rdev->desc->ops->set_voltage) {
ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV, ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV,
&selector); &selector);
...@@ -1858,18 +1879,22 @@ EXPORT_SYMBOL_GPL(regulator_sync_voltage); ...@@ -1858,18 +1879,22 @@ EXPORT_SYMBOL_GPL(regulator_sync_voltage);
static int _regulator_get_voltage(struct regulator_dev *rdev) static int _regulator_get_voltage(struct regulator_dev *rdev)
{ {
int sel; int sel, ret;
if (rdev->desc->ops->get_voltage_sel) { if (rdev->desc->ops->get_voltage_sel) {
sel = rdev->desc->ops->get_voltage_sel(rdev); sel = rdev->desc->ops->get_voltage_sel(rdev);
if (sel < 0) if (sel < 0)
return sel; return sel;
return rdev->desc->ops->list_voltage(rdev, sel); ret = rdev->desc->ops->list_voltage(rdev, sel);
} } else if (rdev->desc->ops->get_voltage) {
if (rdev->desc->ops->get_voltage) ret = rdev->desc->ops->get_voltage(rdev);
return rdev->desc->ops->get_voltage(rdev); } else {
else
return -EINVAL; return -EINVAL;
}
if (ret < 0)
return ret;
return ret - rdev->constraints->uV_offset;
} }
/** /**
...@@ -2005,7 +2030,7 @@ int regulator_set_mode(struct regulator *regulator, unsigned int mode) ...@@ -2005,7 +2030,7 @@ int regulator_set_mode(struct regulator *regulator, unsigned int mode)
} }
/* constraints check */ /* constraints check */
ret = regulator_check_mode(rdev, mode); ret = regulator_mode_constrain(rdev, &mode);
if (ret < 0) if (ret < 0)
goto out; goto out;
...@@ -2081,16 +2106,26 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) ...@@ -2081,16 +2106,26 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
mutex_lock(&rdev->mutex); mutex_lock(&rdev->mutex);
/*
* first check to see if we can set modes at all, otherwise just
* tell the consumer everything is OK.
*/
regulator->uA_load = uA_load; regulator->uA_load = uA_load;
ret = regulator_check_drms(rdev); ret = regulator_check_drms(rdev);
if (ret < 0) if (ret < 0) {
ret = 0;
goto out; goto out;
ret = -EINVAL; }
/* sanity check */
if (!rdev->desc->ops->get_optimum_mode) if (!rdev->desc->ops->get_optimum_mode)
goto out; goto out;
/*
* we can actually do this so any errors are indicators of
* potential real failure.
*/
ret = -EINVAL;
/* get output voltage */ /* get output voltage */
output_uV = _regulator_get_voltage(rdev); output_uV = _regulator_get_voltage(rdev);
if (output_uV <= 0) { if (output_uV <= 0) {
...@@ -2116,7 +2151,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load) ...@@ -2116,7 +2151,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
mode = rdev->desc->ops->get_optimum_mode(rdev, mode = rdev->desc->ops->get_optimum_mode(rdev,
input_uV, output_uV, input_uV, output_uV,
total_uA_load); total_uA_load);
ret = regulator_check_mode(rdev, mode); ret = regulator_mode_constrain(rdev, &mode);
if (ret < 0) { if (ret < 0) {
rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n", rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
total_uA_load, input_uV, output_uV); total_uA_load, input_uV, output_uV);
...@@ -2589,14 +2624,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, ...@@ -2589,14 +2624,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
if (ret < 0) if (ret < 0)
goto scrub; goto scrub;
/* set supply regulator if it exists */
if (init_data->supply_regulator && init_data->supply_regulator_dev) {
dev_err(dev,
"Supply regulator specified by both name and dev\n");
ret = -EINVAL;
goto scrub;
}
if (init_data->supply_regulator) { if (init_data->supply_regulator) {
struct regulator_dev *r; struct regulator_dev *r;
int found = 0; int found = 0;
...@@ -2621,14 +2648,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc, ...@@ -2621,14 +2648,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
goto scrub; goto scrub;
} }
if (init_data->supply_regulator_dev) {
dev_warn(dev, "Uses supply_regulator_dev instead of regulator_supply\n");
ret = set_supply(rdev,
dev_get_drvdata(init_data->supply_regulator_dev));
if (ret < 0)
goto scrub;
}
/* add consumers devices */ /* add consumers devices */
for (i = 0; i < init_data->num_consumer_supplies; i++) { for (i = 0; i < init_data->num_consumer_supplies; i++) {
ret = set_consumer_device_supply(rdev, ret = set_consumer_device_supply(rdev,
......
...@@ -267,7 +267,6 @@ static int max8997_get_enable_register(struct regulator_dev *rdev, ...@@ -267,7 +267,6 @@ static int max8997_get_enable_register(struct regulator_dev *rdev,
default: default:
/* Not controllable or not exists */ /* Not controllable or not exists */
return -EINVAL; return -EINVAL;
break;
} }
return 0; return 0;
...@@ -1033,11 +1032,11 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) ...@@ -1033,11 +1032,11 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
/* For the safety, set max voltage before setting up */ /* For the safety, set max voltage before setting up */
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS(i + 1), max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS1 + i,
max_buck1, 0x3f); max_buck1, 0x3f);
max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS(i + 1), max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i,
max_buck2, 0x3f); max_buck2, 0x3f);
max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS(i + 1), max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i,
max_buck5, 0x3f); max_buck5, 0x3f);
} }
...@@ -1114,13 +1113,13 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev) ...@@ -1114,13 +1113,13 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
/* Initialize all the DVS related BUCK registers */ /* Initialize all the DVS related BUCK registers */
for (i = 0; i < 8; i++) { for (i = 0; i < 8; i++) {
max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS(i + 1), max8997_update_reg(i2c, MAX8997_REG_BUCK1DVS1 + i,
max8997->buck1_vol[i], max8997->buck1_vol[i],
0x3f); 0x3f);
max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS(i + 1), max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i,
max8997->buck2_vol[i], max8997->buck2_vol[i],
0x3f); 0x3f);
max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS(i + 1), max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i,
max8997->buck5_vol[i], max8997->buck5_vol[i],
0x3f); 0x3f);
} }
......
...@@ -732,13 +732,15 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -732,13 +732,15 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
if (!pdata->buck1_set1) { if (!pdata->buck1_set1) {
printk(KERN_ERR "MAX8998 SET1 GPIO defined as 0 !\n"); printk(KERN_ERR "MAX8998 SET1 GPIO defined as 0 !\n");
WARN_ON(!pdata->buck1_set1); WARN_ON(!pdata->buck1_set1);
return -EIO; ret = -EIO;
goto err_free_mem;
} }
/* Check if SET2 is not equal to 0 */ /* Check if SET2 is not equal to 0 */
if (!pdata->buck1_set2) { if (!pdata->buck1_set2) {
printk(KERN_ERR "MAX8998 SET2 GPIO defined as 0 !\n"); printk(KERN_ERR "MAX8998 SET2 GPIO defined as 0 !\n");
WARN_ON(!pdata->buck1_set2); WARN_ON(!pdata->buck1_set2);
return -EIO; ret = -EIO;
goto err_free_mem;
} }
gpio_request(pdata->buck1_set1, "MAX8998 BUCK1_SET1"); gpio_request(pdata->buck1_set1, "MAX8998 BUCK1_SET1");
...@@ -758,7 +760,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -758,7 +760,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
max8998->buck1_vol[0] = i; max8998->buck1_vol[0] = i;
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i); ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i);
if (ret) if (ret)
return ret; goto err_free_mem;
/* Set predefined value for BUCK1 register 2 */ /* Set predefined value for BUCK1 register 2 */
i = 0; i = 0;
...@@ -770,7 +772,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -770,7 +772,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
max8998->buck1_vol[1] = i; max8998->buck1_vol[1] = i;
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i); ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i);
if (ret) if (ret)
return ret; goto err_free_mem;
/* Set predefined value for BUCK1 register 3 */ /* Set predefined value for BUCK1 register 3 */
i = 0; i = 0;
...@@ -782,7 +784,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -782,7 +784,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
max8998->buck1_vol[2] = i; max8998->buck1_vol[2] = i;
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i); ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i);
if (ret) if (ret)
return ret; goto err_free_mem;
/* Set predefined value for BUCK1 register 4 */ /* Set predefined value for BUCK1 register 4 */
i = 0; i = 0;
...@@ -794,7 +796,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -794,7 +796,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
max8998->buck1_vol[3] = i; max8998->buck1_vol[3] = i;
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i); ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i);
if (ret) if (ret)
return ret; goto err_free_mem;
} }
...@@ -803,7 +805,8 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -803,7 +805,8 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
if (!pdata->buck2_set3) { if (!pdata->buck2_set3) {
printk(KERN_ERR "MAX8998 SET3 GPIO defined as 0 !\n"); printk(KERN_ERR "MAX8998 SET3 GPIO defined as 0 !\n");
WARN_ON(!pdata->buck2_set3); WARN_ON(!pdata->buck2_set3);
return -EIO; ret = -EIO;
goto err_free_mem;
} }
gpio_request(pdata->buck2_set3, "MAX8998 BUCK2_SET3"); gpio_request(pdata->buck2_set3, "MAX8998 BUCK2_SET3");
gpio_direction_output(pdata->buck2_set3, gpio_direction_output(pdata->buck2_set3,
...@@ -818,7 +821,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -818,7 +821,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
max8998->buck2_vol[0] = i; max8998->buck2_vol[0] = i;
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i); ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i);
if (ret) if (ret)
return ret; goto err_free_mem;
/* BUCK2 register 2 */ /* BUCK2 register 2 */
i = 0; i = 0;
...@@ -830,7 +833,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -830,7 +833,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
max8998->buck2_vol[1] = i; max8998->buck2_vol[1] = i;
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i); ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i);
if (ret) if (ret)
return ret; goto err_free_mem;
} }
for (i = 0; i < pdata->num_regulators; i++) { for (i = 0; i < pdata->num_regulators; i++) {
...@@ -860,6 +863,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev) ...@@ -860,6 +863,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
if (rdev[i]) if (rdev[i])
regulator_unregister(rdev[i]); regulator_unregister(rdev[i]);
err_free_mem:
kfree(max8998->rdev); kfree(max8998->rdev);
kfree(max8998); kfree(max8998);
......
...@@ -431,7 +431,8 @@ static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev, ...@@ -431,7 +431,8 @@ static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector) int min_uV, int max_uV, unsigned *selector)
{ {
struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev); struct mc13xxx_regulator_priv *priv = rdev_get_drvdata(rdev);
int hi, value, val, mask, id = rdev_get_id(rdev); int hi, value, mask, id = rdev_get_id(rdev);
u32 valread;
int ret; int ret;
dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n", dev_dbg(rdev_get_dev(rdev), "%s id: %d min_uV: %d max_uV: %d\n",
...@@ -447,15 +448,16 @@ static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev, ...@@ -447,15 +448,16 @@ static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev,
mc13xxx_lock(priv->mc13xxx); mc13xxx_lock(priv->mc13xxx);
ret = mc13xxx_reg_read(priv->mc13xxx, ret = mc13xxx_reg_read(priv->mc13xxx,
mc13892_regulators[id].vsel_reg, &val); mc13892_regulators[id].vsel_reg, &valread);
if (ret) if (ret)
goto err; goto err;
hi = val & MC13892_SWITCHERS0_SWxHI; if (value > 1375000)
if (value > 1375)
hi = 1; hi = 1;
if (value < 1100) else if (value < 1100000)
hi = 0; hi = 0;
else
hi = valread & MC13892_SWITCHERS0_SWxHI;
if (hi) { if (hi) {
value = (value - 1100000) / 25000; value = (value - 1100000) / 25000;
...@@ -464,8 +466,10 @@ static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev, ...@@ -464,8 +466,10 @@ static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev,
value = (value - 600000) / 25000; value = (value - 600000) / 25000;
mask = mc13892_regulators[id].vsel_mask | MC13892_SWITCHERS0_SWxHI; mask = mc13892_regulators[id].vsel_mask | MC13892_SWITCHERS0_SWxHI;
ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].vsel_reg, valread = (valread & ~mask) |
mask, value << mc13892_regulators[id].vsel_shift); (value << mc13892_regulators[id].vsel_shift);
ret = mc13xxx_reg_write(priv->mc13xxx, mc13892_regulators[id].vsel_reg,
valread);
err: err:
mc13xxx_unlock(priv->mc13xxx); mc13xxx_unlock(priv->mc13xxx);
......
...@@ -174,7 +174,7 @@ static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev) ...@@ -174,7 +174,7 @@ static int mc13xxx_regulator_get_voltage(struct regulator_dev *rdev)
dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val); dev_dbg(rdev_get_dev(rdev), "%s id: %d val: %d\n", __func__, id, val);
BUG_ON(val > mc13xxx_regulators[id].desc.n_voltages); BUG_ON(val >= mc13xxx_regulators[id].desc.n_voltages);
return mc13xxx_regulators[id].voltages[val]; return mc13xxx_regulators[id].voltages[val];
} }
......
...@@ -158,6 +158,7 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev) ...@@ -158,6 +158,7 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
"failed to register regulator\n"); "failed to register regulator\n");
return ret; return ret;
} }
platform_set_drvdata(pdev, tps6105x);
return 0; return 0;
} }
......
...@@ -466,7 +466,6 @@ static struct regulator_ops tps65023_ldo_ops = { ...@@ -466,7 +466,6 @@ static struct regulator_ops tps65023_ldo_ops = {
static int __devinit tps_65023_probe(struct i2c_client *client, static int __devinit tps_65023_probe(struct i2c_client *client,
const struct i2c_device_id *id) const struct i2c_device_id *id)
{ {
static int desc_id;
const struct tps_info *info = (void *)id->driver_data; const struct tps_info *info = (void *)id->driver_data;
struct regulator_init_data *init_data; struct regulator_init_data *init_data;
struct regulator_dev *rdev; struct regulator_dev *rdev;
...@@ -499,7 +498,7 @@ static int __devinit tps_65023_probe(struct i2c_client *client, ...@@ -499,7 +498,7 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
tps->info[i] = info; tps->info[i] = info;
tps->desc[i].name = info->name; tps->desc[i].name = info->name;
tps->desc[i].id = desc_id++; tps->desc[i].id = i;
tps->desc[i].n_voltages = num_voltages[i]; tps->desc[i].n_voltages = num_voltages[i];
tps->desc[i].ops = (i > TPS65023_DCDC_3 ? tps->desc[i].ops = (i > TPS65023_DCDC_3 ?
&tps65023_ldo_ops : &tps65023_dcdc_ops); &tps65023_ldo_ops : &tps65023_dcdc_ops);
......
...@@ -553,7 +553,6 @@ static __devinit ...@@ -553,7 +553,6 @@ static __devinit
int tps6507x_pmic_probe(struct platform_device *pdev) int tps6507x_pmic_probe(struct platform_device *pdev)
{ {
struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
static int desc_id;
struct tps_info *info = &tps6507x_pmic_regs[0]; struct tps_info *info = &tps6507x_pmic_regs[0];
struct regulator_init_data *init_data; struct regulator_init_data *init_data;
struct regulator_dev *rdev; struct regulator_dev *rdev;
...@@ -598,7 +597,7 @@ int tps6507x_pmic_probe(struct platform_device *pdev) ...@@ -598,7 +597,7 @@ int tps6507x_pmic_probe(struct platform_device *pdev)
} }
tps->desc[i].name = info->name; tps->desc[i].name = info->name;
tps->desc[i].id = desc_id++; tps->desc[i].id = i;
tps->desc[i].n_voltages = num_voltages[i]; tps->desc[i].n_voltages = num_voltages[i];
tps->desc[i].ops = (i > TPS6507X_DCDC_3 ? tps->desc[i].ops = (i > TPS6507X_DCDC_3 ?
&tps6507x_pmic_ldo_ops : &tps6507x_pmic_dcdc_ops); &tps6507x_pmic_ldo_ops : &tps6507x_pmic_dcdc_ops);
......
/*
* tps65910.c -- TI tps65910
*
* Copyright 2010 Texas Instruments Inc.
*
* Author: Graeme Gregory <gg@slimlogic.co.uk>
* Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>
*
* 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.
*
*/
#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/regulator/machine.h>
#include <linux/delay.h>
#include <linux/slab.h>
#include <linux/gpio.h>
#include <linux/mfd/tps65910.h>
#define TPS65910_REG_VRTC 0
#define TPS65910_REG_VIO 1
#define TPS65910_REG_VDD1 2
#define TPS65910_REG_VDD2 3
#define TPS65910_REG_VDD3 4
#define TPS65910_REG_VDIG1 5
#define TPS65910_REG_VDIG2 6
#define TPS65910_REG_VPLL 7
#define TPS65910_REG_VDAC 8
#define TPS65910_REG_VAUX1 9
#define TPS65910_REG_VAUX2 10
#define TPS65910_REG_VAUX33 11
#define TPS65910_REG_VMMC 12
#define TPS65911_REG_VDDCTRL 4
#define TPS65911_REG_LDO1 5
#define TPS65911_REG_LDO2 6
#define TPS65911_REG_LDO3 7
#define TPS65911_REG_LDO4 8
#define TPS65911_REG_LDO5 9
#define TPS65911_REG_LDO6 10
#define TPS65911_REG_LDO7 11
#define TPS65911_REG_LDO8 12
#define TPS65910_NUM_REGULATOR 13
#define TPS65910_SUPPLY_STATE_ENABLED 0x1
/* supported VIO voltages in milivolts */
static const u16 VIO_VSEL_table[] = {
1500, 1800, 2500, 3300,
};
/* VSEL tables for TPS65910 specific LDOs and dcdc's */
/* supported VDD3 voltages in milivolts */
static const u16 VDD3_VSEL_table[] = {
5000,
};
/* supported VDIG1 voltages in milivolts */
static const u16 VDIG1_VSEL_table[] = {
1200, 1500, 1800, 2700,
};
/* supported VDIG2 voltages in milivolts */
static const u16 VDIG2_VSEL_table[] = {
1000, 1100, 1200, 1800,
};
/* supported VPLL voltages in milivolts */
static const u16 VPLL_VSEL_table[] = {
1000, 1100, 1800, 2500,
};
/* supported VDAC voltages in milivolts */
static const u16 VDAC_VSEL_table[] = {
1800, 2600, 2800, 2850,
};
/* supported VAUX1 voltages in milivolts */
static const u16 VAUX1_VSEL_table[] = {
1800, 2500, 2800, 2850,
};
/* supported VAUX2 voltages in milivolts */
static const u16 VAUX2_VSEL_table[] = {
1800, 2800, 2900, 3300,
};
/* supported VAUX33 voltages in milivolts */
static const u16 VAUX33_VSEL_table[] = {
1800, 2000, 2800, 3300,
};
/* supported VMMC voltages in milivolts */
static const u16 VMMC_VSEL_table[] = {
1800, 2800, 3000, 3300,
};
struct tps_info {
const char *name;
unsigned min_uV;
unsigned max_uV;
u8 table_len;
const u16 *table;
};
static struct tps_info tps65910_regs[] = {
{
.name = "VRTC",
},
{
.name = "VIO",
.min_uV = 1500000,
.max_uV = 3300000,
.table_len = ARRAY_SIZE(VIO_VSEL_table),
.table = VIO_VSEL_table,
},
{
.name = "VDD1",
.min_uV = 600000,
.max_uV = 4500000,
},
{
.name = "VDD2",
.min_uV = 600000,
.max_uV = 4500000,
},
{
.name = "VDD3",
.min_uV = 5000000,
.max_uV = 5000000,
.table_len = ARRAY_SIZE(VDD3_VSEL_table),
.table = VDD3_VSEL_table,
},
{
.name = "VDIG1",
.min_uV = 1200000,
.max_uV = 2700000,
.table_len = ARRAY_SIZE(VDIG1_VSEL_table),
.table = VDIG1_VSEL_table,
},
{
.name = "VDIG2",
.min_uV = 1000000,
.max_uV = 1800000,
.table_len = ARRAY_SIZE(VDIG2_VSEL_table),
.table = VDIG2_VSEL_table,
},
{
.name = "VPLL",
.min_uV = 1000000,
.max_uV = 2500000,
.table_len = ARRAY_SIZE(VPLL_VSEL_table),
.table = VPLL_VSEL_table,
},
{
.name = "VDAC",
.min_uV = 1800000,
.max_uV = 2850000,
.table_len = ARRAY_SIZE(VDAC_VSEL_table),
.table = VDAC_VSEL_table,
},
{
.name = "VAUX1",
.min_uV = 1800000,
.max_uV = 2850000,
.table_len = ARRAY_SIZE(VAUX1_VSEL_table),
.table = VAUX1_VSEL_table,
},
{
.name = "VAUX2",
.min_uV = 1800000,
.max_uV = 3300000,
.table_len = ARRAY_SIZE(VAUX2_VSEL_table),
.table = VAUX2_VSEL_table,
},
{
.name = "VAUX33",
.min_uV = 1800000,
.max_uV = 3300000,
.table_len = ARRAY_SIZE(VAUX33_VSEL_table),
.table = VAUX33_VSEL_table,
},
{
.name = "VMMC",
.min_uV = 1800000,
.max_uV = 3300000,
.table_len = ARRAY_SIZE(VMMC_VSEL_table),
.table = VMMC_VSEL_table,
},
};
static struct tps_info tps65911_regs[] = {
{
.name = "VIO",
.min_uV = 1500000,
.max_uV = 3300000,
.table_len = ARRAY_SIZE(VIO_VSEL_table),
.table = VIO_VSEL_table,
},
{
.name = "VDD1",
.min_uV = 600000,
.max_uV = 4500000,
},
{
.name = "VDD2",
.min_uV = 600000,
.max_uV = 4500000,
},
{
.name = "VDDCTRL",
.min_uV = 600000,
.max_uV = 1400000,
},
{
.name = "LDO1",
.min_uV = 1000000,
.max_uV = 3300000,
},
{
.name = "LDO2",
.min_uV = 1000000,
.max_uV = 3300000,
},
{
.name = "LDO3",
.min_uV = 1000000,
.max_uV = 3300000,
},
{
.name = "LDO4",
.min_uV = 1000000,
.max_uV = 3300000,
},
{
.name = "LDO5",
.min_uV = 1000000,
.max_uV = 3300000,
},
{
.name = "LDO6",
.min_uV = 1000000,
.max_uV = 3300000,
},
{
.name = "LDO7",
.min_uV = 1000000,
.max_uV = 3300000,
},
{
.name = "LDO8",
.min_uV = 1000000,
.max_uV = 3300000,
},
};
struct tps65910_reg {
struct regulator_desc desc[TPS65910_NUM_REGULATOR];
struct tps65910 *mfd;
struct regulator_dev *rdev[TPS65910_NUM_REGULATOR];
struct tps_info *info[TPS65910_NUM_REGULATOR];
struct mutex mutex;
int mode;
int (*get_ctrl_reg)(int);
};
static inline int tps65910_read(struct tps65910_reg *pmic, u8 reg)
{
u8 val;
int err;
err = pmic->mfd->read(pmic->mfd, reg, 1, &val);
if (err)
return err;
return val;
}
static inline int tps65910_write(struct tps65910_reg *pmic, u8 reg, u8 val)
{
return pmic->mfd->write(pmic->mfd, reg, 1, &val);
}
static int tps65910_modify_bits(struct tps65910_reg *pmic, u8 reg,
u8 set_mask, u8 clear_mask)
{
int err, data;
mutex_lock(&pmic->mutex);
data = tps65910_read(pmic, reg);
if (data < 0) {
dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg);
err = data;
goto out;
}
data &= ~clear_mask;
data |= set_mask;
err = tps65910_write(pmic, reg, data);
if (err)
dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg);
out:
mutex_unlock(&pmic->mutex);
return err;
}
static int tps65910_reg_read(struct tps65910_reg *pmic, u8 reg)
{
int data;
mutex_lock(&pmic->mutex);
data = tps65910_read(pmic, reg);
if (data < 0)
dev_err(pmic->mfd->dev, "Read from reg 0x%x failed\n", reg);
mutex_unlock(&pmic->mutex);
return data;
}
static int tps65910_reg_write(struct tps65910_reg *pmic, u8 reg, u8 val)
{
int err;
mutex_lock(&pmic->mutex);
err = tps65910_write(pmic, reg, val);
if (err < 0)
dev_err(pmic->mfd->dev, "Write for reg 0x%x failed\n", reg);
mutex_unlock(&pmic->mutex);
return err;
}
static int tps65910_get_ctrl_register(int id)
{
switch (id) {
case TPS65910_REG_VRTC:
return TPS65910_VRTC;
case TPS65910_REG_VIO:
return TPS65910_VIO;
case TPS65910_REG_VDD1:
return TPS65910_VDD1;
case TPS65910_REG_VDD2:
return TPS65910_VDD2;
case TPS65910_REG_VDD3:
return TPS65910_VDD3;
case TPS65910_REG_VDIG1:
return TPS65910_VDIG1;
case TPS65910_REG_VDIG2:
return TPS65910_VDIG2;
case TPS65910_REG_VPLL:
return TPS65910_VPLL;
case TPS65910_REG_VDAC:
return TPS65910_VDAC;
case TPS65910_REG_VAUX1:
return TPS65910_VAUX1;
case TPS65910_REG_VAUX2:
return TPS65910_VAUX2;
case TPS65910_REG_VAUX33:
return TPS65910_VAUX33;
case TPS65910_REG_VMMC:
return TPS65910_VMMC;
default:
return -EINVAL;
}
}
static int tps65911_get_ctrl_register(int id)
{
switch (id) {
case TPS65910_REG_VRTC:
return TPS65910_VRTC;
case TPS65910_REG_VIO:
return TPS65910_VIO;
case TPS65910_REG_VDD1:
return TPS65910_VDD1;
case TPS65910_REG_VDD2:
return TPS65910_VDD2;
case TPS65911_REG_VDDCTRL:
return TPS65911_VDDCTRL;
case TPS65911_REG_LDO1:
return TPS65911_LDO1;
case TPS65911_REG_LDO2:
return TPS65911_LDO2;
case TPS65911_REG_LDO3:
return TPS65911_LDO3;
case TPS65911_REG_LDO4:
return TPS65911_LDO4;
case TPS65911_REG_LDO5:
return TPS65911_LDO5;
case TPS65911_REG_LDO6:
return TPS65911_LDO6;
case TPS65911_REG_LDO7:
return TPS65911_LDO7;
case TPS65911_REG_LDO8:
return TPS65911_LDO8;
default:
return -EINVAL;
}
}
static int tps65910_is_enabled(struct regulator_dev *dev)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
int reg, value, id = rdev_get_id(dev);
reg = pmic->get_ctrl_reg(id);
if (reg < 0)
return reg;
value = tps65910_reg_read(pmic, reg);
if (value < 0)
return value;
return value & TPS65910_SUPPLY_STATE_ENABLED;
}
static int tps65910_enable(struct regulator_dev *dev)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
struct tps65910 *mfd = pmic->mfd;
int reg, id = rdev_get_id(dev);
reg = pmic->get_ctrl_reg(id);
if (reg < 0)
return reg;
return tps65910_set_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED);
}
static int tps65910_disable(struct regulator_dev *dev)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
struct tps65910 *mfd = pmic->mfd;
int reg, id = rdev_get_id(dev);
reg = pmic->get_ctrl_reg(id);
if (reg < 0)
return reg;
return tps65910_clear_bits(mfd, reg, TPS65910_SUPPLY_STATE_ENABLED);
}
static int tps65910_set_mode(struct regulator_dev *dev, unsigned int mode)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
struct tps65910 *mfd = pmic->mfd;
int reg, value, id = rdev_get_id(dev);
reg = pmic->get_ctrl_reg(id);
if (reg < 0)
return reg;
switch (mode) {
case REGULATOR_MODE_NORMAL:
return tps65910_modify_bits(pmic, reg, LDO_ST_ON_BIT,
LDO_ST_MODE_BIT);
case REGULATOR_MODE_IDLE:
value = LDO_ST_ON_BIT | LDO_ST_MODE_BIT;
return tps65910_set_bits(mfd, reg, value);
case REGULATOR_MODE_STANDBY:
return tps65910_clear_bits(mfd, reg, LDO_ST_ON_BIT);
}
return -EINVAL;
}
static unsigned int tps65910_get_mode(struct regulator_dev *dev)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
int reg, value, id = rdev_get_id(dev);
reg = pmic->get_ctrl_reg(id);
if (reg < 0)
return reg;
value = tps65910_reg_read(pmic, reg);
if (value < 0)
return value;
if (value & LDO_ST_ON_BIT)
return REGULATOR_MODE_STANDBY;
else if (value & LDO_ST_MODE_BIT)
return REGULATOR_MODE_IDLE;
else
return REGULATOR_MODE_NORMAL;
}
static int tps65910_get_voltage_dcdc(struct regulator_dev *dev)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
int id = rdev_get_id(dev), voltage = 0;
int opvsel = 0, srvsel = 0, vselmax = 0, mult = 0, sr = 0;
switch (id) {
case TPS65910_REG_VDD1:
opvsel = tps65910_reg_read(pmic, TPS65910_VDD1_OP);
mult = tps65910_reg_read(pmic, TPS65910_VDD1);
mult = (mult & VDD1_VGAIN_SEL_MASK) >> VDD1_VGAIN_SEL_SHIFT;
srvsel = tps65910_reg_read(pmic, TPS65910_VDD1_SR);
sr = opvsel & VDD1_OP_CMD_MASK;
opvsel &= VDD1_OP_SEL_MASK;
srvsel &= VDD1_SR_SEL_MASK;
vselmax = 75;
break;
case TPS65910_REG_VDD2:
opvsel = tps65910_reg_read(pmic, TPS65910_VDD2_OP);
mult = tps65910_reg_read(pmic, TPS65910_VDD2);
mult = (mult & VDD2_VGAIN_SEL_MASK) >> VDD2_VGAIN_SEL_SHIFT;
srvsel = tps65910_reg_read(pmic, TPS65910_VDD2_SR);
sr = opvsel & VDD2_OP_CMD_MASK;
opvsel &= VDD2_OP_SEL_MASK;
srvsel &= VDD2_SR_SEL_MASK;
vselmax = 75;
break;
case TPS65911_REG_VDDCTRL:
opvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_OP);
srvsel = tps65910_reg_read(pmic, TPS65911_VDDCTRL_SR);
sr = opvsel & VDDCTRL_OP_CMD_MASK;
opvsel &= VDDCTRL_OP_SEL_MASK;
srvsel &= VDDCTRL_SR_SEL_MASK;
vselmax = 64;
break;
}
/* multiplier 0 == 1 but 2,3 normal */
if (!mult)
mult=1;
if (sr) {
/* normalise to valid range */
if (srvsel < 3)
srvsel = 3;
if (srvsel > vselmax)
srvsel = vselmax;
srvsel -= 3;
voltage = (srvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100;
} else {
/* normalise to valid range*/
if (opvsel < 3)
opvsel = 3;
if (opvsel > vselmax)
opvsel = vselmax;
opvsel -= 3;
voltage = (opvsel * VDD1_2_OFFSET + VDD1_2_MIN_VOLT) * 100;
}
voltage *= mult;
return voltage;
}
static int tps65910_get_voltage(struct regulator_dev *dev)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
int reg, value, id = rdev_get_id(dev), voltage = 0;
reg = pmic->get_ctrl_reg(id);
if (reg < 0)
return reg;
value = tps65910_reg_read(pmic, reg);
if (value < 0)
return value;
switch (id) {
case TPS65910_REG_VIO:
case TPS65910_REG_VDIG1:
case TPS65910_REG_VDIG2:
case TPS65910_REG_VPLL:
case TPS65910_REG_VDAC:
case TPS65910_REG_VAUX1:
case TPS65910_REG_VAUX2:
case TPS65910_REG_VAUX33:
case TPS65910_REG_VMMC:
value &= LDO_SEL_MASK;
value >>= LDO_SEL_SHIFT;
break;
default:
return -EINVAL;
}
voltage = pmic->info[id]->table[value] * 1000;
return voltage;
}
static int tps65910_get_voltage_vdd3(struct regulator_dev *dev)
{
return 5 * 1000 * 1000;
}
static int tps65911_get_voltage(struct regulator_dev *dev)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
int step_mv, id = rdev_get_id(dev);
u8 value, reg;
reg = pmic->get_ctrl_reg(id);
value = tps65910_reg_read(pmic, reg);
switch (id) {
case TPS65911_REG_LDO1:
case TPS65911_REG_LDO2:
case TPS65911_REG_LDO4:
value &= LDO1_SEL_MASK;
value >>= LDO_SEL_SHIFT;
/* The first 5 values of the selector correspond to 1V */
if (value < 5)
value = 0;
else
value -= 4;
step_mv = 50;
break;
case TPS65911_REG_LDO3:
case TPS65911_REG_LDO5:
case TPS65911_REG_LDO6:
case TPS65911_REG_LDO7:
case TPS65911_REG_LDO8:
value &= LDO3_SEL_MASK;
value >>= LDO_SEL_SHIFT;
/* The first 3 values of the selector correspond to 1V */
if (value < 3)
value = 0;
else
value -= 2;
step_mv = 100;
break;
case TPS65910_REG_VIO:
return pmic->info[id]->table[value] * 1000;
break;
default:
return -EINVAL;
}
return (LDO_MIN_VOLT + value * step_mv) * 1000;
}
static int tps65910_set_voltage_dcdc(struct regulator_dev *dev,
unsigned selector)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
int id = rdev_get_id(dev), vsel;
int dcdc_mult = 0;
switch (id) {
case TPS65910_REG_VDD1:
dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1;
if (dcdc_mult == 1)
dcdc_mult--;
vsel = (selector % VDD1_2_NUM_VOLTS) + 3;
tps65910_modify_bits(pmic, TPS65910_VDD1,
(dcdc_mult << VDD1_VGAIN_SEL_SHIFT),
VDD1_VGAIN_SEL_MASK);
tps65910_reg_write(pmic, TPS65910_VDD1_OP, vsel);
break;
case TPS65910_REG_VDD2:
dcdc_mult = (selector / VDD1_2_NUM_VOLTS) + 1;
if (dcdc_mult == 1)
dcdc_mult--;
vsel = (selector % VDD1_2_NUM_VOLTS) + 3;
tps65910_modify_bits(pmic, TPS65910_VDD2,
(dcdc_mult << VDD2_VGAIN_SEL_SHIFT),
VDD1_VGAIN_SEL_MASK);
tps65910_reg_write(pmic, TPS65910_VDD2_OP, vsel);
break;
case TPS65911_REG_VDDCTRL:
vsel = selector;
tps65910_reg_write(pmic, TPS65911_VDDCTRL_OP, vsel);
}
return 0;
}
static int tps65910_set_voltage(struct regulator_dev *dev, unsigned selector)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
int reg, id = rdev_get_id(dev);
reg = pmic->get_ctrl_reg(id);
if (reg < 0)
return reg;
switch (id) {
case TPS65910_REG_VIO:
case TPS65910_REG_VDIG1:
case TPS65910_REG_VDIG2:
case TPS65910_REG_VPLL:
case TPS65910_REG_VDAC:
case TPS65910_REG_VAUX1:
case TPS65910_REG_VAUX2:
case TPS65910_REG_VAUX33:
case TPS65910_REG_VMMC:
return tps65910_modify_bits(pmic, reg,
(selector << LDO_SEL_SHIFT), LDO_SEL_MASK);
}
return -EINVAL;
}
static int tps65911_set_voltage(struct regulator_dev *dev, unsigned selector)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
int reg, id = rdev_get_id(dev);
reg = pmic->get_ctrl_reg(id);
if (reg < 0)
return reg;
switch (id) {
case TPS65911_REG_LDO1:
case TPS65911_REG_LDO2:
case TPS65911_REG_LDO4:
return tps65910_modify_bits(pmic, reg,
(selector << LDO_SEL_SHIFT), LDO1_SEL_MASK);
case TPS65911_REG_LDO3:
case TPS65911_REG_LDO5:
case TPS65911_REG_LDO6:
case TPS65911_REG_LDO7:
case TPS65911_REG_LDO8:
case TPS65910_REG_VIO:
return tps65910_modify_bits(pmic, reg,
(selector << LDO_SEL_SHIFT), LDO3_SEL_MASK);
}
return -EINVAL;
}
static int tps65910_list_voltage_dcdc(struct regulator_dev *dev,
unsigned selector)
{
int volt, mult = 1, id = rdev_get_id(dev);
switch (id) {
case TPS65910_REG_VDD1:
case TPS65910_REG_VDD2:
mult = (selector / VDD1_2_NUM_VOLTS) + 1;
volt = VDD1_2_MIN_VOLT +
(selector % VDD1_2_NUM_VOLTS) * VDD1_2_OFFSET;
case TPS65911_REG_VDDCTRL:
volt = VDDCTRL_MIN_VOLT + (selector * VDDCTRL_OFFSET);
}
return volt * 100 * mult;
}
static int tps65910_list_voltage(struct regulator_dev *dev,
unsigned selector)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
int id = rdev_get_id(dev), voltage;
if (id < TPS65910_REG_VIO || id > TPS65910_REG_VMMC)
return -EINVAL;
if (selector >= pmic->info[id]->table_len)
return -EINVAL;
else
voltage = pmic->info[id]->table[selector] * 1000;
return voltage;
}
static int tps65911_list_voltage(struct regulator_dev *dev, unsigned selector)
{
struct tps65910_reg *pmic = rdev_get_drvdata(dev);
int step_mv = 0, id = rdev_get_id(dev);
switch(id) {
case TPS65911_REG_LDO1:
case TPS65911_REG_LDO2:
case TPS65911_REG_LDO4:
/* The first 5 values of the selector correspond to 1V */
if (selector < 5)
selector = 0;
else
selector -= 4;
step_mv = 50;
break;
case TPS65911_REG_LDO3:
case TPS65911_REG_LDO5:
case TPS65911_REG_LDO6:
case TPS65911_REG_LDO7:
case TPS65911_REG_LDO8:
/* The first 3 values of the selector correspond to 1V */
if (selector < 3)
selector = 0;
else
selector -= 2;
step_mv = 100;
break;
case TPS65910_REG_VIO:
return pmic->info[id]->table[selector] * 1000;
default:
return -EINVAL;
}
return (LDO_MIN_VOLT + selector * step_mv) * 1000;
}
/* Regulator ops (except VRTC) */
static struct regulator_ops tps65910_ops_dcdc = {
.is_enabled = tps65910_is_enabled,
.enable = tps65910_enable,
.disable = tps65910_disable,
.set_mode = tps65910_set_mode,
.get_mode = tps65910_get_mode,
.get_voltage = tps65910_get_voltage_dcdc,
.set_voltage_sel = tps65910_set_voltage_dcdc,
.list_voltage = tps65910_list_voltage_dcdc,
};
static struct regulator_ops tps65910_ops_vdd3 = {
.is_enabled = tps65910_is_enabled,
.enable = tps65910_enable,
.disable = tps65910_disable,
.set_mode = tps65910_set_mode,
.get_mode = tps65910_get_mode,
.get_voltage = tps65910_get_voltage_vdd3,
.list_voltage = tps65910_list_voltage,
};
static struct regulator_ops tps65910_ops = {
.is_enabled = tps65910_is_enabled,
.enable = tps65910_enable,
.disable = tps65910_disable,
.set_mode = tps65910_set_mode,
.get_mode = tps65910_get_mode,
.get_voltage = tps65910_get_voltage,
.set_voltage_sel = tps65910_set_voltage,
.list_voltage = tps65910_list_voltage,
};
static struct regulator_ops tps65911_ops = {
.is_enabled = tps65910_is_enabled,
.enable = tps65910_enable,
.disable = tps65910_disable,
.set_mode = tps65910_set_mode,
.get_mode = tps65910_get_mode,
.get_voltage = tps65911_get_voltage,
.set_voltage_sel = tps65911_set_voltage,
.list_voltage = tps65911_list_voltage,
};
static __devinit int tps65910_probe(struct platform_device *pdev)
{
struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
struct tps_info *info;
struct regulator_init_data *reg_data;
struct regulator_dev *rdev;
struct tps65910_reg *pmic;
struct tps65910_board *pmic_plat_data;
int i, err;
pmic_plat_data = dev_get_platdata(tps65910->dev);
if (!pmic_plat_data)
return -EINVAL;
reg_data = pmic_plat_data->tps65910_pmic_init_data;
pmic = kzalloc(sizeof(*pmic), GFP_KERNEL);
if (!pmic)
return -ENOMEM;
mutex_init(&pmic->mutex);
pmic->mfd = tps65910;
platform_set_drvdata(pdev, pmic);
/* Give control of all register to control port */
tps65910_set_bits(pmic->mfd, TPS65910_DEVCTRL,
DEVCTRL_SR_CTL_I2C_SEL_MASK);
switch(tps65910_chip_id(tps65910)) {
case TPS65910:
pmic->get_ctrl_reg = &tps65910_get_ctrl_register;
info = tps65910_regs;
case TPS65911:
pmic->get_ctrl_reg = &tps65911_get_ctrl_register;
info = tps65911_regs;
default:
pr_err("Invalid tps chip version\n");
return -ENODEV;
}
for (i = 0; i < TPS65910_NUM_REGULATOR; i++, info++, reg_data++) {
/* Register the regulators */
pmic->info[i] = info;
pmic->desc[i].name = info->name;
pmic->desc[i].id = i;
pmic->desc[i].n_voltages = info->table_len;
if (i == TPS65910_REG_VDD1 || i == TPS65910_REG_VDD2) {
pmic->desc[i].ops = &tps65910_ops_dcdc;
} else if (i == TPS65910_REG_VDD3) {
if (tps65910_chip_id(tps65910) == TPS65910)
pmic->desc[i].ops = &tps65910_ops_vdd3;
else
pmic->desc[i].ops = &tps65910_ops_dcdc;
} else {
if (tps65910_chip_id(tps65910) == TPS65910)
pmic->desc[i].ops = &tps65910_ops;
else
pmic->desc[i].ops = &tps65911_ops;
}
pmic->desc[i].type = REGULATOR_VOLTAGE;
pmic->desc[i].owner = THIS_MODULE;
rdev = regulator_register(&pmic->desc[i],
tps65910->dev, reg_data, pmic);
if (IS_ERR(rdev)) {
dev_err(tps65910->dev,
"failed to register %s regulator\n",
pdev->name);
err = PTR_ERR(rdev);
goto err;
}
/* Save regulator for cleanup */
pmic->rdev[i] = rdev;
}
return 0;
err:
while (--i >= 0)
regulator_unregister(pmic->rdev[i]);
kfree(pmic);
return err;
}
static int __devexit tps65910_remove(struct platform_device *pdev)
{
struct tps65910_reg *tps65910_reg = platform_get_drvdata(pdev);
int i;
for (i = 0; i < TPS65910_NUM_REGULATOR; i++)
regulator_unregister(tps65910_reg->rdev[i]);
kfree(tps65910_reg);
return 0;
}
static struct platform_driver tps65910_driver = {
.driver = {
.name = "tps65910-pmic",
.owner = THIS_MODULE,
},
.probe = tps65910_probe,
.remove = __devexit_p(tps65910_remove),
};
static int __init tps65910_init(void)
{
return platform_driver_register(&tps65910_driver);
}
subsys_initcall(tps65910_init);
static void __exit tps65910_cleanup(void)
{
platform_driver_unregister(&tps65910_driver);
}
module_exit(tps65910_cleanup);
MODULE_AUTHOR("Graeme Gregory <gg@slimlogic.co.uk>");
MODULE_DESCRIPTION("TPS6507x voltage regulator driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:tps65910-pmic");
...@@ -51,8 +51,13 @@ struct twlreg_info { ...@@ -51,8 +51,13 @@ struct twlreg_info {
u16 min_mV; u16 min_mV;
u16 max_mV; u16 max_mV;
u8 flags;
/* used by regulator core */ /* used by regulator core */
struct regulator_desc desc; struct regulator_desc desc;
/* chip specific features */
unsigned long features;
}; };
...@@ -70,12 +75,35 @@ struct twlreg_info { ...@@ -70,12 +75,35 @@ struct twlreg_info {
#define VREG_TRANS 1 #define VREG_TRANS 1
#define VREG_STATE 2 #define VREG_STATE 2
#define VREG_VOLTAGE 3 #define VREG_VOLTAGE 3
#define VREG_VOLTAGE_SMPS 4
/* TWL6030 Misc register offsets */ /* TWL6030 Misc register offsets */
#define VREG_BC_ALL 1 #define VREG_BC_ALL 1
#define VREG_BC_REF 2 #define VREG_BC_REF 2
#define VREG_BC_PROC 3 #define VREG_BC_PROC 3
#define VREG_BC_CLK_RST 4 #define VREG_BC_CLK_RST 4
/* TWL6030 LDO register values for CFG_STATE */
#define TWL6030_CFG_STATE_OFF 0x00
#define TWL6030_CFG_STATE_ON 0x01
#define TWL6030_CFG_STATE_OFF2 0x02
#define TWL6030_CFG_STATE_SLEEP 0x03
#define TWL6030_CFG_STATE_GRP_SHIFT 5
#define TWL6030_CFG_STATE_APP_SHIFT 2
#define TWL6030_CFG_STATE_APP_MASK (0x03 << TWL6030_CFG_STATE_APP_SHIFT)
#define TWL6030_CFG_STATE_APP(v) (((v) & TWL6030_CFG_STATE_APP_MASK) >>\
TWL6030_CFG_STATE_APP_SHIFT)
/* Flags for SMPS Voltage reading */
#define SMPS_OFFSET_EN BIT(0)
#define SMPS_EXTENDED_EN BIT(1)
/* twl6025 SMPS EPROM values */
#define TWL6030_SMPS_OFFSET 0xB0
#define TWL6030_SMPS_MULT 0xB3
#define SMPS_MULTOFFSET_SMPS4 BIT(0)
#define SMPS_MULTOFFSET_VIO BIT(1)
#define SMPS_MULTOFFSET_SMPS3 BIT(6)
static inline int static inline int
twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset) twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset)
{ {
...@@ -118,21 +146,38 @@ static int twlreg_grp(struct regulator_dev *rdev) ...@@ -118,21 +146,38 @@ static int twlreg_grp(struct regulator_dev *rdev)
#define P2_GRP_6030 BIT(1) /* "peripherals" */ #define P2_GRP_6030 BIT(1) /* "peripherals" */
#define P1_GRP_6030 BIT(0) /* CPU/Linux */ #define P1_GRP_6030 BIT(0) /* CPU/Linux */
static int twlreg_is_enabled(struct regulator_dev *rdev) static int twl4030reg_is_enabled(struct regulator_dev *rdev)
{ {
int state = twlreg_grp(rdev); int state = twlreg_grp(rdev);
if (state < 0) if (state < 0)
return state; return state;
if (twl_class_is_4030()) return state & P1_GRP_4030;
state &= P1_GRP_4030; }
static int twl6030reg_is_enabled(struct regulator_dev *rdev)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
int grp = 0, val;
if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
if (grp < 0)
return grp;
if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
grp &= P1_GRP_6030;
else else
state &= P1_GRP_6030; grp = 1;
return state;
val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
val = TWL6030_CFG_STATE_APP(val);
return grp && (val == TWL6030_CFG_STATE_ON);
} }
static int twlreg_enable(struct regulator_dev *rdev) static int twl4030reg_enable(struct regulator_dev *rdev)
{ {
struct twlreg_info *info = rdev_get_drvdata(rdev); struct twlreg_info *info = rdev_get_drvdata(rdev);
int grp; int grp;
...@@ -142,10 +187,7 @@ static int twlreg_enable(struct regulator_dev *rdev) ...@@ -142,10 +187,7 @@ static int twlreg_enable(struct regulator_dev *rdev)
if (grp < 0) if (grp < 0)
return grp; return grp;
if (twl_class_is_4030())
grp |= P1_GRP_4030; grp |= P1_GRP_4030;
else
grp |= P1_GRP_6030;
ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
...@@ -154,29 +196,63 @@ static int twlreg_enable(struct regulator_dev *rdev) ...@@ -154,29 +196,63 @@ static int twlreg_enable(struct regulator_dev *rdev)
return ret; return ret;
} }
static int twlreg_disable(struct regulator_dev *rdev) static int twl6030reg_enable(struct regulator_dev *rdev)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
int grp = 0;
int ret;
if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
if (grp < 0)
return grp;
ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
grp << TWL6030_CFG_STATE_GRP_SHIFT |
TWL6030_CFG_STATE_ON);
udelay(info->delay);
return ret;
}
static int twl4030reg_disable(struct regulator_dev *rdev)
{ {
struct twlreg_info *info = rdev_get_drvdata(rdev); struct twlreg_info *info = rdev_get_drvdata(rdev);
int grp; int grp;
int ret;
grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP); grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
if (grp < 0) if (grp < 0)
return grp; return grp;
if (twl_class_is_4030())
grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030); grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030);
else
grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030);
return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp); ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
return ret;
} }
static int twlreg_get_status(struct regulator_dev *rdev) static int twl6030reg_disable(struct regulator_dev *rdev)
{ {
int state = twlreg_grp(rdev); struct twlreg_info *info = rdev_get_drvdata(rdev);
int grp = 0;
int ret;
if (twl_class_is_6030()) if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
return 0; /* FIXME return for 6030 regulator */ grp = P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030;
/* For 6030, set the off state for all grps enabled */
ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE,
(grp) << TWL6030_CFG_STATE_GRP_SHIFT |
TWL6030_CFG_STATE_OFF);
return ret;
}
static int twl4030reg_get_status(struct regulator_dev *rdev)
{
int state = twlreg_grp(rdev);
if (state < 0) if (state < 0)
return state; return state;
...@@ -190,15 +266,39 @@ static int twlreg_get_status(struct regulator_dev *rdev) ...@@ -190,15 +266,39 @@ static int twlreg_get_status(struct regulator_dev *rdev)
: REGULATOR_STATUS_STANDBY; : REGULATOR_STATUS_STANDBY;
} }
static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode) static int twl6030reg_get_status(struct regulator_dev *rdev)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
int val;
val = twlreg_grp(rdev);
if (val < 0)
return val;
val = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_STATE);
switch (TWL6030_CFG_STATE_APP(val)) {
case TWL6030_CFG_STATE_ON:
return REGULATOR_STATUS_NORMAL;
case TWL6030_CFG_STATE_SLEEP:
return REGULATOR_STATUS_STANDBY;
case TWL6030_CFG_STATE_OFF:
case TWL6030_CFG_STATE_OFF2:
default:
break;
}
return REGULATOR_STATUS_OFF;
}
static int twl4030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
{ {
struct twlreg_info *info = rdev_get_drvdata(rdev); struct twlreg_info *info = rdev_get_drvdata(rdev);
unsigned message; unsigned message;
int status; int status;
if (twl_class_is_6030())
return 0; /* FIXME return for 6030 regulator */
/* We can only set the mode through state machine commands... */ /* We can only set the mode through state machine commands... */
switch (mode) { switch (mode) {
case REGULATOR_MODE_NORMAL: case REGULATOR_MODE_NORMAL:
...@@ -227,6 +327,36 @@ static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode) ...@@ -227,6 +327,36 @@ static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode)
message & 0xff, TWL4030_PM_MASTER_PB_WORD_LSB); message & 0xff, TWL4030_PM_MASTER_PB_WORD_LSB);
} }
static int twl6030reg_set_mode(struct regulator_dev *rdev, unsigned mode)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
int grp = 0;
int val;
if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
if (grp < 0)
return grp;
/* Compose the state register settings */
val = grp << TWL6030_CFG_STATE_GRP_SHIFT;
/* We can only set the mode through state machine commands... */
switch (mode) {
case REGULATOR_MODE_NORMAL:
val |= TWL6030_CFG_STATE_ON;
break;
case REGULATOR_MODE_STANDBY:
val |= TWL6030_CFG_STATE_SLEEP;
break;
default:
return -EINVAL;
}
return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_STATE, val);
}
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
/* /*
...@@ -375,13 +505,13 @@ static struct regulator_ops twl4030ldo_ops = { ...@@ -375,13 +505,13 @@ static struct regulator_ops twl4030ldo_ops = {
.set_voltage = twl4030ldo_set_voltage, .set_voltage = twl4030ldo_set_voltage,
.get_voltage = twl4030ldo_get_voltage, .get_voltage = twl4030ldo_get_voltage,
.enable = twlreg_enable, .enable = twl4030reg_enable,
.disable = twlreg_disable, .disable = twl4030reg_disable,
.is_enabled = twlreg_is_enabled, .is_enabled = twl4030reg_is_enabled,
.set_mode = twlreg_set_mode, .set_mode = twl4030reg_set_mode,
.get_status = twlreg_get_status, .get_status = twl4030reg_get_status,
}; };
static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index) static int twl6030ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
...@@ -433,13 +563,13 @@ static struct regulator_ops twl6030ldo_ops = { ...@@ -433,13 +563,13 @@ static struct regulator_ops twl6030ldo_ops = {
.set_voltage = twl6030ldo_set_voltage, .set_voltage = twl6030ldo_set_voltage,
.get_voltage = twl6030ldo_get_voltage, .get_voltage = twl6030ldo_get_voltage,
.enable = twlreg_enable, .enable = twl6030reg_enable,
.disable = twlreg_disable, .disable = twl6030reg_disable,
.is_enabled = twlreg_is_enabled, .is_enabled = twl6030reg_is_enabled,
.set_mode = twlreg_set_mode, .set_mode = twl6030reg_set_mode,
.get_status = twlreg_get_status, .get_status = twl6030reg_get_status,
}; };
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
...@@ -461,25 +591,242 @@ static int twlfixed_get_voltage(struct regulator_dev *rdev) ...@@ -461,25 +591,242 @@ static int twlfixed_get_voltage(struct regulator_dev *rdev)
return info->min_mV * 1000; return info->min_mV * 1000;
} }
static struct regulator_ops twlfixed_ops = { static struct regulator_ops twl4030fixed_ops = {
.list_voltage = twlfixed_list_voltage, .list_voltage = twlfixed_list_voltage,
.get_voltage = twlfixed_get_voltage, .get_voltage = twlfixed_get_voltage,
.enable = twlreg_enable, .enable = twl4030reg_enable,
.disable = twlreg_disable, .disable = twl4030reg_disable,
.is_enabled = twlreg_is_enabled, .is_enabled = twl4030reg_is_enabled,
.set_mode = twlreg_set_mode, .set_mode = twl4030reg_set_mode,
.get_status = twlreg_get_status, .get_status = twl4030reg_get_status,
};
static struct regulator_ops twl6030fixed_ops = {
.list_voltage = twlfixed_list_voltage,
.get_voltage = twlfixed_get_voltage,
.enable = twl6030reg_enable,
.disable = twl6030reg_disable,
.is_enabled = twl6030reg_is_enabled,
.set_mode = twl6030reg_set_mode,
.get_status = twl6030reg_get_status,
}; };
static struct regulator_ops twl6030_fixed_resource = { static struct regulator_ops twl6030_fixed_resource = {
.enable = twlreg_enable, .enable = twl6030reg_enable,
.disable = twlreg_disable, .disable = twl6030reg_disable,
.is_enabled = twlreg_is_enabled, .is_enabled = twl6030reg_is_enabled,
.get_status = twlreg_get_status, .get_status = twl6030reg_get_status,
};
/*
* SMPS status and control
*/
static int twl6030smps_list_voltage(struct regulator_dev *rdev, unsigned index)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
int voltage = 0;
switch (info->flags) {
case SMPS_OFFSET_EN:
voltage = 100000;
/* fall through */
case 0:
switch (index) {
case 0:
voltage = 0;
break;
case 58:
voltage = 1350 * 1000;
break;
case 59:
voltage = 1500 * 1000;
break;
case 60:
voltage = 1800 * 1000;
break;
case 61:
voltage = 1900 * 1000;
break;
case 62:
voltage = 2100 * 1000;
break;
default:
voltage += (600000 + (12500 * (index - 1)));
}
break;
case SMPS_EXTENDED_EN:
switch (index) {
case 0:
voltage = 0;
break;
case 58:
voltage = 2084 * 1000;
break;
case 59:
voltage = 2315 * 1000;
break;
case 60:
voltage = 2778 * 1000;
break;
case 61:
voltage = 2932 * 1000;
break;
case 62:
voltage = 3241 * 1000;
break;
default:
voltage = (1852000 + (38600 * (index - 1)));
}
break;
case SMPS_OFFSET_EN | SMPS_EXTENDED_EN:
switch (index) {
case 0:
voltage = 0;
break;
case 58:
voltage = 4167 * 1000;
break;
case 59:
voltage = 2315 * 1000;
break;
case 60:
voltage = 2778 * 1000;
break;
case 61:
voltage = 2932 * 1000;
break;
case 62:
voltage = 3241 * 1000;
break;
default:
voltage = (2161000 + (38600 * (index - 1)));
}
break;
}
return voltage;
}
static int
twl6030smps_set_voltage(struct regulator_dev *rdev, int min_uV, int max_uV,
unsigned int *selector)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
int vsel = 0;
switch (info->flags) {
case 0:
if (min_uV == 0)
vsel = 0;
else if ((min_uV >= 600000) && (max_uV <= 1300000)) {
vsel = (min_uV - 600000) / 125;
if (vsel % 100)
vsel += 100;
vsel /= 100;
vsel++;
}
/* Values 1..57 for vsel are linear and can be calculated
* values 58..62 are non linear.
*/
else if ((min_uV > 1900000) && (max_uV >= 2100000))
vsel = 62;
else if ((min_uV > 1800000) && (max_uV >= 1900000))
vsel = 61;
else if ((min_uV > 1500000) && (max_uV >= 1800000))
vsel = 60;
else if ((min_uV > 1350000) && (max_uV >= 1500000))
vsel = 59;
else if ((min_uV > 1300000) && (max_uV >= 1350000))
vsel = 58;
else
return -EINVAL;
break;
case SMPS_OFFSET_EN:
if (min_uV == 0)
vsel = 0;
else if ((min_uV >= 700000) && (max_uV <= 1420000)) {
vsel = (min_uV - 700000) / 125;
if (vsel % 100)
vsel += 100;
vsel /= 100;
vsel++;
}
/* Values 1..57 for vsel are linear and can be calculated
* values 58..62 are non linear.
*/
else if ((min_uV > 1900000) && (max_uV >= 2100000))
vsel = 62;
else if ((min_uV > 1800000) && (max_uV >= 1900000))
vsel = 61;
else if ((min_uV > 1350000) && (max_uV >= 1800000))
vsel = 60;
else if ((min_uV > 1350000) && (max_uV >= 1500000))
vsel = 59;
else if ((min_uV > 1300000) && (max_uV >= 1350000))
vsel = 58;
else
return -EINVAL;
break;
case SMPS_EXTENDED_EN:
if (min_uV == 0)
vsel = 0;
else if ((min_uV >= 1852000) && (max_uV <= 4013600)) {
vsel = (min_uV - 1852000) / 386;
if (vsel % 100)
vsel += 100;
vsel /= 100;
vsel++;
}
break;
case SMPS_OFFSET_EN|SMPS_EXTENDED_EN:
if (min_uV == 0)
vsel = 0;
else if ((min_uV >= 2161000) && (max_uV <= 4321000)) {
vsel = (min_uV - 1852000) / 386;
if (vsel % 100)
vsel += 100;
vsel /= 100;
vsel++;
}
break;
}
*selector = vsel;
return twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS,
vsel);
}
static int twl6030smps_get_voltage_sel(struct regulator_dev *rdev)
{
struct twlreg_info *info = rdev_get_drvdata(rdev);
return twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_VOLTAGE_SMPS);
}
static struct regulator_ops twlsmps_ops = {
.list_voltage = twl6030smps_list_voltage,
.set_voltage = twl6030smps_set_voltage,
.get_voltage_sel = twl6030smps_get_voltage_sel,
.enable = twl6030reg_enable,
.disable = twl6030reg_disable,
.is_enabled = twl6030reg_is_enabled,
.set_mode = twl6030reg_set_mode,
.get_status = twl6030reg_get_status,
}; };
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
...@@ -487,11 +834,10 @@ static struct regulator_ops twl6030_fixed_resource = { ...@@ -487,11 +834,10 @@ static struct regulator_ops twl6030_fixed_resource = {
#define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ #define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
remap_conf) \ remap_conf) \
TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
remap_conf, TWL4030) remap_conf, TWL4030, twl4030fixed_ops)
#define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ #define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay) \
remap_conf) \
TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \ TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
remap_conf, TWL6030) 0x0, TWL6030, twl6030fixed_ops)
#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \ #define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) { \
.base = offset, \ .base = offset, \
...@@ -510,13 +856,11 @@ static struct regulator_ops twl6030_fixed_resource = { ...@@ -510,13 +856,11 @@ static struct regulator_ops twl6030_fixed_resource = {
}, \ }, \
} }
#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num, \ #define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num) { \
remap_conf) { \
.base = offset, \ .base = offset, \
.id = num, \ .id = num, \
.min_mV = min_mVolts, \ .min_mV = min_mVolts, \
.max_mV = max_mVolts, \ .max_mV = max_mVolts, \
.remap = remap_conf, \
.desc = { \ .desc = { \
.name = #label, \ .name = #label, \
.id = TWL6030_REG_##label, \ .id = TWL6030_REG_##label, \
...@@ -527,9 +871,23 @@ static struct regulator_ops twl6030_fixed_resource = { ...@@ -527,9 +871,23 @@ static struct regulator_ops twl6030_fixed_resource = {
}, \ }, \
} }
#define TWL6025_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num) { \
.base = offset, \
.id = num, \
.min_mV = min_mVolts, \
.max_mV = max_mVolts, \
.desc = { \
.name = #label, \
.id = TWL6025_REG_##label, \
.n_voltages = ((max_mVolts - min_mVolts)/100) + 1, \
.ops = &twl6030ldo_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}, \
}
#define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \ #define TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, remap_conf, \
family) { \ family, operations) { \
.base = offset, \ .base = offset, \
.id = num, \ .id = num, \
.min_mV = mVolts, \ .min_mV = mVolts, \
...@@ -539,17 +897,16 @@ static struct regulator_ops twl6030_fixed_resource = { ...@@ -539,17 +897,16 @@ static struct regulator_ops twl6030_fixed_resource = {
.name = #label, \ .name = #label, \
.id = family##_REG_##label, \ .id = family##_REG_##label, \
.n_voltages = 1, \ .n_voltages = 1, \
.ops = &twlfixed_ops, \ .ops = &operations, \
.type = REGULATOR_VOLTAGE, \ .type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \ .owner = THIS_MODULE, \
}, \ }, \
} }
#define TWL6030_FIXED_RESOURCE(label, offset, num, turnon_delay, remap_conf) { \ #define TWL6030_FIXED_RESOURCE(label, offset, num, turnon_delay) { \
.base = offset, \ .base = offset, \
.id = num, \ .id = num, \
.delay = turnon_delay, \ .delay = turnon_delay, \
.remap = remap_conf, \
.desc = { \ .desc = { \
.name = #label, \ .name = #label, \
.id = TWL6030_REG_##label, \ .id = TWL6030_REG_##label, \
...@@ -559,6 +916,21 @@ static struct regulator_ops twl6030_fixed_resource = { ...@@ -559,6 +916,21 @@ static struct regulator_ops twl6030_fixed_resource = {
}, \ }, \
} }
#define TWL6025_ADJUSTABLE_SMPS(label, offset, num) { \
.base = offset, \
.id = num, \
.min_mV = 600, \
.max_mV = 2100, \
.desc = { \
.name = #label, \
.id = TWL6025_REG_##label, \
.n_voltages = 63, \
.ops = &twlsmps_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}, \
}
/* /*
* We list regulators here if systems need some level of * We list regulators here if systems need some level of
* software control over them after boot. * software control over them after boot.
...@@ -589,19 +961,52 @@ static struct twlreg_info twl_regs[] = { ...@@ -589,19 +961,52 @@ static struct twlreg_info twl_regs[] = {
/* 6030 REG with base as PMC Slave Misc : 0x0030 */ /* 6030 REG with base as PMC Slave Misc : 0x0030 */
/* Turnon-delay and remap configuration values for 6030 are not /* Turnon-delay and remap configuration values for 6030 are not
verified since the specification is not public */ verified since the specification is not public */
TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300, 1, 0x21), TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300, 1),
TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 2, 0x21), TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 2),
TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 3, 0x21), TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 3),
TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 4, 0x21), TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 4),
TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 5, 0x21), TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 5),
TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 7, 0x21), TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 7),
TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x21), TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0),
TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x21), TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0),
TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x21), TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0),
TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0, 0x21), TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0),
TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 48, 0, 0x21), TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 48, 0),
/* 6025 are renamed compared to 6030 versions */
TWL6025_ADJUSTABLE_LDO(LDO2, 0x54, 1000, 3300, 1),
TWL6025_ADJUSTABLE_LDO(LDO4, 0x58, 1000, 3300, 2),
TWL6025_ADJUSTABLE_LDO(LDO3, 0x5c, 1000, 3300, 3),
TWL6025_ADJUSTABLE_LDO(LDO5, 0x68, 1000, 3300, 4),
TWL6025_ADJUSTABLE_LDO(LDO1, 0x6c, 1000, 3300, 5),
TWL6025_ADJUSTABLE_LDO(LDO7, 0x74, 1000, 3300, 7),
TWL6025_ADJUSTABLE_LDO(LDO6, 0x60, 1000, 3300, 16),
TWL6025_ADJUSTABLE_LDO(LDOLN, 0x64, 1000, 3300, 17),
TWL6025_ADJUSTABLE_LDO(LDOUSB, 0x70, 1000, 3300, 18),
TWL6025_ADJUSTABLE_SMPS(SMPS3, 0x34, 1),
TWL6025_ADJUSTABLE_SMPS(SMPS4, 0x10, 2),
TWL6025_ADJUSTABLE_SMPS(VIO, 0x16, 3),
}; };
static u8 twl_get_smps_offset(void)
{
u8 value;
twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value,
TWL6030_SMPS_OFFSET);
return value;
}
static u8 twl_get_smps_mult(void)
{
u8 value;
twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &value,
TWL6030_SMPS_MULT);
return value;
}
static int __devinit twlreg_probe(struct platform_device *pdev) static int __devinit twlreg_probe(struct platform_device *pdev)
{ {
int i; int i;
...@@ -623,6 +1028,9 @@ static int __devinit twlreg_probe(struct platform_device *pdev) ...@@ -623,6 +1028,9 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
if (!initdata) if (!initdata)
return -EINVAL; return -EINVAL;
/* copy the features into regulator data */
info->features = (unsigned long)initdata->driver_data;
/* Constrain board-specific capabilities according to what /* Constrain board-specific capabilities according to what
* this driver and the chip itself can actually do. * this driver and the chip itself can actually do.
*/ */
...@@ -645,6 +1053,27 @@ static int __devinit twlreg_probe(struct platform_device *pdev) ...@@ -645,6 +1053,27 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
break; break;
} }
switch (pdev->id) {
case TWL6025_REG_SMPS3:
if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS3)
info->flags |= SMPS_EXTENDED_EN;
if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS3)
info->flags |= SMPS_OFFSET_EN;
break;
case TWL6025_REG_SMPS4:
if (twl_get_smps_mult() & SMPS_MULTOFFSET_SMPS4)
info->flags |= SMPS_EXTENDED_EN;
if (twl_get_smps_offset() & SMPS_MULTOFFSET_SMPS4)
info->flags |= SMPS_OFFSET_EN;
break;
case TWL6025_REG_VIO:
if (twl_get_smps_mult() & SMPS_MULTOFFSET_VIO)
info->flags |= SMPS_EXTENDED_EN;
if (twl_get_smps_offset() & SMPS_MULTOFFSET_VIO)
info->flags |= SMPS_OFFSET_EN;
break;
}
rdev = regulator_register(&info->desc, &pdev->dev, initdata, info); rdev = regulator_register(&info->desc, &pdev->dev, initdata, info);
if (IS_ERR(rdev)) { if (IS_ERR(rdev)) {
dev_err(&pdev->dev, "can't register %s, %ld\n", dev_err(&pdev->dev, "can't register %s, %ld\n",
...@@ -653,6 +1082,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev) ...@@ -653,6 +1082,7 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
} }
platform_set_drvdata(pdev, rdev); platform_set_drvdata(pdev, rdev);
if (twl_class_is_4030())
twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP, twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP,
info->remap); info->remap);
......
...@@ -600,7 +600,6 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev) ...@@ -600,7 +600,6 @@ static __devinit int wm831x_buckv_probe(struct platform_device *pdev)
static __devexit int wm831x_buckv_remove(struct platform_device *pdev) static __devexit int wm831x_buckv_remove(struct platform_device *pdev)
{ {
struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
struct wm831x *wm831x = dcdc->wm831x;
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
...@@ -776,7 +775,6 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev) ...@@ -776,7 +775,6 @@ static __devinit int wm831x_buckp_probe(struct platform_device *pdev)
static __devexit int wm831x_buckp_remove(struct platform_device *pdev) static __devexit int wm831x_buckp_remove(struct platform_device *pdev)
{ {
struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev); struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
struct wm831x *wm831x = dcdc->wm831x;
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
......
...@@ -55,7 +55,7 @@ static int wm8400_ldo_list_voltage(struct regulator_dev *dev, ...@@ -55,7 +55,7 @@ static int wm8400_ldo_list_voltage(struct regulator_dev *dev,
return 1600000 + ((selector - 14) * 100000); return 1600000 + ((selector - 14) * 100000);
} }
static int wm8400_ldo_get_voltage(struct regulator_dev *dev) static int wm8400_ldo_get_voltage_sel(struct regulator_dev *dev)
{ {
struct wm8400 *wm8400 = rdev_get_drvdata(dev); struct wm8400 *wm8400 = rdev_get_drvdata(dev);
u16 val; u16 val;
...@@ -63,7 +63,7 @@ static int wm8400_ldo_get_voltage(struct regulator_dev *dev) ...@@ -63,7 +63,7 @@ static int wm8400_ldo_get_voltage(struct regulator_dev *dev)
val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev)); val = wm8400_reg_read(wm8400, WM8400_LDO1_CONTROL + rdev_get_id(dev));
val &= WM8400_LDO1_VSEL_MASK; val &= WM8400_LDO1_VSEL_MASK;
return wm8400_ldo_list_voltage(dev, val); return val;
} }
static int wm8400_ldo_set_voltage(struct regulator_dev *dev, static int wm8400_ldo_set_voltage(struct regulator_dev *dev,
...@@ -104,7 +104,7 @@ static struct regulator_ops wm8400_ldo_ops = { ...@@ -104,7 +104,7 @@ static struct regulator_ops wm8400_ldo_ops = {
.enable = wm8400_ldo_enable, .enable = wm8400_ldo_enable,
.disable = wm8400_ldo_disable, .disable = wm8400_ldo_disable,
.list_voltage = wm8400_ldo_list_voltage, .list_voltage = wm8400_ldo_list_voltage,
.get_voltage = wm8400_ldo_get_voltage, .get_voltage_sel = wm8400_ldo_get_voltage_sel,
.set_voltage = wm8400_ldo_set_voltage, .set_voltage = wm8400_ldo_set_voltage,
}; };
...@@ -145,7 +145,7 @@ static int wm8400_dcdc_list_voltage(struct regulator_dev *dev, ...@@ -145,7 +145,7 @@ static int wm8400_dcdc_list_voltage(struct regulator_dev *dev,
return 850000 + (selector * 25000); return 850000 + (selector * 25000);
} }
static int wm8400_dcdc_get_voltage(struct regulator_dev *dev) static int wm8400_dcdc_get_voltage_sel(struct regulator_dev *dev)
{ {
struct wm8400 *wm8400 = rdev_get_drvdata(dev); struct wm8400 *wm8400 = rdev_get_drvdata(dev);
u16 val; u16 val;
...@@ -154,7 +154,7 @@ static int wm8400_dcdc_get_voltage(struct regulator_dev *dev) ...@@ -154,7 +154,7 @@ static int wm8400_dcdc_get_voltage(struct regulator_dev *dev)
val = wm8400_reg_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset); val = wm8400_reg_read(wm8400, WM8400_DCDC1_CONTROL_1 + offset);
val &= WM8400_DC1_VSEL_MASK; val &= WM8400_DC1_VSEL_MASK;
return 850000 + (25000 * val); return val;
} }
static int wm8400_dcdc_set_voltage(struct regulator_dev *dev, static int wm8400_dcdc_set_voltage(struct regulator_dev *dev,
...@@ -261,7 +261,7 @@ static struct regulator_ops wm8400_dcdc_ops = { ...@@ -261,7 +261,7 @@ static struct regulator_ops wm8400_dcdc_ops = {
.enable = wm8400_dcdc_enable, .enable = wm8400_dcdc_enable,
.disable = wm8400_dcdc_disable, .disable = wm8400_dcdc_disable,
.list_voltage = wm8400_dcdc_list_voltage, .list_voltage = wm8400_dcdc_list_voltage,
.get_voltage = wm8400_dcdc_get_voltage, .get_voltage_sel = wm8400_dcdc_get_voltage_sel,
.set_voltage = wm8400_dcdc_set_voltage, .set_voltage = wm8400_dcdc_set_voltage,
.get_mode = wm8400_dcdc_get_mode, .get_mode = wm8400_dcdc_get_mode,
.set_mode = wm8400_dcdc_set_mode, .set_mode = wm8400_dcdc_set_mode,
......
...@@ -100,6 +100,7 @@ struct twl6030_usb { ...@@ -100,6 +100,7 @@ struct twl6030_usb {
u8 linkstat; u8 linkstat;
u8 asleep; u8 asleep;
bool irq_enabled; bool irq_enabled;
unsigned long features;
}; };
#define xceiv_to_twl(x) container_of((x), struct twl6030_usb, otg) #define xceiv_to_twl(x) container_of((x), struct twl6030_usb, otg)
...@@ -204,6 +205,12 @@ static int twl6030_start_srp(struct otg_transceiver *x) ...@@ -204,6 +205,12 @@ static int twl6030_start_srp(struct otg_transceiver *x)
static int twl6030_usb_ldo_init(struct twl6030_usb *twl) static int twl6030_usb_ldo_init(struct twl6030_usb *twl)
{ {
char *regulator_name;
if (twl->features & TWL6025_SUBCLASS)
regulator_name = "ldousb";
else
regulator_name = "vusb";
/* Set to OTG_REV 1.3 and turn on the ID_WAKEUP_COMP */ /* Set to OTG_REV 1.3 and turn on the ID_WAKEUP_COMP */
twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_BACKUP_REG); twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_BACKUP_REG);
...@@ -214,7 +221,7 @@ static int twl6030_usb_ldo_init(struct twl6030_usb *twl) ...@@ -214,7 +221,7 @@ static int twl6030_usb_ldo_init(struct twl6030_usb *twl)
/* Program MISC2 register and set bit VUSB_IN_VBAT */ /* Program MISC2 register and set bit VUSB_IN_VBAT */
twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x10, TWL6030_MISC2); twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x10, TWL6030_MISC2);
twl->usb3v3 = regulator_get(twl->dev, "vusb"); twl->usb3v3 = regulator_get(twl->dev, regulator_name);
if (IS_ERR(twl->usb3v3)) if (IS_ERR(twl->usb3v3))
return -ENODEV; return -ENODEV;
...@@ -409,6 +416,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev) ...@@ -409,6 +416,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)
twl->dev = &pdev->dev; twl->dev = &pdev->dev;
twl->irq1 = platform_get_irq(pdev, 0); twl->irq1 = platform_get_irq(pdev, 0);
twl->irq2 = platform_get_irq(pdev, 1); twl->irq2 = platform_get_irq(pdev, 1);
twl->features = pdata->features;
twl->otg.dev = twl->dev; twl->otg.dev = twl->dev;
twl->otg.label = "twl6030"; twl->otg.label = "twl6030";
twl->otg.set_host = twl6030_set_host; twl->otg.set_host = twl6030_set_host;
......
...@@ -311,10 +311,6 @@ enum max8997_irq { ...@@ -311,10 +311,6 @@ enum max8997_irq {
MAX8997_IRQ_NR, MAX8997_IRQ_NR,
}; };
#define MAX8997_REG_BUCK1DVS(x) (MAX8997_REG_BUCK1DVS1 + (x) - 1)
#define MAX8997_REG_BUCK2DVS(x) (MAX8997_REG_BUCK2DVS1 + (x) - 1)
#define MAX8997_REG_BUCK5DVS(x) (MAX8997_REG_BUCK5DVS1 + (x) - 1)
#define MAX8997_NUM_GPIO 12 #define MAX8997_NUM_GPIO 12
struct max8997_dev { struct max8997_dev {
struct device *dev; struct device *dev;
......
/*
* tps65910.h -- TI TPS6591x
*
* Copyright 2010-2011 Texas Instruments Inc.
*
* Author: Graeme Gregory <gg@slimlogic.co.uk>
* Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>
* Author: Arnaud Deconinck <a-deconinck@ti.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.
*
*/
#ifndef __LINUX_MFD_TPS65910_H
#define __LINUX_MFD_TPS65910_H
/* TPS chip id list */
#define TPS65910 0
#define TPS65911 1
/* TPS regulator type list */
#define REGULATOR_LDO 0
#define REGULATOR_DCDC 1
/*
* List of registers for component TPS65910
*
*/
#define TPS65910_SECONDS 0x0
#define TPS65910_MINUTES 0x1
#define TPS65910_HOURS 0x2
#define TPS65910_DAYS 0x3
#define TPS65910_MONTHS 0x4
#define TPS65910_YEARS 0x5
#define TPS65910_WEEKS 0x6
#define TPS65910_ALARM_SECONDS 0x8
#define TPS65910_ALARM_MINUTES 0x9
#define TPS65910_ALARM_HOURS 0xA
#define TPS65910_ALARM_DAYS 0xB
#define TPS65910_ALARM_MONTHS 0xC
#define TPS65910_ALARM_YEARS 0xD
#define TPS65910_RTC_CTRL 0x10
#define TPS65910_RTC_STATUS 0x11
#define TPS65910_RTC_INTERRUPTS 0x12
#define TPS65910_RTC_COMP_LSB 0x13
#define TPS65910_RTC_COMP_MSB 0x14
#define TPS65910_RTC_RES_PROG 0x15
#define TPS65910_RTC_RESET_STATUS 0x16
#define TPS65910_BCK1 0x17
#define TPS65910_BCK2 0x18
#define TPS65910_BCK3 0x19
#define TPS65910_BCK4 0x1A
#define TPS65910_BCK5 0x1B
#define TPS65910_PUADEN 0x1C
#define TPS65910_REF 0x1D
#define TPS65910_VRTC 0x1E
#define TPS65910_VIO 0x20
#define TPS65910_VDD1 0x21
#define TPS65910_VDD1_OP 0x22
#define TPS65910_VDD1_SR 0x23
#define TPS65910_VDD2 0x24
#define TPS65910_VDD2_OP 0x25
#define TPS65910_VDD2_SR 0x26
#define TPS65910_VDD3 0x27
#define TPS65910_VDIG1 0x30
#define TPS65910_VDIG2 0x31
#define TPS65910_VAUX1 0x32
#define TPS65910_VAUX2 0x33
#define TPS65910_VAUX33 0x34
#define TPS65910_VMMC 0x35
#define TPS65910_VPLL 0x36
#define TPS65910_VDAC 0x37
#define TPS65910_THERM 0x38
#define TPS65910_BBCH 0x39
#define TPS65910_DCDCCTRL 0x3E
#define TPS65910_DEVCTRL 0x3F
#define TPS65910_DEVCTRL2 0x40
#define TPS65910_SLEEP_KEEP_LDO_ON 0x41
#define TPS65910_SLEEP_KEEP_RES_ON 0x42
#define TPS65910_SLEEP_SET_LDO_OFF 0x43
#define TPS65910_SLEEP_SET_RES_OFF 0x44
#define TPS65910_EN1_LDO_ASS 0x45
#define TPS65910_EN1_SMPS_ASS 0x46
#define TPS65910_EN2_LDO_ASS 0x47
#define TPS65910_EN2_SMPS_ASS 0x48
#define TPS65910_EN3_LDO_ASS 0x49
#define TPS65910_SPARE 0x4A
#define TPS65910_INT_STS 0x50
#define TPS65910_INT_MSK 0x51
#define TPS65910_INT_STS2 0x52
#define TPS65910_INT_MSK2 0x53
#define TPS65910_INT_STS3 0x54
#define TPS65910_INT_MSK3 0x55
#define TPS65910_GPIO0 0x60
#define TPS65910_GPIO1 0x61
#define TPS65910_GPIO2 0x62
#define TPS65910_GPIO3 0x63
#define TPS65910_GPIO4 0x64
#define TPS65910_GPIO5 0x65
#define TPS65910_GPIO6 0x66
#define TPS65910_GPIO7 0x67
#define TPS65910_GPIO8 0x68
#define TPS65910_JTAGVERNUM 0x80
#define TPS65910_MAX_REGISTER 0x80
/*
* List of registers specific to TPS65911
*/
#define TPS65911_VDDCTRL 0x27
#define TPS65911_VDDCTRL_OP 0x28
#define TPS65911_VDDCTRL_SR 0x29
#define TPS65911_LDO1 0x30
#define TPS65911_LDO2 0x31
#define TPS65911_LDO5 0x32
#define TPS65911_LDO8 0x33
#define TPS65911_LDO7 0x34
#define TPS65911_LDO6 0x35
#define TPS65911_LDO4 0x36
#define TPS65911_LDO3 0x37
#define TPS65911_VMBCH 0x6A
#define TPS65911_VMBCH2 0x6B
/*
* List of register bitfields for component TPS65910
*
*/
/*Register BCK1 (0x80) register.RegisterDescription */
#define BCK1_BCKUP_MASK 0xFF
#define BCK1_BCKUP_SHIFT 0
/*Register BCK2 (0x80) register.RegisterDescription */
#define BCK2_BCKUP_MASK 0xFF
#define BCK2_BCKUP_SHIFT 0
/*Register BCK3 (0x80) register.RegisterDescription */
#define BCK3_BCKUP_MASK 0xFF
#define BCK3_BCKUP_SHIFT 0
/*Register BCK4 (0x80) register.RegisterDescription */
#define BCK4_BCKUP_MASK 0xFF
#define BCK4_BCKUP_SHIFT 0
/*Register BCK5 (0x80) register.RegisterDescription */
#define BCK5_BCKUP_MASK 0xFF
#define BCK5_BCKUP_SHIFT 0
/*Register PUADEN (0x80) register.RegisterDescription */
#define PUADEN_EN3P_MASK 0x80
#define PUADEN_EN3P_SHIFT 7
#define PUADEN_I2CCTLP_MASK 0x40
#define PUADEN_I2CCTLP_SHIFT 6
#define PUADEN_I2CSRP_MASK 0x20
#define PUADEN_I2CSRP_SHIFT 5
#define PUADEN_PWRONP_MASK 0x10
#define PUADEN_PWRONP_SHIFT 4
#define PUADEN_SLEEPP_MASK 0x08
#define PUADEN_SLEEPP_SHIFT 3
#define PUADEN_PWRHOLDP_MASK 0x04
#define PUADEN_PWRHOLDP_SHIFT 2
#define PUADEN_BOOT1P_MASK 0x02
#define PUADEN_BOOT1P_SHIFT 1
#define PUADEN_BOOT0P_MASK 0x01
#define PUADEN_BOOT0P_SHIFT 0
/*Register REF (0x80) register.RegisterDescription */
#define REF_VMBCH_SEL_MASK 0x0C
#define REF_VMBCH_SEL_SHIFT 2
#define REF_ST_MASK 0x03
#define REF_ST_SHIFT 0
/*Register VRTC (0x80) register.RegisterDescription */
#define VRTC_VRTC_OFFMASK_MASK 0x08
#define VRTC_VRTC_OFFMASK_SHIFT 3
#define VRTC_ST_MASK 0x03
#define VRTC_ST_SHIFT 0
/*Register VIO (0x80) register.RegisterDescription */
#define VIO_ILMAX_MASK 0xC0
#define VIO_ILMAX_SHIFT 6
#define VIO_SEL_MASK 0x0C
#define VIO_SEL_SHIFT 2
#define VIO_ST_MASK 0x03
#define VIO_ST_SHIFT 0
/*Register VDD1 (0x80) register.RegisterDescription */
#define VDD1_VGAIN_SEL_MASK 0xC0
#define VDD1_VGAIN_SEL_SHIFT 6
#define VDD1_ILMAX_MASK 0x20
#define VDD1_ILMAX_SHIFT 5
#define VDD1_TSTEP_MASK 0x1C
#define VDD1_TSTEP_SHIFT 2
#define VDD1_ST_MASK 0x03
#define VDD1_ST_SHIFT 0
/*Register VDD1_OP (0x80) register.RegisterDescription */
#define VDD1_OP_CMD_MASK 0x80
#define VDD1_OP_CMD_SHIFT 7
#define VDD1_OP_SEL_MASK 0x7F
#define VDD1_OP_SEL_SHIFT 0
/*Register VDD1_SR (0x80) register.RegisterDescription */
#define VDD1_SR_SEL_MASK 0x7F
#define VDD1_SR_SEL_SHIFT 0
/*Register VDD2 (0x80) register.RegisterDescription */
#define VDD2_VGAIN_SEL_MASK 0xC0
#define VDD2_VGAIN_SEL_SHIFT 6
#define VDD2_ILMAX_MASK 0x20
#define VDD2_ILMAX_SHIFT 5
#define VDD2_TSTEP_MASK 0x1C
#define VDD2_TSTEP_SHIFT 2
#define VDD2_ST_MASK 0x03
#define VDD2_ST_SHIFT 0
/*Register VDD2_OP (0x80) register.RegisterDescription */
#define VDD2_OP_CMD_MASK 0x80
#define VDD2_OP_CMD_SHIFT 7
#define VDD2_OP_SEL_MASK 0x7F
#define VDD2_OP_SEL_SHIFT 0
/*Register VDD2_SR (0x80) register.RegisterDescription */
#define VDD2_SR_SEL_MASK 0x7F
#define VDD2_SR_SEL_SHIFT 0
/*Registers VDD1, VDD2 voltage values definitions */
#define VDD1_2_NUM_VOLTS 73
#define VDD1_2_MIN_VOLT 6000
#define VDD1_2_OFFSET 125
/*Register VDD3 (0x80) register.RegisterDescription */
#define VDD3_CKINEN_MASK 0x04
#define VDD3_CKINEN_SHIFT 2
#define VDD3_ST_MASK 0x03
#define VDD3_ST_SHIFT 0
#define VDDCTRL_MIN_VOLT 6000
#define VDDCTRL_OFFSET 125
/*Registers VDIG (0x80) to VDAC register.RegisterDescription */
#define LDO_SEL_MASK 0x0C
#define LDO_SEL_SHIFT 2
#define LDO_ST_MASK 0x03
#define LDO_ST_SHIFT 0
#define LDO_ST_ON_BIT 0x01
#define LDO_ST_MODE_BIT 0x02
/* Registers LDO1 to LDO8 in tps65910 */
#define LDO1_SEL_MASK 0xFC
#define LDO3_SEL_MASK 0x7C
#define LDO_MIN_VOLT 1000
#define LDO_MAX_VOLT 3300;
/*Register VDIG1 (0x80) register.RegisterDescription */
#define VDIG1_SEL_MASK 0x0C
#define VDIG1_SEL_SHIFT 2
#define VDIG1_ST_MASK 0x03
#define VDIG1_ST_SHIFT 0
/*Register VDIG2 (0x80) register.RegisterDescription */
#define VDIG2_SEL_MASK 0x0C
#define VDIG2_SEL_SHIFT 2
#define VDIG2_ST_MASK 0x03
#define VDIG2_ST_SHIFT 0
/*Register VAUX1 (0x80) register.RegisterDescription */
#define VAUX1_SEL_MASK 0x0C
#define VAUX1_SEL_SHIFT 2
#define VAUX1_ST_MASK 0x03
#define VAUX1_ST_SHIFT 0
/*Register VAUX2 (0x80) register.RegisterDescription */
#define VAUX2_SEL_MASK 0x0C
#define VAUX2_SEL_SHIFT 2
#define VAUX2_ST_MASK 0x03
#define VAUX2_ST_SHIFT 0
/*Register VAUX33 (0x80) register.RegisterDescription */
#define VAUX33_SEL_MASK 0x0C
#define VAUX33_SEL_SHIFT 2
#define VAUX33_ST_MASK 0x03
#define VAUX33_ST_SHIFT 0
/*Register VMMC (0x80) register.RegisterDescription */
#define VMMC_SEL_MASK 0x0C
#define VMMC_SEL_SHIFT 2
#define VMMC_ST_MASK 0x03
#define VMMC_ST_SHIFT 0
/*Register VPLL (0x80) register.RegisterDescription */
#define VPLL_SEL_MASK 0x0C
#define VPLL_SEL_SHIFT 2
#define VPLL_ST_MASK 0x03
#define VPLL_ST_SHIFT 0
/*Register VDAC (0x80) register.RegisterDescription */
#define VDAC_SEL_MASK 0x0C
#define VDAC_SEL_SHIFT 2
#define VDAC_ST_MASK 0x03
#define VDAC_ST_SHIFT 0
/*Register THERM (0x80) register.RegisterDescription */
#define THERM_THERM_HD_MASK 0x20
#define THERM_THERM_HD_SHIFT 5
#define THERM_THERM_TS_MASK 0x10
#define THERM_THERM_TS_SHIFT 4
#define THERM_THERM_HDSEL_MASK 0x0C
#define THERM_THERM_HDSEL_SHIFT 2
#define THERM_RSVD1_MASK 0x02
#define THERM_RSVD1_SHIFT 1
#define THERM_THERM_STATE_MASK 0x01
#define THERM_THERM_STATE_SHIFT 0
/*Register BBCH (0x80) register.RegisterDescription */
#define BBCH_BBSEL_MASK 0x06
#define BBCH_BBSEL_SHIFT 1
#define BBCH_BBCHEN_MASK 0x01
#define BBCH_BBCHEN_SHIFT 0
/*Register DCDCCTRL (0x80) register.RegisterDescription */
#define DCDCCTRL_VDD2_PSKIP_MASK 0x20
#define DCDCCTRL_VDD2_PSKIP_SHIFT 5
#define DCDCCTRL_VDD1_PSKIP_MASK 0x10
#define DCDCCTRL_VDD1_PSKIP_SHIFT 4
#define DCDCCTRL_VIO_PSKIP_MASK 0x08
#define DCDCCTRL_VIO_PSKIP_SHIFT 3
#define DCDCCTRL_DCDCCKEXT_MASK 0x04
#define DCDCCTRL_DCDCCKEXT_SHIFT 2
#define DCDCCTRL_DCDCCKSYNC_MASK 0x03
#define DCDCCTRL_DCDCCKSYNC_SHIFT 0
/*Register DEVCTRL (0x80) register.RegisterDescription */
#define DEVCTRL_RTC_PWDN_MASK 0x40
#define DEVCTRL_RTC_PWDN_SHIFT 6
#define DEVCTRL_CK32K_CTRL_MASK 0x20
#define DEVCTRL_CK32K_CTRL_SHIFT 5
#define DEVCTRL_SR_CTL_I2C_SEL_MASK 0x10
#define DEVCTRL_SR_CTL_I2C_SEL_SHIFT 4
#define DEVCTRL_DEV_OFF_RST_MASK 0x08
#define DEVCTRL_DEV_OFF_RST_SHIFT 3
#define DEVCTRL_DEV_ON_MASK 0x04
#define DEVCTRL_DEV_ON_SHIFT 2
#define DEVCTRL_DEV_SLP_MASK 0x02
#define DEVCTRL_DEV_SLP_SHIFT 1
#define DEVCTRL_DEV_OFF_MASK 0x01
#define DEVCTRL_DEV_OFF_SHIFT 0
/*Register DEVCTRL2 (0x80) register.RegisterDescription */
#define DEVCTRL2_TSLOT_LENGTH_MASK 0x30
#define DEVCTRL2_TSLOT_LENGTH_SHIFT 4
#define DEVCTRL2_SLEEPSIG_POL_MASK 0x08
#define DEVCTRL2_SLEEPSIG_POL_SHIFT 3
#define DEVCTRL2_PWON_LP_OFF_MASK 0x04
#define DEVCTRL2_PWON_LP_OFF_SHIFT 2
#define DEVCTRL2_PWON_LP_RST_MASK 0x02
#define DEVCTRL2_PWON_LP_RST_SHIFT 1
#define DEVCTRL2_IT_POL_MASK 0x01
#define DEVCTRL2_IT_POL_SHIFT 0
/*Register SLEEP_KEEP_LDO_ON (0x80) register.RegisterDescription */
#define SLEEP_KEEP_LDO_ON_VDAC_KEEPON_MASK 0x80
#define SLEEP_KEEP_LDO_ON_VDAC_KEEPON_SHIFT 7
#define SLEEP_KEEP_LDO_ON_VPLL_KEEPON_MASK 0x40
#define SLEEP_KEEP_LDO_ON_VPLL_KEEPON_SHIFT 6
#define SLEEP_KEEP_LDO_ON_VAUX33_KEEPON_MASK 0x20
#define SLEEP_KEEP_LDO_ON_VAUX33_KEEPON_SHIFT 5
#define SLEEP_KEEP_LDO_ON_VAUX2_KEEPON_MASK 0x10
#define SLEEP_KEEP_LDO_ON_VAUX2_KEEPON_SHIFT 4
#define SLEEP_KEEP_LDO_ON_VAUX1_KEEPON_MASK 0x08
#define SLEEP_KEEP_LDO_ON_VAUX1_KEEPON_SHIFT 3
#define SLEEP_KEEP_LDO_ON_VDIG2_KEEPON_MASK 0x04
#define SLEEP_KEEP_LDO_ON_VDIG2_KEEPON_SHIFT 2
#define SLEEP_KEEP_LDO_ON_VDIG1_KEEPON_MASK 0x02
#define SLEEP_KEEP_LDO_ON_VDIG1_KEEPON_SHIFT 1
#define SLEEP_KEEP_LDO_ON_VMMC_KEEPON_MASK 0x01
#define SLEEP_KEEP_LDO_ON_VMMC_KEEPON_SHIFT 0
/*Register SLEEP_KEEP_RES_ON (0x80) register.RegisterDescription */
#define SLEEP_KEEP_RES_ON_THERM_KEEPON_MASK 0x80
#define SLEEP_KEEP_RES_ON_THERM_KEEPON_SHIFT 7
#define SLEEP_KEEP_RES_ON_CLKOUT32K_KEEPON_MASK 0x40
#define SLEEP_KEEP_RES_ON_CLKOUT32K_KEEPON_SHIFT 6
#define SLEEP_KEEP_RES_ON_VRTC_KEEPON_MASK 0x20
#define SLEEP_KEEP_RES_ON_VRTC_KEEPON_SHIFT 5
#define SLEEP_KEEP_RES_ON_I2CHS_KEEPON_MASK 0x10
#define SLEEP_KEEP_RES_ON_I2CHS_KEEPON_SHIFT 4
#define SLEEP_KEEP_RES_ON_VDD3_KEEPON_MASK 0x08
#define SLEEP_KEEP_RES_ON_VDD3_KEEPON_SHIFT 3
#define SLEEP_KEEP_RES_ON_VDD2_KEEPON_MASK 0x04
#define SLEEP_KEEP_RES_ON_VDD2_KEEPON_SHIFT 2
#define SLEEP_KEEP_RES_ON_VDD1_KEEPON_MASK 0x02
#define SLEEP_KEEP_RES_ON_VDD1_KEEPON_SHIFT 1
#define SLEEP_KEEP_RES_ON_VIO_KEEPON_MASK 0x01
#define SLEEP_KEEP_RES_ON_VIO_KEEPON_SHIFT 0
/*Register SLEEP_SET_LDO_OFF (0x80) register.RegisterDescription */
#define SLEEP_SET_LDO_OFF_VDAC_SETOFF_MASK 0x80
#define SLEEP_SET_LDO_OFF_VDAC_SETOFF_SHIFT 7
#define SLEEP_SET_LDO_OFF_VPLL_SETOFF_MASK 0x40
#define SLEEP_SET_LDO_OFF_VPLL_SETOFF_SHIFT 6
#define SLEEP_SET_LDO_OFF_VAUX33_SETOFF_MASK 0x20
#define SLEEP_SET_LDO_OFF_VAUX33_SETOFF_SHIFT 5
#define SLEEP_SET_LDO_OFF_VAUX2_SETOFF_MASK 0x10
#define SLEEP_SET_LDO_OFF_VAUX2_SETOFF_SHIFT 4
#define SLEEP_SET_LDO_OFF_VAUX1_SETOFF_MASK 0x08
#define SLEEP_SET_LDO_OFF_VAUX1_SETOFF_SHIFT 3
#define SLEEP_SET_LDO_OFF_VDIG2_SETOFF_MASK 0x04
#define SLEEP_SET_LDO_OFF_VDIG2_SETOFF_SHIFT 2
#define SLEEP_SET_LDO_OFF_VDIG1_SETOFF_MASK 0x02
#define SLEEP_SET_LDO_OFF_VDIG1_SETOFF_SHIFT 1
#define SLEEP_SET_LDO_OFF_VMMC_SETOFF_MASK 0x01
#define SLEEP_SET_LDO_OFF_VMMC_SETOFF_SHIFT 0
/*Register SLEEP_SET_RES_OFF (0x80) register.RegisterDescription */
#define SLEEP_SET_RES_OFF_DEFAULT_VOLT_MASK 0x80
#define SLEEP_SET_RES_OFF_DEFAULT_VOLT_SHIFT 7
#define SLEEP_SET_RES_OFF_RSVD_MASK 0x60
#define SLEEP_SET_RES_OFF_RSVD_SHIFT 5
#define SLEEP_SET_RES_OFF_SPARE_SETOFF_MASK 0x10
#define SLEEP_SET_RES_OFF_SPARE_SETOFF_SHIFT 4
#define SLEEP_SET_RES_OFF_VDD3_SETOFF_MASK 0x08
#define SLEEP_SET_RES_OFF_VDD3_SETOFF_SHIFT 3
#define SLEEP_SET_RES_OFF_VDD2_SETOFF_MASK 0x04
#define SLEEP_SET_RES_OFF_VDD2_SETOFF_SHIFT 2
#define SLEEP_SET_RES_OFF_VDD1_SETOFF_MASK 0x02
#define SLEEP_SET_RES_OFF_VDD1_SETOFF_SHIFT 1
#define SLEEP_SET_RES_OFF_VIO_SETOFF_MASK 0x01
#define SLEEP_SET_RES_OFF_VIO_SETOFF_SHIFT 0
/*Register EN1_LDO_ASS (0x80) register.RegisterDescription */
#define EN1_LDO_ASS_VDAC_EN1_MASK 0x80
#define EN1_LDO_ASS_VDAC_EN1_SHIFT 7
#define EN1_LDO_ASS_VPLL_EN1_MASK 0x40
#define EN1_LDO_ASS_VPLL_EN1_SHIFT 6
#define EN1_LDO_ASS_VAUX33_EN1_MASK 0x20
#define EN1_LDO_ASS_VAUX33_EN1_SHIFT 5
#define EN1_LDO_ASS_VAUX2_EN1_MASK 0x10
#define EN1_LDO_ASS_VAUX2_EN1_SHIFT 4
#define EN1_LDO_ASS_VAUX1_EN1_MASK 0x08
#define EN1_LDO_ASS_VAUX1_EN1_SHIFT 3
#define EN1_LDO_ASS_VDIG2_EN1_MASK 0x04
#define EN1_LDO_ASS_VDIG2_EN1_SHIFT 2
#define EN1_LDO_ASS_VDIG1_EN1_MASK 0x02
#define EN1_LDO_ASS_VDIG1_EN1_SHIFT 1
#define EN1_LDO_ASS_VMMC_EN1_MASK 0x01
#define EN1_LDO_ASS_VMMC_EN1_SHIFT 0
/*Register EN1_SMPS_ASS (0x80) register.RegisterDescription */
#define EN1_SMPS_ASS_RSVD_MASK 0xE0
#define EN1_SMPS_ASS_RSVD_SHIFT 5
#define EN1_SMPS_ASS_SPARE_EN1_MASK 0x10
#define EN1_SMPS_ASS_SPARE_EN1_SHIFT 4
#define EN1_SMPS_ASS_VDD3_EN1_MASK 0x08
#define EN1_SMPS_ASS_VDD3_EN1_SHIFT 3
#define EN1_SMPS_ASS_VDD2_EN1_MASK 0x04
#define EN1_SMPS_ASS_VDD2_EN1_SHIFT 2
#define EN1_SMPS_ASS_VDD1_EN1_MASK 0x02
#define EN1_SMPS_ASS_VDD1_EN1_SHIFT 1
#define EN1_SMPS_ASS_VIO_EN1_MASK 0x01
#define EN1_SMPS_ASS_VIO_EN1_SHIFT 0
/*Register EN2_LDO_ASS (0x80) register.RegisterDescription */
#define EN2_LDO_ASS_VDAC_EN2_MASK 0x80
#define EN2_LDO_ASS_VDAC_EN2_SHIFT 7
#define EN2_LDO_ASS_VPLL_EN2_MASK 0x40
#define EN2_LDO_ASS_VPLL_EN2_SHIFT 6
#define EN2_LDO_ASS_VAUX33_EN2_MASK 0x20
#define EN2_LDO_ASS_VAUX33_EN2_SHIFT 5
#define EN2_LDO_ASS_VAUX2_EN2_MASK 0x10
#define EN2_LDO_ASS_VAUX2_EN2_SHIFT 4
#define EN2_LDO_ASS_VAUX1_EN2_MASK 0x08
#define EN2_LDO_ASS_VAUX1_EN2_SHIFT 3
#define EN2_LDO_ASS_VDIG2_EN2_MASK 0x04
#define EN2_LDO_ASS_VDIG2_EN2_SHIFT 2
#define EN2_LDO_ASS_VDIG1_EN2_MASK 0x02
#define EN2_LDO_ASS_VDIG1_EN2_SHIFT 1
#define EN2_LDO_ASS_VMMC_EN2_MASK 0x01
#define EN2_LDO_ASS_VMMC_EN2_SHIFT 0
/*Register EN2_SMPS_ASS (0x80) register.RegisterDescription */
#define EN2_SMPS_ASS_RSVD_MASK 0xE0
#define EN2_SMPS_ASS_RSVD_SHIFT 5
#define EN2_SMPS_ASS_SPARE_EN2_MASK 0x10
#define EN2_SMPS_ASS_SPARE_EN2_SHIFT 4
#define EN2_SMPS_ASS_VDD3_EN2_MASK 0x08
#define EN2_SMPS_ASS_VDD3_EN2_SHIFT 3
#define EN2_SMPS_ASS_VDD2_EN2_MASK 0x04
#define EN2_SMPS_ASS_VDD2_EN2_SHIFT 2
#define EN2_SMPS_ASS_VDD1_EN2_MASK 0x02
#define EN2_SMPS_ASS_VDD1_EN2_SHIFT 1
#define EN2_SMPS_ASS_VIO_EN2_MASK 0x01
#define EN2_SMPS_ASS_VIO_EN2_SHIFT 0
/*Register EN3_LDO_ASS (0x80) register.RegisterDescription */
#define EN3_LDO_ASS_VDAC_EN3_MASK 0x80
#define EN3_LDO_ASS_VDAC_EN3_SHIFT 7
#define EN3_LDO_ASS_VPLL_EN3_MASK 0x40
#define EN3_LDO_ASS_VPLL_EN3_SHIFT 6
#define EN3_LDO_ASS_VAUX33_EN3_MASK 0x20
#define EN3_LDO_ASS_VAUX33_EN3_SHIFT 5
#define EN3_LDO_ASS_VAUX2_EN3_MASK 0x10
#define EN3_LDO_ASS_VAUX2_EN3_SHIFT 4
#define EN3_LDO_ASS_VAUX1_EN3_MASK 0x08
#define EN3_LDO_ASS_VAUX1_EN3_SHIFT 3
#define EN3_LDO_ASS_VDIG2_EN3_MASK 0x04
#define EN3_LDO_ASS_VDIG2_EN3_SHIFT 2
#define EN3_LDO_ASS_VDIG1_EN3_MASK 0x02
#define EN3_LDO_ASS_VDIG1_EN3_SHIFT 1
#define EN3_LDO_ASS_VMMC_EN3_MASK 0x01
#define EN3_LDO_ASS_VMMC_EN3_SHIFT 0
/*Register SPARE (0x80) register.RegisterDescription */
#define SPARE_SPARE_MASK 0xFF
#define SPARE_SPARE_SHIFT 0
/*Register INT_STS (0x80) register.RegisterDescription */
#define INT_STS_RTC_PERIOD_IT_MASK 0x80
#define INT_STS_RTC_PERIOD_IT_SHIFT 7
#define INT_STS_RTC_ALARM_IT_MASK 0x40
#define INT_STS_RTC_ALARM_IT_SHIFT 6
#define INT_STS_HOTDIE_IT_MASK 0x20
#define INT_STS_HOTDIE_IT_SHIFT 5
#define INT_STS_PWRHOLD_IT_MASK 0x10
#define INT_STS_PWRHOLD_IT_SHIFT 4
#define INT_STS_PWRON_LP_IT_MASK 0x08
#define INT_STS_PWRON_LP_IT_SHIFT 3
#define INT_STS_PWRON_IT_MASK 0x04
#define INT_STS_PWRON_IT_SHIFT 2
#define INT_STS_VMBHI_IT_MASK 0x02
#define INT_STS_VMBHI_IT_SHIFT 1
#define INT_STS_VMBDCH_IT_MASK 0x01
#define INT_STS_VMBDCH_IT_SHIFT 0
/*Register INT_MSK (0x80) register.RegisterDescription */
#define INT_MSK_RTC_PERIOD_IT_MSK_MASK 0x80
#define INT_MSK_RTC_PERIOD_IT_MSK_SHIFT 7
#define INT_MSK_RTC_ALARM_IT_MSK_MASK 0x40
#define INT_MSK_RTC_ALARM_IT_MSK_SHIFT 6
#define INT_MSK_HOTDIE_IT_MSK_MASK 0x20
#define INT_MSK_HOTDIE_IT_MSK_SHIFT 5
#define INT_MSK_PWRHOLD_IT_MSK_MASK 0x10
#define INT_MSK_PWRHOLD_IT_MSK_SHIFT 4
#define INT_MSK_PWRON_LP_IT_MSK_MASK 0x08
#define INT_MSK_PWRON_LP_IT_MSK_SHIFT 3
#define INT_MSK_PWRON_IT_MSK_MASK 0x04
#define INT_MSK_PWRON_IT_MSK_SHIFT 2
#define INT_MSK_VMBHI_IT_MSK_MASK 0x02
#define INT_MSK_VMBHI_IT_MSK_SHIFT 1
#define INT_MSK_VMBDCH_IT_MSK_MASK 0x01
#define INT_MSK_VMBDCH_IT_MSK_SHIFT 0
/*Register INT_STS2 (0x80) register.RegisterDescription */
#define INT_STS2_GPIO3_F_IT_MASK 0x80
#define INT_STS2_GPIO3_F_IT_SHIFT 7
#define INT_STS2_GPIO3_R_IT_MASK 0x40
#define INT_STS2_GPIO3_R_IT_SHIFT 6
#define INT_STS2_GPIO2_F_IT_MASK 0x20
#define INT_STS2_GPIO2_F_IT_SHIFT 5
#define INT_STS2_GPIO2_R_IT_MASK 0x10
#define INT_STS2_GPIO2_R_IT_SHIFT 4
#define INT_STS2_GPIO1_F_IT_MASK 0x08
#define INT_STS2_GPIO1_F_IT_SHIFT 3
#define INT_STS2_GPIO1_R_IT_MASK 0x04
#define INT_STS2_GPIO1_R_IT_SHIFT 2
#define INT_STS2_GPIO0_F_IT_MASK 0x02
#define INT_STS2_GPIO0_F_IT_SHIFT 1
#define INT_STS2_GPIO0_R_IT_MASK 0x01
#define INT_STS2_GPIO0_R_IT_SHIFT 0
/*Register INT_MSK2 (0x80) register.RegisterDescription */
#define INT_MSK2_GPIO3_F_IT_MSK_MASK 0x80
#define INT_MSK2_GPIO3_F_IT_MSK_SHIFT 7
#define INT_MSK2_GPIO3_R_IT_MSK_MASK 0x40
#define INT_MSK2_GPIO3_R_IT_MSK_SHIFT 6
#define INT_MSK2_GPIO2_F_IT_MSK_MASK 0x20
#define INT_MSK2_GPIO2_F_IT_MSK_SHIFT 5
#define INT_MSK2_GPIO2_R_IT_MSK_MASK 0x10
#define INT_MSK2_GPIO2_R_IT_MSK_SHIFT 4
#define INT_MSK2_GPIO1_F_IT_MSK_MASK 0x08
#define INT_MSK2_GPIO1_F_IT_MSK_SHIFT 3
#define INT_MSK2_GPIO1_R_IT_MSK_MASK 0x04
#define INT_MSK2_GPIO1_R_IT_MSK_SHIFT 2
#define INT_MSK2_GPIO0_F_IT_MSK_MASK 0x02
#define INT_MSK2_GPIO0_F_IT_MSK_SHIFT 1
#define INT_MSK2_GPIO0_R_IT_MSK_MASK 0x01
#define INT_MSK2_GPIO0_R_IT_MSK_SHIFT 0
/*Register INT_STS3 (0x80) register.RegisterDescription */
#define INT_STS3_GPIO5_F_IT_MASK 0x08
#define INT_STS3_GPIO5_F_IT_SHIFT 3
#define INT_STS3_GPIO5_R_IT_MASK 0x04
#define INT_STS3_GPIO5_R_IT_SHIFT 2
#define INT_STS3_GPIO4_F_IT_MASK 0x02
#define INT_STS3_GPIO4_F_IT_SHIFT 1
#define INT_STS3_GPIO4_R_IT_MASK 0x01
#define INT_STS3_GPIO4_R_IT_SHIFT 0
/*Register INT_MSK3 (0x80) register.RegisterDescription */
#define INT_MSK3_GPIO5_F_IT_MSK_MASK 0x08
#define INT_MSK3_GPIO5_F_IT_MSK_SHIFT 3
#define INT_MSK3_GPIO5_R_IT_MSK_MASK 0x04
#define INT_MSK3_GPIO5_R_IT_MSK_SHIFT 2
#define INT_MSK3_GPIO4_F_IT_MSK_MASK 0x02
#define INT_MSK3_GPIO4_F_IT_MSK_SHIFT 1
#define INT_MSK3_GPIO4_R_IT_MSK_MASK 0x01
#define INT_MSK3_GPIO4_R_IT_MSK_SHIFT 0
/*Register GPIO (0x80) register.RegisterDescription */
#define GPIO_DEB_MASK 0x10
#define GPIO_DEB_SHIFT 4
#define GPIO_PUEN_MASK 0x08
#define GPIO_PUEN_SHIFT 3
#define GPIO_CFG_MASK 0x04
#define GPIO_CFG_SHIFT 2
#define GPIO_STS_MASK 0x02
#define GPIO_STS_SHIFT 1
#define GPIO_SET_MASK 0x01
#define GPIO_SET_SHIFT 0
/*Register JTAGVERNUM (0x80) register.RegisterDescription */
#define JTAGVERNUM_VERNUM_MASK 0x0F
#define JTAGVERNUM_VERNUM_SHIFT 0
/* Register VDDCTRL (0x27) bit definitions */
#define VDDCTRL_ST_MASK 0x03
#define VDDCTRL_ST_SHIFT 0
/*Register VDDCTRL_OP (0x28) bit definitios */
#define VDDCTRL_OP_CMD_MASK 0x80
#define VDDCTRL_OP_CMD_SHIFT 7
#define VDDCTRL_OP_SEL_MASK 0x7F
#define VDDCTRL_OP_SEL_SHIFT 0
/*Register VDDCTRL_SR (0x29) bit definitions */
#define VDDCTRL_SR_SEL_MASK 0x7F
#define VDDCTRL_SR_SEL_SHIFT 0
/* IRQ Definitions */
#define TPS65910_IRQ_VBAT_VMBDCH 0
#define TPS65910_IRQ_VBAT_VMHI 1
#define TPS65910_IRQ_PWRON 2
#define TPS65910_IRQ_PWRON_LP 3
#define TPS65910_IRQ_PWRHOLD 4
#define TPS65910_IRQ_HOTDIE 5
#define TPS65910_IRQ_RTC_ALARM 6
#define TPS65910_IRQ_RTC_PERIOD 7
#define TPS65910_IRQ_GPIO_R 8
#define TPS65910_IRQ_GPIO_F 9
#define TPS65910_NUM_IRQ 10
#define TPS65911_IRQ_VBAT_VMBDCH 0
#define TPS65911_IRQ_VBAT_VMBDCH2L 1
#define TPS65911_IRQ_VBAT_VMBDCH2H 2
#define TPS65911_IRQ_VBAT_VMHI 3
#define TPS65911_IRQ_PWRON 4
#define TPS65911_IRQ_PWRON_LP 5
#define TPS65911_IRQ_PWRHOLD_F 6
#define TPS65911_IRQ_PWRHOLD_R 7
#define TPS65911_IRQ_HOTDIE 8
#define TPS65911_IRQ_RTC_ALARM 9
#define TPS65911_IRQ_RTC_PERIOD 10
#define TPS65911_IRQ_GPIO0_R 11
#define TPS65911_IRQ_GPIO0_F 12
#define TPS65911_IRQ_GPIO1_R 13
#define TPS65911_IRQ_GPIO1_F 14
#define TPS65911_IRQ_GPIO2_R 15
#define TPS65911_IRQ_GPIO2_F 16
#define TPS65911_IRQ_GPIO3_R 17
#define TPS65911_IRQ_GPIO3_F 18
#define TPS65911_IRQ_GPIO4_R 19
#define TPS65911_IRQ_GPIO4_F 20
#define TPS65911_IRQ_GPIO5_R 21
#define TPS65911_IRQ_GPIO5_F 22
#define TPS65911_IRQ_WTCHDG 23
#define TPS65911_IRQ_PWRDN 24
#define TPS65911_NUM_IRQ 25
/* GPIO Register Definitions */
#define TPS65910_GPIO_DEB BIT(2)
#define TPS65910_GPIO_PUEN BIT(3)
#define TPS65910_GPIO_CFG BIT(2)
#define TPS65910_GPIO_STS BIT(1)
#define TPS65910_GPIO_SET BIT(0)
/**
* struct tps65910_board
* Board platform data may be used to initialize regulators.
*/
struct tps65910_board {
int gpio_base;
int irq;
int irq_base;
int vmbch_threshold;
int vmbch2_threshold;
struct regulator_init_data *tps65910_pmic_init_data;
};
/**
* struct tps65910 - tps65910 sub-driver chip access routines
*/
struct tps65910 {
struct device *dev;
struct i2c_client *i2c_client;
struct mutex io_mutex;
unsigned int id;
int (*read)(struct tps65910 *tps65910, u8 reg, int size, void *dest);
int (*write)(struct tps65910 *tps65910, u8 reg, int size, void *src);
/* Client devices */
struct tps65910_pmic *pmic;
struct tps65910_rtc *rtc;
struct tps65910_power *power;
/* GPIO Handling */
struct gpio_chip gpio;
/* IRQ Handling */
struct mutex irq_lock;
int chip_irq;
int irq_base;
int irq_num;
u32 irq_mask;
};
struct tps65910_platform_data {
int irq;
int irq_base;
};
int tps65910_set_bits(struct tps65910 *tps65910, u8 reg, u8 mask);
int tps65910_clear_bits(struct tps65910 *tps65910, u8 reg, u8 mask);
void tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base);
int tps65910_irq_init(struct tps65910 *tps65910, int irq,
struct tps65910_platform_data *pdata);
static inline int tps65910_chip_id(struct tps65910 *tps65910)
{
return tps65910->id;
}
#endif /* __LINUX_MFD_TPS65910_H */
...@@ -68,6 +68,8 @@ struct regulator_state { ...@@ -68,6 +68,8 @@ struct regulator_state {
* *
* @min_uV: Smallest voltage consumers may set. * @min_uV: Smallest voltage consumers may set.
* @max_uV: Largest voltage consumers may set. * @max_uV: Largest voltage consumers may set.
* @uV_offset: Offset applied to voltages from consumer to compensate for
* voltage drops.
* *
* @min_uA: Smallest consumers consumers may set. * @min_uA: Smallest consumers consumers may set.
* @max_uA: Largest current consumers may set. * @max_uA: Largest current consumers may set.
...@@ -99,6 +101,8 @@ struct regulation_constraints { ...@@ -99,6 +101,8 @@ struct regulation_constraints {
int min_uV; int min_uV;
int max_uV; int max_uV;
int uV_offset;
/* current output range (inclusive) - for current control */ /* current output range (inclusive) - for current control */
int min_uA; int min_uA;
int max_uA; int max_uA;
...@@ -160,8 +164,6 @@ struct regulator_consumer_supply { ...@@ -160,8 +164,6 @@ struct regulator_consumer_supply {
* @supply_regulator: Parent regulator. Specified using the regulator name * @supply_regulator: Parent regulator. Specified using the regulator name
* as it appears in the name field in sysfs, which can * as it appears in the name field in sysfs, which can
* be explicitly set using the constraints field 'name'. * be explicitly set using the constraints field 'name'.
* @supply_regulator_dev: Parent regulator (if any) - DEPRECATED in favour
* of supply_regulator.
* *
* @constraints: Constraints. These must be specified for the regulator to * @constraints: Constraints. These must be specified for the regulator to
* be usable. * be usable.
...@@ -173,7 +175,6 @@ struct regulator_consumer_supply { ...@@ -173,7 +175,6 @@ struct regulator_consumer_supply {
*/ */
struct regulator_init_data { struct regulator_init_data {
const char *supply_regulator; /* or NULL for system supply */ const char *supply_regulator; /* or NULL for system supply */
struct device *supply_regulator_dev; /* or NULL for system supply */
struct regulation_constraints constraints; struct regulation_constraints constraints;
......
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