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: 12+ 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-11-29 19:10 ` 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 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.