/* Default limits measured in millivolts and milliamps */ #define DA9211_MIN_MV 300 #define DA9211_MAX_MV 1570 #define DA9211_STEP_MV 10
/* Current limits for DA9211 buck (uA) indices * corresponds with register values
*/ staticconstint da9211_current_limits[] = {
2000000, 2200000, 2400000, 2600000, 2800000, 3000000, 3200000, 3400000,
3600000, 3800000, 4000000, 4200000, 4400000, 4600000, 4800000, 5000000
}; /* Current limits for DA9213 buck (uA) indices * corresponds with register values
*/ staticconstint da9213_current_limits[] = {
3000000, 3200000, 3400000, 3600000, 3800000, 4000000, 4200000, 4400000,
4600000, 4800000, 5000000, 5200000, 5400000, 5600000, 5800000, 6000000
}; /* Current limits for DA9215 buck (uA) indices * corresponds with register values
*/ staticconstint da9215_current_limits[] = {
4000000, 4200000, 4400000, 4600000, 4800000, 5000000, 5200000, 5400000,
5600000, 5800000, 6000000, 6200000, 6400000, 6600000, 6800000, 7000000
};
staticunsignedint da9211_map_buck_mode(unsignedint mode)
{ switch (mode) { case DA9211_BUCK_MODE_SLEEP: return REGULATOR_MODE_STANDBY; case DA9211_BUCK_MODE_SYNC: return REGULATOR_MODE_FAST; case DA9211_BUCK_MODE_AUTO: return REGULATOR_MODE_NORMAL; default: return REGULATOR_MODE_INVALID;
}
}
staticunsignedint da9211_buck_get_mode(struct regulator_dev *rdev)
{ int id = rdev_get_id(rdev); struct da9211 *chip = rdev_get_drvdata(rdev); unsignedint data; int ret, mode = 0;
ret = regmap_read(chip->regmap, DA9211_REG_BUCKA_CONF+id, &data); if (ret < 0) return ret;
switch (data & 0x03) { case DA9211_BUCK_MODE_SYNC:
mode = REGULATOR_MODE_FAST; break; case DA9211_BUCK_MODE_AUTO:
mode = REGULATOR_MODE_NORMAL; break; case DA9211_BUCK_MODE_SLEEP:
mode = REGULATOR_MODE_STANDBY; break;
}
return mode;
}
staticint da9211_buck_set_mode(struct regulator_dev *rdev, unsignedint mode)
{ int id = rdev_get_id(rdev); struct da9211 *chip = rdev_get_drvdata(rdev); int val = 0;
switch (mode) { case REGULATOR_MODE_FAST:
val = DA9211_BUCK_MODE_SYNC; break; case REGULATOR_MODE_NORMAL:
val = DA9211_BUCK_MODE_AUTO; break; case REGULATOR_MODE_STANDBY:
val = DA9211_BUCK_MODE_SLEEP; break;
}
staticint da9211_set_current_limit(struct regulator_dev *rdev, int min, int max)
{ int id = rdev_get_id(rdev); struct da9211 *chip = rdev_get_drvdata(rdev); int i, max_size; constint *current_limits;
/* search for closest to maximum */ for (i = max_size; i >= 0; i--) { if (min <= current_limits[i] &&
max >= current_limits[i]) { return regmap_update_bits(chip->regmap,
DA9211_REG_BUCK_ILIM,
(0x0F << id*4), (i << id*4));
}
}
return -EINVAL;
}
staticint da9211_get_current_limit(struct regulator_dev *rdev)
{ int id = rdev_get_id(rdev); struct da9211 *chip = rdev_get_drvdata(rdev); unsignedint data; int ret; constint *current_limits;
switch (chip->chip_id) { case DA9211:
current_limits = da9211_current_limits; break; case DA9213:
current_limits = da9213_current_limits; break; case DA9215:
current_limits = da9215_current_limits; break; default: return -EINVAL;
}
ret = regmap_read(chip->regmap, DA9211_REG_BUCK_ILIM, &data); if (ret < 0) return ret;
/* select one of 16 values: 0000 (2000mA or 3000mA) * to 1111 (5000mA or 6000mA).
*/
data = (data >> id*4) & 0x0F; return current_limits[data];
}
staticstruct da9211_pdata *da9211_parse_regulators_dt( struct device *dev)
{ struct da9211_pdata *pdata; struct device_node *node; int i, num, n;
node = of_get_child_by_name(dev->of_node, "regulators"); if (!node) {
dev_err(dev, "regulators node not found\n"); return ERR_PTR(-ENODEV);
}
num = of_regulator_match(dev, node, da9211_matches,
ARRAY_SIZE(da9211_matches));
of_node_put(node); if (num < 0) {
dev_err(dev, "Failed to match regulators\n"); return ERR_PTR(-EINVAL);
}
pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL); if (!pdata) return ERR_PTR(-ENOMEM);
pdata->num_buck = num;
n = 0; for (i = 0; i < ARRAY_SIZE(da9211_matches); i++) { if (!da9211_matches[i].init_data) continue;
staticint da9211_regulator_init(struct da9211 *chip)
{ struct regulator_config config = { }; int i, ret; unsignedint data;
ret = regmap_read(chip->regmap, DA9211_REG_CONFIG_E, &data); if (ret < 0) {
dev_err(chip->dev, "Failed to read CONFIG_E reg: %d\n", ret); return ret;
}
data &= DA9211_SLAVE_SEL; /* If configuration for 1/2 bucks is different between platform data * and the register, driver should exit.
*/ if (chip->pdata->num_buck == 1 && data == 0x00)
chip->num_regulator = 1; elseif (chip->pdata->num_buck == 2 && data != 0x00)
chip->num_regulator = 2; else {
dev_err(chip->dev, "Configuration is mismatched\n"); return -EINVAL;
}
for (i = 0; i < chip->num_regulator; i++) {
config.init_data = chip->pdata->init_data[i];
config.dev = chip->dev;
config.driver_data = chip;
config.regmap = chip->regmap;
config.of_node = chip->pdata->reg_node[i];
if (chip->pdata->gpiod_ren[i])
config.ena_gpiod = chip->pdata->gpiod_ren[i]; else
config.ena_gpiod = NULL;
/* * Hand the GPIO descriptor management over to the regulator * core, remove it from GPIO devres management.
*/ if (config.ena_gpiod)
devm_gpiod_unhinge(chip->dev, config.ena_gpiod);
chip->rdev[i] = devm_regulator_register(chip->dev,
&da9211_regulators[i], &config); if (IS_ERR(chip->rdev[i])) {
dev_err(chip->dev, "Failed to register DA9211 regulator\n"); return PTR_ERR(chip->rdev[i]);
}
if (chip->chip_irq != 0) {
ret = regmap_update_bits(chip->regmap,
DA9211_REG_MASK_B, DA9211_M_OV_CURR_A << i, 0); if (ret < 0) {
dev_err(chip->dev, "Failed to update mask reg: %d\n", ret); return ret;
}
}
}
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.