leds: rgb: leds-qcom-lpg: Fix calculation of best period Hi-Res PWMs
commit2528eec7daupstream. 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:b00d2ed376("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> Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
This commit is contained in:
committed by
Greg Kroah-Hartman
parent
5ae9e361e2
commit
4b037851ed
@@ -461,7 +461,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;
|
||||
@@ -482,7 +482,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];
|
||||
|
||||
@@ -1291,7 +1291,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 {
|
||||
|
||||
Reference in New Issue
Block a user