Skip to content

Commit 2528eec

Browse files
abelvesalag-linaro
authored andcommitted
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: b00d2ed ("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>
1 parent b7881ea commit 2528eec

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

drivers/leds/rgb/leds-qcom-lpg.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -462,7 +462,7 @@ static int lpg_calc_freq(struct lpg_channel *chan, uint64_t period)
462462
max_res = LPG_RESOLUTION_9BIT;
463463
}
464464

465-
min_period = div64_u64((u64)NSEC_PER_SEC * (1 << pwm_resolution_arr[0]),
465+
min_period = div64_u64((u64)NSEC_PER_SEC * ((1 << pwm_resolution_arr[0]) - 1),
466466
clk_rate_arr[clk_len - 1]);
467467
if (period <= min_period)
468468
return -EINVAL;
@@ -483,7 +483,7 @@ static int lpg_calc_freq(struct lpg_channel *chan, uint64_t period)
483483
*/
484484

485485
for (i = 0; i < pwm_resolution_count; i++) {
486-
resolution = 1 << pwm_resolution_arr[i];
486+
resolution = (1 << pwm_resolution_arr[i]) - 1;
487487
for (clk_sel = 1; clk_sel < clk_len; clk_sel++) {
488488
u64 numerator = period * clk_rate_arr[clk_sel];
489489

@@ -1292,7 +1292,7 @@ static int lpg_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
12921292
if (ret)
12931293
return ret;
12941294

1295-
state->period = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * (1 << resolution) *
1295+
state->period = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * ((1 << resolution) - 1) *
12961296
pre_div * (1 << m), refclk);
12971297
state->duty_cycle = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * pwm_value * pre_div * (1 << m), refclk);
12981298
} else {

0 commit comments

Comments
 (0)