android_kernel_samsung_msm8976/Documentation/arm/msm/gpiomux.txt
Stephen Boyd 5a8d9170e4 Add snapshot of mach-msm from beginning of msm-3.4
This also includes various documentation files and the devicetree
files for msm boards.

Signed-off-by: Stephen Boyd <sboyd@codeaurora.org>
2013-09-04 14:53:53 -07:00

122 lines
4.4 KiB
Text

This document provides an overview of the msm_gpiomux interface, which
is used to provide gpio pin multiplexing and configuration on mach-msm
targets.
Usage
=====
To use gpiomux, do the following before the msmgpio gpiochips probe:
- Call msm_gpiomux_init to allocate needed resources.
- Install one or more sets of gpiomux configuration data via
msm_gpiomux_install and/or msm_gpiomux_write.
Failing to finish these steps before the probe of msmgpio can result in calls
from msmgpio to gpiomux to try and activate lines which have not yet
been configured.
A basic gpiomux setting is described by a gpiomux_setting structure.
A gpiomux configuration is a group of those settings (one for each power
state of the board) paired with a specific gpio, like so:
struct msm_gpiomux_config gpio123_config __initdata = {
.gpio = 123,
.settings = {
[GPIOMUX_ACTIVE] = {
.func = GPIOMUX_FUNC_GPIO,
.drv = GPIOMUX_DRV_2MA,
.pull = GPIOMUX_PULL_NONE,
.dir = GPIOMUX_OUT_HIGH,
},
[GPIOMUX_SUSPENDED] = {
.func = GPIOMUX_FUNC_3,
.drv = GPIOMUX_DRV_8MA,
.pull = GPIOMUX_PULL_DOWN,
},
},
};
The effect of this configuration is as follows:
- When the system boots, gpio 123 will be put into the SUSPENDED setting.
- When the reference count for gpio 123 rises above 0, the ACTIVE setting
will be applied.
- When the reference count falls back to 0, the SUSPENDED setting will be
reapplied.
The reference count rises when msm_gpiomux_get() is called and falls
when msm_gpiomux_put() is called. msmgpio has hooks to these functions
in its gpiolib implementation. This means that when you call gpio_request()
on an msmgpio, msm_gpiomux_get() is automatically called on your behalf.
Similarly, when you call gpio_free(), msm_gpiomux_put() is called for you.
This allows generic drivers to obtain low-level management of msmgpio lines
without having to be aware of the gpiomux layer.
Note that the .dir field is ignored if .func != GPIOMUX_FUNC_GPIO, since
software control of gpios is allowed only in GPIO mode. By selecting any
other .func, you assign the gpio to another piece of hardware and lose
control of it from gpiolib. You can still reserve such gpios with gpio_request
to prevent other modules from using them while they're in such a state,
but other gpiolib functions will not behave as you expect if .func != GPIO.
If a configuration is omitted, nothing will happen at the relevant transitions.
This allows for the creation of 'static configurations' which do not
change as the line is requested and freed.
Static Configurations
=====================
To install a static configuration, which is applied at boot and does
not change after that, install a configuration with a suspended component
but no active component:
.gpio = ...,
.settings = {
[GPIOMUX_SUSPENDED] = {
...
},
},
The suspended setting is applied during boot, and the lack of any valid
active setting prevents any other setting from being applied at runtime.
If other subsystems attempting to access the line is a concern, one could
*really* anchor the configuration down by calling msm_gpiomux_get on the
line at initialization to move the line into active mode. With the line
held, it will never be re-suspended, and with no valid active configuration,
no new configurations will be applied.
But then, if having other subsystems grabbing for the line is truly a concern,
it should be reserved with gpio_request instead, which carries an implicit
msm_gpiomux_get.
gpiomux and gpiolib
===================
It is expected that msm gpio_chips will call msm_gpiomux_get() and
msm_gpiomux_put() from their request and free hooks, like this fictional
example:
static int request(struct gpio_chip *chip, unsigned offset)
{
return msm_gpiomux_get(chip->base + offset);
}
static void free(struct gpio_chip *chip, unsigned offset)
{
msm_gpiomux_put(chip->base + offset);
}
...somewhere in a gpio_chip declaration...
.request = request,
.free = free,
This provides important functionality:
- It guarantees that a gpio line will have its 'active' config applied
when the line is requested, and will not be suspended while the line
remains requested; and
- It guarantees that gpio-direction settings from gpiolib behave sensibly.
See "About Output-Enable Settings."
This mechanism allows for "auto-request" of gpiomux lines via gpiolib
when it is suitable. Drivers wishing more exact control are, of course,
free to also use msm_gpiomux_set and msm_gpiomux_get.