mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/
synced 2025-04-19 20:58:31 +09:00
leds: rgb: leds-qcom-lpg: Fix calculation of best period Hi-Res PWMs
When determining the actual best period by looping through all possible PWM configs, the resolution currently used is based on bit shift value which is off-by-one above the possible maximum PWM value allowed. So subtract one from the resolution before determining the best period so that the maximum duty cycle requested by the PWM user won't result in a value above the maximum allowed by the selected resolution. Cc: stable@vger.kernel.org # 6.4 Fixes: b00d2ed37617 ("leds: rgb: leds-qcom-lpg: Add support for high resolution PWM") Signed-off-by: Abel Vesa <abel.vesa@linaro.org> Reviewed-by: Sebastian Reichel <sre@kernel.org> Link: https://lore.kernel.org/r/20250305-leds-qcom-lpg-fix-max-pwm-on-hi-res-v4-3-bfe124a53a9f@linaro.org Signed-off-by: Lee Jones <lee@kernel.org>
This commit is contained in:
parent
b7881eacc0
commit
2528eec7da
@ -462,7 +462,7 @@ static int lpg_calc_freq(struct lpg_channel *chan, uint64_t period)
|
||||
max_res = LPG_RESOLUTION_9BIT;
|
||||
}
|
||||
|
||||
min_period = div64_u64((u64)NSEC_PER_SEC * (1 << pwm_resolution_arr[0]),
|
||||
min_period = div64_u64((u64)NSEC_PER_SEC * ((1 << pwm_resolution_arr[0]) - 1),
|
||||
clk_rate_arr[clk_len - 1]);
|
||||
if (period <= min_period)
|
||||
return -EINVAL;
|
||||
@ -483,7 +483,7 @@ static int lpg_calc_freq(struct lpg_channel *chan, uint64_t period)
|
||||
*/
|
||||
|
||||
for (i = 0; i < pwm_resolution_count; i++) {
|
||||
resolution = 1 << pwm_resolution_arr[i];
|
||||
resolution = (1 << pwm_resolution_arr[i]) - 1;
|
||||
for (clk_sel = 1; clk_sel < clk_len; clk_sel++) {
|
||||
u64 numerator = period * clk_rate_arr[clk_sel];
|
||||
|
||||
@ -1292,7 +1292,7 @@ static int lpg_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
state->period = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * (1 << resolution) *
|
||||
state->period = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * ((1 << resolution) - 1) *
|
||||
pre_div * (1 << m), refclk);
|
||||
state->duty_cycle = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * pwm_value * pre_div * (1 << m), refclk);
|
||||
} else {
|
||||
|
Loading…
x
Reference in New Issue
Block a user