From: Miquel Raynal <miquel.raynal@bootlin.com>
To: "Uwe Kleine-König" <u.kleine-koenig@pengutronix.de>
Cc: linux-pwm@vger.kernel.org, kernel@pengutronix.de,
linux-gpio@vger.kernel.org,
Linus Walleij <linus.walleij@linaro.org>,
linux-kernel@vger.kernel.org,
Bartosz Golaszewski <bgolaszewski@baylibre.com>,
Thierry Reding <thierry.reding@gmail.com>,
Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Subject: Re: [PATCH v4] gpio: pca953x: Add Maxim MAX7313 PWM support
Date: Mon, 16 Dec 2019 10:14:16 +0100 [thread overview]
Message-ID: <20191216101416.339d873f@xps13> (raw)
In-Reply-To: <20191216085424.x6fqr4gxkph5zqjh@pengutronix.de>
Hi Uwe,
Uwe Kleine-König <u.kleine-koenig@pengutronix.de> wrote on Mon, 16 Dec
2019 09:54:24 +0100:
> Hi Miquel,
>
> On Mon, Dec 16, 2019 at 09:39:55AM +0100, Miquel Raynal wrote:
> > Uwe Kleine-König <u.kleine-koenig@pengutronix.de> wrote on Thu, 12 Dec
> > 2019 22:14:34 +0100:
> >
> > > On Fri, Nov 29, 2019 at 08:10:23PM +0100, Miquel Raynal wrote:
> > > > +static int max7313_pwm_apply(struct pwm_chip *chip,
> > > > + struct pwm_device *pwm,
> > > > + const struct pwm_state *state)
> > > > +{
> > > > + struct max7313_pwm *max_pwm = to_max7313_pwm(chip);
> > > > + struct pca953x_chip *pca_chip = to_pca953x(max_pwm);
> > > > + unsigned int intensity, active;
> > > > + int ret = 0;
> > > > +
> > > > + if (!state->enabled ||
> > > > + state->period < PWM_PERIOD_NS ||
> > > > + state->polarity != PWM_POLARITY_NORMAL)
> > > > + return -EINVAL;
> > > > +
> > > > + /* Convert the duty-cycle to be in the [0;16] range */
> > > > + intensity = DIV_ROUND_DOWN_ULL(state->duty_cycle,
> > > > + state->period / PWM_DC_STATES);
> > >
> > > this looks wrong. The period must not have an influence on the selection
> > > of the duty_cycle (other than duty_cycle < period). So given that the
> > > period is fixed at 31.25 ms, the result of
> > >
> > > pwm_apply_state(pwm, { .enabled = 1, .period = 2s, .duty_cycle = 16 ms })
> > >
> > > must be the same as for
> > >
> > > pwm_apply_state(pwm, { .enabled = 1, .period = 3s, .duty_cycle = 16 ms })
> >
> > This was not my understanding of our previous discussion and, again, I
> > don't really understand this choice but if the framework works like
> > that we shall probably continue with this logic. However, all this
> > should probably be explained directly in the kernel doc of each core
> > helper, that would help a lot.
>
> I agree. There is a pending doc patch and once Thierry applies it I plan
> to add these details.
Great!
>
> The idea is to make the policy simple (both computational and to
> understand). With each policy there are strange corner cases, so for
> sure you can come up with examples that yield results that are way off
> from the request. The idea is that drivers all implement the same policy
> and then create helper functions to match the different consumer needs.
I fully understand and comply with this.
The above logic was not the first one that would have came off my mind
but it is 100% true that it keeps the computation easy (= less bugs, =
quicker) and has probably been much more pondered than mine.
>
> > > . Also dividing by a division looses precision.
> >
> > I agree but this is a problem with fixed point calculations. Maybe I
> > could first multiply the numerator by a factor of 100 or 1000 to
> > minimize the error. Do you have a better idea?
>
> intensity = DIV_ROUND_DOWN_ULL((unsigned long long)state->duty_cycle * PWM_DC_STATES, state->period);
>
> should be both more exact and cheaper to calculate. (But this is
> somewhat moot given that state->period shouldn't be there.)
I feel stupid now - let's put it on monday mood. Of course it's more
accurate this way.
> (And in general you have to care for overflowing, but I think that's not
> a problem in practise here as struct pwm_state::duty_cycle is an int
> (still), and PWM_DC_STATES is small.)
Do you plan to change duty_cycle type?
Right now the multiplication cannot be over 500 000 which is totally
okay for a s32 but not for a s16 for instance.
> > > > +static void max7313_pwm_get_state(struct pwm_chip *chip,
> > > > + struct pwm_device *pwm,
> > > > + struct pwm_state *state)
> > > > +{
> > > > + struct max7313_pwm *max_pwm = to_max7313_pwm(chip);
> > > > + struct pca953x_chip *pca_chip = to_pca953x(max_pwm);
> > > > + u8 intensity;
> > > > +
> > > > + state->enabled = true;
> > > > + state->period = PWM_PERIOD_NS;
> > > > + state->polarity = PWM_POLARITY_NORMAL;
> > > > +
> > > > + intensity = max7313_pwm_get_intensity(pca_chip, pwm->hwpwm);
> > > > + state->duty_cycle = intensity * PWM_OFFSET_NS;
> > >
> > > I think you need to take into account the blink phase bit.
> >
> > It is already done by .pwm_get_intensity itself, no?
>
> Ah, possible, I admin I didn't look deep enough to catch it there.
No problem, thanks anyway for all the careful reviews!
Thanks,
Miquèl
next prev parent reply other threads:[~2019-12-16 9:14 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-29 19:10 [PATCH v4] gpio: pca953x: Add Maxim MAX7313 PWM support Miquel Raynal
2019-12-12 15:26 ` Linus Walleij
2019-12-12 21:14 ` Uwe Kleine-König
2019-12-16 8:39 ` Miquel Raynal
2019-12-16 8:54 ` Uwe Kleine-König
2019-12-16 9:14 ` Miquel Raynal [this message]
2019-12-16 9:24 ` Uwe Kleine-König
2019-12-16 21:50 ` Andy Shevchenko
2020-01-06 13:44 ` Miquel Raynal
2020-01-06 21:11 ` Miquel Raynal
2020-01-07 12:31 ` Linus Walleij
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=20191216101416.339d873f@xps13 \
--to=miquel.raynal@bootlin.com \
--cc=bgolaszewski@baylibre.com \
--cc=kernel@pengutronix.de \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pwm@vger.kernel.org \
--cc=thierry.reding@gmail.com \
--cc=thomas.petazzoni@bootlin.com \
--cc=u.kleine-koenig@pengutronix.de \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox