You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge tag 'regulator-v3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator into next
Pull regulator updates from Mark Brown:
"The bulk of the changes for this release are a few new drivers however
there are a couple of noticable core changes and the usual stream of
cleanups and fixes:
- move disable of unused regulators later in init so it comes after
deferred probe has iterated making startup smoother.
- fixes to reference counting of the DT nodes for constraints from
Charles Keepax. This has little practical impact since all real
users of the regulator bindings use FDT which doesn't need the
reference counting.
- lots of cleanups, especially to the Samsung drivers.
- support for Linear Technologies LTC3589, Texas Instruments
TPS658640 and X-Powers AXP20x"
* tag 'regulator-v3.16' of git://git.kernel.org/pub/scm/linux/kernel/git/broonie/regulator: (64 commits)
regulator: pbias: remove unnecessary OOM messages
regulator: max8649: remove unnecessary OOM messages
regulator: core: Fix the init of DT defined fixed regulators
regulator: core: Disable unused regulators after deferred probing is done
regulator: Don't disable unused regulators we don't have permission for
regulator: axp20x: Use regulator_map_voltage_ascend for LDO4
regulator: use of_property_read_{bool|u32}()
regulator: Fix regulator_get_{optional,exclusive}() documentation
regulators: Add definition of regulator_set_voltage_time() for !CONFIG_REGULATOR
regulator: arizona-ldo1: add missing #include
regulator: pfuze100: Support enable/disable for fixed regulator
regulator: ltc3589: Remove ltc3589_list_voltage_fixed function
regulator: ltc3589: Fix module dependency
regulator: tps6586x: Remove unused to_tps6586x_dev() function
regulator: tps65218: Convert to use regulator_set_voltage_time_sel
regulator: tps6586x: Add support for the TPS658640
regulator: tps6586x: Prepare supporting fixed regulators
regulator: pfuze100: Don't allocate an invalid gpio
regulator: pfuze100: Support SWB enable/disable
regulator: fixed: use of_property_read_{bool|u32}()
...
This commit is contained in:
@@ -19,7 +19,9 @@ Optional child nodes:
|
||||
The valid regulator node names for BCM59056 are:
|
||||
rfldo, camldo1, camldo2, simldo1, simldo2, sdldo, sdxldo,
|
||||
mmcldo1, mmcldo2, audldo, micldo, usbldo, vibldo,
|
||||
csr, iosr1, iosr2, msr, sdsr1, sdsr2, vsr
|
||||
csr, iosr1, iosr2, msr, sdsr1, sdsr2, vsr,
|
||||
gpldo1, gpldo2, gpldo3, gpldo4, gpldo5, gpldo6,
|
||||
vbus
|
||||
|
||||
Example:
|
||||
pmu: bcm59056@8 {
|
||||
|
||||
@@ -56,6 +56,20 @@ for a particular group of BUCKs. So provide same regulator-ramp-delay<value>.
|
||||
Grouping of BUCKs sharing ramp rate setting is as follow : BUCK[1, 6],
|
||||
BUCK[3, 4], and BUCK[7, 8, 10]
|
||||
|
||||
On S2MPS14 the LDO10, LDO11 and LDO12 can be configured to external control
|
||||
over GPIO. To turn this feature on this property must be added to the regulator
|
||||
sub-node:
|
||||
- samsung,ext-control-gpios: GPIO specifier for one GPIO
|
||||
controlling this regulator (enable/disable);
|
||||
Example:
|
||||
LDO12 {
|
||||
regulator-name = "V_EMMC_2.8V";
|
||||
regulator-min-microvolt = <2800000>;
|
||||
regulator-max-microvolt = <2800000>;
|
||||
samsung,ext-control-gpios = <&gpk0 2 0>;
|
||||
};
|
||||
|
||||
|
||||
The regulator constraints inside the regulator nodes use the standard regulator
|
||||
bindings which are documented elsewhere.
|
||||
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
Linear Technology LTC3589, LTC3589-1, and LTC3589-2 8-output regulators
|
||||
|
||||
Required properties:
|
||||
- compatible: "lltc,ltc3589", "lltc,ltc3589-1" or "lltc,ltc3589-2"
|
||||
- reg: I2C slave address
|
||||
|
||||
Required child node:
|
||||
- regulators: Contains eight regulator child nodes sw1, sw2, sw3, bb-out,
|
||||
ldo1, ldo2, ldo3, and ldo4, specifying the initialization data as
|
||||
documented in Documentation/devicetree/bindings/regulator/regulator.txt.
|
||||
|
||||
Each regulator is defined using the standard binding for regulators. The
|
||||
nodes for sw1, sw2, sw3, bb-out, ldo1, and ldo2 additionally need to specify
|
||||
the resistor values of their external feedback voltage dividers:
|
||||
|
||||
Required properties (not on ldo3, ldo4):
|
||||
- lltc,fb-voltage-divider: An array of two integers containing the resistor
|
||||
values R1 and R2 of the feedback voltage divider in ohms.
|
||||
|
||||
Regulators sw1, sw2, sw3, and ldo2 can regulate the feedback reference from
|
||||
0.3625 V to 0.75 V in 12.5 mV steps. The output voltage thus ranges between
|
||||
0.3625 * (1 + R1/R2) V and 0.75 * (1 + R1/R2) V. Regulators bb-out and ldo1
|
||||
have a fixed 0.8 V reference and thus output 0.8 * (1 + R1/R2) V. The ldo3
|
||||
regulator is fixed to 1.8 V on LTC3589 and to 2.8 V on LTC3589-1,2. The ldo4
|
||||
regulator can output between 1.8 V and 3.3 V on LTC3589 and between 1.2 V
|
||||
and 3.2 V on LTC3589-1,2 in four steps. The ldo1 standby regulator can not
|
||||
be disabled and thus should have the regulator-always-on property set.
|
||||
|
||||
Example:
|
||||
|
||||
ltc3589: pmic@34 {
|
||||
compatible = "lltc,ltc3589-1";
|
||||
reg = <0x34>;
|
||||
|
||||
regulators {
|
||||
sw1_reg: sw1 {
|
||||
regulator-min-microvolt = <591930>;
|
||||
regulator-max-microvolt = <1224671>;
|
||||
lltc,fb-voltage-divider = <100000 158000>;
|
||||
regulator-ramp-delay = <7000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
sw2_reg: sw2 {
|
||||
regulator-min-microvolt = <704123>;
|
||||
regulator-max-microvolt = <1456803>;
|
||||
lltc,fb-voltage-divider = <180000 191000>;
|
||||
regulator-ramp-delay = <7000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
sw3_reg: sw3 {
|
||||
regulator-min-microvolt = <1341250>;
|
||||
regulator-max-microvolt = <2775000>;
|
||||
lltc,fb-voltage-divider = <270000 100000>;
|
||||
regulator-ramp-delay = <7000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
bb_out_reg: bb-out {
|
||||
regulator-min-microvolt = <3387341>;
|
||||
regulator-max-microvolt = <3387341>;
|
||||
lltc,fb-voltage-divider = <511000 158000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo1_reg: ldo1 {
|
||||
regulator-min-microvolt = <1306329>;
|
||||
regulator-max-microvolt = <1306329>;
|
||||
lltc,fb-voltage-divider = <100000 158000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo2_reg: ldo2 {
|
||||
regulator-min-microvolt = <704123>;
|
||||
regulator-max-microvolt = <1456806>;
|
||||
lltc,fb-voltage-divider = <180000 191000>;
|
||||
regulator-ramp-delay = <7000>;
|
||||
regulator-boot-on;
|
||||
regulator-always-on;
|
||||
};
|
||||
|
||||
ldo3_reg: ldo3 {
|
||||
regulator-min-microvolt = <2800000>;
|
||||
regulator-max-microvolt = <2800000>;
|
||||
regulator-boot-on;
|
||||
};
|
||||
|
||||
ldo4_reg: ldo4 {
|
||||
regulator-min-microvolt = <1200000>;
|
||||
regulator-max-microvolt = <3200000>;
|
||||
};
|
||||
};
|
||||
};
|
||||
@@ -21,6 +21,10 @@ Optional properties:
|
||||
number should be provided. If it is externally controlled and no GPIO
|
||||
entry then driver will just configure this rails as external control
|
||||
and will not provide any enable/disable APIs.
|
||||
- ti,overcurrent-wait: This is applicable to FET registers, which have a
|
||||
poorly defined "overcurrent wait" field. If this property is present it
|
||||
should be between 0 - 3. If this property isn't present we won't touch the
|
||||
"overcurrent wait" field and we'll leave it to the BIOS/EC to deal with.
|
||||
|
||||
Each regulator is defined using the standard binding for regulators.
|
||||
|
||||
|
||||
@@ -74,6 +74,7 @@ lantiq Lantiq Semiconductor
|
||||
lg LG Corporation
|
||||
linux Linux-specific binding
|
||||
lsi LSI Corp. (LSI Logic)
|
||||
lltc Linear Technology Corporation
|
||||
marvell Marvell Technology Group Ltd.
|
||||
maxim Maxim Integrated Products
|
||||
microchip Microchip Technology Inc.
|
||||
|
||||
+24
-17
@@ -508,19 +508,31 @@ int arizona_of_get_type(struct device *dev)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(arizona_of_get_type);
|
||||
|
||||
int arizona_of_get_named_gpio(struct arizona *arizona, const char *prop,
|
||||
bool mandatory)
|
||||
{
|
||||
int gpio;
|
||||
|
||||
gpio = of_get_named_gpio(arizona->dev->of_node, prop, 0);
|
||||
if (gpio < 0) {
|
||||
if (mandatory)
|
||||
dev_err(arizona->dev,
|
||||
"Mandatory DT gpio %s missing/malformed: %d\n",
|
||||
prop, gpio);
|
||||
|
||||
gpio = 0;
|
||||
}
|
||||
|
||||
return gpio;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(arizona_of_get_named_gpio);
|
||||
|
||||
static int arizona_of_get_core_pdata(struct arizona *arizona)
|
||||
{
|
||||
struct arizona_pdata *pdata = &arizona->pdata;
|
||||
int ret, i;
|
||||
|
||||
arizona->pdata.reset = of_get_named_gpio(arizona->dev->of_node,
|
||||
"wlf,reset", 0);
|
||||
if (arizona->pdata.reset < 0)
|
||||
arizona->pdata.reset = 0;
|
||||
|
||||
arizona->pdata.ldoena = of_get_named_gpio(arizona->dev->of_node,
|
||||
"wlf,ldoena", 0);
|
||||
if (arizona->pdata.ldoena < 0)
|
||||
arizona->pdata.ldoena = 0;
|
||||
pdata->reset = arizona_of_get_named_gpio(arizona, "wlf,reset", true);
|
||||
|
||||
ret = of_property_read_u32_array(arizona->dev->of_node,
|
||||
"wlf,gpio-defaults",
|
||||
@@ -652,6 +664,9 @@ int arizona_dev_init(struct arizona *arizona)
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* Mark DCVDD as external, LDO1 driver will clear if internal */
|
||||
arizona->external_dcvdd = true;
|
||||
|
||||
ret = mfd_add_devices(arizona->dev, -1, early_devs,
|
||||
ARRAY_SIZE(early_devs), NULL, 0, NULL);
|
||||
if (ret != 0) {
|
||||
@@ -851,14 +866,6 @@ int arizona_dev_init(struct arizona *arizona)
|
||||
arizona->pdata.gpio_defaults[i]);
|
||||
}
|
||||
|
||||
/*
|
||||
* LDO1 can only be used to supply DCVDD so if it has no
|
||||
* consumers then DCVDD is supplied externally.
|
||||
*/
|
||||
if (arizona->pdata.ldo1 &&
|
||||
arizona->pdata.ldo1->num_consumer_supplies == 0)
|
||||
arizona->external_dcvdd = true;
|
||||
|
||||
pm_runtime_set_autosuspend_delay(arizona->dev, 100);
|
||||
pm_runtime_use_autosuspend(arizona->dev);
|
||||
pm_runtime_enable(arizona->dev);
|
||||
|
||||
+47
-15
@@ -28,39 +28,71 @@ static const struct mfd_cell bcm590xx_devs[] = {
|
||||
},
|
||||
};
|
||||
|
||||
static const struct regmap_config bcm590xx_regmap_config = {
|
||||
static const struct regmap_config bcm590xx_regmap_config_pri = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = BCM590XX_MAX_REGISTER,
|
||||
.max_register = BCM590XX_MAX_REGISTER_PRI,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static int bcm590xx_i2c_probe(struct i2c_client *i2c,
|
||||
static const struct regmap_config bcm590xx_regmap_config_sec = {
|
||||
.reg_bits = 8,
|
||||
.val_bits = 8,
|
||||
.max_register = BCM590XX_MAX_REGISTER_SEC,
|
||||
.cache_type = REGCACHE_RBTREE,
|
||||
};
|
||||
|
||||
static int bcm590xx_i2c_probe(struct i2c_client *i2c_pri,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct bcm590xx *bcm590xx;
|
||||
int ret;
|
||||
|
||||
bcm590xx = devm_kzalloc(&i2c->dev, sizeof(*bcm590xx), GFP_KERNEL);
|
||||
bcm590xx = devm_kzalloc(&i2c_pri->dev, sizeof(*bcm590xx), GFP_KERNEL);
|
||||
if (!bcm590xx)
|
||||
return -ENOMEM;
|
||||
|
||||
i2c_set_clientdata(i2c, bcm590xx);
|
||||
bcm590xx->dev = &i2c->dev;
|
||||
bcm590xx->i2c_client = i2c;
|
||||
i2c_set_clientdata(i2c_pri, bcm590xx);
|
||||
bcm590xx->dev = &i2c_pri->dev;
|
||||
bcm590xx->i2c_pri = i2c_pri;
|
||||
|
||||
bcm590xx->regmap = devm_regmap_init_i2c(i2c, &bcm590xx_regmap_config);
|
||||
if (IS_ERR(bcm590xx->regmap)) {
|
||||
ret = PTR_ERR(bcm590xx->regmap);
|
||||
dev_err(&i2c->dev, "regmap initialization failed: %d\n", ret);
|
||||
bcm590xx->regmap_pri = devm_regmap_init_i2c(i2c_pri,
|
||||
&bcm590xx_regmap_config_pri);
|
||||
if (IS_ERR(bcm590xx->regmap_pri)) {
|
||||
ret = PTR_ERR(bcm590xx->regmap_pri);
|
||||
dev_err(&i2c_pri->dev, "primary regmap init failed: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(&i2c->dev, -1, bcm590xx_devs,
|
||||
ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL);
|
||||
if (ret < 0)
|
||||
dev_err(&i2c->dev, "failed to add sub-devices: %d\n", ret);
|
||||
/* Secondary I2C slave address is the base address with A(2) asserted */
|
||||
bcm590xx->i2c_sec = i2c_new_dummy(i2c_pri->adapter,
|
||||
i2c_pri->addr | BIT(2));
|
||||
if (IS_ERR_OR_NULL(bcm590xx->i2c_sec)) {
|
||||
dev_err(&i2c_pri->dev, "failed to add secondary I2C device\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
i2c_set_clientdata(bcm590xx->i2c_sec, bcm590xx);
|
||||
|
||||
bcm590xx->regmap_sec = devm_regmap_init_i2c(bcm590xx->i2c_sec,
|
||||
&bcm590xx_regmap_config_sec);
|
||||
if (IS_ERR(bcm590xx->regmap_sec)) {
|
||||
ret = PTR_ERR(bcm590xx->regmap_sec);
|
||||
dev_err(&bcm590xx->i2c_sec->dev,
|
||||
"secondary regmap init failed: %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(&i2c_pri->dev, -1, bcm590xx_devs,
|
||||
ARRAY_SIZE(bcm590xx_devs), NULL, 0, NULL);
|
||||
if (ret < 0) {
|
||||
dev_err(&i2c_pri->dev, "failed to add sub-devices: %d\n", ret);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
i2c_unregister_device(bcm590xx->i2c_sec);
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
+25
-16
@@ -32,14 +32,6 @@
|
||||
#define NUM_INT_REG 2
|
||||
#define TOTAL_NUM_REG 0x18
|
||||
|
||||
/* interrupt status registers */
|
||||
#define TPS65090_INT_STS 0x0
|
||||
#define TPS65090_INT_STS2 0x1
|
||||
|
||||
/* interrupt mask registers */
|
||||
#define TPS65090_INT_MSK 0x2
|
||||
#define TPS65090_INT_MSK2 0x3
|
||||
|
||||
#define TPS65090_INT1_MASK_VAC_STATUS_CHANGE 1
|
||||
#define TPS65090_INT1_MASK_VSYS_STATUS_CHANGE 2
|
||||
#define TPS65090_INT1_MASK_BAT_STATUS_CHANGE 3
|
||||
@@ -64,11 +56,16 @@ static struct resource charger_resources[] = {
|
||||
}
|
||||
};
|
||||
|
||||
static const struct mfd_cell tps65090s[] = {
|
||||
{
|
||||
enum tps65090_cells {
|
||||
PMIC = 0,
|
||||
CHARGER = 1,
|
||||
};
|
||||
|
||||
static struct mfd_cell tps65090s[] = {
|
||||
[PMIC] = {
|
||||
.name = "tps65090-pmic",
|
||||
},
|
||||
{
|
||||
[CHARGER] = {
|
||||
.name = "tps65090-charger",
|
||||
.num_resources = ARRAY_SIZE(charger_resources),
|
||||
.resources = &charger_resources[0],
|
||||
@@ -139,17 +136,26 @@ static struct regmap_irq_chip tps65090_irq_chip = {
|
||||
.irqs = tps65090_irqs,
|
||||
.num_irqs = ARRAY_SIZE(tps65090_irqs),
|
||||
.num_regs = NUM_INT_REG,
|
||||
.status_base = TPS65090_INT_STS,
|
||||
.mask_base = TPS65090_INT_MSK,
|
||||
.status_base = TPS65090_REG_INTR_STS,
|
||||
.mask_base = TPS65090_REG_INTR_MASK,
|
||||
.mask_invert = true,
|
||||
};
|
||||
|
||||
static bool is_volatile_reg(struct device *dev, unsigned int reg)
|
||||
{
|
||||
if ((reg == TPS65090_INT_STS) || (reg == TPS65090_INT_STS2))
|
||||
return true;
|
||||
else
|
||||
/* Nearly all registers have status bits mixed in, except a few */
|
||||
switch (reg) {
|
||||
case TPS65090_REG_INTR_MASK:
|
||||
case TPS65090_REG_INTR_MASK2:
|
||||
case TPS65090_REG_CG_CTRL0:
|
||||
case TPS65090_REG_CG_CTRL1:
|
||||
case TPS65090_REG_CG_CTRL2:
|
||||
case TPS65090_REG_CG_CTRL3:
|
||||
case TPS65090_REG_CG_CTRL4:
|
||||
case TPS65090_REG_CG_CTRL5:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static const struct regmap_config tps65090_regmap_config = {
|
||||
@@ -211,6 +217,9 @@ static int tps65090_i2c_probe(struct i2c_client *client,
|
||||
"IRQ init failed with err: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
} else {
|
||||
/* Don't tell children they have an IRQ that'll never fire */
|
||||
tps65090s[CHARGER].num_resources = 0;
|
||||
}
|
||||
|
||||
ret = mfd_add_devices(tps65090->dev, -1, tps65090s,
|
||||
|
||||
@@ -495,6 +495,10 @@ static void tps6586x_print_version(struct i2c_client *client, int version)
|
||||
case TPS658623:
|
||||
name = "TPS658623";
|
||||
break;
|
||||
case TPS658640:
|
||||
case TPS658640v2:
|
||||
name = "TPS658640";
|
||||
break;
|
||||
case TPS658643:
|
||||
name = "TPS658643";
|
||||
break;
|
||||
|
||||
@@ -28,17 +28,6 @@
|
||||
|
||||
#include <linux/mfd/tps65090.h>
|
||||
|
||||
#define TPS65090_REG_INTR_STS 0x00
|
||||
#define TPS65090_REG_INTR_MASK 0x02
|
||||
#define TPS65090_REG_CG_CTRL0 0x04
|
||||
#define TPS65090_REG_CG_CTRL1 0x05
|
||||
#define TPS65090_REG_CG_CTRL2 0x06
|
||||
#define TPS65090_REG_CG_CTRL3 0x07
|
||||
#define TPS65090_REG_CG_CTRL4 0x08
|
||||
#define TPS65090_REG_CG_CTRL5 0x09
|
||||
#define TPS65090_REG_CG_STATUS1 0x0a
|
||||
#define TPS65090_REG_CG_STATUS2 0x0b
|
||||
|
||||
#define TPS65090_CHARGER_ENABLE BIT(0)
|
||||
#define TPS65090_VACG BIT(1)
|
||||
#define TPS65090_NOITERM BIT(5)
|
||||
|
||||
@@ -139,6 +139,13 @@ config REGULATOR_AS3722
|
||||
AS3722 PMIC. This will enable support for all the software
|
||||
controllable DCDC/LDO regulators.
|
||||
|
||||
config REGULATOR_AXP20X
|
||||
tristate "X-POWERS AXP20X PMIC Regulators"
|
||||
depends on MFD_AXP20X
|
||||
help
|
||||
This driver provides support for the voltage regulators on the
|
||||
AXP20X PMIC.
|
||||
|
||||
config REGULATOR_BCM590XX
|
||||
tristate "Broadcom BCM590xx PMU Regulators"
|
||||
depends on MFD_BCM590XX
|
||||
@@ -265,6 +272,14 @@ config REGULATOR_LP8788
|
||||
help
|
||||
This driver supports LP8788 voltage regulator chip.
|
||||
|
||||
config REGULATOR_LTC3589
|
||||
tristate "LTC3589 8-output voltage regulator"
|
||||
depends on I2C
|
||||
select REGMAP_I2C
|
||||
help
|
||||
This enables support for the LTC3589, LTC3589-1, and LTC3589-2
|
||||
8-output regulators controlled via I2C.
|
||||
|
||||
config REGULATOR_MAX14577
|
||||
tristate "Maxim 14577/77836 regulator"
|
||||
depends on MFD_MAX14577
|
||||
|
||||
@@ -20,6 +20,7 @@ obj-$(CONFIG_REGULATOR_ANATOP) += anatop-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_ARIZONA) += arizona-micsupp.o arizona-ldo1.o
|
||||
obj-$(CONFIG_REGULATOR_AS3711) += as3711-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_AS3722) += as3722-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_AXP20X) += axp20x-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_BCM590XX) += bcm590xx-regulator.o
|
||||
obj-$(CONFIG_REGULATOR_DA903X) += da903x.o
|
||||
obj-$(CONFIG_REGULATOR_DA9052) += da9052-regulator.o
|
||||
@@ -37,6 +38,7 @@ obj-$(CONFIG_REGULATOR_LP872X) += lp872x.o
|
||||
obj-$(CONFIG_REGULATOR_LP8788) += lp8788-buck.o
|
||||
obj-$(CONFIG_REGULATOR_LP8788) += lp8788-ldo.o
|
||||
obj-$(CONFIG_REGULATOR_LP8755) += lp8755.o
|
||||
obj-$(CONFIG_REGULATOR_LTC3589) += ltc3589.o
|
||||
obj-$(CONFIG_REGULATOR_MAX14577) += max14577.o
|
||||
obj-$(CONFIG_REGULATOR_MAX1586) += max1586.o
|
||||
obj-$(CONFIG_REGULATOR_MAX8649) += max8649.o
|
||||
|
||||
@@ -300,7 +300,7 @@ static int anatop_regulator_probe(struct platform_device *pdev)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct of_device_id of_anatop_regulator_match_tbl[] = {
|
||||
static const struct of_device_id of_anatop_regulator_match_tbl[] = {
|
||||
{ .compatible = "fsl,anatop-regulator", },
|
||||
{ /* end */ }
|
||||
};
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/slab.h>
|
||||
|
||||
@@ -178,6 +180,42 @@ static const struct regulator_init_data arizona_ldo1_default = {
|
||||
.num_consumer_supplies = 1,
|
||||
};
|
||||
|
||||
static int arizona_ldo1_of_get_pdata(struct arizona *arizona,
|
||||
struct regulator_config *config)
|
||||
{
|
||||
struct arizona_pdata *pdata = &arizona->pdata;
|
||||
struct arizona_ldo1 *ldo1 = config->driver_data;
|
||||
struct device_node *init_node, *dcvdd_node;
|
||||
struct regulator_init_data *init_data;
|
||||
|
||||
pdata->ldoena = arizona_of_get_named_gpio(arizona, "wlf,ldoena", true);
|
||||
|
||||
init_node = of_get_child_by_name(arizona->dev->of_node, "ldo1");
|
||||
dcvdd_node = of_parse_phandle(arizona->dev->of_node, "DCVDD-supply", 0);
|
||||
|
||||
if (init_node) {
|
||||
config->of_node = init_node;
|
||||
|
||||
init_data = of_get_regulator_init_data(arizona->dev, init_node);
|
||||
|
||||
if (init_data) {
|
||||
init_data->consumer_supplies = &ldo1->supply;
|
||||
init_data->num_consumer_supplies = 1;
|
||||
|
||||
if (dcvdd_node && dcvdd_node != init_node)
|
||||
arizona->external_dcvdd = true;
|
||||
|
||||
pdata->ldo1 = init_data;
|
||||
}
|
||||
} else if (dcvdd_node) {
|
||||
arizona->external_dcvdd = true;
|
||||
}
|
||||
|
||||
of_node_put(dcvdd_node);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arizona_ldo1_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
|
||||
@@ -186,6 +224,8 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
|
||||
struct arizona_ldo1 *ldo1;
|
||||
int ret;
|
||||
|
||||
arizona->external_dcvdd = false;
|
||||
|
||||
ldo1 = devm_kzalloc(&pdev->dev, sizeof(*ldo1), GFP_KERNEL);
|
||||
if (!ldo1)
|
||||
return -ENOMEM;
|
||||
@@ -216,6 +256,15 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
|
||||
config.dev = arizona->dev;
|
||||
config.driver_data = ldo1;
|
||||
config.regmap = arizona->regmap;
|
||||
|
||||
if (IS_ENABLED(CONFIG_OF)) {
|
||||
if (!dev_get_platdata(arizona->dev)) {
|
||||
ret = arizona_ldo1_of_get_pdata(arizona, &config);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
config.ena_gpio = arizona->pdata.ldoena;
|
||||
|
||||
if (arizona->pdata.ldo1)
|
||||
@@ -223,6 +272,13 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
|
||||
else
|
||||
config.init_data = &ldo1->init_data;
|
||||
|
||||
/*
|
||||
* LDO1 can only be used to supply DCVDD so if it has no
|
||||
* consumers then DCVDD is supplied externally.
|
||||
*/
|
||||
if (config.init_data->num_consumer_supplies == 0)
|
||||
arizona->external_dcvdd = true;
|
||||
|
||||
ldo1->regulator = devm_regulator_register(&pdev->dev, desc, &config);
|
||||
if (IS_ERR(ldo1->regulator)) {
|
||||
ret = PTR_ERR(ldo1->regulator);
|
||||
@@ -231,6 +287,8 @@ static int arizona_ldo1_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
of_node_put(config.of_node);
|
||||
|
||||
platform_set_drvdata(pdev, ldo1);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -16,9 +16,11 @@
|
||||
#include <linux/init.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/machine.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/workqueue.h>
|
||||
@@ -195,6 +197,32 @@ static const struct regulator_init_data arizona_micsupp_ext_default = {
|
||||
.num_consumer_supplies = 1,
|
||||
};
|
||||
|
||||
static int arizona_micsupp_of_get_pdata(struct arizona *arizona,
|
||||
struct regulator_config *config)
|
||||
{
|
||||
struct arizona_pdata *pdata = &arizona->pdata;
|
||||
struct arizona_micsupp *micsupp = config->driver_data;
|
||||
struct device_node *np;
|
||||
struct regulator_init_data *init_data;
|
||||
|
||||
np = of_get_child_by_name(arizona->dev->of_node, "micvdd");
|
||||
|
||||
if (np) {
|
||||
config->of_node = np;
|
||||
|
||||
init_data = of_get_regulator_init_data(arizona->dev, np);
|
||||
|
||||
if (init_data) {
|
||||
init_data->consumer_supplies = &micsupp->supply;
|
||||
init_data->num_consumer_supplies = 1;
|
||||
|
||||
pdata->micvdd = init_data;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int arizona_micsupp_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct arizona *arizona = dev_get_drvdata(pdev->dev.parent);
|
||||
@@ -234,6 +262,14 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
|
||||
config.driver_data = micsupp;
|
||||
config.regmap = arizona->regmap;
|
||||
|
||||
if (IS_ENABLED(CONFIG_OF)) {
|
||||
if (!dev_get_platdata(arizona->dev)) {
|
||||
ret = arizona_micsupp_of_get_pdata(arizona, &config);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
if (arizona->pdata.micvdd)
|
||||
config.init_data = arizona->pdata.micvdd;
|
||||
else
|
||||
@@ -253,6 +289,8 @@ static int arizona_micsupp_probe(struct platform_device *pdev)
|
||||
return ret;
|
||||
}
|
||||
|
||||
of_node_put(config.of_node);
|
||||
|
||||
platform_set_drvdata(pdev, micsupp);
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -0,0 +1,286 @@
|
||||
/*
|
||||
* AXP20x regulators driver.
|
||||
*
|
||||
* Copyright (C) 2013 Carlo Caione <carlo@caione.org>
|
||||
*
|
||||
* This file is subject to the terms and conditions of the GNU General
|
||||
* Public License. See the file "COPYING" in the main directory of this
|
||||
* archive for more details.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#include <linux/err.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/regmap.h>
|
||||
#include <linux/mfd/axp20x.h>
|
||||
#include <linux/regulator/driver.h>
|
||||
#include <linux/regulator/of_regulator.h>
|
||||
|
||||
#define AXP20X_IO_ENABLED 0x03
|
||||
#define AXP20X_IO_DISABLED 0x07
|
||||
|
||||
#define AXP20X_WORKMODE_DCDC2_MASK BIT(2)
|
||||
#define AXP20X_WORKMODE_DCDC3_MASK BIT(1)
|
||||
|
||||
#define AXP20X_FREQ_DCDC_MASK 0x0f
|
||||
|
||||
#define AXP20X_DESC_IO(_id, _supply, _min, _max, _step, _vreg, _vmask, _ereg, \
|
||||
_emask, _enable_val, _disable_val) \
|
||||
[AXP20X_##_id] = { \
|
||||
.name = #_id, \
|
||||
.supply_name = (_supply), \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = AXP20X_##_id, \
|
||||
.n_voltages = (((_max) - (_min)) / (_step) + 1), \
|
||||
.owner = THIS_MODULE, \
|
||||
.min_uV = (_min) * 1000, \
|
||||
.uV_step = (_step) * 1000, \
|
||||
.vsel_reg = (_vreg), \
|
||||
.vsel_mask = (_vmask), \
|
||||
.enable_reg = (_ereg), \
|
||||
.enable_mask = (_emask), \
|
||||
.enable_val = (_enable_val), \
|
||||
.disable_val = (_disable_val), \
|
||||
.ops = &axp20x_ops, \
|
||||
}
|
||||
|
||||
#define AXP20X_DESC(_id, _supply, _min, _max, _step, _vreg, _vmask, _ereg, \
|
||||
_emask) \
|
||||
[AXP20X_##_id] = { \
|
||||
.name = #_id, \
|
||||
.supply_name = (_supply), \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = AXP20X_##_id, \
|
||||
.n_voltages = (((_max) - (_min)) / (_step) + 1), \
|
||||
.owner = THIS_MODULE, \
|
||||
.min_uV = (_min) * 1000, \
|
||||
.uV_step = (_step) * 1000, \
|
||||
.vsel_reg = (_vreg), \
|
||||
.vsel_mask = (_vmask), \
|
||||
.enable_reg = (_ereg), \
|
||||
.enable_mask = (_emask), \
|
||||
.ops = &axp20x_ops, \
|
||||
}
|
||||
|
||||
#define AXP20X_DESC_FIXED(_id, _supply, _volt) \
|
||||
[AXP20X_##_id] = { \
|
||||
.name = #_id, \
|
||||
.supply_name = (_supply), \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = AXP20X_##_id, \
|
||||
.n_voltages = 1, \
|
||||
.owner = THIS_MODULE, \
|
||||
.min_uV = (_volt) * 1000, \
|
||||
.ops = &axp20x_ops_fixed \
|
||||
}
|
||||
|
||||
#define AXP20X_DESC_TABLE(_id, _supply, _table, _vreg, _vmask, _ereg, _emask) \
|
||||
[AXP20X_##_id] = { \
|
||||
.name = #_id, \
|
||||
.supply_name = (_supply), \
|
||||
.type = REGULATOR_VOLTAGE, \
|
||||
.id = AXP20X_##_id, \
|
||||
.n_voltages = ARRAY_SIZE(_table), \
|
||||
.owner = THIS_MODULE, \
|
||||
.vsel_reg = (_vreg), \
|
||||
.vsel_mask = (_vmask), \
|
||||
.enable_reg = (_ereg), \
|
||||
.enable_mask = (_emask), \
|
||||
.volt_table = (_table), \
|
||||
.ops = &axp20x_ops_table, \
|
||||
}
|
||||
|
||||
static const int axp20x_ldo4_data[] = { 1250000, 1300000, 1400000, 1500000, 1600000,
|
||||
1700000, 1800000, 1900000, 2000000, 2500000,
|
||||
2700000, 2800000, 3000000, 3100000, 3200000,
|
||||
3300000 };
|
||||
|
||||
static struct regulator_ops axp20x_ops_fixed = {
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
};
|
||||
|
||||
static struct regulator_ops axp20x_ops_table = {
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.list_voltage = regulator_list_voltage_table,
|
||||
.map_voltage = regulator_map_voltage_ascend,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
};
|
||||
|
||||
static struct regulator_ops axp20x_ops = {
|
||||
.set_voltage_sel = regulator_set_voltage_sel_regmap,
|
||||
.get_voltage_sel = regulator_get_voltage_sel_regmap,
|
||||
.list_voltage = regulator_list_voltage_linear,
|
||||
.enable = regulator_enable_regmap,
|
||||
.disable = regulator_disable_regmap,
|
||||
.is_enabled = regulator_is_enabled_regmap,
|
||||
};
|
||||
|
||||
static const struct regulator_desc axp20x_regulators[] = {
|
||||
AXP20X_DESC(DCDC2, "vin2", 700, 2275, 25, AXP20X_DCDC2_V_OUT, 0x3f,
|
||||
AXP20X_PWR_OUT_CTRL, 0x10),
|
||||
AXP20X_DESC(DCDC3, "vin3", 700, 3500, 25, AXP20X_DCDC3_V_OUT, 0x7f,
|
||||
AXP20X_PWR_OUT_CTRL, 0x02),
|
||||
AXP20X_DESC_FIXED(LDO1, "acin", 1300),
|
||||
AXP20X_DESC(LDO2, "ldo24in", 1800, 3300, 100, AXP20X_LDO24_V_OUT, 0xf0,
|
||||
AXP20X_PWR_OUT_CTRL, 0x04),
|
||||
AXP20X_DESC(LDO3, "ldo3in", 700, 3500, 25, AXP20X_LDO3_V_OUT, 0x7f,
|
||||
AXP20X_PWR_OUT_CTRL, 0x40),
|
||||
AXP20X_DESC_TABLE(LDO4, "ldo24in", axp20x_ldo4_data, AXP20X_LDO24_V_OUT, 0x0f,
|
||||
AXP20X_PWR_OUT_CTRL, 0x08),
|
||||
AXP20X_DESC_IO(LDO5, "ldo5in", 1800, 3300, 100, AXP20X_LDO5_V_OUT, 0xf0,
|
||||
AXP20X_GPIO0_CTRL, 0x07, AXP20X_IO_ENABLED,
|
||||
AXP20X_IO_DISABLED),
|
||||
};
|
||||
|
||||
#define AXP_MATCH(_name, _id) \
|
||||
[AXP20X_##_id] = { \
|
||||
.name = #_name, \
|
||||
.driver_data = (void *) &axp20x_regulators[AXP20X_##_id], \
|
||||
}
|
||||
|
||||
static struct of_regulator_match axp20x_matches[] = {
|
||||
AXP_MATCH(dcdc2, DCDC2),
|
||||
AXP_MATCH(dcdc3, DCDC3),
|
||||
AXP_MATCH(ldo1, LDO1),
|
||||
AXP_MATCH(ldo2, LDO2),
|
||||
AXP_MATCH(ldo3, LDO3),
|
||||
AXP_MATCH(ldo4, LDO4),
|
||||
AXP_MATCH(ldo5, LDO5),
|
||||
};
|
||||
|
||||
static int axp20x_set_dcdc_freq(struct platform_device *pdev, u32 dcdcfreq)
|
||||
{
|
||||
struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
|
||||
|
||||
if (dcdcfreq < 750) {
|
||||
dcdcfreq = 750;
|
||||
dev_warn(&pdev->dev, "DCDC frequency too low. Set to 750kHz\n");
|
||||
}
|
||||
|
||||
if (dcdcfreq > 1875) {
|
||||
dcdcfreq = 1875;
|
||||
dev_warn(&pdev->dev, "DCDC frequency too high. Set to 1875kHz\n");
|
||||
}
|
||||
|
||||
dcdcfreq = (dcdcfreq - 750) / 75;
|
||||
|
||||
return regmap_update_bits(axp20x->regmap, AXP20X_DCDC_FREQ,
|
||||
AXP20X_FREQ_DCDC_MASK, dcdcfreq);
|
||||
}
|
||||
|
||||
static int axp20x_regulator_parse_dt(struct platform_device *pdev)
|
||||
{
|
||||
struct device_node *np, *regulators;
|
||||
int ret;
|
||||
u32 dcdcfreq;
|
||||
|
||||
np = of_node_get(pdev->dev.parent->of_node);
|
||||
if (!np)
|
||||
return 0;
|
||||
|
||||
regulators = of_get_child_by_name(np, "regulators");
|
||||
if (!regulators) {
|
||||
dev_warn(&pdev->dev, "regulators node not found\n");
|
||||
} else {
|
||||
ret = of_regulator_match(&pdev->dev, regulators, axp20x_matches,
|
||||
ARRAY_SIZE(axp20x_matches));
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Error parsing regulator init data: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
dcdcfreq = 1500;
|
||||
of_property_read_u32(regulators, "x-powers,dcdc-freq", &dcdcfreq);
|
||||
ret = axp20x_set_dcdc_freq(pdev, dcdcfreq);
|
||||
if (ret < 0) {
|
||||
dev_err(&pdev->dev, "Error setting dcdc frequency: %d\n", ret);
|
||||
return ret;
|
||||
}
|
||||
|
||||
of_node_put(regulators);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int axp20x_set_dcdc_workmode(struct regulator_dev *rdev, int id, u32 workmode)
|
||||
{
|
||||
unsigned int mask = AXP20X_WORKMODE_DCDC2_MASK;
|
||||
|
||||
if ((id != AXP20X_DCDC2) && (id != AXP20X_DCDC3))
|
||||
return -EINVAL;
|
||||
|
||||
if (id == AXP20X_DCDC3)
|
||||
mask = AXP20X_WORKMODE_DCDC3_MASK;
|
||||
|
||||
workmode <<= ffs(mask) - 1;
|
||||
|
||||
return regmap_update_bits(rdev->regmap, AXP20X_DCDC_MODE, mask, workmode);
|
||||
}
|
||||
|
||||
static int axp20x_regulator_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct regulator_dev *rdev;
|
||||
struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
|
||||
struct regulator_config config = { };
|
||||
struct regulator_init_data *init_data;
|
||||
int ret, i;
|
||||
u32 workmode;
|
||||
|
||||
ret = axp20x_regulator_parse_dt(pdev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
for (i = 0; i < AXP20X_REG_ID_MAX; i++) {
|
||||
init_data = axp20x_matches[i].init_data;
|
||||
|
||||
config.dev = &pdev->dev;
|
||||
config.init_data = init_data;
|
||||
config.regmap = axp20x->regmap;
|
||||
config.of_node = axp20x_matches[i].of_node;
|
||||
|
||||
rdev = devm_regulator_register(&pdev->dev, &axp20x_regulators[i],
|
||||
&config);
|
||||
if (IS_ERR(rdev)) {
|
||||
dev_err(&pdev->dev, "Failed to register %s\n",
|
||||
axp20x_regulators[i].name);
|
||||
|
||||
return PTR_ERR(rdev);
|
||||
}
|
||||
|
||||
ret = of_property_read_u32(axp20x_matches[i].of_node, "x-powers,dcdc-workmode",
|
||||
&workmode);
|
||||
if (!ret) {
|
||||
if (axp20x_set_dcdc_workmode(rdev, i, workmode))
|
||||
dev_err(&pdev->dev, "Failed to set workmode on %s\n",
|
||||
axp20x_regulators[i].name);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct platform_driver axp20x_regulator_driver = {
|
||||
.probe = axp20x_regulator_probe,
|
||||
.driver = {
|
||||
.name = "axp20x-regulator",
|
||||
.owner = THIS_MODULE,
|
||||
},
|
||||
};
|
||||
|
||||
module_platform_driver(axp20x_regulator_driver);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_AUTHOR("Carlo Caione <carlo@caione.org>");
|
||||
MODULE_DESCRIPTION("Regulator Driver for AXP20X PMIC");
|
||||
@@ -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;
|
||||
|
||||
+33
-17
@@ -844,15 +844,24 @@ static int machine_constraints_voltage(struct regulator_dev *rdev,
|
||||
/* do we need to apply the constraint voltage */
|
||||
if (rdev->constraints->apply_uV &&
|
||||
rdev->constraints->min_uV == rdev->constraints->max_uV) {
|
||||
ret = _regulator_do_set_voltage(rdev,
|
||||
rdev->constraints->min_uV,
|
||||
int current_uV = _regulator_get_voltage(rdev);
|
||||
if (current_uV < 0) {
|
||||
rdev_err(rdev, "failed to get the current voltage\n");
|
||||
return current_uV;
|
||||
}
|
||||
if (current_uV < rdev->constraints->min_uV ||
|
||||
current_uV > rdev->constraints->max_uV) {
|
||||
ret = _regulator_do_set_voltage(
|
||||
rdev, rdev->constraints->min_uV,
|
||||
rdev->constraints->max_uV);
|
||||
if (ret < 0) {
|
||||
rdev_err(rdev, "failed to apply %duV constraint\n",
|
||||
rdev_err(rdev,
|
||||
"failed to apply %duV constraint\n",
|
||||
rdev->constraints->min_uV);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* constrain machine-level voltage specs to fit
|
||||
* the actual range supported by this regulator.
|
||||
@@ -1430,9 +1439,9 @@ EXPORT_SYMBOL_GPL(regulator_get);
|
||||
*
|
||||
* Returns a struct regulator corresponding to the regulator producer,
|
||||
* or IS_ERR() condition containing errno. Other consumers will be
|
||||
* unable to obtain this reference is held and the use count for the
|
||||
* regulator will be initialised to reflect the current state of the
|
||||
* regulator.
|
||||
* unable to obtain this regulator while this reference is held and the
|
||||
* use count for the regulator will be initialised to reflect the current
|
||||
* state of the regulator.
|
||||
*
|
||||
* This is intended for use by consumers which cannot tolerate shared
|
||||
* use of the regulator such as those which need to force the
|
||||
@@ -1456,10 +1465,7 @@ EXPORT_SYMBOL_GPL(regulator_get_exclusive);
|
||||
* @id: Supply name or regulator ID.
|
||||
*
|
||||
* Returns a struct regulator corresponding to the regulator producer,
|
||||
* or IS_ERR() condition containing errno. Other consumers will be
|
||||
* unable to obtain this reference is held and the use count for the
|
||||
* regulator will be initialised to reflect the current state of the
|
||||
* regulator.
|
||||
* or IS_ERR() condition containing errno.
|
||||
*
|
||||
* This is intended for use by consumers for devices which can have
|
||||
* some supplies unconnected in normal use, such as some MMC devices.
|
||||
@@ -1597,9 +1603,10 @@ EXPORT_SYMBOL_GPL(regulator_unregister_supply_alias);
|
||||
* registered any aliases that were registered will be removed
|
||||
* before returning to the caller.
|
||||
*/
|
||||
int regulator_bulk_register_supply_alias(struct device *dev, const char **id,
|
||||
int regulator_bulk_register_supply_alias(struct device *dev,
|
||||
const char *const *id,
|
||||
struct device *alias_dev,
|
||||
const char **alias_id,
|
||||
const char *const *alias_id,
|
||||
int num_id)
|
||||
{
|
||||
int i;
|
||||
@@ -1637,7 +1644,7 @@ EXPORT_SYMBOL_GPL(regulator_bulk_register_supply_alias);
|
||||
* aliases in one operation.
|
||||
*/
|
||||
void regulator_bulk_unregister_supply_alias(struct device *dev,
|
||||
const char **id,
|
||||
const char *const *id,
|
||||
int num_id)
|
||||
{
|
||||
int i;
|
||||
@@ -2321,6 +2328,10 @@ static int _regulator_do_set_voltage(struct regulator_dev *rdev,
|
||||
regulator_list_voltage_linear)
|
||||
ret = regulator_map_voltage_linear(rdev,
|
||||
min_uV, max_uV);
|
||||
else if (rdev->desc->ops->list_voltage ==
|
||||
regulator_list_voltage_linear_range)
|
||||
ret = regulator_map_voltage_linear_range(rdev,
|
||||
min_uV, max_uV);
|
||||
else
|
||||
ret = regulator_map_voltage_iterate(rdev,
|
||||
min_uV, max_uV);
|
||||
@@ -3447,7 +3458,7 @@ regulator_register(const struct regulator_desc *regulator_desc,
|
||||
|
||||
/* register with sysfs */
|
||||
rdev->dev.class = ®ulator_class;
|
||||
rdev->dev.of_node = config->of_node;
|
||||
rdev->dev.of_node = of_node_get(config->of_node);
|
||||
rdev->dev.parent = dev;
|
||||
dev_set_name(&rdev->dev, "regulator.%d",
|
||||
atomic_inc_return(®ulator_no) - 1);
|
||||
@@ -3589,6 +3600,7 @@ void regulator_unregister(struct regulator_dev *rdev)
|
||||
list_del(&rdev->list);
|
||||
kfree(rdev->constraints);
|
||||
regulator_ena_gpio_free(rdev);
|
||||
of_node_put(rdev->dev.of_node);
|
||||
device_unregister(&rdev->dev);
|
||||
mutex_unlock(®ulator_list_mutex);
|
||||
}
|
||||
@@ -3819,8 +3831,9 @@ static int __init regulator_init_complete(void)
|
||||
mutex_lock(®ulator_list_mutex);
|
||||
|
||||
/* If we have a full configuration then disable any regulators
|
||||
* which are not in use or always_on. This will become the
|
||||
* default behaviour in the future.
|
||||
* we have permission to change the status for and which are
|
||||
* not in use or always_on. This is effectively the default
|
||||
* for DT and ACPI as they have full constraints.
|
||||
*/
|
||||
list_for_each_entry(rdev, ®ulator_list, list) {
|
||||
ops = rdev->desc->ops;
|
||||
@@ -3829,6 +3842,9 @@ static int __init regulator_init_complete(void)
|
||||
if (c && c->always_on)
|
||||
continue;
|
||||
|
||||
if (c && !(c->valid_ops_mask & REGULATOR_CHANGE_STATUS))
|
||||
continue;
|
||||
|
||||
mutex_lock(&rdev->mutex);
|
||||
|
||||
if (rdev->use_count)
|
||||
@@ -3867,4 +3883,4 @@ unlock:
|
||||
|
||||
return 0;
|
||||
}
|
||||
late_initcall(regulator_init_complete);
|
||||
late_initcall_sync(regulator_init_complete);
|
||||
|
||||
@@ -360,9 +360,9 @@ EXPORT_SYMBOL_GPL(devm_regulator_unregister_supply_alias);
|
||||
* will be removed before returning to the caller.
|
||||
*/
|
||||
int devm_regulator_bulk_register_supply_alias(struct device *dev,
|
||||
const char **id,
|
||||
const char *const *id,
|
||||
struct device *alias_dev,
|
||||
const char **alias_id,
|
||||
const char *const *alias_id,
|
||||
int num_id)
|
||||
{
|
||||
int i;
|
||||
@@ -404,7 +404,7 @@ EXPORT_SYMBOL_GPL(devm_regulator_bulk_register_supply_alias);
|
||||
* will ensure that the resource is freed.
|
||||
*/
|
||||
void devm_regulator_bulk_unregister_supply_alias(struct device *dev,
|
||||
const char **id,
|
||||
const char *const *id,
|
||||
int num_id)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -50,7 +50,6 @@ of_get_fixed_voltage_config(struct device *dev)
|
||||
{
|
||||
struct fixed_voltage_config *config;
|
||||
struct device_node *np = dev->of_node;
|
||||
const __be32 *delay;
|
||||
struct regulator_init_data *init_data;
|
||||
|
||||
config = devm_kzalloc(dev, sizeof(struct fixed_voltage_config),
|
||||
@@ -91,15 +90,11 @@ of_get_fixed_voltage_config(struct device *dev)
|
||||
if ((config->gpio == -ENODEV) || (config->gpio == -EPROBE_DEFER))
|
||||
return ERR_PTR(-EPROBE_DEFER);
|
||||
|
||||
delay = of_get_property(np, "startup-delay-us", NULL);
|
||||
if (delay)
|
||||
config->startup_delay = be32_to_cpu(*delay);
|
||||
of_property_read_u32(np, "startup-delay-us", &config->startup_delay);
|
||||
|
||||
if (of_find_property(np, "enable-active-high", NULL))
|
||||
config->enable_high = true;
|
||||
|
||||
if (of_find_property(np, "gpio-open-drain", NULL))
|
||||
config->gpio_is_open_drain = true;
|
||||
config->enable_high = of_property_read_bool(np, "enable-active-high");
|
||||
config->gpio_is_open_drain = of_property_read_bool(np,
|
||||
"gpio-open-drain");
|
||||
|
||||
if (of_find_property(np, "vin-supply", NULL))
|
||||
config->input_supply = "vin";
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user