From: Bjorn Andersson <bjorn.andersson@linaro.org>
To: Marijn Suijten <marijn.suijten@somainline.org>
Cc: Pavel Machek <pavel@ucw.cz>, Dan Murphy <dmurphy@ti.com>,
Rob Herring <robh+dt@kernel.org>, Andy Gross <agross@kernel.org>,
Thierry Reding <thierry.reding@gmail.com>,
Uwe Kleine-K?nig <u.kleine-koenig@pengutronix.de>,
Lee Jones <lee.jones@linaro.org>,
Martin Botka <martin.botka1@gmail.com>,
linux-leds@vger.kernel.org, devicetree@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-arm-msm@vger.kernel.org,
linux-pwm@vger.kernel.org
Subject: Re: [PATCH v6 2/4] leds: Add driver for Qualcomm LPG
Date: Wed, 28 Apr 2021 17:39:39 -0500 [thread overview]
Message-ID: <20210428223939.GN1908499@yoga> (raw)
In-Reply-To: <881fb5a3-fb51-3967-63de-a09950839855@somainline.org>
On Sun 18 Apr 16:54 CDT 2021, Marijn Suijten wrote:
> Hi Bjorn,
>
> On 10/21/20 10:12 PM, Bjorn Andersson wrote:
> > The Light Pulse Generator (LPG) is a PWM-block found in a wide range of
> > PMICs from Qualcomm. It can operate on fixed parameters or based on a
> > lookup-table, altering the duty cycle over time - which provides the
> > means for e.g. hardware assisted transitions of LED brightness.
> >
> > Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
> > Tested-by: Luca Weiss <luca@z3ntu.xyz>
>
>
> Thanks for these patches. I have tested them successfully on the Sony
> Xperia XA2 (Discovery, Nile platform) with the leds on the PM660l - feel
> free to add my Tested-by. Should I send the configuration your way for
> inclusion in this patch, or submit them separately (either applied after, or
> included as separate patches in the next version of this series)?
>
Thanks for testing, let's try to land this first iteration first and
then we can add PM660l and PM8150* definitions/support on top.
> > +/**
> > + * struct lpg_data - initialization data
> > + * @lut_base: base address of LUT block
> > + * @lut_size: number of entries in LUT
> > + * @triled_base: base address of TRILED
> > + * @pwm_9bit_mask: bitmask for switching from 6bit to 9bit pwm
>
>
> Our downstream kernel derives this from the "LPG subtype" for each distinct
> channel, read from register offset +0x5. A value of 0xb is subtype "PWM"
> with a shift of 2, a value of 0x11 is subtype "LPG_LITE" with a shift of 4.
> Can we do the same here instead of hardcoding it for all channels in the LPG
> at once? How should we determine if the mask is one or two bits wide, for
> the 3<<4 case?
>
I don't see any obvious solution to the latter, so perhaps we should
just stick with defining this per compatible? Or am I reading your
suggestion wrong?
> > + * @num_channels: number of channels in LPG
> > + * @channels: list of channel initialization data
> > + */
>
> > + if (ping_pong) {
> > + if (len % 2)
> > + hi_pause = 0;
> > + else
> > + hi_pause = pattern[len + 1 / 2].delta_t;
>
>
> len + 1 should be wrapped in parentheses just like the reassignment to len=
> below, otherwise this is always an out of bounds read (at len + 0).
>
Thanks for spotting this.
> > + lo_pause = pattern[len - 1].delta_t;
> > +
> > + len = (len + 1) / 2;
> > + } else {
> > + hi_pause = pattern[len - 1].delta_t;
> > + lo_pause = 0;
> > + }
> > +
> > + ret = lpg_lut_store(lpg, pattern, len, &lo_idx, &hi_idx);
> > + if (ret < 0)
> > + goto out;
> > +
> > + for (i = 0; i < led->num_channels; i++) {
> > + chan = led->channels[i];
> > +
> > + chan->ramp_duration_ms = pattern[0].delta_t * len;
>
>
> Perhaps this could store the duration of a single step instead, since the
> only use in lpg_apply_lut_control divides it by pattern length again?
>
Sounds like a good idea.
> > + chan->ramp_ping_pong = ping_pong;
> > + chan->ramp_oneshot = repeat != -1;
> > +
> > + chan->ramp_lo_pause_ms = lo_pause;
> > + chan->ramp_hi_pause_ms = hi_pause;
> > +
> > + chan->pattern_lo_idx = lo_idx;
> > + chan->pattern_hi_idx = hi_idx;
> > + }
> > +
> > +out:
> > + return ret;
> > +}
>
> > +static int lpg_init_lut(struct lpg *lpg)
> > +{
> > + const struct lpg_data *data = lpg->data;
> > + size_t bitmap_size;
> > +
> > + if (!data->lut_base)
> > + return 0;
> > +
> > + lpg->lut_base = data->lut_base;
> > + lpg->lut_size = data->lut_size;
> > +
> > + bitmap_size = BITS_TO_LONGS(lpg->lut_size) * sizeof(unsigned long);
> > + lpg->lut_bitmap = devm_kzalloc(lpg->dev, bitmap_size, GFP_KERNEL);
>
>
> Would it be nicer to use BITS_TO_BYTES here, or otherwise devm_kcalloc(...,
> bitmap_size, sizeof(long), ...) without mutiplying with sizeof(unsigned
> long)?
>
Yes, that's cleaner.
> > +
> > + bitmap_clear(lpg->lut_bitmap, 0, lpg->lut_size);
> > + return lpg->lut_bitmap ? 0 : -ENOMEM;
> > +}
> > +
> > +static int lpg_probe(struct platform_device *pdev)
> > +{
> > + struct device_node *np;
> > + struct lpg *lpg;
> > + int ret;
> > + int i;
> > +
> > + lpg = devm_kzalloc(&pdev->dev, sizeof(*lpg), GFP_KERNEL);
> > + if (!lpg)
> > + return -ENOMEM;
> > +
> > + lpg->data = of_device_get_match_data(&pdev->dev);
> > + if (!lpg->data)
> > + return -EINVAL;
> > +
> > + lpg->dev = &pdev->dev;
> > +
> > + lpg->map = dev_get_regmap(pdev->dev.parent, NULL);
> > + if (!lpg->map) {
> > + dev_err(&pdev->dev, "parent regmap unavailable\n");
> > + return -ENXIO;
> > + }
> > +
> > + ret = lpg_init_channels(lpg);
> > + if (ret < 0)
> > + return ret;
> > +
> > + ret = lpg_init_triled(lpg);
> > + if (ret < 0)
> > + return ret;
> > +
> > + ret = lpg_init_lut(lpg);
> > + if (ret < 0)
> > + return ret;
>
>
> How about turning these returns into dev_err_probe? I'm not sure if that's
> the expected way to go nowadays, but having some form of logging when a
> driver fails to probe is always good to have.
>
The intention is that each code path through these functions will either
pass or spit out an error in the log. I looked through them again and
think I cover all paths...
Thanks,
Bjorn
next prev parent reply other threads:[~2021-04-28 22:39 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2020-10-21 20:12 [PATCH v6 0/4] Qualcomm Light Pulse Generator Bjorn Andersson
2020-10-21 20:12 ` [PATCH v6 1/4] dt-bindings: leds: Add Qualcomm Light Pulse Generator binding Bjorn Andersson
2020-10-26 15:02 ` Rob Herring
2020-10-21 20:12 ` [PATCH v6 2/4] leds: Add driver for Qualcomm LPG Bjorn Andersson
2020-10-22 19:25 ` Luca Weiss
2020-10-29 18:13 ` Pavel Machek
2021-04-29 0:12 ` Bjorn Andersson
2021-04-29 21:12 ` Pavel Machek
2021-04-29 21:29 ` Bjorn Andersson
2021-05-04 15:43 ` Pavel Machek
2021-05-04 16:13 ` Bjorn Andersson
2021-05-05 5:21 ` Uwe Kleine-König
2021-04-18 21:54 ` Marijn Suijten
2021-04-28 22:39 ` Bjorn Andersson [this message]
2021-04-29 19:31 ` Marijn Suijten
2021-04-29 20:54 ` Bjorn Andersson
2021-05-05 5:15 ` Uwe Kleine-König
2021-05-05 5:19 ` Uwe Kleine-König
2021-05-13 17:43 ` Bjorn Andersson
2020-10-21 20:12 ` [PATCH v6 3/4] arm64: dts: qcom: pm(i)8994: Add mpp and lpg blocks Bjorn Andersson
2020-10-21 20:12 ` [PATCH v6 4/4] arm64: dts: qcom: Add user LEDs on db820c Bjorn Andersson
-- strict thread matches above, loose matches on Subject: below --
2021-04-15 10:46 [PATCH v6 2/4] leds: Add driver for Qualcomm LPG Yassine Oudjana
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=20210428223939.GN1908499@yoga \
--to=bjorn.andersson@linaro.org \
--cc=agross@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dmurphy@ti.com \
--cc=lee.jones@linaro.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-leds@vger.kernel.org \
--cc=linux-pwm@vger.kernel.org \
--cc=marijn.suijten@somainline.org \
--cc=martin.botka1@gmail.com \
--cc=pavel@ucw.cz \
--cc=robh+dt@kernel.org \
--cc=thierry.reding@gmail.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.