From: "Mathieu Dubois-Briand" <mathieu.dubois-briand@bootlin.com>
To: "Uwe Kleine-König" <ukleinek@kernel.org>
Cc: "Lee Jones" <lee@kernel.org>, "Rob Herring" <robh@kernel.org>,
"Krzysztof Kozlowski" <krzk+dt@kernel.org>,
"Conor Dooley" <conor+dt@kernel.org>,
"Kamel Bouhara" <kamel.bouhara@bootlin.com>,
"Linus Walleij" <linus.walleij@linaro.org>,
"Bartosz Golaszewski" <brgl@bgdev.pl>,
"Dmitry Torokhov" <dmitry.torokhov@gmail.com>,
"Michael Walle" <mwalle@kernel.org>,
"Mark Brown" <broonie@kernel.org>,
"Greg Kroah-Hartman" <gregkh@linuxfoundation.org>,
"Rafael J. Wysocki" <rafael@kernel.org>,
"Danilo Krummrich" <dakr@kernel.org>,
devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
linux-gpio@vger.kernel.org, linux-input@vger.kernel.org,
linux-pwm@vger.kernel.org, andriy.shevchenko@intel.com,
"Grégory Clement" <gregory.clement@bootlin.com>,
"Thomas Petazzoni" <thomas.petazzoni@bootlin.com>,
"Andy Shevchenko" <andriy.shevchenko@linux.intel.com>
Subject: Re: [PATCH v11 04/10] pwm: max7360: Add MAX7360 PWM support
Date: Wed, 16 Jul 2025 09:46:14 +0200 [thread overview]
Message-ID: <DBDB9TTHTCKT.2MZJIDJGFPTDB@bootlin.com> (raw)
In-Reply-To: <j6zavgfpiq7s7cnfkghn2y6fv4h4ziqtpyp7igwmovqlyuasoq@hozlyjcpsxth>
On Fri Jul 11, 2025 at 4:50 PM CEST, Uwe Kleine-König wrote:
> Hello Mathieu,
>
> On Fri, Jul 11, 2025 at 11:29:44AM +0200, Mathieu Dubois-Briand wrote:
>> diff --git a/drivers/pwm/pwm-max7360.c b/drivers/pwm/pwm-max7360.c
>> new file mode 100644
>> index 000000000000..0eb83135f658
>> --- /dev/null
>> +++ b/drivers/pwm/pwm-max7360.c
>> @@ -0,0 +1,193 @@
>> +// SPDX-License-Identifier: GPL-2.0-only
>> +/*
>> + * Copyright 2025 Bootlin
>> + *
>> + * Author: Kamel BOUHARA <kamel.bouhara@bootlin.com>
>> + * Author: Mathieu Dubois-Briand <mathieu.dubois-briand@bootlin.com>
>> + *
>
> A link to the data sheet here would be awesome. I found it at
>
> https://www.analog.com/media/en/technical-documentation/data-sheets/MAX7360.pdf
>
Sure, I will add the link.
>> [...]
>> +static int max7360_pwm_round_waveform_tohw(struct pwm_chip *chip,
>> + struct pwm_device *pwm,
>> + const struct pwm_waveform *wf,
>> + void *_wfhw)
>> +{
>> + struct max7360_pwm_waveform *wfhw = _wfhw;
>> + u64 duty_steps;
>> +
>> + /*
>> + * Ignore user provided values for period_length_ns and duty_offset_ns:
>> + * we only support fixed period of MAX7360_PWM_PERIOD_NS and offset of 0.
>> + */
>> + if (wf->duty_length_ns >= MAX7360_PWM_PERIOD_NS)
>> + duty_steps = MAX7360_PWM_MAX_RES;
>> + else
>> + duty_steps = (u32)wf->duty_length_ns * MAX7360_PWM_MAX_RES / MAX7360_PWM_PERIOD_NS;
>
> I read through the data sheet and I think the right formula for
> duty_steps is:
>
> if (wf->duty_length_ns >= MAX7360_PWM_PERIOD_NS) {
> duty_steps = 255;
> } else {
> duty_steps = (u32)wf->duty_length_ns * 256 / MAX7360_PWM_PERIOD_NS;
> if (duty_steps == 255)
> duty_steps = 254;
> }
>
> (Using magic constants here, but in the end these should be cpp symbols
> of course.)
>
>> + wfhw->duty_steps = min(MAX7360_PWM_MAX_RES, duty_steps);
>> + wfhw->enabled = !!wf->period_length_ns;
>> +
>> + return 0;
>> +}
>> +
>> +static int max7360_pwm_round_waveform_fromhw(struct pwm_chip *chip, struct pwm_device *pwm,
>> + const void *_wfhw, struct pwm_waveform *wf)
>> +{
>> + const struct max7360_pwm_waveform *wfhw = _wfhw;
>> +
>> + wf->period_length_ns = wfhw->enabled ? MAX7360_PWM_PERIOD_NS : 0;
>> + wf->duty_offset_ns = 0;
>> +
>> + if (wfhw->enabled)
>> + wf->duty_length_ns = DIV_ROUND_UP(wfhw->duty_steps * MAX7360_PWM_PERIOD_NS,
>> + MAX7360_PWM_MAX_RES);
>> + else
>> + wf->duty_length_ns = 0;
>
> The matching code here is:
>
> if (wfhw->duty_steps == 255)
> wf->duty_length_ns = MAX7360_PWM_PERIOD_NS;
> else
> wf->duty_length_ns = DIV_ROUND_UP(wfhw->duty_steps * MAX7360_PWM_PERIOD_NS, 256)
>
> This is arguably a strange design, but f_OSC = 128 kHz and the fixed
> period being 2 ms is a strong indication that the divider is 256 and not
> 255. If you don't agree to the manual (e.g. because you measured the
> output and saw your formula to be true), please add a code comment about
> that.
>
Yes, I did a few measurements, and you are right. I'm fixing the code as
you described.
> When you have measureing equipment at hand it would be great if you
> could verify that the right fromhw implementation isn't:
>
> wf->duty_length_ns = DIV_ROUND_UP(wfhw->duty_steps * MAX7360_PWM_PERIOD_NS, 256)
>
> even for wfhw->duty_steps == 255. (Which would mean that the PWM cannot
> provide a 100% duty cycle.)
>
No, I confirm, values from 0 to 254 provide a duty cycle from 0 to
254/256. A value of 255 provides a 100% duty cycle.
>> +static int max7360_pwm_probe(struct platform_device *pdev)
>> +{
>> + struct device *dev = &pdev->dev;
>> + struct pwm_chip *chip;
>> + struct regmap *regmap;
>> + int ret;
>> +
>> + regmap = dev_get_regmap(dev->parent, NULL);
>> + if (!regmap)
>> + return dev_err_probe(dev, -ENODEV, "could not get parent regmap\n");
>> ...
>> +
>> + ret = devm_pwmchip_add(dev, chip);
>> + if (ret)
>> + return dev_err_probe(dev, ret, "failed to add PWM chip\n");
>
> Please start error messages with a capital letter.
>
Fixed, thanks.
> Best regards
> Uwe
Thanks for your review,
Mathieu
--
Mathieu Dubois-Briand, Bootlin
Embedded Linux and Kernel engineering
https://bootlin.com
next prev parent reply other threads:[~2025-07-16 7:46 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2025-07-11 9:29 [PATCH v11 00/10] Add support for MAX7360 Mathieu Dubois-Briand
2025-07-11 9:29 ` [PATCH v11 01/10] dt-bindings: mfd: gpio: Add MAX7360 Mathieu Dubois-Briand
2025-07-11 9:29 ` [PATCH v11 02/10] mfd: Add max7360 support Mathieu Dubois-Briand
2025-07-11 9:29 ` [PATCH v11 03/10] pinctrl: Add MAX7360 pinctrl driver Mathieu Dubois-Briand
2025-07-11 9:29 ` [PATCH v11 04/10] pwm: max7360: Add MAX7360 PWM support Mathieu Dubois-Briand
2025-07-11 14:50 ` Uwe Kleine-König
2025-07-16 7:46 ` Mathieu Dubois-Briand [this message]
2025-07-11 9:29 ` [PATCH v11 05/10] gpio: regmap: Allow to allocate regmap-irq device Mathieu Dubois-Briand
2025-07-11 9:29 ` [PATCH v11 06/10] gpio: regmap: Allow to provide init_valid_mask callback Mathieu Dubois-Briand
2025-07-11 9:29 ` [PATCH v11 07/10] gpio: max7360: Add MAX7360 gpio support Mathieu Dubois-Briand
2025-07-11 9:29 ` [PATCH v11 08/10] input: keyboard: Add support for MAX7360 keypad Mathieu Dubois-Briand
2025-07-11 9:29 ` [PATCH v11 09/10] input: misc: Add support for MAX7360 rotary Mathieu Dubois-Briand
2025-07-11 9:29 ` [PATCH v11 10/10] MAINTAINERS: Add entry on MAX7360 driver Mathieu Dubois-Briand
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=DBDB9TTHTCKT.2MZJIDJGFPTDB@bootlin.com \
--to=mathieu.dubois-briand@bootlin.com \
--cc=andriy.shevchenko@intel.com \
--cc=andriy.shevchenko@linux.intel.com \
--cc=brgl@bgdev.pl \
--cc=broonie@kernel.org \
--cc=conor+dt@kernel.org \
--cc=dakr@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dmitry.torokhov@gmail.com \
--cc=gregkh@linuxfoundation.org \
--cc=gregory.clement@bootlin.com \
--cc=kamel.bouhara@bootlin.com \
--cc=krzk+dt@kernel.org \
--cc=lee@kernel.org \
--cc=linus.walleij@linaro.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-input@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pwm@vger.kernel.org \
--cc=mwalle@kernel.org \
--cc=rafael@kernel.org \
--cc=robh@kernel.org \
--cc=thomas.petazzoni@bootlin.com \
--cc=ukleinek@kernel.org \
/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.