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