/* BCORE1 and BCORE2 in merged mode */
DA9063_ID_BCORES_MERGED, /* BMEM and BIO in merged mode */
DA9063_ID_BMEM_BIO_MERGED, /* When two BUCKs are merged, they cannot be reused separately */
/* LDOs on both DA9063 and DA9063L */
DA9063_ID_LDO3,
DA9063_ID_LDO7,
DA9063_ID_LDO8,
DA9063_ID_LDO9,
DA9063_ID_LDO11,
/* Encapsulates all information for the regulators driver */ struct da9063_regulators { unsignedint n_regulators; /* Array size to be defined during init. Keep at end. */ struct da9063_regulator regulator[] __counted_by(n_regulators);
};
/* * only support enable and disable. * the da9063 offers a GPIO (GP_FB2) which is unasserted if an XV happens. * therefore ignore severity here, as there might be handlers in hardware.
*/ if (lim_uV) return -EINVAL;
switch (mode) { case REGULATOR_MODE_FAST:
val = BUCK_MODE_SYNC; break; case REGULATOR_MODE_NORMAL:
val = BUCK_MODE_AUTO; break; case REGULATOR_MODE_STANDBY:
val = BUCK_MODE_SLEEP; break; default: return -EINVAL;
}
return regmap_field_write(regl->mode, val);
}
/* * Bucks use single mode register field for normal operation * and suspend state. * There are 3 modes to map to: FAST, NORMAL, and STANDBY.
*/
ret = regmap_field_read(regl->mode, &val); if (ret < 0) return ret;
switch (val) { default: case BUCK_MODE_MANUAL: /* Sleep flag bit decides the mode */ break; case BUCK_MODE_SLEEP: return REGULATOR_MODE_STANDBY; case BUCK_MODE_SYNC: return REGULATOR_MODE_FAST; case BUCK_MODE_AUTO: return REGULATOR_MODE_NORMAL;
}
ret = regmap_field_read(regl->sleep, &val); if (ret < 0) return 0;
if (val) return REGULATOR_MODE_STANDBY; else return REGULATOR_MODE_FAST;
}
/* * LDOs use sleep flags - one for normal and one for suspend state. * There are 2 modes to map to: NORMAL and STANDBY (sleep) for each state.
*/
switch (mode) { case REGULATOR_MODE_FAST:
val = BUCK_MODE_SYNC; break; case REGULATOR_MODE_NORMAL:
val = BUCK_MODE_AUTO; break; case REGULATOR_MODE_STANDBY:
val = BUCK_MODE_SLEEP; break; default: return -EINVAL;
}
staticunsignedint da9063_get_overdrive_mask(conststruct regulator_desc *desc)
{ switch (desc->id) { case DA9063_ID_BCORES_MERGED: case DA9063_ID_BCORE1: return DA9063_BCORE1_OD; case DA9063_ID_BCORE2: return DA9063_BCORE2_OD; case DA9063_ID_BPRO: return DA9063_BPRO_OD; default: return 0;
}
}
staticint da9063_buck_set_limit_set_overdrive(struct regulator_dev *rdev, int min_uA, int max_uA, unsignedint overdrive_mask)
{ /* * When enabling overdrive, do it before changing the current limit to * ensure sufficient supply throughout the switch.
*/ struct da9063_regulator *regl = rdev_get_drvdata(rdev); int ret; unsignedint orig_overdrive;
ret = regmap_read(regl->hw->regmap, DA9063_REG_CONFIG_H,
&orig_overdrive); if (ret < 0) return ret;
orig_overdrive &= overdrive_mask;
if (orig_overdrive == 0) {
ret = regmap_set_bits(regl->hw->regmap, DA9063_REG_CONFIG_H,
overdrive_mask); if (ret < 0) return ret;
}
ret = regulator_set_current_limit_regmap(rdev, min_uA / 2, max_uA / 2); if (ret < 0 && orig_overdrive == 0) /* * regulator_set_current_limit_regmap may have rejected the * change because of unusable min_uA and/or max_uA inputs. * Attempt to restore original overdrive state, ignore failure- * on-failure.
*/
regmap_clear_bits(regl->hw->regmap, DA9063_REG_CONFIG_H,
overdrive_mask);
return ret;
}
staticint da9063_buck_set_limit_clear_overdrive(struct regulator_dev *rdev, int min_uA, int max_uA, unsignedint overdrive_mask)
{ /* * When disabling overdrive, do it after changing the current limit to * ensure sufficient supply throughout the switch.
*/ struct da9063_regulator *regl = rdev_get_drvdata(rdev); int ret, orig_limit;
ret = regmap_read(rdev->regmap, rdev->desc->csel_reg, &orig_limit); if (ret < 0) return ret;
ret = regulator_set_current_limit_regmap(rdev, min_uA, max_uA); if (ret < 0) return ret;
ret = regmap_clear_bits(regl->hw->regmap, DA9063_REG_CONFIG_H,
overdrive_mask); if (ret < 0) /* * Attempt to restore original current limit, ignore failure- * on-failure.
*/
regmap_write(rdev->regmap, rdev->desc->csel_reg, orig_limit);
return ret;
}
staticint da9063_buck_set_current_limit(struct regulator_dev *rdev, int min_uA, int max_uA)
{ unsignedint overdrive_mask, n_currents;
overdrive_mask = da9063_get_overdrive_mask(rdev->desc); if (overdrive_mask) {
n_currents = rdev->desc->n_current_limits; if (n_currents == 0) return -EINVAL;
/* make sure that only one severity is used to clarify if unchanged, enabled or disabled */ if ((!!uv_l->prot + !!uv_l->err + !!uv_l->warn) > 1) {
dev_err(config->dev, "%s: at most one voltage monitoring severity allowed!\n",
regl->desc.name); return -EINVAL;
}
/* make sure that UV and OV monitoring is set to the same severity and value */ if (uv_l->prot != ov_l->prot) {
dev_err(config->dev, "%s: protection-microvolt: value must be equal for uv and ov!\n",
regl->desc.name); return -EINVAL;
} if (uv_l->err != ov_l->err) {
dev_err(config->dev, "%s: error-microvolt: value must be equal for uv and ov!\n",
regl->desc.name); return -EINVAL;
} if (uv_l->warn != ov_l->warn) {
dev_err(config->dev, "%s: warn-microvolt: value must be equal for uv and ov!\n",
regl->desc.name); return -EINVAL;
}
staticstruct da9063_regulators_pdata *da9063_parse_regulators_dt( struct platform_device *pdev, struct of_regulator_match **da9063_reg_matches)
{ struct da9063 *da9063 = dev_get_drvdata(pdev->dev.parent); struct da9063_regulators_pdata *pdata; struct da9063_regulator_data *rdata; struct device_node *node; int da9063_matches_len = ARRAY_SIZE(da9063_matches); int i, n, num;
if (da9063->type == PMIC_TYPE_DA9063L)
da9063_matches_len -= 6;
node = of_get_child_by_name(pdev->dev.parent->of_node, "regulators"); if (!node) {
dev_err(&pdev->dev, "Regulators device node not found\n"); return ERR_PTR(-ENODEV);
}
num = of_regulator_match(&pdev->dev, node, da9063_matches,
da9063_matches_len);
of_node_put(node); if (num < 0) {
dev_err(&pdev->dev, "Failed to match regulators\n"); return ERR_PTR(-EINVAL);
}
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return ERR_PTR(-ENOMEM);
if (IS_ERR(regl_pdata) || regl_pdata->n_regulators == 0) {
dev_err(&pdev->dev, "No regulators defined for the platform\n"); return -ENODEV;
}
/* Find regulators set for particular device model */ for (model = regulators_models; model->regulator_info; model++) { if (model->type == da9063->type) break;
} if (!model->regulator_info) {
dev_err(&pdev->dev, "Chip model not recognised (%u)\n",
da9063->type); return -ENODEV;
}
ret = regmap_read(da9063->regmap, DA9063_REG_CONFIG_H, &val); if (ret < 0) {
dev_err(&pdev->dev, "Error while reading BUCKs configuration\n"); return ret;
}
bcores_merged = val & DA9063_BCORE_MERGE;
bmem_bio_merged = val & DA9063_BUCK_MERGE;
/* Register all regulators declared in platform information */
n = 0;
id = 0; while (n < regulators->n_regulators) { /* Skip regulator IDs depending on merge mode configuration */ switch (id) { case DA9063_ID_BCORE1: case DA9063_ID_BCORE2: if (bcores_merged) {
id++; continue;
} break; case DA9063_ID_BMEM: case DA9063_ID_BIO: if (bmem_bio_merged) {
id++; continue;
} break; case DA9063_ID_BCORES_MERGED: if (!bcores_merged) {
id++; continue;
} break; case DA9063_ID_BMEM_BIO_MERGED: if (!bmem_bio_merged) {
id++; continue;
} break;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.