|
@@ -35,6 +35,7 @@
|
|
#define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* cycle based on 24M OSC */
|
|
#define LDO_RAMP_UP_FREQ_IN_MHZ 24 /* cycle based on 24M OSC */
|
|
|
|
|
|
#define LDO_POWER_GATE 0x00
|
|
#define LDO_POWER_GATE 0x00
|
|
|
|
+#define LDO_FET_FULL_ON 0x1f
|
|
|
|
|
|
struct anatop_regulator {
|
|
struct anatop_regulator {
|
|
const char *name;
|
|
const char *name;
|
|
@@ -50,6 +51,7 @@ struct anatop_regulator {
|
|
int max_voltage;
|
|
int max_voltage;
|
|
struct regulator_desc rdesc;
|
|
struct regulator_desc rdesc;
|
|
struct regulator_init_data *initdata;
|
|
struct regulator_init_data *initdata;
|
|
|
|
+ bool bypass;
|
|
int sel;
|
|
int sel;
|
|
};
|
|
};
|
|
|
|
|
|
@@ -103,8 +105,10 @@ static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg)
|
|
static int anatop_regmap_enable(struct regulator_dev *reg)
|
|
static int anatop_regmap_enable(struct regulator_dev *reg)
|
|
{
|
|
{
|
|
struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
|
|
struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
|
|
|
|
+ int sel;
|
|
|
|
|
|
- return regulator_set_voltage_sel_regmap(reg, anatop_reg->sel);
|
|
|
|
|
|
+ sel = anatop_reg->bypass ? LDO_FET_FULL_ON : anatop_reg->sel;
|
|
|
|
+ return regulator_set_voltage_sel_regmap(reg, sel);
|
|
}
|
|
}
|
|
|
|
|
|
static int anatop_regmap_disable(struct regulator_dev *reg)
|
|
static int anatop_regmap_disable(struct regulator_dev *reg)
|
|
@@ -123,7 +127,7 @@ static int anatop_regmap_core_set_voltage_sel(struct regulator_dev *reg,
|
|
struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
|
|
struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
|
|
int ret;
|
|
int ret;
|
|
|
|
|
|
- if (!anatop_regmap_is_enabled(reg)) {
|
|
|
|
|
|
+ if (anatop_reg->bypass || !anatop_regmap_is_enabled(reg)) {
|
|
anatop_reg->sel = selector;
|
|
anatop_reg->sel = selector;
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
@@ -138,12 +142,41 @@ static int anatop_regmap_core_get_voltage_sel(struct regulator_dev *reg)
|
|
{
|
|
{
|
|
struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
|
|
struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
|
|
|
|
|
|
- if (!anatop_regmap_is_enabled(reg))
|
|
|
|
|
|
+ if (anatop_reg->bypass || !anatop_regmap_is_enabled(reg))
|
|
return anatop_reg->sel;
|
|
return anatop_reg->sel;
|
|
|
|
|
|
return regulator_get_voltage_sel_regmap(reg);
|
|
return regulator_get_voltage_sel_regmap(reg);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+static int anatop_regmap_get_bypass(struct regulator_dev *reg, bool *enable)
|
|
|
|
+{
|
|
|
|
+ struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
|
|
|
|
+ int sel;
|
|
|
|
+
|
|
|
|
+ sel = regulator_get_voltage_sel_regmap(reg);
|
|
|
|
+ if (sel == LDO_FET_FULL_ON)
|
|
|
|
+ WARN_ON(!anatop_reg->bypass);
|
|
|
|
+ else if (sel != LDO_POWER_GATE)
|
|
|
|
+ WARN_ON(anatop_reg->bypass);
|
|
|
|
+
|
|
|
|
+ *enable = anatop_reg->bypass;
|
|
|
|
+ return 0;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+static int anatop_regmap_set_bypass(struct regulator_dev *reg, bool enable)
|
|
|
|
+{
|
|
|
|
+ struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
|
|
|
|
+ int sel;
|
|
|
|
+
|
|
|
|
+ if (enable == anatop_reg->bypass)
|
|
|
|
+ return 0;
|
|
|
|
+
|
|
|
|
+ sel = enable ? LDO_FET_FULL_ON : anatop_reg->sel;
|
|
|
|
+ anatop_reg->bypass = enable;
|
|
|
|
+
|
|
|
|
+ return regulator_set_voltage_sel_regmap(reg, sel);
|
|
|
|
+}
|
|
|
|
+
|
|
static struct regulator_ops anatop_rops = {
|
|
static struct regulator_ops anatop_rops = {
|
|
.set_voltage_sel = anatop_regmap_set_voltage_sel,
|
|
.set_voltage_sel = anatop_regmap_set_voltage_sel,
|
|
.get_voltage_sel = anatop_regmap_get_voltage_sel,
|
|
.get_voltage_sel = anatop_regmap_get_voltage_sel,
|
|
@@ -160,6 +193,8 @@ static struct regulator_ops anatop_core_rops = {
|
|
.get_voltage_sel = anatop_regmap_core_get_voltage_sel,
|
|
.get_voltage_sel = anatop_regmap_core_get_voltage_sel,
|
|
.list_voltage = regulator_list_voltage_linear,
|
|
.list_voltage = regulator_list_voltage_linear,
|
|
.map_voltage = regulator_map_voltage_linear,
|
|
.map_voltage = regulator_map_voltage_linear,
|
|
|
|
+ .get_bypass = anatop_regmap_get_bypass,
|
|
|
|
+ .set_bypass = anatop_regmap_set_bypass,
|
|
};
|
|
};
|
|
|
|
|
|
static int anatop_regulator_probe(struct platform_device *pdev)
|
|
static int anatop_regulator_probe(struct platform_device *pdev)
|
|
@@ -265,6 +300,10 @@ static int anatop_regulator_probe(struct platform_device *pdev)
|
|
}
|
|
}
|
|
|
|
|
|
sreg->sel = (val & rdesc->vsel_mask) >> sreg->vol_bit_shift;
|
|
sreg->sel = (val & rdesc->vsel_mask) >> sreg->vol_bit_shift;
|
|
|
|
+ if (sreg->sel == LDO_FET_FULL_ON) {
|
|
|
|
+ sreg->sel = 0;
|
|
|
|
+ sreg->bypass = true;
|
|
|
|
+ }
|
|
} else {
|
|
} else {
|
|
rdesc->ops = &anatop_rops;
|
|
rdesc->ops = &anatop_rops;
|
|
}
|
|
}
|