Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add regulator driver infrastructure #27360

Merged
merged 6 commits into from Oct 28, 2020

Conversation

pabigot
Copy link
Collaborator

@pabigot pabigot commented Aug 3, 2020

To support runtime power management we need to be able to control voltage/current regulators. Although there are boards in-tree that use these, there is no devicetree support for describing them. This PR provides support based on Linux bindings.

The API is based on the Linux API but adapted for Zephyr. The enable operation is asynchronous as it may take time to turn a regulator on. The disable operation is synchronous as the caller doesn't need to know when the regulator transitions to off. (Power management infrastructure will, but that's not part of this API.)

On the theory that user space never needs to control system power the API requires supervisor privileges. This may be changed based on feedback. The API is also isr-ok and pre-kernel-ok.

A significant gap is the lack of any ability to configure the kernel init level and priority on a per-device level. Without that this infrastructure is fragile.

The thingy52_nrf52832 board has been updated to provide its two external power rails, but the pseudo-devices that currently control them cannot be replaced until device-specific init priority is supported.

Commit Contents

  • Introduction of standard devicetree properties for power supply control

d306458c15 devicetree: add properties for power supply control

  • Primary regulator commits

0afd91e3bd drivers: add infrastructure for regulator devices
d34246f19e drivers: regulator: add GPIO-controlled regulator driver
c1bc4515f6 doc: introduce the regulator driver API
1724be2c7b tests: drivers: regulator: add test for fixed regulator

  • Add Thingy:52 on-board regulator devices

85c792590c boards: thingy52_nrf52832: add nodes for on-board voltage regulators

Blockers for merge:

@pabigot
Copy link
Collaborator Author

pabigot commented Aug 3, 2020

My current thought is to add a power-supply optional property to the SPI and I2C device base binding definitions, in lieu of having to add those to every driver. To be discussed.

@pabigot
Copy link
Collaborator Author

pabigot commented Aug 3, 2020

The latest push reveals another gap in dependency information: all regulators are included in the image even if only one (or no) device that depends on them is enabled.

Yes, that could be addressed by marking some or all of them status = "disabled"; but that's pretty painful from an application perspective.

@wentongwu wentongwu requested a review from nashif August 4, 2020 02:12
@galak
Copy link
Collaborator

galak commented Aug 4, 2020

Should we be using regulator-fixed binding/compat instead of regulator-gpio?

@carlescufi
Copy link
Member

carlescufi commented Aug 4, 2020

API meeting 4th August 2020:

  • Initial draft takes the smallest subset possible from the Linux functionality (enable/disable for GPIO-controlled regulators only)
  • Can be later extended to support things like PMICs and other types of regulators
  • This would be combined later with a future PMIC driver [RFC] drivers: Add PMIC driver #12097

@galak
Copy link
Collaborator

galak commented Aug 4, 2020

Looks like regulator-name is a required property. So thinking we should as well, and try and have label and regulator-name match for Zephyr's purposes at this point.

include/drivers/regulator.h Outdated Show resolved Hide resolved
include/drivers/regulator.h Outdated Show resolved Hide resolved
drivers/regulator/regulator_gpio.c Outdated Show resolved Hide resolved
drivers/regulator/regulator_gpio.c Outdated Show resolved Hide resolved
@pabigot
Copy link
Collaborator Author

pabigot commented Aug 4, 2020

Looks like regulator-name is a required property. So thinking we should as well, and try and have label and regulator-name match for Zephyr's purposes at this point.

I'm going to add regulator-name (though it'll be ignored in the driver), but don't agree about documenting that the Zephyr-specific label must match the regulator name. That would limit proper use of the label property in the future, when we are free to make this a human-readable description of the node rather than the globally-unique string used in device_get_binding().

Edit: The documented purpose for regulator-name suggests this might be used in log messages, so maybe it'll be used. More review necessary.

@chrta
Copy link
Collaborator

chrta commented Aug 6, 2020

Thank you, this is a good addition also for all SiLabs boards, since nearly every peripheral on the board must be enabled with a dedicated io pin.

My current thought is to add a power-supply optional property to the SPI and I2C device base binding definitions, in lieu of having to add those to every driver. To be discussed.

I would prefer if there would be a more general approach, but i don't know how to implement it properly, maybe move power-supply optional property to some base binding.

Use cases:

For (nearly all) SiLabs dev boards, there is a virtual serial port (via on-board Segger J-Link, named Board controller in source code) that must be enabled with a gpio pin, see https://github.com/zephyrproject-rtos/zephyr/blob/master/boards/arm/efm32gg_stk3701a/board.c#L20

Also the ethernet phy must be enabled via gpio pin a few lines further down, https://github.com/zephyrproject-rtos/zephyr/blob/master/boards/arm/efm32gg_stk3701a/board.c#L38

@pabigot
Copy link
Collaborator Author

pabigot commented Aug 6, 2020

Yes, I have the sltb004a. It motivates a slightly different approach: there are many cases, these included, where we want a more efficient solution that doesn't involve a full on-off service that supports delayed startup and shutdown. Just controlling a GPIO based on whether a counter is zero or positive handles it. I'm thinking of having another compatible regulator-fixed-direct(?) to handle that case in the same driver. (Alternatively that optimized variant could be selected for an instance based on other properties, like all delays being zero and the referenced pin being directly controlled by a SOC GPIO peripheral.) I'm going to take a look at that next.

If there's only one thing that will ever control the signal, and it already knows the state without a counter, I don't think a full regulator API is appropriate. For that application using power-gpios instead of power-supply might be better. Which is probably the case for the sltb004a peripherals.

It should be possible to eliminate boards/arm/efm32gg_stk3701a/board.h by putting that information into a board node in the devicetree, e.g. eth-power-enable-gpios, eth-ref-clk-gpios and eth-reset-gpios properties. Not sure how to handle the clock, but it should be possible. Whether it's worth doing is a maintainer decision.

include/drivers/regulator.h Outdated Show resolved Hide resolved
*
* @param reg a regulator device
*
* @return non-negative on successful completion of the release
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it wait for the regulator to actually be fully off?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. This was a design trade-off in the context of developing the on-off service. If it's necessary to detect when the transition completes that can be done in other ways.

I suspect it will be necessary, so this may have to change.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general you can only know that you have started to turn it off. Of course you can look at datasheets and some of them will have a 'ready' bit which tells you that the power is stable (or fully off).

IMO it is probably enough to know that we have completed 'asking' for it to turn off. A client could add a udelay if needed.

For turning on, I think we need to know that the power is fully stable, since until it is we cannot advance.

include/drivers/regulator.h Show resolved Hide resolved
include/drivers/regulator.h Show resolved Hide resolved
@sjg20
Copy link
Collaborator

sjg20 commented Sep 29, 2020

@pabigot Sorry I seem to have missed a step so that I could see them but not you. Can you see them now?

@sjg20
Copy link
Collaborator

sjg20 commented Sep 29, 2020

The latest push reveals another gap in dependency information: all regulators are included in the image even if only one (or no) device that depends on them is enabled.

Yes, that could be addressed by marking some or all of them status = "disabled"; but that's pretty painful from an application perspective.

That seems OK to me for now

return rc;
}

struct driver_data_sync {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

struct comment?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suppose we can start requiring that for internal implementation data structures that aren't processed to provide documentation. Do we want to do that?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I think we still want comments

const struct driver_config *cfg = dev->config;
int rc = common_init(dev, &data->gpio);

(void)regulator_fixed_init_onoff;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What are these three lines for?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They eliminated "function defined but not referenced" in cases where only _sync regulators are present.

I may be able to remove them with preprocessor conditional that prevent them from being defined, but I think I tried that and it got ugly.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about __maybe_unused ?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly; no precedent in zephyr.

doc/reference/peripherals/regulators.rst Outdated Show resolved Hide resolved
tests/drivers/regulator/fixed/README.txt Show resolved Hide resolved
tests/drivers/regulator/fixed/src/main.c Show resolved Hide resolved
# compatible = "regulator-fixed-sync", "regulator-fixed";
#

compatible: "regulator-fixed"
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we trying to be in sync with the linux binding for regulator-fixed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To a reasonable degree, yes. We don't support external properties for the active level and open drain, for reasons described in the binding.

required: true
description: Descriptive name for regulator outputs.

enable-gpios:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like upstream just calls this gpio for this property.

Copy link
Collaborator Author

@pabigot pabigot Oct 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, that's true. upstream uses gpio, enable-active-high, and gpio-open-drain. This uses enable-gpios to handle all three of those.

I though we'd discussed this and you agreed we shouldn't attempt to support the extra properties when proper use of a GPIO selector makes them unnecessary. Given that, I think we should use a different name, because gpio would suggest the flags are ignored.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we need to name this zephyr,regulator-fixed to avoid confusion I'm fine with that.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can leave things as is, but can we add a comment in the binding to explain how/why enable-gpios differs from gpio?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@galak Rebased (since this hasn't been tested directly on master since August), and then updated the text.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with documentation text rather than comment, because if we're going to generate human-readable documentation for these things the comments are less visible than when we expect people to look at the binding file directly.

@pabigot pabigot added the dev-review To be discussed in dev-review meeting label Oct 22, 2020
@galak galak removed the dev-review To be discussed in dev-review meeting label Oct 22, 2020
pabigot and others added 2 commits October 22, 2020 08:35
Provide a common set of properties for various ways of controlling
power:
* supply-gpios for a GPIO specifier acting like a switch
* vin-supply for a reference to a regulator device

Document the behavior expected when these properties are present.

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
This PR follows Linux in defining devicetree content for generic
voltage and current regulators, and an initial driver API for
controlling them.

A regulator itself may depend on a power source, so it needs to
support the properties that enable that power source.

Signed-off-by: Peter A. Bigot <pab@pabigot.com>
pabigot and others added 4 commits October 22, 2020 08:39
This provides structure for the regulator device hierarchy and a
driver for GPIO-controlled regulators along with its binding.

Signed-off-by: Peter A. Bigot <pab@pabigot.com>
Add a page for the regulator API and introduce it as an experimental
API.

Signed-off-by: Peter Bigot <peter.bigot@nordicsemi.no>
Basic checks on core regulator functions.

Signed-off-by: Peter A. Bigot <pab@pabigot.com>
This board has a multi-level power domain hierarchy where a sensor has
its own power control that is accessed through an external GPIO
peripheral that itself has a power control.

Signed-off-by: Peter A. Bigot <pab@pabigot.com>
@carlescufi carlescufi merged commit c2bac29 into zephyrproject-rtos:master Oct 28, 2020
Architecture Project automation moved this from In Progress to Done Oct 28, 2020
@pabigot pabigot deleted the pabigot/20200803a branch October 31, 2020 11:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area: API Changes to public APIs area: Boards area: Devicetree Binding PR modifies or adds a Device Tree binding area: Devicetree area: Documentation area: Power Management area: Tests Issues related to a particular existing or missing test
Projects
No open projects
Development

Successfully merging this pull request may close these issues.

None yet

9 participants