summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/pinctrl.txt311
-rw-r--r--arch/arm/mach-u300/core.c66
-rw-r--r--arch/arm/mach-u300/include/mach/gpio-u300.h2
-rw-r--r--drivers/pinctrl/Kconfig22
-rw-r--r--drivers/pinctrl/Makefile4
-rw-r--r--drivers/pinctrl/core.c828
-rw-r--r--drivers/pinctrl/core.h116
-rw-r--r--drivers/pinctrl/pinconf.c297
-rw-r--r--drivers/pinctrl/pinconf.h45
-rw-r--r--drivers/pinctrl/pinctrl-coh901.c16
-rw-r--r--drivers/pinctrl/pinctrl-mmp2.c722
-rw-r--r--drivers/pinctrl/pinctrl-pxa168.c651
-rw-r--r--drivers/pinctrl/pinctrl-pxa3xx.c244
-rw-r--r--drivers/pinctrl/pinctrl-pxa3xx.h264
-rw-r--r--drivers/pinctrl/pinctrl-pxa910.c1007
-rw-r--r--drivers/pinctrl/pinctrl-u300.c20
-rw-r--r--drivers/pinctrl/pinmux.c1175
-rw-r--r--drivers/pinctrl/pinmux.h76
-rw-r--r--drivers/tty/serial/sirfsoc_uart.c24
-rw-r--r--drivers/tty/serial/sirfsoc_uart.h2
-rw-r--r--include/linux/pinctrl/consumer.h159
-rw-r--r--include/linux/pinctrl/machine.h190
-rw-r--r--include/linux/pinctrl/pinconf.h39
-rw-r--r--include/linux/pinctrl/pinctrl-state.h6
-rw-r--r--include/linux/pinctrl/pinctrl.h3
-rw-r--r--include/linux/pinctrl/pinmux.h52
26 files changed, 4938 insertions, 1403 deletions
diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt
index 150fd38..d97bccf 100644
--- a/Documentation/pinctrl.txt
+++ b/Documentation/pinctrl.txt
@@ -206,12 +206,21 @@ using a certain resistor value - pull up and pull down - so that the pin has a
stable value when nothing is driving the rail it is connected to, or when it's
unconnected.
-For example, a platform may do this:
+Pin configuration can be programmed either using the explicit APIs described
+immediately below, or by adding configuration entries into the mapping table;
+see section "Board/machine configuration" below.
+
+For example, a platform may do the following to pull up a pin to VDD:
+
+#include <linux/pinctrl/consumer.h>
ret = pin_config_set("foo-dev", "FOO_GPIO_PIN", PLATFORM_X_PULL_UP);
-To pull up a pin to VDD. The pin configuration driver implements callbacks for
-changing pin configuration in the pin controller ops like this:
+The format and meaning of the configuration parameter, PLATFORM_X_PULL_UP
+above, is entirely defined by the pin controller driver.
+
+The pin configuration driver implements callbacks for changing pin
+configuration in the pin controller ops like this:
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
@@ -492,14 +501,10 @@ Definitions:
{"map-i2c0", i2c0, pinctrl0, fi2c0, gi2c0}
}
- Every map must be assigned a symbolic name, pin controller and function.
- The group is not compulsory - if it is omitted the first group presented by
- the driver as applicable for the function will be selected, which is
- useful for simple cases.
-
- The device name is present in map entries tied to specific devices. Maps
- without device names are referred to as SYSTEM pinmuxes, such as can be taken
- by the machine implementation on boot and not tied to any specific device.
+ Every map must be assigned a state name, pin controller, device and
+ function. The group is not compulsory - if it is omitted the first group
+ presented by the driver as applicable for the function will be selected,
+ which is useful for simple cases.
It is possible to map several groups to the same combination of device,
pin controller and function. This is for cases where a certain function on
@@ -726,19 +731,19 @@ same time.
All the above functions are mandatory to implement for a pinmux driver.
-Pinmux interaction with the GPIO subsystem
-==========================================
+Pin control interaction with the GPIO subsystem
+===============================================
-The public pinmux API contains two functions named pinmux_request_gpio()
-and pinmux_free_gpio(). These two functions shall *ONLY* be called from
+The public pinmux API contains two functions named pinctrl_request_gpio()
+and pinctrl_free_gpio(). These two functions shall *ONLY* be called from
gpiolib-based drivers as part of their gpio_request() and
-gpio_free() semantics. Likewise the pinmux_gpio_direction_[input|output]
+gpio_free() semantics. Likewise the pinctrl_gpio_direction_[input|output]
shall only be called from within respective gpio_direction_[input|output]
gpiolib implementation.
NOTE that platforms and individual drivers shall *NOT* request GPIO pins to be
-muxed in. Instead, implement a proper gpiolib driver and have that driver
-request proper muxing for its pins.
+controlled e.g. muxed in. Instead, implement a proper gpiolib driver and have
+that driver request proper muxing and other control for its pins.
The function list could become long, especially if you can convert every
individual pin into a GPIO pin independent of any other pins, and then try
@@ -747,7 +752,7 @@ the approach to define every pin as a function.
In this case, the function array would become 64 entries for each GPIO
setting and then the device functions.
-For this reason there are two functions a pinmux driver can implement
+For this reason there are two functions a pin control driver can implement
to enable only GPIO on an individual pin: .gpio_request_enable() and
.gpio_disable_free().
@@ -762,12 +767,12 @@ gpiolib driver and the affected GPIO range, pin offset and desired direction
will be passed along to this function.
Alternatively to using these special functions, it is fully allowed to use
-named functions for each GPIO pin, the pinmux_request_gpio() will attempt to
+named functions for each GPIO pin, the pinctrl_request_gpio() will attempt to
obtain the function "gpioN" where "N" is the global GPIO pin number if no
special GPIO-handler is registered.
-Pinmux board/machine configuration
+Board/machine configuration
==================================
Boards and machines define how a certain complete running system is put
@@ -775,27 +780,33 @@ together, including how GPIOs and devices are muxed, how regulators are
constrained and how the clock tree looks. Of course pinmux settings are also
part of this.
-A pinmux config for a machine looks pretty much like a simple regulator
-configuration, so for the example array above we want to enable i2c and
-spi on the second function mapping:
+A pin controller configuration for a machine looks pretty much like a simple
+regulator configuration, so for the example array above we want to enable i2c
+and spi on the second function mapping:
#include <linux/pinctrl/machine.h>
-static const struct pinmux_map __initdata pmx_mapping[] = {
+static const struct pinctrl_map __initdata mapping[] = {
{
- .ctrl_dev_name = "pinctrl-foo",
- .function = "spi0",
.dev_name = "foo-spi.0",
+ .name = PINCTRL_STATE_DEFAULT,
+ .type = PIN_MAP_TYPE_MUX_GROUP,
+ .ctrl_dev_name = "pinctrl-foo",
+ .data.mux.function = "spi0",
},
{
- .ctrl_dev_name = "pinctrl-foo",
- .function = "i2c0",
.dev_name = "foo-i2c.0",
+ .name = PINCTRL_STATE_DEFAULT,
+ .type = PIN_MAP_TYPE_MUX_GROUP,
+ .ctrl_dev_name = "pinctrl-foo",
+ .data.mux.function = "i2c0",
},
{
- .ctrl_dev_name = "pinctrl-foo",
- .function = "mmc0",
.dev_name = "foo-mmc.0",
+ .name = PINCTRL_STATE_DEFAULT,
+ .type = PIN_MAP_TYPE_MUX_GROUP,
+ .ctrl_dev_name = "pinctrl-foo",
+ .data.mux.function = "mmc0",
},
};
@@ -805,21 +816,51 @@ must match a function provided by the pinmux driver handling this pin range.
As you can see we may have several pin controllers on the system and thus
we need to specify which one of them that contain the functions we wish
-to map. The map can also use struct device * directly, so there is no
-inherent need to use strings to specify .dev_name or .ctrl_dev_name, these
-are for the situation where you do not have a handle to the struct device *,
-for example if they are not yet instantiated or cumbersome to obtain.
+to map.
You register this pinmux mapping to the pinmux subsystem by simply:
- ret = pinmux_register_mappings(pmx_mapping, ARRAY_SIZE(pmx_mapping));
+ ret = pinctrl_register_mappings(mapping, ARRAY_SIZE(mapping));
Since the above construct is pretty common there is a helper macro to make
it even more compact which assumes you want to use pinctrl-foo and position
0 for mapping, for example:
-static struct pinmux_map __initdata pmx_mapping[] = {
- PINMUX_MAP("I2CMAP", "pinctrl-foo", "i2c0", "foo-i2c.0"),
+static struct pinctrl_map __initdata mapping[] = {
+ PIN_MAP_MUX_GROUP("foo-i2c.o", PINCTRL_STATE_DEFAULT, "pinctrl-foo", NULL, "i2c0"),
+};
+
+The mapping table may also contain pin configuration entries. It's common for
+each pin/group to have a number of configuration entries that affect it, so
+the table entries for configuration reference an array of config parameters
+and values. An example using the convenience macros is shown below:
+
+static unsigned long i2c_grp_configs[] = {
+ FOO_PIN_DRIVEN,
+ FOO_PIN_PULLUP,
+};
+
+static unsigned long i2c_pin_configs[] = {
+ FOO_OPEN_COLLECTOR,
+ FOO_SLEW_RATE_SLOW,
+};
+
+static struct pinctrl_map __initdata mapping[] = {
+ PIN_MAP_MUX_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", "i2c0"),
+ PIN_MAP_MUX_CONFIGS_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", i2c_grp_configs),
+ PIN_MAP_MUX_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0scl", i2c_pin_configs),
+ PIN_MAP_MUX_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0sda", i2c_pin_configs),
+};
+
+Finally, some devices expect the mapping table to contain certain specific
+named states. When running on hardware that doesn't need any pin controller
+configuration, the mapping table must still contain those named states, in
+order to explicitly indicate that the states were provided and intended to
+be empty. Table entry macro PIN_MAP_DUMMY_STATE serves the purpose of defining
+a named state without causing any pin controller to be programmed:
+
+static struct pinctrl_map __initdata mapping[] = {
+ PIN_MAP_DUMMY_STATE("foo-i2c.0", PINCTRL_STATE_DEFAULT),
};
@@ -831,81 +872,96 @@ As it is possible to map a function to different groups of pins an optional
...
{
+ .dev_name = "foo-spi.0",
.name = "spi0-pos-A",
+ .type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "spi0",
.group = "spi0_0_grp",
- .dev_name = "foo-spi.0",
},
{
+ .dev_name = "foo-spi.0",
.name = "spi0-pos-B",
+ .type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "spi0",
.group = "spi0_1_grp",
- .dev_name = "foo-spi.0",
},
...
This example mapping is used to switch between two positions for spi0 at
runtime, as described further below under the heading "Runtime pinmuxing".
-Further it is possible to match several groups of pins to the same function
-for a single device, say for example in the mmc0 example above, where you can
+Further it is possible for one named state to affect the muxing of several
+groups of pins, say for example in the mmc0 example above, where you can
additively expand the mmc0 bus from 2 to 4 to 8 pins. If we want to use all
three groups for a total of 2+2+4 = 8 pins (for an 8-bit MMC bus as is the
case), we define a mapping like this:
...
{
+ .dev_name = "foo-mmc.0",
.name = "2bit"
+ .type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_1_grp",
- .dev_name = "foo-mmc.0",
},
{
+ .dev_name = "foo-mmc.0",
.name = "4bit"
+ .type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_1_grp",
- .dev_name = "foo-mmc.0",
},
{
+ .dev_name = "foo-mmc.0",
.name = "4bit"
+ .type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_2_grp",
- .dev_name = "foo-mmc.0",
},
{
+ .dev_name = "foo-mmc.0",
.name = "8bit"
+ .type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
+ .function = "mmc0",
.group = "mmc0_1_grp",
- .dev_name = "foo-mmc.0",
},
{
+ .dev_name = "foo-mmc.0",
.name = "8bit"
+ .type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_2_grp",
- .dev_name = "foo-mmc.0",
},
{
+ .dev_name = "foo-mmc.0",
.name = "8bit"
+ .type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_3_grp",
- .dev_name = "foo-mmc.0",
},
...
The result of grabbing this mapping from the device with something like
this (see next paragraph):
- pmx = pinmux_get(&device, "8bit");
+ p = pinctrl_get(dev);
+ s = pinctrl_lookup_state(p, "8bit");
+ ret = pinctrl_select_state(p, s);
+
+or more simply:
+
+ p = pinctrl_get_select(dev, "8bit");
Will be that you activate all the three bottom records in the mapping at
-once. Since they share the same name, pin controller device, funcion and
+once. Since they share the same name, pin controller device, function and
device, and since we allow multiple groups to match to a single device, they
all get selected, and they all get enabled and disable simultaneously by the
pinmux core.
@@ -914,97 +970,111 @@ pinmux core.
Pinmux requests from drivers
============================
-Generally it is discouraged to let individual drivers get and enable pinmuxes.
-So if possible, handle the pinmuxes in platform code or some other place where
-you have access to all the affected struct device * pointers. In some cases
-where a driver needs to switch between different mux mappings at runtime
-this is not possible.
+Generally it is discouraged to let individual drivers get and enable pin
+control. So if possible, handle the pin control in platform code or some other
+place where you have access to all the affected struct device * pointers. In
+some cases where a driver needs to e.g. switch between different mux mappings
+at runtime this is not possible.
-A driver may request a certain mux to be activated, usually just the default
-mux like this:
+A driver may request a certain control state to be activated, usually just the
+default state like this:
-#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/consumer.h>
struct foo_state {
- struct pinmux *pmx;
+ struct pinctrl *p;
+ struct pinctrl_state *s;
...
};
foo_probe()
{
- /* Allocate a state holder named "state" etc */
- struct pinmux pmx;
+ /* Allocate a state holder named "foo" etc */
+ struct foo_state *foo = ...;
+
+ foo->p = pinctrl_get(&device);
+ if (IS_ERR(foo->p)) {
+ /* FIXME: clean up "foo" here */
+ return PTR_ERR(foo->p);
+ }
- pmx = pinmux_get(&device, NULL);
- if IS_ERR(pmx)
- return PTR_ERR(pmx);
- pinmux_enable(pmx);
+ foo->s = pinctrl_lookup_state(foo->p, PINCTRL_STATE_DEFAULT);
+ if (IS_ERR(foo->s)) {
+ pinctrl_put(foo->p);
+ /* FIXME: clean up "foo" here */
+ return PTR_ERR(s);
+ }
- state->pmx = pmx;
+ ret = pinctrl_select_state(foo->s);
+ if (ret < 0) {
+ pinctrl_put(foo->p);
+ /* FIXME: clean up "foo" here */
+ return ret;
+ }
}
foo_remove()
{
- pinmux_disable(state->pmx);
- pinmux_put(state->pmx);
+ pinctrl_put(state->p);
}
-If you want to grab a specific mux mapping and not just the first one found for
-this device you can specify a specific mapping name, for example in the above
-example the second i2c0 setting: pinmux_get(&device, "spi0-pos-B");
-
-This get/enable/disable/put sequence can just as well be handled by bus drivers
+This get/lookup/select/put sequence can just as well be handled by bus drivers
if you don't want each and every driver to handle it and you know the
arrangement on your bus.
-The semantics of the get/enable respective disable/put is as follows:
+The semantics of the pinctrl APIs are:
+
+- pinctrl_get() is called in process context to obtain a handle to all pinctrl
+ information for a given client device. It will allocate a struct from the
+ kernel memory to hold the pinmux state. All mapping table parsing or similar
+ slow operations take place within this API.
-- pinmux_get() is called in process context to reserve the pins affected with
- a certain mapping and set up the pinmux core and the driver. It will allocate
- a struct from the kernel memory to hold the pinmux state.
+- pinctrl_lookup_state() is called in process context to obtain a handle to a
+ specific state for a the client device. This operation may be slow too.
-- pinmux_enable()/pinmux_disable() is quick and can be called from fastpath
- (irq context) when you quickly want to set up/tear down the hardware muxing
- when running a device driver. Usually it will just poke some values into a
- register.
+- pinctrl_select_state() programs pin controller hardware according to the
+ definition of the state as given by the mapping table. In theory this is a
+ fast-path operation, since it only involved blasting some register settings
+ into hardware. However, note that some pin controllers may have their
+ registers on a slow/IRQ-based bus, so client devices should not assume they
+ can call pinctrl_select_state() from non-blocking contexts.
-- pinmux_disable() is called in process context to tear down the pin requests
- and release the state holder struct for the mux setting.
+- pinctrl_put() frees all information associated with a pinctrl handle.
-Usually the pinmux core handled the get/put pair and call out to the device
-drivers bookkeeping operations, like checking available functions and the
-associated pins, whereas the enable/disable pass on to the pin controller
+Usually the pin control core handled the get/put pair and call out to the
+device drivers bookkeeping operations, like checking available functions and
+the associated pins, whereas the enable/disable pass on to the pin controller
driver which takes care of activating and/or deactivating the mux setting by
quickly poking some registers.
-The pins are allocated for your device when you issue the pinmux_get() call,
+The pins are allocated for your device when you issue the pinctrl_get() call,
after this you should be able to see this in the debugfs listing of all pins.
-System pinmux hogging
-=====================
+System pin control hogging
+==========================
-A system pinmux map entry, i.e. a pinmux setting that does not have a device
-associated with it, can be hogged by the core when the pin controller is
-registered. This means that the core will attempt to call pinmux_get() and
-pinmux_enable() on it immediately after the pin control device has been
-registered.
+Pin control map entries can be hogged by the core when the pin controller
+is registered. This means that the core will attempt to call pinctrl_get(),
+lookup_state() and select_state() on it immediately after the pin control
+device has been registered.
-This is enabled by simply setting the .hog_on_boot field in the map to true,
-like this:
+This occurs for mapping table entries where the client device name is equal
+to the pin controller device name, and the state name is PINCTRL_STATE_DEFAULT.
{
- .name = "POWERMAP"
+ .dev_name = "pinctrl-foo",
+ .name = PINCTRL_STATE_DEFAULT,
+ .type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "power_func",
- .hog_on_boot = true,
},
Since it may be common to request the core to hog a few always-applicable
mux settings on the primary pin controller, there is a convenience macro for
this:
-PINMUX_MAP_PRIMARY_SYS_HOG("POWERMAP", "power_func")
+PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-foo", NULL /* group */, "power_func")
This gives the exact same result as the above construction.
@@ -1016,32 +1086,47 @@ It is possible to mux a certain function in and out at runtime, say to move
an SPI port from one set of pins to another set of pins. Say for example for
spi0 in the example above, we expose two different groups of pins for the same
function, but with different named in the mapping as described under
-"Advanced mapping" above. So we have two mappings named "spi0-pos-A" and
-"spi0-pos-B".
+"Advanced mapping" above. So that for an SPI device, we have two states named
+"pos-A" and "pos-B".
This snippet first muxes the function in the pins defined by group A, enables
it, disables and releases it, and muxes it in on the pins defined by group B:
+#include <linux/pinctrl/consumer.h>
+
foo_switch()
{
- struct pinmux *pmx;
+ struct pinctrl *p;
+ struct pinctrl_state *s1, *s2;
+
+ /* Setup */
+ p = pinctrl_get(&device);
+ if (IS_ERR(p))
+ ...
+
+ s1 = pinctrl_lookup_state(foo->p, "pos-A");
+ if (IS_ERR(s1))
+ ...
+
+ s2 = pinctrl_lookup_state(foo->p, "pos-B");
+ if (IS_ERR(s2))
+ ...
/* Enable on position A */
- pmx = pinmux_get(&device, "spi0-pos-A");
- if IS_ERR(pmx)
- return PTR_ERR(pmx);
- pinmux_enable(pmx);
+ ret = pinctrl_select_state(s1);
+ if (ret < 0)
+ ...
- /* This releases the pins again */
- pinmux_disable(pmx);
- pinmux_put(pmx);
+ ...
/* Enable on position B */
- pmx = pinmux_get(&device, "spi0-pos-B");
- if IS_ERR(pmx)
- return PTR_ERR(pmx);
- pinmux_enable(pmx);
+ ret = pinctrl_select_state(s2);
+ if (ret < 0)
+ ...
+
...
+
+ pinctrl_put(p);
}
The above has to be done from process context.
diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c
index b4c6926..f326d31 100644
--- a/arch/arm/mach-u300/core.c
+++ b/arch/arm/mach-u300/core.c
@@ -26,7 +26,7 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/fsmc.h>
#include <linux/pinctrl/machine.h>
-#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/consumer.h>
#include <linux/dma-mapping.h>
#include <asm/types.h>
@@ -1477,7 +1477,7 @@ static struct coh901318_platform coh901318_platform = {
.max_channels = U300_DMA_CHANNELS,
};
-static struct resource pinmux_resources[] = {
+static struct resource pinctrl_resources[] = {
{
.start = U300_SYSCON_BASE,
.end = U300_SYSCON_BASE + SZ_4K - 1,
@@ -1506,6 +1506,13 @@ static struct platform_device i2c1_device = {
.resource = i2c1_resources,
};
+static struct platform_device pinctrl_device = {
+ .name = "pinctrl-u300",
+ .id = -1,
+ .num_resources = ARRAY_SIZE(pinctrl_resources),
+ .resource = pinctrl_resources,
+};
+
/*
* The different variants have a few different versions of the
* GPIO block, with different number of ports.
@@ -1525,6 +1532,7 @@ static struct u300_gpio_platform u300_gpio_plat = {
#endif
.gpio_base = 0,
.gpio_irq_base = IRQ_U300_GPIO_BASE,
+ .pinctrl_device = &pinctrl_device,
};
static struct platform_device gpio_device = {
@@ -1597,71 +1605,54 @@ static struct platform_device dma_device = {
},
};
-static struct platform_device pinmux_device = {
- .name = "pinmux-u300",
- .id = -1,
- .num_resources = ARRAY_SIZE(pinmux_resources),
- .resource = pinmux_resources,
-};
-
/* Pinmux settings */
-static struct pinmux_map __initdata u300_pinmux_map[] = {
+static struct pinctrl_map __initdata u300_pinmux_map[] = {
/* anonymous maps for chip power and EMIFs */
- PINMUX_MAP_SYS_HOG("POWER", "pinmux-u300", "power"),
- PINMUX_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"),
- PINMUX_MAP_SYS_HOG("EMIF1", "pinmux-u300", "emif1"),
+ PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "power"),
+ PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif0"),
+ PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif1"),
/* per-device maps for MMC/SD, SPI and UART */
- PINMUX_MAP("MMCSD", "pinmux-u300", "mmc0", "mmci"),
- PINMUX_MAP("SPI", "pinmux-u300", "spi0", "pl022"),
- PINMUX_MAP("UART0", "pinmux-u300", "uart0", "uart0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("mmci", "pinctrl-u300", NULL, "mmc0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("pl022", "pinctrl-u300", NULL, "spi0"),
+ PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-u300", NULL, "uart0"),
};
struct u300_mux_hog {
- const char *name;
struct device *dev;
- struct pinmux *pmx;
+ struct pinctrl *p;
};
static struct u300_mux_hog u300_mux_hogs[] = {
{
- .name = "uart0",
.dev = &uart0_device.dev,
},
{
- .name = "spi0",
.dev = &pl022_device.dev,
},
{
- .name = "mmc0",
.dev = &mmcsd_device.dev,
},
};
-static int __init u300_pinmux_fetch(void)
+static int __init u300_pinctrl_fetch(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(u300_mux_hogs); i++) {
- struct pinmux *pmx;
+ struct pinctrl *p;
int ret;
- pmx = pinmux_get(u300_mux_hogs[i].dev, NULL);
- if (IS_ERR(pmx)) {
- pr_err("u300: could not get pinmux hog %s\n",
- u300_mux_hogs[i].name);
- continue;
- }
- ret = pinmux_enable(pmx);
- if (ret) {
- pr_err("u300: could enable pinmux hog %s\n",
- u300_mux_hogs[i].name);
+ p = pinctrl_get_select_default(u300_mux_hogs[i].dev);
+ if (IS_ERR(p)) {
+ pr_err("u300: could not get pinmux hog for dev %s\n",
+ dev_name(u300_mux_hogs[i].dev));
continue;
}
- u300_mux_hogs[i].pmx = pmx;
+ u300_mux_hogs[i].p = p;
}
return 0;
}
-subsys_initcall(u300_pinmux_fetch);
+subsys_initcall(u300_pinctrl_fetch);
/*
* Notice that AMBA devices are initialized before platform devices.
@@ -1676,7 +1667,6 @@ static struct platform_device *platform_devs[] __initdata = {
&gpio_device,
&nand_device,
&wdog_device,
- &pinmux_device,
};
/*
@@ -1861,8 +1851,8 @@ void __init u300_init_devices(void)
u300_assign_physmem();
/* Initialize pinmuxing */
- pinmux_register_mappings(u300_pinmux_map,
- ARRAY_SIZE(u300_pinmux_map));
+ pinctrl_register_mappings(u300_pinmux_map,
+ ARRAY_SIZE(u300_pinmux_map));
/* Register subdevices on the I2C buses */
u300_i2c_register_board_devices();
diff --git a/arch/arm/mach-u300/include/mach/gpio-u300.h b/arch/arm/mach-u300/include/mach/gpio-u300.h
index bf4c793..e81400c 100644
--- a/arch/arm/mach-u300/include/mach/gpio-u300.h
+++ b/arch/arm/mach-u300/include/mach/gpio-u300.h
@@ -24,12 +24,14 @@ enum u300_gpio_variant {
* @ports: number of GPIO block ports
* @gpio_base: first GPIO number for this block (use a free range)
* @gpio_irq_base: first GPIO IRQ number for this block (use a free range)
+ * @pinctrl_device: pin control device to spawn as child
*/
struct u300_gpio_platform {
enum u300_gpio_variant variant;
u8 ports;
int gpio_base;
int gpio_irq_base;
+ struct platform_device *pinctrl_device;
};
#endif /* __MACH_U300_GPIO_U300_H */
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index 4beb5f6..c6d29ff 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -23,6 +23,28 @@ config DEBUG_PINCTRL
help
Say Y here to add some extra checks and diagnostics to PINCTRL calls.
+config PINCTRL_PXA3xx
+ bool
+ select PINMUX
+
+config PINCTRL_MMP2
+ bool "MMP2 pin controller driver"
+ depends on ARCH_MMP
+ select PINCTRL_PXA3xx
+ select PINCONF
+
+config PINCTRL_PXA168
+ bool "PXA168 pin controller driver"
+ depends on ARCH_MMP
+ select PINCTRL_PXA3xx
+ select PINCONF
+
+config PINCTRL_PXA910
+ bool "PXA910 pin controller driver"
+ depends on ARCH_MMP
+ select PINCTRL_PXA3xx
+ select PINCONF
+
config PINCTRL_SIRF
bool "CSR SiRFprimaII pin controller driver"
depends on ARCH_PRIMA2
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index be38455..754329b 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -5,6 +5,10 @@ ccflags-$(CONFIG_DEBUG_PINCTRL) += -DDEBUG
obj-$(CONFIG_PINCTRL) += core.o
obj-$(CONFIG_PINMUX) += pinmux.o
obj-$(CONFIG_PINCONF) += pinconf.o
+obj-$(CONFIG_PINCTRL_PXA3xx) += pinctrl-pxa3xx.o
+obj-$(CONFIG_PINCTRL_MMP2) += pinctrl-mmp2.o
+obj-$(CONFIG_PINCTRL_PXA168) += pinctrl-pxa168.o
+obj-$(CONFIG_PINCTRL_PXA910) += pinctrl-pxa910.o
obj-$(CONFIG_PINCTRL_SIRF) += pinctrl-sirf.o
obj-$(CONFIG_PINCTRL_TEGRA) += pinctrl-tegra.o
obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c
index 8fe15cf..ec3b8cc 100644
--- a/drivers/pinctrl/core.c
+++ b/drivers/pinctrl/core.c
@@ -1,12 +1,14 @@
/*
* Core driver for the pin control subsystem
*
- * Copyright (C) 2011 ST-Ericsson SA
+ * Copyright (C) 2011-2012 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
* Based on bits of regulator core, gpio core and clk core
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
+ * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
+ *
* License terms: GNU General Public License (GPL) version 2
*/
#define pr_fmt(fmt) "pinctrl core: " fmt
@@ -16,11 +18,8 @@
#include <linux/init.h>
#include <linux/device.h>
#include <linux/slab.h>
-#include <linux/radix-tree.h>
#include <linux/err.h>
#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/spinlock.h>
#include <linux/sysfs.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
@@ -30,10 +29,36 @@
#include "pinmux.h"
#include "pinconf.h"
-/* Global list of pin control devices */
-static DEFINE_MUTEX(pinctrldev_list_mutex);
+/**
+ * struct pinctrl_maps - a list item containing part of the mapping table
+ * @node: mapping table list node
+ * @maps: array of mapping table entries
+ * @num_maps: the number of entries in @maps
+ */
+struct pinctrl_maps {
+ struct list_head node;
+ struct pinctrl_map const *maps;
+ unsigned num_maps;
+};
+
+/* Mutex taken by all entry points */
+DEFINE_MUTEX(pinctrl_mutex);
+
+/* Global list of pin control devices (struct pinctrl_dev) */
static LIST_HEAD(pinctrldev_list);
+/* List of pin controller handles (struct pinctrl) */
+static LIST_HEAD(pinctrl_list);
+
+/* List of pinctrl maps (struct pinctrl_maps) */
+static LIST_HEAD(pinctrl_maps);
+
+#define for_each_maps(_maps_node_, _i_, _map_) \
+ list_for_each_entry(_maps_node_, &pinctrl_maps, node) \
+ for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \
+ _i_ < _maps_node_->num_maps; \
+ i++, _map_ = &_maps_node_->maps[_i_])
+
const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev)
{
/* We're not allowed to register devices without name */
@@ -48,53 +73,31 @@ void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev)
EXPORT_SYMBOL_GPL(pinctrl_dev_get_drvdata);
/**
- * get_pinctrl_dev_from_dev() - look up pin controller device
- * @dev: a device pointer, this may be NULL but then devname needs to be
- * defined instead
- * @devname: the name of a device instance, as returned by dev_name(), this
- * may be NULL but then dev needs to be defined instead
+ * get_pinctrl_dev_from_devname() - look up pin controller device
+ * @devname: the name of a device instance, as returned by dev_name()
*
* Looks up a pin control device matching a certain device name or pure device
* pointer, the pure device pointer will take precedence.
*/
-struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev,
- const char *devname)
+struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname)
{
struct pinctrl_dev *pctldev = NULL;
bool found = false;
- mutex_lock(&pinctrldev_list_mutex);
- list_for_each_entry(pctldev, &pinctrldev_list, node) {
- if (dev && pctldev->dev == dev) {
- /* Matched on device pointer */
- found = true;
- break;
- }
+ if (!devname)
+ return NULL;
- if (devname &&
- !strcmp(dev_name(pctldev->dev), devname)) {
+ list_for_each_entry(pctldev, &pinctrldev_list, node) {
+ if (!strcmp(dev_name(pctldev->dev), devname)) {
/* Matched on device name */
found = true;
break;
}
}
- mutex_unlock(&pinctrldev_list_mutex);
return found ? pctldev : NULL;
}
-struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin)
-{
- struct pin_desc *pindesc;
- unsigned long flags;
-
- spin_lock_irqsave(&pctldev->pin_desc_tree_lock, flags);
- pindesc = radix_tree_lookup(&pctldev->pin_desc_tree, pin);
- spin_unlock_irqrestore(&pctldev->pin_desc_tree_lock, flags);
-
- return pindesc;
-}
-
/**
* pin_get_from_name() - look up a pin number from a name
* @pctldev: the pin control device to lookup the pin on
@@ -135,11 +138,11 @@ bool pin_is_valid(struct pinctrl_dev *pctldev, int pin)
if (pin < 0)
return false;
+ mutex_lock(&pinctrl_mutex);
pindesc = pin_desc_get(pctldev, pin);
- if (pindesc == NULL)
- return false;
+ mutex_unlock(&pinctrl_mutex);
- return true;
+ return pindesc != NULL;
}
EXPORT_SYMBOL_GPL(pin_is_valid);
@@ -150,7 +153,6 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev,
{
int i;
- spin_lock(&pctldev->pin_desc_tree_lock);
for (i = 0; i < num_pins; i++) {
struct pin_desc *pindesc;
@@ -164,7 +166,6 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev,
}
kfree(pindesc);
}
- spin_unlock(&pctldev->pin_desc_tree_lock);
}
static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
@@ -180,16 +181,16 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
}
pindesc = kzalloc(sizeof(*pindesc), GFP_KERNEL);
- if (pindesc == NULL)
+ if (pindesc == NULL) {
+ dev_err(pctldev->dev, "failed to alloc struct pin_desc\n");
return -ENOMEM;
-
- spin_lock_init(&pindesc->lock);
+ }
/* Set owner */
pindesc->pctldev = pctldev;
/* Copy basic pin info */
- if (pindesc->name) {
+ if (name) {
pindesc->name = name;
} else {
pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", number);
@@ -198,9 +199,7 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
pindesc->dynamic_name = true;
}
- spin_lock(&pctldev->pin_desc_tree_lock);
radix_tree_insert(&pctldev->pin_desc_tree, number, pindesc);
- spin_unlock(&pctldev->pin_desc_tree_lock);
pr_debug("registered pin %d (%s) on %s\n",
number, pindesc->name, pctldev->desc->name);
return 0;
@@ -237,16 +236,13 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio)
struct pinctrl_gpio_range *range = NULL;
/* Loop over the ranges */
- mutex_lock(&pctldev->gpio_ranges_lock);
list_for_each_entry(range, &pctldev->gpio_ranges, node) {
/* Check if we're in the valid range */
if (gpio >= range->base &&
gpio < range->base + range->npins) {
- mutex_unlock(&pctldev->gpio_ranges_lock);
return range;
}
}
- mutex_unlock(&pctldev->gpio_ranges_lock);
return NULL;
}
@@ -261,14 +257,13 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio)
* the GPIO subsystem, return the device and the matching GPIO range. Returns
* negative if the GPIO range could not be found in any device.
*/
-int pinctrl_get_device_gpio_range(unsigned gpio,
- struct pinctrl_dev **outdev,
- struct pinctrl_gpio_range **outrange)
+static int pinctrl_get_device_gpio_range(unsigned gpio,
+ struct pinctrl_dev **outdev,
+ struct pinctrl_gpio_range **outrange)
{
struct pinctrl_dev *pctldev = NULL;
/* Loop over the pin controllers */
- mutex_lock(&pinctrldev_list_mutex);
list_for_each_entry(pctldev, &pinctrldev_list, node) {
struct pinctrl_gpio_range *range;
@@ -276,11 +271,9 @@ int pinctrl_get_device_gpio_range(unsigned gpio,
if (range != NULL) {
*outdev = pctldev;
*outrange = range;
- mutex_unlock(&pinctrldev_list_mutex);
return 0;
}
}
- mutex_unlock(&pinctrldev_list_mutex);
return -EINVAL;
}
@@ -296,10 +289,11 @@ int pinctrl_get_device_gpio_range(unsigned gpio,
void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range)
{
- mutex_lock(&pctldev->gpio_ranges_lock);
- list_add(&range->node, &pctldev->gpio_ranges);
- mutex_unlock(&pctldev->gpio_ranges_lock);
+ mutex_lock(&pinctrl_mutex);
+ list_add_tail(&range->node, &pctldev->gpio_ranges);
+ mutex_unlock(&pinctrl_mutex);
}
+EXPORT_SYMBOL_GPL(pinctrl_add_gpio_range);
/**
* pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller
@@ -309,10 +303,11 @@ void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev,
void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range)
{
- mutex_lock(&pctldev->gpio_ranges_lock);
+ mutex_lock(&pinctrl_mutex);
list_del(&range->node);
- mutex_unlock(&pctldev->gpio_ranges_lock);
+ mutex_unlock(&pinctrl_mutex);
}
+EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range);
/**
* pinctrl_get_group_selector() - returns the group selector for a group
@@ -345,6 +340,531 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
return -EINVAL;
}
+/**
+ * pinctrl_request_gpio() - request a single pin to be used in as GPIO
+ * @gpio: the GPIO pin number from the GPIO subsystem number space
+ *
+ * This function should *ONLY* be used from gpiolib-based GPIO drivers,
+ * as part of their gpio_request() semantics, platforms and individual drivers
+ * shall *NOT* request GPIO pins to be muxed in.
+ */
+int pinctrl_request_gpio(unsigned gpio)
+{
+ struct pinctrl_dev *pctldev;
+ struct pinctrl_gpio_range *range;
+ int ret;
+ int pin;
+
+ mutex_lock(&pinctrl_mutex);
+
+ ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
+ if (ret) {
+ mutex_unlock(&pinctrl_mutex);
+ return -EINVAL;
+ }
+
+ /* Convert to the pin controllers number space */
+ pin = gpio - range->base + range->pin_base;
+
+ ret = pinmux_request_gpio(pctldev, range, pin, gpio);
+
+ mutex_unlock(&pinctrl_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pinctrl_request_gpio);
+
+/**
+ * pinctrl_free_gpio() - free control on a single pin, currently used as GPIO
+ * @gpio: the GPIO pin number from the GPIO subsystem number space
+ *
+ * This function should *ONLY* be used from gpiolib-based GPIO drivers,
+ * as part of their gpio_free() semantics, platforms and individual drivers
+ * shall *NOT* request GPIO pins to be muxed out.
+ */
+void pinctrl_free_gpio(unsigned gpio)
+{
+ struct pinctrl_dev *pctldev;
+ struct pinctrl_gpio_range *range;
+ int ret;
+ int pin;
+
+ mutex_lock(&pinctrl_mutex);
+
+ ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
+ if (ret) {
+ mutex_unlock(&pinctrl_mutex);
+ return;
+ }
+
+ /* Convert to the pin controllers number space */
+ pin = gpio - range->base + range->pin_base;
+
+ pinmux_free_gpio(pctldev, pin, range);
+
+ mutex_unlock(&pinctrl_mutex);
+}
+EXPORT_SYMBOL_GPL(pinctrl_free_gpio);
+
+static int pinctrl_gpio_direction(unsigned gpio, bool input)
+{
+ struct pinctrl_dev *pctldev;
+ struct pinctrl_gpio_range *range;
+ int ret;
+ int pin;
+
+ ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
+ if (ret)
+ return ret;
+
+ /* Convert to the pin controllers number space */
+ pin = gpio - range->base + range->pin_base;
+
+ return pinmux_gpio_direction(pctldev, range, pin, input);
+}
+
+/**
+ * pinctrl_gpio_direction_input() - request a GPIO pin to go into input mode
+ * @gpio: the GPIO pin number from the GPIO subsystem number space
+ *
+ * This function should *ONLY* be used from gpiolib-based GPIO drivers,
+ * as part of their gpio_direction_input() semantics, platforms and individual
+ * drivers shall *NOT* touch pin control GPIO calls.
+ */
+int pinctrl_gpio_direction_input(unsigned gpio)
+{
+ int ret;
+ mutex_lock(&pinctrl_mutex);
+ ret = pinctrl_gpio_direction(gpio, true);
+ mutex_unlock(&pinctrl_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input);
+
+/**
+ * pinctrl_gpio_direction_output() - request a GPIO pin to go into output mode
+ * @gpio: the GPIO pin number from the GPIO subsystem number space
+ *
+ * This function should *ONLY* be used from gpiolib-based GPIO drivers,
+ * as part of their gpio_direction_output() semantics, platforms and individual
+ * drivers shall *NOT* touch pin control GPIO calls.
+ */
+int pinctrl_gpio_direction_output(unsigned gpio)
+{
+ int ret;
+ mutex_lock(&pinctrl_mutex);
+ ret = pinctrl_gpio_direction(gpio, false);
+ mutex_unlock(&pinctrl_mutex);
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output);
+
+static struct pinctrl_state *find_state(struct pinctrl *p,
+ const char *name)
+{
+ struct pinctrl_state *state;
+
+ list_for_each_entry(state, &p->states, node)
+ if (!strcmp(state->name, name))
+ return state;
+
+ return NULL;
+}
+
+static struct pinctrl_state *create_state(struct pinctrl *p,
+ const char *name)
+{
+ struct pinctrl_state *state;
+
+ state = kzalloc(sizeof(*state), GFP_KERNEL);
+ if (state == NULL) {
+ dev_err(p->dev,
+ "failed to alloc struct pinctrl_state\n");
+ return ERR_PTR(-ENOMEM);
+ }
+
+ state->name = name;
+ INIT_LIST_HEAD(&state->settings);
+
+ list_add_tail(&state->node, &p->states);
+
+ return state;
+}
+
+static int add_setting(struct pinctrl *p, struct pinctrl_map const *map)
+{
+ struct pinctrl_state *state;
+ struct pinctrl_setting *setting;
+ int ret;
+
+ state = find_state(p, map->name);
+ if (!state)
+ state = create_state(p, map->name);
+ if (IS_ERR(state))
+ return PTR_ERR(state);
+
+ if (map->type == PIN_MAP_TYPE_DUMMY_STATE)
+ return 0;
+
+ setting = kzalloc(sizeof(*setting), GFP_KERNEL);
+ if (setting == NULL) {
+ dev_err(p->dev,
+ "failed to alloc struct pinctrl_setting\n");
+ return -ENOMEM;
+ }
+
+ setting->type = map->type;
+
+ setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name);
+ if (setting->pctldev == NULL) {
+ dev_err(p->dev, "unknown pinctrl device %s in map entry",
+ map->ctrl_dev_name);
+ kfree(setting);
+ /* Eventually, this should trigger deferred probe */
+ return -ENODEV;
+ }
+
+ switch (map->type) {
+ case PIN_MAP_TYPE_MUX_GROUP:
+ ret = pinmux_map_to_setting(map, setting);
+ break;
+ case PIN_MAP_TYPE_CONFIGS_PIN:
+ case PIN_MAP_TYPE_CONFIGS_GROUP:
+ ret = pinconf_map_to_setting(map, setting);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ if (ret < 0) {
+ kfree(setting);
+ return ret;
+ }
+
+ list_add_tail(&setting->node, &state->settings);
+
+ return 0;
+}
+
+static struct pinctrl *find_pinctrl(struct device *dev)
+{
+ struct pinctrl *p;
+
+ list_for_each_entry(p, &pinctrl_list, node)
+ if (p->dev == dev)
+ return p;
+
+ return NULL;
+}
+
+static void pinctrl_put_locked(struct pinctrl *p, bool inlist);
+
+static struct pinctrl *create_pinctrl(struct device *dev)
+{
+ struct pinctrl *p;
+ const char *devname;
+ struct pinctrl_maps *maps_node;
+ int i;
+ struct pinctrl_map const *map;
+ int ret;
+
+ /*
+ * create the state cookie holder struct pinctrl for each
+ * mapping, this is what consumers will get when requesting
+ * a pin control handle with pinctrl_get()
+ */
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
+ if (p == NULL) {
+ dev_err(dev, "failed to alloc struct pinctrl\n");
+ return ERR_PTR(-ENOMEM);
+ }
+ p->dev = dev;
+ INIT_LIST_HEAD(&p->states);
+
+ devname = dev_name(dev);
+
+ /* Iterate over the pin control maps to locate the right ones */
+ for_each_maps(maps_node, i, map) {
+ /* Map must be for this device */
+ if (strcmp(map->dev_name, devname))
+ continue;
+
+ ret = add_setting(p, map);
+ if (ret < 0) {
+ pinctrl_put_locked(p, false);
+ return ERR_PTR(ret);
+ }
+ }
+
+ /* Add the pinmux to the global list */
+ list_add_tail(&p->node, &pinctrl_list);
+
+ return p;
+}
+
+static struct pinctrl *pinctrl_get_locked(struct device *dev)
+{
+ struct pinctrl *p;
+
+ if (WARN_ON(!dev))
+ return ERR_PTR(-EINVAL);
+
+ p = find_pinctrl(dev);
+ if (p != NULL)
+ return ERR_PTR(-EBUSY);
+
+ p = create_pinctrl(dev);
+ if (IS_ERR(p))
+ return p;
+
+ return p;
+}
+
+/**
+ * pinctrl_get() - retrieves the pinctrl handle for a device
+ * @dev: the device to obtain the handle for
+ */
+struct pinctrl *pinctrl_get(struct device *dev)
+{
+ struct pinctrl *p;
+
+ mutex_lock(&pinctrl_mutex);
+ p = pinctrl_get_locked(dev);
+ mutex_unlock(&pinctrl_mutex);
+
+ return p;
+}
+EXPORT_SYMBOL_GPL(pinctrl_get);
+
+static void pinctrl_put_locked(struct pinctrl *p, bool inlist)
+{
+ struct pinctrl_state *state, *n1;
+ struct pinctrl_setting *setting, *n2;
+
+ list_for_each_entry_safe(state, n1, &p->states, node) {
+ list_for_each_entry_safe(setting, n2, &state->settings, node) {
+ switch (setting->type) {
+ case PIN_MAP_TYPE_MUX_GROUP:
+ if (state == p->state)
+ pinmux_disable_setting(setting);
+ pinmux_free_setting(setting);
+ break;
+ case PIN_MAP_TYPE_CONFIGS_PIN:
+ case PIN_MAP_TYPE_CONFIGS_GROUP:
+ pinconf_free_setting(setting);
+ break;
+ default:
+ break;
+ }
+ list_del(&setting->node);
+ kfree(setting);
+ }
+ list_del(&state->node);
+ kfree(state);
+ }
+
+ if (inlist)
+ list_del(&p->node);
+ kfree(p);
+}
+
+/**
+ * pinctrl_put() - release a previously claimed pinctrl handle
+ * @p: the pinctrl handle to release
+ */
+void pinctrl_put(struct pinctrl *p)
+{
+ mutex_lock(&pinctrl_mutex);
+ pinctrl_put_locked(p, true);
+ mutex_unlock(&pinctrl_mutex);
+}
+EXPORT_SYMBOL_GPL(pinctrl_put);
+
+static struct pinctrl_state *pinctrl_lookup_state_locked(struct pinctrl *p,
+ const char *name)
+{
+ struct pinctrl_state *state;
+
+ state = find_state(p, name);
+ if (!state)
+ return ERR_PTR(-ENODEV);
+
+ return state;
+}
+
+/**
+ * pinctrl_lookup_state() - retrieves a state handle from a pinctrl handle
+ * @p: the pinctrl handle to retrieve the state from
+ * @name: the state name to retrieve
+ */
+struct pinctrl_state *pinctrl_lookup_state(struct pinctrl *p, const char *name)
+{
+ struct pinctrl_state *s;
+
+ mutex_lock(&pinctrl_mutex);
+ s = pinctrl_lookup_state_locked(p, name);
+ mutex_unlock(&pinctrl_mutex);
+
+ return s;
+}
+EXPORT_SYMBOL_GPL(pinctrl_lookup_state);
+
+static int pinctrl_select_state_locked(struct pinctrl *p,
+ struct pinctrl_state *state)
+{
+ struct pinctrl_setting *setting, *setting2;
+ int ret;
+
+ if (p->state == state)
+ return 0;
+
+ if (p->state) {
+ /*
+ * The set of groups with a mux configuration in the old state
+ * may not be identical to the set of groups with a mux setting
+ * in the new state. While this might be unusual, it's entirely
+ * possible for the "user"-supplied mapping table to be written
+ * that way. For each group that was configured in the old state
+ * but not in the new state, this code puts that group into a
+ * safe/disabled state.
+ */
+ list_for_each_entry(setting, &p->state->settings, node) {
+ bool found = false;
+ if (setting->type != PIN_MAP_TYPE_MUX_GROUP)
+ continue;
+ list_for_each_entry(setting2, &state->settings, node) {
+ if (setting2->type != PIN_MAP_TYPE_MUX_GROUP)
+ continue;
+ if (setting2->data.mux.group ==
+ setting->data.mux.group) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ pinmux_disable_setting(setting);
+ }
+ }
+
+ p->state = state;
+
+ /* Apply all the settings for the new state */
+ list_for_each_entry(setting, &state->settings, node) {
+ switch (setting->type) {
+ case PIN_MAP_TYPE_MUX_GROUP:
+ ret = pinmux_enable_setting(setting);
+ break;
+ case PIN_MAP_TYPE_CONFIGS_PIN:
+ case PIN_MAP_TYPE_CONFIGS_GROUP:
+ ret = pinconf_apply_setting(setting);
+ break;
+ default:
+ ret = -EINVAL;
+ break;
+ }
+ if (ret < 0) {
+ /* FIXME: Difficult to return to prev state */
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
+/**
+ * pinctrl_select() - select/activate/program a pinctrl state to HW
+ * @p: the pinctrl handle for the device that requests configuratio
+ * @state: the state handle to select/activate/program
+ */
+int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state)
+{
+ int ret;
+
+ mutex_lock(&pinctrl_mutex);
+ ret = pinctrl_select_state_locked(p, state);
+ mutex_unlock(&pinctrl_mutex);
+
+ return ret;
+}
+EXPORT_SYMBOL_GPL(pinctrl_select_state);
+
+/**
+ * pinctrl_register_mappings() - register a set of pin controller mappings
+ * @maps: the pincontrol mappings table to register. This should probably be
+ * marked with __initdata so it can be discarded after boot. This
+ * function will perform a shallow copy for the mapping entries.
+ * @num_maps: the number of maps in the mapping table
+ */
+int pinctrl_register_mappings(struct pinctrl_map const *maps,
+ unsigned num_maps)
+{
+ int i, ret;
+ struct pinctrl_maps *maps_node;
+
+ pr_debug("add %d pinmux maps\n", num_maps);
+
+ /* First sanity check the new mapping */
+ for (i = 0; i < num_maps; i++) {
+ if (!maps[i].dev_name) {
+ pr_err("failed to register map %s (%d): no device given\n",
+ maps[i].name, i);
+ return -EINVAL;
+ }
+
+ if (!maps[i].name) {
+ pr_err("failed to register map %d: no map name given\n",
+ i);
+ return -EINVAL;
+ }
+
+ if (maps[i].type != PIN_MAP_TYPE_DUMMY_STATE &&
+ !maps[i].ctrl_dev_name) {
+ pr_err("failed to register map %s (%d): no pin control device given\n",
+ maps[i].name, i);
+ return -EINVAL;
+ }
+
+ switch (maps[i].type) {
+ case PIN_MAP_TYPE_DUMMY_STATE:
+ break;
+ case PIN_MAP_TYPE_MUX_GROUP:
+ ret = pinmux_validate_map(&maps[i], i);
+ if (ret < 0)
+ return 0;
+ break;
+ case PIN_MAP_TYPE_CONFIGS_PIN:
+ case PIN_MAP_TYPE_CONFIGS_GROUP:
+ ret = pinconf_validate_map(&maps[i], i);
+ if (ret < 0)
+ return 0;
+ break;
+ default:
+ pr_err("failed to register map %s (%d): invalid type given\n",
+ maps[i].name, i);
+ return -EINVAL;
+ }
+ }
+
+ maps_node = kzalloc(sizeof(*maps_node), GFP_KERNEL);
+ if (!maps_node) {
+ pr_err("failed to alloc struct pinctrl_maps\n");
+ return -ENOMEM;
+ }
+
+ maps_node->num_maps = num_maps;
+ maps_node->maps = kmemdup(maps, sizeof(*maps) * num_maps, GFP_KERNEL);
+ if (!maps_node->maps) {
+ pr_err("failed to duplicate mapping table\n");
+ kfree(maps_node);
+ return -ENOMEM;
+ }
+
+ mutex_lock(&pinctrl_mutex);
+ list_add_tail(&maps_node->node, &pinctrl_maps);
+ mutex_unlock(&pinctrl_mutex);
+
+ return 0;
+}
+
#ifdef CONFIG_DEBUG_FS
static int pinctrl_pins_show(struct seq_file *s, void *what)
@@ -355,6 +875,8 @@ static int pinctrl_pins_show(struct seq_file *s, void *what)
seq_printf(s, "registered pins: %d\n", pctldev->desc->npins);
+ mutex_lock(&pinctrl_mutex);
+
/* The pin number can be retrived from the pin controller descriptor */
for (i = 0; i < pctldev->desc->npins; i++) {
struct pin_desc *desc;
@@ -375,6 +897,8 @@ static int pinctrl_pins_show(struct seq_file *s, void *what)
seq_puts(s, "\n");
}
+ mutex_unlock(&pinctrl_mutex);
+
return 0;
}
@@ -388,6 +912,8 @@ static int pinctrl_groups_show(struct seq_file *s, void *what)
if (!ops)
return 0;
+ mutex_lock(&pinctrl_mutex);
+
seq_puts(s, "registered pin groups:\n");
while (ops->list_groups(pctldev, selector) >= 0) {
const unsigned *pins;
@@ -410,6 +936,7 @@ static int pinctrl_groups_show(struct seq_file *s, void *what)
selector++;
}
+ mutex_unlock(&pinctrl_mutex);
return 0;
}
@@ -421,8 +948,9 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what)
seq_puts(s, "GPIO ranges handled:\n");
+ mutex_lock(&pinctrl_mutex);
+
/* Loop over the ranges */
- mutex_lock(&pctldev->gpio_ranges_lock);
list_for_each_entry(range, &pctldev->gpio_ranges, node) {
seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n",
range->id, range->name,
@@ -430,7 +958,8 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what)
range->pin_base,
(range->pin_base + range->npins - 1));
}
- mutex_unlock(&pctldev->gpio_ranges_lock);
+
+ mutex_unlock(&pinctrl_mutex);
return 0;
}
@@ -440,7 +969,9 @@ static int pinctrl_devices_show(struct seq_file *s, void *what)
struct pinctrl_dev *pctldev;
seq_puts(s, "name [pinmux] [pinconf]\n");
- mutex_lock(&pinctrldev_list_mutex);
+
+ mutex_lock(&pinctrl_mutex);
+
list_for_each_entry(pctldev, &pinctrldev_list, node) {
seq_printf(s, "%s ", pctldev->desc->name);
if (pctldev->desc->pmxops)
@@ -453,7 +984,108 @@ static int pinctrl_devices_show(struct seq_file *s, void *what)
seq_puts(s, "no");
seq_puts(s, "\n");
}
- mutex_unlock(&pinctrldev_list_mutex);
+
+ mutex_unlock(&pinctrl_mutex);
+
+ return 0;
+}
+
+static inline const char *map_type(enum pinctrl_map_type type)
+{
+ static const char * const names[] = {
+ "INVALID",
+ "DUMMY_STATE",
+ "MUX_GROUP",
+ "CONFIGS_PIN",
+ "CONFIGS_GROUP",
+ };
+
+ if (type >= ARRAY_SIZE(names))
+ return "UNKNOWN";
+
+ return names[type];
+}
+
+static int pinctrl_maps_show(struct seq_file *s, void *what)
+{
+ struct pinctrl_maps *maps_node;
+ int i;
+ struct pinctrl_map const *map;
+
+ seq_puts(s, "Pinctrl maps:\n");
+
+ mutex_lock(&pinctrl_mutex);
+
+ for_each_maps(maps_node, i, map) {
+ seq_printf(s, "device %s\nstate %s\ntype %s (%d)\n",
+ map->dev_name, map->name, map_type(map->type),
+ map->type);
+
+ if (map->type != PIN_MAP_TYPE_DUMMY_STATE)
+ seq_printf(s, "controlling device %s\n",
+ map->ctrl_dev_name);
+
+ switch (map->type) {
+ case PIN_MAP_TYPE_MUX_GROUP:
+ pinmux_show_map(s, map);
+ break;
+ case PIN_MAP_TYPE_CONFIGS_PIN:
+ case PIN_MAP_TYPE_CONFIGS_GROUP:
+ pinconf_show_map(s, map);
+ break;
+ default:
+ break;
+ }
+
+ seq_printf(s, "\n");
+ }
+
+ mutex_unlock(&pinctrl_mutex);
+
+ return 0;
+}
+
+static int pinctrl_show(struct seq_file *s, void *what)
+{
+ struct pinctrl *p;
+ struct pinctrl_state *state;
+ struct pinctrl_setting *setting;
+
+ seq_puts(s, "Requested pin control handlers their pinmux maps:\n");
+
+ mutex_lock(&pinctrl_mutex);
+
+ list_for_each_entry(p, &pinctrl_list, node) {
+ seq_printf(s, "device: %s current state: %s\n",
+ dev_name(p->dev),
+ p->state ? p->state->name : "none");
+
+ list_for_each_entry(state, &p->states, node) {
+ seq_printf(s, " state: %s\n", state->name);
+
+ list_for_each_entry(setting, &state->settings, node) {
+ struct pinctrl_dev *pctldev = setting->pctldev;
+
+ seq_printf(s, " type: %s controller %s ",
+ map_type(setting->type),
+ pinctrl_dev_get_name(pctldev));
+
+ switch (setting->type) {
+ case PIN_MAP_TYPE_MUX_GROUP:
+ pinmux_show_setting(s, setting);
+ break;
+ case PIN_MAP_TYPE_CONFIGS_PIN:
+ case PIN_MAP_TYPE_CONFIGS_GROUP:
+ pinconf_show_setting(s, setting);
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ }
+
+ mutex_unlock(&pinctrl_mutex);
return 0;
}
@@ -478,6 +1110,16 @@ static int pinctrl_devices_open(struct inode *inode, struct file *file)
return single_open(file, pinctrl_devices_show, NULL);
}
+static int pinctrl_maps_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, pinctrl_maps_show, NULL);
+}
+
+static int pinctrl_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, pinctrl_show, NULL);
+}
+
static const struct file_operations pinctrl_pins_ops = {
.open = pinctrl_pins_open,
.read = seq_read,
@@ -506,6 +1148,20 @@ static const struct file_operations pinctrl_devices_ops = {
.release = single_release,
};
+static const struct file_operations pinctrl_maps_ops = {
+ .open = pinctrl_maps_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static const struct file_operations pinctrl_ops = {
+ .open = pinctrl_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
static struct dentry *debugfs_root;
static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
@@ -547,7 +1203,10 @@ static void pinctrl_init_debugfs(void)
debugfs_create_file("pinctrl-devices", S_IFREG | S_IRUGO,
debugfs_root, NULL, &pinctrl_devices_ops);
- pinmux_init_debugfs(debugfs_root);
+ debugfs_create_file("pinctrl-maps", S_IFREG | S_IRUGO,
+ debugfs_root, NULL, &pinctrl_maps_ops);
+ debugfs_create_file("pinctrl-handles", S_IFREG | S_IRUGO,
+ debugfs_root, NULL, &pinctrl_ops);
}
#else /* CONFIG_DEBUG_FS */
@@ -583,18 +1242,18 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
if (pctldesc->name == NULL)
return NULL;
- pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL);
- if (pctldev == NULL)
+ pctldev = kzalloc(sizeof(*pctldev), GFP_KERNEL);
+ if (pctldev == NULL) {
+ dev_err(dev, "failed to alloc struct pinctrl_dev\n");
return NULL;
+ }
/* Initialize pin control device struct */
pctldev->owner = pctldesc->owner;
pctldev->desc = pctldesc;
pctldev->driver_data = driver_data;
INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL);
- spin_lock_init(&pctldev->pin_desc_tree_lock);
INIT_LIST_HEAD(&pctldev->gpio_ranges);
- mutex_init(&pctldev->gpio_ranges_lock);
pctldev->dev = dev;
/* If we're implementing pinmuxing, check the ops for sanity */
@@ -628,11 +1287,23 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
goto out_err;
}
+ mutex_lock(&pinctrl_mutex);
+
+ list_add_tail(&pctldev->node, &pinctrldev_list);
+
+ pctldev->p = pinctrl_get_locked(pctldev->dev);
+ if (!IS_ERR(pctldev->p)) {
+ struct pinctrl_state *s =
+ pinctrl_lookup_state_locked(pctldev->p,
+ PINCTRL_STATE_DEFAULT);
+ if (!IS_ERR(s))
+ pinctrl_select_state_locked(pctldev->p, s);
+ }
+
+ mutex_unlock(&pinctrl_mutex);
+
pinctrl_init_device_debugfs(pctldev);
- mutex_lock(&pinctrldev_list_mutex);
- list_add(&pctldev->node, &pinctrldev_list);
- mutex_unlock(&pinctrldev_list_mutex);
- pinmux_hog_maps(pctldev);
+
return pctldev;
out_err:
@@ -653,15 +1324,20 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev)
return;
pinctrl_remove_device_debugfs(pctldev);
- pinmux_unhog_maps(pctldev);
+
+ mutex_lock(&pinctrl_mutex);
+
+ if (!IS_ERR(pctldev->p))
+ pinctrl_put_locked(pctldev->p, true);
+
/* TODO: check that no pinmuxes are still active? */
- mutex_lock(&pinctrldev_list_mutex);
list_del(&pctldev->node);
- mutex_unlock(&pinctrldev_list_mutex);
/* Destroy descriptor tree */
pinctrl_free_pindescs(pctldev, pctldev->desc->pins,
pctldev->desc->npins);
kfree(pctldev);
+
+ mutex_unlock(&pinctrl_mutex);
}
EXPORT_SYMBOL_GPL(pinctrl_unregister);
diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h
index cfa86da..efbfb62 100644
--- a/drivers/pinctrl/core.h
+++ b/drivers/pinctrl/core.h
@@ -9,7 +9,10 @@
* License terms: GNU General Public License (GPL) version 2
*/
+#include <linux/mutex.h>
+#include <linux/radix-tree.h>
#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/machine.h>
struct pinctrl_gpio_range;
@@ -20,34 +23,94 @@ struct pinctrl_gpio_range;
* controller
* @pin_desc_tree: each pin descriptor for this pin controller is stored in
* this radix tree
- * @pin_desc_tree_lock: lock for the descriptor tree
* @gpio_ranges: a list of GPIO ranges that is handled by this pin controller,
* ranges are added to this list at runtime
- * @gpio_ranges_lock: lock for the GPIO ranges list
* @dev: the device entry for this pin controller
* @owner: module providing the pin controller, used for refcounting
* @driver_data: driver data for drivers registering to the pin controller
* subsystem
- * @pinmux_hogs_lock: lock for the pinmux hog list
- * @pinmux_hogs: list of pinmux maps hogged by this device
+ * @p: result of pinctrl_get() for this device
+ * @device_root: debugfs root for this device
*/
struct pinctrl_dev {
struct list_head node;
struct pinctrl_desc *desc;
struct radix_tree_root pin_desc_tree;
- spinlock_t pin_desc_tree_lock;
struct list_head gpio_ranges;
- struct mutex gpio_ranges_lock;
struct device *dev;
struct module *owner;
void *driver_data;
+ struct pinctrl *p;
#ifdef CONFIG_DEBUG_FS
struct dentry *device_root;
#endif
-#ifdef CONFIG_PINMUX
- struct mutex pinmux_hogs_lock;
- struct list_head pinmux_hogs;
-#endif
+};
+
+/**
+ * struct pinctrl - per-device pin control state holder
+ * @node: global list node
+ * @dev: the device using this pin control handle
+ * @states: a list of states for this device
+ * @state: the current state
+ */
+struct pinctrl {
+ struct list_head node;
+ struct device *dev;
+ struct list_head states;
+ struct pinctrl_state *state;
+};
+
+/**
+ * struct pinctrl_state - a pinctrl state for a device
+ * @node: list not for struct pinctrl's @states field
+ * @name: the name of this state
+ * @settings: a list of settings for this state
+ */
+struct pinctrl_state {
+ struct list_head node;
+ const char *name;
+ struct list_head settings;
+};
+
+/**
+ * struct pinctrl_setting_mux - setting data for MAP_TYPE_MUX_GROUP
+ * @group: the group selector to program
+ * @func: the function selector to program
+ */
+struct pinctrl_setting_mux {
+ unsigned group;
+ unsigned func;
+};
+
+/**
+ * struct pinctrl_setting_configs - setting data for MAP_TYPE_CONFIGS_*
+ * @group_or_pin: the group selector or pin ID to program
+ * @configs: a pointer to an array of config parameters/values to program into
+ * hardware. Each individual pin controller defines the format and meaning
+ * of config parameters.
+ * @num_configs: the number of entries in array @configs
+ */
+struct pinctrl_setting_configs {
+ unsigned group_or_pin;
+ unsigned long *configs;
+ unsigned num_configs;
+};
+
+/**
+ * struct pinctrl_setting - an individual mux or config setting
+ * @node: list node for struct pinctrl_settings's @settings field
+ * @type: the type of setting
+ * @pctldev: pin control device handling to be programmed
+ * @data: Data specific to the setting type
+ */
+struct pinctrl_setting {
+ struct list_head node;
+ enum pinctrl_map_type type;
+ struct pinctrl_dev *pctldev;
+ union {
+ struct pinctrl_setting_mux mux;
+ struct pinctrl_setting_configs configs;
+ } data;
};
/**
@@ -56,28 +119,37 @@ struct pinctrl_dev {
* @name: a name for the pin, e.g. the name of the pin/pad/finger on a
* datasheet or such
* @dynamic_name: if the name of this pin was dynamically allocated
- * @lock: a lock to protect the descriptor structure
- * @mux_requested: whether the pin is already requested by pinmux or not
- * @mux_function: a named muxing function for the pin that will be passed to
- * subdrivers and shown in debugfs etc
+ * @usecount: If zero, the pin is not claimed, and @owner should be NULL.
+ * If non-zero, this pin is claimed by @owner. This field is an integer
+ * rather than a boolean, since pinctrl_get() might process multiple
+ * mapping table entries that refer to, and hence claim, the same group
+ * or pin, and each of these will increment the @usecount.
+ * @owner: The name of the entity owning the pin. Typically, this is the name
+ * of the device that called pinctrl_get(). Alternatively, it may be the
+ * name of the GPIO passed to pinctrl_request_gpio().
+ * @mux_setting: The most recent selected mux setting for this pin, if any.
*/
struct pin_desc {
struct pinctrl_dev *pctldev;
const char *name;
bool dynamic_name;
- spinlock_t lock;
/* These fields only added when supporting pinmux drivers */
#ifdef CONFIG_PINMUX
- const char *mux_function;
+ unsigned usecount;
+ const char *owner;
+ const struct pinctrl_setting_mux *mux_setting;
#endif
};
-struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev,
- const char *dev_name);
-struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin);
+struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name);
int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name);
-int pinctrl_get_device_gpio_range(unsigned gpio,
- struct pinctrl_dev **outdev,
- struct pinctrl_gpio_range **outrange);
int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
const char *pin_group);
+
+static inline struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev,
+ unsigned int pin)
+{
+ return radix_tree_lookup(&pctldev->pin_desc_tree, pin);
+}
+
+extern struct mutex pinctrl_mutex;
diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c
index 9fb7545..84869f2 100644
--- a/drivers/pinctrl/pinconf.c
+++ b/drivers/pinctrl/pinconf.c
@@ -23,7 +23,38 @@
#include "core.h"
#include "pinconf.h"
-int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
+int pinconf_check_ops(struct pinctrl_dev *pctldev)
+{
+ const struct pinconf_ops *ops = pctldev->desc->confops;
+
+ /* We must be able to read out pin status */
+ if (!ops->pin_config_get && !ops->pin_config_group_get)
+ return -EINVAL;
+ /* We have to be able to config the pins in SOME way */
+ if (!ops->pin_config_set && !ops->pin_config_group_set)
+ return -EINVAL;
+ return 0;
+}
+
+int pinconf_validate_map(struct pinctrl_map const *map, int i)
+{
+ if (!map->data.configs.group_or_pin) {
+ pr_err("failed to register map %s (%d): no group/pin given\n",
+ map->name, i);
+ return -EINVAL;
+ }
+
+ if (map->data.configs.num_configs &&
+ !map->data.configs.configs) {
+ pr_err("failed to register map %s (%d): no configs ptr given\n",
+ map->name, i);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long *config)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
@@ -51,19 +82,27 @@ int pin_config_get(const char *dev_name, const char *name,
struct pinctrl_dev *pctldev;
int pin;
- pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
- if (!pctldev)
- return -EINVAL;
+ mutex_lock(&pinctrl_mutex);
+
+ pctldev = get_pinctrl_dev_from_devname(dev_name);
+ if (!pctldev) {
+ pin = -EINVAL;
+ goto unlock;
+ }
pin = pin_get_from_name(pctldev, name);
if (pin < 0)
- return pin;
+ goto unlock;
+
+ pin = pin_config_get_for_pin(pctldev, pin, config);
- return pin_config_get_for_pin(pctldev, pin, config);
+unlock:
+ mutex_unlock(&pinctrl_mutex);
+ return pin;
}
EXPORT_SYMBOL(pin_config_get);
-int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
+static int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long config)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
@@ -97,17 +136,27 @@ int pin_config_set(const char *dev_name, const char *name,
unsigned long config)
{
struct pinctrl_dev *pctldev;
- int pin;
+ int pin, ret;
- pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
- if (!pctldev)
- return -EINVAL;
+ mutex_lock(&pinctrl_mutex);
+
+ pctldev = get_pinctrl_dev_from_devname(dev_name);
+ if (!pctldev) {
+ ret = -EINVAL;
+ goto unlock;
+ }
pin = pin_get_from_name(pctldev, name);
- if (pin < 0)
- return pin;
+ if (pin < 0) {
+ ret = pin;
+ goto unlock;
+ }
+
+ ret = pin_config_set_for_pin(pctldev, pin, config);
- return pin_config_set_for_pin(pctldev, pin, config);
+unlock:
+ mutex_unlock(&pinctrl_mutex);
+ return ret;
}
EXPORT_SYMBOL(pin_config_set);
@@ -116,29 +165,39 @@ int pin_config_group_get(const char *dev_name, const char *pin_group,
{
struct pinctrl_dev *pctldev;
const struct pinconf_ops *ops;
- int selector;
+ int selector, ret;
- pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
- if (!pctldev)
- return -EINVAL;
+ mutex_lock(&pinctrl_mutex);
+
+ pctldev = get_pinctrl_dev_from_devname(dev_name);
+ if (!pctldev) {
+ ret = -EINVAL;
+ goto unlock;
+ }
ops = pctldev->desc->confops;
if (!ops || !ops->pin_config_group_get) {
dev_err(pctldev->dev, "cannot get configuration for pin "
"group, missing group config get function in "
"driver\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto unlock;
}
selector = pinctrl_get_group_selector(pctldev, pin_group);
- if (selector < 0)
- return selector;
+ if (selector < 0) {
+ ret = selector;
+ goto unlock;
+ }
- return ops->pin_config_group_get(pctldev, selector, config);
+ ret = ops->pin_config_group_get(pctldev, selector, config);
+
+unlock:
+ mutex_unlock(&pinctrl_mutex);
+ return ret;
}
EXPORT_SYMBOL(pin_config_group_get);
-
int pin_config_group_set(const char *dev_name, const char *pin_group,
unsigned long config)
{
@@ -151,27 +210,34 @@ int pin_config_group_set(const char *dev_name, const char *pin_group,
int ret;
int i;
- pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
- if (!pctldev)
- return -EINVAL;
+ mutex_lock(&pinctrl_mutex);
+
+ pctldev = get_pinctrl_dev_from_devname(dev_name);
+ if (!pctldev) {
+ ret = -EINVAL;
+ goto unlock;
+ }
ops = pctldev->desc->confops;
pctlops = pctldev->desc->pctlops;
if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) {
dev_err(pctldev->dev, "cannot configure pin group, missing "
"config function in driver\n");
- return -EINVAL;
+ ret = -EINVAL;
+ goto unlock;
}
selector = pinctrl_get_group_selector(pctldev, pin_group);
- if (selector < 0)
- return selector;
+ if (selector < 0) {
+ ret = selector;
+ goto unlock;
+ }
ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins);
if (ret) {
dev_err(pctldev->dev, "cannot configure pin group, error "
"getting pins\n");
- return ret;
+ goto unlock;
}
/*
@@ -185,41 +251,182 @@ int pin_config_group_set(const char *dev_name, const char *pin_group,
* pin-by-pin as well, it returns -EAGAIN.
*/
if (ret != -EAGAIN)
- return ret;
+ goto unlock;
}
/*
* If the controller cannot handle entire groups, we configure each pin
* individually.
*/
- if (!ops->pin_config_set)
- return 0;
+ if (!ops->pin_config_set) {
+ ret = 0;
+ goto unlock;
+ }
for (i = 0; i < num_pins; i++) {
ret = ops->pin_config_set(pctldev, pins[i], config);
if (ret < 0)
- return ret;
+ goto unlock;
}
- return 0;
+ ret = 0;
+
+unlock:
+ mutex_unlock(&pinctrl_mutex);
+
+ return ret;
}
EXPORT_SYMBOL(pin_config_group_set);
-int pinconf_check_ops(struct pinctrl_dev *pctldev)
+int pinconf_map_to_setting(struct pinctrl_map const *map,
+ struct pinctrl_setting *setting)
+{
+ struct pinctrl_dev *pctldev = setting->pctldev;
+
+ switch (setting->type) {
+ case PIN_MAP_TYPE_CONFIGS_PIN:
+ setting->data.configs.group_or_pin =
+ pin_get_from_name(pctldev,
+ map->data.configs.group_or_pin);
+ if (setting->data.configs.group_or_pin < 0)
+ return setting->data.configs.group_or_pin;
+ break;
+ case PIN_MAP_TYPE_CONFIGS_GROUP:
+ setting->data.configs.group_or_pin =
+ pinctrl_get_group_selector(pctldev,
+ map->data.configs.group_or_pin);
+ if (setting->data.configs.group_or_pin < 0)
+ return setting->data.configs.group_or_pin;
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ setting->data.configs.num_configs = map->data.configs.num_configs;
+ setting->data.configs.configs = map->data.configs.configs;
+
+ return 0;
+}
+
+void pinconf_free_setting(struct pinctrl_setting const *setting)
{
+}
+
+int pinconf_apply_setting(struct pinctrl_setting const *setting)
+{
+ struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinconf_ops *ops = pctldev->desc->confops;
+ int i, ret;
- /* We must be able to read out pin status */
- if (!ops->pin_config_get && !ops->pin_config_group_get)
+ if (!ops) {
+ dev_err(pctldev->dev, "missing confops\n");
return -EINVAL;
- /* We have to be able to config the pins in SOME way */
- if (!ops->pin_config_set && !ops->pin_config_group_set)
+ }
+
+ switch (setting->type) {
+ case PIN_MAP_TYPE_CONFIGS_PIN:
+ if (!ops->pin_config_set) {
+ dev_err(pctldev->dev, "missing pin_config_set op\n");
+ return -EINVAL;
+ }
+ for (i = 0; i < setting->data.configs.num_configs; i++) {
+ ret = ops->pin_config_set(pctldev,
+ setting->data.configs.group_or_pin,
+ setting->data.configs.configs[i]);
+ if (ret < 0) {
+ dev_err(pctldev->dev,
+ "pin_config_set op failed for pin %d config %08lx\n",
+ setting->data.configs.group_or_pin,
+ setting->data.configs.configs[i]);
+ return ret;
+ }
+ }
+ break;
+ case PIN_MAP_TYPE_CONFIGS_GROUP:
+ if (!ops->pin_config_group_set) {
+ dev_err(pctldev->dev,
+ "missing pin_config_group_set op\n");
+ return -EINVAL;
+ }
+ for (i = 0; i < setting->data.configs.num_configs; i++) {
+ ret = ops->pin_config_group_set(pctldev,
+ setting->data.configs.group_or_pin,
+ setting->data.configs.configs[i]);
+ if (ret < 0) {
+ dev_err(pctldev->dev,
+ "pin_config_group_set op failed for group %d config %08lx\n",
+ setting->data.configs.group_or_pin,
+ setting->data.configs.configs[i]);
+ return ret;
+ }
+ }
+ break;
+ default:
return -EINVAL;
+ }
+
return 0;
}
#ifdef CONFIG_DEBUG_FS
+void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map)
+{
+ int i;
+
+ switch (map->type) {
+ case PIN_MAP_TYPE_CONFIGS_PIN:
+ seq_printf(s, "pin ");
+ break;
+ case PIN_MAP_TYPE_CONFIGS_GROUP:
+ seq_printf(s, "group ");
+ break;
+ default:
+ break;
+ }
+
+ seq_printf(s, "%s\n", map->data.configs.group_or_pin);
+
+ for (i = 0; i < map->data.configs.num_configs; i++)
+ seq_printf(s, "config %08lx\n", map->data.configs.configs[i]);
+}
+
+void pinconf_show_setting(struct seq_file *s,
+ struct pinctrl_setting const *setting)
+{
+ struct pinctrl_dev *pctldev = setting->pctldev;
+ const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
+ struct pin_desc *desc;
+ int i;
+
+ switch (setting->type) {
+ case PIN_MAP_TYPE_CONFIGS_PIN:
+ desc = pin_desc_get(setting->pctldev,
+ setting->data.configs.group_or_pin);
+ seq_printf(s, "pin %s (%d)",
+ desc->name ? desc->name : "unnamed",
+ setting->data.configs.group_or_pin);
+ break;
+ case PIN_MAP_TYPE_CONFIGS_GROUP:
+ seq_printf(s, "group %s (%d)",
+ pctlops->get_group_name(pctldev,
+ setting->data.configs.group_or_pin),
+ setting->data.configs.group_or_pin);
+ break;
+ default:
+ break;
+ }
+
+ /*
+ * FIXME: We should really get the pin controler to dump the config
+ * values, so they can be decoded to something meaningful.
+ */
+ for (i = 0; i < setting->data.configs.num_configs; i++)
+ seq_printf(s, " %08lx", setting->data.configs.configs[i]);
+
+ seq_printf(s, "\n");
+}
+
static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
struct seq_file *s, int pin)
{
@@ -237,6 +444,8 @@ static int pinconf_pins_show(struct seq_file *s, void *what)
seq_puts(s, "Pin config settings per pin\n");
seq_puts(s, "Format: pin (name): pinmux setting array\n");
+ mutex_lock(&pinctrl_mutex);
+
/* The pin number can be retrived from the pin controller descriptor */
for (i = 0; i < pctldev->desc->npins; i++) {
struct pin_desc *desc;
@@ -255,6 +464,8 @@ static int pinconf_pins_show(struct seq_file *s, void *what)
seq_printf(s, "\n");
}
+ mutex_unlock(&pinctrl_mutex);
+
return 0;
}
@@ -281,14 +492,20 @@ static int pinconf_groups_show(struct seq_file *s, void *what)
seq_puts(s, "Pin config settings per pin group\n");
seq_puts(s, "Format: group (name): pinmux setting array\n");
+ mutex_lock(&pinctrl_mutex);
+
while (pctlops->list_groups(pctldev, selector) >= 0) {
const char *gname = pctlops->get_group_name(pctldev, selector);
seq_printf(s, "%u (%s):", selector, gname);
pinconf_dump_group(pctldev, s, selector, gname);
+ seq_printf(s, "\n");
+
selector++;
}
+ mutex_unlock(&pinctrl_mutex);
+
return 0;
}
diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h
index 006b77f..0ded227 100644
--- a/drivers/pinctrl/pinconf.h
+++ b/drivers/pinctrl/pinconf.h
@@ -14,12 +14,19 @@
#ifdef CONFIG_PINCONF
int pinconf_check_ops(struct pinctrl_dev *pctldev);
+
+int pinconf_validate_map(struct pinctrl_map const *map, int i);
+
+int pinconf_map_to_setting(struct pinctrl_map const *map,
+ struct pinctrl_setting *setting);
+void pinconf_free_setting(struct pinctrl_setting const *setting);
+int pinconf_apply_setting(struct pinctrl_setting const *setting);
+
+void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map);
+void pinconf_show_setting(struct seq_file *s,
+ struct pinctrl_setting const *setting);
void pinconf_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev);
-int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
- unsigned long *config);
-int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
- unsigned long config);
#else
@@ -28,6 +35,36 @@ static inline int pinconf_check_ops(struct pinctrl_dev *pctldev)
return 0;
}
+static inline int pinconf_validate_map(struct pinctrl_map const *map, int i)
+{
+ return 0;
+}
+
+static inline int pinconf_map_to_setting(struct pinctrl_map const *map,
+ struct pinctrl_setting *setting)
+{
+ return 0;
+}
+
+static inline void pinconf_free_setting(struct pinctrl_setting const *setting)
+{
+}
+
+static inline int pinconf_apply_setting(struct pinctrl_setting const *setting)
+{
+ return 0;
+}
+
+static inline void pinconf_show_map(struct seq_file *s,
+ struct pinctrl_map const *map)
+{
+}
+
+static inline void pinconf_show_setting(struct seq_file *s,
+ struct pinctrl_setting const *setting)
+{
+}
+
static inline void pinconf_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev)
{
diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c
index 69fb707..b90c011 100644
--- a/drivers/pinctrl/pinctrl-coh901.c
+++ b/drivers/pinctrl/pinctrl-coh901.c
@@ -22,7 +22,7 @@
#include <linux/gpio.h>
#include <linux/list.h>
#include <linux/slab.h>
-#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/consumer.h>
#include <mach/gpio-u300.h>
/*
@@ -360,14 +360,14 @@ static int u300_gpio_request(struct gpio_chip *chip, unsigned offset)
*/
int gpio = chip->base + offset;
- return pinmux_request_gpio(gpio);
+ return pinctrl_request_gpio(gpio);
}
static void u300_gpio_free(struct gpio_chip *chip, unsigned offset)
{
int gpio = chip->base + offset;
- pinmux_free_gpio(gpio);
+ pinctrl_free_gpio(gpio);
}
static int u300_gpio_get(struct gpio_chip *chip, unsigned offset)
@@ -705,7 +705,6 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio)
list_for_each_safe(p, n, &gpio->port_list) {
port = list_entry(p, struct u300_gpio_port, node);
list_del(&port->node);
- free_irq(port->irq, port);
kfree(port);
}
}
@@ -861,10 +860,18 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
goto err_no_chip;
}
+ /* Spawn pin controller device as child of the GPIO, pass gpio chip */
+ plat->pinctrl_device->dev.platform_data = &gpio->chip;
+ err = platform_device_register(plat->pinctrl_device);
+ if (err)
+ goto err_no_pinctrl;
+
platform_set_drvdata(pdev, gpio);
return 0;
+err_no_pinctrl:
+ err = gpiochip_remove(&gpio->chip);
err_no_chip:
err_no_port:
u300_gpio_free_ports(gpio);
@@ -919,7 +926,6 @@ static struct platform_driver u300_gpio_driver = {
.remove = __exit_p(u300_gpio_remove),
};
-
static int __init u300_gpio_init(void)
{
return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe);
diff --git a/drivers/pinctrl/pinctrl-mmp2.c b/drivers/pinctrl/pinctrl-mmp2.c
new file mode 100644
index 0000000..2cfed55
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-mmp2.c
@@ -0,0 +1,722 @@
+/*
+ * linux/drivers/pinctrl/pinmux-mmp2.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ *
+ * Copyright (C) 2011, Marvell Technology Group Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include "pinctrl-pxa3xx.h"
+
+#define MMP2_DS_MASK 0x1800
+#define MMP2_DS_SHIFT 11
+#define MMP2_SLEEP_MASK 0x38
+#define MMP2_SLEEP_SELECT (1 << 9)
+#define MMP2_SLEEP_DATA (1 << 8)
+#define MMP2_SLEEP_DIR (1 << 7)
+
+#define MFPR_MMP2(a, r, f0, f1, f2, f3, f4, f5, f6, f7) \
+ { \
+ .name = #a, \
+ .pin = a, \
+ .mfpr = r, \
+ .func = { \
+ MMP2_MUX_##f0, \
+ MMP2_MUX_##f1, \
+ MMP2_MUX_##f2, \
+ MMP2_MUX_##f3, \
+ MMP2_MUX_##f4, \
+ MMP2_MUX_##f5, \
+ MMP2_MUX_##f6, \
+ MMP2_MUX_##f7, \
+ }, \
+ }
+
+#define GRP_MMP2(a, m, p) \
+ { .name = a, .mux = MMP2_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), }
+
+/* 174 pins */
+enum mmp2_pin_list {
+ /* 0~168: GPIO0~GPIO168 */
+ TWSI4_SCL = 169,
+ TWSI4_SDA, /* 170 */
+ G_CLKREQ,
+ VCXO_REQ,
+ VCXO_OUT,
+};
+
+enum mmp2_mux {
+ /* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */
+ MMP2_MUX_GPIO = 0,
+ MMP2_MUX_G_CLKREQ,
+ MMP2_MUX_VCXO_REQ,
+ MMP2_MUX_VCXO_OUT,
+ MMP2_MUX_KP_MK,
+ MMP2_MUX_KP_DK,
+ MMP2_MUX_CCIC1,
+ MMP2_MUX_CCIC2,
+ MMP2_MUX_SPI,
+ MMP2_MUX_SSPA2,
+ MMP2_MUX_ROT,
+ MMP2_MUX_I2S,
+ MMP2_MUX_TB,
+ MMP2_MUX_CAM2,
+ MMP2_MUX_HDMI,
+ MMP2_MUX_TWSI2,
+ MMP2_MUX_TWSI3,
+ MMP2_MUX_TWSI4,
+ MMP2_MUX_TWSI5,
+ MMP2_MUX_TWSI6,
+ MMP2_MUX_UART1,
+ MMP2_MUX_UART2,
+ MMP2_MUX_UART3,
+ MMP2_MUX_UART4,
+ MMP2_MUX_SSP1_RX,
+ MMP2_MUX_SSP1_FRM,
+ MMP2_MUX_SSP1_TXRX,
+ MMP2_MUX_SSP2_RX,
+ MMP2_MUX_SSP2_FRM,
+ MMP2_MUX_SSP1,
+ MMP2_MUX_SSP2,
+ MMP2_MUX_SSP3,
+ MMP2_MUX_SSP4,
+ MMP2_MUX_MMC1,
+ MMP2_MUX_MMC2,
+ MMP2_MUX_MMC3,
+ MMP2_MUX_MMC4,
+ MMP2_MUX_ULPI,
+ MMP2_MUX_AC,
+ MMP2_MUX_CA,
+ MMP2_MUX_PWM,
+ MMP2_MUX_USIM,
+ MMP2_MUX_TIPU,
+ MMP2_MUX_PLL,
+ MMP2_MUX_NAND,
+ MMP2_MUX_FSIC,
+ MMP2_MUX_SLEEP_IND,
+ MMP2_MUX_EXT_DMA,
+ MMP2_MUX_ONE_WIRE,
+ MMP2_MUX_LCD,
+ MMP2_MUX_SMC,
+ MMP2_MUX_SMC_INT,
+ MMP2_MUX_MSP,
+ MMP2_MUX_G_CLKOUT,
+ MMP2_MUX_32K_CLKOUT,
+ MMP2_MUX_PRI_JTAG,
+ MMP2_MUX_AAS_JTAG,
+ MMP2_MUX_AAS_GPIO,
+ MMP2_MUX_AAS_SPI,
+ MMP2_MUX_AAS_TWSI,
+ MMP2_MUX_AAS_DEU_EX,
+ MMP2_MUX_NONE = 0xffff,
+};
+
+static struct pinctrl_pin_desc mmp2_pads[] = {
+ /*
+ * The name indicates function 0 of this pin.
+ * After reset, function 0 is the default function of pin.
+ */
+ PINCTRL_PIN(GPIO0, "GPIO0"),
+ PINCTRL_PIN(GPIO1, "GPIO1"),
+ PINCTRL_PIN(GPIO2, "GPIO2"),
+ PINCTRL_PIN(GPIO3, "GPIO3"),
+ PINCTRL_PIN(GPIO4, "GPIO4"),
+ PINCTRL_PIN(GPIO5, "GPIO5"),
+ PINCTRL_PIN(GPIO6, "GPIO6"),
+ PINCTRL_PIN(GPIO7, "GPIO7"),
+ PINCTRL_PIN(GPIO8, "GPIO8"),
+ PINCTRL_PIN(GPIO9, "GPIO9"),
+ PINCTRL_PIN(GPIO10, "GPIO10"),
+ PINCTRL_PIN(GPIO11, "GPIO11"),
+ PINCTRL_PIN(GPIO12, "GPIO12"),
+ PINCTRL_PIN(GPIO13, "GPIO13"),
+ PINCTRL_PIN(GPIO14, "GPIO14"),
+ PINCTRL_PIN(GPIO15, "GPIO15"),
+ PINCTRL_PIN(GPIO16, "GPIO16"),
+ PINCTRL_PIN(GPIO17, "GPIO17"),
+ PINCTRL_PIN(GPIO18, "GPIO18"),
+ PINCTRL_PIN(GPIO19, "GPIO19"),
+ PINCTRL_PIN(GPIO20, "GPIO20"),
+ PINCTRL_PIN(GPIO21, "GPIO21"),
+ PINCTRL_PIN(GPIO22, "GPIO22"),
+ PINCTRL_PIN(GPIO23, "GPIO23"),
+ PINCTRL_PIN(GPIO24, "GPIO24"),
+ PINCTRL_PIN(GPIO25, "GPIO25"),
+ PINCTRL_PIN(GPIO26, "GPIO26"),
+ PINCTRL_PIN(GPIO27, "GPIO27"),
+ PINCTRL_PIN(GPIO28, "GPIO28"),
+ PINCTRL_PIN(GPIO29, "GPIO29"),
+ PINCTRL_PIN(GPIO30, "GPIO30"),
+ PINCTRL_PIN(GPIO31, "GPIO31"),
+ PINCTRL_PIN(GPIO32, "GPIO32"),
+ PINCTRL_PIN(GPIO33, "GPIO33"),
+ PINCTRL_PIN(GPIO34, "GPIO34"),
+ PINCTRL_PIN(GPIO35, "GPIO35"),
+ PINCTRL_PIN(GPIO36, "GPIO36"),
+ PINCTRL_PIN(GPIO37, "GPIO37"),
+ PINCTRL_PIN(GPIO38, "GPIO38"),
+ PINCTRL_PIN(GPIO39, "GPIO39"),
+ PINCTRL_PIN(GPIO40, "GPIO40"),
+ PINCTRL_PIN(GPIO41, "GPIO41"),
+ PINCTRL_PIN(GPIO42, "GPIO42"),
+ PINCTRL_PIN(GPIO43, "GPIO43"),
+ PINCTRL_PIN(GPIO44, "GPIO44"),
+ PINCTRL_PIN(GPIO45, "GPIO45"),
+ PINCTRL_PIN(GPIO46, "GPIO46"),
+ PINCTRL_PIN(GPIO47, "GPIO47"),
+ PINCTRL_PIN(GPIO48, "GPIO48"),
+ PINCTRL_PIN(GPIO49, "GPIO49"),
+ PINCTRL_PIN(GPIO50, "GPIO50"),
+ PINCTRL_PIN(GPIO51, "GPIO51"),
+ PINCTRL_PIN(GPIO52, "GPIO52"),
+ PINCTRL_PIN(GPIO53, "GPIO53"),
+ PINCTRL_PIN(GPIO54, "GPIO54"),
+ PINCTRL_PIN(GPIO55, "GPIO55"),
+ PINCTRL_PIN(GPIO56, "GPIO56"),
+ PINCTRL_PIN(GPIO57, "GPIO57"),
+ PINCTRL_PIN(GPIO58, "GPIO58"),
+ PINCTRL_PIN(GPIO59, "GPIO59"),
+ PINCTRL_PIN(GPIO60, "GPIO60"),
+ PINCTRL_PIN(GPIO61, "GPIO61"),
+ PINCTRL_PIN(GPIO62, "GPIO62"),
+ PINCTRL_PIN(GPIO63, "GPIO63"),
+ PINCTRL_PIN(GPIO64, "GPIO64"),
+ PINCTRL_PIN(GPIO65, "GPIO65"),
+ PINCTRL_PIN(GPIO66, "GPIO66"),
+ PINCTRL_PIN(GPIO67, "GPIO67"),
+ PINCTRL_PIN(GPIO68, "GPIO68"),
+ PINCTRL_PIN(GPIO69, "GPIO69"),
+ PINCTRL_PIN(GPIO70, "GPIO70"),
+ PINCTRL_PIN(GPIO71, "GPIO71"),
+ PINCTRL_PIN(GPIO72, "GPIO72"),
+ PINCTRL_PIN(GPIO73, "GPIO73"),
+ PINCTRL_PIN(GPIO74, "GPIO74"),
+ PINCTRL_PIN(GPIO75, "GPIO75"),
+ PINCTRL_PIN(GPIO76, "GPIO76"),
+ PINCTRL_PIN(GPIO77, "GPIO77"),
+ PINCTRL_PIN(GPIO78, "GPIO78"),
+ PINCTRL_PIN(GPIO79, "GPIO79"),
+ PINCTRL_PIN(GPIO80, "GPIO80"),
+ PINCTRL_PIN(GPIO81, "GPIO81"),
+ PINCTRL_PIN(GPIO82, "GPIO82"),
+ PINCTRL_PIN(GPIO83, "GPIO83"),
+ PINCTRL_PIN(GPIO84, "GPIO84"),
+ PINCTRL_PIN(GPIO85, "GPIO85"),
+ PINCTRL_PIN(GPIO86, "GPIO86"),
+ PINCTRL_PIN(GPIO87, "GPIO87"),
+ PINCTRL_PIN(GPIO88, "GPIO88"),
+ PINCTRL_PIN(GPIO89, "GPIO89"),
+ PINCTRL_PIN(GPIO90, "GPIO90"),
+ PINCTRL_PIN(GPIO91, "GPIO91"),
+ PINCTRL_PIN(GPIO92, "GPIO92"),
+ PINCTRL_PIN(GPIO93, "GPIO93"),
+ PINCTRL_PIN(GPIO94, "GPIO94"),
+ PINCTRL_PIN(GPIO95, "GPIO95"),
+ PINCTRL_PIN(GPIO96, "GPIO96"),
+ PINCTRL_PIN(GPIO97, "GPIO97"),
+ PINCTRL_PIN(GPIO98, "GPIO98"),
+ PINCTRL_PIN(GPIO99, "GPIO99"),
+ PINCTRL_PIN(GPIO100, "GPIO100"),
+ PINCTRL_PIN(GPIO101, "GPIO101"),
+ PINCTRL_PIN(GPIO102, "GPIO102"),
+ PINCTRL_PIN(GPIO103, "GPIO103"),
+ PINCTRL_PIN(GPIO104, "GPIO104"),
+ PINCTRL_PIN(GPIO105, "GPIO105"),
+ PINCTRL_PIN(GPIO106, "GPIO106"),
+ PINCTRL_PIN(GPIO107, "GPIO107"),
+ PINCTRL_PIN(GPIO108, "GPIO108"),
+ PINCTRL_PIN(GPIO109, "GPIO109"),
+ PINCTRL_PIN(GPIO110, "GPIO110"),
+ PINCTRL_PIN(GPIO111, "GPIO111"),
+ PINCTRL_PIN(GPIO112, "GPIO112"),
+ PINCTRL_PIN(GPIO113, "GPIO113"),
+ PINCTRL_PIN(GPIO114, "GPIO114"),
+ PINCTRL_PIN(GPIO115, "GPIO115"),
+ PINCTRL_PIN(GPIO116, "GPIO116"),
+ PINCTRL_PIN(GPIO117, "GPIO117"),
+ PINCTRL_PIN(GPIO118, "GPIO118"),
+ PINCTRL_PIN(GPIO119, "GPIO119"),
+ PINCTRL_PIN(GPIO120, "GPIO120"),
+ PINCTRL_PIN(GPIO121, "GPIO121"),
+ PINCTRL_PIN(GPIO122, "GPIO122"),
+ PINCTRL_PIN(GPIO123, "GPIO123"),
+ PINCTRL_PIN(GPIO124, "GPIO124"),
+ PINCTRL_PIN(GPIO125, "GPIO125"),
+ PINCTRL_PIN(GPIO126, "GPIO126"),
+ PINCTRL_PIN(GPIO127, "GPIO127"),
+ PINCTRL_PIN(GPIO128, "GPIO128"),
+ PINCTRL_PIN(GPIO129, "GPIO129"),
+ PINCTRL_PIN(GPIO130, "GPIO130"),
+ PINCTRL_PIN(GPIO131, "GPIO131"),
+ PINCTRL_PIN(GPIO132, "GPIO132"),
+ PINCTRL_PIN(GPIO133, "GPIO133"),
+ PINCTRL_PIN(GPIO134, "GPIO134"),
+ PINCTRL_PIN(GPIO135, "GPIO135"),
+ PINCTRL_PIN(GPIO136, "GPIO136"),
+ PINCTRL_PIN(GPIO137, "GPIO137"),
+ PINCTRL_PIN(GPIO138, "GPIO138"),
+ PINCTRL_PIN(GPIO139, "GPIO139"),
+ PINCTRL_PIN(GPIO140, "GPIO140"),
+ PINCTRL_PIN(GPIO141, "GPIO141"),
+ PINCTRL_PIN(GPIO142, "GPIO142"),
+ PINCTRL_PIN(GPIO143, "GPIO143"),
+ PINCTRL_PIN(GPIO144, "GPIO144"),
+ PINCTRL_PIN(GPIO145, "GPIO145"),
+ PINCTRL_PIN(GPIO146, "GPIO146"),
+ PINCTRL_PIN(GPIO147, "GPIO147"),
+ PINCTRL_PIN(GPIO148, "GPIO148"),
+ PINCTRL_PIN(GPIO149, "GPIO149"),
+ PINCTRL_PIN(GPIO150, "GPIO150"),
+ PINCTRL_PIN(GPIO151, "GPIO151"),
+ PINCTRL_PIN(GPIO152, "GPIO152"),
+ PINCTRL_PIN(GPIO153, "GPIO153"),
+ PINCTRL_PIN(GPIO154, "GPIO154"),
+ PINCTRL_PIN(GPIO155, "GPIO155"),
+ PINCTRL_PIN(GPIO156, "GPIO156"),
+ PINCTRL_PIN(GPIO157, "GPIO157"),
+ PINCTRL_PIN(GPIO158, "GPIO158"),
+ PINCTRL_PIN(GPIO159, "GPIO159"),
+ PINCTRL_PIN(GPIO160, "GPIO160"),
+ PINCTRL_PIN(GPIO161, "GPIO161"),
+ PINCTRL_PIN(GPIO162, "GPIO162"),
+ PINCTRL_PIN(GPIO163, "GPIO163"),
+ PINCTRL_PIN(GPIO164, "GPIO164"),
+ PINCTRL_PIN(GPIO165, "GPIO165"),
+ PINCTRL_PIN(GPIO166, "GPIO166"),
+ PINCTRL_PIN(GPIO167, "GPIO167"),
+ PINCTRL_PIN(GPIO168, "GPIO168"),
+ PINCTRL_PIN(TWSI4_SCL, "TWSI4_SCL"),
+ PINCTRL_PIN(TWSI4_SDA, "TWSI4_SDA"),
+ PINCTRL_PIN(G_CLKREQ, "G_CLKREQ"),
+ PINCTRL_PIN(VCXO_REQ, "VCXO_REQ"),
+ PINCTRL_PIN(VCXO_OUT, "VCXO_OUT"),
+};
+
+struct pxa3xx_mfp_pin mmp2_mfp[] = {
+ /* pin offs f0 f1 f2 f3 f4 f5 f6 f7 */
+ MFPR_MMP2(GPIO0, 0x054, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO1, 0x058, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO2, 0x05C, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO3, 0x060, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO4, 0x064, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO5, 0x068, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO6, 0x06C, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO7, 0x070, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO8, 0x074, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO9, 0x078, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO10, 0x07C, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO11, 0x080, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO12, 0x084, GPIO, KP_MK, NONE, CCIC1, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO13, 0x088, GPIO, KP_MK, NONE, CCIC1, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO14, 0x08C, GPIO, KP_MK, NONE, CCIC1, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO15, 0x090, GPIO, KP_MK, KP_DK, CCIC1, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO16, 0x094, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO17, 0x098, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO18, 0x09C, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO19, 0x0A0, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO20, 0x0A4, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO21, 0x0A8, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO22, 0x0AC, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO23, 0x0B0, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO24, 0x0B4, GPIO, I2S, VCXO_OUT, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO25, 0x0B8, GPIO, I2S, HDMI, SSPA2, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO26, 0x0BC, GPIO, I2S, HDMI, SSPA2, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO27, 0x0C0, GPIO, I2S, HDMI, SSPA2, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO28, 0x0C4, GPIO, I2S, NONE, SSPA2, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO29, 0x0C8, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE),
+ MFPR_MMP2(GPIO30, 0x0CC, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE),
+ MFPR_MMP2(GPIO31, 0x0D0, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE),
+ MFPR_MMP2(GPIO32, 0x0D4, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE),
+ MFPR_MMP2(GPIO33, 0x0D8, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO34, 0x0DC, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO35, 0x0E0, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO36, 0x0E4, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO37, 0x0E8, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI),
+ MFPR_MMP2(GPIO38, 0x0EC, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI),
+ MFPR_MMP2(GPIO39, 0x0F0, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI),
+ MFPR_MMP2(GPIO40, 0x0F4, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI),
+ MFPR_MMP2(GPIO41, 0x0F8, GPIO, MMC2, TWSI5, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO42, 0x0FC, GPIO, MMC2, TWSI5, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO43, 0x100, GPIO, TWSI2, UART4, SSP1, UART2, UART3, NONE, AAS_TWSI),
+ MFPR_MMP2(GPIO44, 0x104, GPIO, TWSI2, UART4, SSP1, UART2, UART3, NONE, AAS_TWSI),
+ MFPR_MMP2(GPIO45, 0x108, GPIO, UART1, UART4, SSP1, UART2, UART3, NONE, NONE),
+ MFPR_MMP2(GPIO46, 0x10C, GPIO, UART1, UART4, SSP1, UART2, UART3, NONE, NONE),
+ MFPR_MMP2(GPIO47, 0x110, GPIO, UART2, SSP2, TWSI6, CAM2, AAS_SPI, AAS_GPIO, NONE),
+ MFPR_MMP2(GPIO48, 0x114, GPIO, UART2, SSP2, TWSI6, CAM2, AAS_SPI, AAS_GPIO, NONE),
+ MFPR_MMP2(GPIO49, 0x118, GPIO, UART2, SSP2, PWM, CCIC2, AAS_SPI, NONE, NONE),
+ MFPR_MMP2(GPIO50, 0x11C, GPIO, UART2, SSP2, PWM, CCIC2, AAS_SPI, NONE, NONE),
+ MFPR_MMP2(GPIO51, 0x120, GPIO, UART3, ROT, AAS_GPIO, PWM, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO52, 0x124, GPIO, UART3, ROT, AAS_GPIO, PWM, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO53, 0x128, GPIO, UART3, TWSI2, VCXO_REQ, NONE, PWM, NONE, AAS_TWSI),
+ MFPR_MMP2(GPIO54, 0x12C, GPIO, UART3, TWSI2, VCXO_OUT, HDMI, PWM, NONE, AAS_TWSI),
+ MFPR_MMP2(GPIO55, 0x130, GPIO, SSP2, SSP1, UART2, ROT, TWSI2, SSP3, AAS_TWSI),
+ MFPR_MMP2(GPIO56, 0x134, GPIO, SSP2, SSP1, UART2, ROT, TWSI2, KP_DK, AAS_TWSI),
+ MFPR_MMP2(GPIO57, 0x138, GPIO, SSP2_RX, SSP1_TXRX, SSP2_FRM, SSP1_RX, VCXO_REQ, KP_DK, NONE),
+ MFPR_MMP2(GPIO58, 0x13C, GPIO, SSP2, SSP1_RX, SSP1_FRM, SSP1_TXRX, VCXO_REQ, KP_DK, NONE),
+ MFPR_MMP2(GPIO59, 0x280, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, UART4, NONE),
+ MFPR_MMP2(GPIO60, 0x284, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, UART4, NONE),
+ MFPR_MMP2(GPIO61, 0x288, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, HDMI, NONE),
+ MFPR_MMP2(GPIO62, 0x28C, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, NONE, NONE),
+ MFPR_MMP2(GPIO63, 0x290, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE),
+ MFPR_MMP2(GPIO64, 0x294, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE),
+ MFPR_MMP2(GPIO65, 0x298, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE),
+ MFPR_MMP2(GPIO66, 0x29C, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE),
+ MFPR_MMP2(GPIO67, 0x2A0, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, NONE, NONE),
+ MFPR_MMP2(GPIO68, 0x2A4, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, LCD, NONE),
+ MFPR_MMP2(GPIO69, 0x2A8, GPIO, CCIC1, ULPI, MMC3, CCIC2, NONE, LCD, NONE),
+ MFPR_MMP2(GPIO70, 0x2AC, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, LCD, NONE),
+ MFPR_MMP2(GPIO71, 0x2B0, GPIO, TWSI3, NONE, PWM, NONE, NONE, LCD, AAS_TWSI),
+ MFPR_MMP2(GPIO72, 0x2B4, GPIO, TWSI3, HDMI, PWM, NONE, NONE, LCD, AAS_TWSI),
+ MFPR_MMP2(GPIO73, 0x2B8, GPIO, VCXO_REQ, 32K_CLKOUT, PWM, VCXO_OUT, NONE, LCD, NONE),
+ MFPR_MMP2(GPIO74, 0x170, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU),
+ MFPR_MMP2(GPIO75, 0x174, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU),
+ MFPR_MMP2(GPIO76, 0x178, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU),
+ MFPR_MMP2(GPIO77, 0x17C, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU),
+ MFPR_MMP2(GPIO78, 0x180, GPIO, LCD, HDMI, MMC4, NONE, SSP4, AAS_SPI, TIPU),
+ MFPR_MMP2(GPIO79, 0x184, GPIO, LCD, AAS_GPIO, MMC4, NONE, SSP4, AAS_SPI, TIPU),
+ MFPR_MMP2(GPIO80, 0x188, GPIO, LCD, AAS_GPIO, MMC4, NONE, SSP4, AAS_SPI, TIPU),
+ MFPR_MMP2(GPIO81, 0x18C, GPIO, LCD, AAS_GPIO, MMC4, NONE, SSP4, AAS_SPI, TIPU),
+ MFPR_MMP2(GPIO82, 0x190, GPIO, LCD, NONE, MMC4, NONE, NONE, CCIC2, TIPU),
+ MFPR_MMP2(GPIO83, 0x194, GPIO, LCD, NONE, MMC4, NONE, NONE, CCIC2, TIPU),
+ MFPR_MMP2(GPIO84, 0x198, GPIO, LCD, SMC, MMC2, NONE, TWSI5, AAS_TWSI, TIPU),
+ MFPR_MMP2(GPIO85, 0x19C, GPIO, LCD, SMC, MMC2, NONE, TWSI5, AAS_TWSI, TIPU),
+ MFPR_MMP2(GPIO86, 0x1A0, GPIO, LCD, SMC, MMC2, NONE, TWSI6, CCIC2, TIPU),
+ MFPR_MMP2(GPIO87, 0x1A4, GPIO, LCD, SMC, MMC2, NONE, TWSI6, CCIC2, TIPU),
+ MFPR_MMP2(GPIO88, 0x1A8, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU),
+ MFPR_MMP2(GPIO89, 0x1AC, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU),
+ MFPR_MMP2(GPIO90, 0x1B0, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU),
+ MFPR_MMP2(GPIO91, 0x1B4, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU),
+ MFPR_MMP2(GPIO92, 0x1B8, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU),
+ MFPR_MMP2(GPIO93, 0x1BC, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU),
+ MFPR_MMP2(GPIO94, 0x1C0, GPIO, LCD, AAS_GPIO, SPI, NONE, AAS_SPI, CCIC2, TIPU),
+ MFPR_MMP2(GPIO95, 0x1C4, GPIO, LCD, TWSI3, SPI, AAS_DEU_EX, AAS_SPI, CCIC2, TIPU),
+ MFPR_MMP2(GPIO96, 0x1C8, GPIO, LCD, TWSI3, SPI, AAS_DEU_EX, AAS_SPI, NONE, TIPU),
+ MFPR_MMP2(GPIO97, 0x1CC, GPIO, LCD, TWSI6, SPI, AAS_DEU_EX, AAS_SPI, NONE, TIPU),
+ MFPR_MMP2(GPIO98, 0x1D0, GPIO, LCD, TWSI6, SPI, ONE_WIRE, NONE, NONE, TIPU),
+ MFPR_MMP2(GPIO99, 0x1D4, GPIO, LCD, SMC, SPI, TWSI5, NONE, NONE, TIPU),
+ MFPR_MMP2(GPIO100, 0x1D8, GPIO, LCD, SMC, SPI, TWSI5, NONE, NONE, TIPU),
+ MFPR_MMP2(GPIO101, 0x1DC, GPIO, LCD, SMC, SPI, NONE, NONE, NONE, TIPU),
+ MFPR_MMP2(GPIO102, 0x000, USIM, GPIO, FSIC, KP_DK, LCD, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO103, 0x004, USIM, GPIO, FSIC, KP_DK, LCD, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO104, 0x1FC, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO105, 0x1F8, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO106, 0x1F4, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO107, 0x1F0, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO108, 0x21C, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO109, 0x218, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO110, 0x214, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO111, 0x200, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO112, 0x244, NAND, GPIO, MMC3, SMC, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO113, 0x25C, SMC, GPIO, EXT_DMA, MMC3, SMC, HDMI, NONE, NONE),
+ MFPR_MMP2(GPIO114, 0x164, G_CLKOUT, 32K_CLKOUT, HDMI, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO115, 0x260, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE),
+ MFPR_MMP2(GPIO116, 0x264, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE),
+ MFPR_MMP2(GPIO117, 0x268, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE),
+ MFPR_MMP2(GPIO118, 0x26C, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE),
+ MFPR_MMP2(GPIO119, 0x270, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO120, 0x274, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO121, 0x278, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO122, 0x27C, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO123, 0x148, GPIO, SLEEP_IND, ONE_WIRE, 32K_CLKOUT, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO124, 0x00C, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO125, 0x010, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO126, 0x014, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO127, 0x018, GPIO, NONE, LCD, MMC3, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO128, 0x01C, GPIO, NONE, LCD, MMC3, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO129, 0x020, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO130, 0x024, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO131, 0x028, GPIO, MMC1, NONE, MSP, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO132, 0x02C, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE),
+ MFPR_MMP2(GPIO133, 0x030, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE),
+ MFPR_MMP2(GPIO134, 0x034, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE),
+ MFPR_MMP2(GPIO135, 0x038, GPIO, NONE, LCD, MMC3, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO136, 0x03C, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE),
+ MFPR_MMP2(GPIO137, 0x040, GPIO, HDMI, LCD, MSP, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO138, 0x044, GPIO, NONE, LCD, MMC3, SMC, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO139, 0x048, GPIO, MMC1, PRI_JTAG, MSP, NONE, AAS_JTAG, NONE, NONE),
+ MFPR_MMP2(GPIO140, 0x04C, GPIO, MMC1, LCD, NONE, NONE, UART2, UART1, NONE),
+ MFPR_MMP2(GPIO141, 0x050, GPIO, MMC1, LCD, NONE, NONE, UART2, UART1, NONE),
+ MFPR_MMP2(GPIO142, 0x008, USIM, GPIO, FSIC, KP_DK, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO143, 0x220, NAND, GPIO, SMC, NONE, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO144, 0x224, NAND, GPIO, SMC_INT, SMC, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO145, 0x228, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO146, 0x22C, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO147, 0x230, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO148, 0x234, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO149, 0x238, NAND, GPIO, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO150, 0x23C, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO151, 0x240, SMC, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO152, 0x248, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO153, 0x24C, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO154, 0x254, SMC_INT, GPIO, SMC, NONE, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO155, 0x258, EXT_DMA, GPIO, SMC, NONE, EXT_DMA, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO156, 0x14C, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO157, 0x150, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO158, 0x154, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO159, 0x158, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO160, 0x250, NAND, GPIO, SMC, NONE, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO161, 0x210, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO162, 0x20C, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO163, 0x208, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO164, 0x204, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO165, 0x1EC, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO166, 0x1E8, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO167, 0x1E4, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(GPIO168, 0x1E0, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(TWSI4_SCL, 0x2BC, TWSI4, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(TWSI4_SDA, 0x2C0, TWSI4, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(G_CLKREQ, 0x160, G_CLKREQ, ONE_WIRE, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(VCXO_REQ, 0x168, VCXO_REQ, ONE_WIRE, PLL, NONE, NONE, NONE, NONE, NONE),
+ MFPR_MMP2(VCXO_OUT, 0x16C, VCXO_OUT, 32K_CLKOUT, NONE, NONE, NONE, NONE, NONE, NONE),
+};
+
+static const unsigned mmp2_uart1_pin1[] = {GPIO29, GPIO30, GPIO31, GPIO32};
+static const unsigned mmp2_uart1_pin2[] = {GPIO45, GPIO46};
+static const unsigned mmp2_uart1_pin3[] = {GPIO140, GPIO141};
+static const unsigned mmp2_uart2_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40};
+static const unsigned mmp2_uart2_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned mmp2_uart2_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50};
+static const unsigned mmp2_uart2_pin4[] = {GPIO74, GPIO75, GPIO76, GPIO77};
+static const unsigned mmp2_uart2_pin5[] = {GPIO55, GPIO56};
+static const unsigned mmp2_uart2_pin6[] = {GPIO140, GPIO141};
+static const unsigned mmp2_uart3_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40};
+static const unsigned mmp2_uart3_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned mmp2_uart3_pin3[] = {GPIO51, GPIO52, GPIO53, GPIO54};
+static const unsigned mmp2_uart3_pin4[] = {GPIO59, GPIO60, GPIO61, GPIO62};
+static const unsigned mmp2_uart3_pin5[] = {GPIO115, GPIO116, GPIO117, GPIO118};
+static const unsigned mmp2_uart3_pin6[] = {GPIO51, GPIO52};
+static const unsigned mmp2_uart4_pin1[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned mmp2_uart4_pin2[] = {GPIO63, GPIO64, GPIO65, GPIO66};
+static const unsigned mmp2_uart4_pin3[] = {GPIO74, GPIO75, GPIO76, GPIO77};
+static const unsigned mmp2_uart4_pin4[] = {GPIO115, GPIO116, GPIO117, GPIO118};
+static const unsigned mmp2_uart4_pin5[] = {GPIO59, GPIO60};
+static const unsigned mmp2_kpdk_pin1[] = {GPIO16, GPIO17, GPIO18, GPIO19};
+static const unsigned mmp2_kpdk_pin2[] = {GPIO16, GPIO17};
+static const unsigned mmp2_twsi2_pin1[] = {GPIO37, GPIO38};
+static const unsigned mmp2_twsi2_pin2[] = {GPIO39, GPIO40};
+static const unsigned mmp2_twsi2_pin3[] = {GPIO43, GPIO44};
+static const unsigned mmp2_twsi2_pin4[] = {GPIO53, GPIO54};
+static const unsigned mmp2_twsi2_pin5[] = {GPIO55, GPIO56};
+static const unsigned mmp2_twsi3_pin1[] = {GPIO71, GPIO72};
+static const unsigned mmp2_twsi3_pin2[] = {GPIO95, GPIO96};
+static const unsigned mmp2_twsi4_pin1[] = {TWSI4_SCL, TWSI4_SDA};
+static const unsigned mmp2_twsi5_pin1[] = {GPIO41, GPIO42};
+static const unsigned mmp2_twsi5_pin2[] = {GPIO84, GPIO85};
+static const unsigned mmp2_twsi5_pin3[] = {GPIO99, GPIO100};
+static const unsigned mmp2_twsi6_pin1[] = {GPIO47, GPIO48};
+static const unsigned mmp2_twsi6_pin2[] = {GPIO86, GPIO87};
+static const unsigned mmp2_twsi6_pin3[] = {GPIO97, GPIO98};
+static const unsigned mmp2_ccic1_pin1[] = {GPIO12, GPIO13, GPIO14, GPIO15,
+ GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, GPIO23};
+static const unsigned mmp2_ccic1_pin2[] = {GPIO59, GPIO60, GPIO61, GPIO62,
+ GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70};
+static const unsigned mmp2_ccic2_pin1[] = {GPIO59, GPIO60, GPIO61, GPIO62,
+ GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70};
+static const unsigned mmp2_ccic2_pin2[] = {GPIO82, GPIO83, GPIO86, GPIO87,
+ GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, GPIO93, GPIO94, GPIO95};
+static const unsigned mmp2_ulpi_pin1[] = {GPIO59, GPIO60, GPIO61, GPIO62,
+ GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70};
+static const unsigned mmp2_ro_pin1[] = {GPIO16, GPIO17};
+static const unsigned mmp2_ro_pin2[] = {GPIO18, GPIO19};
+static const unsigned mmp2_ro_pin3[] = {GPIO51, GPIO52};
+static const unsigned mmp2_ro_pin4[] = {GPIO55, GPIO56};
+static const unsigned mmp2_i2s_pin1[] = {GPIO24, GPIO25, GPIO26, GPIO27,
+ GPIO28};
+static const unsigned mmp2_i2s_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36};
+static const unsigned mmp2_ssp1_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40};
+static const unsigned mmp2_ssp1_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned mmp2_ssp1_pin3[] = {GPIO115, GPIO116, GPIO117, GPIO118};
+static const unsigned mmp2_ssp2_pin1[] = {GPIO47, GPIO48, GPIO49, GPIO50};
+static const unsigned mmp2_ssp3_pin1[] = {GPIO119, GPIO120, GPIO121, GPIO122};
+static const unsigned mmp2_ssp3_pin2[] = {GPIO132, GPIO133, GPIO133, GPIO136};
+static const unsigned mmp2_sspa2_pin1[] = {GPIO25, GPIO26, GPIO27, GPIO28};
+static const unsigned mmp2_sspa2_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36};
+static const unsigned mmp2_mmc1_pin1[] = {GPIO131, GPIO132, GPIO133, GPIO134,
+ GPIO136, GPIO139, GPIO140, GPIO141};
+static const unsigned mmp2_mmc2_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40,
+ GPIO41, GPIO42};
+static const unsigned mmp2_mmc3_pin1[] = {GPIO111, GPIO112, GPIO151, GPIO162,
+ GPIO163, GPIO164, GPIO165, GPIO166, GPIO167, GPIO168};
+
+static struct pxa3xx_pin_group mmp2_grps[] = {
+ GRP_MMP2("uart1 4p1", UART1, mmp2_uart1_pin1),
+ GRP_MMP2("uart1 2p2", UART1, mmp2_uart1_pin2),
+ GRP_MMP2("uart1 2p3", UART1, mmp2_uart1_pin3),
+ GRP_MMP2("uart2 4p1", UART2, mmp2_uart2_pin1),
+ GRP_MMP2("uart2 4p2", UART2, mmp2_uart2_pin2),
+ GRP_MMP2("uart2 4p3", UART2, mmp2_uart2_pin3),
+ GRP_MMP2("uart2 4p4", UART2, mmp2_uart2_pin4),
+ GRP_MMP2("uart2 2p5", UART2, mmp2_uart2_pin5),
+ GRP_MMP2("uart2 2p6", UART2, mmp2_uart2_pin6),
+ GRP_MMP2("uart3 4p1", UART3, mmp2_uart3_pin1),
+ GRP_MMP2("uart3 4p2", UART3, mmp2_uart3_pin2),
+ GRP_MMP2("uart3 4p3", UART3, mmp2_uart3_pin3),
+ GRP_MMP2("uart3 4p4", UART3, mmp2_uart3_pin4),
+ GRP_MMP2("uart3 4p5", UART3, mmp2_uart3_pin5),
+ GRP_MMP2("uart3 2p6", UART3, mmp2_uart3_pin6),
+ GRP_MMP2("uart4 4p1", UART4, mmp2_uart4_pin1),
+ GRP_MMP2("uart4 4p2", UART4, mmp2_uart4_pin2),
+ GRP_MMP2("uart4 4p3", UART4, mmp2_uart4_pin3),
+ GRP_MMP2("uart4 4p4", UART4, mmp2_uart4_pin4),
+ GRP_MMP2("uart4 2p5", UART4, mmp2_uart4_pin5),
+ GRP_MMP2("kpdk 4p1", KP_DK, mmp2_kpdk_pin1),
+ GRP_MMP2("kpdk 4p2", KP_DK, mmp2_kpdk_pin2),
+ GRP_MMP2("twsi2-1", TWSI2, mmp2_twsi2_pin1),
+ GRP_MMP2("twsi2-2", TWSI2, mmp2_twsi2_pin2),
+ GRP_MMP2("twsi2-3", TWSI2, mmp2_twsi2_pin3),
+ GRP_MMP2("twsi2-4", TWSI2, mmp2_twsi2_pin4),
+ GRP_MMP2("twsi2-5", TWSI2, mmp2_twsi2_pin5),
+ GRP_MMP2("twsi3-1", TWSI3, mmp2_twsi3_pin1),
+ GRP_MMP2("twsi3-2", TWSI3, mmp2_twsi3_pin2),
+ GRP_MMP2("twsi4", TWSI4, mmp2_twsi4_pin1),
+ GRP_MMP2("twsi5-1", TWSI5, mmp2_twsi5_pin1),
+ GRP_MMP2("twsi5-2", TWSI5, mmp2_twsi5_pin2),
+ GRP_MMP2("twsi5-3", TWSI5, mmp2_twsi5_pin3),
+ GRP_MMP2("twsi6-1", TWSI6, mmp2_twsi6_pin1),
+ GRP_MMP2("twsi6-2", TWSI6, mmp2_twsi6_pin2),
+ GRP_MMP2("twsi6-3", TWSI6, mmp2_twsi6_pin3),
+ GRP_MMP2("ccic1-1", CCIC1, mmp2_ccic1_pin1),
+ GRP_MMP2("ccic1-2", CCIC1, mmp2_ccic1_pin2),
+ GRP_MMP2("ccic2-1", CCIC2, mmp2_ccic2_pin1),
+ GRP_MMP2("ccic2-1", CCIC2, mmp2_ccic2_pin2),
+ GRP_MMP2("ulpi", ULPI, mmp2_ulpi_pin1),
+ GRP_MMP2("ro-1", ROT, mmp2_ro_pin1),
+ GRP_MMP2("ro-2", ROT, mmp2_ro_pin2),
+ GRP_MMP2("ro-3", ROT, mmp2_ro_pin3),
+ GRP_MMP2("ro-4", ROT, mmp2_ro_pin4),
+ GRP_MMP2("i2s 5p1", I2S, mmp2_i2s_pin1),
+ GRP_MMP2("i2s 4p2", I2S, mmp2_i2s_pin2),
+ GRP_MMP2("ssp1 4p1", SSP1, mmp2_ssp1_pin1),
+ GRP_MMP2("ssp1 4p2", SSP1, mmp2_ssp1_pin2),
+ GRP_MMP2("ssp1 4p3", SSP1, mmp2_ssp1_pin3),
+ GRP_MMP2("ssp2 4p1", SSP2, mmp2_ssp2_pin1),
+ GRP_MMP2("ssp3 4p1", SSP3, mmp2_ssp3_pin1),
+ GRP_MMP2("ssp3 4p2", SSP3, mmp2_ssp3_pin2),
+ GRP_MMP2("sspa2 4p1", SSPA2, mmp2_sspa2_pin1),
+ GRP_MMP2("sspa2 4p2", SSPA2, mmp2_sspa2_pin2),
+ GRP_MMP2("mmc1 8p1", MMC1, mmp2_mmc1_pin1),
+ GRP_MMP2("mmc2 6p1", MMC2, mmp2_mmc2_pin1),
+ GRP_MMP2("mmc3 10p1", MMC3, mmp2_mmc3_pin1),
+};
+
+static const char * const mmp2_uart1_grps[] = {"uart1 4p1", "uart1 2p2",
+ "uart1 2p3"};
+static const char * const mmp2_uart2_grps[] = {"uart2 4p1", "uart2 4p2",
+ "uart2 4p3", "uart2 4p4", "uart2 4p5", "uart2 4p6"};
+static const char * const mmp2_uart3_grps[] = {"uart3 4p1", "uart3 4p2",
+ "uart3 4p3", "uart3 4p4", "uart3 4p5", "uart3 2p6"};
+static const char * const mmp2_uart4_grps[] = {"uart4 4p1", "uart4 4p2",
+ "uart4 4p3", "uart4 4p4", "uart4 2p5"};
+static const char * const mmp2_kpdk_grps[] = {"kpdk 4p1", "kpdk 4p2"};
+static const char * const mmp2_twsi2_grps[] = {"twsi2-1", "twsi2-2",
+ "twsi2-3", "twsi2-4", "twsi2-5"};
+static const char * const mmp2_twsi3_grps[] = {"twsi3-1", "twsi3-2"};
+static const char * const mmp2_twsi4_grps[] = {"twsi4"};
+static const char * const mmp2_twsi5_grps[] = {"twsi5-1", "twsi5-2",
+ "twsi5-3"};
+static const char * const mmp2_twsi6_grps[] = {"twsi6-1", "twsi6-2",
+ "twsi6-3"};
+static const char * const mmp2_ccic1_grps[] = {"ccic1-1", "ccic1-2"};
+static const char * const mmp2_ccic2_grps[] = {"ccic2-1", "ccic2-2"};
+static const char * const mmp2_ulpi_grps[] = {"ulpi"};
+static const char * const mmp2_ro_grps[] = {"ro-1", "ro-2", "ro-3", "ro-4"};
+static const char * const mmp2_i2s_grps[] = {"i2s 5p1", "i2s 4p2"};
+static const char * const mmp2_ssp1_grps[] = {"ssp1 4p1", "ssp1 4p2",
+ "ssp1 4p3"};
+static const char * const mmp2_ssp2_grps[] = {"ssp2 4p1"};
+static const char * const mmp2_ssp3_grps[] = {"ssp3 4p1", "ssp3 4p2"};
+static const char * const mmp2_sspa2_grps[] = {"sspa2 4p1", "sspa2 4p2"};
+static const char * const mmp2_mmc1_grps[] = {"mmc1 8p1"};
+static const char * const mmp2_mmc2_grps[] = {"mmc2 6p1"};
+static const char * const mmp2_mmc3_grps[] = {"mmc3 10p1"};
+
+static struct pxa3xx_pmx_func mmp2_funcs[] = {
+ {"uart1", ARRAY_AND_SIZE(mmp2_uart1_grps)},
+ {"uart2", ARRAY_AND_SIZE(mmp2_uart2_grps)},
+ {"uart3", ARRAY_AND_SIZE(mmp2_uart3_grps)},
+ {"uart4", ARRAY_AND_SIZE(mmp2_uart4_grps)},
+ {"kpdk", ARRAY_AND_SIZE(mmp2_kpdk_grps)},
+ {"twsi2", ARRAY_AND_SIZE(mmp2_twsi2_grps)},
+ {"twsi3", ARRAY_AND_SIZE(mmp2_twsi3_grps)},
+ {"twsi4", ARRAY_AND_SIZE(mmp2_twsi4_grps)},
+ {"twsi5", ARRAY_AND_SIZE(mmp2_twsi5_grps)},
+ {"twsi6", ARRAY_AND_SIZE(mmp2_twsi6_grps)},
+ {"ccic1", ARRAY_AND_SIZE(mmp2_ccic1_grps)},
+ {"ccic2", ARRAY_AND_SIZE(mmp2_ccic2_grps)},
+ {"ulpi", ARRAY_AND_SIZE(mmp2_ulpi_grps)},
+ {"ro", ARRAY_AND_SIZE(mmp2_ro_grps)},
+ {"i2s", ARRAY_AND_SIZE(mmp2_i2s_grps)},
+ {"ssp1", ARRAY_AND_SIZE(mmp2_ssp1_grps)},
+ {"ssp2", ARRAY_AND_SIZE(mmp2_ssp2_grps)},
+ {"ssp3", ARRAY_AND_SIZE(mmp2_ssp3_grps)},
+ {"sspa2", ARRAY_AND_SIZE(mmp2_sspa2_grps)},
+ {"mmc1", ARRAY_AND_SIZE(mmp2_mmc1_grps)},
+ {"mmc2", ARRAY_AND_SIZE(mmp2_mmc2_grps)},
+ {"mmc3", ARRAY_AND_SIZE(mmp2_mmc3_grps)},
+};
+
+static struct pinctrl_desc mmp2_pctrl_desc = {
+ .name = "mmp2-pinctrl",
+ .owner = THIS_MODULE,
+};
+
+static struct pxa3xx_pinmux_info mmp2_info = {
+ .mfp = mmp2_mfp,
+ .num_mfp = ARRAY_SIZE(mmp2_mfp),
+ .grps = mmp2_grps,
+ .num_grps = ARRAY_SIZE(mmp2_grps),
+ .funcs = mmp2_funcs,
+ .num_funcs = ARRAY_SIZE(mmp2_funcs),
+ .num_gpio = 169,
+ .desc = &mmp2_pctrl_desc,
+ .pads = mmp2_pads,
+ .num_pads = ARRAY_SIZE(mmp2_pads),
+
+ .cputype = PINCTRL_MMP2,
+ .ds_mask = MMP2_DS_MASK,
+ .ds_shift = MMP2_DS_SHIFT,
+};
+
+static int __devinit mmp2_pinmux_probe(struct platform_device *pdev)
+{
+ return pxa3xx_pinctrl_register(pdev, &mmp2_info);
+}
+
+static int __devexit mmp2_pinmux_remove(struct platform_device *pdev)
+{
+ return pxa3xx_pinctrl_unregister(pdev);
+}
+
+static struct platform_driver mmp2_pinmux_driver = {
+ .driver = {
+ .name = "mmp2-pinmux",
+ .owner = THIS_MODULE,
+ },
+ .probe = mmp2_pinmux_probe,
+ .remove = __devexit_p(mmp2_pinmux_remove),
+};
+
+static int __init mmp2_pinmux_init(void)
+{
+ return platform_driver_register(&mmp2_pinmux_driver);
+}
+core_initcall_sync(mmp2_pinmux_init);
+
+static void __exit mmp2_pinmux_exit(void)
+{
+ platform_driver_unregister(&mmp2_pinmux_driver);
+}
+module_exit(mmp2_pinmux_exit);
+
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_DESCRIPTION("PXA3xx pin control driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-pxa168.c b/drivers/pinctrl/pinctrl-pxa168.c
new file mode 100644
index 0000000..c1997fa
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-pxa168.c
@@ -0,0 +1,651 @@
+/*
+ * linux/drivers/pinctrl/pinmux-pxa168.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ *
+ * Copyright (C) 2011, Marvell Technology Group Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include "pinctrl-pxa3xx.h"
+
+#define PXA168_DS_MASK 0x1800
+#define PXA168_DS_SHIFT 11
+#define PXA168_SLEEP_MASK 0x38
+#define PXA168_SLEEP_SELECT (1 << 9)
+#define PXA168_SLEEP_DATA (1 << 8)
+#define PXA168_SLEEP_DIR (1 << 7)
+
+#define MFPR_168(a, r, f0, f1, f2, f3, f4, f5, f6, f7) \
+ { \
+ .name = #a, \
+ .pin = a, \
+ .mfpr = r, \
+ .func = { \
+ PXA168_MUX_##f0, \
+ PXA168_MUX_##f1, \
+ PXA168_MUX_##f2, \
+ PXA168_MUX_##f3, \
+ PXA168_MUX_##f4, \
+ PXA168_MUX_##f5, \
+ PXA168_MUX_##f6, \
+ PXA168_MUX_##f7, \
+ }, \
+ }
+
+#define GRP_168(a, m, p) \
+ { .name = a, .mux = PXA168_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), }
+
+/* 131 pins */
+enum pxa168_pin_list {
+ /* 0~122: GPIO0~GPIO122 */
+ PWR_SCL = 123,
+ PWR_SDA,
+ TDI,
+ TMS,
+ TCK,
+ TDO,
+ TRST,
+ WAKEUP = 130,
+};
+
+enum pxa168_mux {
+ /* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */
+ PXA168_MUX_GPIO = 0,
+ PXA168_MUX_DFIO,
+ PXA168_MUX_NAND,
+ PXA168_MUX_SMC,
+ PXA168_MUX_SMC_CS0,
+ PXA168_MUX_SMC_CS1,
+ PXA168_MUX_SMC_INT,
+ PXA168_MUX_SMC_RDY,
+ PXA168_MUX_MMC1,
+ PXA168_MUX_MMC2,
+ PXA168_MUX_MMC2_CMD,
+ PXA168_MUX_MMC2_CLK,
+ PXA168_MUX_MMC3,
+ PXA168_MUX_MMC3_CMD,
+ PXA168_MUX_MMC3_CLK,
+ PXA168_MUX_MMC4,
+ PXA168_MUX_MSP,
+ PXA168_MUX_MSP_DAT3,
+ PXA168_MUX_MSP_INS,
+ PXA168_MUX_I2C,
+ PXA168_MUX_PWRI2C,
+ PXA168_MUX_AC97,
+ PXA168_MUX_AC97_SYSCLK,
+ PXA168_MUX_PWM,
+ PXA168_MUX_PWM1,
+ PXA168_MUX_XD,
+ PXA168_MUX_XP,
+ PXA168_MUX_LCD,
+ PXA168_MUX_CCIC,
+ PXA168_MUX_CF,
+ PXA168_MUX_CF_RDY,
+ PXA168_MUX_CF_nINPACK,
+ PXA168_MUX_CF_nWAIT,
+ PXA168_MUX_KP_MKOUT,
+ PXA168_MUX_KP_MKIN,
+ PXA168_MUX_KP_DK,
+ PXA168_MUX_ETH,
+ PXA168_MUX_ETH_TX,
+ PXA168_MUX_ETH_RX,
+ PXA168_MUX_ONE_WIRE,
+ PXA168_MUX_UART1,
+ PXA168_MUX_UART1_TX,
+ PXA168_MUX_UART1_CTS,
+ PXA168_MUX_UART1_nRI,
+ PXA168_MUX_UART1_DTR,
+ PXA168_MUX_UART2,
+ PXA168_MUX_UART2_TX,
+ PXA168_MUX_UART3,
+ PXA168_MUX_UART3_TX,
+ PXA168_MUX_UART3_CTS,
+ PXA168_MUX_SSP1,
+ PXA168_MUX_SSP1_TX,
+ PXA168_MUX_SSP2,
+ PXA168_MUX_SSP2_TX,
+ PXA168_MUX_SSP3,
+ PXA168_MUX_SSP3_TX,
+ PXA168_MUX_SSP4,
+ PXA168_MUX_SSP4_TX,
+ PXA168_MUX_SSP5,
+ PXA168_MUX_SSP5_TX,
+ PXA168_MUX_USB,
+ PXA168_MUX_JTAG,
+ PXA168_MUX_RESET,
+ PXA168_MUX_WAKEUP,
+ PXA168_MUX_EXT_32K_IN,
+ PXA168_MUX_NONE = 0xffff,
+};
+
+static struct pinctrl_pin_desc pxa168_pads[] = {
+ PINCTRL_PIN(GPIO0, "GPIO0"),
+ PINCTRL_PIN(GPIO1, "GPIO1"),
+ PINCTRL_PIN(GPIO2, "GPIO2"),
+ PINCTRL_PIN(GPIO3, "GPIO3"),
+ PINCTRL_PIN(GPIO4, "GPIO4"),
+ PINCTRL_PIN(GPIO5, "GPIO5"),
+ PINCTRL_PIN(GPIO6, "GPIO6"),
+ PINCTRL_PIN(GPIO7, "GPIO7"),
+ PINCTRL_PIN(GPIO8, "GPIO8"),
+ PINCTRL_PIN(GPIO9, "GPIO9"),
+ PINCTRL_PIN(GPIO10, "GPIO10"),
+ PINCTRL_PIN(GPIO11, "GPIO11"),
+ PINCTRL_PIN(GPIO12, "GPIO12"),
+ PINCTRL_PIN(GPIO13, "GPIO13"),
+ PINCTRL_PIN(GPIO14, "GPIO14"),
+ PINCTRL_PIN(GPIO15, "GPIO15"),
+ PINCTRL_PIN(GPIO16, "GPIO16"),
+ PINCTRL_PIN(GPIO17, "GPIO17"),
+ PINCTRL_PIN(GPIO18, "GPIO18"),
+ PINCTRL_PIN(GPIO19, "GPIO19"),
+ PINCTRL_PIN(GPIO20, "GPIO20"),
+ PINCTRL_PIN(GPIO21, "GPIO21"),
+ PINCTRL_PIN(GPIO22, "GPIO22"),
+ PINCTRL_PIN(GPIO23, "GPIO23"),
+ PINCTRL_PIN(GPIO24, "GPIO24"),
+ PINCTRL_PIN(GPIO25, "GPIO25"),
+ PINCTRL_PIN(GPIO26, "GPIO26"),
+ PINCTRL_PIN(GPIO27, "GPIO27"),
+ PINCTRL_PIN(GPIO28, "GPIO28"),
+ PINCTRL_PIN(GPIO29, "GPIO29"),
+ PINCTRL_PIN(GPIO30, "GPIO30"),
+ PINCTRL_PIN(GPIO31, "GPIO31"),
+ PINCTRL_PIN(GPIO32, "GPIO32"),
+ PINCTRL_PIN(GPIO33, "GPIO33"),
+ PINCTRL_PIN(GPIO34, "GPIO34"),
+ PINCTRL_PIN(GPIO35, "GPIO35"),
+ PINCTRL_PIN(GPIO36, "GPIO36"),
+ PINCTRL_PIN(GPIO37, "GPIO37"),
+ PINCTRL_PIN(GPIO38, "GPIO38"),
+ PINCTRL_PIN(GPIO39, "GPIO39"),
+ PINCTRL_PIN(GPIO40, "GPIO40"),
+ PINCTRL_PIN(GPIO41, "GPIO41"),
+ PINCTRL_PIN(GPIO42, "GPIO42"),
+ PINCTRL_PIN(GPIO43, "GPIO43"),
+ PINCTRL_PIN(GPIO44, "GPIO44"),
+ PINCTRL_PIN(GPIO45, "GPIO45"),
+ PINCTRL_PIN(GPIO46, "GPIO46"),
+ PINCTRL_PIN(GPIO47, "GPIO47"),
+ PINCTRL_PIN(GPIO48, "GPIO48"),
+ PINCTRL_PIN(GPIO49, "GPIO49"),
+ PINCTRL_PIN(GPIO50, "GPIO50"),
+ PINCTRL_PIN(GPIO51, "GPIO51"),
+ PINCTRL_PIN(GPIO52, "GPIO52"),
+ PINCTRL_PIN(GPIO53, "GPIO53"),
+ PINCTRL_PIN(GPIO54, "GPIO54"),
+ PINCTRL_PIN(GPIO55, "GPIO55"),
+ PINCTRL_PIN(GPIO56, "GPIO56"),
+ PINCTRL_PIN(GPIO57, "GPIO57"),
+ PINCTRL_PIN(GPIO58, "GPIO58"),
+ PINCTRL_PIN(GPIO59, "GPIO59"),
+ PINCTRL_PIN(GPIO60, "GPIO60"),
+ PINCTRL_PIN(GPIO61, "GPIO61"),
+ PINCTRL_PIN(GPIO62, "GPIO62"),
+ PINCTRL_PIN(GPIO63, "GPIO63"),
+ PINCTRL_PIN(GPIO64, "GPIO64"),
+ PINCTRL_PIN(GPIO65, "GPIO65"),
+ PINCTRL_PIN(GPIO66, "GPIO66"),
+ PINCTRL_PIN(GPIO67, "GPIO67"),
+ PINCTRL_PIN(GPIO68, "GPIO68"),
+ PINCTRL_PIN(GPIO69, "GPIO69"),
+ PINCTRL_PIN(GPIO70, "GPIO70"),
+ PINCTRL_PIN(GPIO71, "GPIO71"),
+ PINCTRL_PIN(GPIO72, "GPIO72"),
+ PINCTRL_PIN(GPIO73, "GPIO73"),
+ PINCTRL_PIN(GPIO74, "GPIO74"),
+ PINCTRL_PIN(GPIO75, "GPIO75"),
+ PINCTRL_PIN(GPIO76, "GPIO76"),
+ PINCTRL_PIN(GPIO77, "GPIO77"),
+ PINCTRL_PIN(GPIO78, "GPIO78"),
+ PINCTRL_PIN(GPIO79, "GPIO79"),
+ PINCTRL_PIN(GPIO80, "GPIO80"),
+ PINCTRL_PIN(GPIO81, "GPIO81"),
+ PINCTRL_PIN(GPIO82, "GPIO82"),
+ PINCTRL_PIN(GPIO83, "GPIO83"),
+ PINCTRL_PIN(GPIO84, "GPIO84"),
+ PINCTRL_PIN(GPIO85, "GPIO85"),
+ PINCTRL_PIN(GPIO86, "GPIO86"),
+ PINCTRL_PIN(GPIO87, "GPIO87"),
+ PINCTRL_PIN(GPIO88, "GPIO88"),
+ PINCTRL_PIN(GPIO89, "GPIO89"),
+ PINCTRL_PIN(GPIO90, "GPIO90"),
+ PINCTRL_PIN(GPIO91, "GPIO91"),
+ PINCTRL_PIN(GPIO92, "GPIO92"),
+ PINCTRL_PIN(GPIO93, "GPIO93"),
+ PINCTRL_PIN(GPIO94, "GPIO94"),
+ PINCTRL_PIN(GPIO95, "GPIO95"),
+ PINCTRL_PIN(GPIO96, "GPIO96"),
+ PINCTRL_PIN(GPIO97, "GPIO97"),
+ PINCTRL_PIN(GPIO98, "GPIO98"),
+ PINCTRL_PIN(GPIO99, "GPIO99"),
+ PINCTRL_PIN(GPIO100, "GPIO100"),
+ PINCTRL_PIN(GPIO101, "GPIO101"),
+ PINCTRL_PIN(GPIO102, "GPIO102"),
+ PINCTRL_PIN(GPIO103, "GPIO103"),
+ PINCTRL_PIN(GPIO104, "GPIO104"),
+ PINCTRL_PIN(GPIO105, "GPIO105"),
+ PINCTRL_PIN(GPIO106, "GPIO106"),
+ PINCTRL_PIN(GPIO107, "GPIO107"),
+ PINCTRL_PIN(GPIO108, "GPIO108"),
+ PINCTRL_PIN(GPIO109, "GPIO109"),
+ PINCTRL_PIN(GPIO110, "GPIO110"),
+ PINCTRL_PIN(GPIO111, "GPIO111"),
+ PINCTRL_PIN(GPIO112, "GPIO112"),
+ PINCTRL_PIN(GPIO113, "GPIO113"),
+ PINCTRL_PIN(GPIO114, "GPIO114"),
+ PINCTRL_PIN(GPIO115, "GPIO115"),
+ PINCTRL_PIN(GPIO116, "GPIO116"),
+ PINCTRL_PIN(GPIO117, "GPIO117"),
+ PINCTRL_PIN(GPIO118, "GPIO118"),
+ PINCTRL_PIN(GPIO119, "GPIO119"),
+ PINCTRL_PIN(GPIO120, "GPIO120"),
+ PINCTRL_PIN(GPIO121, "GPIO121"),
+ PINCTRL_PIN(GPIO122, "GPIO122"),
+ PINCTRL_PIN(PWR_SCL, "PWR_SCL"),
+ PINCTRL_PIN(PWR_SDA, "PWR_SDA"),
+ PINCTRL_PIN(TDI, "TDI"),
+ PINCTRL_PIN(TMS, "TMS"),
+ PINCTRL_PIN(TCK, "TCK"),
+ PINCTRL_PIN(TDO, "TDO"),
+ PINCTRL_PIN(TRST, "TRST"),
+ PINCTRL_PIN(WAKEUP, "WAKEUP"),
+};
+
+struct pxa3xx_mfp_pin pxa168_mfp[] = {
+ /* pin offs f0 f1 f2 f3 f4 f5 f6 f7 */
+ MFPR_168(GPIO0, 0x04C, DFIO, NONE, NONE, MSP, MMC3_CMD, GPIO, MMC3, NONE),
+ MFPR_168(GPIO1, 0x050, DFIO, NONE, NONE, MSP, MMC3_CLK, GPIO, MMC3, NONE),
+ MFPR_168(GPIO2, 0x054, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE),
+ MFPR_168(GPIO3, 0x058, DFIO, NONE, NONE, NONE, NONE, GPIO, MMC3, NONE),
+ MFPR_168(GPIO4, 0x05C, DFIO, NONE, NONE, MSP_DAT3, NONE, GPIO, MMC3, NONE),
+ MFPR_168(GPIO5, 0x060, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE),
+ MFPR_168(GPIO6, 0x064, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE),
+ MFPR_168(GPIO7, 0x068, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE),
+ MFPR_168(GPIO8, 0x06C, DFIO, MMC2, UART3_TX, NONE, MMC2_CMD, GPIO, MMC3_CLK, NONE),
+ MFPR_168(GPIO9, 0x070, DFIO, MMC2, UART3, NONE, MMC2_CLK, GPIO, MMC3_CMD, NONE),
+ MFPR_168(GPIO10, 0x074, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP_DAT3, NONE),
+ MFPR_168(GPIO11, 0x078, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP, NONE),
+ MFPR_168(GPIO12, 0x07C, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP, NONE),
+ MFPR_168(GPIO13, 0x080, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP, NONE),
+ MFPR_168(GPIO14, 0x084, DFIO, MMC2, NONE, NONE, NONE, GPIO, MSP, NONE),
+ MFPR_168(GPIO15, 0x088, DFIO, MMC2, NONE, NONE, NONE, GPIO, MSP, NONE),
+ MFPR_168(GPIO16, 0x08C, GPIO, NAND, SMC_CS0, SMC_CS1, NONE, NONE, MMC3, NONE),
+ MFPR_168(GPIO17, 0x090, NAND, NONE, NONE, NONE, NONE, GPIO, MSP, NONE),
+ MFPR_168(GPIO18, 0x094, GPIO, NAND, SMC_CS1, SMC_CS0, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO19, 0x098, SMC_CS0, NONE, NONE, CF, NONE, GPIO, NONE, NONE),
+ MFPR_168(GPIO20, 0x09C, GPIO, NONE, SMC_CS1, CF, CF_RDY, NONE, NONE, NONE),
+ MFPR_168(GPIO21, 0x0A0, NAND, MMC2_CLK, NONE, NONE, NONE, GPIO, NONE, NONE),
+ MFPR_168(GPIO22, 0x0A4, NAND, MMC2_CMD, NONE, NONE, NONE, GPIO, NONE, NONE),
+ MFPR_168(GPIO23, 0x0A8, SMC, NAND, NONE, CF, NONE, GPIO, NONE, NONE),
+ MFPR_168(GPIO24, 0x0AC, NAND, NONE, NONE, NONE, NONE, GPIO, NONE, NONE),
+ MFPR_168(GPIO25, 0x0B0, SMC, NAND, NONE, CF, NONE, GPIO, NONE, NONE),
+ MFPR_168(GPIO26, 0x0B4, GPIO, NAND, NONE, NONE, CF, NONE, NONE, NONE),
+ MFPR_168(GPIO27, 0x0B8, SMC_INT, NAND, SMC, NONE, SMC_RDY, GPIO, NONE, NONE),
+ MFPR_168(GPIO28, 0x0BC, SMC_RDY, MMC4, SMC, CF_RDY, NONE, GPIO, MMC2_CMD, NONE),
+ MFPR_168(GPIO29, 0x0C0, SMC, MMC4, NONE, CF, NONE, GPIO, MMC2_CLK, KP_DK),
+ MFPR_168(GPIO30, 0x0C4, SMC, MMC4, UART3_TX, CF, NONE, GPIO, MMC2, KP_DK),
+ MFPR_168(GPIO31, 0x0C8, SMC, MMC4, UART3, CF, NONE, GPIO, MMC2, KP_DK),
+ MFPR_168(GPIO32, 0x0CC, SMC, MMC4, UART3, CF, NONE, GPIO, MMC2, KP_DK),
+ MFPR_168(GPIO33, 0x0D0, SMC, MMC4, UART3, CF, CF_nINPACK, GPIO, MMC2, KP_DK),
+ MFPR_168(GPIO34, 0x0D4, GPIO, NONE, SMC_CS1, CF, CF_nWAIT, NONE, MMC3, KP_DK),
+ MFPR_168(GPIO35, 0x0D8, GPIO, NONE, SMC, CF_nINPACK, NONE, NONE, MMC3_CMD, KP_DK),
+ MFPR_168(GPIO36, 0x0DC, GPIO, NONE, SMC, CF_nWAIT, NONE, NONE, MMC3_CLK, KP_DK),
+ MFPR_168(GPIO37, 0x000, GPIO, MMC1, NONE, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK),
+ MFPR_168(GPIO38, 0x004, GPIO, MMC1, NONE, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK),
+ MFPR_168(GPIO39, 0x008, GPIO, NONE, NONE, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK),
+ MFPR_168(GPIO40, 0x00C, GPIO, MMC1, MSP, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK),
+ MFPR_168(GPIO41, 0x010, GPIO, MMC1, MSP, NONE, CCIC, XP, KP_MKIN, KP_DK),
+ MFPR_168(GPIO42, 0x014, GPIO, I2C, NONE, MSP, CCIC, XP, KP_MKIN, KP_DK),
+ MFPR_168(GPIO43, 0x018, GPIO, MMC1, MSP, MSP_INS, NONE, NONE, KP_MKIN, KP_DK),
+ MFPR_168(GPIO44, 0x01C, GPIO, MMC1, MSP_DAT3, MSP, CCIC, XP, KP_MKIN, KP_DK),
+ MFPR_168(GPIO45, 0x020, GPIO, NONE, NONE, MSP, CCIC, XP, NONE, KP_DK),
+ MFPR_168(GPIO46, 0x024, GPIO, MMC1, MSP_INS, MSP, CCIC, NONE, KP_MKOUT, KP_DK),
+ MFPR_168(GPIO47, 0x028, GPIO, NONE, NONE, MSP_INS, NONE, XP, NONE, KP_DK),
+ MFPR_168(GPIO48, 0x02C, GPIO, MMC1, NONE, MSP_DAT3, CCIC, NONE, NONE, KP_DK),
+ MFPR_168(GPIO49, 0x030, GPIO, MMC1, NONE, MSP, NONE, XD, KP_MKOUT, NONE),
+ MFPR_168(GPIO50, 0x034, GPIO, I2C, NONE, MSP, CCIC, XD, KP_MKOUT, NONE),
+ MFPR_168(GPIO51, 0x038, GPIO, MMC1, NONE, MSP, NONE, XD, KP_MKOUT, NONE),
+ MFPR_168(GPIO52, 0x03C, GPIO, MMC1, NONE, MSP, NONE, XD, KP_MKOUT, NONE),
+ MFPR_168(GPIO53, 0x040, GPIO, MMC1, NONE, NONE, NONE, XD, KP_MKOUT, NONE),
+ MFPR_168(GPIO54, 0x044, GPIO, MMC1, NONE, NONE, CCIC, XD, KP_MKOUT, NONE),
+ MFPR_168(GPIO55, 0x048, GPIO, NONE, NONE, MSP, CCIC, XD, KP_MKOUT, NONE),
+ MFPR_168(GPIO56, 0x0E0, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO57, 0x0E4, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO58, 0x0E8, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO59, 0x0EC, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO60, 0x0F0, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO61, 0x0F4, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO62, 0x0F8, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO63, 0x0FC, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO64, 0x100, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO65, 0x104, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO66, 0x108, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO67, 0x10C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO68, 0x110, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO69, 0x114, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO70, 0x118, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO71, 0x11C, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO72, 0x120, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO73, 0x124, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO74, 0x128, GPIO, LCD, PWM, XD, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO75, 0x12C, GPIO, LCD, PWM, XD, ONE_WIRE, NONE, NONE, NONE),
+ MFPR_168(GPIO76, 0x130, GPIO, LCD, PWM, I2C, NONE, NONE, MSP_INS, NONE),
+ MFPR_168(GPIO77, 0x134, GPIO, LCD, PWM1, I2C, ONE_WIRE, NONE, XD, NONE),
+ MFPR_168(GPIO78, 0x138, GPIO, LCD, NONE, NONE, NONE, MMC4, NONE, NONE),
+ MFPR_168(GPIO79, 0x13C, GPIO, LCD, NONE, NONE, ONE_WIRE, MMC4, NONE, NONE),
+ MFPR_168(GPIO80, 0x140, GPIO, LCD, NONE, I2C, NONE, MMC4, NONE, NONE),
+ MFPR_168(GPIO81, 0x144, GPIO, LCD, NONE, I2C, ONE_WIRE, MMC4, NONE, NONE),
+ MFPR_168(GPIO82, 0x148, GPIO, LCD, PWM, NONE, NONE, MMC4, NONE, NONE),
+ MFPR_168(GPIO83, 0x14C, GPIO, LCD, PWM, NONE, RESET, MMC4, NONE, NONE),
+ MFPR_168(GPIO84, 0x150, GPIO, NONE, PWM, ONE_WIRE, PWM1, NONE, NONE, EXT_32K_IN),
+ MFPR_168(GPIO85, 0x154, GPIO, NONE, PWM1, NONE, NONE, NONE, NONE, USB),
+ MFPR_168(GPIO86, 0x158, GPIO, MMC2, UART2, NONE, JTAG, ETH_TX, SSP5_TX, SSP5),
+ MFPR_168(GPIO87, 0x15C, GPIO, MMC2, UART2, NONE, JTAG, ETH_TX, SSP5, SSP5_TX),
+ MFPR_168(GPIO88, 0x160, GPIO, MMC2, UART2, UART2_TX, JTAG, ETH_TX, ETH_RX, SSP5),
+ MFPR_168(GPIO89, 0x164, GPIO, MMC2, UART2_TX, UART2, JTAG, ETH_TX, ETH_RX, SSP5),
+ MFPR_168(GPIO90, 0x168, GPIO, MMC2, NONE, SSP3, JTAG, ETH_TX, ETH_RX, NONE),
+ MFPR_168(GPIO91, 0x16C, GPIO, MMC2, NONE, SSP3, SSP4, ETH_TX, ETH_RX, NONE),
+ MFPR_168(GPIO92, 0x170, GPIO, MMC2, NONE, SSP3, SSP3_TX, ETH, NONE, NONE),
+ MFPR_168(GPIO93, 0x174, GPIO, MMC2, NONE, SSP3_TX, SSP3, ETH, NONE, NONE),
+ MFPR_168(GPIO94, 0x178, GPIO, MMC2_CMD, SSP3, AC97_SYSCLK, AC97, ETH, NONE, NONE),
+ MFPR_168(GPIO95, 0x17C, GPIO, MMC2_CLK, NONE, NONE, AC97, ETH, NONE, NONE),
+ MFPR_168(GPIO96, 0x180, GPIO, PWM, NONE, MMC2, NONE, ETH_RX, ETH_TX, NONE),
+ MFPR_168(GPIO97, 0x184, GPIO, PWM, ONE_WIRE, NONE, NONE, ETH_RX, ETH_TX, NONE),
+ MFPR_168(GPIO98, 0x188, GPIO, PWM1, UART3_TX, UART3, NONE, ETH_RX, ETH_TX, NONE),
+ MFPR_168(GPIO99, 0x18C, GPIO, ONE_WIRE, UART3, UART3_TX, NONE, ETH_RX, ETH_TX, NONE),
+ MFPR_168(GPIO100, 0x190, GPIO, NONE, UART3_CTS, UART3, NONE, ETH, NONE, NONE),
+ MFPR_168(GPIO101, 0x194, GPIO, NONE, UART3, UART3_CTS, NONE, ETH, NONE, NONE),
+ MFPR_168(GPIO102, 0x198, GPIO, I2C, UART3, SSP4, NONE, NONE, NONE, NONE),
+ MFPR_168(GPIO103, 0x19C, GPIO, I2C, UART3, SSP4, SSP2, ETH, NONE, NONE),
+ MFPR_168(GPIO104, 0x1A0, GPIO, PWM, UART1, SSP4, SSP4_TX, AC97, KP_MKOUT, NONE),
+ MFPR_168(GPIO105, 0x1A4, GPIO, I2C, UART1, SSP4_TX, SSP4, AC97, KP_MKOUT, NONE),
+ MFPR_168(GPIO106, 0x1A8, GPIO, I2C, PWM1, AC97_SYSCLK, MMC2, NONE, KP_MKOUT, NONE),
+ MFPR_168(GPIO107, 0x1AC, GPIO, UART1_TX, UART1, NONE, SSP2, MSP_DAT3, NONE, KP_MKIN),
+ MFPR_168(GPIO108, 0x1B0, GPIO, UART1, UART1_TX, NONE, SSP2_TX, MSP, NONE, KP_MKIN),
+ MFPR_168(GPIO109, 0x1B4, GPIO, UART1_CTS, UART1, NONE, AC97_SYSCLK, MSP, NONE, KP_MKIN),
+ MFPR_168(GPIO110, 0x1B8, GPIO, UART1, UART1_CTS, NONE, SMC_RDY, MSP, NONE, KP_MKIN),
+ MFPR_168(GPIO111, 0x1BC, GPIO, UART1_nRI, UART1, SSP3, SSP2, MSP, XD, KP_MKOUT),
+ MFPR_168(GPIO112, 0x1C0, GPIO, UART1_DTR, UART1, ONE_WIRE, SSP2, MSP, XD, KP_MKOUT),
+ MFPR_168(GPIO113, 0x1C4, GPIO, NONE, NONE, NONE, NONE, NONE, AC97_SYSCLK, NONE),
+ MFPR_168(GPIO114, 0x1C8, GPIO, SSP1, NONE, NONE, NONE, NONE, AC97, NONE),
+ MFPR_168(GPIO115, 0x1CC, GPIO, SSP1, NONE, NONE, NONE, NONE, AC97, NONE),
+ MFPR_168(GPIO116, 0x1D0, GPIO, SSP1_TX, SSP1, NONE, NONE, NONE, AC97, NONE),
+ MFPR_168(GPIO117, 0x1D4, GPIO, SSP1, SSP1_TX, NONE, MMC2_CMD, NONE, AC97, NONE),
+ MFPR_168(GPIO118, 0x1D8, GPIO, SSP2, NONE, NONE, MMC2_CLK, NONE, AC97, KP_MKIN),
+ MFPR_168(GPIO119, 0x1DC, GPIO, SSP2, NONE, NONE, MMC2, NONE, AC97, KP_MKIN),
+ MFPR_168(GPIO120, 0x1E0, GPIO, SSP2, SSP2_TX, NONE, MMC2, NONE, NONE, KP_MKIN),
+ MFPR_168(GPIO121, 0x1E4, GPIO, SSP2_TX, SSP2, NONE, MMC2, NONE, NONE, KP_MKIN),
+ MFPR_168(GPIO122, 0x1E8, GPIO, AC97_SYSCLK, SSP2, PWM, MMC2, NONE, NONE, NONE),
+ MFPR_168(PWR_SCL, 0x1EC, PWRI2C, NONE, NONE, NONE, NONE, NONE, GPIO, MMC4),
+ MFPR_168(PWR_SDA, 0x1F0, PWRI2C, NONE, NONE, NONE, NONE, NONE, GPIO, NONE),
+ MFPR_168(TDI, 0x1F4, JTAG, PWM1, UART2, MMC4, SSP5, NONE, XD, MMC4),
+ MFPR_168(TMS, 0x1F8, JTAG, PWM, UART2, NONE, SSP5, NONE, XD, MMC4),
+ MFPR_168(TCK, 0x1FC, JTAG, PWM, UART2, UART2_TX, SSP5, NONE, XD, MMC4),
+ MFPR_168(TDO, 0x200, JTAG, PWM, UART2_TX, UART2, SSP5_TX, NONE, XD, MMC4),
+ MFPR_168(TRST, 0x204, JTAG, ONE_WIRE, SSP2, SSP3, AC97_SYSCLK, NONE, XD, MMC4),
+ MFPR_168(WAKEUP, 0x208, WAKEUP, ONE_WIRE, PWM1, PWM, SSP2, NONE, GPIO, MMC4),
+};
+
+static const unsigned p168_jtag_pin1[] = {TDI, TMS, TCK, TDO, TRST};
+static const unsigned p168_wakeup_pin1[] = {WAKEUP};
+static const unsigned p168_ssp1rx_pin1[] = {GPIO114, GPIO115, GPIO116};
+static const unsigned p168_ssp1tx_pin1[] = {GPIO117};
+static const unsigned p168_ssp4rx_pin1[] = {GPIO102, GPIO103, GPIO104};
+static const unsigned p168_ssp4tx_pin1[] = {GPIO105};
+static const unsigned p168_ssp5rx_pin1[] = {GPIO86, GPIO88, GPIO89};
+static const unsigned p168_ssp5tx_pin1[] = {GPIO87};
+static const unsigned p168_i2c_pin1[] = {GPIO105, GPIO106};
+static const unsigned p168_pwri2c_pin1[] = {PWR_SCL, PWR_SDA};
+static const unsigned p168_mmc1_pin1[] = {GPIO40, GPIO41, GPIO43, GPIO46,
+ GPIO49, GPIO51, GPIO52, GPIO53};
+static const unsigned p168_mmc2_data_pin1[] = {GPIO90, GPIO91, GPIO92, GPIO93};
+static const unsigned p168_mmc2_cmd_pin1[] = {GPIO94};
+static const unsigned p168_mmc2_clk_pin1[] = {GPIO95};
+static const unsigned p168_mmc3_data_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3,
+ GPIO4, GPIO5, GPIO6, GPIO7};
+static const unsigned p168_mmc3_cmd_pin1[] = {GPIO9};
+static const unsigned p168_mmc3_clk_pin1[] = {GPIO8};
+static const unsigned p168_eth_pin1[] = {GPIO92, GPIO93, GPIO100, GPIO101,
+ GPIO103};
+static const unsigned p168_ethtx_pin1[] = {GPIO86, GPIO87, GPIO88, GPIO89,
+ GPIO90, GPIO91};
+static const unsigned p168_ethrx_pin1[] = {GPIO94, GPIO95, GPIO96, GPIO97,
+ GPIO98, GPIO99};
+static const unsigned p168_uart1rx_pin1[] = {GPIO107};
+static const unsigned p168_uart1tx_pin1[] = {GPIO108};
+static const unsigned p168_uart3rx_pin1[] = {GPIO98, GPIO100, GPIO101};
+static const unsigned p168_uart3tx_pin1[] = {GPIO99};
+static const unsigned p168_msp_pin1[] = {GPIO40, GPIO41, GPIO42, GPIO43,
+ GPIO44, GPIO50};
+static const unsigned p168_ccic_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40,
+ GPIO41, GPIO42, GPIO44, GPIO45, GPIO46, GPIO48, GPIO54, GPIO55};
+static const unsigned p168_xd_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40,
+ GPIO41, GPIO42, GPIO44, GPIO45, GPIO47, GPIO48, GPIO49, GPIO50,
+ GPIO51, GPIO52};
+static const unsigned p168_lcd_pin1[] = {GPIO56, GPIO57, GPIO58, GPIO59,
+ GPIO60, GPIO61, GPIO62, GPIO63, GPIO64, GPIO65, GPIO66, GPIO67,
+ GPIO68, GPIO69, GPIO70, GPIO71, GPIO72, GPIO73, GPIO74, GPIO75,
+ GPIO76, GPIO77, GPIO78, GPIO79, GPIO80, GPIO81, GPIO82, GPIO83};
+static const unsigned p168_dfio_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3,
+ GPIO4, GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12,
+ GPIO13, GPIO14, GPIO15};
+static const unsigned p168_nand_pin1[] = {GPIO16, GPIO17, GPIO21, GPIO22,
+ GPIO24, GPIO26};
+static const unsigned p168_smc_pin1[] = {GPIO23, GPIO25, GPIO29, GPIO35,
+ GPIO36};
+static const unsigned p168_smccs0_pin1[] = {GPIO18};
+static const unsigned p168_smccs1_pin1[] = {GPIO34};
+static const unsigned p168_smcrdy_pin1[] = {GPIO28};
+static const unsigned p168_ac97sysclk_pin1[] = {GPIO113};
+static const unsigned p168_ac97_pin1[] = {GPIO114, GPIO115, GPIO117, GPIO118,
+ GPIO119};
+static const unsigned p168_cf_pin1[] = {GPIO19, GPIO20, GPIO23, GPIO25,
+ GPIO28, GPIO29, GPIO30, GPIO31, GPIO32, GPIO33, GPIO34, GPIO35,
+ GPIO36};
+static const unsigned p168_kpmkin_pin1[] = {GPIO109, GPIO110, GPIO121};
+static const unsigned p168_kpmkout_pin1[] = {GPIO111, GPIO112};
+static const unsigned p168_gpio86_pin1[] = {WAKEUP};
+static const unsigned p168_gpio86_pin2[] = {GPIO86};
+static const unsigned p168_gpio87_pin1[] = {GPIO87};
+static const unsigned p168_gpio87_pin2[] = {PWR_SDA};
+static const unsigned p168_gpio88_pin1[] = {GPIO88};
+static const unsigned p168_gpio88_pin2[] = {PWR_SCL};
+
+static struct pxa3xx_pin_group pxa168_grps[] = {
+ GRP_168("uart1rx-1", UART1, p168_uart1rx_pin1),
+ GRP_168("uart1tx-1", UART1_TX, p168_uart1tx_pin1),
+ GRP_168("uart3rx-1", UART3, p168_uart3rx_pin1),
+ GRP_168("uart3tx-1", UART3_TX, p168_uart3tx_pin1),
+ GRP_168("ssp1rx-1", SSP1, p168_ssp1rx_pin1),
+ GRP_168("ssp1tx-1", SSP1_TX, p168_ssp1tx_pin1),
+ GRP_168("ssp4rx-1", SSP4, p168_ssp4rx_pin1),
+ GRP_168("ssp4tx-1", SSP4_TX, p168_ssp4tx_pin1),
+ GRP_168("ssp5rx-1", SSP5, p168_ssp5rx_pin1),
+ GRP_168("ssp5tx-1", SSP5_TX, p168_ssp5tx_pin1),
+ GRP_168("jtag", JTAG, p168_jtag_pin1),
+ GRP_168("wakeup", WAKEUP, p168_wakeup_pin1),
+ GRP_168("i2c", I2C, p168_i2c_pin1),
+ GRP_168("pwri2c", PWRI2C, p168_pwri2c_pin1),
+ GRP_168("mmc1 8p1", MMC1, p168_mmc1_pin1),
+ GRP_168("mmc2 4p1", MMC2, p168_mmc2_data_pin1),
+ GRP_168("mmc2 cmd1", MMC2_CMD, p168_mmc2_cmd_pin1),
+ GRP_168("mmc2 clk1", MMC2_CLK, p168_mmc2_clk_pin1),
+ GRP_168("mmc3 8p1", MMC3, p168_mmc3_data_pin1),
+ GRP_168("mmc3 cmd1", MMC3_CMD, p168_mmc3_cmd_pin1),
+ GRP_168("mmc3 clk1", MMC3_CLK, p168_mmc3_clk_pin1),
+ GRP_168("eth", ETH, p168_eth_pin1),
+ GRP_168("eth rx", ETH_RX, p168_ethrx_pin1),
+ GRP_168("eth tx", ETH_TX, p168_ethtx_pin1),
+ GRP_168("msp", MSP, p168_msp_pin1),
+ GRP_168("ccic", CCIC, p168_ccic_pin1),
+ GRP_168("xd", XD, p168_xd_pin1),
+ GRP_168("lcd", LCD, p168_lcd_pin1),
+ GRP_168("dfio", DFIO, p168_dfio_pin1),
+ GRP_168("nand", NAND, p168_nand_pin1),
+ GRP_168("smc", SMC, p168_smc_pin1),
+ GRP_168("smc cs0", SMC_CS0, p168_smccs0_pin1),
+ GRP_168("smc cs1", SMC_CS1, p168_smccs1_pin1),
+ GRP_168("smc rdy", SMC_RDY, p168_smcrdy_pin1),
+ GRP_168("ac97 sysclk", AC97_SYSCLK, p168_ac97sysclk_pin1),
+ GRP_168("ac97", AC97, p168_ac97_pin1),
+ GRP_168("cf", CF, p168_cf_pin1),
+ GRP_168("kp mkin 3p1", KP_MKIN, p168_kpmkin_pin1),
+ GRP_168("kp mkout 2p1", KP_MKOUT, p168_kpmkout_pin1),
+ GRP_168("gpio86-1", GPIO, p168_gpio86_pin1),
+ GRP_168("gpio86-2", GPIO, p168_gpio86_pin2),
+ GRP_168("gpio87-1", GPIO, p168_gpio87_pin1),
+ GRP_168("gpio87-2", GPIO, p168_gpio87_pin2),
+ GRP_168("gpio88-1", GPIO, p168_gpio88_pin1),
+ GRP_168("gpio88-2", GPIO, p168_gpio88_pin2),
+};
+
+static const char * const p168_uart1rx_grps[] = {"uart1rx-1"};
+static const char * const p168_uart1tx_grps[] = {"uart1tx-1"};
+static const char * const p168_uart3rx_grps[] = {"uart3rx-1"};
+static const char * const p168_uart3tx_grps[] = {"uart3tx-1"};
+static const char * const p168_ssp1rx_grps[] = {"ssp1rx-1"};
+static const char * const p168_ssp1tx_grps[] = {"ssp1tx-1"};
+static const char * const p168_ssp4rx_grps[] = {"ssp4rx-1"};
+static const char * const p168_ssp4tx_grps[] = {"ssp4tx-1"};
+static const char * const p168_ssp5rx_grps[] = {"ssp5rx-1"};
+static const char * const p168_ssp5tx_grps[] = {"ssp5tx-1"};
+static const char * const p168_i2c_grps[] = {"i2c"};
+static const char * const p168_pwri2c_grps[] = {"pwri2c"};
+static const char * const p168_mmc1_grps[] = {"mmc1 8p1"};
+static const char * const p168_mmc2_data_grps[] = {"mmc2 4p1"};
+static const char * const p168_mmc2_cmd_grps[] = {"mmc2 cmd1"};
+static const char * const p168_mmc2_clk_grps[] = {"mmc2 clk1"};
+static const char * const p168_mmc3_data_grps[] = {"mmc3 8p1"};
+static const char * const p168_mmc3_cmd_grps[] = {"mmc3 cmd1"};
+static const char * const p168_mmc3_clk_grps[] = {"mmc3 clk1"};
+static const char * const p168_eth_grps[] = {"eth"};
+static const char * const p168_ethrx_grps[] = {"eth rx"};
+static const char * const p168_ethtx_grps[] = {"eth tx"};
+static const char * const p168_msp_grps[] = {"msp"};
+static const char * const p168_ccic_grps[] = {"ccic"};
+static const char * const p168_xd_grps[] = {"xd"};
+static const char * const p168_lcd_grps[] = {"lcd"};
+static const char * const p168_dfio_grps[] = {"dfio"};
+static const char * const p168_nand_grps[] = {"nand"};
+static const char * const p168_smc_grps[] = {"smc"};
+static const char * const p168_smccs0_grps[] = {"smc cs0"};
+static const char * const p168_smccs1_grps[] = {"smc cs1"};
+static const char * const p168_smcrdy_grps[] = {"smc rdy"};
+static const char * const p168_ac97sysclk_grps[] = {"ac97 sysclk"};
+static const char * const p168_ac97_grps[] = {"ac97"};
+static const char * const p168_cf_grps[] = {"cf"};
+static const char * const p168_kpmkin_grps[] = {"kp mkin 3p1"};
+static const char * const p168_kpmkout_grps[] = {"kp mkout 2p1"};
+static const char * const p168_gpio86_grps[] = {"gpio86-1", "gpio86-2"};
+static const char * const p168_gpio87_grps[] = {"gpio87-1", "gpio87-2"};
+static const char * const p168_gpio88_grps[] = {"gpio88-1", "gpio88-2"};
+
+static struct pxa3xx_pmx_func pxa168_funcs[] = {
+ {"uart1 rx", ARRAY_AND_SIZE(p168_uart1rx_grps)},
+ {"uart1 tx", ARRAY_AND_SIZE(p168_uart1tx_grps)},
+ {"uart3 rx", ARRAY_AND_SIZE(p168_uart3rx_grps)},
+ {"uart3 tx", ARRAY_AND_SIZE(p168_uart3tx_grps)},
+ {"ssp1 rx", ARRAY_AND_SIZE(p168_ssp1rx_grps)},
+ {"ssp1 tx", ARRAY_AND_SIZE(p168_ssp1tx_grps)},
+ {"ssp4 rx", ARRAY_AND_SIZE(p168_ssp4rx_grps)},
+ {"ssp4 tx", ARRAY_AND_SIZE(p168_ssp4tx_grps)},
+ {"ssp5 rx", ARRAY_AND_SIZE(p168_ssp5rx_grps)},
+ {"ssp5 tx", ARRAY_AND_SIZE(p168_ssp5tx_grps)},
+ {"i2c", ARRAY_AND_SIZE(p168_i2c_grps)},
+ {"pwri2c", ARRAY_AND_SIZE(p168_pwri2c_grps)},
+ {"mmc1", ARRAY_AND_SIZE(p168_mmc1_grps)},
+ {"mmc2", ARRAY_AND_SIZE(p168_mmc2_data_grps)},
+ {"mmc2 cmd", ARRAY_AND_SIZE(p168_mmc2_cmd_grps)},
+ {"mmc2 clk", ARRAY_AND_SIZE(p168_mmc2_clk_grps)},
+ {"mmc3", ARRAY_AND_SIZE(p168_mmc3_data_grps)},
+ {"mmc3 cmd", ARRAY_AND_SIZE(p168_mmc3_cmd_grps)},
+ {"mmc3 clk", ARRAY_AND_SIZE(p168_mmc3_clk_grps)},
+ {"eth", ARRAY_AND_SIZE(p168_eth_grps)},
+ {"eth rx", ARRAY_AND_SIZE(p168_ethrx_grps)},
+ {"eth tx", ARRAY_AND_SIZE(p168_ethtx_grps)},
+ {"msp", ARRAY_AND_SIZE(p168_msp_grps)},
+ {"ccic", ARRAY_AND_SIZE(p168_ccic_grps)},
+ {"xd", ARRAY_AND_SIZE(p168_xd_grps)},
+ {"lcd", ARRAY_AND_SIZE(p168_lcd_grps)},
+ {"dfio", ARRAY_AND_SIZE(p168_dfio_grps)},
+ {"nand", ARRAY_AND_SIZE(p168_nand_grps)},
+ {"smc", ARRAY_AND_SIZE(p168_smc_grps)},
+ {"smc cs0", ARRAY_AND_SIZE(p168_smccs0_grps)},
+ {"smc cs1", ARRAY_AND_SIZE(p168_smccs1_grps)},
+ {"smc rdy", ARRAY_AND_SIZE(p168_smcrdy_grps)},
+ {"ac97", ARRAY_AND_SIZE(p168_ac97_grps)},
+ {"ac97 sysclk", ARRAY_AND_SIZE(p168_ac97sysclk_grps)},
+ {"cf", ARRAY_AND_SIZE(p168_cf_grps)},
+ {"kpmkin", ARRAY_AND_SIZE(p168_kpmkin_grps)},
+ {"kpmkout", ARRAY_AND_SIZE(p168_kpmkout_grps)},
+ {"gpio86", ARRAY_AND_SIZE(p168_gpio86_grps)},
+ {"gpio87", ARRAY_AND_SIZE(p168_gpio87_grps)},
+ {"gpio88", ARRAY_AND_SIZE(p168_gpio88_grps)},
+};
+
+static struct pinctrl_desc pxa168_pctrl_desc = {
+ .name = "pxa168-pinctrl",
+ .owner = THIS_MODULE,
+};
+
+static struct pxa3xx_pinmux_info pxa168_info = {
+ .mfp = pxa168_mfp,
+ .num_mfp = ARRAY_SIZE(pxa168_mfp),
+ .grps = pxa168_grps,
+ .num_grps = ARRAY_SIZE(pxa168_grps),
+ .funcs = pxa168_funcs,
+ .num_funcs = ARRAY_SIZE(pxa168_funcs),
+ .num_gpio = 128,
+ .desc = &pxa168_pctrl_desc,
+ .pads = pxa168_pads,
+ .num_pads = ARRAY_SIZE(pxa168_pads),
+
+ .cputype = PINCTRL_PXA168,
+ .ds_mask = PXA168_DS_MASK,
+ .ds_shift = PXA168_DS_SHIFT,
+};
+
+static int __devinit pxa168_pinmux_probe(struct platform_device *pdev)
+{
+ return pxa3xx_pinctrl_register(pdev, &pxa168_info);
+}
+
+static int __devexit pxa168_pinmux_remove(struct platform_device *pdev)
+{
+ return pxa3xx_pinctrl_unregister(pdev);
+}
+
+static struct platform_driver pxa168_pinmux_driver = {
+ .driver = {
+ .name = "pxa168-pinmux",
+ .owner = THIS_MODULE,
+ },
+ .probe = pxa168_pinmux_probe,
+ .remove = __devexit_p(pxa168_pinmux_remove),
+};
+
+static int __init pxa168_pinmux_init(void)
+{
+ return platform_driver_register(&pxa168_pinmux_driver);
+}
+core_initcall_sync(pxa168_pinmux_init);
+
+static void __exit pxa168_pinmux_exit(void)
+{
+ platform_driver_unregister(&pxa168_pinmux_driver);
+}
+module_exit(pxa168_pinmux_exit);
+
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_DESCRIPTION("PXA3xx pin control driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-pxa3xx.c b/drivers/pinctrl/pinctrl-pxa3xx.c
new file mode 100644
index 0000000..079dce0
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-pxa3xx.c
@@ -0,0 +1,244 @@
+/*
+ * linux/drivers/pinctrl/pinctrl-pxa3xx.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ *
+ * Copyright (C) 2011, Marvell Technology Group Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+#include "pinctrl-pxa3xx.h"
+
+static struct pinctrl_gpio_range pxa3xx_pinctrl_gpio_range = {
+ .name = "PXA3xx GPIO",
+ .id = 0,
+ .base = 0,
+ .pin_base = 0,
+};
+
+static int pxa3xx_list_groups(struct pinctrl_dev *pctrldev, unsigned selector)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ if (selector >= info->num_grps)
+ return -EINVAL;
+ return 0;
+}
+
+static const char *pxa3xx_get_group_name(struct pinctrl_dev *pctrldev,
+ unsigned selector)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ if (selector >= info->num_grps)
+ return NULL;
+ return info->grps[selector].name;
+}
+
+static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev,
+ unsigned selector,
+ const unsigned **pins,
+ unsigned *num_pins)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ if (selector >= info->num_grps)
+ return -EINVAL;
+ *pins = info->grps[selector].pins;
+ *num_pins = info->grps[selector].npins;
+ return 0;
+}
+
+static struct pinctrl_ops pxa3xx_pctrl_ops = {
+ .list_groups = pxa3xx_list_groups,
+ .get_group_name = pxa3xx_get_group_name,
+ .get_group_pins = pxa3xx_get_group_pins,
+};
+
+static int pxa3xx_pmx_list_func(struct pinctrl_dev *pctrldev, unsigned func)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ if (func >= info->num_funcs)
+ return -EINVAL;
+ return 0;
+}
+
+static const char *pxa3xx_pmx_get_func_name(struct pinctrl_dev *pctrldev,
+ unsigned func)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ return info->funcs[func].name;
+}
+
+static int pxa3xx_pmx_get_groups(struct pinctrl_dev *pctrldev, unsigned func,
+ const char * const **groups,
+ unsigned * const num_groups)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ *groups = info->funcs[func].groups;
+ *num_groups = info->funcs[func].num_groups;
+ return 0;
+}
+
+/* Return function number. If failure, return negative value. */
+static int match_mux(struct pxa3xx_mfp_pin *mfp, unsigned mux)
+{
+ int i;
+ for (i = 0; i < PXA3xx_MAX_MUX; i++) {
+ if (mfp->func[i] == mux)
+ break;
+ }
+ if (i >= PXA3xx_MAX_MUX)
+ return -EINVAL;
+ return i;
+}
+
+/* check whether current pin configuration is valid. Negative for failure */
+static int match_group_mux(struct pxa3xx_pin_group *grp,
+ struct pxa3xx_pinmux_info *info,
+ unsigned mux)
+{
+ int i, pin, ret = 0;
+ for (i = 0; i < grp->npins; i++) {
+ pin = grp->pins[i];
+ ret = match_mux(&info->mfp[pin], mux);
+ if (ret < 0) {
+ dev_err(info->dev, "Can't find mux %d on pin%d\n",
+ mux, pin);
+ break;
+ }
+ }
+ return ret;
+}
+
+static int pxa3xx_pmx_enable(struct pinctrl_dev *pctrldev, unsigned func,
+ unsigned group)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ struct pxa3xx_pin_group *pin_grp = &info->grps[group];
+ unsigned int data;
+ int i, mfpr, pin, pin_func;
+
+ if (!pin_grp->npins ||
+ (match_group_mux(pin_grp, info, pin_grp->mux) < 0)) {
+ dev_err(info->dev, "Failed to set the pin group: %d\n", group);
+ return -EINVAL;
+ }
+ for (i = 0; i < pin_grp->npins; i++) {
+ pin = pin_grp->pins[i];
+ pin_func = match_mux(&info->mfp[pin], pin_grp->mux);
+ mfpr = info->mfp[pin].mfpr;
+ data = readl_relaxed(info->virt_base + mfpr);
+ data &= ~MFPR_FUNC_MASK;
+ data |= pin_func;
+ writel_relaxed(data, info->virt_base + mfpr);
+ }
+ return 0;
+}
+
+static void pxa3xx_pmx_disable(struct pinctrl_dev *pctrldev, unsigned func,
+ unsigned group)
+{
+}
+
+static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev,
+ struct pinctrl_gpio_range *range,
+ unsigned pin)
+{
+ struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
+ unsigned int data;
+ int pin_func, mfpr;
+
+ pin_func = match_mux(&info->mfp[pin], PXA3xx_MUX_GPIO);
+ if (pin_func < 0) {
+ dev_err(info->dev, "No GPIO function on pin%d (%s)\n",
+ pin, info->pads[pin].name);
+ return -EINVAL;
+ }
+ mfpr = info->mfp[pin].mfpr;
+ /* write gpio function into mfpr register */
+ data = readl_relaxed(info->virt_base + mfpr) & ~MFPR_FUNC_MASK;
+ data |= pin_func;
+ writel_relaxed(data, info->virt_base + mfpr);
+ return 0;
+}
+
+static struct pinmux_ops pxa3xx_pmx_ops = {
+ .list_functions = pxa3xx_pmx_list_func,
+ .get_function_name = pxa3xx_pmx_get_func_name,
+ .get_function_groups = pxa3xx_pmx_get_groups,
+ .enable = pxa3xx_pmx_enable,
+ .disable = pxa3xx_pmx_disable,
+ .gpio_request_enable = pxa3xx_pmx_request_gpio,
+};
+
+int pxa3xx_pinctrl_register(struct platform_device *pdev,
+ struct pxa3xx_pinmux_info *info)
+{
+ struct pinctrl_desc *desc;
+ struct resource *res;
+ int ret = 0;
+
+ if (!info || !info->cputype)
+ return -EINVAL;
+ desc = info->desc;
+ desc->pins = info->pads;
+ desc->npins = info->num_pads;
+ desc->pctlops = &pxa3xx_pctrl_ops;
+ desc->pmxops = &pxa3xx_pmx_ops;
+ info->dev = &pdev->dev;
+ pxa3xx_pinctrl_gpio_range.npins = info->num_gpio;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res)
+ return -ENOENT;
+ info->phy_base = res->start;
+ info->phy_size = resource_size(res);
+ info->virt_base = ioremap(info->phy_base, info->phy_size);
+ if (!info->virt_base)
+ return -ENOMEM;
+ info->pctrl = pinctrl_register(desc, &pdev->dev, info);
+ if (!info->pctrl) {
+ dev_err(&pdev->dev, "failed to register PXA pinmux driver\n");
+ ret = -EINVAL;
+ goto err;
+ }
+ pinctrl_add_gpio_range(info->pctrl, &pxa3xx_pinctrl_gpio_range);
+ platform_set_drvdata(pdev, info);
+ return 0;
+err:
+ iounmap(info->virt_base);
+ return ret;
+}
+
+int pxa3xx_pinctrl_unregister(struct platform_device *pdev)
+{
+ struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev);
+
+ pinctrl_unregister(info->pctrl);
+ iounmap(info->virt_base);
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+static int __init pxa3xx_pinctrl_init(void)
+{
+ pr_info("pxa3xx-pinctrl: PXA3xx pinctrl driver initializing\n");
+ return 0;
+}
+core_initcall_sync(pxa3xx_pinctrl_init);
+
+static void __exit pxa3xx_pinctrl_exit(void)
+{
+}
+module_exit(pxa3xx_pinctrl_exit);
+
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_DESCRIPTION("PXA3xx pin control driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-pxa3xx.h b/drivers/pinctrl/pinctrl-pxa3xx.h
new file mode 100644
index 0000000..8135744
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-pxa3xx.h
@@ -0,0 +1,264 @@
+/*
+ * linux/drivers/pinctrl/pinctrl-pxa3xx.h
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ *
+ * Copyright (C) 2011, Marvell Technology Group Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ */
+
+#ifndef __PINCTRL_PXA3XX_H
+
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+
+#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
+
+#define PXA3xx_MUX_GPIO 0
+
+#define PXA3xx_MAX_MUX 8
+#define MFPR_FUNC_MASK 0x7
+
+enum pxa_cpu_type {
+ PINCTRL_INVALID = 0,
+ PINCTRL_PXA300,
+ PINCTRL_PXA310,
+ PINCTRL_PXA320,
+ PINCTRL_PXA168,
+ PINCTRL_PXA910,
+ PINCTRL_PXA930,
+ PINCTRL_PXA955,
+ PINCTRL_MMP2,
+ PINCTRL_MAX,
+};
+
+struct pxa3xx_mfp_pin {
+ const char *name;
+ const unsigned int pin;
+ const unsigned int mfpr; /* register offset */
+ const unsigned short func[8];
+};
+
+struct pxa3xx_pin_group {
+ const char *name;
+ const unsigned mux;
+ const unsigned *pins;
+ const unsigned npins;
+};
+
+struct pxa3xx_pmx_func {
+ const char *name;
+ const char * const * groups;
+ const unsigned num_groups;
+};
+
+struct pxa3xx_pinmux_info {
+ struct device *dev;
+ struct pinctrl_dev *pctrl;
+ enum pxa_cpu_type cputype;
+ unsigned int phy_base;
+ unsigned int phy_size;
+ void __iomem *virt_base;
+
+ struct pxa3xx_mfp_pin *mfp;
+ unsigned int num_mfp;
+ struct pxa3xx_pin_group *grps;
+ unsigned int num_grps;
+ struct pxa3xx_pmx_func *funcs;
+ unsigned int num_funcs;
+ unsigned int num_gpio;
+ struct pinctrl_desc *desc;
+ struct pinctrl_pin_desc *pads;
+ unsigned int num_pads;
+
+ unsigned ds_mask; /* drive strength mask */
+ unsigned ds_shift; /* drive strength shift */
+ unsigned slp_mask; /* sleep mask */
+ unsigned slp_input_low;
+ unsigned slp_input_high;
+ unsigned slp_output_low;
+ unsigned slp_output_high;
+ unsigned slp_float;
+};
+
+enum pxa3xx_pin_list {
+ GPIO0 = 0,
+ GPIO1,
+ GPIO2,
+ GPIO3,
+ GPIO4,
+ GPIO5,
+ GPIO6,
+ GPIO7,
+ GPIO8,
+ GPIO9,
+ GPIO10, /* 10 */
+ GPIO11,
+ GPIO12,
+ GPIO13,
+ GPIO14,
+ GPIO15,
+ GPIO16,
+ GPIO17,
+ GPIO18,
+ GPIO19,
+ GPIO20, /* 20 */
+ GPIO21,
+ GPIO22,
+ GPIO23,
+ GPIO24,
+ GPIO25,
+ GPIO26,
+ GPIO27,
+ GPIO28,
+ GPIO29,
+ GPIO30, /* 30 */
+ GPIO31,
+ GPIO32,
+ GPIO33,
+ GPIO34,
+ GPIO35,
+ GPIO36,
+ GPIO37,
+ GPIO38,
+ GPIO39,
+ GPIO40, /* 40 */
+ GPIO41,
+ GPIO42,
+ GPIO43,
+ GPIO44,
+ GPIO45,
+ GPIO46,
+ GPIO47,
+ GPIO48,
+ GPIO49,
+ GPIO50, /* 50 */
+ GPIO51,
+ GPIO52,
+ GPIO53,
+ GPIO54,
+ GPIO55,
+ GPIO56,
+ GPIO57,
+ GPIO58,
+ GPIO59,
+ GPIO60, /* 60 */
+ GPIO61,
+ GPIO62,
+ GPIO63,
+ GPIO64,
+ GPIO65,
+ GPIO66,
+ GPIO67,
+ GPIO68,
+ GPIO69,
+ GPIO70, /* 70 */
+ GPIO71,
+ GPIO72,
+ GPIO73,
+ GPIO74,
+ GPIO75,
+ GPIO76,
+ GPIO77,
+ GPIO78,
+ GPIO79,
+ GPIO80, /* 80 */
+ GPIO81,
+ GPIO82,
+ GPIO83,
+ GPIO84,
+ GPIO85,
+ GPIO86,
+ GPIO87,
+ GPIO88,
+ GPIO89,
+ GPIO90, /* 90 */
+ GPIO91,
+ GPIO92,
+ GPIO93,
+ GPIO94,
+ GPIO95,
+ GPIO96,
+ GPIO97,
+ GPIO98,
+ GPIO99,
+ GPIO100, /* 100 */
+ GPIO101,
+ GPIO102,
+ GPIO103,
+ GPIO104,
+ GPIO105,
+ GPIO106,
+ GPIO107,
+ GPIO108,
+ GPIO109,
+ GPIO110, /* 110 */
+ GPIO111,
+ GPIO112,
+ GPIO113,
+ GPIO114,
+ GPIO115,
+ GPIO116,
+ GPIO117,
+ GPIO118,
+ GPIO119,
+ GPIO120, /* 120 */
+ GPIO121,
+ GPIO122,
+ GPIO123,
+ GPIO124,
+ GPIO125,
+ GPIO126,
+ GPIO127,
+ GPIO128,
+ GPIO129,
+ GPIO130, /* 130 */
+ GPIO131,
+ GPIO132,
+ GPIO133,
+ GPIO134,
+ GPIO135,
+ GPIO136,
+ GPIO137,
+ GPIO138,
+ GPIO139,
+ GPIO140, /* 140 */
+ GPIO141,
+ GPIO142,
+ GPIO143,
+ GPIO144,
+ GPIO145,
+ GPIO146,
+ GPIO147,
+ GPIO148,
+ GPIO149,
+ GPIO150, /* 150 */
+ GPIO151,
+ GPIO152,
+ GPIO153,
+ GPIO154,
+ GPIO155,
+ GPIO156,
+ GPIO157,
+ GPIO158,
+ GPIO159,
+ GPIO160, /* 160 */
+ GPIO161,
+ GPIO162,
+ GPIO163,
+ GPIO164,
+ GPIO165,
+ GPIO166,
+ GPIO167,
+ GPIO168,
+ GPIO169,
+};
+
+extern int pxa3xx_pinctrl_register(struct platform_device *pdev,
+ struct pxa3xx_pinmux_info *info);
+extern int pxa3xx_pinctrl_unregister(struct platform_device *pdev);
+#endif /* __PINCTRL_PXA3XX_H */
diff --git a/drivers/pinctrl/pinctrl-pxa910.c b/drivers/pinctrl/pinctrl-pxa910.c
new file mode 100644
index 0000000..c72ab4b
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-pxa910.c
@@ -0,0 +1,1007 @@
+/*
+ * linux/drivers/pinctrl/pinmux-pxa910.c
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * publishhed by the Free Software Foundation.
+ *
+ * Copyright (C) 2011, Marvell Technology Group Ltd.
+ *
+ * Author: Haojian Zhuang <haojian.zhuang@marvell.com>
+ *
+ */
+
+#include <linux/device.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/platform_device.h>
+#include "pinctrl-pxa3xx.h"
+
+#define PXA910_DS_MASK 0x1800
+#define PXA910_DS_SHIFT 11
+#define PXA910_SLEEP_MASK 0x38
+#define PXA910_SLEEP_SELECT (1 << 9)
+#define PXA910_SLEEP_DATA (1 << 8)
+#define PXA910_SLEEP_DIR (1 << 7)
+
+#define MFPR_910(a, r, f0, f1, f2, f3, f4, f5, f6, f7) \
+ { \
+ .name = #a, \
+ .pin = a, \
+ .mfpr = r, \
+ .func = { \
+ PXA910_MUX_##f0, \
+ PXA910_MUX_##f1, \
+ PXA910_MUX_##f2, \
+ PXA910_MUX_##f3, \
+ PXA910_MUX_##f4, \
+ PXA910_MUX_##f5, \
+ PXA910_MUX_##f6, \
+ PXA910_MUX_##f7, \
+ }, \
+ }
+
+#define GRP_910(a, m, p) \
+ { .name = a, .mux = PXA910_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), }
+
+/* 170 pins */
+enum pxa910_pin_list {
+ /* 0~127: GPIO0~GPIO127 */
+ ND_IO15 = 128,
+ ND_IO14,
+ ND_IO13, /* 130 */
+ ND_IO12,
+ ND_IO11,
+ ND_IO10,
+ ND_IO9,
+ ND_IO8,
+ ND_IO7,
+ ND_IO6,
+ ND_IO5,
+ ND_IO4,
+ ND_IO3, /* 140 */
+ ND_IO2,
+ ND_IO1,
+ ND_IO0,
+ ND_NCS0,
+ ND_NCS1,
+ SM_NCS0,
+ SM_NCS1,
+ ND_NWE,
+ ND_NRE,
+ ND_CLE, /* 150 */
+ ND_ALE,
+ SM_SCLK,
+ ND_RDY0,
+ SM_ADV,
+ ND_RDY1,
+ SM_ADVMUX,
+ SM_RDY,
+ MMC1_DAT7,
+ MMC1_DAT6,
+ MMC1_DAT5, /* 160 */
+ MMC1_DAT4,
+ MMC1_DAT3,
+ MMC1_DAT2,
+ MMC1_DAT1,
+ MMC1_DAT0,
+ MMC1_CMD,
+ MMC1_CLK,
+ MMC1_CD,
+ VCXO_OUT,
+};
+
+enum pxa910_mux {
+ /* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */
+ PXA910_MUX_GPIO = 0,
+ PXA910_MUX_NAND,
+ PXA910_MUX_USIM2,
+ PXA910_MUX_EXT_DMA,
+ PXA910_MUX_EXT_INT,
+ PXA910_MUX_MMC1,
+ PXA910_MUX_MMC2,
+ PXA910_MUX_MMC3,
+ PXA910_MUX_SM_INT,
+ PXA910_MUX_PRI_JTAG,
+ PXA910_MUX_SEC1_JTAG,
+ PXA910_MUX_SEC2_JTAG,
+ PXA910_MUX_RESET, /* SLAVE RESET OUT */
+ PXA910_MUX_CLK_REQ,
+ PXA910_MUX_VCXO_REQ,
+ PXA910_MUX_VCXO_OUT,
+ PXA910_MUX_VCXO_REQ2,
+ PXA910_MUX_VCXO_OUT2,
+ PXA910_MUX_SPI,
+ PXA910_MUX_SPI2,
+ PXA910_MUX_GSSP,
+ PXA910_MUX_SSP0,
+ PXA910_MUX_SSP1,
+ PXA910_MUX_SSP2,
+ PXA910_MUX_DSSP2,
+ PXA910_MUX_DSSP3,
+ PXA910_MUX_UART0,
+ PXA910_MUX_UART1,
+ PXA910_MUX_UART2,
+ PXA910_MUX_TWSI,
+ PXA910_MUX_CCIC,
+ PXA910_MUX_PWM0,
+ PXA910_MUX_PWM1,
+ PXA910_MUX_PWM2,
+ PXA910_MUX_PWM3,
+ PXA910_MUX_HSL,
+ PXA910_MUX_ONE_WIRE,
+ PXA910_MUX_LCD,
+ PXA910_MUX_DAC_ST23,
+ PXA910_MUX_ULPI,
+ PXA910_MUX_TB,
+ PXA910_MUX_KP_MK,
+ PXA910_MUX_KP_DK,
+ PXA910_MUX_TCU_GPOA,
+ PXA910_MUX_TCU_GPOB,
+ PXA910_MUX_ROT,
+ PXA910_MUX_TDS,
+ PXA910_MUX_32K_CLK, /* 32KHz CLK OUT */
+ PXA910_MUX_MN_CLK, /* MN CLK OUT */
+ PXA910_MUX_SMC,
+ PXA910_MUX_SM_ADDR18,
+ PXA910_MUX_SM_ADDR19,
+ PXA910_MUX_SM_ADDR20,
+ PXA910_MUX_NONE = 0xffff,
+};
+
+
+static struct pinctrl_pin_desc pxa910_pads[] = {
+ PINCTRL_PIN(GPIO0, "GPIO0"),
+ PINCTRL_PIN(GPIO1, "GPIO1"),
+ PINCTRL_PIN(GPIO2, "GPIO2"),
+ PINCTRL_PIN(GPIO3, "GPIO3"),
+ PINCTRL_PIN(GPIO4, "GPIO4"),
+ PINCTRL_PIN(GPIO5, "GPIO5"),
+ PINCTRL_PIN(GPIO6, "GPIO6"),
+ PINCTRL_PIN(GPIO7, "GPIO7"),
+ PINCTRL_PIN(GPIO8, "GPIO8"),
+ PINCTRL_PIN(GPIO9, "GPIO9"),
+ PINCTRL_PIN(GPIO10, "GPIO10"),
+ PINCTRL_PIN(GPIO11, "GPIO11"),
+ PINCTRL_PIN(GPIO12, "GPIO12"),
+ PINCTRL_PIN(GPIO13, "GPIO13"),
+ PINCTRL_PIN(GPIO14, "GPIO14"),
+ PINCTRL_PIN(GPIO15, "GPIO15"),
+ PINCTRL_PIN(GPIO16, "GPIO16"),
+ PINCTRL_PIN(GPIO17, "GPIO17"),
+ PINCTRL_PIN(GPIO18, "GPIO18"),
+ PINCTRL_PIN(GPIO19, "GPIO19"),
+ PINCTRL_PIN(GPIO20, "GPIO20"),
+ PINCTRL_PIN(GPIO21, "GPIO21"),
+ PINCTRL_PIN(GPIO22, "GPIO22"),
+ PINCTRL_PIN(GPIO23, "GPIO23"),
+ PINCTRL_PIN(GPIO24, "GPIO24"),
+ PINCTRL_PIN(GPIO25, "GPIO25"),
+ PINCTRL_PIN(GPIO26, "GPIO26"),
+ PINCTRL_PIN(GPIO27, "GPIO27"),
+ PINCTRL_PIN(GPIO28, "GPIO28"),
+ PINCTRL_PIN(GPIO29, "GPIO29"),
+ PINCTRL_PIN(GPIO30, "GPIO30"),
+ PINCTRL_PIN(GPIO31, "GPIO31"),
+ PINCTRL_PIN(GPIO32, "GPIO32"),
+ PINCTRL_PIN(GPIO33, "GPIO33"),
+ PINCTRL_PIN(GPIO34, "GPIO34"),
+ PINCTRL_PIN(GPIO35, "GPIO35"),
+ PINCTRL_PIN(GPIO36, "GPIO36"),
+ PINCTRL_PIN(GPIO37, "GPIO37"),
+ PINCTRL_PIN(GPIO38, "GPIO38"),
+ PINCTRL_PIN(GPIO39, "GPIO39"),
+ PINCTRL_PIN(GPIO40, "GPIO40"),
+ PINCTRL_PIN(GPIO41, "GPIO41"),
+ PINCTRL_PIN(GPIO42, "GPIO42"),
+ PINCTRL_PIN(GPIO43, "GPIO43"),
+ PINCTRL_PIN(GPIO44, "GPIO44"),
+ PINCTRL_PIN(GPIO45, "GPIO45"),
+ PINCTRL_PIN(GPIO46, "GPIO46"),
+ PINCTRL_PIN(GPIO47, "GPIO47"),
+ PINCTRL_PIN(GPIO48, "GPIO48"),
+ PINCTRL_PIN(GPIO49, "GPIO49"),
+ PINCTRL_PIN(GPIO50, "GPIO50"),
+ PINCTRL_PIN(GPIO51, "GPIO51"),
+ PINCTRL_PIN(GPIO52, "GPIO52"),
+ PINCTRL_PIN(GPIO53, "GPIO53"),
+ PINCTRL_PIN(GPIO54, "GPIO54"),
+ PINCTRL_PIN(GPIO55, "GPIO55"),
+ PINCTRL_PIN(GPIO56, "GPIO56"),
+ PINCTRL_PIN(GPIO57, "GPIO57"),
+ PINCTRL_PIN(GPIO58, "GPIO58"),
+ PINCTRL_PIN(GPIO59, "GPIO59"),
+ PINCTRL_PIN(GPIO60, "GPIO60"),
+ PINCTRL_PIN(GPIO61, "GPIO61"),
+ PINCTRL_PIN(GPIO62, "GPIO62"),
+ PINCTRL_PIN(GPIO63, "GPIO63"),
+ PINCTRL_PIN(GPIO64, "GPIO64"),
+ PINCTRL_PIN(GPIO65, "GPIO65"),
+ PINCTRL_PIN(GPIO66, "GPIO66"),
+ PINCTRL_PIN(GPIO67, "GPIO67"),
+ PINCTRL_PIN(GPIO68, "GPIO68"),
+ PINCTRL_PIN(GPIO69, "GPIO69"),
+ PINCTRL_PIN(GPIO70, "GPIO70"),
+ PINCTRL_PIN(GPIO71, "GPIO71"),
+ PINCTRL_PIN(GPIO72, "GPIO72"),
+ PINCTRL_PIN(GPIO73, "GPIO73"),
+ PINCTRL_PIN(GPIO74, "GPIO74"),
+ PINCTRL_PIN(GPIO75, "GPIO75"),
+ PINCTRL_PIN(GPIO76, "GPIO76"),
+ PINCTRL_PIN(GPIO77, "GPIO77"),
+ PINCTRL_PIN(GPIO78, "GPIO78"),
+ PINCTRL_PIN(GPIO79, "GPIO79"),
+ PINCTRL_PIN(GPIO80, "GPIO80"),
+ PINCTRL_PIN(GPIO81, "GPIO81"),
+ PINCTRL_PIN(GPIO82, "GPIO82"),
+ PINCTRL_PIN(GPIO83, "GPIO83"),
+ PINCTRL_PIN(GPIO84, "GPIO84"),
+ PINCTRL_PIN(GPIO85, "GPIO85"),
+ PINCTRL_PIN(GPIO86, "GPIO86"),
+ PINCTRL_PIN(GPIO87, "GPIO87"),
+ PINCTRL_PIN(GPIO88, "GPIO88"),
+ PINCTRL_PIN(GPIO89, "GPIO89"),
+ PINCTRL_PIN(GPIO90, "GPIO90"),
+ PINCTRL_PIN(GPIO91, "GPIO91"),
+ PINCTRL_PIN(GPIO92, "GPIO92"),
+ PINCTRL_PIN(GPIO93, "GPIO93"),
+ PINCTRL_PIN(GPIO94, "GPIO94"),
+ PINCTRL_PIN(GPIO95, "GPIO95"),
+ PINCTRL_PIN(GPIO96, "GPIO96"),
+ PINCTRL_PIN(GPIO97, "GPIO97"),
+ PINCTRL_PIN(GPIO98, "GPIO98"),
+ PINCTRL_PIN(GPIO99, "GPIO99"),
+ PINCTRL_PIN(GPIO100, "GPIO100"),
+ PINCTRL_PIN(GPIO101, "GPIO101"),
+ PINCTRL_PIN(GPIO102, "GPIO102"),
+ PINCTRL_PIN(GPIO103, "GPIO103"),
+ PINCTRL_PIN(GPIO104, "GPIO104"),
+ PINCTRL_PIN(GPIO105, "GPIO105"),
+ PINCTRL_PIN(GPIO106, "GPIO106"),
+ PINCTRL_PIN(GPIO107, "GPIO107"),
+ PINCTRL_PIN(GPIO108, "GPIO108"),
+ PINCTRL_PIN(GPIO109, "GPIO109"),
+ PINCTRL_PIN(GPIO110, "GPIO110"),
+ PINCTRL_PIN(GPIO111, "GPIO111"),
+ PINCTRL_PIN(GPIO112, "GPIO112"),
+ PINCTRL_PIN(GPIO113, "GPIO113"),
+ PINCTRL_PIN(GPIO114, "GPIO114"),
+ PINCTRL_PIN(GPIO115, "GPIO115"),
+ PINCTRL_PIN(GPIO116, "GPIO116"),
+ PINCTRL_PIN(GPIO117, "GPIO117"),
+ PINCTRL_PIN(GPIO118, "GPIO118"),
+ PINCTRL_PIN(GPIO119, "GPIO119"),
+ PINCTRL_PIN(GPIO120, "GPIO120"),
+ PINCTRL_PIN(GPIO121, "GPIO121"),
+ PINCTRL_PIN(GPIO122, "GPIO122"),
+ PINCTRL_PIN(GPIO123, "GPIO123"),
+ PINCTRL_PIN(GPIO124, "GPIO124"),
+ PINCTRL_PIN(GPIO125, "GPIO125"),
+ PINCTRL_PIN(GPIO126, "GPIO126"),
+ PINCTRL_PIN(GPIO127, "GPIO127"),
+ PINCTRL_PIN(ND_IO15, "ND_IO15"),
+ PINCTRL_PIN(ND_IO14, "ND_IO14"),
+ PINCTRL_PIN(ND_IO13, "ND_IO13"),
+ PINCTRL_PIN(ND_IO12, "ND_IO12"),
+ PINCTRL_PIN(ND_IO11, "ND_IO11"),
+ PINCTRL_PIN(ND_IO10, "ND_IO10"),
+ PINCTRL_PIN(ND_IO9, "ND_IO9"),
+ PINCTRL_PIN(ND_IO8, "ND_IO8"),
+ PINCTRL_PIN(ND_IO7, "ND_IO7"),
+ PINCTRL_PIN(ND_IO6, "ND_IO6"),
+ PINCTRL_PIN(ND_IO5, "ND_IO5"),
+ PINCTRL_PIN(ND_IO4, "ND_IO4"),
+ PINCTRL_PIN(ND_IO3, "ND_IO3"),
+ PINCTRL_PIN(ND_IO2, "ND_IO2"),
+ PINCTRL_PIN(ND_IO1, "ND_IO1"),
+ PINCTRL_PIN(ND_IO0, "ND_IO0"),
+ PINCTRL_PIN(ND_NCS0, "ND_NCS0_SM_NCS2"),
+ PINCTRL_PIN(ND_NCS1, "ND_NCS1_SM_NCS3"),
+ PINCTRL_PIN(SM_NCS0, "SM_NCS0"),
+ PINCTRL_PIN(SM_NCS1, "SM_NCS1"),
+ PINCTRL_PIN(ND_NWE, "ND_NWE"),
+ PINCTRL_PIN(ND_NRE, "ND_NRE"),
+ PINCTRL_PIN(ND_CLE, "ND_CLE_SM_NOE"),
+ PINCTRL_PIN(ND_ALE, "ND_ALE_SM_NWE"),
+ PINCTRL_PIN(SM_SCLK, "SM_SCLK"),
+ PINCTRL_PIN(ND_RDY0, "ND_RDY0"),
+ PINCTRL_PIN(SM_ADV, "SM_ADV"),
+ PINCTRL_PIN(ND_RDY1, "ND_RDY1"),
+ PINCTRL_PIN(SM_RDY, "SM_RDY"),
+ PINCTRL_PIN(MMC1_DAT7, "MMC1_DAT7"),
+ PINCTRL_PIN(MMC1_DAT6, "MMC1_DAT6"),
+ PINCTRL_PIN(MMC1_DAT5, "MMC1_DAT5"),
+ PINCTRL_PIN(MMC1_DAT4, "MMC1_DAT4"),
+ PINCTRL_PIN(MMC1_DAT3, "MMC1_DAT3"),
+ PINCTRL_PIN(MMC1_DAT2, "MMC1_DAT2"),
+ PINCTRL_PIN(MMC1_DAT1, "MMC1_DAT1"),
+ PINCTRL_PIN(MMC1_DAT0, "MMC1_DAT0"),
+ PINCTRL_PIN(MMC1_CMD, "MMC1 CMD"),
+ PINCTRL_PIN(MMC1_CLK, "MMC1 CLK"),
+ PINCTRL_PIN(MMC1_CD, "MMC1 CD"),
+ PINCTRL_PIN(VCXO_OUT, "VCXO_OUT"),
+};
+
+struct pxa3xx_mfp_pin pxa910_mfp[] = {
+ /* pin offs f0 f1 f2 f3 f4 f5 f6 f7 */
+ MFPR_910(GPIO0, 0x0DC, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO1, 0x0E0, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO2, 0x0E4, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO3, 0x0E8, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO4, 0x0EC, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO5, 0x0F0, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO6, 0x0F4, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO7, 0x0F8, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO8, 0x0FC, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO9, 0x100, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO10, 0x104, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO11, 0x108, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO12, 0x10C, GPIO, KP_MK, NONE, NONE, KP_DK, NONE, NONE, NONE),
+ MFPR_910(GPIO13, 0x110, GPIO, KP_MK, NONE, NONE, KP_DK, NONE, NONE, NONE),
+ MFPR_910(GPIO14, 0x114, GPIO, KP_MK, NONE, NONE, KP_DK, TB, NONE, NONE),
+ MFPR_910(GPIO15, 0x118, GPIO, KP_MK, NONE, NONE, KP_DK, TB, NONE, NONE),
+ MFPR_910(GPIO16, 0x11C, GPIO, KP_DK, NONE, NONE, NONE, TB, NONE, NONE),
+ MFPR_910(GPIO17, 0x120, GPIO, KP_DK, NONE, NONE, NONE, TB, NONE, NONE),
+ MFPR_910(GPIO18, 0x124, GPIO, KP_DK, NONE, NONE, ROT, NONE, NONE, NONE),
+ MFPR_910(GPIO19, 0x128, GPIO, KP_DK, NONE, NONE, ROT, NONE, NONE, NONE),
+ MFPR_910(GPIO20, 0x12C, GPIO, SSP1, NONE, NONE, VCXO_OUT, NONE, NONE, NONE),
+ MFPR_910(GPIO21, 0x130, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO22, 0x134, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO23, 0x138, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO24, 0x13C, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO25, 0x140, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO26, 0x144, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO27, 0x148, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO28, 0x14C, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO29, 0x150, GPIO, UART0, NONE, NONE, UART1, NONE, NONE, NONE),
+ MFPR_910(GPIO30, 0x154, GPIO, UART0, NONE, NONE, UART1, NONE, NONE, NONE),
+ MFPR_910(GPIO31, 0x158, GPIO, UART0, NONE, NONE, UART1, NONE, NONE, NONE),
+ MFPR_910(GPIO32, 0x15C, GPIO, UART0, DAC_ST23, NONE, UART1, NONE, NONE, NONE),
+ MFPR_910(GPIO33, 0x160, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3),
+ MFPR_910(GPIO34, 0x164, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3),
+ MFPR_910(GPIO35, 0x168, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3),
+ MFPR_910(GPIO36, 0x16C, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3),
+ MFPR_910(GPIO37, 0x170, GPIO, MMC2, NONE, NONE, NONE, SPI, HSL, NONE),
+ MFPR_910(GPIO38, 0x174, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE),
+ MFPR_910(GPIO39, 0x178, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE),
+ MFPR_910(GPIO40, 0x17C, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE),
+ MFPR_910(GPIO41, 0x180, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE),
+ MFPR_910(GPIO42, 0x184, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE),
+ MFPR_910(GPIO43, 0x188, GPIO, UART1, NONE, DAC_ST23, NONE, DSSP2, SPI, UART2),
+ MFPR_910(GPIO44, 0x18C, GPIO, UART1, NONE, EXT_INT, NONE, DSSP2, SPI, UART2),
+ MFPR_910(GPIO45, 0x190, GPIO, UART1, NONE, EXT_INT, NONE, DSSP2, SPI, UART2),
+ MFPR_910(GPIO46, 0x194, GPIO, UART1, NONE, EXT_INT, NONE, DSSP2, SPI, UART2),
+ MFPR_910(GPIO47, 0x198, GPIO, SSP0, NONE, NONE, NONE, SSP2, UART1, NONE),
+ MFPR_910(GPIO48, 0x19C, GPIO, SSP0, NONE, NONE, NONE, SSP2, UART1, NONE),
+ MFPR_910(GPIO49, 0x1A0, GPIO, SSP0, UART0, VCXO_REQ, NONE, SSP2, NONE, MMC3),
+ MFPR_910(GPIO50, 0x1A4, GPIO, SSP0, UART0, VCXO_OUT, NONE, SSP2, NONE, MMC3),
+ MFPR_910(GPIO51, 0x1A8, GPIO, UART2, PWM1, TWSI, SSP0, NONE, DSSP3, NONE),
+ MFPR_910(GPIO52, 0x1AC, GPIO, UART2, DAC_ST23, TWSI, SSP0, NONE, DSSP3, NONE),
+ MFPR_910(GPIO53, 0x1B0, GPIO, UART2, TWSI, NONE, SSP0, NONE, DSSP3, NONE),
+ MFPR_910(GPIO54, 0x1B4, GPIO, UART2, TWSI, SSP0, NONE, NONE, DSSP3, NONE),
+ MFPR_910(GPIO55, 0x2F0, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO56, 0x2F4, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO57, 0x2F8, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO58, 0x2FC, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO59, 0x300, TDS, GPIO, TCU_GPOA, TCU_GPOB, ONE_WIRE, NONE, NONE, NONE),
+ MFPR_910(GPIO60, 0x304, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO61, 0x308, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL),
+ MFPR_910(GPIO62, 0x30C, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL),
+ MFPR_910(GPIO63, 0x310, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL),
+ MFPR_910(GPIO64, 0x314, GPIO, SPI2, NONE, NONE, NONE, NONE, NONE, HSL),
+ MFPR_910(GPIO65, 0x318, GPIO, SPI2, NONE, NONE, NONE, NONE, ONE_WIRE, HSL),
+ MFPR_910(GPIO66, 0x31C, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL),
+ MFPR_910(GPIO67, 0x1B8, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, USIM2),
+ MFPR_910(GPIO68, 0x1BC, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, USIM2),
+ MFPR_910(GPIO69, 0x1C0, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, USIM2),
+ MFPR_910(GPIO70, 0x1C4, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, NONE),
+ MFPR_910(GPIO71, 0x1C8, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, NONE),
+ MFPR_910(GPIO72, 0x1CC, GPIO, CCIC, EXT_DMA, NONE, NONE, ULPI, NONE, NONE),
+ MFPR_910(GPIO73, 0x1D0, GPIO, CCIC, EXT_DMA, NONE, NONE, ULPI, NONE, NONE),
+ MFPR_910(GPIO74, 0x1D4, GPIO, CCIC, EXT_DMA, NONE, NONE, ULPI, NONE, NONE),
+ MFPR_910(GPIO75, 0x1D8, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE),
+ MFPR_910(GPIO76, 0x1DC, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE),
+ MFPR_910(GPIO77, 0x1E0, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE),
+ MFPR_910(GPIO78, 0x1E4, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE),
+ MFPR_910(GPIO79, 0x1E8, GPIO, TWSI, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO80, 0x1EC, GPIO, TWSI, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO81, 0x1F0, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO82, 0x1F4, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO83, 0x1F8, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO84, 0x1FC, GPIO, LCD, VCXO_REQ2, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO85, 0x200, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO86, 0x204, GPIO, LCD, VCXO_OUT2, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO87, 0x208, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO88, 0x20C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO89, 0x210, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO90, 0x214, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO91, 0x218, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO92, 0x21C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO93, 0x220, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO94, 0x224, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO95, 0x228, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO96, 0x22C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO97, 0x230, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO98, 0x234, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO99, 0x0B0, MMC1, GPIO, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO100, 0x238, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO101, 0x23C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO102, 0x240, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, SPI2),
+ MFPR_910(GPIO103, 0x244, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, SPI2),
+ MFPR_910(GPIO104, 0x248, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO105, 0x24C, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO106, 0x250, GPIO, LCD, DSSP3, ONE_WIRE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO107, 0x254, GPIO, LCD, DSSP3, SPI, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO108, 0x258, GPIO, LCD, DSSP3, SPI, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO109, 0x25C, GPIO, LCD, DSSP3, SPI, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO110, 0x298, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO111, 0x29C, GPIO, NONE, DSSP2, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO112, 0x2A0, GPIO, NONE, DSSP2, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO113, 0x2A4, GPIO, NONE, DSSP2, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO114, 0x2A8, GPIO, NONE, DSSP3, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO115, 0x2AC, GPIO, NONE, DSSP3, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO116, 0x2B0, GPIO, NONE, DSSP3, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO117, 0x0B4, PRI_JTAG, GPIO, PWM0, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO118, 0x0B8, PRI_JTAG, GPIO, PWM1, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO119, 0x0BC, PRI_JTAG, GPIO, PWM2, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO120, 0x0C0, PRI_JTAG, GPIO, PWM3, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO121, 0x32C, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO122, 0x0C8, RESET, GPIO, 32K_CLK, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO123, 0x0CC, CLK_REQ, GPIO, ONE_WIRE, EXT_DMA, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO124, 0x0D0, GPIO, MN_CLK, DAC_ST23, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO125, 0x0D4, VCXO_REQ, GPIO, NONE, EXT_INT, NONE, NONE, NONE, NONE),
+ MFPR_910(GPIO126, 0x06C, GPIO, SMC, NONE, SM_ADDR18, NONE, EXT_DMA, NONE, NONE),
+ MFPR_910(GPIO127, 0x070, GPIO, SMC, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_IO15, 0x004, NAND, GPIO, USIM2, EXT_DMA, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_IO14, 0x008, NAND, GPIO, USIM2, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_IO13, 0x00C, NAND, GPIO, USIM2, EXT_INT, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_IO12, 0x010, NAND, GPIO, SSP2, EXT_INT, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_IO11, 0x014, NAND, GPIO, SSP2, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_IO10, 0x018, NAND, GPIO, SSP2, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_IO9, 0x01C, NAND, GPIO, SSP2, NONE, VCXO_OUT2, NONE, NONE, NONE),
+ MFPR_910(ND_IO8, 0x020, NAND, GPIO, NONE, NONE, PWM3, NONE, NONE, NONE),
+ MFPR_910(ND_IO7, 0x024, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_IO6, 0x028, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_IO5, 0x02C, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_IO4, 0x030, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_IO3, 0x034, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_IO2, 0x038, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_IO1, 0x03C, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_IO0, 0x040, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_NCS0, 0x044, NAND, GPIO, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_NCS1, 0x048, NAND, GPIO, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(SM_NCS0, 0x04C, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(SM_NCS1, 0x050, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_NWE, 0x054, GPIO, NAND, NONE, SM_ADDR20, NONE, SMC, NONE, NONE),
+ MFPR_910(ND_NRE, 0x058, GPIO, NAND, NONE, SMC, NONE, EXT_DMA, NONE, NONE),
+ MFPR_910(ND_CLE, 0x05C, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_ALE, 0x060, GPIO, NAND, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(SM_SCLK, 0x064, MMC3, NONE, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_RDY0, 0x068, NAND, GPIO, NONE, SMC, NONE, NONE, NONE, NONE),
+ MFPR_910(SM_ADV, 0x074, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(ND_RDY1, 0x078, NAND, GPIO, NONE, SMC, NONE, NONE, NONE, NONE),
+ MFPR_910(SM_ADVMUX, 0x07C, SMC, GPIO, NONE, SM_ADDR19, NONE, NONE, NONE, NONE),
+ MFPR_910(SM_RDY, 0x080, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(MMC1_DAT7, 0x084, MMC1, GPIO, SEC1_JTAG, TB, NONE, NONE, NONE, NONE),
+ MFPR_910(MMC1_DAT6, 0x088, MMC1, GPIO, SEC1_JTAG, TB, NONE, NONE, NONE, NONE),
+ MFPR_910(MMC1_DAT5, 0x08C, MMC1, GPIO, SEC1_JTAG, TB, NONE, NONE, NONE, NONE),
+ MFPR_910(MMC1_DAT4, 0x090, MMC1, GPIO, NONE, TB, NONE, NONE, NONE, NONE),
+ MFPR_910(MMC1_DAT3, 0x094, MMC1, HSL, SEC2_JTAG, SSP0, NONE, NONE, NONE, NONE),
+ MFPR_910(MMC1_DAT2, 0x098, MMC1, HSL, SEC2_JTAG, SSP2, SSP0, NONE, NONE, NONE),
+ MFPR_910(MMC1_DAT1, 0x09C, MMC1, HSL, SEC2_JTAG, SSP2, SSP0, NONE, NONE, NONE),
+ MFPR_910(MMC1_DAT0, 0x0A0, MMC1, HSL, SEC2_JTAG, SSP2, NONE, NONE, NONE, NONE),
+ MFPR_910(MMC1_CMD, 0x0A4, MMC1, HSL, SEC1_JTAG, SSP2, NONE, NONE, NONE, NONE),
+ MFPR_910(MMC1_CLK, 0x0A8, MMC1, HSL, SEC2_JTAG, SSP0, NONE, NONE, NONE, NONE),
+ MFPR_910(MMC1_CD, 0x0AC, MMC1, GPIO, SEC1_JTAG, NONE, NONE, NONE, NONE, NONE),
+ MFPR_910(VCXO_OUT, 0x0D8, VCXO_OUT, PWM3, NONE, NONE, NONE, NONE, NONE, NONE),
+};
+
+
+static const unsigned p910_usim2_pin1[] = {GPIO67, GPIO68, GPIO69};
+static const unsigned p910_usim2_pin2[] = {ND_IO15, ND_IO14, ND_IO13};
+static const unsigned p910_mmc1_pin1[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5,
+ MMC1_DAT4, MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, MMC1_DAT0, MMC1_CMD,
+ MMC1_CLK, MMC1_CD, GPIO99};
+static const unsigned p910_mmc2_pin1[] = {GPIO33, GPIO34, GPIO35, GPIO36,
+ GPIO37, GPIO38, GPIO39, GPIO40, GPIO41, GPIO42};
+static const unsigned p910_mmc3_pin1[] = {GPIO33, GPIO34, GPIO35, GPIO36,
+ GPIO49, GPIO50};
+static const unsigned p910_mmc3_pin2[] = {ND_IO7, ND_IO6, ND_IO5, ND_IO4,
+ ND_IO3, ND_IO2, ND_IO1, ND_IO0, ND_CLE, SM_SCLK};
+static const unsigned p910_uart0_pin1[] = {GPIO29, GPIO30, GPIO31, GPIO32};
+static const unsigned p910_uart1_pin1[] = {GPIO47, GPIO48};
+static const unsigned p910_uart1_pin2[] = {GPIO31, GPIO32};
+static const unsigned p910_uart1_pin3[] = {GPIO45, GPIO46};
+static const unsigned p910_uart1_pin4[] = {GPIO29, GPIO30, GPIO31, GPIO32};
+static const unsigned p910_uart1_pin5[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned p910_uart2_pin1[] = {GPIO43, GPIO44};
+static const unsigned p910_uart2_pin2[] = {GPIO51, GPIO52};
+static const unsigned p910_uart2_pin3[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned p910_uart2_pin4[] = {GPIO51, GPIO52, GPIO53, GPIO54};
+static const unsigned p910_twsi_pin1[] = {GPIO51, GPIO52};
+static const unsigned p910_twsi_pin2[] = {GPIO53, GPIO54};
+static const unsigned p910_twsi_pin3[] = {GPIO79, GPIO80};
+static const unsigned p910_ccic_pin1[] = {GPIO67, GPIO68, GPIO69, GPIO70,
+ GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78};
+static const unsigned p910_lcd_pin1[] = {GPIO81, GPIO82, GPIO83, GPIO84,
+ GPIO85, GPIO86, GPIO87, GPIO88, GPIO89, GPIO90, GPIO91, GPIO92,
+ GPIO93, GPIO94, GPIO95, GPIO96, GPIO97, GPIO98, GPIO100, GPIO101,
+ GPIO102, GPIO103};
+static const unsigned p910_spi_pin1[] = {GPIO104, GPIO105, GPIO107, GPIO108};
+static const unsigned p910_spi_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned p910_spi_pin3[] = {GPIO33, GPIO34, GPIO35, GPIO36,
+ GPIO37};
+static const unsigned p910_spi_pin4[] = {GPIO67, GPIO68, GPIO69, GPIO70,
+ GPIO71};
+static const unsigned p910_spi2_pin1[] = {GPIO64, GPIO65};
+static const unsigned p910_spi2_pin2[] = {GPIO102, GPIO103};
+static const unsigned p910_dssp2_pin1[] = {GPIO102, GPIO103, GPIO104, GPIO105};
+static const unsigned p910_dssp2_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46};
+static const unsigned p910_dssp2_pin3[] = {GPIO111, GPIO112, GPIO113};
+static const unsigned p910_dssp3_pin1[] = {GPIO106, GPIO107, GPIO108, GPIO109};
+static const unsigned p910_dssp3_pin2[] = {GPIO51, GPIO52, GPIO53, GPIO54};
+static const unsigned p910_dssp3_pin3[] = {GPIO114, GPIO115, GPIO116};
+static const unsigned p910_ssp0_pin1[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1,
+ MMC1_CLK};
+static const unsigned p910_ssp0_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36};
+static const unsigned p910_ssp0_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50};
+static const unsigned p910_ssp0_pin4[] = {GPIO51, GPIO52, GPIO53, GPIO54};
+static const unsigned p910_ssp1_pin1[] = {GPIO21, GPIO22, GPIO23, GPIO24};
+static const unsigned p910_ssp1_pin2[] = {GPIO20, GPIO21, GPIO22, GPIO23,
+ GPIO24};
+static const unsigned p910_ssp2_pin1[] = {MMC1_DAT2, MMC1_DAT1, MMC1_DAT0,
+ MMC1_CMD};
+static const unsigned p910_ssp2_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36};
+static const unsigned p910_ssp2_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50};
+static const unsigned p910_ssp2_pin4[] = {ND_IO12, ND_IO11, ND_IO10, ND_IO9};
+static const unsigned p910_gssp_pin1[] = {GPIO25, GPIO26, GPIO27, GPIO28};
+static const unsigned p910_pwm0_pin1[] = {GPIO117};
+static const unsigned p910_pwm1_pin1[] = {GPIO118};
+static const unsigned p910_pwm1_pin2[] = {GPIO51};
+static const unsigned p910_pwm2_pin1[] = {GPIO119};
+static const unsigned p910_pwm3_pin1[] = {GPIO120};
+static const unsigned p910_pwm3_pin2[] = {ND_IO8};
+static const unsigned p910_pwm3_pin3[] = {VCXO_OUT};
+static const unsigned p910_pri_jtag_pin1[] = {GPIO117, GPIO118, GPIO119,
+ GPIO120};
+static const unsigned p910_sec1_jtag_pin1[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5,
+ MMC1_CMD, MMC1_CD};
+static const unsigned p910_sec2_jtag_pin1[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1,
+ MMC1_DAT0, MMC1_CLK};
+static const unsigned p910_hsl_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40,
+ GPIO41, GPIO42};
+static const unsigned p910_hsl_pin2[] = {GPIO61, GPIO62, GPIO63, GPIO64,
+ GPIO65, GPIO66};
+static const unsigned p910_hsl_pin3[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1,
+ MMC1_DAT0, MMC1_CMD, MMC1_CLK};
+static const unsigned p910_w1_pin1[] = {GPIO59};
+static const unsigned p910_w1_pin2[] = {GPIO65};
+static const unsigned p910_w1_pin3[] = {GPIO106};
+static const unsigned p910_w1_pin4[] = {GPIO123};
+static const unsigned p910_kpmk_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3, GPIO4,
+ GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, GPIO13,
+ GPIO14, GPIO15};
+static const unsigned p910_kpmk_pin2[] = {GPIO0, GPIO1, GPIO2, GPIO3, GPIO4,
+ GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO12};
+static const unsigned p910_kpdk_pin1[] = {GPIO12, GPIO13, GPIO14, GPIO15,
+ GPIO16, GPIO17, GPIO18, GPIO19};
+static const unsigned p910_tds_pin1[] = {GPIO55, GPIO56, GPIO57, GPIO58,
+ GPIO59};
+static const unsigned p910_tds_pin2[] = {GPIO55, GPIO57, GPIO58, GPIO59};
+static const unsigned p910_tb_pin1[] = {GPIO14, GPIO15, GPIO16, GPIO17};
+static const unsigned p910_tb_pin2[] = {GPIO55, GPIO56, GPIO57, GPIO58};
+static const unsigned p910_tb_pin3[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5,
+ MMC1_DAT4};
+static const unsigned p910_ext_dma0_pin1[] = {GPIO72};
+static const unsigned p910_ext_dma0_pin2[] = {ND_IO15};
+static const unsigned p910_ext_dma0_pin3[] = {ND_NRE};
+static const unsigned p910_ext_dma1_pin1[] = {GPIO73};
+static const unsigned p910_ext_dma1_pin2[] = {GPIO123};
+static const unsigned p910_ext_dma1_pin3[] = {GPIO126};
+static const unsigned p910_ext_dma2_pin1[] = {GPIO74};
+static const unsigned p910_ext0_int_pin1[] = {GPIO44};
+static const unsigned p910_ext0_int_pin2[] = {ND_IO13};
+static const unsigned p910_ext1_int_pin1[] = {GPIO45};
+static const unsigned p910_ext1_int_pin2[] = {ND_IO12};
+static const unsigned p910_ext2_int_pin1[] = {GPIO46};
+static const unsigned p910_ext2_int_pin2[] = {GPIO125};
+static const unsigned p910_dac_st23_pin1[] = {GPIO32};
+static const unsigned p910_dac_st23_pin2[] = {GPIO43};
+static const unsigned p910_dac_st23_pin3[] = {GPIO52};
+static const unsigned p910_dac_st23_pin4[] = {GPIO124};
+static const unsigned p910_vcxo_out_pin1[] = {GPIO50};
+static const unsigned p910_vcxo_out_pin2[] = {VCXO_OUT};
+static const unsigned p910_vcxo_out_pin3[] = {GPIO20};
+static const unsigned p910_vcxo_req_pin1[] = {GPIO49};
+static const unsigned p910_vcxo_req_pin2[] = {GPIO125};
+static const unsigned p910_vcxo_out2_pin1[] = {GPIO86};
+static const unsigned p910_vcxo_out2_pin2[] = {ND_IO9};
+static const unsigned p910_vcxo_req2_pin1[] = {GPIO84};
+static const unsigned p910_ulpi_pin1[] = {GPIO67, GPIO68, GPIO69, GPIO70,
+ GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78};
+static const unsigned p910_nand_pin1[] = {ND_IO15, ND_IO14, ND_IO13, ND_IO12,
+ ND_IO11, ND_IO10, ND_IO9, ND_IO8, ND_IO7, ND_IO6, ND_IO5, ND_IO4,
+ ND_IO3, ND_IO2, ND_IO1, ND_IO0, ND_NCS0, ND_NWE, ND_NRE, ND_CLE,
+ ND_ALE, ND_RDY0};
+static const unsigned p910_gpio0_pin1[] = {GPIO0};
+static const unsigned p910_gpio0_pin2[] = {SM_ADV};
+static const unsigned p910_gpio1_pin1[] = {GPIO1};
+static const unsigned p910_gpio1_pin2[] = {ND_RDY1};
+static const unsigned p910_gpio2_pin1[] = {GPIO2};
+static const unsigned p910_gpio2_pin2[] = {SM_ADVMUX};
+static const unsigned p910_gpio3_pin1[] = {GPIO3};
+static const unsigned p910_gpio3_pin2[] = {SM_RDY};
+static const unsigned p910_gpio20_pin1[] = {GPIO20};
+static const unsigned p910_gpio20_pin2[] = {ND_IO15};
+static const unsigned p910_gpio20_pin3[] = {MMC1_DAT6};
+static const unsigned p910_gpio21_pin1[] = {GPIO21};
+static const unsigned p910_gpio21_pin2[] = {ND_IO14};
+static const unsigned p910_gpio21_pin3[] = {MMC1_DAT5};
+static const unsigned p910_gpio22_pin1[] = {GPIO22};
+static const unsigned p910_gpio22_pin2[] = {ND_IO13};
+static const unsigned p910_gpio22_pin3[] = {MMC1_DAT4};
+static const unsigned p910_gpio23_pin1[] = {GPIO23};
+static const unsigned p910_gpio23_pin2[] = {ND_IO12};
+static const unsigned p910_gpio23_pin3[] = {MMC1_CD};
+static const unsigned p910_gpio24_pin1[] = {GPIO24};
+static const unsigned p910_gpio24_pin2[] = {ND_IO11};
+static const unsigned p910_gpio24_pin3[] = {MMC1_DAT7};
+static const unsigned p910_gpio25_pin1[] = {GPIO25};
+static const unsigned p910_gpio25_pin2[] = {ND_IO10};
+static const unsigned p910_gpio26_pin1[] = {GPIO26};
+static const unsigned p910_gpio26_pin2[] = {ND_IO9};
+static const unsigned p910_gpio27_pin1[] = {GPIO27};
+static const unsigned p910_gpio27_pin2[] = {ND_IO8};
+static const unsigned p910_gpio85_pin1[] = {GPIO85};
+static const unsigned p910_gpio85_pin2[] = {ND_NCS0};
+static const unsigned p910_gpio86_pin1[] = {GPIO86};
+static const unsigned p910_gpio86_pin2[] = {ND_NCS1};
+static const unsigned p910_gpio87_pin1[] = {GPIO87};
+static const unsigned p910_gpio87_pin2[] = {SM_NCS0};
+static const unsigned p910_gpio88_pin1[] = {GPIO88};
+static const unsigned p910_gpio88_pin2[] = {SM_NCS1};
+static const unsigned p910_gpio89_pin1[] = {GPIO89};
+static const unsigned p910_gpio89_pin2[] = {ND_NWE};
+static const unsigned p910_gpio90_pin1[] = {GPIO90};
+static const unsigned p910_gpio90_pin2[] = {ND_NRE};
+static const unsigned p910_gpio91_pin1[] = {GPIO91};
+static const unsigned p910_gpio91_pin2[] = {ND_ALE};
+static const unsigned p910_gpio92_pin1[] = {GPIO92};
+static const unsigned p910_gpio92_pin2[] = {ND_RDY0};
+
+static struct pxa3xx_pin_group pxa910_grps[] = {
+ GRP_910("usim2 3p1", USIM2, p910_usim2_pin1),
+ GRP_910("usim2 3p2", USIM2, p910_usim2_pin2),
+ GRP_910("mmc1 12p", MMC1, p910_mmc1_pin1),
+ GRP_910("mmc2 10p", MMC2, p910_mmc2_pin1),
+ GRP_910("mmc3 6p", MMC3, p910_mmc3_pin1),
+ GRP_910("mmc3 10p", MMC3, p910_mmc3_pin2),
+ GRP_910("uart0 4p", UART0, p910_uart0_pin1),
+ GRP_910("uart1 2p1", UART1, p910_uart1_pin1),
+ GRP_910("uart1 2p2", UART1, p910_uart1_pin2),
+ GRP_910("uart1 2p3", UART1, p910_uart1_pin3),
+ GRP_910("uart1 4p4", UART1, p910_uart1_pin4),
+ GRP_910("uart1 4p5", UART1, p910_uart1_pin5),
+ GRP_910("uart2 2p1", UART2, p910_uart2_pin1),
+ GRP_910("uart2 2p2", UART2, p910_uart2_pin2),
+ GRP_910("uart2 4p3", UART2, p910_uart2_pin3),
+ GRP_910("uart2 4p4", UART2, p910_uart2_pin4),
+ GRP_910("twsi 2p1", TWSI, p910_twsi_pin1),
+ GRP_910("twsi 2p2", TWSI, p910_twsi_pin2),
+ GRP_910("twsi 2p3", TWSI, p910_twsi_pin3),
+ GRP_910("ccic", CCIC, p910_ccic_pin1),
+ GRP_910("lcd", LCD, p910_lcd_pin1),
+ GRP_910("spi 4p1", SPI, p910_spi_pin1),
+ GRP_910("spi 4p2", SPI, p910_spi_pin2),
+ GRP_910("spi 5p3", SPI, p910_spi_pin3),
+ GRP_910("spi 5p4", SPI, p910_spi_pin4),
+ GRP_910("dssp2 4p1", DSSP2, p910_dssp2_pin1),
+ GRP_910("dssp2 4p2", DSSP2, p910_dssp2_pin2),
+ GRP_910("dssp2 3p3", DSSP2, p910_dssp2_pin3),
+ GRP_910("dssp3 4p1", DSSP3, p910_dssp3_pin1),
+ GRP_910("dssp3 4p2", DSSP3, p910_dssp3_pin2),
+ GRP_910("dssp3 3p3", DSSP3, p910_dssp3_pin3),
+ GRP_910("ssp0 4p1", SSP0, p910_ssp0_pin1),
+ GRP_910("ssp0 4p2", SSP0, p910_ssp0_pin2),
+ GRP_910("ssp0 4p3", SSP0, p910_ssp0_pin3),
+ GRP_910("ssp0 4p4", SSP0, p910_ssp0_pin4),
+ GRP_910("ssp1 4p1", SSP1, p910_ssp1_pin1),
+ GRP_910("ssp1 5p2", SSP1, p910_ssp1_pin2),
+ GRP_910("ssp2 4p1", SSP2, p910_ssp2_pin1),
+ GRP_910("ssp2 4p2", SSP2, p910_ssp2_pin2),
+ GRP_910("ssp2 4p3", SSP2, p910_ssp2_pin3),
+ GRP_910("ssp2 4p4", SSP2, p910_ssp2_pin4),
+ GRP_910("gssp", GSSP, p910_gssp_pin1),
+ GRP_910("pwm0", PWM0, p910_pwm0_pin1),
+ GRP_910("pwm1-1", PWM1, p910_pwm1_pin1),
+ GRP_910("pwm1-2", PWM1, p910_pwm1_pin2),
+ GRP_910("pwm2", PWM2, p910_pwm2_pin1),
+ GRP_910("pwm3-1", PWM3, p910_pwm3_pin1),
+ GRP_910("pwm3-2", PWM3, p910_pwm3_pin2),
+ GRP_910("pwm3-3", PWM3, p910_pwm3_pin3),
+ GRP_910("pri jtag", PRI_JTAG, p910_pri_jtag_pin1),
+ GRP_910("sec1 jtag", SEC1_JTAG, p910_sec1_jtag_pin1),
+ GRP_910("sec2 jtag", SEC2_JTAG, p910_sec2_jtag_pin1),
+ GRP_910("hsl 6p1", HSL, p910_hsl_pin1),
+ GRP_910("hsl 6p2", HSL, p910_hsl_pin2),
+ GRP_910("hsl 6p3", HSL, p910_hsl_pin3),
+ GRP_910("w1-1", ONE_WIRE, p910_w1_pin1),
+ GRP_910("w1-2", ONE_WIRE, p910_w1_pin2),
+ GRP_910("w1-3", ONE_WIRE, p910_w1_pin3),
+ GRP_910("w1-4", ONE_WIRE, p910_w1_pin4),
+ GRP_910("kpmk 16p1", KP_MK, p910_kpmk_pin1),
+ GRP_910("kpmk 11p2", KP_MK, p910_kpmk_pin2),
+ GRP_910("kpdk 8p1", KP_DK, p910_kpdk_pin1),
+ GRP_910("tds 5p1", TDS, p910_tds_pin1),
+ GRP_910("tds 4p2", TDS, p910_tds_pin2),
+ GRP_910("tb 4p1", TB, p910_tb_pin1),
+ GRP_910("tb 4p2", TB, p910_tb_pin2),
+ GRP_910("tb 4p3", TB, p910_tb_pin3),
+ GRP_910("ext dma0-1", EXT_DMA, p910_ext_dma0_pin1),
+ GRP_910("ext dma0-2", EXT_DMA, p910_ext_dma0_pin2),
+ GRP_910("ext dma0-3", EXT_DMA, p910_ext_dma0_pin3),
+ GRP_910("ext dma1-1", EXT_DMA, p910_ext_dma1_pin1),
+ GRP_910("ext dma1-2", EXT_DMA, p910_ext_dma1_pin2),
+ GRP_910("ext dma1-3", EXT_DMA, p910_ext_dma1_pin3),
+ GRP_910("ext dma2", EXT_DMA, p910_ext_dma2_pin1),
+ GRP_910("ext0 int-1", EXT_INT, p910_ext0_int_pin1),
+ GRP_910("ext0 int-2", EXT_INT, p910_ext0_int_pin2),
+ GRP_910("ext1 int-1", EXT_INT, p910_ext1_int_pin1),
+ GRP_910("ext1 int-2", EXT_INT, p910_ext1_int_pin2),
+ GRP_910("ext2 int-1", EXT_INT, p910_ext2_int_pin1),
+ GRP_910("ext2 int-2", EXT_INT, p910_ext2_int_pin2),
+ GRP_910("dac st23-1", DAC_ST23, p910_dac_st23_pin1),
+ GRP_910("dac st23-2", DAC_ST23, p910_dac_st23_pin2),
+ GRP_910("dac st23-3", DAC_ST23, p910_dac_st23_pin3),
+ GRP_910("dac st23-4", DAC_ST23, p910_dac_st23_pin4),
+ GRP_910("vcxo out-1", VCXO_OUT, p910_vcxo_out_pin1),
+ GRP_910("vcxo out-2", VCXO_OUT, p910_vcxo_out_pin2),
+ GRP_910("vcxo out-3", VCXO_OUT, p910_vcxo_out_pin3),
+ GRP_910("vcxo req-1", VCXO_REQ, p910_vcxo_req_pin1),
+ GRP_910("vcxo req-2", VCXO_REQ, p910_vcxo_req_pin2),
+ GRP_910("vcxo out2-1", VCXO_OUT2, p910_vcxo_out2_pin1),
+ GRP_910("vcxo out2-2", VCXO_OUT2, p910_vcxo_out2_pin2),
+ GRP_910("vcxo req2", VCXO_REQ2, p910_vcxo_req2_pin1),
+ GRP_910("ulpi", ULPI, p910_ulpi_pin1),
+ GRP_910("nand", NAND, p910_nand_pin1),
+ GRP_910("gpio0-1", GPIO, p910_gpio0_pin1),
+ GRP_910("gpio0-2", GPIO, p910_gpio0_pin2),
+ GRP_910("gpio1-1", GPIO, p910_gpio1_pin1),
+ GRP_910("gpio1-2", GPIO, p910_gpio1_pin2),
+ GRP_910("gpio2-1", GPIO, p910_gpio2_pin1),
+ GRP_910("gpio2-2", GPIO, p910_gpio2_pin2),
+ GRP_910("gpio3-1", GPIO, p910_gpio3_pin1),
+ GRP_910("gpio3-2", GPIO, p910_gpio3_pin2),
+ GRP_910("gpio20-1", GPIO, p910_gpio20_pin1),
+ GRP_910("gpio20-2", GPIO, p910_gpio20_pin2),
+ GRP_910("gpio21-1", GPIO, p910_gpio21_pin1),
+ GRP_910("gpio21-2", GPIO, p910_gpio21_pin2),
+ GRP_910("gpio22-1", GPIO, p910_gpio22_pin1),
+ GRP_910("gpio22-2", GPIO, p910_gpio22_pin2),
+ GRP_910("gpio23-1", GPIO, p910_gpio23_pin1),
+ GRP_910("gpio23-2", GPIO, p910_gpio23_pin2),
+ GRP_910("gpio24-1", GPIO, p910_gpio24_pin1),
+ GRP_910("gpio24-2", GPIO, p910_gpio24_pin2),
+ GRP_910("gpio25-1", GPIO, p910_gpio25_pin1),
+ GRP_910("gpio25-2", GPIO, p910_gpio25_pin2),
+ GRP_910("gpio26-1", GPIO, p910_gpio26_pin1),
+ GRP_910("gpio26-2", GPIO, p910_gpio26_pin2),
+ GRP_910("gpio27-1", GPIO, p910_gpio27_pin1),
+ GRP_910("gpio27-2", GPIO, p910_gpio27_pin2),
+ GRP_910("gpio85-1", GPIO, p910_gpio85_pin1),
+ GRP_910("gpio85-2", GPIO, p910_gpio85_pin2),
+ GRP_910("gpio86-1", GPIO, p910_gpio86_pin1),
+ GRP_910("gpio86-2", GPIO, p910_gpio86_pin2),
+ GRP_910("gpio87-1", GPIO, p910_gpio87_pin1),
+ GRP_910("gpio87-2", GPIO, p910_gpio87_pin2),
+ GRP_910("gpio88-1", GPIO, p910_gpio88_pin1),
+ GRP_910("gpio88-2", GPIO, p910_gpio88_pin2),
+ GRP_910("gpio89-1", GPIO, p910_gpio89_pin1),
+ GRP_910("gpio89-2", GPIO, p910_gpio89_pin2),
+ GRP_910("gpio90-1", GPIO, p910_gpio90_pin1),
+ GRP_910("gpio90-2", GPIO, p910_gpio90_pin2),
+ GRP_910("gpio91-1", GPIO, p910_gpio91_pin1),
+ GRP_910("gpio91-2", GPIO, p910_gpio91_pin2),
+ GRP_910("gpio92-1", GPIO, p910_gpio92_pin1),
+ GRP_910("gpio92-2", GPIO, p910_gpio92_pin2),
+};
+
+static const char * const p910_usim2_grps[] = {"usim2 3p1", "usim2 3p2"};
+static const char * const p910_mmc1_grps[] = {"mmc1 12p"};
+static const char * const p910_mmc2_grps[] = {"mmc2 10p"};
+static const char * const p910_mmc3_grps[] = {"mmc3 6p", "mmc3 10p"};
+static const char * const p910_uart0_grps[] = {"uart0 4p"};
+static const char * const p910_uart1_grps[] = {"uart1 2p1", "uart1 2p2",
+ "uart1 2p3", "uart1 4p4", "uart1 4p5"};
+static const char * const p910_uart2_grps[] = {"uart2 2p1", "uart2 2p2",
+ "uart2 4p3", "uart2 4p4"};
+static const char * const p910_twsi_grps[] = {"twsi 2p1", "twsi 2p2",
+ "twsi 2p3"};
+static const char * const p910_ccic_grps[] = {"ccic"};
+static const char * const p910_lcd_grps[] = {"lcd"};
+static const char * const p910_spi_grps[] = {"spi 4p1", "spi 4p2", "spi 5p3",
+ "spi 5p4"};
+static const char * const p910_dssp2_grps[] = {"dssp2 4p1", "dssp2 4p2",
+ "dssp2 3p3"};
+static const char * const p910_dssp3_grps[] = {"dssp3 4p1", "dssp3 4p2",
+ "dssp3 3p3"};
+static const char * const p910_ssp0_grps[] = {"ssp0 4p1", "ssp0 4p2",
+ "ssp0 4p3", "ssp0 4p4"};
+static const char * const p910_ssp1_grps[] = {"ssp1 4p1", "ssp1 5p2"};
+static const char * const p910_ssp2_grps[] = {"ssp2 4p1", "ssp2 4p2",
+ "ssp2 4p3", "ssp2 4p4"};
+static const char * const p910_gssp_grps[] = {"gssp"};
+static const char * const p910_pwm0_grps[] = {"pwm0"};
+static const char * const p910_pwm1_grps[] = {"pwm1-1", "pwm1-2"};
+static const char * const p910_pwm2_grps[] = {"pwm2"};
+static const char * const p910_pwm3_grps[] = {"pwm3-1", "pwm3-2", "pwm3-3"};
+static const char * const p910_pri_jtag_grps[] = {"pri jtag"};
+static const char * const p910_sec1_jtag_grps[] = {"sec1 jtag"};
+static const char * const p910_sec2_jtag_grps[] = {"sec2 jtag"};
+static const char * const p910_hsl_grps[] = {"hsl 6p1", "hsl 6p2", "hsl 6p3"};
+static const char * const p910_w1_grps[] = {"w1-1", "w1-2", "w1-3", "w1-4"};
+static const char * const p910_kpmk_grps[] = {"kpmk 16p1", "kpmk 11p2"};
+static const char * const p910_kpdk_grps[] = {"kpdk 8p1"};
+static const char * const p910_tds_grps[] = {"tds 5p1", "tds 4p2"};
+static const char * const p910_tb_grps[] = {"tb 4p1", "tb 4p2", "tb 4p3"};
+static const char * const p910_dma0_grps[] = {"ext dma0-1", "ext dma0-2",
+ "ext dma0-3"};
+static const char * const p910_dma1_grps[] = {"ext dma1-1", "ext dma1-2",
+ "ext dma1-3"};
+static const char * const p910_dma2_grps[] = {"ext dma2"};
+static const char * const p910_int0_grps[] = {"ext0 int-1", "ext0 int-2"};
+static const char * const p910_int1_grps[] = {"ext1 int-1", "ext1 int-2"};
+static const char * const p910_int2_grps[] = {"ext2 int-1", "ext2 int-2"};
+static const char * const p910_dac_st23_grps[] = {"dac st23-1", "dac st23-2",
+ "dac st23-3", "dac st23-4"};
+static const char * const p910_vcxo_out_grps[] = {"vcxo out-1", "vcxo out-2",
+ "vcxo out-3"};
+static const char * const p910_vcxo_req_grps[] = {"vcxo req-1", "vcxo req-2"};
+static const char * const p910_vcxo_out2_grps[] = {"vcxo out2-1",
+ "vcxo out2-2"};
+static const char * const p910_vcxo_req2_grps[] = {"vcxo req2"};
+static const char * const p910_ulpi_grps[] = {"ulpi"};
+static const char * const p910_nand_grps[] = {"nand"};
+static const char * const p910_gpio0_grps[] = {"gpio0-1", "gpio0-2"};
+static const char * const p910_gpio1_grps[] = {"gpio1-1", "gpio1-2"};
+static const char * const p910_gpio2_grps[] = {"gpio2-1", "gpio2-2"};
+static const char * const p910_gpio3_grps[] = {"gpio3-1", "gpio3-2"};
+static const char * const p910_gpio20_grps[] = {"gpio20-1", "gpio20-2"};
+static const char * const p910_gpio21_grps[] = {"gpio21-1", "gpio21-2"};
+static const char * const p910_gpio22_grps[] = {"gpio22-1", "gpio22-2"};
+static const char * const p910_gpio23_grps[] = {"gpio23-1", "gpio23-2"};
+static const char * const p910_gpio24_grps[] = {"gpio24-1", "gpio24-2"};
+static const char * const p910_gpio25_grps[] = {"gpio25-1", "gpio25-2"};
+static const char * const p910_gpio26_grps[] = {"gpio26-1", "gpio26-2"};
+static const char * const p910_gpio27_grps[] = {"gpio27-1", "gpio27-2"};
+static const char * const p910_gpio85_grps[] = {"gpio85-1", "gpio85-2"};
+static const char * const p910_gpio86_grps[] = {"gpio86-1", "gpio86-2"};
+static const char * const p910_gpio87_grps[] = {"gpio87-1", "gpio87-2"};
+static const char * const p910_gpio88_grps[] = {"gpio88-1", "gpio88-2"};
+static const char * const p910_gpio89_grps[] = {"gpio89-1", "gpio89-2"};
+static const char * const p910_gpio90_grps[] = {"gpio90-1", "gpio90-2"};
+static const char * const p910_gpio91_grps[] = {"gpio91-1", "gpio91-2"};
+static const char * const p910_gpio92_grps[] = {"gpio92-1", "gpio92-2"};
+
+static struct pxa3xx_pmx_func pxa910_funcs[] = {
+ {"usim2", ARRAY_AND_SIZE(p910_usim2_grps)},
+ {"mmc1", ARRAY_AND_SIZE(p910_mmc1_grps)},
+ {"mmc2", ARRAY_AND_SIZE(p910_mmc2_grps)},
+ {"mmc3", ARRAY_AND_SIZE(p910_mmc3_grps)},
+ {"uart0", ARRAY_AND_SIZE(p910_uart0_grps)},
+ {"uart1", ARRAY_AND_SIZE(p910_uart1_grps)},
+ {"uart2", ARRAY_AND_SIZE(p910_uart2_grps)},
+ {"twsi", ARRAY_AND_SIZE(p910_twsi_grps)},
+ {"ccic", ARRAY_AND_SIZE(p910_ccic_grps)},
+ {"lcd", ARRAY_AND_SIZE(p910_lcd_grps)},
+ {"spi", ARRAY_AND_SIZE(p910_spi_grps)},
+ {"dssp2", ARRAY_AND_SIZE(p910_dssp2_grps)},
+ {"dssp3", ARRAY_AND_SIZE(p910_dssp3_grps)},
+ {"ssp0", ARRAY_AND_SIZE(p910_ssp0_grps)},
+ {"ssp1", ARRAY_AND_SIZE(p910_ssp1_grps)},
+ {"ssp2", ARRAY_AND_SIZE(p910_ssp2_grps)},
+ {"gssp", ARRAY_AND_SIZE(p910_gssp_grps)},
+ {"pwm0", ARRAY_AND_SIZE(p910_pwm0_grps)},
+ {"pwm1", ARRAY_AND_SIZE(p910_pwm1_grps)},
+ {"pwm2", ARRAY_AND_SIZE(p910_pwm2_grps)},
+ {"pwm3", ARRAY_AND_SIZE(p910_pwm3_grps)},
+ {"pri_jtag", ARRAY_AND_SIZE(p910_pri_jtag_grps)},
+ {"sec1_jtag", ARRAY_AND_SIZE(p910_sec1_jtag_grps)},
+ {"sec2_jtag", ARRAY_AND_SIZE(p910_sec2_jtag_grps)},
+ {"hsl", ARRAY_AND_SIZE(p910_hsl_grps)},
+ {"w1", ARRAY_AND_SIZE(p910_w1_grps)},
+ {"kpmk", ARRAY_AND_SIZE(p910_kpmk_grps)},
+ {"kpdk", ARRAY_AND_SIZE(p910_kpdk_grps)},
+ {"tds", ARRAY_AND_SIZE(p910_tds_grps)},
+ {"tb", ARRAY_AND_SIZE(p910_tb_grps)},
+ {"dma0", ARRAY_AND_SIZE(p910_dma0_grps)},
+ {"dma1", ARRAY_AND_SIZE(p910_dma1_grps)},
+ {"dma2", ARRAY_AND_SIZE(p910_dma2_grps)},
+ {"int0", ARRAY_AND_SIZE(p910_int0_grps)},
+ {"int1", ARRAY_AND_SIZE(p910_int1_grps)},
+ {"int2", ARRAY_AND_SIZE(p910_int2_grps)},
+ {"dac_st23", ARRAY_AND_SIZE(p910_dac_st23_grps)},
+ {"vcxo_out", ARRAY_AND_SIZE(p910_vcxo_out_grps)},
+ {"vcxo_req", ARRAY_AND_SIZE(p910_vcxo_req_grps)},
+ {"vcxo_out2", ARRAY_AND_SIZE(p910_vcxo_out2_grps)},
+ {"vcxo_req2", ARRAY_AND_SIZE(p910_vcxo_req2_grps)},
+ {"ulpi", ARRAY_AND_SIZE(p910_ulpi_grps)},
+ {"nand", ARRAY_AND_SIZE(p910_nand_grps)},
+ {"gpio0", ARRAY_AND_SIZE(p910_gpio0_grps)},
+ {"gpio1", ARRAY_AND_SIZE(p910_gpio1_grps)},
+ {"gpio2", ARRAY_AND_SIZE(p910_gpio2_grps)},
+ {"gpio3", ARRAY_AND_SIZE(p910_gpio3_grps)},
+ {"gpio20", ARRAY_AND_SIZE(p910_gpio20_grps)},
+ {"gpio21", ARRAY_AND_SIZE(p910_gpio21_grps)},
+ {"gpio22", ARRAY_AND_SIZE(p910_gpio22_grps)},
+ {"gpio23", ARRAY_AND_SIZE(p910_gpio23_grps)},
+ {"gpio24", ARRAY_AND_SIZE(p910_gpio24_grps)},
+ {"gpio25", ARRAY_AND_SIZE(p910_gpio25_grps)},
+ {"gpio26", ARRAY_AND_SIZE(p910_gpio26_grps)},
+ {"gpio27", ARRAY_AND_SIZE(p910_gpio27_grps)},
+ {"gpio85", ARRAY_AND_SIZE(p910_gpio85_grps)},
+ {"gpio86", ARRAY_AND_SIZE(p910_gpio86_grps)},
+ {"gpio87", ARRAY_AND_SIZE(p910_gpio87_grps)},
+ {"gpio88", ARRAY_AND_SIZE(p910_gpio88_grps)},
+ {"gpio89", ARRAY_AND_SIZE(p910_gpio89_grps)},
+ {"gpio90", ARRAY_AND_SIZE(p910_gpio90_grps)},
+ {"gpio91", ARRAY_AND_SIZE(p910_gpio91_grps)},
+ {"gpio92", ARRAY_AND_SIZE(p910_gpio92_grps)},
+};
+
+static struct pinctrl_desc pxa910_pctrl_desc = {
+ .name = "pxa910-pinctrl",
+ .owner = THIS_MODULE,
+};
+
+static struct pxa3xx_pinmux_info pxa910_info = {
+ .mfp = pxa910_mfp,
+ .num_mfp = ARRAY_SIZE(pxa910_mfp),
+ .grps = pxa910_grps,
+ .num_grps = ARRAY_SIZE(pxa910_grps),
+ .funcs = pxa910_funcs,
+ .num_funcs = ARRAY_SIZE(pxa910_funcs),
+ .num_gpio = 128,
+ .desc = &pxa910_pctrl_desc,
+ .pads = pxa910_pads,
+ .num_pads = ARRAY_SIZE(pxa910_pads),
+
+ .cputype = PINCTRL_PXA910,
+ .ds_mask = PXA910_DS_MASK,
+ .ds_shift = PXA910_DS_SHIFT,
+};
+
+static int __devinit pxa910_pinmux_probe(struct platform_device *pdev)
+{
+ return pxa3xx_pinctrl_register(pdev, &pxa910_info);
+}
+
+static int __devexit pxa910_pinmux_remove(struct platform_device *pdev)
+{
+ return pxa3xx_pinctrl_unregister(pdev);
+}
+
+static struct platform_driver pxa910_pinmux_driver = {
+ .driver = {
+ .name = "pxa910-pinmux",
+ .owner = THIS_MODULE,
+ },
+ .probe = pxa910_pinmux_probe,
+ .remove = __devexit_p(pxa910_pinmux_remove),
+};
+
+static int __init pxa910_pinmux_init(void)
+{
+ return platform_driver_register(&pxa910_pinmux_driver);
+}
+core_initcall_sync(pxa910_pinmux_init);
+
+static void __exit pxa910_pinmux_exit(void)
+{
+ platform_driver_unregister(&pxa910_pinmux_driver);
+}
+module_exit(pxa910_pinmux_exit);
+
+MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
+MODULE_DESCRIPTION("PXA3xx pin control driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c
index c8d02f1..fc4a281 100644
--- a/drivers/pinctrl/pinctrl-u300.c
+++ b/drivers/pinctrl/pinctrl-u300.c
@@ -162,7 +162,7 @@
#define U300_SYSCON_PMC4R_APP_MISC_16_APP_UART1_CTS 0x0100
#define U300_SYSCON_PMC4R_APP_MISC_16_EMIF_1_STATIC_CS5_N 0x0200
-#define DRIVER_NAME "pinmux-u300"
+#define DRIVER_NAME "pinctrl-u300"
/*
* The DB3350 has 467 pads, I have enumerated the pads clockwise around the
@@ -1053,13 +1053,16 @@ static struct pinctrl_desc u300_pmx_desc = {
.owner = THIS_MODULE,
};
-static int __init u300_pmx_probe(struct platform_device *pdev)
+static int __devinit u300_pmx_probe(struct platform_device *pdev)
{
struct u300_pmx *upmx;
struct resource *res;
+ struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev);
int ret;
int i;
+ pr_err("U300 PMX PROBE\n");
+
/* Create state holders etc for this driver */
upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL);
if (!upmx)
@@ -1095,12 +1098,14 @@ static int __init u300_pmx_probe(struct platform_device *pdev)
}
/* We will handle a range of GPIO pins */
- for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++)
+ for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) {
+ u300_gpio_ranges[i].gc = gpio_chip;
pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]);
+ }
platform_set_drvdata(pdev, upmx);
- dev_info(&pdev->dev, "initialized U300 pinmux driver\n");
+ dev_info(&pdev->dev, "initialized U300 pin control driver\n");
return 0;
@@ -1115,7 +1120,7 @@ out_no_resource:
return ret;
}
-static int __exit u300_pmx_remove(struct platform_device *pdev)
+static int __devexit u300_pmx_remove(struct platform_device *pdev)
{
struct u300_pmx *upmx = platform_get_drvdata(pdev);
int i;
@@ -1136,12 +1141,13 @@ static struct platform_driver u300_pmx_driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
- .remove = __exit_p(u300_pmx_remove),
+ .probe = u300_pmx_probe,
+ .remove = __devexit_p(u300_pmx_remove),
};
static int __init u300_pmx_init(void)
{
- return platform_driver_probe(&u300_pmx_driver, u300_pmx_probe);
+ return platform_driver_register(&u300_pmx_driver);
}
arch_initcall(u300_pmx_init);
diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c
index 7c3193f..86e4017 100644
--- a/drivers/pinctrl/pinmux.c
+++ b/drivers/pinctrl/pinmux.c
@@ -1,12 +1,14 @@
/*
* Core driver for the pin muxing portions of the pin control subsystem
*
- * Copyright (C) 2011 ST-Ericsson SA
+ * Copyright (C) 2011-2012 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
* Based on bits of regulator core, gpio core and clk core
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
+ * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
+ *
* License terms: GNU General Public License (GPL) version 2
*/
#define pr_fmt(fmt) "pinmux core: " fmt
@@ -19,8 +21,6 @@
#include <linux/radix-tree.h>
#include <linux/err.h>
#include <linux/list.h>
-#include <linux/mutex.h>
-#include <linux/spinlock.h>
#include <linux/string.h>
#include <linux/sysfs.h>
#include <linux/debugfs.h>
@@ -28,80 +28,64 @@
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinmux.h>
#include "core.h"
+#include "pinmux.h"
-/* List of pinmuxes */
-static DEFINE_MUTEX(pinmux_list_mutex);
-static LIST_HEAD(pinmux_list);
+int pinmux_check_ops(struct pinctrl_dev *pctldev)
+{
+ const struct pinmux_ops *ops = pctldev->desc->pmxops;
+ unsigned selector = 0;
-/* Global pinmux maps */
-static struct pinmux_map *pinmux_maps;
-static unsigned pinmux_maps_num;
+ /* Check that we implement required operations */
+ if (!ops->list_functions ||
+ !ops->get_function_name ||
+ !ops->get_function_groups ||
+ !ops->enable ||
+ !ops->disable)
+ return -EINVAL;
-/**
- * struct pinmux_group - group list item for pinmux groups
- * @node: pinmux group list node
- * @group_selector: the group selector for this group
- */
-struct pinmux_group {
- struct list_head node;
- unsigned group_selector;
-};
+ /* Check that all functions registered have names */
+ while (ops->list_functions(pctldev, selector) >= 0) {
+ const char *fname = ops->get_function_name(pctldev,
+ selector);
+ if (!fname) {
+ pr_err("pinmux ops has no name for function%u\n",
+ selector);
+ return -EINVAL;
+ }
+ selector++;
+ }
-/**
- * struct pinmux - per-device pinmux state holder
- * @node: global list node
- * @dev: the device using this pinmux
- * @usecount: the number of active users of this mux setting, used to keep
- * track of nested use cases
- * @pctldev: pin control device handling this pinmux
- * @func_selector: the function selector for the pinmux device handling
- * this pinmux
- * @groups: the group selectors for the pinmux device and
- * selector combination handling this pinmux, this is a list that
- * will be traversed on all pinmux operations such as
- * get/put/enable/disable
- * @mutex: a lock for the pinmux state holder
- */
-struct pinmux {
- struct list_head node;
- struct device *dev;
- unsigned usecount;
- struct pinctrl_dev *pctldev;
- unsigned func_selector;
- struct list_head groups;
- struct mutex mutex;
-};
+ return 0;
+}
-/**
- * struct pinmux_hog - a list item to stash mux hogs
- * @node: pinmux hog list node
- * @map: map entry responsible for this hogging
- * @pmx: the pinmux hogged by this item
- */
-struct pinmux_hog {
- struct list_head node;
- struct pinmux_map const *map;
- struct pinmux *pmx;
-};
+int pinmux_validate_map(struct pinctrl_map const *map, int i)
+{
+ if (!map->data.mux.function) {
+ pr_err("failed to register map %s (%d): no function given\n",
+ map->name, i);
+ return -EINVAL;
+ }
+
+ return 0;
+}
/**
* pin_request() - request a single pin to be muxed in, typically for GPIO
* @pin: the pin number in the global pin space
- * @function: a functional name to give to this pin, passed to the driver
- * so it knows what function to mux in, e.g. the string "gpioNN"
- * means that you want to mux in the pin for use as GPIO number NN
+ * @owner: a representation of the owner of this pin; typically the device
+ * name that controls its mux function, or the requested GPIO name
* @gpio_range: the range matching the GPIO pin if this is a request for a
* single GPIO pin
*/
static int pin_request(struct pinctrl_dev *pctldev,
- int pin, const char *function,
+ int pin, const char *owner,
struct pinctrl_gpio_range *gpio_range)
{
struct pin_desc *desc;
const struct pinmux_ops *ops = pctldev->desc->pmxops;
int status = -EINVAL;
- dev_dbg(pctldev->dev, "request pin %d for %s\n", pin, function);
+ dev_dbg(pctldev->dev, "request pin %d for %s\n", pin, owner);
desc = pin_desc_get(pctldev, pin);
if (desc == NULL) {
@@ -110,20 +94,17 @@ static int pin_request(struct pinctrl_dev *pctldev,
goto out;
}
- if (!function) {
- dev_err(pctldev->dev, "no function name given\n");
- return -EINVAL;
- }
-
- spin_lock(&desc->lock);
- if (desc->mux_function) {
- spin_unlock(&desc->lock);
+ if (desc->usecount && strcmp(desc->owner, owner)) {
dev_err(pctldev->dev,
"pin already requested\n");
goto out;
}
- desc->mux_function = function;
- spin_unlock(&desc->lock);
+
+ desc->usecount++;
+ if (desc->usecount > 1)
+ return 0;
+
+ desc->owner = owner;
/* Let each pin increase references to this module */
if (!try_module_get(pctldev->owner)) {
@@ -146,19 +127,22 @@ static int pin_request(struct pinctrl_dev *pctldev,
else
status = 0;
- if (status)
+ if (status) {
dev_err(pctldev->dev, "->request on device %s failed for pin %d\n",
pctldev->desc->name, pin);
+ module_put(pctldev->owner);
+ }
+
out_free_pin:
if (status) {
- spin_lock(&desc->lock);
- desc->mux_function = NULL;
- spin_unlock(&desc->lock);
+ desc->usecount--;
+ if (!desc->usecount)
+ desc->owner = NULL;
}
out:
if (status)
dev_err(pctldev->dev, "pin-%d (%s) status %d\n",
- pin, function ? : "?", status);
+ pin, owner, status);
return status;
}
@@ -170,8 +154,8 @@ out:
* @gpio_range: the range matching the GPIO pin if this is a request for a
* single GPIO pin
*
- * This function returns a pointer to the function name in use. This is used
- * for callers that dynamically allocate a function name so it can be freed
+ * This function returns a pointer to the previous owner. This is used
+ * for callers that dynamically allocate an owner name so it can be freed
* once the pin is free. This is done for GPIO request functions.
*/
static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
@@ -179,7 +163,7 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
{
const struct pinmux_ops *ops = pctldev->desc->pmxops;
struct pin_desc *desc;
- const char *func;
+ const char *owner;
desc = pin_desc_get(pctldev, pin);
if (desc == NULL) {
@@ -188,6 +172,10 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
return NULL;
}
+ desc->usecount--;
+ if (desc->usecount)
+ return NULL;
+
/*
* If there is no kind of request function for the pin we just assume
* we got it by default and proceed.
@@ -197,99 +185,73 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
else if (ops->free)
ops->free(pctldev, pin);
- spin_lock(&desc->lock);
- func = desc->mux_function;
- desc->mux_function = NULL;
- spin_unlock(&desc->lock);
+ owner = desc->owner;
+ desc->owner = NULL;
+ desc->mux_setting = NULL;
module_put(pctldev->owner);
- return func;
+ return owner;
}
/**
- * pinmux_request_gpio() - request a single pin to be muxed in as GPIO
- * @gpio: the GPIO pin number from the GPIO subsystem number space
- *
- * This function should *ONLY* be used from gpiolib-based GPIO drivers,
- * as part of their gpio_request() semantics, platforms and individual drivers
- * shall *NOT* request GPIO pins to be muxed in.
+ * pinmux_request_gpio() - request pinmuxing for a GPIO pin
+ * @pctldev: pin controller device affected
+ * @pin: the pin to mux in for GPIO
+ * @range: the applicable GPIO range
*/
-int pinmux_request_gpio(unsigned gpio)
+int pinmux_request_gpio(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned pin, unsigned gpio)
{
char gpiostr[16];
- const char *function;
- struct pinctrl_dev *pctldev;
- struct pinctrl_gpio_range *range;
+ const char *owner;
int ret;
- int pin;
-
- ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
- if (ret)
- return -EINVAL;
-
- /* Convert to the pin controllers number space */
- pin = gpio - range->base + range->pin_base;
/* Conjure some name stating what chip and pin this is taken by */
snprintf(gpiostr, 15, "%s:%d", range->name, gpio);
- function = kstrdup(gpiostr, GFP_KERNEL);
- if (!function)
+ owner = kstrdup(gpiostr, GFP_KERNEL);
+ if (!owner)
return -EINVAL;
- ret = pin_request(pctldev, pin, function, range);
+ ret = pin_request(pctldev, pin, owner, range);
if (ret < 0)
- kfree(function);
+ kfree(owner);
return ret;
}
-EXPORT_SYMBOL_GPL(pinmux_request_gpio);
/**
- * pinmux_free_gpio() - free a single pin, currently used as GPIO
- * @gpio: the GPIO pin number from the GPIO subsystem number space
- *
- * This function should *ONLY* be used from gpiolib-based GPIO drivers,
- * as part of their gpio_free() semantics, platforms and individual drivers
- * shall *NOT* request GPIO pins to be muxed out.
+ * pinmux_free_gpio() - release a pin from GPIO muxing
+ * @pctldev: the pin controller device for the pin
+ * @pin: the affected currently GPIO-muxed in pin
+ * @range: applicable GPIO range
*/
-void pinmux_free_gpio(unsigned gpio)
+void pinmux_free_gpio(struct pinctrl_dev *pctldev, unsigned pin,
+ struct pinctrl_gpio_range *range)
{
- struct pinctrl_dev *pctldev;
- struct pinctrl_gpio_range *range;
- int ret;
- int pin;
- const char *func;
+ const char *owner;
- ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
- if (ret)
- return;
-
- /* Convert to the pin controllers number space */
- pin = gpio - range->base + range->pin_base;
-
- func = pin_free(pctldev, pin, range);
- kfree(func);
+ owner = pin_free(pctldev, pin, range);
+ kfree(owner);
}
-EXPORT_SYMBOL_GPL(pinmux_free_gpio);
-static int pinmux_gpio_direction(unsigned gpio, bool input)
+/**
+ * pinmux_gpio_direction() - set the direction of a single muxed-in GPIO pin
+ * @pctldev: the pin controller handling this pin
+ * @range: applicable GPIO range
+ * @pin: the affected GPIO pin in this controller
+ * @input: true if we set the pin as input, false for output
+ */
+int pinmux_gpio_direction(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned pin, bool input)
{
- struct pinctrl_dev *pctldev;
- struct pinctrl_gpio_range *range;
const struct pinmux_ops *ops;
int ret;
- int pin;
-
- ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
- if (ret)
- return ret;
ops = pctldev->desc->pmxops;
- /* Convert to the pin controllers number space */
- pin = gpio - range->base + range->pin_base;
-
if (ops->gpio_set_direction)
ret = ops->gpio_set_direction(pctldev, range, pin, input);
else
@@ -298,146 +260,89 @@ static int pinmux_gpio_direction(unsigned gpio, bool input)
return ret;
}
-/**
- * pinmux_gpio_direction_input() - request a GPIO pin to go into input mode
- * @gpio: the GPIO pin number from the GPIO subsystem number space
- *
- * This function should *ONLY* be used from gpiolib-based GPIO drivers,
- * as part of their gpio_direction_input() semantics, platforms and individual
- * drivers shall *NOT* touch pinmux GPIO calls.
- */
-int pinmux_gpio_direction_input(unsigned gpio)
-{
- return pinmux_gpio_direction(gpio, true);
-}
-EXPORT_SYMBOL_GPL(pinmux_gpio_direction_input);
-
-/**
- * pinmux_gpio_direction_output() - request a GPIO pin to go into output mode
- * @gpio: the GPIO pin number from the GPIO subsystem number space
- *
- * This function should *ONLY* be used from gpiolib-based GPIO drivers,
- * as part of their gpio_direction_output() semantics, platforms and individual
- * drivers shall *NOT* touch pinmux GPIO calls.
- */
-int pinmux_gpio_direction_output(unsigned gpio)
-{
- return pinmux_gpio_direction(gpio, false);
-}
-EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output);
-
-/**
- * pinmux_register_mappings() - register a set of pinmux mappings
- * @maps: the pinmux mappings table to register, this should be marked with
- * __initdata so it can be discarded after boot, this function will
- * perform a shallow copy for the mapping entries.
- * @num_maps: the number of maps in the mapping table
- *
- * Only call this once during initialization of your machine, the function is
- * tagged as __init and won't be callable after init has completed. The map
- * passed into this function will be owned by the pinmux core and cannot be
- * freed.
- */
-int __init pinmux_register_mappings(struct pinmux_map const *maps,
- unsigned num_maps)
+static int pinmux_func_name_to_selector(struct pinctrl_dev *pctldev,
+ const char *function)
{
- void *tmp_maps;
- int i;
-
- pr_debug("add %d pinmux maps\n", num_maps);
-
- /* First sanity check the new mapping */
- for (i = 0; i < num_maps; i++) {
- if (!maps[i].name) {
- pr_err("failed to register map %d: no map name given\n",
- i);
- return -EINVAL;
- }
-
- if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) {
- pr_err("failed to register map %s (%d): no pin control device given\n",
- maps[i].name, i);
- return -EINVAL;
- }
+ const struct pinmux_ops *ops = pctldev->desc->pmxops;
+ unsigned selector = 0;
- if (!maps[i].function) {
- pr_err("failed to register map %s (%d): no function ID given\n",
- maps[i].name, i);
- return -EINVAL;
- }
+ /* See if this pctldev has this function */
+ while (ops->list_functions(pctldev, selector) >= 0) {
+ const char *fname = ops->get_function_name(pctldev,
+ selector);
- if (!maps[i].dev && !maps[i].dev_name)
- pr_debug("add system map %s function %s with no device\n",
- maps[i].name,
- maps[i].function);
- else
- pr_debug("register map %s, function %s\n",
- maps[i].name,
- maps[i].function);
- }
+ if (!strcmp(function, fname))
+ return selector;
- /*
- * Make a copy of the map array - string pointers will end up in the
- * kernel const section anyway so these do not need to be deep copied.
- */
- if (!pinmux_maps_num) {
- /* On first call, just copy them */
- tmp_maps = kmemdup(maps,
- sizeof(struct pinmux_map) * num_maps,
- GFP_KERNEL);
- if (!tmp_maps)
- return -ENOMEM;
- } else {
- /* Subsequent calls, reallocate array to new size */
- size_t oldsize = sizeof(struct pinmux_map) * pinmux_maps_num;
- size_t newsize = sizeof(struct pinmux_map) * num_maps;
-
- tmp_maps = krealloc(pinmux_maps, oldsize + newsize, GFP_KERNEL);
- if (!tmp_maps)
- return -ENOMEM;
- memcpy((tmp_maps + oldsize), maps, newsize);
+ selector++;
}
- pinmux_maps = tmp_maps;
- pinmux_maps_num += num_maps;
- return 0;
+ pr_err("%s does not support function %s\n",
+ pinctrl_dev_get_name(pctldev), function);
+ return -EINVAL;
}
-/**
- * acquire_pins() - acquire all the pins for a certain function on a pinmux
- * @pctldev: the device to take the pins on
- * @func_selector: the function selector to acquire the pins for
- * @group_selector: the group selector containing the pins to acquire
- */
-static int acquire_pins(struct pinctrl_dev *pctldev,
- unsigned func_selector,
- unsigned group_selector)
+int pinmux_map_to_setting(struct pinctrl_map const *map,
+ struct pinctrl_setting *setting)
{
- const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
+ struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
- const char *func = pmxops->get_function_name(pctldev,
- func_selector);
- const unsigned *pins;
- unsigned num_pins;
+ const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
+ char const * const *groups;
+ unsigned num_groups;
int ret;
+ const char *group;
int i;
+ const unsigned *pins;
+ unsigned num_pins;
- ret = pctlops->get_group_pins(pctldev, group_selector,
- &pins, &num_pins);
- if (ret)
+ setting->data.mux.func =
+ pinmux_func_name_to_selector(pctldev, map->data.mux.function);
+ if (setting->data.mux.func < 0)
+ return setting->data.mux.func;
+
+ ret = pmxops->get_function_groups(pctldev, setting->data.mux.func,
+ &groups, &num_groups);
+ if (ret < 0)
return ret;
+ if (!num_groups)
+ return -EINVAL;
+
+ if (map->data.mux.group) {
+ bool found = false;
+ group = map->data.mux.group;
+ for (i = 0; i < num_groups; i++) {
+ if (!strcmp(group, groups[i])) {
+ found = true;
+ break;
+ }
+ }
+ if (!found)
+ return -EINVAL;
+ } else {
+ group = groups[0];
+ }
+
+ setting->data.mux.group = pinctrl_get_group_selector(pctldev, group);
+ if (setting->data.mux.group < 0)
+ return setting->data.mux.group;
- dev_dbg(pctldev->dev, "requesting the %u pins from group %u\n",
- num_pins, group_selector);
+ ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, &pins,
+ &num_pins);
+ if (ret) {
+ dev_err(pctldev->dev,
+ "could not get pins for device %s group selector %d\n",
+ pinctrl_dev_get_name(pctldev), setting->data.mux.group);
+ return -ENODEV;
+ }
/* Try to allocate all pins in this group, one by one */
for (i = 0; i < num_pins; i++) {
- ret = pin_request(pctldev, pins[i], func, NULL);
+ ret = pin_request(pctldev, pins[i], map->dev_name, NULL);
if (ret) {
dev_err(pctldev->dev,
- "could not get pin %d for function %s on device %s - conflicting mux mappings?\n",
- pins[i], func ? : "(undefined)",
- pinctrl_dev_get_name(pctldev));
+ "could not get request pin %d on device %s\n",
+ pins[i], pinctrl_dev_get_name(pctldev));
/* On error release all taken pins */
i--; /* this pin just failed */
for (; i >= 0; i--)
@@ -445,587 +350,101 @@ static int acquire_pins(struct pinctrl_dev *pctldev,
return -ENODEV;
}
}
+
return 0;
}
-/**
- * release_pins() - release pins taken by earlier acquirement
- * @pctldev: the device to free the pins on
- * @group_selector: the group selector containing the pins to free
- */
-static void release_pins(struct pinctrl_dev *pctldev,
- unsigned group_selector)
+void pinmux_free_setting(struct pinctrl_setting const *setting)
{
+ struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
const unsigned *pins;
unsigned num_pins;
int ret;
int i;
- ret = pctlops->get_group_pins(pctldev, group_selector,
+ ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
&pins, &num_pins);
if (ret) {
- dev_err(pctldev->dev, "could not get pins to release for group selector %d\n",
- group_selector);
+ dev_err(pctldev->dev,
+ "could not get pins for device %s group selector %d\n",
+ pinctrl_dev_get_name(pctldev), setting->data.mux.group);
return;
}
+
for (i = 0; i < num_pins; i++)
pin_free(pctldev, pins[i], NULL);
}
-/**
- * pinmux_check_pin_group() - check function and pin group combo
- * @pctldev: device to check the pin group vs function for
- * @func_selector: the function selector to check the pin group for, we have
- * already looked this up in the calling function
- * @pin_group: the pin group to match to the function
- *
- * This function will check that the pinmux driver can supply the
- * selected pin group for a certain function, returns the group selector if
- * the group and function selector will work fine together, else returns
- * negative
- */
-static int pinmux_check_pin_group(struct pinctrl_dev *pctldev,
- unsigned func_selector,
- const char *pin_group)
+int pinmux_enable_setting(struct pinctrl_setting const *setting)
{
- const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
+ struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
- int ret;
-
- /*
- * If the driver does not support different pin groups for the
- * functions, we only support group 0, and assume this exists.
- */
- if (!pctlops || !pctlops->list_groups)
- return 0;
-
- /*
- * Passing NULL (no specific group) will select the first and
- * hopefully only group of pins available for this function.
- */
- if (!pin_group) {
- char const * const *groups;
- unsigned num_groups;
-
- ret = pmxops->get_function_groups(pctldev, func_selector,
- &groups, &num_groups);
- if (ret)
- return ret;
- if (num_groups < 1)
- return -EINVAL;
- ret = pinctrl_get_group_selector(pctldev, groups[0]);
- if (ret < 0) {
- dev_err(pctldev->dev,
- "function %s wants group %s but the pin controller does not seem to have that group\n",
- pmxops->get_function_name(pctldev, func_selector),
- groups[0]);
- return ret;
- }
-
- if (num_groups > 1)
- dev_dbg(pctldev->dev,
- "function %s support more than one group, default-selecting first group %s (%d)\n",
- pmxops->get_function_name(pctldev, func_selector),
- groups[0],
- ret);
-
- return ret;
- }
-
- dev_dbg(pctldev->dev,
- "check if we have pin group %s on controller %s\n",
- pin_group, pinctrl_dev_get_name(pctldev));
-
- ret = pinctrl_get_group_selector(pctldev, pin_group);
- if (ret < 0) {
- dev_dbg(pctldev->dev,
- "%s does not support pin group %s with function %s\n",
- pinctrl_dev_get_name(pctldev),
- pin_group,
- pmxops->get_function_name(pctldev, func_selector));
- }
- return ret;
-}
-
-/**
- * pinmux_search_function() - check pin control driver for a certain function
- * @pctldev: device to check for function and position
- * @map: function map containing the function and position to look for
- * @func_selector: returns the applicable function selector if found
- * @group_selector: returns the applicable group selector if found
- *
- * This will search the pinmux driver for an applicable
- * function with a specific pin group, returns 0 if these can be mapped
- * negative otherwise
- */
-static int pinmux_search_function(struct pinctrl_dev *pctldev,
- struct pinmux_map const *map,
- unsigned *func_selector,
- unsigned *group_selector)
-{
const struct pinmux_ops *ops = pctldev->desc->pmxops;
- unsigned selector = 0;
-
- /* See if this pctldev has this function */
- while (ops->list_functions(pctldev, selector) >= 0) {
- const char *fname = ops->get_function_name(pctldev,
- selector);
- int ret;
-
- if (!strcmp(map->function, fname)) {
- /* Found the function, check pin group */
- ret = pinmux_check_pin_group(pctldev, selector,
- map->group);
- if (ret < 0)
- return ret;
-
- /* This function and group selector can be used */
- *func_selector = selector;
- *group_selector = ret;
- return 0;
-
- }
- selector++;
- }
-
- pr_err("%s does not support function %s\n",
- pinctrl_dev_get_name(pctldev), map->function);
- return -EINVAL;
-}
-
-/**
- * pinmux_enable_muxmap() - enable a map entry for a certain pinmux
- */
-static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev,
- struct pinmux *pmx,
- struct device *dev,
- const char *devname,
- struct pinmux_map const *map)
-{
- unsigned func_selector;
- unsigned group_selector;
- struct pinmux_group *grp;
int ret;
+ const unsigned *pins;
+ unsigned num_pins;
+ int i;
+ struct pin_desc *desc;
- /*
- * Note that we're not locking the pinmux mutex here, because
- * this is only called at pinmux initialization time when it
- * has not been added to any list and thus is not reachable
- * by anyone else.
- */
-
- if (pmx->pctldev && pmx->pctldev != pctldev) {
- dev_err(pctldev->dev,
- "different pin control devices given for device %s, function %s\n",
- devname, map->function);
- return -EINVAL;
- }
- pmx->dev = dev;
- pmx->pctldev = pctldev;
-
- /* Now go into the driver and try to match a function and group */
- ret = pinmux_search_function(pctldev, map, &func_selector,
- &group_selector);
- if (ret < 0)
- return ret;
-
- /*
- * If the function selector is already set, it needs to be identical,
- * we support several groups with one function but not several
- * functions with one or several groups in the same pinmux.
- */
- if (pmx->func_selector != UINT_MAX &&
- pmx->func_selector != func_selector) {
- dev_err(pctldev->dev,
- "dual function defines in the map for device %s\n",
- devname);
- return -EINVAL;
- }
- pmx->func_selector = func_selector;
-
- /* Now add this group selector, we may have many of them */
- grp = kmalloc(sizeof(struct pinmux_group), GFP_KERNEL);
- if (!grp)
- return -ENOMEM;
- grp->group_selector = group_selector;
- ret = acquire_pins(pctldev, func_selector, group_selector);
+ ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
+ &pins, &num_pins);
if (ret) {
- kfree(grp);
- return ret;
+ /* errors only affect debug data, so just warn */
+ dev_warn(pctldev->dev,
+ "could not get pins for group selector %d\n",
+ setting->data.mux.group);
+ num_pins = 0;
}
- list_add(&grp->node, &pmx->groups);
-
- return 0;
-}
-static void pinmux_free_groups(struct pinmux *pmx)
-{
- struct list_head *node, *tmp;
-
- list_for_each_safe(node, tmp, &pmx->groups) {
- struct pinmux_group *grp =
- list_entry(node, struct pinmux_group, node);
- /* Release all pins taken by this group */
- release_pins(pmx->pctldev, grp->group_selector);
- list_del(node);
- kfree(grp);
- }
-}
-
-/**
- * pinmux_get() - retrieves the pinmux for a certain device
- * @dev: the device to get the pinmux for
- * @name: an optional specific mux mapping name or NULL, the name is only
- * needed if you want to have more than one mapping per device, or if you
- * need an anonymous pinmux (not tied to any specific device)
- */
-struct pinmux *pinmux_get(struct device *dev, const char *name)
-{
- struct pinmux_map const *map = NULL;
- struct pinctrl_dev *pctldev = NULL;
- const char *devname = NULL;
- struct pinmux *pmx;
- bool found_map;
- unsigned num_maps = 0;
- int ret = -ENODEV;
- int i;
-
- /* We must have dev or ID or both */
- if (!dev && !name)
- return ERR_PTR(-EINVAL);
-
- if (dev)
- devname = dev_name(dev);
-
- pr_debug("get mux %s for device %s\n", name,
- devname ? devname : "(none)");
-
- /*
- * create the state cookie holder struct pinmux for each
- * mapping, this is what consumers will get when requesting
- * a pinmux handle with pinmux_get()
- */
- pmx = kzalloc(sizeof(struct pinmux), GFP_KERNEL);
- if (pmx == NULL)
- return ERR_PTR(-ENOMEM);
- mutex_init(&pmx->mutex);
- pmx->func_selector = UINT_MAX;
- INIT_LIST_HEAD(&pmx->groups);
-
- /* Iterate over the pinmux maps to locate the right ones */
- for (i = 0; i < pinmux_maps_num; i++) {
- map = &pinmux_maps[i];
- found_map = false;
-
- /*
- * First, try to find the pctldev given in the map
- */
- pctldev = get_pinctrl_dev_from_dev(map->ctrl_dev,
- map->ctrl_dev_name);
- if (!pctldev) {
- const char *devname = NULL;
-
- if (map->ctrl_dev)
- devname = dev_name(map->ctrl_dev);
- else if (map->ctrl_dev_name)
- devname = map->ctrl_dev_name;
-
- pr_warning("could not find a pinctrl device for pinmux function %s, fishy, they shall all have one\n",
- map->function);
- pr_warning("given pinctrl device name: %s",
- devname ? devname : "UNDEFINED");
-
- /* Continue to check the other mappings anyway... */
+ for (i = 0; i < num_pins; i++) {
+ desc = pin_desc_get(pctldev, pins[i]);
+ if (desc == NULL) {
+ dev_warn(pctldev->dev,
+ "could not get pin desc for pin %d\n",
+ pins[i]);
continue;
}
-
- pr_debug("in map, found pctldev %s to handle function %s",
- dev_name(pctldev->dev), map->function);
-
-
- /*
- * If we're looking for a specific named map, this must match,
- * else we loop and look for the next.
- */
- if (name != NULL) {
- if (map->name == NULL)
- continue;
- if (strcmp(map->name, name))
- continue;
- }
-
- /*
- * This is for the case where no device name is given, we
- * already know that the function name matches from above
- * code.
- */
- if (!map->dev_name && (name != NULL))
- found_map = true;
-
- /* If the mapping has a device set up it must match */
- if (map->dev_name &&
- (!devname || !strcmp(map->dev_name, devname)))
- /* MATCH! */
- found_map = true;
-
- /* If this map is applicable, then apply it */
- if (found_map) {
- ret = pinmux_enable_muxmap(pctldev, pmx, dev,
- devname, map);
- if (ret) {
- pinmux_free_groups(pmx);
- kfree(pmx);
- return ERR_PTR(ret);
- }
- num_maps++;
- }
- }
-
-
- /* We should have atleast one map, right */
- if (!num_maps) {
- pr_err("could not find any mux maps for device %s, ID %s\n",
- devname ? devname : "(anonymous)",
- name ? name : "(undefined)");
- kfree(pmx);
- return ERR_PTR(-EINVAL);
- }
-
- pr_debug("found %u mux maps for device %s, UD %s\n",
- num_maps,
- devname ? devname : "(anonymous)",
- name ? name : "(undefined)");
-
- /* Add the pinmux to the global list */
- mutex_lock(&pinmux_list_mutex);
- list_add(&pmx->node, &pinmux_list);
- mutex_unlock(&pinmux_list_mutex);
-
- return pmx;
-}
-EXPORT_SYMBOL_GPL(pinmux_get);
-
-/**
- * pinmux_put() - release a previously claimed pinmux
- * @pmx: a pinmux previously claimed by pinmux_get()
- */
-void pinmux_put(struct pinmux *pmx)
-{
- if (pmx == NULL)
- return;
-
- mutex_lock(&pmx->mutex);
- if (pmx->usecount)
- pr_warn("releasing pinmux with active users!\n");
- /* Free the groups and all acquired pins */
- pinmux_free_groups(pmx);
- mutex_unlock(&pmx->mutex);
-
- /* Remove from list */
- mutex_lock(&pinmux_list_mutex);
- list_del(&pmx->node);
- mutex_unlock(&pinmux_list_mutex);
-
- kfree(pmx);
-}
-EXPORT_SYMBOL_GPL(pinmux_put);
-
-/**
- * pinmux_enable() - enable a certain pinmux setting
- * @pmx: the pinmux to enable, previously claimed by pinmux_get()
- */
-int pinmux_enable(struct pinmux *pmx)
-{
- int ret = 0;
-
- if (pmx == NULL)
- return -EINVAL;
- mutex_lock(&pmx->mutex);
- if (pmx->usecount++ == 0) {
- struct pinctrl_dev *pctldev = pmx->pctldev;
- const struct pinmux_ops *ops = pctldev->desc->pmxops;
- struct pinmux_group *grp;
-
- list_for_each_entry(grp, &pmx->groups, node) {
- ret = ops->enable(pctldev, pmx->func_selector,
- grp->group_selector);
- if (ret) {
- /*
- * TODO: call disable() on all groups we called
- * enable() on to this point?
- */
- pmx->usecount--;
- break;
- }
- }
+ desc->mux_setting = &(setting->data.mux);
}
- mutex_unlock(&pmx->mutex);
- return ret;
-}
-EXPORT_SYMBOL_GPL(pinmux_enable);
-/**
- * pinmux_disable() - disable a certain pinmux setting
- * @pmx: the pinmux to disable, previously claimed by pinmux_get()
- */
-void pinmux_disable(struct pinmux *pmx)
-{
- if (pmx == NULL)
- return;
-
- mutex_lock(&pmx->mutex);
- if (--pmx->usecount == 0) {
- struct pinctrl_dev *pctldev = pmx->pctldev;
- const struct pinmux_ops *ops = pctldev->desc->pmxops;
- struct pinmux_group *grp;
-
- list_for_each_entry(grp, &pmx->groups, node) {
- ops->disable(pctldev, pmx->func_selector,
- grp->group_selector);
- }
- }
- mutex_unlock(&pmx->mutex);
+ return ops->enable(pctldev, setting->data.mux.func,
+ setting->data.mux.group);
}
-EXPORT_SYMBOL_GPL(pinmux_disable);
-int pinmux_check_ops(struct pinctrl_dev *pctldev)
+void pinmux_disable_setting(struct pinctrl_setting const *setting)
{
+ struct pinctrl_dev *pctldev = setting->pctldev;
+ const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
const struct pinmux_ops *ops = pctldev->desc->pmxops;
- unsigned selector = 0;
-
- /* Check that we implement required operations */
- if (!ops->list_functions ||
- !ops->get_function_name ||
- !ops->get_function_groups ||
- !ops->enable ||
- !ops->disable)
- return -EINVAL;
-
- /* Check that all functions registered have names */
- while (ops->list_functions(pctldev, selector) >= 0) {
- const char *fname = ops->get_function_name(pctldev,
- selector);
- if (!fname) {
- pr_err("pinmux ops has no name for function%u\n",
- selector);
- return -EINVAL;
- }
- selector++;
- }
-
- return 0;
-}
-
-/* Hog a single map entry and add to the hoglist */
-static int pinmux_hog_map(struct pinctrl_dev *pctldev,
- struct pinmux_map const *map)
-{
- struct pinmux_hog *hog;
- struct pinmux *pmx;
int ret;
+ const unsigned *pins;
+ unsigned num_pins;
+ int i;
+ struct pin_desc *desc;
- if (map->dev || map->dev_name) {
- /*
- * TODO: the day we have device tree support, we can
- * traverse the device tree and hog to specific device nodes
- * without any problems, so then we can hog pinmuxes for
- * all devices that just want a static pin mux at this point.
- */
- dev_err(pctldev->dev, "map %s wants to hog a non-system pinmux, this is not going to work\n",
- map->name);
- return -EINVAL;
- }
-
- hog = kzalloc(sizeof(struct pinmux_hog), GFP_KERNEL);
- if (!hog)
- return -ENOMEM;
-
- pmx = pinmux_get(NULL, map->name);
- if (IS_ERR(pmx)) {
- kfree(hog);
- dev_err(pctldev->dev,
- "could not get the %s pinmux mapping for hogging\n",
- map->name);
- return PTR_ERR(pmx);
- }
-
- ret = pinmux_enable(pmx);
+ ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
+ &pins, &num_pins);
if (ret) {
- pinmux_put(pmx);
- kfree(hog);
- dev_err(pctldev->dev,
- "could not enable the %s pinmux mapping for hogging\n",
- map->name);
- return ret;
+ /* errors only affect debug data, so just warn */
+ dev_warn(pctldev->dev,
+ "could not get pins for group selector %d\n",
+ setting->data.mux.group);
+ num_pins = 0;
}
- hog->map = map;
- hog->pmx = pmx;
-
- dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name,
- map->function);
- mutex_lock(&pctldev->pinmux_hogs_lock);
- list_add(&hog->node, &pctldev->pinmux_hogs);
- mutex_unlock(&pctldev->pinmux_hogs_lock);
-
- return 0;
-}
-
-/**
- * pinmux_hog_maps() - hog specific map entries on controller device
- * @pctldev: the pin control device to hog entries on
- *
- * When the pin controllers are registered, there may be some specific pinmux
- * map entries that need to be hogged, i.e. get+enabled until the system shuts
- * down.
- */
-int pinmux_hog_maps(struct pinctrl_dev *pctldev)
-{
- struct device *dev = pctldev->dev;
- const char *devname = dev_name(dev);
- int ret;
- int i;
-
- INIT_LIST_HEAD(&pctldev->pinmux_hogs);
- mutex_init(&pctldev->pinmux_hogs_lock);
-
- for (i = 0; i < pinmux_maps_num; i++) {
- struct pinmux_map const *map = &pinmux_maps[i];
-
- if (!map->hog_on_boot)
+ for (i = 0; i < num_pins; i++) {
+ desc = pin_desc_get(pctldev, pins[i]);
+ if (desc == NULL) {
+ dev_warn(pctldev->dev,
+ "could not get pin desc for pin %d\n",
+ pins[i]);
continue;
-
- if ((map->ctrl_dev == dev) ||
- (map->ctrl_dev_name &&
- !strcmp(map->ctrl_dev_name, devname))) {
- /* OK time to hog! */
- ret = pinmux_hog_map(pctldev, map);
- if (ret)
- return ret;
}
+ desc->mux_setting = NULL;
}
- return 0;
-}
-/**
- * pinmux_unhog_maps() - unhog specific map entries on controller device
- * @pctldev: the pin control device to unhog entries on
- */
-void pinmux_unhog_maps(struct pinctrl_dev *pctldev)
-{
- struct list_head *node, *tmp;
-
- mutex_lock(&pctldev->pinmux_hogs_lock);
- list_for_each_safe(node, tmp, &pctldev->pinmux_hogs) {
- struct pinmux_hog *hog =
- list_entry(node, struct pinmux_hog, node);
- pinmux_disable(hog->pmx);
- pinmux_put(hog->pmx);
- list_del(node);
- kfree(hog);
- }
- mutex_unlock(&pctldev->pinmux_hogs_lock);
+ ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group);
}
#ifdef CONFIG_DEBUG_FS
@@ -1037,6 +456,8 @@ static int pinmux_functions_show(struct seq_file *s, void *what)
const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
unsigned func_selector = 0;
+ mutex_lock(&pinctrl_mutex);
+
while (pmxops->list_functions(pctldev, func_selector) >= 0) {
const char *func = pmxops->get_function_name(pctldev,
func_selector);
@@ -1057,24 +478,29 @@ static int pinmux_functions_show(struct seq_file *s, void *what)
seq_puts(s, "]\n");
func_selector++;
-
}
+ mutex_unlock(&pinctrl_mutex);
+
return 0;
}
static int pinmux_pins_show(struct seq_file *s, void *what)
{
struct pinctrl_dev *pctldev = s->private;
+ const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
+ const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
unsigned i, pin;
seq_puts(s, "Pinmux settings per pin\n");
- seq_puts(s, "Format: pin (name): pinmuxfunction\n");
+ seq_puts(s, "Format: pin (name): owner\n");
+
+ mutex_lock(&pinctrl_mutex);
/* The pin number can be retrived from the pin controller descriptor */
for (i = 0; i < pctldev->desc->npins; i++) {
-
struct pin_desc *desc;
+ bool is_hog = false;
pin = pctldev->desc->pins[i].number;
desc = pin_desc_get(pctldev, pin);
@@ -1082,94 +508,49 @@ static int pinmux_pins_show(struct seq_file *s, void *what)
if (desc == NULL)
continue;
- seq_printf(s, "pin %d (%s): %s\n", pin,
- desc->name ? desc->name : "unnamed",
- desc->mux_function ? desc->mux_function
- : "UNCLAIMED");
- }
-
- return 0;
-}
+ if (desc->owner &&
+ !strcmp(desc->owner, pinctrl_dev_get_name(pctldev)))
+ is_hog = true;
-static int pinmux_hogs_show(struct seq_file *s, void *what)
-{
- struct pinctrl_dev *pctldev = s->private;
- struct pinmux_hog *hog;
+ seq_printf(s, "pin %d (%s): %s%s", pin,
+ desc->name ? desc->name : "unnamed",
+ desc->owner ? desc->owner : "UNCLAIMED",
+ is_hog ? " (HOG)" : "");
- seq_puts(s, "Pinmux map hogs held by device\n");
+ if (desc->mux_setting)
+ seq_printf(s, " function %s group %s\n",
+ pmxops->get_function_name(pctldev,
+ desc->mux_setting->func),
+ pctlops->get_group_name(pctldev,
+ desc->mux_setting->group));
+ else
+ seq_printf(s, "\n");
+ }
- list_for_each_entry(hog, &pctldev->pinmux_hogs, node)
- seq_printf(s, "%s\n", hog->map->name);
+ mutex_unlock(&pinctrl_mutex);
return 0;
}
-static int pinmux_show(struct seq_file *s, void *what)
+void pinmux_show_map(struct seq_file *s, struct pinctrl_map const *map)
{
- struct pinmux *pmx;
-
- seq_puts(s, "Requested pinmuxes and their maps:\n");
- list_for_each_entry(pmx, &pinmux_list, node) {
- struct pinctrl_dev *pctldev = pmx->pctldev;
- const struct pinmux_ops *pmxops;
- const struct pinctrl_ops *pctlops;
- struct pinmux_group *grp;
-
- if (!pctldev) {
- seq_puts(s, "NO PIN CONTROLLER DEVICE\n");
- continue;
- }
-
- pmxops = pctldev->desc->pmxops;
- pctlops = pctldev->desc->pctlops;
-
- seq_printf(s, "device: %s function: %s (%u),",
- pinctrl_dev_get_name(pmx->pctldev),
- pmxops->get_function_name(pctldev,
- pmx->func_selector),
- pmx->func_selector);
-
- seq_printf(s, " groups: [");
- list_for_each_entry(grp, &pmx->groups, node) {
- seq_printf(s, " %s (%u)",
- pctlops->get_group_name(pctldev,
- grp->group_selector),
- grp->group_selector);
- }
- seq_printf(s, " ]");
-
- seq_printf(s, " users: %u map-> %s\n",
- pmx->usecount,
- pmx->dev ? dev_name(pmx->dev) : "(system)");
- }
-
- return 0;
+ seq_printf(s, "group %s\nfunction %s\n",
+ map->data.mux.group ? map->data.mux.group : "(default)",
+ map->data.mux.function);
}
-static int pinmux_maps_show(struct seq_file *s, void *what)
+void pinmux_show_setting(struct seq_file *s,
+ struct pinctrl_setting const *setting)
{
- int i;
-
- seq_puts(s, "Pinmux maps:\n");
-
- for (i = 0; i < pinmux_maps_num; i++) {
- struct pinmux_map const *map = &pinmux_maps[i];
+ struct pinctrl_dev *pctldev = setting->pctldev;
+ const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
+ const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
- seq_printf(s, "%s:\n", map->name);
- if (map->dev || map->dev_name)
- seq_printf(s, " device: %s\n",
- map->dev ? dev_name(map->dev) :
- map->dev_name);
- else
- seq_printf(s, " SYSTEM MUX\n");
- seq_printf(s, " controlling device %s\n",
- map->ctrl_dev ? dev_name(map->ctrl_dev) :
- map->ctrl_dev_name);
- seq_printf(s, " function: %s\n", map->function);
- seq_printf(s, " group: %s\n", map->group ? map->group :
- "(default)");
- }
- return 0;
+ seq_printf(s, "group: %s (%u) function: %s (%u)\n",
+ pctlops->get_group_name(pctldev, setting->data.mux.group),
+ setting->data.mux.group,
+ pmxops->get_function_name(pctldev, setting->data.mux.func),
+ setting->data.mux.func);
}
static int pinmux_functions_open(struct inode *inode, struct file *file)
@@ -1182,21 +563,6 @@ static int pinmux_pins_open(struct inode *inode, struct file *file)
return single_open(file, pinmux_pins_show, inode->i_private);
}
-static int pinmux_hogs_open(struct inode *inode, struct file *file)
-{
- return single_open(file, pinmux_hogs_show, inode->i_private);
-}
-
-static int pinmux_open(struct inode *inode, struct file *file)
-{
- return single_open(file, pinmux_show, NULL);
-}
-
-static int pinmux_maps_open(struct inode *inode, struct file *file)
-{
- return single_open(file, pinmux_maps_show, NULL);
-}
-
static const struct file_operations pinmux_functions_ops = {
.open = pinmux_functions_open,
.read = seq_read,
@@ -1211,27 +577,6 @@ static const struct file_operations pinmux_pins_ops = {
.release = single_release,
};
-static const struct file_operations pinmux_hogs_ops = {
- .open = pinmux_hogs_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations pinmux_ops = {
- .open = pinmux_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-static const struct file_operations pinmux_maps_ops = {
- .open = pinmux_maps_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
void pinmux_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev)
{
@@ -1239,16 +584,6 @@ void pinmux_init_device_debugfs(struct dentry *devroot,
devroot, pctldev, &pinmux_functions_ops);
debugfs_create_file("pinmux-pins", S_IFREG | S_IRUGO,
devroot, pctldev, &pinmux_pins_ops);
- debugfs_create_file("pinmux-hogs", S_IFREG | S_IRUGO,
- devroot, pctldev, &pinmux_hogs_ops);
-}
-
-void pinmux_init_debugfs(struct dentry *subsys_root)
-{
- debugfs_create_file("pinmuxes", S_IFREG | S_IRUGO,
- subsys_root, NULL, &pinmux_ops);
- debugfs_create_file("pinmux-maps", S_IFREG | S_IRUGO,
- subsys_root, NULL, &pinmux_maps_ops);
}
#endif /* CONFIG_DEBUG_FS */
diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h
index 97f5222..6fc4700 100644
--- a/drivers/pinctrl/pinmux.h
+++ b/drivers/pinctrl/pinmux.h
@@ -13,11 +13,29 @@
#ifdef CONFIG_PINMUX
int pinmux_check_ops(struct pinctrl_dev *pctldev);
+
+int pinmux_validate_map(struct pinctrl_map const *map, int i);
+
+int pinmux_request_gpio(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned pin, unsigned gpio);
+void pinmux_free_gpio(struct pinctrl_dev *pctldev, unsigned pin,
+ struct pinctrl_gpio_range *range);
+int pinmux_gpio_direction(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned pin, bool input);
+
+int pinmux_map_to_setting(struct pinctrl_map const *map,
+ struct pinctrl_setting *setting);
+void pinmux_free_setting(struct pinctrl_setting const *setting);
+int pinmux_enable_setting(struct pinctrl_setting const *setting);
+void pinmux_disable_setting(struct pinctrl_setting const *setting);
+
+void pinmux_show_map(struct seq_file *s, struct pinctrl_map const *map);
+void pinmux_show_setting(struct seq_file *s,
+ struct pinctrl_setting const *setting);
void pinmux_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev);
-void pinmux_init_debugfs(struct dentry *subsys_root);
-int pinmux_hog_maps(struct pinctrl_dev *pctldev);
-void pinmux_unhog_maps(struct pinctrl_dev *pctldev);
#else
@@ -26,21 +44,63 @@ static inline int pinmux_check_ops(struct pinctrl_dev *pctldev)
return 0;
}
-static inline void pinmux_init_device_debugfs(struct dentry *devroot,
- struct pinctrl_dev *pctldev)
+static inline int pinmux_validate_map(struct pinctrl_map const *map, int i)
{
+ return 0;
}
-static inline void pinmux_init_debugfs(struct dentry *subsys_root)
+static inline int pinmux_request_gpio(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned pin, unsigned gpio)
{
+ return 0;
}
-static inline int pinmux_hog_maps(struct pinctrl_dev *pctldev)
+static inline void pinmux_free_gpio(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ struct pinctrl_gpio_range *range)
+{
+}
+
+static inline int pinmux_gpio_direction(struct pinctrl_dev *pctldev,
+ struct pinctrl_gpio_range *range,
+ unsigned pin, bool input)
+{
+ return 0;
+}
+
+static inline int pinmux_map_to_setting(struct pinctrl_map const *map,
+ struct pinctrl_setting *setting)
{
return 0;
}
-static inline void pinmux_unhog_maps(struct pinctrl_dev *pctldev)
+static inline void pinmux_free_setting(struct pinctrl_setting const *setting)
+{
+}
+
+static inline int pinmux_enable_setting(struct pinctrl_setting const *setting)
+{
+ return 0;
+}
+
+static inline void pinmux_disable_setting(
+ struct pinctrl_setting const *setting)
+{
+}
+
+static inline void pinmux_show_map(struct seq_file *s,
+ struct pinctrl_map const *map)
+{
+}
+
+static inline void pinmux_show_setting(struct seq_file *s,
+ struct pinctrl_setting const *setting)
+{
+}
+
+static inline void pinmux_init_device_debugfs(struct dentry *devroot,
+ struct pinctrl_dev *pctldev)
{
}
diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c
index a60523f..5b3eda2 100644
--- a/drivers/tty/serial/sirfsoc_uart.c
+++ b/drivers/tty/serial/sirfsoc_uart.c
@@ -22,7 +22,7 @@
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
-#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/consumer.h>
#include "sirfsoc_uart.h"
@@ -673,12 +673,10 @@ int sirfsoc_uart_probe(struct platform_device *pdev)
port->irq = res->start;
if (sirfport->hw_flow_ctrl) {
- sirfport->pmx = pinmux_get(&pdev->dev, NULL);
- ret = IS_ERR(sirfport->pmx);
+ sirfport->p = pinctrl_get_select_default(&pdev->dev);
+ ret = IS_ERR(sirfport->p);
if (ret)
- goto pmx_err;
-
- pinmux_enable(sirfport->pmx);
+ goto pin_err;
}
port->ops = &sirfsoc_uart_ops;
@@ -695,11 +693,9 @@ int sirfsoc_uart_probe(struct platform_device *pdev)
port_err:
platform_set_drvdata(pdev, NULL);
- if (sirfport->hw_flow_ctrl) {
- pinmux_disable(sirfport->pmx);
- pinmux_put(sirfport->pmx);
- }
-pmx_err:
+ if (sirfport->hw_flow_ctrl)
+ pinctrl_put(sirfport->p);
+pin_err:
irq_err:
devm_iounmap(&pdev->dev, port->membase);
err:
@@ -711,10 +707,8 @@ static int sirfsoc_uart_remove(struct platform_device *pdev)
struct sirfsoc_uart_port *sirfport = platform_get_drvdata(pdev);
struct uart_port *port = &sirfport->port;
platform_set_drvdata(pdev, NULL);
- if (sirfport->hw_flow_ctrl) {
- pinmux_disable(sirfport->pmx);
- pinmux_put(sirfport->pmx);
- }
+ if (sirfport->hw_flow_ctrl)
+ pinctrl_put(sirfport->p);
devm_iounmap(&pdev->dev, port->membase);
uart_remove_one_port(&sirfsoc_uart_drv, port);
return 0;
diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h
index fc64260..6e207fd 100644
--- a/drivers/tty/serial/sirfsoc_uart.h
+++ b/drivers/tty/serial/sirfsoc_uart.h
@@ -162,7 +162,7 @@ struct sirfsoc_uart_port {
unsigned char ms_enabled;
struct uart_port port;
- struct pinmux *pmx;
+ struct pinctrl *p;
};
/* Hardware Flow Control */
diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h
new file mode 100644
index 0000000..191e726
--- /dev/null
+++ b/include/linux/pinctrl/consumer.h
@@ -0,0 +1,159 @@
+/*
+ * Consumer interface the pin control subsystem
+ *
+ * Copyright (C) 2012 ST-Ericsson SA
+ * Written on behalf of Linaro for ST-Ericsson
+ * Based on bits of regulator core, gpio core and clk core
+ *
+ * Author: Linus Walleij <linus.walleij@linaro.org>
+ *
+ * License terms: GNU General Public License (GPL) version 2
+ */
+#ifndef __LINUX_PINCTRL_CONSUMER_H
+#define __LINUX_PINCTRL_CONSUMER_H
+
+#include <linux/err.h>
+#include <linux/list.h>
+#include <linux/seq_file.h>
+#include "pinctrl-state.h"
+
+/* This struct is private to the core and should be regarded as a cookie */
+struct pinctrl;
+struct pinctrl_state;
+
+#ifdef CONFIG_PINCTRL
+
+/* External interface to pin control */
+extern int pinctrl_request_gpio(unsigned gpio);
+extern void pinctrl_free_gpio(unsigned gpio);
+extern int pinctrl_gpio_direction_input(unsigned gpio);
+extern int pinctrl_gpio_direction_output(unsigned gpio);
+
+extern struct pinctrl * __must_check pinctrl_get(struct device *dev);
+extern void pinctrl_put(struct pinctrl *p);
+extern struct pinctrl_state * __must_check pinctrl_lookup_state(
+ struct pinctrl *p,
+ const char *name);
+extern int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *s);
+
+#else /* !CONFIG_PINCTRL */
+
+static inline int pinctrl_request_gpio(unsigned gpio)
+{
+ return 0;
+}
+
+static inline void pinctrl_free_gpio(unsigned gpio)
+{
+}
+
+static inline int pinctrl_gpio_direction_input(unsigned gpio)
+{
+ return 0;
+}
+
+static inline int pinctrl_gpio_direction_output(unsigned gpio)
+{
+ return 0;
+}
+
+static inline struct pinctrl * __must_check pinctrl_get(struct device *dev)
+{
+ return NULL;
+}
+
+static inline void pinctrl_put(struct pinctrl *p)
+{
+}
+
+static inline struct pinctrl_state * __must_check pinctrl_lookup_state(
+ struct pinctrl *p,
+ const char *name)
+{
+ return NULL;
+}
+
+static inline int pinctrl_select_state(struct pinctrl *p,
+ struct pinctrl_state *s)
+{
+ return 0;
+}
+
+#endif /* CONFIG_PINCTRL */
+
+static inline struct pinctrl * __must_check pinctrl_get_select(
+ struct device *dev, const char *name)
+{
+ struct pinctrl *p;
+ struct pinctrl_state *s;
+ int ret;
+
+ p = pinctrl_get(dev);
+ if (IS_ERR(p))
+ return p;
+
+ s = pinctrl_lookup_state(p, name);
+ if (IS_ERR(s)) {
+ pinctrl_put(p);
+ return ERR_PTR(PTR_ERR(s));
+ }
+
+ ret = pinctrl_select_state(p, s);
+ if (ret < 0) {
+ pinctrl_put(p);
+ return ERR_PTR(ret);
+ }
+
+ return p;
+}
+
+static inline struct pinctrl * __must_check pinctrl_get_select_default(
+ struct device *dev)
+{
+ return pinctrl_get_select(dev, PINCTRL_STATE_DEFAULT);
+}
+
+#ifdef CONFIG_PINCONF
+
+extern int pin_config_get(const char *dev_name, const char *name,
+ unsigned long *config);
+extern int pin_config_set(const char *dev_name, const char *name,
+ unsigned long config);
+extern int pin_config_group_get(const char *dev_name,
+ const char *pin_group,
+ unsigned long *config);
+extern int pin_config_group_set(const char *dev_name,
+ const char *pin_group,
+ unsigned long config);
+
+#else
+
+static inline int pin_config_get(const char *dev_name, const char *name,
+ unsigned long *config)
+{
+ return 0;
+}
+
+static inline int pin_config_set(const char *dev_name, const char *name,
+ unsigned long config)
+{
+ return 0;
+}
+
+static inline int pin_config_group_get(const char *dev_name,
+ const char *pin_group,
+ unsigned long *config)
+{
+ return 0;
+}
+
+static inline int pin_config_group_set(const char *dev_name,
+ const char *pin_group,
+ unsigned long config)
+{
+ return 0;
+}
+
+#endif
+
+#endif /* __LINUX_PINCTRL_CONSUMER_H */
diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h
index d0aecb7..fee4349 100644
--- a/include/linux/pinctrl/machine.h
+++ b/include/linux/pinctrl/machine.h
@@ -9,87 +9,153 @@
*
* License terms: GNU General Public License (GPL) version 2
*/
-#ifndef __LINUX_PINMUX_MACHINE_H
-#define __LINUX_PINMUX_MACHINE_H
+#ifndef __LINUX_PINCTRL_MACHINE_H
+#define __LINUX_PINCTRL_MACHINE_H
+
+#include "pinctrl-state.h"
+
+enum pinctrl_map_type {
+ PIN_MAP_TYPE_INVALID,
+ PIN_MAP_TYPE_DUMMY_STATE,
+ PIN_MAP_TYPE_MUX_GROUP,
+ PIN_MAP_TYPE_CONFIGS_PIN,
+ PIN_MAP_TYPE_CONFIGS_GROUP,
+};
+
+/**
+ * struct pinctrl_map_mux - mapping table content for MAP_TYPE_MUX_GROUP
+ * @group: the name of the group whose mux function is to be configured. This
+ * field may be left NULL, and the first applicable group for the function
+ * will be used.
+ * @function: the mux function to select for the group
+ */
+struct pinctrl_map_mux {
+ const char *group;
+ const char *function;
+};
/**
- * struct pinmux_map - boards/machines shall provide this map for devices
+ * struct pinctrl_map_configs - mapping table content for MAP_TYPE_CONFIGS_*
+ * @group_or_pin: the name of the pin or group whose configuration parameters
+ * are to be configured.
+ * @configs: a pointer to an array of config parameters/values to program into
+ * hardware. Each individual pin controller defines the format and meaning
+ * of config parameters.
+ * @num_configs: the number of entries in array @configs
+ */
+struct pinctrl_map_configs {
+ const char *group_or_pin;
+ unsigned long *configs;
+ unsigned num_configs;
+};
+
+/**
+ * struct pinctrl_map - boards/machines shall provide this map for devices
+ * @dev_name: the name of the device using this specific mapping, the name
+ * must be the same as in your struct device*. If this name is set to the
+ * same name as the pin controllers own dev_name(), the map entry will be
+ * hogged by the driver itself upon registration
* @name: the name of this specific map entry for the particular machine.
- * This is the second parameter passed to pinmux_get() when you want
- * to have several mappings to the same device
- * @ctrl_dev: the pin control device to be used by this mapping, may be NULL
- * if you provide .ctrl_dev_name instead (this is more common)
+ * This is the parameter passed to pinmux_lookup_state()
+ * @type: the type of mapping table entry
* @ctrl_dev_name: the name of the device controlling this specific mapping,
- * the name must be the same as in your struct device*, may be NULL if
- * you provide .ctrl_dev instead
- * @function: a function in the driver to use for this mapping, the driver
- * will lookup the function referenced by this ID on the specified
- * pin control device
- * @group: sometimes a function can map to different pin groups, so this
- * selects a certain specific pin group to activate for the function, if
- * left as NULL, the first applicable group will be used
- * @dev: the device using this specific mapping, may be NULL if you provide
- * .dev_name instead (this is more common)
- * @dev_name: the name of the device using this specific mapping, the name
- * must be the same as in your struct device*, may be NULL if you
- * provide .dev instead
- * @hog_on_boot: if this is set to true, the pin control subsystem will itself
- * hog the mappings as the pinmux device drivers are attached, so this is
- * typically used with system maps (mux mappings without an assigned
- * device) that you want to get hogged and enabled by default as soon as
- * a pinmux device supporting it is registered. These maps will not be
- * disabled and put until the system shuts down.
+ * the name must be the same as in your struct device*. This field is not
+ * used for PIN_MAP_TYPE_DUMMY_STATE
+ * @data: Data specific to the mapping type
*/
-struct pinmux_map {
+struct pinctrl_map {
+ const char *dev_name;
const char *name;
- struct device *ctrl_dev;
+ enum pinctrl_map_type type;
const char *ctrl_dev_name;
- const char *function;
- const char *group;
- struct device *dev;
- const char *dev_name;
- bool hog_on_boot;
+ union {
+ struct pinctrl_map_mux mux;
+ struct pinctrl_map_configs configs;
+ } data;
};
-/*
- * Convenience macro to set a simple map from a certain pin controller and a
- * certain function to a named device
- */
-#define PINMUX_MAP(a, b, c, d) \
- { .name = a, .ctrl_dev_name = b, .function = c, .dev_name = d }
+/* Convenience macros to create mapping table entries */
-/*
- * Convenience macro to map a system function onto a certain pinctrl device.
- * System functions are not assigned to a particular device.
- */
-#define PINMUX_MAP_SYS(a, b, c) \
- { .name = a, .ctrl_dev_name = b, .function = c }
+#define PIN_MAP_DUMMY_STATE(dev, state) \
+ { \
+ .dev_name = dev, \
+ .name = state, \
+ .type = PIN_MAP_TYPE_DUMMY_STATE, \
+ }
-/*
- * Convenience macro to map a system function onto a certain pinctrl device,
- * to be hogged by the pinmux core until the system shuts down.
- */
-#define PINMUX_MAP_SYS_HOG(a, b, c) \
- { .name = a, .ctrl_dev_name = b, .function = c, \
- .hog_on_boot = true }
+#define PIN_MAP_MUX_GROUP(dev, state, pinctrl, grp, func) \
+ { \
+ .dev_name = dev, \
+ .name = state, \
+ .type = PIN_MAP_TYPE_MUX_GROUP, \
+ .ctrl_dev_name = pinctrl, \
+ .data.mux = { \
+ .group = grp, \
+ .function = func, \
+ }, \
+ }
-/*
- * Convenience macro to map a system function onto a certain pinctrl device
- * using a specified group, to be hogged by the pinmux core until the system
- * shuts down.
- */
-#define PINMUX_MAP_SYS_HOG_GROUP(a, b, c, d) \
- { .name = a, .ctrl_dev_name = b, .function = c, .group = d, \
- .hog_on_boot = true }
+#define PIN_MAP_MUX_GROUP_DEFAULT(dev, pinctrl, grp, func) \
+ PIN_MAP_MUX_GROUP(dev, PINCTRL_STATE_DEFAULT, pinctrl, grp, func)
+
+#define PIN_MAP_MUX_GROUP_HOG(dev, state, grp, func) \
+ PIN_MAP_MUX_GROUP(dev, state, dev, grp, func)
+
+#define PIN_MAP_MUX_GROUP_HOG_DEFAULT(dev, grp, func) \
+ PIN_MAP_MUX_GROUP(dev, PINCTRL_STATE_DEFAULT, dev, grp, func)
+
+#define PIN_MAP_CONFIGS_PIN(dev, state, pinctrl, pin, cfgs) \
+ { \
+ .dev_name = dev, \
+ .name = state, \
+ .type = PIN_MAP_TYPE_CONFIGS_PIN, \
+ .ctrl_dev_name = pinctrl, \
+ .data.configs = { \
+ .group_or_pin = pin, \
+ .configs = cfgs, \
+ .num_configs = ARRAY_SIZE(cfgs), \
+ }, \
+ }
+
+#define PIN_MAP_CONFIGS_PIN_DEFAULT(dev, pinctrl, pin, cfgs) \
+ PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_DEFAULT, pinctrl, pin, cfgs)
+
+#define PIN_MAP_CONFIGS_PIN_HOG(dev, state, pin, cfgs) \
+ PIN_MAP_CONFIGS_PIN(dev, state, dev, pin, cfgs)
+
+#define PIN_MAP_CONFIGS_PIN_HOG_DEFAULT(dev, pin, cfgs) \
+ PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_DEFAULT, dev, pin, cfgs)
+
+#define PIN_MAP_CONFIGS_GROUP(dev, state, pinctrl, grp, cfgs) \
+ { \
+ .dev_name = dev, \
+ .name = state, \
+ .type = PIN_MAP_TYPE_CONFIGS_GROUP, \
+ .ctrl_dev_name = pinctrl, \
+ .data.configs = { \
+ .group_or_pin = grp, \
+ .configs = cfgs, \
+ .num_configs = ARRAY_SIZE(cfgs), \
+ }, \
+ }
+
+#define PIN_MAP_CONFIGS_GROUP_DEFAULT(dev, pinctrl, grp, cfgs) \
+ PIN_MAP_CONFIGS_GROUP(dev, PINCTRL_STATE_DEFAULT, pinctrl, grp, cfgs)
+
+#define PIN_MAP_CONFIGS_GROUP_HOG(dev, state, grp, cfgs) \
+ PIN_MAP_CONFIGS_GROUP(dev, state, dev, grp, cfgs)
+
+#define PIN_MAP_CONFIGS_GROUP_HOG_DEFAULT(dev, grp, cfgs) \
+ PIN_MAP_CONFIGS_GROUP(dev, PINCTRL_STATE_DEFAULT, dev, grp, cfgs)
#ifdef CONFIG_PINMUX
-extern int pinmux_register_mappings(struct pinmux_map const *map,
+extern int pinctrl_register_mappings(struct pinctrl_map const *map,
unsigned num_maps);
#else
-static inline int pinmux_register_mappings(struct pinmux_map const *map,
+static inline int pinctrl_register_mappings(struct pinctrl_map const *map,
unsigned num_maps)
{
return 0;
diff --git a/include/linux/pinctrl/pinconf.h b/include/linux/pinctrl/pinconf.h
index 477922c..f8cf156 100644
--- a/include/linux/pinctrl/pinconf.h
+++ b/include/linux/pinctrl/pinconf.h
@@ -53,45 +53,6 @@ struct pinconf_ops {
unsigned selector);
};
-extern int pin_config_get(const char *dev_name, const char *name,
- unsigned long *config);
-extern int pin_config_set(const char *dev_name, const char *name,
- unsigned long config);
-extern int pin_config_group_get(const char *dev_name,
- const char *pin_group,
- unsigned long *config);
-extern int pin_config_group_set(const char *dev_name,
- const char *pin_group,
- unsigned long config);
-
-#else
-
-static inline int pin_config_get(const char *dev_name, const char *name,
- unsigned long *config)
-{
- return 0;
-}
-
-static inline int pin_config_set(const char *dev_name, const char *name,
- unsigned long config)
-{
- return 0;
-}
-
-static inline int pin_config_group_get(const char *dev_name,
- const char *pin_group,
- unsigned long *config)
-{
- return 0;
-}
-
-static inline int pin_config_group_set(const char *dev_name,
- const char *pin_group,
- unsigned long config)
-{
- return 0;
-}
-
#endif
#endif /* __LINUX_PINCTRL_PINCONF_H */
diff --git a/include/linux/pinctrl/pinctrl-state.h b/include/linux/pinctrl/pinctrl-state.h
new file mode 100644
index 0000000..3920e28
--- /dev/null
+++ b/include/linux/pinctrl/pinctrl-state.h
@@ -0,0 +1,6 @@
+/*
+ * Standard pin control state definitions
+ */
+
+#define PINCTRL_STATE_DEFAULT "default"
+#define PINCTRL_STATE_IDLE "idle"
diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h
index 8bd22ee..4e9f078 100644
--- a/include/linux/pinctrl/pinctrl.h
+++ b/include/linux/pinctrl/pinctrl.h
@@ -15,10 +15,11 @@
#ifdef CONFIG_PINCTRL
#include <linux/radix-tree.h>
-#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/seq_file.h>
+#include "pinctrl-state.h"
+struct device;
struct pinctrl_dev;
struct pinmux_ops;
struct pinconf_ops;
diff --git a/include/linux/pinctrl/pinmux.h b/include/linux/pinctrl/pinmux.h
index 937b3e2..47e9237 100644
--- a/include/linux/pinctrl/pinmux.h
+++ b/include/linux/pinctrl/pinmux.h
@@ -16,9 +16,6 @@
#include <linux/seq_file.h>
#include "pinctrl.h"
-/* This struct is private to the core and should be regarded as a cookie */
-struct pinmux;
-
#ifdef CONFIG_PINMUX
struct pinctrl_dev;
@@ -88,55 +85,6 @@ struct pinmux_ops {
bool input);
};
-/* External interface to pinmux */
-extern int pinmux_request_gpio(unsigned gpio);
-extern void pinmux_free_gpio(unsigned gpio);
-extern int pinmux_gpio_direction_input(unsigned gpio);
-extern int pinmux_gpio_direction_output(unsigned gpio);
-extern struct pinmux * __must_check pinmux_get(struct device *dev, const char *name);
-extern void pinmux_put(struct pinmux *pmx);
-extern int pinmux_enable(struct pinmux *pmx);
-extern void pinmux_disable(struct pinmux *pmx);
-
-#else /* !CONFIG_PINMUX */
-
-static inline int pinmux_request_gpio(unsigned gpio)
-{
- return 0;
-}
-
-static inline void pinmux_free_gpio(unsigned gpio)
-{
-}
-
-static inline int pinmux_gpio_direction_input(unsigned gpio)
-{
- return 0;
-}
-
-static inline int pinmux_gpio_direction_output(unsigned gpio)
-{
- return 0;
-}
-
-static inline struct pinmux * __must_check pinmux_get(struct device *dev, const char *name)
-{
- return NULL;
-}
-
-static inline void pinmux_put(struct pinmux *pmx)
-{
-}
-
-static inline int pinmux_enable(struct pinmux *pmx)
-{
- return 0;
-}
-
-static inline void pinmux_disable(struct pinmux *pmx)
-{
-}
-
#endif /* CONFIG_PINMUX */
#endif /* __LINUX_PINCTRL_PINMUX_H */
OpenPOWER on IntegriCloud