aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/staging/hikey9xx/hi6421v600-regulator.c69
1 files changed, 42 insertions, 27 deletions
diff --git a/drivers/staging/hikey9xx/hi6421v600-regulator.c b/drivers/staging/hikey9xx/hi6421v600-regulator.c
index 21467fce9980..72f51594b5ff 100644
--- a/drivers/staging/hikey9xx/hi6421v600-regulator.c
+++ b/drivers/staging/hikey9xx/hi6421v600-regulator.c
@@ -45,8 +45,7 @@
struct hi6421v600_regulator {
struct regulator_desc rdesc;
struct hi6421_spmi_pmic *pmic;
- u8 eco_mode_mask;
- u32 eco_uA;
+ u32 eco_mode_mask, eco_uA;
};
static DEFINE_MUTEX(enable_mutex);
@@ -226,36 +225,49 @@ static int hi6421_spmi_dt_parse(struct platform_device *pdev,
{
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
- unsigned int register_info[3] = {0};
unsigned int *v_table;
int ret;
- /* parse .register_info.enable_reg */
- ret = of_property_read_u32_array(np, "hi6421-ctrl",
- register_info, 3);
+ ret = of_property_read_u32(np, "reg", &rdesc->enable_reg);
if (ret) {
- dev_err(dev, "no hi6421-ctrl property set\n");
+ dev_err(dev, "missing reg property\nn");
return ret;
}
- rdesc->enable_reg = register_info[0];
- rdesc->enable_mask = register_info[1];
- sreg->eco_mode_mask = register_info[2];
- /* parse .register_info.vsel_reg */
- ret = of_property_read_u32_array(np, "hi6421-vsel",
- register_info, 2);
+ ret = of_property_read_u32(np, "vsel-reg", &rdesc->vsel_reg);
if (ret) {
- dev_err(dev, "no hi6421-vsel property set\n");
+ dev_err(dev, "missing vsel-reg property\n");
return ret;
}
- rdesc->vsel_reg = register_info[0];
- rdesc->vsel_mask = register_info[1];
+
+ ret = of_property_read_u32(np, "enable-mask", &rdesc->enable_mask);
+ if (ret) {
+ dev_err(dev, "missing enable-mask property\n");
+ return ret;
+ }
+
+ /*
+ * Not all regulators work on idle mode
+ */
+ ret = of_property_read_u32(np, "idle-mode-mask", &sreg->eco_mode_mask);
+ if (ret) {
+ dev_dbg(dev, "LDO doesn't support economy mode.\n");
+ sreg->eco_mode_mask = 0;
+ sreg->eco_uA = 0;
+ } else {
+ ret = of_property_read_u32(np, "eco-microamp",
+ &sreg->eco_uA);
+ if (ret) {
+ dev_err(dev, "missing eco-microamp property\n");
+ return ret;
+ }
+ }
/* parse .off-on-delay */
ret = of_property_read_u32(np, "off-on-delay-us",
&rdesc->off_on_delay);
if (ret) {
- dev_err(dev, "no off-on-delay-us property set\n");
+ dev_err(dev, "missing off-on-delay-us property\n");
return ret;
}
@@ -263,21 +275,13 @@ static int hi6421_spmi_dt_parse(struct platform_device *pdev,
ret = of_property_read_u32(np, "startup-delay-us",
&rdesc->enable_time);
if (ret) {
- dev_err(dev, "no startup-delay-us property set\n");
+ dev_err(dev, "missing startup-delay-us property\n");
return ret;
}
/* FIXME: are there a better value for this? */
rdesc->ramp_delay = rdesc->enable_time;
- /* parse .eco_uA */
- ret = of_property_read_u32(np, "eco-microamp",
- &sreg->eco_uA);
- if (ret) {
- sreg->eco_uA = 0;
- ret = 0;
- }
-
/* parse volt_table */
rdesc->n_voltages = of_property_count_u32_elems(np, "voltage-table");
@@ -291,10 +295,21 @@ static int hi6421_spmi_dt_parse(struct platform_device *pdev,
ret = of_property_read_u32_array(np, "voltage-table",
v_table, rdesc->n_voltages);
if (ret) {
- dev_err(dev, "no voltage-table property set\n");
+ dev_err(dev, "missing voltage-table property\n");
return ret;
}
+ /*
+ * Instead of explicitly requiring a mask for the voltage selector,
+ * as they all start from bit zero (at least on the known LDOs),
+ * just use the number of voltages at the voltage table, getting the
+ * minimal mask that would pick everything.
+ */
+ rdesc->vsel_mask = (1 << (fls(rdesc->n_voltages) - 1)) - 1;
+
+ dev_dbg(dev, "voltage selector settings: reg: 0x%x, mask: 0x%x",
+ rdesc->vsel_reg, rdesc->vsel_mask);
+
return 0;
}