Re: [PATCH RFC] leds: rgb: leds-qcom-lpg: Compute PWM value based on period instead

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi,

On Mon, Mar 03, 2025 at 06:14:36PM +0200, Abel Vesa wrote:
> Currently, the implementation computes the best matched period based
> on the requested one, by looping through all possible register
> configurations. The best matched period is below the requested period.
> This means the PWM consumer could request duty cycle values between
> the best matched period and the requested period, which with the current
> implementation for computing the PWM value, it will result in values out
> of range with respect to the selected resolution.
> 
> So change the way the PWM value is determined as a ratio between the
> requested period and duty cycle, mapped on the resolution interval.
> Do this in contrast to using the register configuration selected when
> the best matching period was determined.
> 
> Signed-off-by: Abel Vesa <abel.vesa@xxxxxxxxxx>
> ---
> This patch is based on the following patchset:
> https://lore.kernel.org/all/20250303-leds-qcom-lpg-fix-max-pwm-on-hi-res-v3-0-62703c0ab76a@xxxxxxxxxx/
> ---

Tested-by: Sebastian Reichel <sre@xxxxxxxxxx>

Greetings,

-- Sebastian

>  drivers/leds/rgb/leds-qcom-lpg.c | 16 ++++++++++------
>  1 file changed, 10 insertions(+), 6 deletions(-)
> 
> diff --git a/drivers/leds/rgb/leds-qcom-lpg.c b/drivers/leds/rgb/leds-qcom-lpg.c
> index 4f2a178e3d265a2cc88e651d3e2ca6ae3dfac2e2..80130c205dce7c6ae1c356b7a7c5f6460a2b0bb0 100644
> --- a/drivers/leds/rgb/leds-qcom-lpg.c
> +++ b/drivers/leds/rgb/leds-qcom-lpg.c
> @@ -523,8 +523,10 @@ static int lpg_calc_freq(struct lpg_channel *chan, uint64_t period)
>  	return 0;
>  }
>  
> -static void lpg_calc_duty(struct lpg_channel *chan, uint64_t duty)
> +static void lpg_calc_duty(struct lpg_channel *chan, uint64_t duty, uint64_t period)
>  {
> +	const unsigned int *pwm_resolution_arr;
> +	unsigned int step;
>  	unsigned int max;
>  	unsigned int val;
>  	unsigned int clk_rate;
> @@ -532,13 +534,15 @@ static void lpg_calc_duty(struct lpg_channel *chan, uint64_t duty)
>  	if (chan->subtype == LPG_SUBTYPE_HI_RES_PWM) {
>  		max = BIT(lpg_pwm_resolution_hi_res[chan->pwm_resolution_sel]) - 1;
>  		clk_rate = lpg_clk_rates_hi_res[chan->clk_sel];
> +		pwm_resolution_arr = lpg_pwm_resolution_hi_res;
>  	} else {
>  		max = BIT(lpg_pwm_resolution[chan->pwm_resolution_sel]) - 1;
>  		clk_rate = lpg_clk_rates[chan->clk_sel];
> +		pwm_resolution_arr = lpg_pwm_resolution;
>  	}
>  
> -	val = div64_u64(duty * clk_rate,
> -			(u64)NSEC_PER_SEC * lpg_pre_divs[chan->pre_div_sel] * (1 << chan->pre_div_exp));
> +	step = div64_u64(period, max);
> +	val = div64_u64(duty, step);
>  
>  	chan->pwm_value = min(val, max);
>  }
> @@ -829,7 +833,7 @@ static void lpg_brightness_set(struct lpg_led *led, struct led_classdev *cdev,
>  			lpg_calc_freq(chan, NSEC_PER_MSEC);
>  
>  			duty = div_u64(brightness * chan->period, cdev->max_brightness);
> -			lpg_calc_duty(chan, duty);
> +			lpg_calc_duty(chan, duty, NSEC_PER_MSEC);
>  			chan->enabled = true;
>  			chan->ramp_enabled = false;
>  
> @@ -906,7 +910,7 @@ static int lpg_blink_set(struct lpg_led *led,
>  		chan = led->channels[i];
>  
>  		lpg_calc_freq(chan, period);
> -		lpg_calc_duty(chan, duty);
> +		lpg_calc_duty(chan, duty, period);
>  
>  		chan->enabled = true;
>  		chan->ramp_enabled = false;
> @@ -1241,7 +1245,7 @@ static int lpg_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
>  		if (ret < 0)
>  			goto out_unlock;
>  
> -		lpg_calc_duty(chan, state->duty_cycle);
> +		lpg_calc_duty(chan, state->duty_cycle, state->period);
>  	}
>  	chan->enabled = state->enabled;
>  
> 
> ---
> base-commit: 0067a4b21c9ab441bbe6bf3635b3ddd21f6ca7c3
> change-id: 20250303-leds-qcom-lpg-compute-pwm-value-using-period-0823ceb7542a
> 
> Best regards,
> -- 
> Abel Vesa <abel.vesa@xxxxxxxxxx>
> 

Attachment: signature.asc
Description: PGP signature


[Index of Archives]     [Linux ARM Kernel]     [Linux ARM]     [Linux Omap]     [Fedora ARM]     [Linux for Sparc]     [IETF Annouce]     [Security]     [Bugtraq]     [Linux MIPS]     [ECOS]     [Asterisk Internet PBX]     [Linux API]

  Powered by Linux