All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
To: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
Cc: thierry.reding@gmail.com, linux-pwm@vger.kernel.org,
	linux-kernel@vger.kernel.org
Subject: Re: [PATCH 4/4] pwm: pca9685: migrate config/enable/disable to apply
Date: Wed, 26 Feb 2020 16:05:32 +0100	[thread overview]
Message-ID: <20200226150532.n45yl6hx6vjolde2@pengutronix.de> (raw)
In-Reply-To: <20200226135229.24929-4-matthias.schiffer@ew.tq-group.com>

Hello,

On Wed, Feb 26, 2020 at 02:52:29PM +0100, Matthias Schiffer wrote:
> For consistency with disabled state, initialize all LEDs in FULL_OFF
> state during probe.
> 
> This also fixes a broken interaction between config with 100% duty cycle
> (which would set the LED to FULL_ON) and enable (which would unset
> FULL_ON), effectively disabling the LED again when enable was called
> after config. This behaviour was observed with the leds-pwm driver when
> directly switching from 0 to maximum brightness.
> 
> Signed-off-by: Matthias Schiffer <matthias.schiffer@ew.tq-group.com>
> ---
>  drivers/pwm/pwm-pca9685.c | 53 +++++++++++----------------------------
>  1 file changed, 14 insertions(+), 39 deletions(-)
> 
> diff --git a/drivers/pwm/pwm-pca9685.c b/drivers/pwm/pwm-pca9685.c
> index 370691b21107..e266cbbd39bf 100644
> --- a/drivers/pwm/pwm-pca9685.c
> +++ b/drivers/pwm/pwm-pca9685.c
> @@ -219,15 +219,16 @@ static void pca9685_set_sleep_mode(struct pca9685 *pca, bool enable)
>  	}
>  }
>  
> -static int pca9685_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
> -			      int duty_ns, int period_ns)
> +static int pca9685_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
> +			     const struct pwm_state *state)
>  {
>  	struct pca9685 *pca = to_pca(chip);
>  	unsigned long long duty;
>  	int prescale;
>  
> -	if (period_ns != pca->period_ns) {
> -		prescale = DIV_ROUND_CLOSEST(PCA9685_OSC_CLOCK_MHZ * period_ns,
> +	if (state->period != pca->period_ns) {
> +		prescale = DIV_ROUND_CLOSEST(PCA9685_OSC_CLOCK_MHZ *
> +					     state->period,
>  					     PCA9685_COUNTER_RANGE * 1000) - 1;
>  
>  		if (prescale >= PCA9685_PRESCALE_MIN &&
> @@ -247,7 +248,7 @@ static int pca9685_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
>  			/* Wake the chip up */
>  			pca9685_set_sleep_mode(pca, false);
>  
> -			pca->period_ns = period_ns;
> +			pca->period_ns = state->period;
>  		} else {
>  			dev_err(chip->dev,
>  				"prescaler not set: period out of bounds!\n");
> @@ -255,13 +256,13 @@ static int pca9685_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
>  		}
>  	}
>  
> -	if (duty_ns < 1) {
> +	if (!state->enabled || state->duty_cycle < 1) {
> +		/* Set the full OFF bit */
>  		regmap_write(pca->regmap, LED_N_OFF_H(pwm->hwpwm), LED_FULL);
> -
>  		return 0;
>  	}
>  
> -	if (duty_ns == period_ns) {
> +	if (state->duty_cycle == state->period) {
>  		/* Clear both OFF registers */
>  		regmap_write(pca->regmap, LED_N_OFF_L(pwm->hwpwm), 0x0);
>  		regmap_write(pca->regmap, LED_N_OFF_H(pwm->hwpwm), 0x0);
> @@ -272,8 +273,8 @@ static int pca9685_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
>  		return 0;
>  	}
>  
> -	duty = PCA9685_COUNTER_RANGE * (unsigned long long)duty_ns;
> -	duty = DIV_ROUND_UP_ULL(duty, period_ns);
> +	duty = PCA9685_COUNTER_RANGE * (unsigned long long)state->duty_cycle;
> +	duty = DIV_ROUND_UP_ULL(duty, state->period);
>  
>  	regmap_write(pca->regmap, LED_N_OFF_L(pwm->hwpwm), (int)duty & 0xff);
>  	regmap_write(pca->regmap, LED_N_OFF_H(pwm->hwpwm),
> @@ -285,29 +286,6 @@ static int pca9685_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
>  	return 0;

You seem to ignore state->polarity which is wrong.

>  }
>  
> -static int pca9685_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
> -{
> -	struct pca9685 *pca = to_pca(chip);
> -
> -	/*
> -	 * Clear the full-off bit.
> -	 * It has precedence over the others and must be off.
> -	 */
> -	regmap_update_bits(pca->regmap, LED_N_OFF_H(pwm->hwpwm), LED_FULL, 0x0);
> -
> -	return 0;
> -}
> -
> -static void pca9685_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
> -{
> -	struct pca9685 *pca = to_pca(chip);
> -
> -	regmap_write(pca->regmap, LED_N_OFF_H(pwm->hwpwm), LED_FULL);
> -
> -	/* Clear the LED_OFF counter. */
> -	regmap_write(pca->regmap, LED_N_OFF_L(pwm->hwpwm), 0x0);
> -}
> -
>  static int pca9685_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
>  {
>  	struct pca9685 *pca = to_pca(chip);
> @@ -321,14 +299,11 @@ static int pca9685_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
>  
>  static void pca9685_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
>  {
> -	pca9685_pwm_disable(chip, pwm);
>  	pm_runtime_put(chip->dev);
>  }
>  
>  static const struct pwm_ops pca9685_pwm_ops = {
> -	.enable = pca9685_pwm_enable,
> -	.disable = pca9685_pwm_disable,
> -	.config = pca9685_pwm_config,
> +	.apply = pca9685_pwm_apply,
>  	.request = pca9685_pwm_request,
>  	.free = pca9685_pwm_free,
>  	.owner = THIS_MODULE,
> @@ -377,9 +352,9 @@ static int pca9685_pwm_probe(struct i2c_client *client,
>  
>  	regmap_write(pca->regmap, PCA9685_MODE2, mode2);
>  
> -	/* clear all "full off" bits */
> +	/* Set all LEDs full off */
>  	regmap_write(pca->regmap, PCA9685_ALL_LED_OFF_L, 0);
> -	regmap_write(pca->regmap, PCA9685_ALL_LED_OFF_H, 0);
> +	regmap_write(pca->regmap, PCA9685_ALL_LED_OFF_H, LED_FULL);

This looks wrong or at least unrelated?

Best regards
Uwe

-- 
Pengutronix e.K.                           | Uwe Kleine-König            |
Industrial Linux Solutions                 | https://www.pengutronix.de/ |

  reply	other threads:[~2020-02-26 15:05 UTC|newest]

Thread overview: 39+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-02-26 13:52 [PATCH 1/4] pwm: pca9685: remove unused duty_cycle struct element Matthias Schiffer
2020-02-26 13:52 ` [PATCH 2/4] pwm: pca9685: remove ALL_LED PWM channel Matthias Schiffer
2020-03-30 13:07   ` Thierry Reding
2020-03-30 13:15     ` Thierry Reding
2020-03-30 13:19     ` Andy Shevchenko
2020-03-30 15:38       ` Thierry Reding
2020-03-30 13:34     ` Clemens Gruber
2020-03-30 15:40       ` Thierry Reding
2020-03-30 15:43         ` Thierry Reding
2020-03-30 16:07         ` Clemens Gruber
2020-03-31 12:09           ` (EXT) " Matthias Schiffer
2020-03-31 13:14             ` Clemens Gruber
2020-02-26 13:52 ` [PATCH 3/4] pwm: pca9685: initialize all LED registers during probe Matthias Schiffer
2020-02-26 15:00   ` Uwe Kleine-König
2020-02-26 16:13     ` (EXT) " Matthias Schiffer
2020-03-30 13:07       ` Thierry Reding
2020-02-26 13:52 ` [PATCH 4/4] pwm: pca9685: migrate config/enable/disable to apply Matthias Schiffer
2020-02-26 15:05   ` Uwe Kleine-König [this message]
2020-02-26 15:10 ` [PATCH 1/4] pwm: pca9685: remove unused duty_cycle struct element Uwe Kleine-König
2020-02-26 17:03   ` (EXT) " Matthias Schiffer
2020-02-26 19:21     ` Uwe Kleine-König
2020-02-28 13:26       ` (EXT) " Matthias Schiffer
2020-03-30 15:12     ` Clemens Gruber
2020-04-03 23:50       ` Sven Van Asbroeck
2020-04-04 17:35         ` Clemens Gruber
2020-04-04 20:17           ` Sven Van Asbroeck
2020-04-06  9:51             ` Thierry Reding
2020-04-07 13:00               ` (EXT) " Matthias Schiffer
2020-04-09 11:42               ` Sven Van Asbroeck
2020-04-03 23:47     ` Sven Van Asbroeck
2020-04-07 14:46       ` (EXT) " Matthias Schiffer
2020-04-08  8:00         ` Matthias Schiffer
2020-03-30 13:07 ` Thierry Reding
2020-03-30 13:18   ` Andy Shevchenko
2020-03-30 16:02     ` Thierry Reding
2020-03-30 16:10       ` Clemens Gruber
2020-04-01 16:36       ` Clemens Gruber
2020-04-01 17:45         ` Thierry Reding
2020-04-02  7:10           ` (EXT) " Matthias Schiffer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200226150532.n45yl6hx6vjolde2@pengutronix.de \
    --to=u.kleine-koenig@pengutronix.de \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pwm@vger.kernel.org \
    --cc=matthias.schiffer@ew.tq-group.com \
    --cc=thierry.reding@gmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.