blob: 411b839f1a74406807dc5adb479d88862fd15ac0 [file] [log] [blame]
/*
* driver/regulator/tps80031-regulator.c
*
* Regulator driver for TI TPS80031
*
* Copyright (C) 2011 NVIDIA Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#include <linux/kernel.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/err.h>
#include <linux/slab.h>
#include <linux/platform_device.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/tps80031-regulator.h>
#include <linux/mfd/tps80031.h>
/* Flags for DCDC Voltage reading */
#define DCDC_OFFSET_EN BIT(0)
#define DCDC_EXTENDED_EN BIT(1)
#define TRACK_MODE_ENABLE BIT(2)
#define SMPS_MULTOFFSET_VIO BIT(1)
#define SMPS_MULTOFFSET_SMPS1 BIT(3)
#define SMPS_MULTOFFSET_SMPS2 BIT(4)
#define SMPS_MULTOFFSET_SMPS3 BIT(6)
#define SMPS_MULTOFFSET_SMPS4 BIT(0)
#define PMC_SMPS_OFFSET_ADD 0xE0
#define PMC_SMPS_MULT_ADD 0xE3
#define STATE_OFF 0x00
#define STATE_ON 0x01
#define STATE_MASK 0x03
#define TRANS_SLEEP_OFF 0x00
#define TRANS_SLEEP_ON 0x04
#define TRANS_SLEEP_MASK 0x0C
#define SMPS_CMD_MASK 0xC0
#define SMPS_VSEL_MASK 0x3F
#define LDO_VSEL_MASK 0x1F
#define TPS80031_MISC2_ADD 0xE5
#define MISC2_LDOUSB_IN_VSYS 0x10
#define MISC2_LDOUSB_IN_PMID 0x08
#define MISC2_LDOUSB_IN_MASK 0x18
#define MISC2_LDO3_SEL_VIB_VAL BIT(0)
#define MISC2_LDO3_SEL_VIB_MASK 0x1
#define CHARGERUSB_CTRL3_ADD 0xEA
#define BOOST_HW_PWR_EN BIT(5)
#define BOOST_HW_PWR_EN_MASK BIT(5)
#define CHARGERUSB_CTRL1_ADD 0xE8
#define OPA_MODE_EN BIT(6)
#define OPA_MODE_EN_MASK BIT(6)
#define USB_VBUS_CTRL_SET 0x04
#define USB_VBUS_CTRL_CLR 0x05
#define VBUS_DISCHRG 0x20
#define EXT_PWR_REQ (PWR_REQ_INPUT_PREQ1 | PWR_REQ_INPUT_PREQ2 | \
PWR_REQ_INPUT_PREQ3)
struct tps80031_regulator {
/* Regulator register address.*/
u8 trans_reg;
u8 state_reg;
u8 force_reg;
u8 volt_reg;
u8 volt_id;
uint8_t trans_reg_cache;
uint8_t state_reg_cache;
uint8_t force_reg_cache;
uint8_t volt_reg_cache;
/* twl resource ID, for resource control state machine */
u8 id;
/* chip constraints on regulator behavior */
u16 min_mV;
u16 max_mV;
/* regulator specific turn-on delay */
int delay;
u8 flags;
unsigned int platform_flags;
unsigned int ext_ctrl_flag;
/* used by regulator core */
struct regulator_desc desc;
/* Device */
struct device *dev;
/*Power request bits */
int preq_bit;
};
static inline struct device *to_tps80031_dev(struct regulator_dev *rdev)
{
return rdev_get_dev(rdev)->parent->parent;
}
static int tps80031_regulator_enable_time(struct regulator_dev *rdev)
{
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
return ri->delay;
}
static u8 tps80031_get_smps_offset(struct device *parent)
{
u8 value;
int ret;
ret = tps80031_read(parent, SLAVE_ID1, PMC_SMPS_OFFSET_ADD, &value);
if (ret < 0) {
dev_err(parent, "Error in reading smps offset register\n");
return 0;
}
return value;
}
static u8 tps80031_get_smps_mult(struct device *parent)
{
u8 value;
int ret;
ret = tps80031_read(parent, SLAVE_ID1, PMC_SMPS_MULT_ADD, &value);
if (ret < 0) {
dev_err(parent, "Error in reading smps mult register\n");
return 0;
}
return value;
}
static int tps80031_reg_is_enabled(struct regulator_dev *rdev)
{
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
if (ri->ext_ctrl_flag & EXT_PWR_REQ)
return true;
return ((ri->state_reg_cache & STATE_MASK) == STATE_ON);
}
static int tps80031_reg_enable(struct regulator_dev *rdev)
{
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
struct device *parent = to_tps80031_dev(rdev);
int ret;
uint8_t reg_val;
if (ri->ext_ctrl_flag & EXT_PWR_REQ)
return 0;
reg_val = (ri->state_reg_cache & ~STATE_MASK) |
(STATE_ON & STATE_MASK);
ret = tps80031_write(parent, SLAVE_ID1, ri->state_reg, reg_val);
if (ret < 0) {
dev_err(&rdev->dev, "Error in writing the STATE register\n");
return ret;
}
ri->state_reg_cache = reg_val;
udelay(ri->delay);
return ret;
}
static int tps80031_reg_disable(struct regulator_dev *rdev)
{
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
struct device *parent = to_tps80031_dev(rdev);
int ret;
uint8_t reg_val;
if (ri->ext_ctrl_flag & EXT_PWR_REQ)
return 0;
reg_val = (ri->state_reg_cache & ~STATE_MASK) |
(STATE_OFF & STATE_MASK);
ret = tps80031_write(parent, SLAVE_ID1, ri->state_reg, reg_val);
if (ret < 0)
dev_err(&rdev->dev, "Error in writing the STATE register\n");
else
ri->state_reg_cache = reg_val;
return ret;
}
/*
* DCDC status and control
*/
static int tps80031dcdc_list_voltage(struct regulator_dev *rdev, unsigned index)
{
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
int voltage = 0;
switch (ri->flags) {
case 0:
if (index == 0)
voltage = 0;
else if (index < 58)
voltage = (607700 + (12660 * (index - 1)));
else if (index == 58)
voltage = 1350 * 1000;
else if (index == 59)
voltage = 1500 * 1000;
else if (index == 60)
voltage = 1800 * 1000;
else if (index == 61)
voltage = 1900 * 1000;
else if (index == 62)
voltage = 2100 * 1000;
break;
case DCDC_OFFSET_EN:
if (index == 0)
voltage = 0;
else if (index < 58)
voltage = (700000 + (12500 * (index - 1)));
else if (index == 58)
voltage = 1350 * 1000;
else if (index == 59)
voltage = 1500 * 1000;
else if (index == 60)
voltage = 1800 * 1000;
else if (index == 61)
voltage = 1900 * 1000;
else if (index == 62)
voltage = 2100 * 1000;
break;
case DCDC_EXTENDED_EN:
if (index == 0)
voltage = 0;
else if (index < 58)
voltage = (1852000 + (38600 * (index - 1)));
else if (index == 58)
voltage = 2084 * 1000;
else if (index == 59)
voltage = 2315 * 1000;
else if (index == 60)
voltage = 2778 * 1000;
else if (index == 61)
voltage = 2932 * 1000;
else if (index == 62)
voltage = 3241 * 1000;
break;
case DCDC_OFFSET_EN|DCDC_EXTENDED_EN:
if (index == 0)
voltage = 0;
else if (index < 58)
voltage = (2161000 + (38600 * (index - 1)));
else if (index == 58)
voltage = 4167 * 1000;
else if (index == 59)
voltage = 2315 * 1000;
else if (index == 60)
voltage = 2778 * 1000;
else if (index == 61)
voltage = 2932 * 1000;
else if (index == 62)
voltage = 3241 * 1000;
break;
}
return voltage;
}
static int __tps80031_dcdc_set_voltage(struct device *parent,
struct tps80031_regulator *ri,
int min_uV, int max_uV,
unsigned *selector)
{
int vsel = 0;
int ret;
switch (ri->flags) {
case 0:
if (min_uV == 0)
vsel = 0;
else if ((min_uV >= 607700) && (min_uV <= 1300000)) {
int cal_volt;
vsel = (10 * (min_uV - 607700)) / 1266;
if (vsel % 100)
vsel += 100;
vsel /= 100;
vsel++;
cal_volt = (607700 + (12660 * (vsel - 1)));
if (cal_volt > max_uV)
return -EINVAL;
} 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 DCDC_OFFSET_EN:
if (min_uV == 0)
vsel = 0;
else if ((min_uV >= 700000) && (min_uV <= 1420000)) {
int cal_volt;
vsel = (min_uV - 700000) / 125;
if (vsel % 100)
vsel += 100;
vsel /= 100;
vsel++;
cal_volt = (700000 + (12500 * (vsel - 1)));
if (cal_volt > max_uV)
return -EINVAL;
} 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 DCDC_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++;
}
break;
case DCDC_OFFSET_EN|DCDC_EXTENDED_EN:
if (min_uV == 0)
vsel = 0;
else if ((min_uV >= 2161000) && (max_uV <= 4321000)) {
vsel = (min_uV - 2161000) / 386;
if (vsel % 100)
vsel += 100;
vsel /= 100;
vsel++;
}
break;
}
if (selector)
*selector = vsel;
if (ri->force_reg) {
if (((ri->force_reg_cache >> 6) & 0x3) == 0) {
ret = tps80031_write(parent, ri->volt_id,
ri->force_reg, vsel);
if (ret < 0)
dev_err(ri->dev, "Error in writing the "
"force register\n");
else
ri->force_reg_cache = vsel;
return ret;
}
}
ret = tps80031_write(parent, ri->volt_id, ri->volt_reg, vsel);
if (ret < 0)
dev_err(ri->dev, "Error in writing the Voltage register\n");
else
ri->volt_reg_cache = vsel;
return ret;
}
static int tps80031dcdc_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector)
{
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
struct device *parent = to_tps80031_dev(rdev);
return __tps80031_dcdc_set_voltage(parent, ri, min_uV, max_uV,
selector);
}
static int tps80031dcdc_get_voltage(struct regulator_dev *rdev)
{
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
uint8_t vsel = 0;
int voltage = 0;
if (ri->force_reg) {
vsel = ri->force_reg_cache;
if ((vsel & SMPS_CMD_MASK) == 0)
goto decode;
}
vsel = ri->volt_reg_cache;
decode:
vsel &= SMPS_VSEL_MASK;
switch (ri->flags) {
case 0:
if (vsel == 0)
voltage = 0;
else if (vsel < 58)
voltage = (607700 + (12660 * (vsel - 1)));
else if (vsel == 58)
voltage = 1350 * 1000;
else if (vsel == 59)
voltage = 1500 * 1000;
else if (vsel == 60)
voltage = 1800 * 1000;
else if (vsel == 61)
voltage = 1900 * 1000;
else if (vsel == 62)
voltage = 2100 * 1000;
break;
case DCDC_OFFSET_EN:
if (vsel == 0)
voltage = 0;
else if (vsel < 58)
voltage = (700000 + (12500 * (vsel - 1)));
else if (vsel == 58)
voltage = 1350 * 1000;
else if (vsel == 59)
voltage = 1500 * 1000;
else if (vsel == 60)
voltage = 1800 * 1000;
else if (vsel == 61)
voltage = 1900 * 1000;
else if (vsel == 62)
voltage = 2100 * 1000;
break;
case DCDC_EXTENDED_EN:
if (vsel == 0)
voltage = 0;
else if (vsel < 58)
voltage = (1852000 + (38600 * (vsel - 1)));
else if (vsel == 58)
voltage = 2084 * 1000;
else if (vsel == 59)
voltage = 2315 * 1000;
else if (vsel == 60)
voltage = 2778 * 1000;
else if (vsel == 61)
voltage = 2932 * 1000;
else if (vsel == 62)
voltage = 3241 * 1000;
break;
case DCDC_EXTENDED_EN|DCDC_OFFSET_EN:
if (vsel == 0)
voltage = 0;
else if (vsel < 58)
voltage = (2161000 + (38600 * (vsel - 1)));
else if (vsel == 58)
voltage = 4167 * 1000;
else if (vsel == 59)
voltage = 2315 * 1000;
else if (vsel == 60)
voltage = 2778 * 1000;
else if (vsel == 61)
voltage = 2932 * 1000;
else if (vsel == 62)
voltage = 3241 * 1000;
break;
}
return voltage;
}
static int tps80031ldo_list_voltage(struct regulator_dev *rdev, unsigned index)
{
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
if (index == 0)
return 0;
if ((ri->desc.id == TPS80031_ID_LDO2) &&
(ri->flags & TRACK_MODE_ENABLE))
return (ri->min_mV + (((index - 1) * 125))/10) * 1000;
return (ri->min_mV + ((index - 1) * 100)) * 1000;
}
static int __tps80031_ldo2_set_voltage_track_mode(struct device *parent,
struct tps80031_regulator *ri, int min_uV, int max_uV)
{
int vsel = 0;
int ret;
int nvsel;
if (min_uV < 600000) {
vsel = 0;
} else if ((min_uV >= 600000) && (max_uV <= 1300000)) {
vsel = (min_uV - 600000) / 125;
if (vsel % 100)
vsel += 100;
vsel /= 100;
vsel++;
} else {
return -EINVAL;
}
/* Check for valid setting for TPS80031 or TPS80032-ES1.0 */
if ((tps80031_get_chip_info(parent) == TPS80031) ||
((tps80031_get_chip_info(parent) == TPS80032) &&
(tps80031_get_pmu_version(parent) == 0x0))) {
nvsel = vsel & 0x1F;
if ((nvsel == 0x0) || (nvsel >= 0x19 && nvsel <= 0x1F)) {
dev_err(ri->dev, "Invalid value for track mode LDO2 "
"configuration for TPS8003x PMU\n");
return -EINVAL;
}
}
ret = tps80031_write(parent, ri->volt_id, ri->volt_reg, vsel);
if (ret < 0)
dev_err(ri->dev, "Error in writing the Voltage register\n");
else
ri->volt_reg_cache = vsel;
return ret;
}
static int __tps80031_ldo_set_voltage(struct device *parent,
struct tps80031_regulator *ri,
int min_uV, int max_uV,
unsigned *selector)
{
int vsel;
int ret;
if ((min_uV/1000 < ri->min_mV) || (max_uV/1000 > ri->max_mV))
return -EDOM;
if ((ri->desc.id == TPS80031_ID_LDO2) &&
(ri->flags & TRACK_MODE_ENABLE))
return __tps80031_ldo2_set_voltage_track_mode(parent, ri,
min_uV, max_uV);
/*
* Use the below formula to calculate vsel
* mV = 1000mv + 100mv * (vsel - 1)
*/
vsel = (min_uV/1000 - 1000)/100 + 1;
if (selector)
*selector = vsel;
ret = tps80031_write(parent, ri->volt_id, ri->volt_reg, vsel);
if (ret < 0)
dev_err(ri->dev, "Error in writing the Voltage register\n");
else
ri->volt_reg_cache = vsel;
return ret;
}
static int tps80031ldo_set_voltage(struct regulator_dev *rdev,
int min_uV, int max_uV, unsigned *selector)
{
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
struct device *parent = to_tps80031_dev(rdev);
return __tps80031_ldo_set_voltage(parent, ri, min_uV, max_uV,
selector);
}
static int tps80031ldo_get_voltage(struct regulator_dev *rdev)
{
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
uint8_t vsel;
if ((ri->desc.id == TPS80031_ID_LDO2) &&
(ri->flags & TRACK_MODE_ENABLE)) {
vsel = ri->volt_reg_cache & 0x3F;
return (ri->min_mV + (((vsel - 1) * 125))/10) * 1000;
}
vsel = ri->volt_reg_cache & LDO_VSEL_MASK;
/*
* Use the below formula to calculate vsel
* mV = 1000mv + 100mv * (vsel - 1)
*/
return (1000 + (100 * (vsel - 1))) * 1000;
}
/* VBUS */
static int tps80031_vbus_enable_time(struct regulator_dev *rdev)
{
/* Enable and settling time for vbus is 3ms */
return 3000;
}
static int tps80031_vbus_is_enabled(struct regulator_dev *rdev)
{
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
struct device *parent = to_tps80031_dev(rdev);
uint8_t ctrl1, ctrl3;
int ret;
if (ri->platform_flags & VBUS_SW_ONLY) {
ret = tps80031_read(parent, SLAVE_ID2,
CHARGERUSB_CTRL1_ADD, &ctrl1);
if (!ret)
ret = tps80031_read(parent, SLAVE_ID2,
CHARGERUSB_CTRL3_ADD, &ctrl3);
if (ret < 0) {
dev_err(&rdev->dev, "Error in reading control reg\n");
return ret;
}
if ((ctrl1 & OPA_MODE_EN) && (ctrl3 & BOOST_HW_PWR_EN))
return 1;
return 0;
} else {
return -EIO;
}
}
static int tps80031_vbus_enable(struct regulator_dev *rdev)
{
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
struct device *parent = to_tps80031_dev(rdev);
int ret;
if (ri->platform_flags & VBUS_SW_ONLY) {
ret = tps80031_set_bits(parent, SLAVE_ID2,
CHARGERUSB_CTRL1_ADD, OPA_MODE_EN);
if (!ret)
ret = tps80031_set_bits(parent, SLAVE_ID2,
CHARGERUSB_CTRL3_ADD, BOOST_HW_PWR_EN);
if (ret < 0) {
dev_err(&rdev->dev, "Error in reading control reg\n");
return ret;
}
udelay(ri->delay);
return ret;
}
dev_err(&rdev->dev, "%s() is not supported with flag 0x%08x\n",
__func__, ri->platform_flags);
return -EIO;
}
static int tps80031_vbus_disable(struct regulator_dev *rdev)
{
struct tps80031_regulator *ri = rdev_get_drvdata(rdev);
struct device *parent = to_tps80031_dev(rdev);
int ret = 0;
if (ri->platform_flags & VBUS_SW_ONLY) {
if (ri->platform_flags & VBUS_DISCHRG_EN_PDN)
ret = tps80031_write(parent, SLAVE_ID2,
USB_VBUS_CTRL_SET, VBUS_DISCHRG);
if (!ret)
ret = tps80031_clr_bits(parent, SLAVE_ID2,
CHARGERUSB_CTRL1_ADD, OPA_MODE_EN);
if (!ret)
ret = tps80031_clr_bits(parent, SLAVE_ID2,
CHARGERUSB_CTRL3_ADD, BOOST_HW_PWR_EN);
if (!ret)
mdelay((ri->delay + 999)/1000);
if (ri->platform_flags & VBUS_DISCHRG_EN_PDN)
tps80031_write(parent, SLAVE_ID2,
USB_VBUS_CTRL_CLR, VBUS_DISCHRG);
if (ret < 0)
dev_err(&rdev->dev, "Error in reading control reg\n");
return ret;
}
dev_err(&rdev->dev, "%s() is not supported with flag 0x%08x\n",
__func__, ri->platform_flags);
return -EIO;
}
static int tps80031vbus_get_voltage(struct regulator_dev *rdev)
{
int ret;
ret = tps80031_vbus_is_enabled(rdev);
if (ret > 0)
return 5000000;
return ret;
}
static struct regulator_ops tps80031dcdc_ops = {
.list_voltage = tps80031dcdc_list_voltage,
.set_voltage = tps80031dcdc_set_voltage,
.get_voltage = tps80031dcdc_get_voltage,
.enable = tps80031_reg_enable,
.disable = tps80031_reg_disable,
.is_enabled = tps80031_reg_is_enabled,
.enable_time = tps80031_regulator_enable_time,
};
static struct regulator_ops tps80031ldo_ops = {
.list_voltage = tps80031ldo_list_voltage,
.set_voltage = tps80031ldo_set_voltage,
.get_voltage = tps80031ldo_get_voltage,
.enable = tps80031_reg_enable,
.disable = tps80031_reg_disable,
.is_enabled = tps80031_reg_is_enabled,
.enable_time = tps80031_regulator_enable_time,
};
static struct regulator_ops tps80031vbus_ops = {
.get_voltage = tps80031vbus_get_voltage,
.enable = tps80031_vbus_enable,
.disable = tps80031_vbus_disable,
.is_enabled = tps80031_vbus_is_enabled,
.enable_time = tps80031_vbus_enable_time,
};
#define TPS80031_REG(_id, _trans_reg, _state_reg, _force_reg, _volt_reg, \
_volt_id, min_mVolts, max_mVolts, _ops, _n_volt, _delay, \
_preq_bit) \
{ \
.trans_reg = _trans_reg, \
.state_reg = _state_reg, \
.force_reg = _force_reg, \
.volt_reg = _volt_reg, \
.volt_id = _volt_id, \
.id = TPS80031_ID_##_id, \
.min_mV = min_mVolts, \
.max_mV = max_mVolts, \
.desc = { \
.name = tps80031_rails(_id), \
.id = TPS80031_ID_##_id, \
.n_voltages = _n_volt, \
.ops = &_ops, \
.type = REGULATOR_VOLTAGE, \
.owner = THIS_MODULE, \
}, \
.delay = _delay, \
.preq_bit = _preq_bit, \
}
static struct tps80031_regulator tps80031_regulator[] = {
TPS80031_REG(VIO, 0x47, 0x48, 0x49, 0x4A, SLAVE_ID0, 600, 2100,
tps80031dcdc_ops, 63, 500, 4),
TPS80031_REG(SMPS1, 0x53, 0x54, 0x55, 0x56, SLAVE_ID0, 600, 2100,
tps80031dcdc_ops, 63, 500, 0),
TPS80031_REG(SMPS2, 0x59, 0x5A, 0x5B, 0x5C, SLAVE_ID0, 600, 2100,
tps80031dcdc_ops, 63, 500, 1),
TPS80031_REG(SMPS3, 0x65, 0x66, 0x00, 0x68, SLAVE_ID1, 600, 2100,
tps80031dcdc_ops, 63, 500, 2),
TPS80031_REG(SMPS4, 0x41, 0x42, 0x00, 0x44, SLAVE_ID1, 600, 2100,
tps80031dcdc_ops, 63, 500, 3),
TPS80031_REG(LDO1, 0x9D, 0x9E, 0x00, 0x9F, SLAVE_ID1, 1000, 3300,
tps80031ldo_ops, 25, 500, 8),
TPS80031_REG(LDO2, 0x85, 0x86, 0x00, 0x87, SLAVE_ID1, 1000, 3300,
tps80031ldo_ops, 25, 500, 9),
TPS80031_REG(LDO3, 0x8D, 0x8E, 0x00, 0x8F, SLAVE_ID1, 1000, 3300,
tps80031ldo_ops, 25, 500, 10),
TPS80031_REG(LDO4, 0x89, 0x8A, 0x00, 0x8B, SLAVE_ID1, 1000, 3300,
tps80031ldo_ops, 25, 500, 11),
TPS80031_REG(LDO5, 0x99, 0x9A, 0x00, 0x9B, SLAVE_ID1, 1000, 3300,
tps80031ldo_ops, 25, 500, 12),
TPS80031_REG(LDO6, 0x91, 0x92, 0x00, 0x93, SLAVE_ID1, 1000, 3300,
tps80031ldo_ops, 25, 500, 13),
TPS80031_REG(LDO7, 0xA5, 0xA6, 0x00, 0xA7, SLAVE_ID1, 1000, 3300,
tps80031ldo_ops, 25, 500, 14),
TPS80031_REG(LDOUSB, 0xA1, 0xA2, 0x00, 0xA3, SLAVE_ID1, 1000, 3300,
tps80031ldo_ops, 25, 500, 5),
TPS80031_REG(LDOLN, 0x95, 0x96, 0x00, 0x97, SLAVE_ID1, 1000, 3300,
tps80031ldo_ops, 25, 500, 15),
TPS80031_REG(VANA, 0x81, 0x82, 0x00, 0x83, SLAVE_ID1, 1000, 3300,
tps80031ldo_ops, 25, 500, -1),
TPS80031_REG(VBUS, 0x0, 0x0, 0x00, 0x0, SLAVE_ID1, 0, 5000,
tps80031vbus_ops, 2, 200000, -1),
};
static int tps80031_power_req_config(struct device *parent,
struct tps80031_regulator *ri,
struct tps80031_regulator_platform_data *tps80031_pdata)
{
int ret;
uint8_t reg_val;
if (ri->preq_bit < 0)
return 0;
ret = tps80031_ext_power_req_config(parent, ri->ext_ctrl_flag,
ri->preq_bit, ri->state_reg, ri->trans_reg);
if (!ret)
ret = tps80031_read(parent, SLAVE_ID1, ri->trans_reg,
&ri->trans_reg_cache);
if (!ret && ri->state_reg)
ret = tps80031_read(parent, SLAVE_ID1, ri->state_reg,
&ri->state_reg_cache);
if (ret < 0) {
dev_err(ri->dev, "%s() fails\n", __func__);
return ret;
}
if (tps80031_pdata->ext_ctrl_flag &
(PWR_OFF_ON_SLEEP | PWR_ON_ON_SLEEP)) {
reg_val = (ri->trans_reg_cache & ~0xC);
if (tps80031_pdata->ext_ctrl_flag & PWR_ON_ON_SLEEP)
reg_val |= 0x4;
ret = tps80031_write(parent, SLAVE_ID1, ri->trans_reg,
reg_val);
if (ret < 0)
dev_err(ri->dev, "Not able to write reg 0x%02x\n",
ri->trans_reg);
else
ri->trans_reg_cache = reg_val;
}
return ret;
}
static int tps80031_regulator_preinit(struct device *parent,
struct tps80031_regulator *ri,
struct tps80031_regulator_platform_data *tps80031_pdata)
{
int ret = 0;
uint8_t reg_val;
if (ri->desc.id == TPS80031_ID_LDOUSB) {
if (ri->platform_flags & USBLDO_INPUT_VSYS)
ret = tps80031_update(parent, SLAVE_ID1,
TPS80031_MISC2_ADD,
MISC2_LDOUSB_IN_VSYS, MISC2_LDOUSB_IN_MASK);
if (ri->platform_flags & USBLDO_INPUT_PMID)
ret = tps80031_update(parent, SLAVE_ID1,
TPS80031_MISC2_ADD,
MISC2_LDOUSB_IN_PMID, MISC2_LDOUSB_IN_MASK);
if (ret < 0) {
dev_err(ri->dev, "Not able to configure the rail "
"LDOUSB as per platform data error %d\n", ret);
return ret;
}
}
if (ri->desc.id == TPS80031_ID_LDO3) {
if (ri->platform_flags & LDO3_OUTPUT_VIB)
ret = tps80031_update(parent, SLAVE_ID1,
TPS80031_MISC2_ADD,
MISC2_LDO3_SEL_VIB_VAL,
MISC2_LDO3_SEL_VIB_MASK);
if (ret < 0) {
dev_err(ri->dev, "Not able to configure the rail "
"LDO3 as per platform data error %d\n", ret);
return ret;
}
}
if (!tps80031_pdata->init_apply)
return 0;
if (tps80031_pdata->init_uV >= 0) {
switch (ri->desc.id) {
case TPS80031_ID_VIO:
case TPS80031_ID_SMPS1:
case TPS80031_ID_SMPS2:
case TPS80031_ID_SMPS3:
case TPS80031_ID_SMPS4:
ret = __tps80031_dcdc_set_voltage(parent, ri,
tps80031_pdata->init_uV,
tps80031_pdata->init_uV, 0);
break;
case TPS80031_ID_LDO1:
case TPS80031_ID_LDO2:
case TPS80031_ID_LDO3:
case TPS80031_ID_LDO4:
case TPS80031_ID_LDO5:
case TPS80031_ID_LDO6:
case TPS80031_ID_LDO7:
case TPS80031_ID_LDOUSB:
case TPS80031_ID_LDOLN:
case TPS80031_ID_VANA:
ret = __tps80031_ldo_set_voltage(parent, ri,
tps80031_pdata->init_uV,
tps80031_pdata->init_uV, 0);
break;
default:
ret = -EINVAL;
break;
}
if (ret < 0) {
dev_err(ri->dev, "Not able to initialize voltage %d "
"for rail %d err %d\n", tps80031_pdata->init_uV,
ri->desc.id, ret);
return ret;
}
}
if (tps80031_pdata->init_enable)
reg_val = (ri->state_reg_cache & ~STATE_MASK) |
(STATE_ON & STATE_MASK);
else
reg_val = (ri->state_reg_cache & ~STATE_MASK) |
(STATE_OFF & STATE_MASK);
ret = tps80031_write(parent, SLAVE_ID1, ri->state_reg, reg_val);
if (ret < 0)
dev_err(ri->dev, "Not able to %s rail %d err %d\n",
(tps80031_pdata->init_enable) ? "enable" : "disable",
ri->desc.id, ret);
else
ri->state_reg_cache = reg_val;
return ret;
}
static inline struct tps80031_regulator *find_regulator_info(int id)
{
struct tps80031_regulator *ri;
int i;
for (i = 0; i < ARRAY_SIZE(tps80031_regulator); i++) {
ri = &tps80031_regulator[i];
if (ri->desc.id == id)
return ri;
}
return NULL;
}
static void check_smps_mode_mult(struct device *parent,
struct tps80031_regulator *ri)
{
int mult_offset;
switch (ri->desc.id) {
case TPS80031_ID_VIO:
mult_offset = SMPS_MULTOFFSET_VIO;
break;
case TPS80031_ID_SMPS1:
mult_offset = SMPS_MULTOFFSET_SMPS1;
break;
case TPS80031_ID_SMPS2:
mult_offset = SMPS_MULTOFFSET_SMPS2;
break;
case TPS80031_ID_SMPS3:
mult_offset = SMPS_MULTOFFSET_SMPS3;
break;
case TPS80031_ID_SMPS4:
mult_offset = SMPS_MULTOFFSET_SMPS4;
break;
case TPS80031_ID_LDO2:
ri->flags = (tps80031_get_smps_mult(parent) & (1 << 5)) ?
TRACK_MODE_ENABLE : 0;
/* TRACK mode the ldo2 varies from 600mV to 1300mV */
if (ri->flags & TRACK_MODE_ENABLE) {
ri->min_mV = 600;
ri->max_mV = 1300;
ri->desc.n_voltages = 57;
}
return;
default:
return;
}
ri->flags = (tps80031_get_smps_offset(parent) & mult_offset) ?
DCDC_OFFSET_EN : 0;
ri->flags |= (tps80031_get_smps_mult(parent) & mult_offset) ?
DCDC_EXTENDED_EN : 0;
return;
}
static inline int tps80031_cache_regulator_register(struct device *parent,
struct tps80031_regulator *ri)
{
int ret;
ret = tps80031_read(parent, SLAVE_ID1, ri->trans_reg,
&ri->trans_reg_cache);
if (!ret && ri->state_reg)
ret = tps80031_read(parent, SLAVE_ID1, ri->state_reg,
&ri->state_reg_cache);
if (!ret && ri->force_reg)
ret = tps80031_read(parent, ri->volt_id, ri->force_reg,
&ri->force_reg_cache);
if (!ret && ri->volt_reg)
ret = tps80031_read(parent, ri->volt_id, ri->volt_reg,
&ri->volt_reg_cache);
return ret;
}
static int __devinit tps80031_regulator_probe(struct platform_device *pdev)
{
struct tps80031_regulator *ri = NULL;
struct regulator_dev *rdev;
struct tps80031_regulator_platform_data *tps_pdata;
int id = pdev->id;
int err;
dev_dbg(&pdev->dev, "Probing reulator %d\n", id);
ri = find_regulator_info(id);
if (ri == NULL) {
dev_err(&pdev->dev, "invalid regulator ID specified\n");
return -EINVAL;
}
tps_pdata = pdev->dev.platform_data;
ri->dev = &pdev->dev;
if (tps_pdata->delay_us > 0)
ri->delay = tps_pdata->delay_us;
check_smps_mode_mult(pdev->dev.parent, ri);
ri->platform_flags = tps_pdata->flags;
ri->ext_ctrl_flag = tps_pdata->ext_ctrl_flag;
err = tps80031_cache_regulator_register(pdev->dev.parent, ri);
if (err) {
dev_err(&pdev->dev, "Register access for caching is failed\n");
return err;
}
err = tps80031_regulator_preinit(pdev->dev.parent, ri, tps_pdata);
if (err)
return err;
err = tps80031_power_req_config(pdev->dev.parent, ri, tps_pdata);
if (err)
return err;
rdev = regulator_register(&ri->desc, &pdev->dev,
&tps_pdata->regulator, ri);
if (IS_ERR_OR_NULL(rdev)) {
dev_err(&pdev->dev, "failed to register regulator %s\n",
ri->desc.name);
return PTR_ERR(rdev);
}
platform_set_drvdata(pdev, rdev);
return 0;
}
static int __devexit tps80031_regulator_remove(struct platform_device *pdev)
{
struct regulator_dev *rdev = platform_get_drvdata(pdev);
regulator_unregister(rdev);
return 0;
}
static struct platform_driver tps80031_regulator_driver = {
.driver = {
.name = "tps80031-regulator",
.owner = THIS_MODULE,
},
.probe = tps80031_regulator_probe,
.remove = __devexit_p(tps80031_regulator_remove),
};
static int __init tps80031_regulator_init(void)
{
return platform_driver_register(&tps80031_regulator_driver);
}
subsys_initcall(tps80031_regulator_init);
static void __exit tps80031_regulator_exit(void)
{
platform_driver_unregister(&tps80031_regulator_driver);
}
module_exit(tps80031_regulator_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Regulator Driver for TI TPS80031 PMIC");
MODULE_ALIAS("platform:tps80031-regulator");