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);
{
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;
}
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");
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;
}