Merge remote-tracking branches 'regulator/topic/qcom-spmi', 'regulator/topic/rn5t618', 'regulator/topic/tps65218' and 'regulator/topic/twl' into regulator-next
This commit is contained in:
Коммит
a485f5fc8c
|
@ -1,18 +1,21 @@
|
|||
* Ricoh RN5T618 PMIC
|
||||
* Ricoh RN5T567/RN5T618 PMIC
|
||||
|
||||
Ricoh RN5T618 is a power management IC which integrates 3 step-down
|
||||
DCDC converters, 7 low-dropout regulators, a Li-ion battery charger,
|
||||
fuel gauge, ADC, GPIOs and a watchdog timer. It can be controlled
|
||||
through a I2C interface.
|
||||
Ricoh RN5T567/RN5T618 is a power management IC family which integrates
|
||||
3 to 4 step-down DCDC converters, 7 low-dropout regulators, GPIOs and
|
||||
a watchdog timer. The RN5T618 provides additionally a Li-ion battery
|
||||
charger, fuel gauge and an ADC. It can be controlled through an I2C
|
||||
interface.
|
||||
|
||||
Required properties:
|
||||
- compatible: should be "ricoh,rn5t618"
|
||||
- compatible: must be one of
|
||||
"ricoh,rn5t567"
|
||||
"ricoh,rn5t618"
|
||||
- reg: the I2C slave address of the device
|
||||
|
||||
Sub-nodes:
|
||||
- regulators: the node is required if the regulator functionality is
|
||||
needed. The valid regulator names are: DCDC1, DCDC2, DCDC3, LDO1,
|
||||
LDO2, LDO3, LDO4, LDO5, LDORTC1 and LDORTC2.
|
||||
needed. The valid regulator names are: DCDC1, DCDC2, DCDC3, DCDC4
|
||||
(RN5T567), LDO1, LDO2, LDO3, LDO4, LDO5, LDORTC1 and LDORTC2.
|
||||
The common bindings for each individual regulator can be found in:
|
||||
Documentation/devicetree/bindings/regulator/regulator.txt
|
||||
|
||||
|
|
|
@ -113,9 +113,9 @@ pm8916:
|
|||
l14, l15, l16, l17, l18
|
||||
|
||||
pm8941:
|
||||
s1, s2, s3, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13, l14,
|
||||
l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3,
|
||||
mvs1, mvs2
|
||||
s1, s2, s3, s4, l1, l2, l3, l4, l5, l6, l7, l8, l9, l10, l11, l12, l13,
|
||||
l14, l15, l16, l17, l18, l19, l20, l21, l22, l23, l24, lvs1, lvs2, lvs3,
|
||||
5vs1, 5vs2
|
||||
|
||||
pm8994:
|
||||
s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, l1, l2, l3, l4, l5,
|
||||
|
|
|
@ -80,6 +80,7 @@
|
|||
pmic@32 {
|
||||
compatible = "ricoh,rn5t618";
|
||||
reg = <0x32>;
|
||||
system-power-controller;
|
||||
|
||||
regulators {
|
||||
};
|
||||
|
|
|
@ -852,13 +852,14 @@ config MFD_RK808
|
|||
including interrupts, RTC, LDO & DCDC regulators, and onkey.
|
||||
|
||||
config MFD_RN5T618
|
||||
tristate "Ricoh RN5T5618 PMIC"
|
||||
tristate "Ricoh RN5T567/618 PMIC"
|
||||
depends on I2C
|
||||
depends on OF
|
||||
select MFD_CORE
|
||||
select REGMAP_I2C
|
||||
help
|
||||
Say yes here to add support for the Ricoh RN5T618 PMIC. This
|
||||
driver provides common support for accessing the device,
|
||||
Say yes here to add support for the Ricoh RN5T567 or R5T618 PMIC.
|
||||
This driver provides common support for accessing the device,
|
||||
additional drivers must be enabled in order to use the
|
||||
functionality of the device.
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
* MFD core driver for Ricoh RN5T618 PMIC
|
||||
*
|
||||
* Copyright (C) 2014 Beniamino Galvani <b.galvani@gmail.com>
|
||||
* Copyright (C) 2016 Toradex AG
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
|
@ -11,10 +12,13 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <linux/delay.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/mfd/core.h>
|
||||
#include <linux/mfd/rn5t618.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/reboot.h>
|
||||
#include <linux/regmap.h>
|
||||
|
||||
static const struct mfd_cell rn5t618_cells[] = {
|
||||
|
@ -48,28 +52,64 @@ static const struct regmap_config rn5t618_regmap_config = {
|
|||
};
|
||||
|
||||
static struct rn5t618 *rn5t618_pm_power_off;
|
||||
static struct notifier_block rn5t618_restart_handler;
|
||||
|
||||
static void rn5t618_power_off(void)
|
||||
static void rn5t618_trigger_poweroff_sequence(bool repower)
|
||||
{
|
||||
/* disable automatic repower-on */
|
||||
regmap_update_bits(rn5t618_pm_power_off->regmap, RN5T618_REPCNT,
|
||||
RN5T618_REPCNT_REPWRON, 0);
|
||||
RN5T618_REPCNT_REPWRON,
|
||||
repower ? RN5T618_REPCNT_REPWRON : 0);
|
||||
/* start power-off sequence */
|
||||
regmap_update_bits(rn5t618_pm_power_off->regmap, RN5T618_SLPCNT,
|
||||
RN5T618_SLPCNT_SWPWROFF, RN5T618_SLPCNT_SWPWROFF);
|
||||
}
|
||||
|
||||
static void rn5t618_power_off(void)
|
||||
{
|
||||
rn5t618_trigger_poweroff_sequence(false);
|
||||
}
|
||||
|
||||
static int rn5t618_restart(struct notifier_block *this,
|
||||
unsigned long mode, void *cmd)
|
||||
{
|
||||
rn5t618_trigger_poweroff_sequence(true);
|
||||
|
||||
/*
|
||||
* Re-power factor detection on PMIC side is not instant. 1ms
|
||||
* proved to be enough time until reset takes effect.
|
||||
*/
|
||||
mdelay(1);
|
||||
|
||||
return NOTIFY_DONE;
|
||||
}
|
||||
|
||||
static const struct of_device_id rn5t618_of_match[] = {
|
||||
{ .compatible = "ricoh,rn5t567", .data = (void *)RN5T567 },
|
||||
{ .compatible = "ricoh,rn5t618", .data = (void *)RN5T618 },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rn5t618_of_match);
|
||||
|
||||
static int rn5t618_i2c_probe(struct i2c_client *i2c,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
const struct of_device_id *of_id;
|
||||
struct rn5t618 *priv;
|
||||
int ret;
|
||||
|
||||
of_id = of_match_device(rn5t618_of_match, &i2c->dev);
|
||||
if (!of_id) {
|
||||
dev_err(&i2c->dev, "Failed to find matching DT ID\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
priv = devm_kzalloc(&i2c->dev, sizeof(*priv), GFP_KERNEL);
|
||||
if (!priv)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(i2c, priv);
|
||||
priv->variant = (long)of_id->data;
|
||||
|
||||
priv->regmap = devm_regmap_init_i2c(i2c, &rn5t618_regmap_config);
|
||||
if (IS_ERR(priv->regmap)) {
|
||||
|
@ -85,9 +125,21 @@ static int rn5t618_i2c_probe(struct i2c_client *i2c,
|
|||
return ret;
|
||||
}
|
||||
|
||||
if (!pm_power_off) {
|
||||
rn5t618_pm_power_off = priv;
|
||||
pm_power_off = rn5t618_power_off;
|
||||
rn5t618_pm_power_off = priv;
|
||||
if (of_device_is_system_power_controller(i2c->dev.of_node)) {
|
||||
if (!pm_power_off)
|
||||
pm_power_off = rn5t618_power_off;
|
||||
else
|
||||
dev_warn(&i2c->dev, "Poweroff callback already assigned\n");
|
||||
}
|
||||
|
||||
rn5t618_restart_handler.notifier_call = rn5t618_restart;
|
||||
rn5t618_restart_handler.priority = 192;
|
||||
|
||||
ret = register_restart_handler(&rn5t618_restart_handler);
|
||||
if (ret) {
|
||||
dev_err(&i2c->dev, "cannot register restart handler, %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
@ -105,12 +157,6 @@ static int rn5t618_i2c_remove(struct i2c_client *i2c)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static const struct of_device_id rn5t618_of_match[] = {
|
||||
{ .compatible = "ricoh,rn5t618" },
|
||||
{ }
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, rn5t618_of_match);
|
||||
|
||||
static const struct i2c_device_id rn5t618_i2c_id[] = {
|
||||
{ }
|
||||
};
|
||||
|
@ -129,5 +175,5 @@ static struct i2c_driver rn5t618_i2c_driver = {
|
|||
module_i2c_driver(rn5t618_i2c_driver);
|
||||
|
||||
MODULE_AUTHOR("Beniamino Galvani <b.galvani@gmail.com>");
|
||||
MODULE_DESCRIPTION("Ricoh RN5T618 MFD driver");
|
||||
MODULE_DESCRIPTION("Ricoh RN5T567/618 MFD driver");
|
||||
MODULE_LICENSE("GPL v2");
|
||||
|
|
|
@ -645,10 +645,11 @@ config REGULATOR_RK808
|
|||
outputs which can be controlled by i2c communication.
|
||||
|
||||
config REGULATOR_RN5T618
|
||||
tristate "Ricoh RN5T618 voltage regulators"
|
||||
tristate "Ricoh RN5T567/618 voltage regulators"
|
||||
depends on MFD_RN5T618
|
||||
help
|
||||
Say y here to support the regulators found on Ricoh RN5T618 PMIC.
|
||||
Say y here to support the regulators found on Ricoh RN5T567 or
|
||||
RN5T618 PMIC.
|
||||
|
||||
config REGULATOR_RT5033
|
||||
tristate "Richtek RT5033 Regulators"
|
||||
|
|
|
@ -1085,6 +1085,8 @@ static struct regulator_ops spmi_vs_ops = {
|
|||
.set_pull_down = spmi_regulator_common_set_pull_down,
|
||||
.set_soft_start = spmi_regulator_common_set_soft_start,
|
||||
.set_over_current_protection = spmi_regulator_vs_ocp,
|
||||
.set_mode = spmi_regulator_common_set_mode,
|
||||
.get_mode = spmi_regulator_common_get_mode,
|
||||
};
|
||||
|
||||
static struct regulator_ops spmi_boost_ops = {
|
||||
|
@ -1496,6 +1498,7 @@ static const struct spmi_regulator_data pm8941_regulators[] = {
|
|||
{ "s1", 0x1400, "vdd_s1", },
|
||||
{ "s2", 0x1700, "vdd_s2", },
|
||||
{ "s3", 0x1a00, "vdd_s3", },
|
||||
{ "s4", 0xa000, },
|
||||
{ "l1", 0x4000, "vdd_l1_l3", },
|
||||
{ "l2", 0x4100, "vdd_l2_lvs_1_2_3", },
|
||||
{ "l3", 0x4200, "vdd_l1_l3", },
|
||||
|
@ -1523,8 +1526,8 @@ static const struct spmi_regulator_data pm8941_regulators[] = {
|
|||
{ "lvs1", 0x8000, "vdd_l2_lvs_1_2_3", },
|
||||
{ "lvs2", 0x8100, "vdd_l2_lvs_1_2_3", },
|
||||
{ "lvs3", 0x8200, "vdd_l2_lvs_1_2_3", },
|
||||
{ "mvs1", 0x8300, "vin_5vs", },
|
||||
{ "mvs2", 0x8400, "vin_5vs", },
|
||||
{ "5vs1", 0x8300, "vin_5vs", "ocp-5vs1", },
|
||||
{ "5vs2", 0x8400, "vin_5vs", "ocp-5vs2", },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
|
@ -46,6 +46,23 @@ static struct regulator_ops rn5t618_reg_ops = {
|
|||
.vsel_mask = (vmask), \
|
||||
}
|
||||
|
||||
static struct regulator_desc rn5t567_regulators[] = {
|
||||
/* DCDC */
|
||||
REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500),
|
||||
REG(DCDC2, DC2CTL, BIT(0), DC2DAC, 0xff, 600000, 3500000, 12500),
|
||||
REG(DCDC3, DC3CTL, BIT(0), DC3DAC, 0xff, 600000, 3500000, 12500),
|
||||
REG(DCDC4, DC4CTL, BIT(0), DC4DAC, 0xff, 600000, 3500000, 12500),
|
||||
/* LDO */
|
||||
REG(LDO1, LDOEN1, BIT(0), LDO1DAC, 0x7f, 900000, 3500000, 25000),
|
||||
REG(LDO2, LDOEN1, BIT(1), LDO2DAC, 0x7f, 900000, 3500000, 25000),
|
||||
REG(LDO3, LDOEN1, BIT(2), LDO3DAC, 0x7f, 600000, 3500000, 25000),
|
||||
REG(LDO4, LDOEN1, BIT(3), LDO4DAC, 0x7f, 900000, 3500000, 25000),
|
||||
REG(LDO5, LDOEN1, BIT(4), LDO5DAC, 0x7f, 900000, 3500000, 25000),
|
||||
/* LDO RTC */
|
||||
REG(LDORTC1, LDOEN2, BIT(4), LDORTCDAC, 0x7f, 1200000, 3500000, 25000),
|
||||
REG(LDORTC2, LDOEN2, BIT(5), LDORTC2DAC, 0x7f, 900000, 3500000, 25000),
|
||||
};
|
||||
|
||||
static struct regulator_desc rn5t618_regulators[] = {
|
||||
/* DCDC */
|
||||
REG(DCDC1, DC1CTL, BIT(0), DC1DAC, 0xff, 600000, 3500000, 12500),
|
||||
|
@ -67,18 +84,33 @@ static int rn5t618_regulator_probe(struct platform_device *pdev)
|
|||
struct rn5t618 *rn5t618 = dev_get_drvdata(pdev->dev.parent);
|
||||
struct regulator_config config = { };
|
||||
struct regulator_dev *rdev;
|
||||
struct regulator_desc *regulators;
|
||||
int i;
|
||||
|
||||
switch (rn5t618->variant) {
|
||||
case RN5T567:
|
||||
regulators = rn5t567_regulators;
|
||||
break;
|
||||
case RN5T618:
|
||||
regulators = rn5t618_regulators;
|
||||
break;
|
||||
default:
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
config.dev = pdev->dev.parent;
|
||||
config.regmap = rn5t618->regmap;
|
||||
|
||||
for (i = 0; i < RN5T618_REG_NUM; i++) {
|
||||
config.dev = pdev->dev.parent;
|
||||
config.regmap = rn5t618->regmap;
|
||||
if (!regulators[i].name)
|
||||
continue;
|
||||
|
||||
rdev = devm_regulator_register(&pdev->dev,
|
||||
&rn5t618_regulators[i],
|
||||
®ulators[i],
|
||||
&config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "failed to register %s regulator\n",
|
||||
rn5t618_regulators[i].name);
|
||||
regulators[i].name);
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
#include <linux/mfd/tps65217.h>
|
||||
|
||||
#define TPS65217_REGULATOR(_name, _id, _of_match, _ops, _n, _vr, _vm, _em, \
|
||||
_t, _lr, _nlr) \
|
||||
_t, _lr, _nlr, _sr, _sm) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.id = _id, \
|
||||
|
@ -45,6 +45,8 @@
|
|||
.volt_table = _t, \
|
||||
.linear_ranges = _lr, \
|
||||
.n_linear_ranges = _nlr, \
|
||||
.bypass_reg = _sr, \
|
||||
.bypass_mask = _sm, \
|
||||
} \
|
||||
|
||||
static const unsigned int LDO1_VSEL_table[] = {
|
||||
|
@ -118,6 +120,35 @@ static int tps65217_pmic_set_voltage_sel(struct regulator_dev *dev,
|
|||
return ret;
|
||||
}
|
||||
|
||||
static int tps65217_pmic_set_suspend_enable(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps65217 *tps = rdev_get_drvdata(dev);
|
||||
unsigned int rid = rdev_get_id(dev);
|
||||
|
||||
if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4)
|
||||
return -EINVAL;
|
||||
|
||||
return tps65217_clear_bits(tps, dev->desc->bypass_reg,
|
||||
dev->desc->bypass_mask,
|
||||
TPS65217_PROTECT_L1);
|
||||
}
|
||||
|
||||
static int tps65217_pmic_set_suspend_disable(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps65217 *tps = rdev_get_drvdata(dev);
|
||||
unsigned int rid = rdev_get_id(dev);
|
||||
|
||||
if (rid < TPS65217_DCDC_1 || rid > TPS65217_LDO_4)
|
||||
return -EINVAL;
|
||||
|
||||
if (!tps->strobes[rid])
|
||||
return -EINVAL;
|
||||
|
||||
return tps65217_set_bits(tps, dev->desc->bypass_reg,
|
||||
dev->desc->bypass_mask,
|
||||
tps->strobes[rid], TPS65217_PROTECT_L1);
|
||||
}
|
||||
|
||||
/* Operations permitted on DCDCx, LDO2, LDO3 and LDO4 */
|
||||
static struct regulator_ops tps65217_pmic_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
|
@ -127,6 +158,8 @@ static struct regulator_ops tps65217_pmic_ops = {
|
|||
.set_voltage_sel = tps65217_pmic_set_voltage_sel,
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.set_suspend_enable = tps65217_pmic_set_suspend_enable,
|
||||
.set_suspend_disable = tps65217_pmic_set_suspend_disable,
|
||||
};
|
||||
|
||||
/* Operations permitted on LDO1 */
|
||||
|
@ -138,41 +171,50 @@ static struct regulator_ops tps65217_pmic_ldo1_ops = {
|
|||
.set_voltage_sel = tps65217_pmic_set_voltage_sel,
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.map_voltage = regulator_map_voltage_ascend,
|
||||
.set_suspend_enable = tps65217_pmic_set_suspend_enable,
|
||||
.set_suspend_disable = tps65217_pmic_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const struct regulator_desc regulators[] = {
|
||||
TPS65217_REGULATOR("DCDC1", TPS65217_DCDC_1, "dcdc1",
|
||||
tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC1,
|
||||
TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC1_EN,
|
||||
NULL, tps65217_uv1_ranges, 2),
|
||||
NULL, tps65217_uv1_ranges, 2, TPS65217_REG_SEQ1,
|
||||
TPS65217_SEQ1_DC1_SEQ_MASK),
|
||||
TPS65217_REGULATOR("DCDC2", TPS65217_DCDC_2, "dcdc2",
|
||||
tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC2,
|
||||
TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC2_EN,
|
||||
NULL, tps65217_uv1_ranges,
|
||||
ARRAY_SIZE(tps65217_uv1_ranges)),
|
||||
ARRAY_SIZE(tps65217_uv1_ranges), TPS65217_REG_SEQ1,
|
||||
TPS65217_SEQ1_DC2_SEQ_MASK),
|
||||
TPS65217_REGULATOR("DCDC3", TPS65217_DCDC_3, "dcdc3",
|
||||
tps65217_pmic_ops, 64, TPS65217_REG_DEFDCDC3,
|
||||
TPS65217_DEFDCDCX_DCDC_MASK, TPS65217_ENABLE_DC3_EN,
|
||||
NULL, tps65217_uv1_ranges, 1),
|
||||
NULL, tps65217_uv1_ranges, 1, TPS65217_REG_SEQ2,
|
||||
TPS65217_SEQ2_DC3_SEQ_MASK),
|
||||
TPS65217_REGULATOR("LDO1", TPS65217_LDO_1, "ldo1",
|
||||
tps65217_pmic_ldo1_ops, 16, TPS65217_REG_DEFLDO1,
|
||||
TPS65217_DEFLDO1_LDO1_MASK, TPS65217_ENABLE_LDO1_EN,
|
||||
LDO1_VSEL_table, NULL, 0),
|
||||
LDO1_VSEL_table, NULL, 0, TPS65217_REG_SEQ2,
|
||||
TPS65217_SEQ2_LDO1_SEQ_MASK),
|
||||
TPS65217_REGULATOR("LDO2", TPS65217_LDO_2, "ldo2", tps65217_pmic_ops,
|
||||
64, TPS65217_REG_DEFLDO2,
|
||||
TPS65217_DEFLDO2_LDO2_MASK, TPS65217_ENABLE_LDO2_EN,
|
||||
NULL, tps65217_uv1_ranges,
|
||||
ARRAY_SIZE(tps65217_uv1_ranges)),
|
||||
ARRAY_SIZE(tps65217_uv1_ranges), TPS65217_REG_SEQ3,
|
||||
TPS65217_SEQ3_LDO2_SEQ_MASK),
|
||||
TPS65217_REGULATOR("LDO3", TPS65217_LDO_3, "ldo3", tps65217_pmic_ops,
|
||||
32, TPS65217_REG_DEFLS1, TPS65217_DEFLDO3_LDO3_MASK,
|
||||
TPS65217_ENABLE_LS1_EN | TPS65217_DEFLDO3_LDO3_EN,
|
||||
NULL, tps65217_uv2_ranges,
|
||||
ARRAY_SIZE(tps65217_uv2_ranges)),
|
||||
ARRAY_SIZE(tps65217_uv2_ranges), TPS65217_REG_SEQ3,
|
||||
TPS65217_SEQ3_LDO3_SEQ_MASK),
|
||||
TPS65217_REGULATOR("LDO4", TPS65217_LDO_4, "ldo4", tps65217_pmic_ops,
|
||||
32, TPS65217_REG_DEFLS2, TPS65217_DEFLDO4_LDO4_MASK,
|
||||
TPS65217_ENABLE_LS2_EN | TPS65217_DEFLDO4_LDO4_EN,
|
||||
NULL, tps65217_uv2_ranges,
|
||||
ARRAY_SIZE(tps65217_uv2_ranges)),
|
||||
ARRAY_SIZE(tps65217_uv2_ranges), TPS65217_REG_SEQ4,
|
||||
TPS65217_SEQ4_LDO4_SEQ_MASK),
|
||||
};
|
||||
|
||||
static int tps65217_regulator_probe(struct platform_device *pdev)
|
||||
|
@ -181,13 +223,18 @@ static int tps65217_regulator_probe(struct platform_device *pdev)
|
|||
struct tps65217_board *pdata = dev_get_platdata(tps->dev);
|
||||
struct regulator_dev *rdev;
|
||||
struct regulator_config config = { };
|
||||
int i;
|
||||
int i, ret;
|
||||
unsigned int val;
|
||||
|
||||
if (tps65217_chip_id(tps) != TPS65217) {
|
||||
dev_err(&pdev->dev, "Invalid tps chip version\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* Allocate memory for strobes */
|
||||
tps->strobes = devm_kzalloc(&pdev->dev, sizeof(u8) *
|
||||
TPS65217_NUM_REGULATOR, GFP_KERNEL);
|
||||
|
||||
platform_set_drvdata(pdev, tps);
|
||||
|
||||
for (i = 0; i < TPS65217_NUM_REGULATOR; i++) {
|
||||
|
@ -205,6 +252,10 @@ static int tps65217_regulator_probe(struct platform_device *pdev)
|
|||
pdev->name);
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
|
||||
/* Store default strobe info */
|
||||
ret = tps65217_reg_read(tps, regulators[i].bypass_reg, &val);
|
||||
tps->strobes[i] = val & regulators[i].bypass_mask;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -31,7 +31,7 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4,
|
|||
DCDC5, DCDC6, LDO1, LS3 };
|
||||
|
||||
#define TPS65218_REGULATOR(_name, _id, _type, _ops, _n, _vr, _vm, _er, _em, \
|
||||
_cr, _cm, _lr, _nlr, _delay, _fuv) \
|
||||
_cr, _cm, _lr, _nlr, _delay, _fuv, _sr, _sm) \
|
||||
{ \
|
||||
.name = _name, \
|
||||
.id = _id, \
|
||||
|
@ -49,7 +49,9 @@ enum tps65218_regulators { DCDC1, DCDC2, DCDC3, DCDC4,
|
|||
.linear_ranges = _lr, \
|
||||
.n_linear_ranges = _nlr, \
|
||||
.ramp_delay = _delay, \
|
||||
.fixed_uV = _fuv \
|
||||
.fixed_uV = _fuv, \
|
||||
.bypass_reg = _sr, \
|
||||
.bypass_mask = _sm, \
|
||||
} \
|
||||
|
||||
#define TPS65218_INFO(_id, _nm, _min, _max) \
|
||||
|
@ -157,6 +159,40 @@ static int tps65218_pmic_disable(struct regulator_dev *dev)
|
|||
dev->desc->enable_mask, TPS65218_PROTECT_L1);
|
||||
}
|
||||
|
||||
static int tps65218_pmic_set_suspend_enable(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps65218 *tps = rdev_get_drvdata(dev);
|
||||
unsigned int rid = rdev_get_id(dev);
|
||||
|
||||
if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1)
|
||||
return -EINVAL;
|
||||
|
||||
return tps65218_clear_bits(tps, dev->desc->bypass_reg,
|
||||
dev->desc->bypass_mask,
|
||||
TPS65218_PROTECT_L1);
|
||||
}
|
||||
|
||||
static int tps65218_pmic_set_suspend_disable(struct regulator_dev *dev)
|
||||
{
|
||||
struct tps65218 *tps = rdev_get_drvdata(dev);
|
||||
unsigned int rid = rdev_get_id(dev);
|
||||
|
||||
if (rid < TPS65218_DCDC_1 || rid > TPS65218_LDO_1)
|
||||
return -EINVAL;
|
||||
|
||||
if (!tps->info[rid]->strobe) {
|
||||
if (rid == TPS65218_DCDC_3)
|
||||
tps->info[rid]->strobe = 3;
|
||||
else
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return tps65218_set_bits(tps, dev->desc->bypass_reg,
|
||||
dev->desc->bypass_mask,
|
||||
tps->info[rid]->strobe,
|
||||
TPS65218_PROTECT_L1);
|
||||
}
|
||||
|
||||
/* Operations permitted on DCDC1, DCDC2 */
|
||||
static struct regulator_ops tps65218_dcdc12_ops = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
|
@ -167,6 +203,8 @@ static struct regulator_ops tps65218_dcdc12_ops = {
|
|||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.set_voltage_time_sel = regulator_set_voltage_time_sel,
|
||||
.set_suspend_enable = tps65218_pmic_set_suspend_enable,
|
||||
.set_suspend_disable = tps65218_pmic_set_suspend_disable,
|
||||
};
|
||||
|
||||
/* Operations permitted on DCDC3, DCDC4 and LDO1 */
|
||||
|
@ -178,6 +216,8 @@ static struct regulator_ops tps65218_ldo1_dcdc34_ops = {
|
|||
.set_voltage_sel = tps65218_pmic_set_voltage_sel,
|
||||
.list_voltage = regulator_list_voltage_linear_range,
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
.set_suspend_enable = tps65218_pmic_set_suspend_enable,
|
||||
.set_suspend_disable = tps65218_pmic_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const int ls3_currents[] = { 100, 200, 500, 1000 };
|
||||
|
@ -247,6 +287,8 @@ static struct regulator_ops tps65218_dcdc56_pmic_ops = {
|
|||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = tps65218_pmic_enable,
|
||||
.disable = tps65218_pmic_disable,
|
||||
.set_suspend_enable = tps65218_pmic_set_suspend_enable,
|
||||
.set_suspend_disable = tps65218_pmic_set_suspend_disable,
|
||||
};
|
||||
|
||||
static const struct regulator_desc regulators[] = {
|
||||
|
@ -254,42 +296,47 @@ static const struct regulator_desc regulators[] = {
|
|||
tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC1,
|
||||
TPS65218_CONTROL_DCDC1_MASK, TPS65218_REG_ENABLE1,
|
||||
TPS65218_ENABLE1_DC1_EN, 0, 0, dcdc1_dcdc2_ranges,
|
||||
2, 4000, 0),
|
||||
2, 4000, 0, TPS65218_REG_SEQ3,
|
||||
TPS65218_SEQ3_DC1_SEQ_MASK),
|
||||
TPS65218_REGULATOR("DCDC2", TPS65218_DCDC_2, REGULATOR_VOLTAGE,
|
||||
tps65218_dcdc12_ops, 64, TPS65218_REG_CONTROL_DCDC2,
|
||||
TPS65218_CONTROL_DCDC2_MASK, TPS65218_REG_ENABLE1,
|
||||
TPS65218_ENABLE1_DC2_EN, 0, 0, dcdc1_dcdc2_ranges,
|
||||
2, 4000, 0),
|
||||
2, 4000, 0, TPS65218_REG_SEQ3,
|
||||
TPS65218_SEQ3_DC2_SEQ_MASK),
|
||||
TPS65218_REGULATOR("DCDC3", TPS65218_DCDC_3, REGULATOR_VOLTAGE,
|
||||
tps65218_ldo1_dcdc34_ops, 64,
|
||||
TPS65218_REG_CONTROL_DCDC3,
|
||||
TPS65218_CONTROL_DCDC3_MASK, TPS65218_REG_ENABLE1,
|
||||
TPS65218_ENABLE1_DC3_EN, 0, 0, ldo1_dcdc3_ranges, 2,
|
||||
0, 0),
|
||||
0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC3_SEQ_MASK),
|
||||
TPS65218_REGULATOR("DCDC4", TPS65218_DCDC_4, REGULATOR_VOLTAGE,
|
||||
tps65218_ldo1_dcdc34_ops, 53,
|
||||
TPS65218_REG_CONTROL_DCDC4,
|
||||
TPS65218_CONTROL_DCDC4_MASK, TPS65218_REG_ENABLE1,
|
||||
TPS65218_ENABLE1_DC4_EN, 0, 0, dcdc4_ranges, 2,
|
||||
0, 0),
|
||||
0, 0, TPS65218_REG_SEQ4, TPS65218_SEQ4_DC4_SEQ_MASK),
|
||||
TPS65218_REGULATOR("DCDC5", TPS65218_DCDC_5, REGULATOR_VOLTAGE,
|
||||
tps65218_dcdc56_pmic_ops, 1, -1, -1,
|
||||
TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC5_EN, 0, 0,
|
||||
NULL, 0, 0, 1000000),
|
||||
NULL, 0, 0, 1000000, TPS65218_REG_SEQ5,
|
||||
TPS65218_SEQ5_DC5_SEQ_MASK),
|
||||
TPS65218_REGULATOR("DCDC6", TPS65218_DCDC_6, REGULATOR_VOLTAGE,
|
||||
tps65218_dcdc56_pmic_ops, 1, -1, -1,
|
||||
TPS65218_REG_ENABLE1, TPS65218_ENABLE1_DC6_EN, 0, 0,
|
||||
NULL, 0, 0, 1800000),
|
||||
NULL, 0, 0, 1800000, TPS65218_REG_SEQ5,
|
||||
TPS65218_SEQ5_DC6_SEQ_MASK),
|
||||
TPS65218_REGULATOR("LDO1", TPS65218_LDO_1, REGULATOR_VOLTAGE,
|
||||
tps65218_ldo1_dcdc34_ops, 64,
|
||||
TPS65218_REG_CONTROL_LDO1,
|
||||
TPS65218_CONTROL_LDO1_MASK, TPS65218_REG_ENABLE2,
|
||||
TPS65218_ENABLE2_LDO1_EN, 0, 0, ldo1_dcdc3_ranges,
|
||||
2, 0, 0),
|
||||
2, 0, 0, TPS65218_REG_SEQ6,
|
||||
TPS65218_SEQ6_LDO1_SEQ_MASK),
|
||||
TPS65218_REGULATOR("LS3", TPS65218_LS_3, REGULATOR_CURRENT,
|
||||
tps65218_ls3_ops, 0, 0, 0, TPS65218_REG_ENABLE2,
|
||||
TPS65218_ENABLE2_LS3_EN, TPS65218_REG_CONFIG2,
|
||||
TPS65218_CONFIG2_LS3ILIM_MASK, NULL, 0, 0, 0),
|
||||
TPS65218_CONFIG2_LS3ILIM_MASK, NULL, 0, 0, 0, 0, 0),
|
||||
};
|
||||
|
||||
static int tps65218_regulator_probe(struct platform_device *pdev)
|
||||
|
@ -300,7 +347,8 @@ static int tps65218_regulator_probe(struct platform_device *pdev)
|
|||
struct regulator_dev *rdev;
|
||||
const struct of_device_id *match;
|
||||
struct regulator_config config = { };
|
||||
int id;
|
||||
int id, ret;
|
||||
unsigned int val;
|
||||
|
||||
match = of_match_device(tps65218_of_match, &pdev->dev);
|
||||
if (!match)
|
||||
|
@ -327,6 +375,12 @@ static int tps65218_regulator_probe(struct platform_device *pdev)
|
|||
return PTR_ERR(rdev);
|
||||
}
|
||||
|
||||
ret = tps65218_reg_read(tps, regulators[id].bypass_reg, &val);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
tps->info[id]->strobe = val & regulators[id].bypass_mask;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -905,7 +905,7 @@ static struct regulator_ops twlsmps_ops = {
|
|||
twl4030reg_map_mode)
|
||||
#define TWL6030_FIXED_LDO(label, offset, mVolts, turnon_delay) \
|
||||
TWL_FIXED_LDO(label, offset, mVolts, 0x0, turnon_delay, \
|
||||
0x0, TWL6030, twl6030fixed_ops, 0x0)
|
||||
0x0, TWL6030, twl6030fixed_ops, NULL)
|
||||
|
||||
#define TWL4030_ADJUSTABLE_LDO(label, offset, num, turnon_delay, remap_conf) \
|
||||
static const struct twlreg_info TWL4030_INFO_##label = { \
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
#define RN5T618_OTPVER 0x01
|
||||
#define RN5T618_IODAC 0x02
|
||||
#define RN5T618_VINDAC 0x03
|
||||
#define RN5T618_OUT32KEN 0x05
|
||||
#define RN5T618_CPUCNT 0x06
|
||||
#define RN5T618_PSWR 0x07
|
||||
#define RN5T618_PONHIS 0x09
|
||||
|
@ -38,6 +39,7 @@
|
|||
#define RN5T618_DC1_SLOT 0x16
|
||||
#define RN5T618_DC2_SLOT 0x17
|
||||
#define RN5T618_DC3_SLOT 0x18
|
||||
#define RN5T618_DC4_SLOT 0x19
|
||||
#define RN5T618_LDO1_SLOT 0x1b
|
||||
#define RN5T618_LDO2_SLOT 0x1c
|
||||
#define RN5T618_LDO3_SLOT 0x1d
|
||||
|
@ -54,12 +56,16 @@
|
|||
#define RN5T618_DC2CTL2 0x2f
|
||||
#define RN5T618_DC3CTL 0x30
|
||||
#define RN5T618_DC3CTL2 0x31
|
||||
#define RN5T618_DC4CTL 0x32
|
||||
#define RN5T618_DC4CTL2 0x33
|
||||
#define RN5T618_DC1DAC 0x36
|
||||
#define RN5T618_DC2DAC 0x37
|
||||
#define RN5T618_DC3DAC 0x38
|
||||
#define RN5T618_DC4DAC 0x39
|
||||
#define RN5T618_DC1DAC_SLP 0x3b
|
||||
#define RN5T618_DC2DAC_SLP 0x3c
|
||||
#define RN5T618_DC3DAC_SLP 0x3d
|
||||
#define RN5T618_DC4DAC_SLP 0x3e
|
||||
#define RN5T618_DCIREN 0x40
|
||||
#define RN5T618_DCIRQ 0x41
|
||||
#define RN5T618_DCIRMON 0x42
|
||||
|
@ -211,6 +217,7 @@ enum {
|
|||
RN5T618_DCDC1,
|
||||
RN5T618_DCDC2,
|
||||
RN5T618_DCDC3,
|
||||
RN5T618_DCDC4,
|
||||
RN5T618_LDO1,
|
||||
RN5T618_LDO2,
|
||||
RN5T618_LDO3,
|
||||
|
@ -221,8 +228,14 @@ enum {
|
|||
RN5T618_REG_NUM,
|
||||
};
|
||||
|
||||
enum {
|
||||
RN5T567 = 0,
|
||||
RN5T618,
|
||||
};
|
||||
|
||||
struct rn5t618 {
|
||||
struct regmap *regmap;
|
||||
long variant;
|
||||
};
|
||||
|
||||
#endif /* __LINUX_MFD_RN5T618_H */
|
||||
|
|
|
@ -257,6 +257,7 @@ struct tps65217 {
|
|||
unsigned long id;
|
||||
struct regulator_desc desc[TPS65217_NUM_REGULATOR];
|
||||
struct regmap *regmap;
|
||||
u8 *strobes;
|
||||
};
|
||||
|
||||
static inline struct tps65217 *dev_to_tps65217(struct device *dev)
|
||||
|
|
|
@ -246,6 +246,7 @@ enum tps65218_irqs {
|
|||
* @name: Voltage regulator name
|
||||
* @min_uV: minimum micro volts
|
||||
* @max_uV: minimum micro volts
|
||||
* @strobe: sequencing strobe value for the regulator
|
||||
*
|
||||
* This data is used to check the regualtor voltage limits while setting.
|
||||
*/
|
||||
|
@ -254,6 +255,7 @@ struct tps_info {
|
|||
const char *name;
|
||||
int min_uV;
|
||||
int max_uV;
|
||||
int strobe;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
Загрузка…
Ссылка в новой задаче