if (!pstate.enabled) { if (pstate.polarity == PWM_POLARITY_INVERSED)
pstate.duty_cycle = pstate.period; else
pstate.duty_cycle = 0;
}
voltage = pwm_get_relative_duty_cycle(&pstate, duty_unit); if (voltage < min(max_uV_duty, min_uV_duty) ||
voltage > max(max_uV_duty, min_uV_duty)) return -ENOTRECOVERABLE;
/* * The dutycycle for min_uV might be greater than the one for max_uV. * This is happening when the user needs an inversed polarity, but the * PWM device does not support inversing it in hardware.
*/ if (max_uV_duty < min_uV_duty) {
voltage = min_uV_duty - voltage;
diff_duty = min_uV_duty - max_uV_duty;
} else {
voltage = voltage - min_uV_duty;
diff_duty = max_uV_duty - min_uV_duty;
}
voltage = DIV_ROUND_CLOSEST_ULL((u64)voltage * diff_uV, diff_duty);
return voltage + min_uV;
}
staticint pwm_regulator_set_voltage(struct regulator_dev *rdev, int req_min_uV, int req_max_uV, unsignedint *selector)
{ struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev); unsignedint min_uV_duty = drvdata->continuous.min_uV_dutycycle; unsignedint max_uV_duty = drvdata->continuous.max_uV_dutycycle; unsignedint duty_unit = drvdata->continuous.dutycycle_unit; int min_uV = rdev->constraints->min_uV; int max_uV = rdev->constraints->max_uV; int diff_uV = max_uV - min_uV; struct pwm_state pstate; unsignedint diff_duty; unsignedint dutycycle; int ret;
pwm_init_state(drvdata->pwm, &pstate);
/* * The dutycycle for min_uV might be greater than the one for max_uV. * This is happening when the user needs an inversed polarity, but the * PWM device does not support inversing it in hardware.
*/ if (max_uV_duty < min_uV_duty)
diff_duty = min_uV_duty - max_uV_duty; else
diff_duty = max_uV_duty - min_uV_duty;
if (!init_data->constraints.boot_on || drvdata->enb_gpio) return 0;
pwm_get_state(drvdata->pwm, &pstate); if (pstate.enabled) return 0;
/* * Update the duty cycle so the output does not change * when the regulator core enables the regulator (and * thus the PWM channel).
*/ if (pstate.polarity == PWM_POLARITY_INVERSED)
pstate.duty_cycle = pstate.period; else
pstate.duty_cycle = 0;
if (of_property_present(np, "voltage-table"))
ret = pwm_regulator_init_table(pdev, drvdata); else
ret = pwm_regulator_init_continuous(pdev, drvdata); if (ret) return ret;
init_data = of_get_regulator_init_data(&pdev->dev, np,
&drvdata->desc); if (!init_data) return -ENOMEM;
drvdata->pwm = devm_pwm_get(&pdev->dev, NULL); if (IS_ERR(drvdata->pwm)) return dev_err_probe(&pdev->dev, PTR_ERR(drvdata->pwm), "Failed to get PWM\n");
if (init_data->constraints.boot_on || init_data->constraints.always_on)
gpio_flags = GPIOD_OUT_HIGH; else
gpio_flags = GPIOD_OUT_LOW;
drvdata->enb_gpio = devm_gpiod_get_optional(&pdev->dev, "enable",
gpio_flags); if (IS_ERR(drvdata->enb_gpio)) {
ret = PTR_ERR(drvdata->enb_gpio); return dev_err_probe(&pdev->dev, ret, "Failed to get enable GPIO\n");
}
ret = pwm_adjust_config(drvdata->pwm); if (ret) return ret;
ret = pwm_regulator_init_boot_on(pdev, drvdata, init_data); if (ret) return dev_err_probe(&pdev->dev, ret, "Failed to apply boot_on settings\n");
regulator = devm_regulator_register(&pdev->dev,
&drvdata->desc, &config); if (IS_ERR(regulator)) {
ret = PTR_ERR(regulator); return dev_err_probe(&pdev->dev, ret, "Failed to register regulator %s\n",
drvdata->desc.name);
}
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.