From: Mark Brown Date: Tue, 3 May 2016 14:09:56 +0000 (+0100) Subject: Merge branch 'for-4.7/pwm-regulator' of git://git.kernel.org/pub/scm/linux/kernel... X-Git-Tag: v4.14-rc1~3240^2~2^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bc0868c62bb13834b20a864f684cced1f84a2412;p=platform%2Fkernel%2Flinux-rpi.git Merge branch 'for-4.7/pwm-regulator' of git://git./linux/kernel/git/thierry.reding/linux-pwm into regulator-pwm --- bc0868c62bb13834b20a864f684cced1f84a2412 diff --cc drivers/regulator/pwm-regulator.c index 8e928f2,ffdb895..fafa348 --- a/drivers/regulator/pwm-regulator.c +++ b/drivers/regulator/pwm-regulator.c @@@ -63,14 -63,14 +63,14 @@@ static int pwm_regulator_set_voltage_se int dutycycle; int ret; - pwm_reg_period = pwm_get_period(drvdata->pwm); + pwm_get_args(drvdata->pwm, &pargs); - dutycycle = (pwm_reg_period * + dutycycle = (pargs.period * drvdata->duty_cycle_table[selector].dutycycle) / 100; - ret = pwm_config(drvdata->pwm, dutycycle, pwm_reg_period); + ret = pwm_config(drvdata->pwm, dutycycle, pargs.period); if (ret) { - dev_err(&rdev->dev, "Failed to configure PWM\n"); + dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret); return ret; } @@@ -126,35 -138,17 +126,36 @@@ static int pwm_regulator_set_voltage(st { struct pwm_regulator_data *drvdata = rdev_get_drvdata(rdev); unsigned int ramp_delay = rdev->constraints->ramp_delay; - unsigned int period = pwm_get_period(drvdata->pwm); + struct pwm_args pargs; - int duty_cycle; + unsigned int req_diff = min_uV - rdev->constraints->min_uV; + unsigned int diff; + unsigned int duty_pulse; + u64 req_period; + u32 rem; int ret; + pwm_get_args(drvdata->pwm, &pargs); - duty_cycle = pwm_voltage_to_duty_cycle_percentage(rdev, min_uV); + diff = rdev->constraints->max_uV - rdev->constraints->min_uV; + + /* First try to find out if we get the iduty cycle time which is + * factor of PWM period time. If (request_diff_to_min * pwm_period) + * is perfect divided by voltage_range_diff then it is possible to + * get duty cycle time which is factor of PWM period. This will help + * to get output voltage nearer to requested value as there is no + * calculation loss. + */ - req_period = req_diff * period; ++ req_period = req_diff * pargs.period; + div_u64_rem(req_period, diff, &rem); + if (!rem) { + do_div(req_period, diff); + duty_pulse = (unsigned int)req_period; + } else { - duty_pulse = (period / 100) * ((req_diff * 100) / diff); ++ duty_pulse = (pargs.period / 100) * ((req_diff * 100) / diff); + } - ret = pwm_config(drvdata->pwm, duty_pulse, period); - ret = pwm_config(drvdata->pwm, (pargs.period / 100) * duty_cycle, - pargs.period); ++ ret = pwm_config(drvdata->pwm, duty_pulse, pargs.period); if (ret) { - dev_err(&rdev->dev, "Failed to configure PWM\n"); + dev_err(&rdev->dev, "Failed to configure PWM: %d\n", ret); return ret; } @@@ -284,11 -279,16 +285,17 @@@ static int pwm_regulator_probe(struct p drvdata->pwm = devm_pwm_get(&pdev->dev, NULL); if (IS_ERR(drvdata->pwm)) { - dev_err(&pdev->dev, "Failed to get PWM\n"); - return PTR_ERR(drvdata->pwm); + ret = PTR_ERR(drvdata->pwm); + dev_err(&pdev->dev, "Failed to get PWM: %d\n", ret); + return ret; } + /* + * FIXME: pwm_apply_args() should be removed when switching to the + * atomic PWM API. + */ + pwm_apply_args(drvdata->pwm); + regulator = devm_regulator_register(&pdev->dev, &drvdata->desc, &config); if (IS_ERR(regulator)) {