mbox series

[v2,00/14] arm64: dts: qcom: sc8280xp-x13s: enable pm8008 camera pmic

Message ID 20240529162958.18081-1-johan+linaro@kernel.org
Headers show
Series arm64: dts: qcom: sc8280xp-x13s: enable pm8008 camera pmic | expand

Message

Johan Hovold May 29, 2024, 4:29 p.m. UTC
The Qualcomm PM8008 PMIC is a so called QPNP PMIC with seven LDO
regulators, a temperature alarm block and two GPIO pins (which are also
used for interrupt signalling and reset).

Unlike previous QPNP PMICs it uses an I2C rather than SPMI interface,
which has implications for how interrupts are handled.

A previous attempt by Qualcomm to upstream support for PM8008 stalled
two years ago at version 15 after a lot of back and forth discussion on
how best to describe this device in the devicetree. [1]

After reviewing the backstory on this and surveying the current SPMI
PMIC bindings and implementation, I opted for a new approach that does
not describe internal details like register offsets and interrupts in
the devicetree.

The original decision to include registers offsets and internal
interrupts for SPMI PMICs has led to a number of PMIC dtsi being created
to avoid copying lots of boiler plate declarations. This in turn causes
trouble when the PMIC USID address is configurable as the address is
included in every interrupt specifier.

The current SPMI bindings still do not describe the devices fully and
additional data is therefore already provided by drivers (e.g.
additional register blocks, supplies, additional interrupt specifiers).

The fact that PMICs which use two USIDs (addresses) are modelled as two
separate devices causes trouble, for example, when there are
dependencies between subfunctions. [2]

Subfunctions also do not necessarily map neatly onto the 256-register
block partitioning of the SPMI register space, something which has lead
to unresolved inconsistencies in how functions like PWM are described.
[3]

In short, it's a bit of a mess.

With the new style of bindings, by contrast, only essential information
that actually differs between machines would be included in the
devicetree. The bindings would also be mostly decoupled from the
implementation, which has started to leak out into the binding (e.g. how
the QPNP interrupts are handled). This also allows for extending the
implementation without having to update the binding, which is especially
important as Qualcomm does not publish any documentation (e.g. to later
enable regulator over-current protection).

Some PMICs support both I2C and SPMI interfaces (e.g. PM8010) and we
want to be able to reuse the same bindings regardless of the interface.

As a proof concept I have written a new pmc8280 driver for one of the
SPMI PMICs in the Lenovo ThinkPad X13s that uses the new style of
bindings and I've been using that one to control backlight and
peripheral regulators for a while now. Specifically, the gpio and
temperature-alarm blocks can be used with some minor updates to the
current drivers.

That work still needs a bit of polish before posting, but my working PoC
means that I'm confident enough that the new model will work and that we
can go ahead and merge regulator support for the PM8008.

This series is specifically needed for the camera sensors in the X13s,
for which camera subsystem (camss) support has now been merged for 6.10.

The first seven patches are preparatory and can possibly be merged
separately from the rest of the series. The next two patches drop the
broken GPIO support for PM8008 which had already been upstreamed. The
last five patches rework the binding and MFD driver, add support for the
regulators and enable the camera PMIC on the X13s.

Johan

[1] https://lore.kernel.org/all/1655200111-18357-1-git-send-email-quic_c_skakit@quicinc.com
[2] https://lore.kernel.org/lkml/20231003152927.15000-3-johan+linaro@kernel.org
[3] https://lore.kernel.org/r/20220828132648.3624126-3-bryan.odonoghue@linaro.org


Changes in v2
 - use IRQ_TYPE_SENSE_MASK in regmap_irq table
 - add post-reset delay
 - reorder pinctrl binding and driver update
 - split out binding cleanups
 - use platform_device_id matching
 - replace underscore in supply names with dash
 - use more fine-grained includes in regulator driver
 - rework regulator driver and update authorship


Johan Hovold (14):
  dt-bindings: mfd: pm8008: add reset gpio
  mfd: pm8008: fix regmap irq chip initialisation
  mfd: pm8008: deassert reset on probe
  mfd: pm8008: mark regmap structures as const
  mfd: pm8008: use lower case hex notation
  mfd: pm8008: rename irq chip
  mfd: pm8008: drop unused driver data
  pinctrl: qcom: spmi-gpio: drop broken pm8008 support
  dt-bindings: pinctrl: qcom,pmic-gpio: drop pm8008
  dt-bindings: mfd: pm8008: drop redundant descriptions
  dt-bindings: mfd: pm8008: rework binding
  mfd: pm8008: rework driver
  regulator: add pm8008 pmic regulator driver
  arm64: dts: qcom: sc8280xp-x13s: enable pm8008 camera pmic

 .../devicetree/bindings/mfd/qcom,pm8008.yaml  | 158 ++++++++------
 .../bindings/pinctrl/qcom,pmic-gpio.yaml      |   3 -
 .../qcom/sc8280xp-lenovo-thinkpad-x13s.dts    | 123 +++++++++++
 drivers/mfd/Kconfig                           |   1 +
 drivers/mfd/qcom-pm8008.c                     | 169 ++++++++++-----
 drivers/pinctrl/qcom/pinctrl-spmi-gpio.c      |   1 -
 drivers/regulator/Kconfig                     |   7 +
 drivers/regulator/Makefile                    |   1 +
 drivers/regulator/qcom-pm8008-regulator.c     | 198 ++++++++++++++++++
 include/dt-bindings/mfd/qcom-pm8008.h         |  19 --
 10 files changed, 542 insertions(+), 138 deletions(-)
 create mode 100644 drivers/regulator/qcom-pm8008-regulator.c
 delete mode 100644 include/dt-bindings/mfd/qcom-pm8008.h

Comments

Andy Shevchenko May 29, 2024, 7:53 p.m. UTC | #1
On Wed, May 29, 2024 at 7:30 PM Johan Hovold <johan+linaro@kernel.org> wrote:
>
> Rework the pm8008 driver to match the new binding which no longer
> describes internal details like interrupts and register offsets
> (including which of the two consecutive I2C addresses the registers
> belong to).
>
> Instead make the interrupt controller implementation internal and pass
> interrupts to the subdrivers using MFD cell resources.
>
> Note that subdrivers may either get their resources, like register block
> offsets, from the parent MFD or this can be included in the subdrivers
> directly.
>
> In the current implementation, the temperature alarm driver is generic
> enough to just get its base address and alarm interrupt from the parent
> driver, which already uses this information to implement the interrupt
> controller.
>
> The regulator driver, however, needs additional information like parent
> supplies and regulator characteristics so in that case it is easier to
> just augment its table with the regulator register base addresses.
>
> Similarly, the current GPIO driver already holds the number of pins and
> that lookup table can therefore also be extended with register offsets.
>
> Note that subdrivers can now access the two regmaps by name, even if the
> primary regmap is registered last so that it is returned by default when
> no name is provided in lookups.
>
> Finally, note that the temperature alarm and GPIO subdrivers need some
> minor rework before they can be used with non-SPMI devices like the
> PM8008. The temperature alarm MFD cell name specifically uses a "qpnp"
> rather than "spmi" prefix to prevent binding until the driver has been
> updated.

...

> +       dummy = devm_i2c_new_dummy_device(dev, client->adapter, client->addr + 1);
> +       if (IS_ERR(dummy)) {
> +               ret = PTR_ERR(dummy);
> +               dev_err(dev, "failed to claim second address: %d\n", ret);
> +               return ret;
> +       }


> +       ret = devm_regmap_add_irq_chip_fwnode(dev, fwnode, regmap, client->irq,
>                                 IRQF_SHARED, 0, &pm8008_irq_chip, &irq_data);
> +       if (ret) {
> +               dev_err(dev, "failed to add IRQ chip: %d\n", ret);
> +               return ret;
>         }

I believe there is no harm to use

  return dev_err_probe(...);

for these. But it seems you don't like that API. Whatever, no-one will
die, just additional work for the future :-)
Johan Hovold May 30, 2024, 8:09 a.m. UTC | #2
On Wed, May 29, 2024 at 10:53:09PM +0300, Andy Shevchenko wrote:
> On Wed, May 29, 2024 at 7:30 PM Johan Hovold <johan+linaro@kernel.org> wrote:

> > +       ret = devm_regmap_add_irq_chip_fwnode(dev, fwnode, regmap, client->irq,
> >                                 IRQF_SHARED, 0, &pm8008_irq_chip, &irq_data);
> > +       if (ret) {
> > +               dev_err(dev, "failed to add IRQ chip: %d\n", ret);
> > +               return ret;
> >         }
> 
> I believe there is no harm to use
> 
>   return dev_err_probe(...);
> 
> for these. But it seems you don't like that API. Whatever, no-one will
> die, just additional work for the future :-)

Correct. And there's no additional work for the future here either.

Johan
Andy Shevchenko May 30, 2024, 8:34 a.m. UTC | #3
On Thu, May 30, 2024 at 11:08 AM Johan Hovold <johan@kernel.org> wrote:
> On Wed, May 29, 2024 at 10:45:40PM +0300, Andy Shevchenko wrote:
> > On Wed, May 29, 2024 at 7:30 PM Johan Hovold <johan+linaro@kernel.org> wrote:
> > >
> > > Request and deassert any (optional) reset gpio during probe in case it
> > > has been left asserted by the boot firmware.
> > >
> > > Note the reset line is not asserted to avoid reverting to the default
> > > I2C address in case the firmware has configured an alternate address.

...

> > > +       /*
> > > +        * The PMIC does not appear to require a post-reset delay, but wait
> > > +        * for a millisecond for now anyway.
> > > +        */
> >
> > > +       usleep_range(1000, 2000);
> >
> > fsleep() ?
>
> No, I'd only use fsleep() when the argument is variable.

Okay, this is basically the same issue as with use of dev_err_probe()
with known errors. fsleep() hides the choice between let's say
msleep() / usleep_range() / udelay() from the caller. This, in
particular, might allow shifting constraints if the timer core is
changed or becomes more granular. It's independent to the variable or
constant parameter(s). Whatever, I'm not going to insist.
Lee Jones May 31, 2024, 5:11 p.m. UTC | #4
On Wed, 29 May 2024, Johan Hovold wrote:

> The Qualcomm PM8008 PMIC is a so called QPNP PMIC with seven LDO
> regulators, a temperature alarm block and two GPIO pins (which are also
> used for interrupt signalling and reset).

I don't see any issues with the MFD commits.

When you submit this, would you do me a favour and change the subject
lines to match that of the subsystem.  I usually silently change them,
but this is a large set and it'll become annoying real quick.

`git log --oneline -- <subsystem>` is your friend.

Thanks.