summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/devicetree/bindings/mfd/axp20x.txt6
-rw-r--r--drivers/regulator/axp20x-regulator.c30
2 files changed, 36 insertions, 0 deletions
diff --git a/Documentation/devicetree/bindings/mfd/axp20x.txt b/Documentation/devicetree/bindings/mfd/axp20x.txt
index d20b1034e967..585a95546288 100644
--- a/Documentation/devicetree/bindings/mfd/axp20x.txt
+++ b/Documentation/devicetree/bindings/mfd/axp20x.txt
@@ -22,6 +22,11 @@ Optional properties:
AXP152/20X: range: 750-1875, Default: 1.5 MHz
AXP22X/80X: range: 1800-4050, Default: 3 MHz
+- x-powers,drive-vbus-en: axp221 / axp223 only boolean, set this when the
+ N_VBUSEN pin is used as an output pin to control an external
+ regulator to drive the OTG VBus, rather then as an input pin
+ which signals whether the board is driving OTG VBus or not.
+
- <input>-supply: a phandle to the regulator supply node. May be omitted if
inputs are unregulated, such as using the IPSOUT output
from the PMIC.
@@ -79,6 +84,7 @@ ELDO3 : LDO : eldoin-supply : shared supply
LDO_IO0 : LDO : ips-supply : GPIO 0
LDO_IO1 : LDO : ips-supply : GPIO 1
RTC_LDO : LDO : ips-supply : always on
+DRIVEVBUS : Enable output : drivevbus-supply : external regulator
AXP809 regulators, type, and corresponding input supply names:
diff --git a/drivers/regulator/axp20x-regulator.c b/drivers/regulator/axp20x-regulator.c
index 728be64e817a..6d9ac76a772f 100644
--- a/drivers/regulator/axp20x-regulator.c
+++ b/drivers/regulator/axp20x-regulator.c
@@ -36,6 +36,8 @@
#define AXP20X_FREQ_DCDC_MASK 0x0f
+#define AXP22X_MISC_N_VBUSEN_FUNC BIT(4)
+
#define AXP_DESC_IO(_family, _id, _match, _supply, _min, _max, _step, _vreg, \
_vmask, _ereg, _emask, _enable_val, _disable_val) \
[_family##_##_id] = { \
@@ -230,6 +232,18 @@ static const struct regulator_desc axp22x_regulators[] = {
AXP_DESC_FIXED(AXP22X, RTC_LDO, "rtc_ldo", "ips", 3000),
};
+static const struct regulator_desc axp22x_drivevbus_regulator = {
+ .name = "drivevbus",
+ .supply_name = "drivevbus",
+ .of_match = of_match_ptr("drivevbus"),
+ .regulators_node = of_match_ptr("regulators"),
+ .type = REGULATOR_VOLTAGE,
+ .owner = THIS_MODULE,
+ .enable_reg = AXP20X_VBUS_IPSOUT_MGMT,
+ .enable_mask = BIT(2),
+ .ops = &axp20x_ops_sw,
+};
+
static const struct regulator_linear_range axp809_dcdc4_ranges[] = {
REGULATOR_LINEAR_RANGE(600000, 0x0, 0x2f, 20000),
REGULATOR_LINEAR_RANGE(1800000, 0x30, 0x38, 100000),
@@ -411,6 +425,7 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
u32 workmode;
const char *dcdc1_name = axp22x_regulators[AXP22X_DCDC1].name;
const char *dcdc5_name = axp22x_regulators[AXP22X_DCDC5].name;
+ bool drivevbus = false;
switch (axp20x->variant) {
case AXP202_ID:
@@ -422,6 +437,8 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
case AXP223_ID:
regulators = axp22x_regulators;
nregulators = AXP22X_REG_ID_MAX;
+ drivevbus = of_property_read_bool(pdev->dev.parent->of_node,
+ "x-powers,drive-vbus-en");
break;
case AXP809_ID:
regulators = axp809_regulators;
@@ -500,6 +517,19 @@ static int axp20x_regulator_probe(struct platform_device *pdev)
&dcdc5_name);
}
+ if (drivevbus) {
+ /* Change N_VBUSEN sense pin to DRIVEVBUS output pin */
+ regmap_update_bits(axp20x->regmap, AXP20X_OVER_TMP,
+ AXP22X_MISC_N_VBUSEN_FUNC, 0);
+ rdev = devm_regulator_register(&pdev->dev,
+ &axp22x_drivevbus_regulator,
+ &config);
+ if (IS_ERR(rdev)) {
+ dev_err(&pdev->dev, "Failed to register drivevbus\n");
+ return PTR_ERR(rdev);
+ }
+ }
+
return 0;
}