123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123 |
- 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.
|