mirror of
https://github.com/torvalds/linux.git
synced 2024-11-29 23:51:37 +00:00
regulator: bcm590xx: Add support for regulators on secondary I2C slave
The bcm590xx MFD driver now exposes a secondary regmap descriptor making the registers for regulators on the secondary I2C slave address available. Add support for GPLDO1-6 and VBUS regulators found within this register range. Signed-off-by: Matt Porter <mporter@linaro.org> Acked-by: Mark Brown <broonie@linaro.org> Signed-off-by: Lee Jones <lee.jones@linaro.org>
This commit is contained in:
parent
9e1e726311
commit
c6466950e9
@ -22,7 +22,7 @@
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
/* Register defs */
|
||||
/* I2C slave 0 registers */
|
||||
#define BCM590XX_RFLDOPMCTRL1 0x60
|
||||
#define BCM590XX_IOSR1PMCTRL1 0x7a
|
||||
#define BCM590XX_IOSR2PMCTRL1 0x7c
|
||||
@ -31,13 +31,34 @@
|
||||
#define BCM590XX_SDSR2PMCTRL1 0x86
|
||||
#define BCM590XX_MSRPMCTRL1 0x8a
|
||||
#define BCM590XX_VSRPMCTRL1 0x8e
|
||||
#define BCM590XX_REG_ENABLE BIT(7)
|
||||
|
||||
#define BCM590XX_RFLDOCTRL 0x96
|
||||
#define BCM590XX_CSRVOUT1 0xc0
|
||||
|
||||
/* I2C slave 1 registers */
|
||||
#define BCM590XX_GPLDO5PMCTRL1 0x16
|
||||
#define BCM590XX_GPLDO6PMCTRL1 0x18
|
||||
#define BCM590XX_GPLDO1CTRL 0x1a
|
||||
#define BCM590XX_GPLDO2CTRL 0x1b
|
||||
#define BCM590XX_GPLDO3CTRL 0x1c
|
||||
#define BCM590XX_GPLDO4CTRL 0x1d
|
||||
#define BCM590XX_GPLDO5CTRL 0x1e
|
||||
#define BCM590XX_GPLDO6CTRL 0x1f
|
||||
#define BCM590XX_OTG_CTRL 0x40
|
||||
#define BCM590XX_GPLDO1PMCTRL1 0x57
|
||||
#define BCM590XX_GPLDO2PMCTRL1 0x59
|
||||
#define BCM590XX_GPLDO3PMCTRL1 0x5b
|
||||
#define BCM590XX_GPLDO4PMCTRL1 0x5d
|
||||
|
||||
#define BCM590XX_REG_ENABLE BIT(7)
|
||||
#define BCM590XX_VBUS_ENABLE BIT(2)
|
||||
#define BCM590XX_LDO_VSEL_MASK GENMASK(5, 3)
|
||||
#define BCM590XX_SR_VSEL_MASK GENMASK(5, 0)
|
||||
|
||||
/*
|
||||
* RFLDO to VSR regulators are
|
||||
* accessed via I2C slave 0
|
||||
*/
|
||||
|
||||
/* LDO regulator IDs */
|
||||
#define BCM590XX_REG_RFLDO 0
|
||||
#define BCM590XX_REG_CAMLDO1 1
|
||||
@ -62,9 +83,25 @@
|
||||
#define BCM590XX_REG_SDSR2 18
|
||||
#define BCM590XX_REG_VSR 19
|
||||
|
||||
#define BCM590XX_NUM_REGS 20
|
||||
/*
|
||||
* GPLDO1 to VBUS regulators are
|
||||
* accessed via I2C slave 1
|
||||
*/
|
||||
|
||||
#define BCM590XX_REG_GPLDO1 20
|
||||
#define BCM590XX_REG_GPLDO2 21
|
||||
#define BCM590XX_REG_GPLDO3 22
|
||||
#define BCM590XX_REG_GPLDO4 23
|
||||
#define BCM590XX_REG_GPLDO5 24
|
||||
#define BCM590XX_REG_GPLDO6 25
|
||||
#define BCM590XX_REG_VBUS 26
|
||||
|
||||
#define BCM590XX_NUM_REGS 27
|
||||
|
||||
#define BCM590XX_REG_IS_LDO(n) (n < BCM590XX_REG_CSR)
|
||||
#define BCM590XX_REG_IS_GPLDO(n) \
|
||||
((n > BCM590XX_REG_VSR) && (n < BCM590XX_REG_VBUS))
|
||||
#define BCM590XX_REG_IS_VBUS(n) (n == BCM590XX_REG_VBUS)
|
||||
|
||||
struct bcm590xx_board {
|
||||
struct regulator_init_data *bcm590xx_pmu_init_data[BCM590XX_NUM_REGS];
|
||||
@ -149,6 +186,12 @@ static struct bcm590xx_info bcm590xx_regs[] = {
|
||||
BCM590XX_REG_RANGES(sdsr1, dcdc_sdsr1_ranges),
|
||||
BCM590XX_REG_RANGES(sdsr2, dcdc_iosr1_ranges),
|
||||
BCM590XX_REG_RANGES(vsr, dcdc_iosr1_ranges),
|
||||
BCM590XX_REG_TABLE(gpldo1, ldo_a_table),
|
||||
BCM590XX_REG_TABLE(gpldo2, ldo_a_table),
|
||||
BCM590XX_REG_TABLE(gpldo3, ldo_a_table),
|
||||
BCM590XX_REG_TABLE(gpldo4, ldo_a_table),
|
||||
BCM590XX_REG_TABLE(gpldo5, ldo_a_table),
|
||||
BCM590XX_REG_TABLE(gpldo6, ldo_a_table),
|
||||
};
|
||||
|
||||
struct bcm590xx_reg {
|
||||
@ -161,6 +204,8 @@ static int bcm590xx_get_vsel_register(int id)
|
||||
{
|
||||
if (BCM590XX_REG_IS_LDO(id))
|
||||
return BCM590XX_RFLDOCTRL + id;
|
||||
else if (BCM590XX_REG_IS_GPLDO(id))
|
||||
return BCM590XX_GPLDO1CTRL + id;
|
||||
else
|
||||
return BCM590XX_CSRVOUT1 + (id - BCM590XX_REG_CSR) * 3;
|
||||
}
|
||||
@ -171,6 +216,8 @@ static int bcm590xx_get_enable_register(int id)
|
||||
|
||||
if (BCM590XX_REG_IS_LDO(id))
|
||||
reg = BCM590XX_RFLDOPMCTRL1 + id * 2;
|
||||
else if (BCM590XX_REG_IS_GPLDO(id))
|
||||
reg = BCM590XX_GPLDO1PMCTRL1 + id * 2;
|
||||
else
|
||||
switch (id) {
|
||||
case BCM590XX_REG_CSR:
|
||||
@ -191,8 +238,11 @@ static int bcm590xx_get_enable_register(int id)
|
||||
case BCM590XX_REG_SDSR2:
|
||||
reg = BCM590XX_SDSR2PMCTRL1;
|
||||
break;
|
||||
case BCM590XX_REG_VBUS:
|
||||
reg = BCM590XX_OTG_CTRL;
|
||||
};
|
||||
|
||||
|
||||
return reg;
|
||||
}
|
||||
|
||||
@ -216,6 +266,12 @@ static struct regulator_ops bcm590xx_ops_dcdc = {
|
||||
.map_voltage = regulator_map_voltage_linear_range,
|
||||
};
|
||||
|
||||
static struct regulator_ops bcm590xx_ops_vbus = {
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
};
|
||||
|
||||
#define BCM590XX_MATCH(_name, _id) \
|
||||
{ \
|
||||
.name = #_name, \
|
||||
@ -243,6 +299,13 @@ static struct of_regulator_match bcm590xx_matches[] = {
|
||||
BCM590XX_MATCH(sdsr1, SDSR1),
|
||||
BCM590XX_MATCH(sdsr2, SDSR2),
|
||||
BCM590XX_MATCH(vsr, VSR),
|
||||
BCM590XX_MATCH(gpldo1, GPLDO1),
|
||||
BCM590XX_MATCH(gpldo2, GPLDO2),
|
||||
BCM590XX_MATCH(gpldo3, GPLDO3),
|
||||
BCM590XX_MATCH(gpldo4, GPLDO4),
|
||||
BCM590XX_MATCH(gpldo5, GPLDO5),
|
||||
BCM590XX_MATCH(gpldo6, GPLDO6),
|
||||
BCM590XX_MATCH(vbus, VBUS),
|
||||
};
|
||||
|
||||
static struct bcm590xx_board *bcm590xx_parse_dt_reg_data(
|
||||
@ -353,17 +416,23 @@ static int bcm590xx_probe(struct platform_device *pdev)
|
||||
pmu->desc[i].linear_ranges = info->linear_ranges;
|
||||
pmu->desc[i].n_linear_ranges = info->n_linear_ranges;
|
||||
|
||||
if (BCM590XX_REG_IS_LDO(i)) {
|
||||
if ((BCM590XX_REG_IS_LDO(i)) || (BCM590XX_REG_IS_GPLDO(i))) {
|
||||
pmu->desc[i].ops = &bcm590xx_ops_ldo;
|
||||
pmu->desc[i].vsel_mask = BCM590XX_LDO_VSEL_MASK;
|
||||
} else {
|
||||
} else if (BCM590XX_REG_IS_VBUS(i))
|
||||
pmu->desc[i].ops = &bcm590xx_ops_vbus;
|
||||
else {
|
||||
pmu->desc[i].ops = &bcm590xx_ops_dcdc;
|
||||
pmu->desc[i].vsel_mask = BCM590XX_SR_VSEL_MASK;
|
||||
}
|
||||
|
||||
if (BCM590XX_REG_IS_VBUS(i))
|
||||
pmu->desc[i].enable_mask = BCM590XX_VBUS_ENABLE;
|
||||
else {
|
||||
pmu->desc[i].vsel_reg = bcm590xx_get_vsel_register(i);
|
||||
pmu->desc[i].enable_is_inverted = true;
|
||||
pmu->desc[i].enable_mask = BCM590XX_REG_ENABLE;
|
||||
}
|
||||
pmu->desc[i].enable_reg = bcm590xx_get_enable_register(i);
|
||||
pmu->desc[i].type = REGULATOR_VOLTAGE;
|
||||
pmu->desc[i].owner = THIS_MODULE;
|
||||
@ -371,7 +440,10 @@ static int bcm590xx_probe(struct platform_device *pdev)
|
||||
config.dev = bcm590xx->dev;
|
||||
config.init_data = reg_data;
|
||||
config.driver_data = pmu;
|
||||
config.regmap = bcm590xx->regmap;
|
||||
if (BCM590XX_REG_IS_GPLDO(i) || BCM590XX_REG_IS_VBUS(i))
|
||||
config.regmap = bcm590xx->regmap_sec;
|
||||
else
|
||||
config.regmap = bcm590xx->regmap_pri;
|
||||
|
||||
if (bcm590xx_reg_matches)
|
||||
config.of_node = bcm590xx_reg_matches[i].of_node;
|
||||
|
Loading…
Reference in New Issue
Block a user