mirror of
https://github.com/torvalds/linux.git
synced 2024-11-17 09:31:50 +00:00
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 ...
This commit is contained in:
commit
f7fc06e3a4
@ -53,11 +53,11 @@ static struct regulator_init_data regulator1_data = {
|
||||
|
||||
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
|
||||
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:-
|
||||
|
||||
static struct regulator_init_data regulator2_data = {
|
||||
.supply_regulator_dev = &platform_regulator1_device.dev,
|
||||
.supply_regulator = "regulator_name",
|
||||
.constraints = {
|
||||
.min_uV = 1800000,
|
||||
.max_uV = 2000000,
|
||||
|
@ -424,4 +424,11 @@ config AB8500_GPIO
|
||||
depends on AB8500_CORE && BROKEN
|
||||
help
|
||||
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
|
||||
|
@ -40,3 +40,4 @@ obj-$(CONFIG_GPIO_SX150X) += sx150x.o
|
||||
obj-$(CONFIG_GPIO_VX855) += vx855_gpio.o
|
||||
obj-$(CONFIG_GPIO_ML_IOH) += ml_ioh_gpio.o
|
||||
obj-$(CONFIG_AB8500_GPIO) += ab8500-gpio.o
|
||||
obj-$(CONFIG_GPIO_TPS65910) += tps65910-gpio.o
|
||||
|
100
drivers/gpio/tps65910-gpio.c
Normal file
100
drivers/gpio/tps65910-gpio.c
Normal file
@ -0,0 +1,100 @@
|
||||
/*
|
||||
* 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
|
||||
This is required to use certain other PM 8xxx features, such as GPIO
|
||||
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
|
||||
|
||||
menu "Multimedia Capabilities Port drivers"
|
||||
|
@ -93,3 +93,4 @@ obj-$(CONFIG_MFD_CS5535) += cs5535-mfd.o
|
||||
obj-$(CONFIG_MFD_OMAP_USB_HOST) += omap-usb-host.o
|
||||
obj-$(CONFIG_MFD_PM8921_CORE) += pm8921-core.o
|
||||
obj-$(CONFIG_MFD_PM8XXX_IRQ) += pm8xxx-irq.o
|
||||
obj-$(CONFIG_MFD_TPS65910) += tps65910.o tps65910-irq.o
|
||||
|
218
drivers/mfd/tps65910-irq.c
Normal file
218
drivers/mfd/tps65910-irq.c
Normal file
@ -0,0 +1,218 @@
|
||||
/*
|
||||
* 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, ®);
|
||||
irq_sts = reg;
|
||||
tps65910->read(tps65910, TPS65910_INT_STS2, 1, ®);
|
||||
irq_sts |= reg << 8;
|
||||
switch (tps65910_chip_id(tps65910)) {
|
||||
case TPS65911:
|
||||
tps65910->read(tps65910, TPS65910_INT_STS3, 1, ®);
|
||||
irq_sts |= reg << 16;
|
||||
}
|
||||
|
||||
tps65910->read(tps65910, TPS65910_INT_MSK, 1, ®);
|
||||
irq_mask = reg;
|
||||
tps65910->read(tps65910, TPS65910_INT_MSK2, 1, ®);
|
||||
irq_mask |= reg << 8;
|
||||
switch (tps65910_chip_id(tps65910)) {
|
||||
case TPS65911:
|
||||
tps65910->read(tps65910, TPS65910_INT_MSK3, 1, ®);
|
||||
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 = irq_sts & 0xFF;
|
||||
tps65910->write(tps65910, TPS65910_INT_STS2, 1, ®);
|
||||
switch (tps65910_chip_id(tps65910)) {
|
||||
case TPS65911:
|
||||
reg = irq_sts >> 8;
|
||||
tps65910->write(tps65910, TPS65910_INT_STS3, 1, ®);
|
||||
}
|
||||
|
||||
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_mask = reg;
|
||||
tps65910->read(tps65910, TPS65910_INT_MSK2, 1, ®);
|
||||
reg_mask |= reg << 8;
|
||||
switch (tps65910_chip_id(tps65910)) {
|
||||
case TPS65911:
|
||||
tps65910->read(tps65910, TPS65910_INT_MSK3, 1, ®);
|
||||
reg_mask |= reg << 16;
|
||||
}
|
||||
|
||||
if (tps65910->irq_mask != reg_mask) {
|
||||
reg = tps65910->irq_mask & 0xFF;
|
||||
tps65910->write(tps65910, TPS65910_INT_MSK, 1, ®);
|
||||
reg = tps65910->irq_mask >> 8 & 0xFF;
|
||||
tps65910->write(tps65910, TPS65910_INT_MSK2, 1, ®);
|
||||
switch (tps65910_chip_id(tps65910)) {
|
||||
case TPS65911:
|
||||
reg = tps65910->irq_mask >> 16;
|
||||
tps65910->write(tps65910, TPS65910_INT_MSK3, 1, ®);
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
229
drivers/mfd/tps65910.c
Normal file
229
drivers/mfd/tps65910.c
Normal file
@ -0,0 +1,229 @@
|
||||
/*
|
||||
* 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 = ®
|
||||
|
||||
/* 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");
|
188
drivers/mfd/tps65911-comparator.c
Normal file
188
drivers/mfd/tps65911-comparator.c
Normal file
@ -0,0 +1,188 @@
|
||||
/*
|
||||
* 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
|
||||
serial interface currently supported on the sequencer serial
|
||||
port controller.
|
||||
|
||||
config REGULATOR_TPS65910
|
||||
tristate "TI TPS65910 Power Regulator"
|
||||
depends on MFD_TPS65910
|
||||
help
|
||||
This driver supports TPS65910 voltage regulator chips.
|
||||
|
||||
endif
|
||||
|
||||
|
@ -42,5 +42,6 @@ obj-$(CONFIG_REGULATOR_88PM8607) += 88pm8607.o
|
||||
obj-$(CONFIG_REGULATOR_ISL6271A) += isl6271a-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_AB8500) += ab8500.o
|
||||
obj-$(CONFIG_REGULATOR_DB8500_PRCMU) += db8500-prcmu.o
|
||||
obj-$(CONFIG_REGULATOR_TPS65910) += tps65910-regulator.o
|
||||
|
||||
ccflags-$(CONFIG_REGULATOR_DEBUG) += -DDEBUG
|
||||
|
@ -158,6 +158,13 @@ static int regulator_check_consumers(struct regulator_dev *rdev,
|
||||
struct regulator *regulator;
|
||||
|
||||
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)
|
||||
*max_uV = regulator->max_uV;
|
||||
if (*min_uV < regulator->min_uV)
|
||||
@ -197,9 +204,9 @@ static int regulator_check_current_limit(struct regulator_dev *rdev,
|
||||
}
|
||||
|
||||
/* 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_NORMAL:
|
||||
case REGULATOR_MODE_IDLE:
|
||||
@ -217,11 +224,17 @@ static int regulator_check_mode(struct regulator_dev *rdev, int mode)
|
||||
rdev_err(rdev, "operation not allowed\n");
|
||||
return -EPERM;
|
||||
}
|
||||
if (!(rdev->constraints->valid_modes_mask & mode)) {
|
||||
rdev_err(rdev, "invalid mode %x\n", mode);
|
||||
return -EINVAL;
|
||||
|
||||
/* The modes are bitmasks, the most power hungry modes having
|
||||
* the lowest values. If the requested mode isn't supported
|
||||
* try higher modes. */
|
||||
while (*mode) {
|
||||
if (rdev->constraints->valid_modes_mask & *mode)
|
||||
return 0;
|
||||
*mode /= 2;
|
||||
}
|
||||
return 0;
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* dynamic regulator mode switching constraint check */
|
||||
@ -612,7 +625,7 @@ static void drms_uA_update(struct regulator_dev *rdev)
|
||||
output_uV, current_uA);
|
||||
|
||||
/* check the new mode is allowed */
|
||||
err = regulator_check_mode(rdev, mode);
|
||||
err = regulator_mode_constrain(rdev, &mode);
|
||||
if (err == 0)
|
||||
rdev->desc->ops->set_mode(rdev, mode);
|
||||
}
|
||||
@ -718,6 +731,10 @@ static void print_constraints(struct regulator_dev *rdev)
|
||||
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)
|
||||
count += sprintf(buf + count, "%d mA ",
|
||||
@ -1498,13 +1515,14 @@ static int _regulator_force_disable(struct regulator_dev *rdev,
|
||||
*/
|
||||
int regulator_force_disable(struct regulator *regulator)
|
||||
{
|
||||
struct regulator_dev *rdev = regulator->rdev;
|
||||
struct regulator_dev *supply_rdev = NULL;
|
||||
int ret;
|
||||
|
||||
mutex_lock(®ulator->rdev->mutex);
|
||||
mutex_lock(&rdev->mutex);
|
||||
regulator->uA_load = 0;
|
||||
ret = _regulator_force_disable(regulator->rdev, &supply_rdev);
|
||||
mutex_unlock(®ulator->rdev->mutex);
|
||||
ret = _regulator_force_disable(rdev, &supply_rdev);
|
||||
mutex_unlock(&rdev->mutex);
|
||||
|
||||
if (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,
|
||||
|
||||
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) {
|
||||
ret = rdev->desc->ops->set_voltage(rdev, min_uV, max_uV,
|
||||
&selector);
|
||||
@ -1858,18 +1879,22 @@ EXPORT_SYMBOL_GPL(regulator_sync_voltage);
|
||||
|
||||
static int _regulator_get_voltage(struct regulator_dev *rdev)
|
||||
{
|
||||
int sel;
|
||||
int sel, ret;
|
||||
|
||||
if (rdev->desc->ops->get_voltage_sel) {
|
||||
sel = rdev->desc->ops->get_voltage_sel(rdev);
|
||||
if (sel < 0)
|
||||
return sel;
|
||||
return rdev->desc->ops->list_voltage(rdev, sel);
|
||||
}
|
||||
if (rdev->desc->ops->get_voltage)
|
||||
return rdev->desc->ops->get_voltage(rdev);
|
||||
else
|
||||
ret = rdev->desc->ops->list_voltage(rdev, sel);
|
||||
} else if (rdev->desc->ops->get_voltage) {
|
||||
ret = rdev->desc->ops->get_voltage(rdev);
|
||||
} else {
|
||||
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)
|
||||
}
|
||||
|
||||
/* constraints check */
|
||||
ret = regulator_check_mode(rdev, mode);
|
||||
ret = regulator_mode_constrain(rdev, &mode);
|
||||
if (ret < 0)
|
||||
goto out;
|
||||
|
||||
@ -2081,16 +2106,26 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
|
||||
|
||||
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;
|
||||
ret = regulator_check_drms(rdev);
|
||||
if (ret < 0)
|
||||
if (ret < 0) {
|
||||
ret = 0;
|
||||
goto out;
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
/* sanity check */
|
||||
if (!rdev->desc->ops->get_optimum_mode)
|
||||
goto out;
|
||||
|
||||
/*
|
||||
* we can actually do this so any errors are indicators of
|
||||
* potential real failure.
|
||||
*/
|
||||
ret = -EINVAL;
|
||||
|
||||
/* get output voltage */
|
||||
output_uV = _regulator_get_voltage(rdev);
|
||||
if (output_uV <= 0) {
|
||||
@ -2116,7 +2151,7 @@ int regulator_set_optimum_mode(struct regulator *regulator, int uA_load)
|
||||
mode = rdev->desc->ops->get_optimum_mode(rdev,
|
||||
input_uV, output_uV,
|
||||
total_uA_load);
|
||||
ret = regulator_check_mode(rdev, mode);
|
||||
ret = regulator_mode_constrain(rdev, &mode);
|
||||
if (ret < 0) {
|
||||
rdev_err(rdev, "failed to get optimum mode @ %d uA %d -> %d uV\n",
|
||||
total_uA_load, input_uV, output_uV);
|
||||
@ -2589,14 +2624,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
|
||||
if (ret < 0)
|
||||
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) {
|
||||
struct regulator_dev *r;
|
||||
int found = 0;
|
||||
@ -2621,14 +2648,6 @@ struct regulator_dev *regulator_register(struct regulator_desc *regulator_desc,
|
||||
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 */
|
||||
for (i = 0; i < init_data->num_consumer_supplies; i++) {
|
||||
ret = set_consumer_device_supply(rdev,
|
||||
|
@ -267,7 +267,6 @@ static int max8997_get_enable_register(struct regulator_dev *rdev,
|
||||
default:
|
||||
/* Not controllable or not exists */
|
||||
return -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -1033,11 +1032,11 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
|
||||
|
||||
/* For the safety, set max voltage before setting up */
|
||||
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);
|
||||
max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS(i + 1),
|
||||
max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i,
|
||||
max_buck2, 0x3f);
|
||||
max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS(i + 1),
|
||||
max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i,
|
||||
max_buck5, 0x3f);
|
||||
}
|
||||
|
||||
@ -1114,13 +1113,13 @@ static __devinit int max8997_pmic_probe(struct platform_device *pdev)
|
||||
|
||||
/* Initialize all the DVS related BUCK registers */
|
||||
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],
|
||||
0x3f);
|
||||
max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS(i + 1),
|
||||
max8997_update_reg(i2c, MAX8997_REG_BUCK2DVS1 + i,
|
||||
max8997->buck2_vol[i],
|
||||
0x3f);
|
||||
max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS(i + 1),
|
||||
max8997_update_reg(i2c, MAX8997_REG_BUCK5DVS1 + i,
|
||||
max8997->buck5_vol[i],
|
||||
0x3f);
|
||||
}
|
||||
|
@ -732,13 +732,15 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
|
||||
if (!pdata->buck1_set1) {
|
||||
printk(KERN_ERR "MAX8998 SET1 GPIO defined as 0 !\n");
|
||||
WARN_ON(!pdata->buck1_set1);
|
||||
return -EIO;
|
||||
ret = -EIO;
|
||||
goto err_free_mem;
|
||||
}
|
||||
/* Check if SET2 is not equal to 0 */
|
||||
if (!pdata->buck1_set2) {
|
||||
printk(KERN_ERR "MAX8998 SET2 GPIO defined as 0 !\n");
|
||||
WARN_ON(!pdata->buck1_set2);
|
||||
return -EIO;
|
||||
ret = -EIO;
|
||||
goto err_free_mem;
|
||||
}
|
||||
|
||||
gpio_request(pdata->buck1_set1, "MAX8998 BUCK1_SET1");
|
||||
@ -758,7 +760,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
|
||||
max8998->buck1_vol[0] = i;
|
||||
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE1, i);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_free_mem;
|
||||
|
||||
/* Set predefined value for BUCK1 register 2 */
|
||||
i = 0;
|
||||
@ -770,7 +772,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
|
||||
max8998->buck1_vol[1] = i;
|
||||
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE2, i);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_free_mem;
|
||||
|
||||
/* Set predefined value for BUCK1 register 3 */
|
||||
i = 0;
|
||||
@ -782,7 +784,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
|
||||
max8998->buck1_vol[2] = i;
|
||||
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE3, i);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_free_mem;
|
||||
|
||||
/* Set predefined value for BUCK1 register 4 */
|
||||
i = 0;
|
||||
@ -794,7 +796,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
|
||||
max8998->buck1_vol[3] = i;
|
||||
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK1_VOLTAGE4, i);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_free_mem;
|
||||
|
||||
}
|
||||
|
||||
@ -803,7 +805,8 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
|
||||
if (!pdata->buck2_set3) {
|
||||
printk(KERN_ERR "MAX8998 SET3 GPIO defined as 0 !\n");
|
||||
WARN_ON(!pdata->buck2_set3);
|
||||
return -EIO;
|
||||
ret = -EIO;
|
||||
goto err_free_mem;
|
||||
}
|
||||
gpio_request(pdata->buck2_set3, "MAX8998 BUCK2_SET3");
|
||||
gpio_direction_output(pdata->buck2_set3,
|
||||
@ -818,7 +821,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
|
||||
max8998->buck2_vol[0] = i;
|
||||
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE1, i);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_free_mem;
|
||||
|
||||
/* BUCK2 register 2 */
|
||||
i = 0;
|
||||
@ -830,7 +833,7 @@ static __devinit int max8998_pmic_probe(struct platform_device *pdev)
|
||||
max8998->buck2_vol[1] = i;
|
||||
ret = max8998_write_reg(i2c, MAX8998_REG_BUCK2_VOLTAGE2, i);
|
||||
if (ret)
|
||||
return ret;
|
||||
goto err_free_mem;
|
||||
}
|
||||
|
||||
for (i = 0; i < pdata->num_regulators; i++) {
|
||||
@ -860,6 +863,7 @@ err:
|
||||
if (rdev[i])
|
||||
regulator_unregister(rdev[i]);
|
||||
|
||||
err_free_mem:
|
||||
kfree(max8998->rdev);
|
||||
kfree(max8998);
|
||||
|
||||
|
@ -431,7 +431,8 @@ static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev,
|
||||
int min_uV, int max_uV, unsigned *selector)
|
||||
{
|
||||
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;
|
||||
|
||||
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,
|
||||
|
||||
mc13xxx_lock(priv->mc13xxx);
|
||||
ret = mc13xxx_reg_read(priv->mc13xxx,
|
||||
mc13892_regulators[id].vsel_reg, &val);
|
||||
mc13892_regulators[id].vsel_reg, &valread);
|
||||
if (ret)
|
||||
goto err;
|
||||
|
||||
hi = val & MC13892_SWITCHERS0_SWxHI;
|
||||
if (value > 1375)
|
||||
if (value > 1375000)
|
||||
hi = 1;
|
||||
if (value < 1100)
|
||||
else if (value < 1100000)
|
||||
hi = 0;
|
||||
else
|
||||
hi = valread & MC13892_SWITCHERS0_SWxHI;
|
||||
|
||||
if (hi) {
|
||||
value = (value - 1100000) / 25000;
|
||||
@ -464,8 +466,10 @@ static int mc13892_sw_regulator_set_voltage(struct regulator_dev *rdev,
|
||||
value = (value - 600000) / 25000;
|
||||
|
||||
mask = mc13892_regulators[id].vsel_mask | MC13892_SWITCHERS0_SWxHI;
|
||||
ret = mc13xxx_reg_rmw(priv->mc13xxx, mc13892_regulators[id].vsel_reg,
|
||||
mask, value << mc13892_regulators[id].vsel_shift);
|
||||
valread = (valread & ~mask) |
|
||||
(value << mc13892_regulators[id].vsel_shift);
|
||||
ret = mc13xxx_reg_write(priv->mc13xxx, mc13892_regulators[id].vsel_reg,
|
||||
valread);
|
||||
err:
|
||||
mc13xxx_unlock(priv->mc13xxx);
|
||||
|
||||
|
@ -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);
|
||||
|
||||
BUG_ON(val > mc13xxx_regulators[id].desc.n_voltages);
|
||||
BUG_ON(val >= mc13xxx_regulators[id].desc.n_voltages);
|
||||
|
||||
return mc13xxx_regulators[id].voltages[val];
|
||||
}
|
||||
|
@ -158,6 +158,7 @@ static int __devinit tps6105x_regulator_probe(struct platform_device *pdev)
|
||||
"failed to register regulator\n");
|
||||
return ret;
|
||||
}
|
||||
platform_set_drvdata(pdev, tps6105x);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -466,7 +466,6 @@ static struct regulator_ops tps65023_ldo_ops = {
|
||||
static int __devinit tps_65023_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
static int desc_id;
|
||||
const struct tps_info *info = (void *)id->driver_data;
|
||||
struct regulator_init_data *init_data;
|
||||
struct regulator_dev *rdev;
|
||||
@ -499,7 +498,7 @@ static int __devinit tps_65023_probe(struct i2c_client *client,
|
||||
tps->info[i] = info;
|
||||
|
||||
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].ops = (i > TPS65023_DCDC_3 ?
|
||||
&tps65023_ldo_ops : &tps65023_dcdc_ops);
|
||||
|
@ -553,7 +553,6 @@ static __devinit
|
||||
int tps6507x_pmic_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent);
|
||||
static int desc_id;
|
||||
struct tps_info *info = &tps6507x_pmic_regs[0];
|
||||
struct regulator_init_data *init_data;
|
||||
struct regulator_dev *rdev;
|
||||
@ -598,7 +597,7 @@ int tps6507x_pmic_probe(struct platform_device *pdev)
|
||||
}
|
||||
|
||||
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].ops = (i > TPS6507X_DCDC_3 ?
|
||||
&tps6507x_pmic_ldo_ops : &tps6507x_pmic_dcdc_ops);
|
||||
|
993
drivers/regulator/tps65910-regulator.c
Normal file
993
drivers/regulator/tps65910-regulator.c
Normal file
@ -0,0 +1,993 @@
|
||||
/*
|
||||
* 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 {
|
||||
u16 min_mV;
|
||||
u16 max_mV;
|
||||
|
||||
u8 flags;
|
||||
|
||||
/* used by regulator core */
|
||||
struct regulator_desc desc;
|
||||
|
||||
/* chip specific features */
|
||||
unsigned long features;
|
||||
};
|
||||
|
||||
|
||||
@ -70,12 +75,35 @@ struct twlreg_info {
|
||||
#define VREG_TRANS 1
|
||||
#define VREG_STATE 2
|
||||
#define VREG_VOLTAGE 3
|
||||
#define VREG_VOLTAGE_SMPS 4
|
||||
/* TWL6030 Misc register offsets */
|
||||
#define VREG_BC_ALL 1
|
||||
#define VREG_BC_REF 2
|
||||
#define VREG_BC_PROC 3
|
||||
#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
|
||||
twlreg_read(struct twlreg_info *info, unsigned slave_subgp, unsigned offset)
|
||||
{
|
||||
@ -118,21 +146,38 @@ static int twlreg_grp(struct regulator_dev *rdev)
|
||||
#define P2_GRP_6030 BIT(1) /* "peripherals" */
|
||||
#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);
|
||||
|
||||
if (state < 0)
|
||||
return state;
|
||||
|
||||
if (twl_class_is_4030())
|
||||
state &= P1_GRP_4030;
|
||||
else
|
||||
state &= P1_GRP_6030;
|
||||
return state;
|
||||
return state & P1_GRP_4030;
|
||||
}
|
||||
|
||||
static int twlreg_enable(struct regulator_dev *rdev)
|
||||
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
|
||||
grp = 1;
|
||||
|
||||
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 twl4030reg_enable(struct regulator_dev *rdev)
|
||||
{
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
int grp;
|
||||
@ -142,10 +187,7 @@ static int twlreg_enable(struct regulator_dev *rdev)
|
||||
if (grp < 0)
|
||||
return grp;
|
||||
|
||||
if (twl_class_is_4030())
|
||||
grp |= P1_GRP_4030;
|
||||
else
|
||||
grp |= P1_GRP_6030;
|
||||
grp |= P1_GRP_4030;
|
||||
|
||||
ret = twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_GRP, grp);
|
||||
|
||||
@ -154,30 +196,64 @@ static int twlreg_enable(struct regulator_dev *rdev)
|
||||
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);
|
||||
int grp;
|
||||
int ret;
|
||||
|
||||
grp = twlreg_read(info, TWL_MODULE_PM_RECEIVER, VREG_GRP);
|
||||
if (grp < 0)
|
||||
return grp;
|
||||
|
||||
if (twl_class_is_4030())
|
||||
grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030);
|
||||
else
|
||||
grp &= ~(P1_GRP_6030 | P2_GRP_6030 | P3_GRP_6030);
|
||||
grp &= ~(P1_GRP_4030 | P2_GRP_4030 | P3_GRP_4030);
|
||||
|
||||
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)
|
||||
{
|
||||
struct twlreg_info *info = rdev_get_drvdata(rdev);
|
||||
int grp = 0;
|
||||
int ret;
|
||||
|
||||
if (!(twl_class_is_6030() && (info->features & TWL6025_SUBCLASS)))
|
||||
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 (twl_class_is_6030())
|
||||
return 0; /* FIXME return for 6030 regulator */
|
||||
|
||||
if (state < 0)
|
||||
return state;
|
||||
state &= 0x0f;
|
||||
@ -190,15 +266,39 @@ static int twlreg_get_status(struct regulator_dev *rdev)
|
||||
: 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);
|
||||
unsigned message;
|
||||
int status;
|
||||
|
||||
if (twl_class_is_6030())
|
||||
return 0; /* FIXME return for 6030 regulator */
|
||||
|
||||
/* We can only set the mode through state machine commands... */
|
||||
switch (mode) {
|
||||
case REGULATOR_MODE_NORMAL:
|
||||
@ -227,6 +327,36 @@ static int twlreg_set_mode(struct regulator_dev *rdev, unsigned mode)
|
||||
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 = {
|
||||
.set_voltage = twl4030ldo_set_voltage,
|
||||
.get_voltage = twl4030ldo_get_voltage,
|
||||
|
||||
.enable = twlreg_enable,
|
||||
.disable = twlreg_disable,
|
||||
.is_enabled = twlreg_is_enabled,
|
||||
.enable = twl4030reg_enable,
|
||||
.disable = twl4030reg_disable,
|
||||
.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)
|
||||
@ -433,13 +563,13 @@ static struct regulator_ops twl6030ldo_ops = {
|
||||
.set_voltage = twl6030ldo_set_voltage,
|
||||
.get_voltage = twl6030ldo_get_voltage,
|
||||
|
||||
.enable = twlreg_enable,
|
||||
.disable = twlreg_disable,
|
||||
.is_enabled = twlreg_is_enabled,
|
||||
.enable = twl6030reg_enable,
|
||||
.disable = twl6030reg_disable,
|
||||
.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)
|
||||
return info->min_mV * 1000;
|
||||
}
|
||||
|
||||
static struct regulator_ops twlfixed_ops = {
|
||||
static struct regulator_ops twl4030fixed_ops = {
|
||||
.list_voltage = twlfixed_list_voltage,
|
||||
|
||||
.get_voltage = twlfixed_get_voltage,
|
||||
|
||||
.enable = twlreg_enable,
|
||||
.disable = twlreg_disable,
|
||||
.is_enabled = twlreg_is_enabled,
|
||||
.enable = twl4030reg_enable,
|
||||
.disable = twl4030reg_disable,
|
||||
.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 = {
|
||||
.enable = twlreg_enable,
|
||||
.disable = twlreg_disable,
|
||||
.is_enabled = twlreg_is_enabled,
|
||||
.get_status = twlreg_get_status,
|
||||
.enable = twl6030reg_enable,
|
||||
.disable = twl6030reg_disable,
|
||||
.is_enabled = twl6030reg_is_enabled,
|
||||
.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 = {
|
||||
#define TWL4030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
|
||||
remap_conf) \
|
||||
TWL_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
|
||||
remap_conf, TWL4030)
|
||||
#define TWL6030_FIXED_LDO(label, offset, mVolts, num, turnon_delay, \
|
||||
remap_conf) \
|
||||
remap_conf, TWL4030, twl4030fixed_ops)
|
||||
#define TWL6030_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) { \
|
||||
.base = offset, \
|
||||
@ -510,13 +856,11 @@ static struct regulator_ops twl6030_fixed_resource = {
|
||||
}, \
|
||||
}
|
||||
|
||||
#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num, \
|
||||
remap_conf) { \
|
||||
#define TWL6030_ADJUSTABLE_LDO(label, offset, min_mVolts, max_mVolts, num) { \
|
||||
.base = offset, \
|
||||
.id = num, \
|
||||
.min_mV = min_mVolts, \
|
||||
.max_mV = max_mVolts, \
|
||||
.remap = remap_conf, \
|
||||
.desc = { \
|
||||
.name = #label, \
|
||||
.id = TWL6030_REG_##label, \
|
||||
@ -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, \
|
||||
family) { \
|
||||
family, operations) { \
|
||||
.base = offset, \
|
||||
.id = num, \
|
||||
.min_mV = mVolts, \
|
||||
@ -539,17 +897,16 @@ static struct regulator_ops twl6030_fixed_resource = {
|
||||
.name = #label, \
|
||||
.id = family##_REG_##label, \
|
||||
.n_voltages = 1, \
|
||||
.ops = &twlfixed_ops, \
|
||||
.ops = &operations, \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.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, \
|
||||
.id = num, \
|
||||
.delay = turnon_delay, \
|
||||
.remap = remap_conf, \
|
||||
.desc = { \
|
||||
.name = #label, \
|
||||
.id = TWL6030_REG_##label, \
|
||||
@ -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
|
||||
* software control over them after boot.
|
||||
@ -589,19 +961,52 @@ static struct twlreg_info twl_regs[] = {
|
||||
/* 6030 REG with base as PMC Slave Misc : 0x0030 */
|
||||
/* Turnon-delay and remap configuration values for 6030 are not
|
||||
verified since the specification is not public */
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300, 1, 0x21),
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 2, 0x21),
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 3, 0x21),
|
||||
TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 4, 0x21),
|
||||
TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 5, 0x21),
|
||||
TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 7, 0x21),
|
||||
TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0, 0x21),
|
||||
TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0, 0x21),
|
||||
TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0, 0x21),
|
||||
TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0, 0x21),
|
||||
TWL6030_FIXED_RESOURCE(CLK32KG, 0x8C, 48, 0, 0x21),
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX1_6030, 0x54, 1000, 3300, 1),
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX2_6030, 0x58, 1000, 3300, 2),
|
||||
TWL6030_ADJUSTABLE_LDO(VAUX3_6030, 0x5c, 1000, 3300, 3),
|
||||
TWL6030_ADJUSTABLE_LDO(VMMC, 0x68, 1000, 3300, 4),
|
||||
TWL6030_ADJUSTABLE_LDO(VPP, 0x6c, 1000, 3300, 5),
|
||||
TWL6030_ADJUSTABLE_LDO(VUSIM, 0x74, 1000, 3300, 7),
|
||||
TWL6030_FIXED_LDO(VANA, 0x50, 2100, 15, 0),
|
||||
TWL6030_FIXED_LDO(VCXIO, 0x60, 1800, 16, 0),
|
||||
TWL6030_FIXED_LDO(VDAC, 0x64, 1800, 17, 0),
|
||||
TWL6030_FIXED_LDO(VUSB, 0x70, 3300, 18, 0),
|
||||
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)
|
||||
{
|
||||
int i;
|
||||
@ -623,6 +1028,9 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
||||
if (!initdata)
|
||||
return -EINVAL;
|
||||
|
||||
/* copy the features into regulator data */
|
||||
info->features = (unsigned long)initdata->driver_data;
|
||||
|
||||
/* Constrain board-specific capabilities according to what
|
||||
* this driver and the chip itself can actually do.
|
||||
*/
|
||||
@ -645,6 +1053,27 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
||||
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);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "can't register %s, %ld\n",
|
||||
@ -653,7 +1082,8 @@ static int __devinit twlreg_probe(struct platform_device *pdev)
|
||||
}
|
||||
platform_set_drvdata(pdev, rdev);
|
||||
|
||||
twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP,
|
||||
if (twl_class_is_4030())
|
||||
twlreg_write(info, TWL_MODULE_PM_RECEIVER, VREG_REMAP,
|
||||
info->remap);
|
||||
|
||||
/* NOTE: many regulators support short-circuit IRQs (presentable
|
||||
|
@ -600,7 +600,6 @@ err:
|
||||
static __devexit int wm831x_buckv_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
|
||||
struct wm831x *wm831x = dcdc->wm831x;
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
@ -776,7 +775,6 @@ err:
|
||||
static __devexit int wm831x_buckp_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct wm831x_dcdc *dcdc = platform_get_drvdata(pdev);
|
||||
struct wm831x *wm831x = dcdc->wm831x;
|
||||
|
||||
platform_set_drvdata(pdev, NULL);
|
||||
|
||||
|
@ -55,7 +55,7 @@ static int wm8400_ldo_list_voltage(struct regulator_dev *dev,
|
||||
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);
|
||||
u16 val;
|
||||
@ -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_LDO1_VSEL_MASK;
|
||||
|
||||
return wm8400_ldo_list_voltage(dev, val);
|
||||
return val;
|
||||
}
|
||||
|
||||
static int wm8400_ldo_set_voltage(struct regulator_dev *dev,
|
||||
@ -104,7 +104,7 @@ static struct regulator_ops wm8400_ldo_ops = {
|
||||
.enable = wm8400_ldo_enable,
|
||||
.disable = wm8400_ldo_disable,
|
||||
.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,
|
||||
};
|
||||
|
||||
@ -145,7 +145,7 @@ static int wm8400_dcdc_list_voltage(struct regulator_dev *dev,
|
||||
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);
|
||||
u16 val;
|
||||
@ -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_DC1_VSEL_MASK;
|
||||
|
||||
return 850000 + (25000 * val);
|
||||
return val;
|
||||
}
|
||||
|
||||
static int wm8400_dcdc_set_voltage(struct regulator_dev *dev,
|
||||
@ -261,7 +261,7 @@ static struct regulator_ops wm8400_dcdc_ops = {
|
||||
.enable = wm8400_dcdc_enable,
|
||||
.disable = wm8400_dcdc_disable,
|
||||
.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,
|
||||
.get_mode = wm8400_dcdc_get_mode,
|
||||
.set_mode = wm8400_dcdc_set_mode,
|
||||
|
@ -100,6 +100,7 @@ struct twl6030_usb {
|
||||
u8 linkstat;
|
||||
u8 asleep;
|
||||
bool irq_enabled;
|
||||
unsigned long features;
|
||||
};
|
||||
|
||||
#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)
|
||||
|
||||
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 */
|
||||
twl6030_writeb(twl, TWL6030_MODULE_ID0 , 0x1, TWL6030_BACKUP_REG);
|
||||
@ -214,7 +221,7 @@ static int twl6030_usb_ldo_init(struct twl6030_usb *twl)
|
||||
/* Program MISC2 register and set bit VUSB_IN_VBAT */
|
||||
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))
|
||||
return -ENODEV;
|
||||
|
||||
@ -409,6 +416,7 @@ static int __devinit twl6030_usb_probe(struct platform_device *pdev)
|
||||
twl->dev = &pdev->dev;
|
||||
twl->irq1 = platform_get_irq(pdev, 0);
|
||||
twl->irq2 = platform_get_irq(pdev, 1);
|
||||
twl->features = pdata->features;
|
||||
twl->otg.dev = twl->dev;
|
||||
twl->otg.label = "twl6030";
|
||||
twl->otg.set_host = twl6030_set_host;
|
||||
|
@ -311,10 +311,6 @@ enum max8997_irq {
|
||||
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
|
||||
struct max8997_dev {
|
||||
struct device *dev;
|
||||
|
800
include/linux/mfd/tps65910.h
Normal file
800
include/linux/mfd/tps65910.h
Normal file
@ -0,0 +1,800 @@
|
||||
/*
|
||||
* 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 {
|
||||
*
|
||||
* @min_uV: Smallest 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.
|
||||
* @max_uA: Largest current consumers may set.
|
||||
@ -99,6 +101,8 @@ struct regulation_constraints {
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
|
||||
int uV_offset;
|
||||
|
||||
/* current output range (inclusive) - for current control */
|
||||
int min_uA;
|
||||
int max_uA;
|
||||
@ -160,8 +164,6 @@ struct regulator_consumer_supply {
|
||||
* @supply_regulator: Parent regulator. Specified using the regulator name
|
||||
* as it appears in the name field in sysfs, which can
|
||||
* 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
|
||||
* be usable.
|
||||
@ -173,7 +175,6 @@ struct regulator_consumer_supply {
|
||||
*/
|
||||
struct regulator_init_data {
|
||||
const char *supply_regulator; /* or NULL for system supply */
|
||||
struct device *supply_regulator_dev; /* or NULL for system supply */
|
||||
|
||||
struct regulation_constraints constraints;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user