Commit 7fc86a79 authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pinctrl-for-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl

Pull pinctrl updates for v3.4 from Linus Walleij (*):
 - Switches the PXA 168, 910 and MMP over to use pinctrl
 - Locking revamped
 - Massive refactorings...
 - Reform the driver API to use multiple states
 - Support pin config in the mapping tables
 - Pinctrl drivers for the nVidia Tegra series
 - Generic pin config support lib for simple pin controllers
 - Implement pin config for the U300

* tag 'pinctrl-for-3.4' of git://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-pinctrl: (48 commits)
  ARM: u300: configure some pins as an example
  pinctrl: support pinconfig on the U300
  pinctrl/coh901: use generic pinconf enums and parameters
  pinctrl: introduce generic pin config
  pinctrl: fix error path in pinconf_map_to_setting()
  pinctrl: allow concurrent gpio and mux function ownership of pins
  pinctrl: forward-declare struct device
  pinctrl: split pincontrol states into its own header
  pinctrl: include machine header to core.h
  ARM: tegra: Select PINCTRL Kconfig variables
  pinctrl: add a driver for NVIDIA Tegra
  pinctrl: Show selected function and group in pinmux-pins debugfs
  pinctrl: enhance mapping table to support pin config operations
  pinctrl: API changes to support multiple states per device
  pinctrl: add usecount to pins for muxing
  pinctrl: refactor struct pinctrl handling in core.c vs pinmux.c
  pinctrl: fix and simplify locking
  pinctrl: fix the pin descriptor kerneldoc
  pinctrl: assume map table entries can't have a NULL name field
  pinctrl: introduce PINCTRL_STATE_DEFAULT, define hogs as that state
  ...

(*) What is it with all these Linuses these days? There's a Linus at
    google too.  Some day I will get myself my own broadsword, and run
    around screaming "There can be only one".

    I used to be _special_ dammit. Snif.
parents 90597b6c 51dddfe8
...@@ -206,12 +206,21 @@ using a certain resistor value - pull up and pull down - so that the pin has a ...@@ -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 stable value when nothing is driving the rail it is connected to, or when it's
unconnected. 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); 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 The format and meaning of the configuration parameter, PLATFORM_X_PULL_UP
changing pin configuration in the pin controller ops like this: 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/pinctrl.h>
#include <linux/pinctrl/pinconf.h> #include <linux/pinctrl/pinconf.h>
...@@ -492,14 +501,10 @@ Definitions: ...@@ -492,14 +501,10 @@ Definitions:
{"map-i2c0", i2c0, pinctrl0, fi2c0, gi2c0} {"map-i2c0", i2c0, pinctrl0, fi2c0, gi2c0}
} }
Every map must be assigned a symbolic name, pin controller and function. Every map must be assigned a state name, pin controller, device and
The group is not compulsory - if it is omitted the first group presented by function. The group is not compulsory - if it is omitted the first group
the driver as applicable for the function will be selected, which is presented by the driver as applicable for the function will be selected,
useful for simple cases. 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.
It is possible to map several groups to the same combination of device, 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 pin controller and function. This is for cases where a certain function on
...@@ -726,19 +731,19 @@ same time. ...@@ -726,19 +731,19 @@ same time.
All the above functions are mandatory to implement for a pinmux driver. 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() The public pinmux API contains two functions named pinctrl_request_gpio()
and pinmux_free_gpio(). These two functions shall *ONLY* be called from and pinctrl_free_gpio(). These two functions shall *ONLY* be called from
gpiolib-based drivers as part of their gpio_request() and 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] shall only be called from within respective gpio_direction_[input|output]
gpiolib implementation. gpiolib implementation.
NOTE that platforms and individual drivers shall *NOT* request GPIO pins to be 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 controlled e.g. muxed in. Instead, implement a proper gpiolib driver and have
request proper muxing for its pins. that driver request proper muxing and other control for its pins.
The function list could become long, especially if you can convert every 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 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. ...@@ -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 In this case, the function array would become 64 entries for each GPIO
setting and then the device functions. 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 to enable only GPIO on an individual pin: .gpio_request_enable() and
.gpio_disable_free(). .gpio_disable_free().
...@@ -762,12 +767,12 @@ gpiolib driver and the affected GPIO range, pin offset and desired direction ...@@ -762,12 +767,12 @@ gpiolib driver and the affected GPIO range, pin offset and desired direction
will be passed along to this function. will be passed along to this function.
Alternatively to using these special functions, it is fully allowed to use 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 obtain the function "gpioN" where "N" is the global GPIO pin number if no
special GPIO-handler is registered. special GPIO-handler is registered.
Pinmux board/machine configuration Board/machine configuration
================================== ==================================
Boards and machines define how a certain complete running system is put 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 ...@@ -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 constrained and how the clock tree looks. Of course pinmux settings are also
part of this. part of this.
A pinmux config for a machine looks pretty much like a simple regulator A pin controller configuration for a machine looks pretty much like a simple
configuration, so for the example array above we want to enable i2c and regulator configuration, so for the example array above we want to enable i2c
spi on the second function mapping: and spi on the second function mapping:
#include <linux/pinctrl/machine.h> #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", .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", .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", .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. ...@@ -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 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 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 to map.
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.
You register this pinmux mapping to the pinmux subsystem by simply: 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 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 it even more compact which assumes you want to use pinctrl-foo and position
0 for mapping, for example: 0 for mapping, for example:
static struct pinmux_map __initdata pmx_mapping[] = { static struct pinctrl_map __initdata mapping[] = {
PINMUX_MAP("I2CMAP", "pinctrl-foo", "i2c0", "foo-i2c.0"), 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 ...@@ -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", .name = "spi0-pos-A",
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo", .ctrl_dev_name = "pinctrl-foo",
.function = "spi0", .function = "spi0",
.group = "spi0_0_grp", .group = "spi0_0_grp",
.dev_name = "foo-spi.0",
}, },
{ {
.dev_name = "foo-spi.0",
.name = "spi0-pos-B", .name = "spi0-pos-B",
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo", .ctrl_dev_name = "pinctrl-foo",
.function = "spi0", .function = "spi0",
.group = "spi0_1_grp", .group = "spi0_1_grp",
.dev_name = "foo-spi.0",
}, },
... ...
This example mapping is used to switch between two positions for spi0 at This example mapping is used to switch between two positions for spi0 at
runtime, as described further below under the heading "Runtime pinmuxing". runtime, as described further below under the heading "Runtime pinmuxing".
Further it is possible to match several groups of pins to the same function Further it is possible for one named state to affect the muxing of several
for a single device, say for example in the mmc0 example above, where you can 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 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 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: case), we define a mapping like this:
... ...
{ {
.dev_name = "foo-mmc.0",
.name = "2bit" .name = "2bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo", .ctrl_dev_name = "pinctrl-foo",
.function = "mmc0", .function = "mmc0",
.group = "mmc0_1_grp", .group = "mmc0_1_grp",
.dev_name = "foo-mmc.0",
}, },
{ {
.dev_name = "foo-mmc.0",
.name = "4bit" .name = "4bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo", .ctrl_dev_name = "pinctrl-foo",
.function = "mmc0", .function = "mmc0",
.group = "mmc0_1_grp", .group = "mmc0_1_grp",
.dev_name = "foo-mmc.0",
}, },
{ {
.dev_name = "foo-mmc.0",
.name = "4bit" .name = "4bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo", .ctrl_dev_name = "pinctrl-foo",
.function = "mmc0", .function = "mmc0",
.group = "mmc0_2_grp", .group = "mmc0_2_grp",
.dev_name = "foo-mmc.0",
}, },
{ {
.dev_name = "foo-mmc.0",
.name = "8bit" .name = "8bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo", .ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_1_grp", .group = "mmc0_1_grp",
.dev_name = "foo-mmc.0",
}, },
{ {
.dev_name = "foo-mmc.0",
.name = "8bit" .name = "8bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo", .ctrl_dev_name = "pinctrl-foo",
.function = "mmc0", .function = "mmc0",
.group = "mmc0_2_grp", .group = "mmc0_2_grp",
.dev_name = "foo-mmc.0",
}, },
{ {
.dev_name = "foo-mmc.0",
.name = "8bit" .name = "8bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo", .ctrl_dev_name = "pinctrl-foo",
.function = "mmc0", .function = "mmc0",
.group = "mmc0_3_grp", .group = "mmc0_3_grp",
.dev_name = "foo-mmc.0",
}, },
... ...
The result of grabbing this mapping from the device with something like The result of grabbing this mapping from the device with something like
this (see next paragraph): 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 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 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 all get selected, and they all get enabled and disable simultaneously by the
pinmux core. pinmux core.
...@@ -914,97 +970,111 @@ pinmux core. ...@@ -914,97 +970,111 @@ pinmux core.
Pinmux requests from drivers Pinmux requests from drivers
============================ ============================
Generally it is discouraged to let individual drivers get and enable pinmuxes. Generally it is discouraged to let individual drivers get and enable pin
So if possible, handle the pinmuxes in platform code or some other place where control. So if possible, handle the pin control in platform code or some other
you have access to all the affected struct device * pointers. In some cases place where you have access to all the affected struct device * pointers. In
where a driver needs to switch between different mux mappings at runtime some cases where a driver needs to e.g. switch between different mux mappings
this is not possible. at runtime this is not possible.
A driver may request a certain mux to be activated, usually just the default A driver may request a certain control state to be activated, usually just the
mux like this: default state like this:
#include <linux/pinctrl/pinmux.h> #include <linux/pinctrl/consumer.h>
struct foo_state { struct foo_state {
struct pinmux *pmx; struct pinctrl *p;
struct pinctrl_state *s;
... ...
}; };
foo_probe() foo_probe()
{ {
/* Allocate a state holder named "state" etc */ /* Allocate a state holder named "foo" etc */
struct pinmux pmx; 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); foo->s = pinctrl_lookup_state(foo->p, PINCTRL_STATE_DEFAULT);
if IS_ERR(pmx) if (IS_ERR(foo->s)) {
return PTR_ERR(pmx); pinctrl_put(foo->p);
pinmux_enable(pmx); /* 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() foo_remove()
{ {
pinmux_disable(state->pmx); pinctrl_put(state->p);
pinmux_put(state->pmx);
} }
If you want to grab a specific mux mapping and not just the first one found for This get/lookup/select/put sequence can just as well be handled by bus drivers
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
if you don't want each and every driver to handle it and you know the if you don't want each and every driver to handle it and you know the
arrangement on your bus. 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 - pinctrl_lookup_state() is called in process context to obtain a handle to a
a certain mapping and set up the pinmux core and the driver. It will allocate specific state for a the client device. This operation may be slow too.
a struct from the kernel memory to hold the pinmux state.
- pinmux_enable()/pinmux_disable() is quick and can be called from fastpath - pinctrl_select_state() programs pin controller hardware according to the
(irq context) when you quickly want to set up/tear down the hardware muxing definition of the state as given by the mapping table. In theory this is a
when running a device driver. Usually it will just poke some values into a fast-path operation, since it only involved blasting some register settings
register. 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 - pinctrl_put() frees all information associated with a pinctrl handle.
and release the state holder struct for the mux setting.
Usually the pinmux core handled the get/put pair and call out to the device Usually the pin control core handled the get/put pair and call out to the
drivers bookkeeping operations, like checking available functions and the device drivers bookkeeping operations, like checking available functions and
associated pins, whereas the enable/disable pass on to the pin controller 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 driver which takes care of activating and/or deactivating the mux setting by
quickly poking some registers. 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. 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 Pin control map entries can be hogged by the core when the pin controller
associated with it, can be hogged by the core when the pin controller is is registered. This means that the core will attempt to call pinctrl_get(),
registered. This means that the core will attempt to call pinmux_get() and lookup_state() and select_state() on it immediately after the pin control
pinmux_enable() on it immediately after the pin control device has been device has been registered.
registered.
This is enabled by simply setting the .hog_on_boot field in the map to true, This occurs for mapping table entries where the client device name is equal
like this: 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", .ctrl_dev_name = "pinctrl-foo",
.function = "power_func", .function = "power_func",
.hog_on_boot = true,
}, },
Since it may be common to request the core to hog a few always-applicable 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 mux settings on the primary pin controller, there is a convenience macro for
this: 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. 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 ...@@ -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 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 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 function, but with different named in the mapping as described under
"Advanced mapping" above. So we have two mappings named "spi0-pos-A" and "Advanced mapping" above. So that for an SPI device, we have two states named
"spi0-pos-B". "pos-A" and "pos-B".
This snippet first muxes the function in the pins defined by group A, enables 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: it, disables and releases it, and muxes it in on the pins defined by group B:
#include <linux/pinctrl/consumer.h>
foo_switch() 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 */ /* Enable on position A */
pmx = pinmux_get(&device, "spi0-pos-A"); ret = pinctrl_select_state(s1);
if IS_ERR(pmx) if (ret < 0)
return PTR_ERR(pmx); ...
pinmux_enable(pmx);
/* This releases the pins again */ ...
pinmux_disable(pmx);
pinmux_put(pmx);
/* Enable on position B */ /* Enable on position B */
pmx = pinmux_get(&device, "spi0-pos-B"); ret = pinctrl_select_state(s2);
if IS_ERR(pmx) if (ret < 0)
return PTR_ERR(pmx); ...
pinmux_enable(pmx);
... ...
pinctrl_put(p);
} }
The above has to be done from process context. The above has to be done from process context.
...@@ -7,6 +7,8 @@ config ARCH_TEGRA_2x_SOC ...@@ -7,6 +7,8 @@ config ARCH_TEGRA_2x_SOC
select CPU_V7 select CPU_V7
select ARM_GIC select ARM_GIC
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select PINCTRL
select PINCTRL_TEGRA20
select USB_ARCH_HAS_EHCI if USB_SUPPORT select USB_ARCH_HAS_EHCI if USB_SUPPORT
select USB_ULPI if USB_SUPPORT select USB_ULPI if USB_SUPPORT
select USB_ULPI_VIEWPORT if USB_SUPPORT select USB_ULPI_VIEWPORT if USB_SUPPORT
...@@ -19,6 +21,8 @@ config ARCH_TEGRA_3x_SOC ...@@ -19,6 +21,8 @@ config ARCH_TEGRA_3x_SOC
select CPU_V7 select CPU_V7
select ARM_GIC select ARM_GIC
select ARCH_REQUIRE_GPIOLIB select ARCH_REQUIRE_GPIOLIB
select PINCTRL
select PINCTRL_TEGRA30
select USB_ARCH_HAS_EHCI if USB_SUPPORT select USB_ARCH_HAS_EHCI if USB_SUPPORT
select USB_ULPI if USB_SUPPORT select USB_ULPI if USB_SUPPORT
select USB_ULPI_VIEWPORT if USB_SUPPORT select USB_ULPI_VIEWPORT if USB_SUPPORT
......
/*
* pinctrl configuration definitions for the NVIDIA Tegra pinmux
*
* Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef __PINCONF_TEGRA_H__
#define __PINCONF_TEGRA_H__
enum tegra_pinconf_param {
/* argument: tegra_pinconf_pull */
TEGRA_PINCONF_PARAM_PULL,
/* argument: tegra_pinconf_tristate */
TEGRA_PINCONF_PARAM_TRISTATE,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_ENABLE_INPUT,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_OPEN_DRAIN,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_LOCK,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_IORESET,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_SCHMITT,
/* argument: Boolean */
TEGRA_PINCONF_PARAM_LOW_POWER_MODE,
/* argument: Integer, range is HW-dependant */
TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH,
/* argument: Integer, range is HW-dependant */
TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH,
/* argument: Integer, range is HW-dependant */
TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING,
/* argument: Integer, range is HW-dependant */
TEGRA_PINCONF_PARAM_SLEW_RATE_RISING,
};
enum tegra_pinconf_pull {
TEGRA_PINCONFIG_PULL_NONE,
TEGRA_PINCONFIG_PULL_DOWN,
TEGRA_PINCONFIG_PULL_UP,
};
enum tegra_pinconf_tristate {
TEGRA_PINCONFIG_DRIVEN,
TEGRA_PINCONFIG_TRISTATE,
};
#define TEGRA_PINCONF_PACK(_param_, _arg_) ((_param_) << 16 | (_arg_))
#define TEGRA_PINCONF_UNPACK_PARAM(_conf_) ((_conf_) >> 16)
#define TEGRA_PINCONF_UNPACK_ARG(_conf_) ((_conf_) & 0xffff)
#endif
...@@ -26,7 +26,8 @@ ...@@ -26,7 +26,8 @@
#include <linux/mtd/nand.h> #include <linux/mtd/nand.h>
#include <linux/mtd/fsmc.h> #include <linux/mtd/fsmc.h>
#include <linux/pinctrl/machine.h> #include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinmux.h> #include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/dma-mapping.h> #include <linux/dma-mapping.h>
#include <asm/types.h> #include <asm/types.h>
...@@ -1477,7 +1478,7 @@ static struct coh901318_platform coh901318_platform = { ...@@ -1477,7 +1478,7 @@ static struct coh901318_platform coh901318_platform = {
.max_channels = U300_DMA_CHANNELS, .max_channels = U300_DMA_CHANNELS,
}; };
static struct resource pinmux_resources[] = { static struct resource pinctrl_resources[] = {
{ {
.start = U300_SYSCON_BASE, .start = U300_SYSCON_BASE,
.end = U300_SYSCON_BASE + SZ_4K - 1, .end = U300_SYSCON_BASE + SZ_4K - 1,
...@@ -1506,6 +1507,13 @@ static struct platform_device i2c1_device = { ...@@ -1506,6 +1507,13 @@ static struct platform_device i2c1_device = {
.resource = i2c1_resources, .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 * The different variants have a few different versions of the
* GPIO block, with different number of ports. * GPIO block, with different number of ports.
...@@ -1525,6 +1533,7 @@ static struct u300_gpio_platform u300_gpio_plat = { ...@@ -1525,6 +1533,7 @@ static struct u300_gpio_platform u300_gpio_plat = {
#endif #endif
.gpio_base = 0, .gpio_base = 0,
.gpio_irq_base = IRQ_U300_GPIO_BASE, .gpio_irq_base = IRQ_U300_GPIO_BASE,
.pinctrl_device = &pinctrl_device,
}; };
static struct platform_device gpio_device = { static struct platform_device gpio_device = {
...@@ -1597,71 +1606,67 @@ static struct platform_device dma_device = { ...@@ -1597,71 +1606,67 @@ static struct platform_device dma_device = {
}, },
}; };
static struct platform_device pinmux_device = { static unsigned long pin_pullup_conf[] = {
.name = "pinmux-u300", PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 1),
.id = -1,
.num_resources = ARRAY_SIZE(pinmux_resources),
.resource = pinmux_resources,
}; };
/* Pinmux settings */ static unsigned long pin_highz_conf[] = {
static struct pinmux_map __initdata u300_pinmux_map[] = { PIN_CONF_PACKED(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, 0),
};
/* Pin control settings */
static struct pinctrl_map __initdata u300_pinmux_map[] = {
/* anonymous maps for chip power and EMIFs */ /* anonymous maps for chip power and EMIFs */
PINMUX_MAP_SYS_HOG("POWER", "pinmux-u300", "power"), PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "power"),
PINMUX_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"), PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif0"),
PINMUX_MAP_SYS_HOG("EMIF1", "pinmux-u300", "emif1"), PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif1"),
/* per-device maps for MMC/SD, SPI and UART */ /* per-device maps for MMC/SD, SPI and UART */
PINMUX_MAP("MMCSD", "pinmux-u300", "mmc0", "mmci"), PIN_MAP_MUX_GROUP_DEFAULT("mmci", "pinctrl-u300", NULL, "mmc0"),
PINMUX_MAP("SPI", "pinmux-u300", "spi0", "pl022"), PIN_MAP_MUX_GROUP_DEFAULT("pl022", "pinctrl-u300", NULL, "spi0"),
PINMUX_MAP("UART0", "pinmux-u300", "uart0", "uart0"), PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-u300", NULL, "uart0"),
/* This pin is used for clock return rather than GPIO */
PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO APP GPIO 11",
pin_pullup_conf),
/* This pin is used for card detect */
PIN_MAP_CONFIGS_PIN_DEFAULT("mmci", "pinctrl-u300", "PIO MS INS",
pin_highz_conf),
}; };
struct u300_mux_hog { struct u300_mux_hog {
const char *name;
struct device *dev; struct device *dev;
struct pinmux *pmx; struct pinctrl *p;
}; };
static struct u300_mux_hog u300_mux_hogs[] = { static struct u300_mux_hog u300_mux_hogs[] = {
{ {
.name = "uart0",
.dev = &uart0_device.dev, .dev = &uart0_device.dev,
}, },
{ {
.name = "spi0",
.dev = &pl022_device.dev, .dev = &pl022_device.dev,
}, },
{ {
.name = "mmc0",
.dev = &mmcsd_device.dev, .dev = &mmcsd_device.dev,
}, },
}; };
static int __init u300_pinmux_fetch(void) static int __init u300_pinctrl_fetch(void)
{ {
int i; int i;
for (i = 0; i < ARRAY_SIZE(u300_mux_hogs); 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); p = pinctrl_get_select_default(u300_mux_hogs[i].dev);
if (IS_ERR(pmx)) { if (IS_ERR(p)) {
pr_err("u300: could not get pinmux hog %s\n", pr_err("u300: could not get pinmux hog for dev %s\n",
u300_mux_hogs[i].name); dev_name(u300_mux_hogs[i].dev));
continue;
}
ret = pinmux_enable(pmx);
if (ret) {
pr_err("u300: could enable pinmux hog %s\n",
u300_mux_hogs[i].name);
continue; continue;
} }
u300_mux_hogs[i].pmx = pmx; u300_mux_hogs[i].p = p;
} }
return 0; return 0;
} }
subsys_initcall(u300_pinmux_fetch); subsys_initcall(u300_pinctrl_fetch);
/* /*
* Notice that AMBA devices are initialized before platform devices. * Notice that AMBA devices are initialized before platform devices.
...@@ -1676,7 +1681,6 @@ static struct platform_device *platform_devs[] __initdata = { ...@@ -1676,7 +1681,6 @@ static struct platform_device *platform_devs[] __initdata = {
&gpio_device, &gpio_device,
&nand_device, &nand_device,
&wdog_device, &wdog_device,
&pinmux_device,
}; };
/* /*
...@@ -1861,8 +1865,8 @@ void __init u300_init_devices(void) ...@@ -1861,8 +1865,8 @@ void __init u300_init_devices(void)
u300_assign_physmem(); u300_assign_physmem();
/* Initialize pinmuxing */ /* Initialize pinmuxing */
pinmux_register_mappings(u300_pinmux_map, pinctrl_register_mappings(u300_pinmux_map,
ARRAY_SIZE(u300_pinmux_map)); ARRAY_SIZE(u300_pinmux_map));
/* Register subdevices on the I2C buses */ /* Register subdevices on the I2C buses */
u300_i2c_register_board_devices(); u300_i2c_register_board_devices();
......
...@@ -24,12 +24,14 @@ enum u300_gpio_variant { ...@@ -24,12 +24,14 @@ enum u300_gpio_variant {
* @ports: number of GPIO block ports * @ports: number of GPIO block ports
* @gpio_base: first GPIO number for this block (use a free range) * @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) * @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 { struct u300_gpio_platform {
enum u300_gpio_variant variant; enum u300_gpio_variant variant;
u8 ports; u8 ports;
int gpio_base; int gpio_base;
int gpio_irq_base; int gpio_irq_base;
struct platform_device *pinctrl_device;
}; };
#endif /* __MACH_U300_GPIO_U300_H */ #endif /* __MACH_U300_GPIO_U300_H */
...@@ -17,21 +17,63 @@ config PINMUX ...@@ -17,21 +17,63 @@ config PINMUX
config PINCONF config PINCONF
bool "Support pin configuration controllers" bool "Support pin configuration controllers"
config GENERIC_PINCONF
bool
select PINCONF
config DEBUG_PINCTRL config DEBUG_PINCTRL
bool "Debug PINCTRL calls" bool "Debug PINCTRL calls"
depends on DEBUG_KERNEL depends on DEBUG_KERNEL
help help
Say Y here to add some extra checks and diagnostics to PINCTRL calls. 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 config PINCTRL_SIRF
bool "CSR SiRFprimaII pin controller driver" bool "CSR SiRFprimaII pin controller driver"
depends on ARCH_PRIMA2 depends on ARCH_PRIMA2
select PINMUX select PINMUX
config PINCTRL_TEGRA
bool
config PINCTRL_TEGRA20
bool
select PINMUX
select PINCONF
select PINCTRL_TEGRA
config PINCTRL_TEGRA30
bool
select PINMUX
select PINCONF
select PINCTRL_TEGRA
config PINCTRL_U300 config PINCTRL_U300
bool "U300 pin controller driver" bool "U300 pin controller driver"
depends on ARCH_U300 depends on ARCH_U300
select PINMUX select PINMUX
select GENERIC_PINCONF
config PINCTRL_COH901 config PINCTRL_COH901
bool "ST-Ericsson U300 COH 901 335/571 GPIO" bool "ST-Ericsson U300 COH 901 335/571 GPIO"
......
...@@ -5,6 +5,14 @@ ccflags-$(CONFIG_DEBUG_PINCTRL) += -DDEBUG ...@@ -5,6 +5,14 @@ ccflags-$(CONFIG_DEBUG_PINCTRL) += -DDEBUG
obj-$(CONFIG_PINCTRL) += core.o obj-$(CONFIG_PINCTRL) += core.o
obj-$(CONFIG_PINMUX) += pinmux.o obj-$(CONFIG_PINMUX) += pinmux.o
obj-$(CONFIG_PINCONF) += pinconf.o obj-$(CONFIG_PINCONF) += pinconf.o
obj-$(CONFIG_GENERIC_PINCONF) += pinconf-generic.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_SIRF) += pinctrl-sirf.o
obj-$(CONFIG_PINCTRL_TEGRA) += pinctrl-tegra.o
obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o
obj-$(CONFIG_PINCTRL_TEGRA30) += pinctrl-tegra30.o
obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o
obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o
/* /*
* Core driver for the pin control subsystem * 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 * Written on behalf of Linaro for ST-Ericsson
* Based on bits of regulator core, gpio core and clk core * Based on bits of regulator core, gpio core and clk core
* *
* Author: Linus Walleij <linus.walleij@linaro.org> * Author: Linus Walleij <linus.walleij@linaro.org>
* *
* Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
*
* License terms: GNU General Public License (GPL) version 2 * License terms: GNU General Public License (GPL) version 2
*/ */
#define pr_fmt(fmt) "pinctrl core: " fmt #define pr_fmt(fmt) "pinctrl core: " fmt
...@@ -16,11 +18,8 @@ ...@@ -16,11 +18,8 @@
#include <linux/init.h> #include <linux/init.h>
#include <linux/device.h> #include <linux/device.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/radix-tree.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
...@@ -30,10 +29,36 @@ ...@@ -30,10 +29,36 @@
#include "pinmux.h" #include "pinmux.h"
#include "pinconf.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); 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) const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev)
{ {
/* We're not allowed to register devices without name */ /* We're not allowed to register devices without name */
...@@ -48,53 +73,31 @@ void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev) ...@@ -48,53 +73,31 @@ void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev)
EXPORT_SYMBOL_GPL(pinctrl_dev_get_drvdata); EXPORT_SYMBOL_GPL(pinctrl_dev_get_drvdata);
/** /**
* get_pinctrl_dev_from_dev() - look up pin controller device * get_pinctrl_dev_from_devname() - look up pin controller device
* @dev: a device pointer, this may be NULL but then devname needs to be * @devname: the name of a device instance, as returned by dev_name()
* 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
* *
* Looks up a pin control device matching a certain device name or pure device * Looks up a pin control device matching a certain device name or pure device
* pointer, the pure device pointer will take precedence. * pointer, the pure device pointer will take precedence.
*/ */
struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname)
const char *devname)
{ {
struct pinctrl_dev *pctldev = NULL; struct pinctrl_dev *pctldev = NULL;
bool found = false; bool found = false;
mutex_lock(&pinctrldev_list_mutex); if (!devname)
list_for_each_entry(pctldev, &pinctrldev_list, node) { return NULL;
if (dev && pctldev->dev == dev) {
/* Matched on device pointer */
found = true;
break;
}
if (devname && list_for_each_entry(pctldev, &pinctrldev_list, node) {
!strcmp(dev_name(pctldev->dev), devname)) { if (!strcmp(dev_name(pctldev->dev), devname)) {
/* Matched on device name */ /* Matched on device name */
found = true; found = true;
break; break;
} }
} }
mutex_unlock(&pinctrldev_list_mutex);
return found ? pctldev : NULL; 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 * pin_get_from_name() - look up a pin number from a name
* @pctldev: the pin control device to lookup the pin on * @pctldev: the pin control device to lookup the pin on
...@@ -135,11 +138,11 @@ bool pin_is_valid(struct pinctrl_dev *pctldev, int pin) ...@@ -135,11 +138,11 @@ bool pin_is_valid(struct pinctrl_dev *pctldev, int pin)
if (pin < 0) if (pin < 0)
return false; return false;
mutex_lock(&pinctrl_mutex);
pindesc = pin_desc_get(pctldev, pin); pindesc = pin_desc_get(pctldev, pin);
if (pindesc == NULL) mutex_unlock(&pinctrl_mutex);
return false;
return true; return pindesc != NULL;
} }
EXPORT_SYMBOL_GPL(pin_is_valid); EXPORT_SYMBOL_GPL(pin_is_valid);
...@@ -150,7 +153,6 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev, ...@@ -150,7 +153,6 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev,
{ {
int i; int i;
spin_lock(&pctldev->pin_desc_tree_lock);
for (i = 0; i < num_pins; i++) { for (i = 0; i < num_pins; i++) {
struct pin_desc *pindesc; struct pin_desc *pindesc;
...@@ -164,7 +166,6 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev, ...@@ -164,7 +166,6 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev,
} }
kfree(pindesc); kfree(pindesc);
} }
spin_unlock(&pctldev->pin_desc_tree_lock);
} }
static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
...@@ -180,10 +181,10 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, ...@@ -180,10 +181,10 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
} }
pindesc = kzalloc(sizeof(*pindesc), GFP_KERNEL); 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; return -ENOMEM;
}
spin_lock_init(&pindesc->lock);
/* Set owner */ /* Set owner */
pindesc->pctldev = pctldev; pindesc->pctldev = pctldev;
...@@ -198,9 +199,7 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, ...@@ -198,9 +199,7 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev,
pindesc->dynamic_name = true; pindesc->dynamic_name = true;
} }
spin_lock(&pctldev->pin_desc_tree_lock);
radix_tree_insert(&pctldev->pin_desc_tree, number, pindesc); 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", pr_debug("registered pin %d (%s) on %s\n",
number, pindesc->name, pctldev->desc->name); number, pindesc->name, pctldev->desc->name);
return 0; return 0;
...@@ -237,16 +236,13 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio) ...@@ -237,16 +236,13 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio)
struct pinctrl_gpio_range *range = NULL; struct pinctrl_gpio_range *range = NULL;
/* Loop over the ranges */ /* Loop over the ranges */
mutex_lock(&pctldev->gpio_ranges_lock);
list_for_each_entry(range, &pctldev->gpio_ranges, node) { list_for_each_entry(range, &pctldev->gpio_ranges, node) {
/* Check if we're in the valid range */ /* Check if we're in the valid range */
if (gpio >= range->base && if (gpio >= range->base &&
gpio < range->base + range->npins) { gpio < range->base + range->npins) {
mutex_unlock(&pctldev->gpio_ranges_lock);
return range; return range;
} }
} }
mutex_unlock(&pctldev->gpio_ranges_lock);
return NULL; return NULL;
} }
...@@ -261,14 +257,13 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio) ...@@ -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 * the GPIO subsystem, return the device and the matching GPIO range. Returns
* negative if the GPIO range could not be found in any device. * negative if the GPIO range could not be found in any device.
*/ */
int pinctrl_get_device_gpio_range(unsigned gpio, static int pinctrl_get_device_gpio_range(unsigned gpio,
struct pinctrl_dev **outdev, struct pinctrl_dev **outdev,
struct pinctrl_gpio_range **outrange) struct pinctrl_gpio_range **outrange)
{ {
struct pinctrl_dev *pctldev = NULL; struct pinctrl_dev *pctldev = NULL;
/* Loop over the pin controllers */ /* Loop over the pin controllers */
mutex_lock(&pinctrldev_list_mutex);
list_for_each_entry(pctldev, &pinctrldev_list, node) { list_for_each_entry(pctldev, &pinctrldev_list, node) {
struct pinctrl_gpio_range *range; struct pinctrl_gpio_range *range;
...@@ -276,11 +271,9 @@ int pinctrl_get_device_gpio_range(unsigned gpio, ...@@ -276,11 +271,9 @@ int pinctrl_get_device_gpio_range(unsigned gpio,
if (range != NULL) { if (range != NULL) {
*outdev = pctldev; *outdev = pctldev;
*outrange = range; *outrange = range;
mutex_unlock(&pinctrldev_list_mutex);
return 0; return 0;
} }
} }
mutex_unlock(&pinctrldev_list_mutex);
return -EINVAL; return -EINVAL;
} }
...@@ -296,10 +289,11 @@ int pinctrl_get_device_gpio_range(unsigned gpio, ...@@ -296,10 +289,11 @@ int pinctrl_get_device_gpio_range(unsigned gpio,
void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev, void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range) struct pinctrl_gpio_range *range)
{ {
mutex_lock(&pctldev->gpio_ranges_lock); mutex_lock(&pinctrl_mutex);
list_add(&range->node, &pctldev->gpio_ranges); list_add_tail(&range->node, &pctldev->gpio_ranges);
mutex_unlock(&pctldev->gpio_ranges_lock); mutex_unlock(&pinctrl_mutex);
} }
EXPORT_SYMBOL_GPL(pinctrl_add_gpio_range);
/** /**
* pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller * 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, ...@@ -309,10 +303,11 @@ void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev,
void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range) struct pinctrl_gpio_range *range)
{ {
mutex_lock(&pctldev->gpio_ranges_lock); mutex_lock(&pinctrl_mutex);
list_del(&range->node); 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 * pinctrl_get_group_selector() - returns the group selector for a group
...@@ -345,6 +340,531 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev, ...@@ -345,6 +340,531 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
return -EINVAL; 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 #ifdef CONFIG_DEBUG_FS
static int pinctrl_pins_show(struct seq_file *s, void *what) 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) ...@@ -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); 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 */ /* The pin number can be retrived from the pin controller descriptor */
for (i = 0; i < pctldev->desc->npins; i++) { for (i = 0; i < pctldev->desc->npins; i++) {
struct pin_desc *desc; struct pin_desc *desc;
...@@ -375,6 +897,8 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) ...@@ -375,6 +897,8 @@ static int pinctrl_pins_show(struct seq_file *s, void *what)
seq_puts(s, "\n"); seq_puts(s, "\n");
} }
mutex_unlock(&pinctrl_mutex);
return 0; return 0;
} }
...@@ -388,6 +912,8 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) ...@@ -388,6 +912,8 @@ static int pinctrl_groups_show(struct seq_file *s, void *what)
if (!ops) if (!ops)
return 0; return 0;
mutex_lock(&pinctrl_mutex);
seq_puts(s, "registered pin groups:\n"); seq_puts(s, "registered pin groups:\n");
while (ops->list_groups(pctldev, selector) >= 0) { while (ops->list_groups(pctldev, selector) >= 0) {
const unsigned *pins; const unsigned *pins;
...@@ -410,6 +936,7 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) ...@@ -410,6 +936,7 @@ static int pinctrl_groups_show(struct seq_file *s, void *what)
selector++; selector++;
} }
mutex_unlock(&pinctrl_mutex);
return 0; return 0;
} }
...@@ -421,8 +948,9 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) ...@@ -421,8 +948,9 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what)
seq_puts(s, "GPIO ranges handled:\n"); seq_puts(s, "GPIO ranges handled:\n");
mutex_lock(&pinctrl_mutex);
/* Loop over the ranges */ /* Loop over the ranges */
mutex_lock(&pctldev->gpio_ranges_lock);
list_for_each_entry(range, &pctldev->gpio_ranges, node) { list_for_each_entry(range, &pctldev->gpio_ranges, node) {
seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n", seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n",
range->id, range->name, range->id, range->name,
...@@ -430,7 +958,8 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) ...@@ -430,7 +958,8 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what)
range->pin_base, range->pin_base,
(range->pin_base + range->npins - 1)); (range->pin_base + range->npins - 1));
} }
mutex_unlock(&pctldev->gpio_ranges_lock);
mutex_unlock(&pinctrl_mutex);
return 0; return 0;
} }
...@@ -440,7 +969,9 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) ...@@ -440,7 +969,9 @@ static int pinctrl_devices_show(struct seq_file *s, void *what)
struct pinctrl_dev *pctldev; struct pinctrl_dev *pctldev;
seq_puts(s, "name [pinmux] [pinconf]\n"); seq_puts(s, "name [pinmux] [pinconf]\n");
mutex_lock(&pinctrldev_list_mutex);
mutex_lock(&pinctrl_mutex);
list_for_each_entry(pctldev, &pinctrldev_list, node) { list_for_each_entry(pctldev, &pinctrldev_list, node) {
seq_printf(s, "%s ", pctldev->desc->name); seq_printf(s, "%s ", pctldev->desc->name);
if (pctldev->desc->pmxops) if (pctldev->desc->pmxops)
...@@ -453,7 +984,108 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) ...@@ -453,7 +984,108 @@ static int pinctrl_devices_show(struct seq_file *s, void *what)
seq_puts(s, "no"); seq_puts(s, "no");
seq_puts(s, "\n"); 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; return 0;
} }
...@@ -478,6 +1110,16 @@ static int pinctrl_devices_open(struct inode *inode, struct file *file) ...@@ -478,6 +1110,16 @@ static int pinctrl_devices_open(struct inode *inode, struct file *file)
return single_open(file, pinctrl_devices_show, NULL); 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 = { static const struct file_operations pinctrl_pins_ops = {
.open = pinctrl_pins_open, .open = pinctrl_pins_open,
.read = seq_read, .read = seq_read,
...@@ -506,6 +1148,20 @@ static const struct file_operations pinctrl_devices_ops = { ...@@ -506,6 +1148,20 @@ static const struct file_operations pinctrl_devices_ops = {
.release = single_release, .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 struct dentry *debugfs_root;
static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev)
...@@ -547,7 +1203,10 @@ static void pinctrl_init_debugfs(void) ...@@ -547,7 +1203,10 @@ static void pinctrl_init_debugfs(void)
debugfs_create_file("pinctrl-devices", S_IFREG | S_IRUGO, debugfs_create_file("pinctrl-devices", S_IFREG | S_IRUGO,
debugfs_root, NULL, &pinctrl_devices_ops); 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 */ #else /* CONFIG_DEBUG_FS */
...@@ -583,18 +1242,18 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, ...@@ -583,18 +1242,18 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
if (pctldesc->name == NULL) if (pctldesc->name == NULL)
return NULL; return NULL;
pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL); pctldev = kzalloc(sizeof(*pctldev), GFP_KERNEL);
if (pctldev == NULL) if (pctldev == NULL) {
dev_err(dev, "failed to alloc struct pinctrl_dev\n");
return NULL; return NULL;
}
/* Initialize pin control device struct */ /* Initialize pin control device struct */
pctldev->owner = pctldesc->owner; pctldev->owner = pctldesc->owner;
pctldev->desc = pctldesc; pctldev->desc = pctldesc;
pctldev->driver_data = driver_data; pctldev->driver_data = driver_data;
INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL); INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL);
spin_lock_init(&pctldev->pin_desc_tree_lock);
INIT_LIST_HEAD(&pctldev->gpio_ranges); INIT_LIST_HEAD(&pctldev->gpio_ranges);
mutex_init(&pctldev->gpio_ranges_lock);
pctldev->dev = dev; pctldev->dev = dev;
/* If we're implementing pinmuxing, check the ops for sanity */ /* If we're implementing pinmuxing, check the ops for sanity */
...@@ -628,11 +1287,23 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, ...@@ -628,11 +1287,23 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc,
goto out_err; 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); 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; return pctldev;
out_err: out_err:
...@@ -653,15 +1324,20 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) ...@@ -653,15 +1324,20 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev)
return; return;
pinctrl_remove_device_debugfs(pctldev); 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? */ /* TODO: check that no pinmuxes are still active? */
mutex_lock(&pinctrldev_list_mutex);
list_del(&pctldev->node); list_del(&pctldev->node);
mutex_unlock(&pinctrldev_list_mutex);
/* Destroy descriptor tree */ /* Destroy descriptor tree */
pinctrl_free_pindescs(pctldev, pctldev->desc->pins, pinctrl_free_pindescs(pctldev, pctldev->desc->pins,
pctldev->desc->npins); pctldev->desc->npins);
kfree(pctldev); kfree(pctldev);
mutex_unlock(&pinctrl_mutex);
} }
EXPORT_SYMBOL_GPL(pinctrl_unregister); EXPORT_SYMBOL_GPL(pinctrl_unregister);
......
...@@ -9,7 +9,10 @@ ...@@ -9,7 +9,10 @@
* License terms: GNU General Public License (GPL) version 2 * 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/pinconf.h>
#include <linux/pinctrl/machine.h>
struct pinctrl_gpio_range; struct pinctrl_gpio_range;
...@@ -20,34 +23,94 @@ struct pinctrl_gpio_range; ...@@ -20,34 +23,94 @@ struct pinctrl_gpio_range;
* controller * controller
* @pin_desc_tree: each pin descriptor for this pin controller is stored in * @pin_desc_tree: each pin descriptor for this pin controller is stored in
* this radix tree * 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, * @gpio_ranges: a list of GPIO ranges that is handled by this pin controller,
* ranges are added to this list at runtime * 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 * @dev: the device entry for this pin controller
* @owner: module providing the pin controller, used for refcounting * @owner: module providing the pin controller, used for refcounting
* @driver_data: driver data for drivers registering to the pin controller * @driver_data: driver data for drivers registering to the pin controller
* subsystem * subsystem
* @pinmux_hogs_lock: lock for the pinmux hog list * @p: result of pinctrl_get() for this device
* @pinmux_hogs: list of pinmux maps hogged by this device * @device_root: debugfs root for this device
*/ */
struct pinctrl_dev { struct pinctrl_dev {
struct list_head node; struct list_head node;
struct pinctrl_desc *desc; struct pinctrl_desc *desc;
struct radix_tree_root pin_desc_tree; struct radix_tree_root pin_desc_tree;
spinlock_t pin_desc_tree_lock;
struct list_head gpio_ranges; struct list_head gpio_ranges;
struct mutex gpio_ranges_lock;
struct device *dev; struct device *dev;
struct module *owner; struct module *owner;
void *driver_data; void *driver_data;
struct pinctrl *p;
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
struct dentry *device_root; struct dentry *device_root;
#endif #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,38 @@ struct pinctrl_dev { ...@@ -56,28 +119,38 @@ struct pinctrl_dev {
* @name: a name for the pin, e.g. the name of the pin/pad/finger on a * @name: a name for the pin, e.g. the name of the pin/pad/finger on a
* datasheet or such * datasheet or such
* @dynamic_name: if the name of this pin was dynamically allocated * @dynamic_name: if the name of this pin was dynamically allocated
* @lock: a lock to protect the descriptor structure * @mux_usecount: If zero, the pin is not claimed, and @owner should be NULL.
* @mux_requested: whether the pin is already requested by pinmux or not * If non-zero, this pin is claimed by @owner. This field is an integer
* @mux_function: a named muxing function for the pin that will be passed to * rather than a boolean, since pinctrl_get() might process multiple
* subdrivers and shown in debugfs etc * mapping table entries that refer to, and hence claim, the same group
* or pin, and each of these will increment the @usecount.
* @mux_owner: The name of device that called pinctrl_get().
* @mux_setting: The most recent selected mux setting for this pin, if any.
* @gpio_owner: If pinctrl_request_gpio() was called for this pin, this is
* the name of the GPIO that "owns" this pin.
*/ */
struct pin_desc { struct pin_desc {
struct pinctrl_dev *pctldev; struct pinctrl_dev *pctldev;
const char *name; const char *name;
bool dynamic_name; bool dynamic_name;
spinlock_t lock;
/* These fields only added when supporting pinmux drivers */ /* These fields only added when supporting pinmux drivers */
#ifdef CONFIG_PINMUX #ifdef CONFIG_PINMUX
const char *mux_function; unsigned mux_usecount;
const char *mux_owner;
const struct pinctrl_setting_mux *mux_setting;
const char *gpio_owner;
#endif #endif
}; };
struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name);
const char *dev_name);
struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin);
int pin_get_from_name(struct pinctrl_dev *pctldev, const char *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, int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
const char *pin_group); 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;
/*
* Core driver for the generic pin config portions of the pin control subsystem
*
* Copyright (C) 2011 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
* License terms: GNU General Public License (GPL) version 2
*/
#define pr_fmt(fmt) "generic pinconfig core: " fmt
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include "core.h"
#include "pinconf.h"
#ifdef CONFIG_DEBUG_FS
struct pin_config_item {
const enum pin_config_param param;
const char * const display;
const char * const format;
};
#define PCONFDUMP(a, b, c) { .param = a, .display = b, .format = c }
struct pin_config_item conf_items[] = {
PCONFDUMP(PIN_CONFIG_BIAS_DISABLE, "input bias disabled", NULL),
PCONFDUMP(PIN_CONFIG_BIAS_HIGH_IMPEDANCE, "input bias high impedance", NULL),
PCONFDUMP(PIN_CONFIG_BIAS_PULL_UP, "input bias pull up", NULL),
PCONFDUMP(PIN_CONFIG_BIAS_PULL_DOWN, "input bias pull down", NULL),
PCONFDUMP(PIN_CONFIG_DRIVE_PUSH_PULL, "output drive push pull", NULL),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_DRAIN, "output drive open drain", NULL),
PCONFDUMP(PIN_CONFIG_DRIVE_OPEN_SOURCE, "output drive open source", NULL),
PCONFDUMP(PIN_CONFIG_INPUT_SCHMITT, "input schmitt trigger", NULL),
PCONFDUMP(PIN_CONFIG_INPUT_DEBOUNCE, "input debounce", "time units"),
PCONFDUMP(PIN_CONFIG_POWER_SOURCE, "pin power source", "selector"),
PCONFDUMP(PIN_CONFIG_LOW_POWER_MODE, "pin low power", "mode"),
};
void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned pin)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
int i;
if (!ops->is_generic)
return;
for(i = 0; i < ARRAY_SIZE(conf_items); i++) {
unsigned long config;
int ret;
/* We want to check out this parameter */
config = pinconf_to_config_packed(conf_items[i].param, 0);
ret = pin_config_get_for_pin(pctldev, pin, &config);
/* These are legal errors */
if (ret == -EINVAL || ret == -ENOTSUPP)
continue;
if (ret) {
seq_printf(s, "ERROR READING CONFIG SETTING %d ", i);
continue;
}
/* Space between multiple configs */
seq_puts(s, " ");
seq_puts(s, conf_items[i].display);
/* Print unit if available */
if (conf_items[i].format &&
pinconf_to_config_argument(config) != 0)
seq_printf(s, " (%u %s)",
pinconf_to_config_argument(config),
conf_items[i].format);
}
}
void pinconf_generic_dump_group(struct pinctrl_dev *pctldev,
struct seq_file *s, const char *gname)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
int i;
if (!ops->is_generic)
return;
for(i = 0; i < ARRAY_SIZE(conf_items); i++) {
unsigned long config;
int ret;
/* We want to check out this parameter */
config = pinconf_to_config_packed(conf_items[i].param, 0);
ret = pin_config_group_get(dev_name(pctldev->dev), gname,
&config);
/* These are legal errors */
if (ret == -EINVAL || ret == -ENOTSUPP)
continue;
if (ret) {
seq_printf(s, "ERROR READING CONFIG SETTING %d ", i);
continue;
}
/* Space between multiple configs */
seq_puts(s, " ");
seq_puts(s, conf_items[i].display);
/* Print unit if available */
if (conf_items[i].format && config != 0)
seq_printf(s, " (%u %s)",
pinconf_to_config_argument(config),
conf_items[i].format);
}
}
#endif
...@@ -23,6 +23,37 @@ ...@@ -23,6 +23,37 @@
#include "core.h" #include "core.h"
#include "pinconf.h" #include "pinconf.h"
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;
}
int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long *config) unsigned long *config)
{ {
...@@ -51,19 +82,27 @@ int pin_config_get(const char *dev_name, const char *name, ...@@ -51,19 +82,27 @@ int pin_config_get(const char *dev_name, const char *name,
struct pinctrl_dev *pctldev; struct pinctrl_dev *pctldev;
int pin; int pin;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); mutex_lock(&pinctrl_mutex);
if (!pctldev)
return -EINVAL; pctldev = get_pinctrl_dev_from_devname(dev_name);
if (!pctldev) {
pin = -EINVAL;
goto unlock;
}
pin = pin_get_from_name(pctldev, name); pin = pin_get_from_name(pctldev, name);
if (pin < 0) 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); 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) unsigned long config)
{ {
const struct pinconf_ops *ops = pctldev->desc->confops; const struct pinconf_ops *ops = pctldev->desc->confops;
...@@ -97,17 +136,27 @@ int pin_config_set(const char *dev_name, const char *name, ...@@ -97,17 +136,27 @@ int pin_config_set(const char *dev_name, const char *name,
unsigned long config) unsigned long config)
{ {
struct pinctrl_dev *pctldev; struct pinctrl_dev *pctldev;
int pin; int pin, ret;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); mutex_lock(&pinctrl_mutex);
if (!pctldev)
return -EINVAL; pctldev = get_pinctrl_dev_from_devname(dev_name);
if (!pctldev) {
ret = -EINVAL;
goto unlock;
}
pin = pin_get_from_name(pctldev, name); pin = pin_get_from_name(pctldev, name);
if (pin < 0) if (pin < 0) {
return pin; 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); EXPORT_SYMBOL(pin_config_set);
...@@ -116,29 +165,39 @@ int pin_config_group_get(const char *dev_name, const char *pin_group, ...@@ -116,29 +165,39 @@ int pin_config_group_get(const char *dev_name, const char *pin_group,
{ {
struct pinctrl_dev *pctldev; struct pinctrl_dev *pctldev;
const struct pinconf_ops *ops; const struct pinconf_ops *ops;
int selector; int selector, ret;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); mutex_lock(&pinctrl_mutex);
if (!pctldev)
return -EINVAL; pctldev = get_pinctrl_dev_from_devname(dev_name);
if (!pctldev) {
ret = -EINVAL;
goto unlock;
}
ops = pctldev->desc->confops; ops = pctldev->desc->confops;
if (!ops || !ops->pin_config_group_get) { if (!ops || !ops->pin_config_group_get) {
dev_err(pctldev->dev, "cannot get configuration for pin " dev_err(pctldev->dev, "cannot get configuration for pin "
"group, missing group config get function in " "group, missing group config get function in "
"driver\n"); "driver\n");
return -EINVAL; ret = -EINVAL;
goto unlock;
} }
selector = pinctrl_get_group_selector(pctldev, pin_group); selector = pinctrl_get_group_selector(pctldev, pin_group);
if (selector < 0) if (selector < 0) {
return selector; ret = selector;
goto unlock;
}
ret = ops->pin_config_group_get(pctldev, selector, config);
return ops->pin_config_group_get(pctldev, selector, config); unlock:
mutex_unlock(&pinctrl_mutex);
return ret;
} }
EXPORT_SYMBOL(pin_config_group_get); EXPORT_SYMBOL(pin_config_group_get);
int pin_config_group_set(const char *dev_name, const char *pin_group, int pin_config_group_set(const char *dev_name, const char *pin_group,
unsigned long config) unsigned long config)
{ {
...@@ -151,27 +210,34 @@ int pin_config_group_set(const char *dev_name, const char *pin_group, ...@@ -151,27 +210,34 @@ int pin_config_group_set(const char *dev_name, const char *pin_group,
int ret; int ret;
int i; int i;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); mutex_lock(&pinctrl_mutex);
if (!pctldev)
return -EINVAL; pctldev = get_pinctrl_dev_from_devname(dev_name);
if (!pctldev) {
ret = -EINVAL;
goto unlock;
}
ops = pctldev->desc->confops; ops = pctldev->desc->confops;
pctlops = pctldev->desc->pctlops; pctlops = pctldev->desc->pctlops;
if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) { if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) {
dev_err(pctldev->dev, "cannot configure pin group, missing " dev_err(pctldev->dev, "cannot configure pin group, missing "
"config function in driver\n"); "config function in driver\n");
return -EINVAL; ret = -EINVAL;
goto unlock;
} }
selector = pinctrl_get_group_selector(pctldev, pin_group); selector = pinctrl_get_group_selector(pctldev, pin_group);
if (selector < 0) if (selector < 0) {
return selector; ret = selector;
goto unlock;
}
ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins); ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins);
if (ret) { if (ret) {
dev_err(pctldev->dev, "cannot configure pin group, error " dev_err(pctldev->dev, "cannot configure pin group, error "
"getting pins\n"); "getting pins\n");
return ret; goto unlock;
} }
/* /*
...@@ -185,46 +251,196 @@ int pin_config_group_set(const char *dev_name, const char *pin_group, ...@@ -185,46 +251,196 @@ int pin_config_group_set(const char *dev_name, const char *pin_group,
* pin-by-pin as well, it returns -EAGAIN. * pin-by-pin as well, it returns -EAGAIN.
*/ */
if (ret != -EAGAIN) if (ret != -EAGAIN)
return ret; goto unlock;
} }
/* /*
* If the controller cannot handle entire groups, we configure each pin * If the controller cannot handle entire groups, we configure each pin
* individually. * individually.
*/ */
if (!ops->pin_config_set) if (!ops->pin_config_set) {
return 0; ret = 0;
goto unlock;
}
for (i = 0; i < num_pins; i++) { for (i = 0; i < num_pins; i++) {
ret = ops->pin_config_set(pctldev, pins[i], config); ret = ops->pin_config_set(pctldev, pins[i], config);
if (ret < 0) if (ret < 0)
return ret; goto unlock;
} }
return 0; ret = 0;
unlock:
mutex_unlock(&pinctrl_mutex);
return ret;
} }
EXPORT_SYMBOL(pin_config_group_set); 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;
int pin;
switch (setting->type) {
case PIN_MAP_TYPE_CONFIGS_PIN:
pin = pin_get_from_name(pctldev,
map->data.configs.group_or_pin);
if (pin < 0) {
dev_err(pctldev->dev, "could not map pin config for \"%s\"",
map->data.configs.group_or_pin);
return pin;
}
setting->data.configs.group_or_pin = pin;
break;
case PIN_MAP_TYPE_CONFIGS_GROUP:
pin = pinctrl_get_group_selector(pctldev,
map->data.configs.group_or_pin);
if (pin < 0) {
dev_err(pctldev->dev, "could not map group config for \"%s\"",
map->data.configs.group_or_pin);
return pin;
}
setting->data.configs.group_or_pin = 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; const struct pinconf_ops *ops = pctldev->desc->confops;
int i, ret;
/* We must be able to read out pin status */ if (!ops) {
if (!ops->pin_config_get && !ops->pin_config_group_get) dev_err(pctldev->dev, "missing confops\n");
return -EINVAL; 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 -EINVAL;
}
return 0; return 0;
} }
#ifdef CONFIG_DEBUG_FS #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, static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
struct seq_file *s, int pin) struct seq_file *s, int pin)
{ {
const struct pinconf_ops *ops = pctldev->desc->confops; const struct pinconf_ops *ops = pctldev->desc->confops;
/* no-op when not using generic pin config */
pinconf_generic_dump_pin(pctldev, s, pin);
if (ops && ops->pin_config_dbg_show) if (ops && ops->pin_config_dbg_show)
ops->pin_config_dbg_show(pctldev, s, pin); ops->pin_config_dbg_show(pctldev, s, pin);
} }
...@@ -237,6 +453,8 @@ static int pinconf_pins_show(struct seq_file *s, void *what) ...@@ -237,6 +453,8 @@ static int pinconf_pins_show(struct seq_file *s, void *what)
seq_puts(s, "Pin config settings per pin\n"); seq_puts(s, "Pin config settings per pin\n");
seq_puts(s, "Format: pin (name): pinmux setting array\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 */ /* The pin number can be retrived from the pin controller descriptor */
for (i = 0; i < pctldev->desc->npins; i++) { for (i = 0; i < pctldev->desc->npins; i++) {
struct pin_desc *desc; struct pin_desc *desc;
...@@ -255,6 +473,8 @@ static int pinconf_pins_show(struct seq_file *s, void *what) ...@@ -255,6 +473,8 @@ static int pinconf_pins_show(struct seq_file *s, void *what)
seq_printf(s, "\n"); seq_printf(s, "\n");
} }
mutex_unlock(&pinctrl_mutex);
return 0; return 0;
} }
...@@ -264,6 +484,8 @@ static void pinconf_dump_group(struct pinctrl_dev *pctldev, ...@@ -264,6 +484,8 @@ static void pinconf_dump_group(struct pinctrl_dev *pctldev,
{ {
const struct pinconf_ops *ops = pctldev->desc->confops; const struct pinconf_ops *ops = pctldev->desc->confops;
/* no-op when not using generic pin config */
pinconf_generic_dump_group(pctldev, s, gname);
if (ops && ops->pin_config_group_dbg_show) if (ops && ops->pin_config_group_dbg_show)
ops->pin_config_group_dbg_show(pctldev, s, selector); ops->pin_config_group_dbg_show(pctldev, s, selector);
} }
...@@ -281,14 +503,20 @@ static int pinconf_groups_show(struct seq_file *s, void *what) ...@@ -281,14 +503,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, "Pin config settings per pin group\n");
seq_puts(s, "Format: group (name): pinmux setting array\n"); seq_puts(s, "Format: group (name): pinmux setting array\n");
mutex_lock(&pinctrl_mutex);
while (pctlops->list_groups(pctldev, selector) >= 0) { while (pctlops->list_groups(pctldev, selector) >= 0) {
const char *gname = pctlops->get_group_name(pctldev, selector); const char *gname = pctlops->get_group_name(pctldev, selector);
seq_printf(s, "%u (%s):", selector, gname); seq_printf(s, "%u (%s):", selector, gname);
pinconf_dump_group(pctldev, s, selector, gname); pinconf_dump_group(pctldev, s, selector, gname);
seq_printf(s, "\n");
selector++; selector++;
} }
mutex_unlock(&pinctrl_mutex);
return 0; return 0;
} }
......
...@@ -14,12 +14,25 @@ ...@@ -14,12 +14,25 @@
#ifdef CONFIG_PINCONF #ifdef CONFIG_PINCONF
int pinconf_check_ops(struct pinctrl_dev *pctldev); 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, void pinconf_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev); struct pinctrl_dev *pctldev);
/*
* You will only be interested in these if you're using PINCONF
* so don't supply any stubs for these.
*/
int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long *config); unsigned long *config);
int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin, int pin_config_group_get(const char *dev_name, const char *pin_group,
unsigned long config); unsigned long *config);
#else #else
...@@ -28,9 +41,70 @@ static inline int pinconf_check_ops(struct pinctrl_dev *pctldev) ...@@ -28,9 +41,70 @@ static inline int pinconf_check_ops(struct pinctrl_dev *pctldev)
return 0; 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, static inline void pinconf_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev) struct pinctrl_dev *pctldev)
{ {
} }
#endif #endif
/*
* The following functions are available if the driver uses the generic
* pin config.
*/
#ifdef CONFIG_GENERIC_PINCONF
void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned pin);
void pinconf_generic_dump_group(struct pinctrl_dev *pctldev,
struct seq_file *s, const char *gname);
#else
static inline void pinconf_generic_dump_pin(struct pinctrl_dev *pctldev,
struct seq_file *s,
unsigned pin)
{
return;
}
static inline void pinconf_generic_dump_group(struct pinctrl_dev *pctldev,
struct seq_file *s,
const char *gname)
{
return;
}
#endif
...@@ -22,38 +22,10 @@ ...@@ -22,38 +22,10 @@
#include <linux/gpio.h> #include <linux/gpio.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/slab.h> #include <linux/slab.h>
#include <linux/pinctrl/pinmux.h> #include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <mach/gpio-u300.h> #include <mach/gpio-u300.h>
#include "pinctrl-coh901.h"
/*
* Bias modes for U300 GPIOs
*
* GPIO_U300_CONFIG_BIAS_UNKNOWN: this bias mode is not known to us
* GPIO_U300_CONFIG_BIAS_FLOAT: no specific bias, the GPIO will float or state
* is not controlled by software
* GPIO_U300_CONFIG_BIAS_PULL_UP: the GPIO will be pulled up (usually with high
* impedance to VDD)
*/
#define GPIO_U300_CONFIG_BIAS_UNKNOWN 0x1000
#define GPIO_U300_CONFIG_BIAS_FLOAT 0x1001
#define GPIO_U300_CONFIG_BIAS_PULL_UP 0x1002
/*
* Drive modes for U300 GPIOs (output)
*
* GPIO_U300_CONFIG_DRIVE_PUSH_PULL: the GPIO will be driven actively high and
* low, this is the most typical case and is typically achieved with two
* active transistors on the output
* GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN: the GPIO will be driven with open drain
* (open collector) which means it is usually wired with other output
* ports which are then pulled up with an external resistor
* GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE: the GPIO will be driven with open drain
* (open emitter) which is the same as open drain mutatis mutandis but
* pulled to ground
*/
#define GPIO_U300_CONFIG_DRIVE_PUSH_PULL 0x2000
#define GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN 0x2001
#define GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE 0x2002
/* /*
* Register definitions for COH 901 335 variant * Register definitions for COH 901 335 variant
...@@ -181,12 +153,12 @@ struct u300_gpio_confdata { ...@@ -181,12 +153,12 @@ struct u300_gpio_confdata {
#define BS365_GPIO_NUM_PORTS 5 #define BS365_GPIO_NUM_PORTS 5
#define U300_FLOATING_INPUT { \ #define U300_FLOATING_INPUT { \
.bias_mode = GPIO_U300_CONFIG_BIAS_FLOAT, \ .bias_mode = PIN_CONFIG_BIAS_HIGH_IMPEDANCE, \
.output = false, \ .output = false, \
} }
#define U300_PULL_UP_INPUT { \ #define U300_PULL_UP_INPUT { \
.bias_mode = GPIO_U300_CONFIG_BIAS_PULL_UP, \ .bias_mode = PIN_CONFIG_BIAS_PULL_UP, \
.output = false, \ .output = false, \
} }
...@@ -360,14 +332,14 @@ static int u300_gpio_request(struct gpio_chip *chip, unsigned offset) ...@@ -360,14 +332,14 @@ static int u300_gpio_request(struct gpio_chip *chip, unsigned offset)
*/ */
int gpio = chip->base + 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) static void u300_gpio_free(struct gpio_chip *chip, unsigned offset)
{ {
int gpio = chip->base + 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) static int u300_gpio_get(struct gpio_chip *chip, unsigned offset)
...@@ -448,8 +420,68 @@ static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset) ...@@ -448,8 +420,68 @@ static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
return retirq; return retirq;
} }
static int u300_gpio_config(struct gpio_chip *chip, unsigned offset, /* Returning -EINVAL means "supported but not available" */
u16 param, unsigned long *data) int u300_gpio_config_get(struct gpio_chip *chip,
unsigned offset,
unsigned long *config)
{
struct u300_gpio *gpio = to_u300_gpio(chip);
enum pin_config_param param = (enum pin_config_param) *config;
bool biasmode;
u32 drmode;
/* One bit per pin, clamp to bool range */
biasmode = !!(readl(U300_PIN_REG(offset, per)) & U300_PIN_BIT(offset));
/* Mask out the two bits for this pin and shift to bits 0,1 */
drmode = readl(U300_PIN_REG(offset, pcr));
drmode &= (U300_GPIO_PXPCR_PIN_MODE_MASK << ((offset & 0x07) << 1));
drmode >>= ((offset & 0x07) << 1);
switch(param) {
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
*config = 0;
if (biasmode)
return 0;
else
return -EINVAL;
break;
case PIN_CONFIG_BIAS_PULL_UP:
*config = 0;
if (!biasmode)
return 0;
else
return -EINVAL;
break;
case PIN_CONFIG_DRIVE_PUSH_PULL:
*config = 0;
if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL)
return 0;
else
return -EINVAL;
break;
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
*config = 0;
if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN)
return 0;
else
return -EINVAL;
break;
case PIN_CONFIG_DRIVE_OPEN_SOURCE:
*config = 0;
if (drmode == U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE)
return 0;
else
return -EINVAL;
break;
default:
break;
}
return -ENOTSUPP;
}
int u300_gpio_config_set(struct gpio_chip *chip, unsigned offset,
enum pin_config_param param)
{ {
struct u300_gpio *gpio = to_u300_gpio(chip); struct u300_gpio *gpio = to_u300_gpio(chip);
unsigned long flags; unsigned long flags;
...@@ -457,16 +489,16 @@ static int u300_gpio_config(struct gpio_chip *chip, unsigned offset, ...@@ -457,16 +489,16 @@ static int u300_gpio_config(struct gpio_chip *chip, unsigned offset,
local_irq_save(flags); local_irq_save(flags);
switch (param) { switch (param) {
case GPIO_U300_CONFIG_BIAS_UNKNOWN: case PIN_CONFIG_BIAS_DISABLE:
case GPIO_U300_CONFIG_BIAS_FLOAT: case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
val = readl(U300_PIN_REG(offset, per)); val = readl(U300_PIN_REG(offset, per));
writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, per)); writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, per));
break; break;
case GPIO_U300_CONFIG_BIAS_PULL_UP: case PIN_CONFIG_BIAS_PULL_UP:
val = readl(U300_PIN_REG(offset, per)); val = readl(U300_PIN_REG(offset, per));
writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, per)); writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, per));
break; break;
case GPIO_U300_CONFIG_DRIVE_PUSH_PULL: case PIN_CONFIG_DRIVE_PUSH_PULL:
val = readl(U300_PIN_REG(offset, pcr)); val = readl(U300_PIN_REG(offset, pcr));
val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK
<< ((offset & 0x07) << 1)); << ((offset & 0x07) << 1));
...@@ -474,7 +506,7 @@ static int u300_gpio_config(struct gpio_chip *chip, unsigned offset, ...@@ -474,7 +506,7 @@ static int u300_gpio_config(struct gpio_chip *chip, unsigned offset,
<< ((offset & 0x07) << 1)); << ((offset & 0x07) << 1));
writel(val, U300_PIN_REG(offset, pcr)); writel(val, U300_PIN_REG(offset, pcr));
break; break;
case GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN: case PIN_CONFIG_DRIVE_OPEN_DRAIN:
val = readl(U300_PIN_REG(offset, pcr)); val = readl(U300_PIN_REG(offset, pcr));
val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK
<< ((offset & 0x07) << 1)); << ((offset & 0x07) << 1));
...@@ -482,7 +514,7 @@ static int u300_gpio_config(struct gpio_chip *chip, unsigned offset, ...@@ -482,7 +514,7 @@ static int u300_gpio_config(struct gpio_chip *chip, unsigned offset,
<< ((offset & 0x07) << 1)); << ((offset & 0x07) << 1));
writel(val, U300_PIN_REG(offset, pcr)); writel(val, U300_PIN_REG(offset, pcr));
break; break;
case GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE: case PIN_CONFIG_DRIVE_OPEN_SOURCE:
val = readl(U300_PIN_REG(offset, pcr)); val = readl(U300_PIN_REG(offset, pcr));
val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK
<< ((offset & 0x07) << 1)); << ((offset & 0x07) << 1));
...@@ -650,13 +682,12 @@ static void __init u300_gpio_init_pin(struct u300_gpio *gpio, ...@@ -650,13 +682,12 @@ static void __init u300_gpio_init_pin(struct u300_gpio *gpio,
u300_gpio_direction_output(&gpio->chip, offset, conf->outval); u300_gpio_direction_output(&gpio->chip, offset, conf->outval);
/* Deactivate bias mode for output */ /* Deactivate bias mode for output */
u300_gpio_config(&gpio->chip, offset, u300_gpio_config_set(&gpio->chip, offset,
GPIO_U300_CONFIG_BIAS_FLOAT, PIN_CONFIG_BIAS_HIGH_IMPEDANCE);
NULL);
/* Set drive mode for output */ /* Set drive mode for output */
u300_gpio_config(&gpio->chip, offset, u300_gpio_config_set(&gpio->chip, offset,
GPIO_U300_CONFIG_DRIVE_PUSH_PULL, NULL); PIN_CONFIG_DRIVE_PUSH_PULL);
dev_dbg(gpio->dev, "set up pin %d as output, value: %d\n", dev_dbg(gpio->dev, "set up pin %d as output, value: %d\n",
offset, conf->outval); offset, conf->outval);
...@@ -667,7 +698,7 @@ static void __init u300_gpio_init_pin(struct u300_gpio *gpio, ...@@ -667,7 +698,7 @@ static void __init u300_gpio_init_pin(struct u300_gpio *gpio,
u300_gpio_set(&gpio->chip, offset, 0); u300_gpio_set(&gpio->chip, offset, 0);
/* Set bias mode for input */ /* Set bias mode for input */
u300_gpio_config(&gpio->chip, offset, conf->bias_mode, NULL); u300_gpio_config_set(&gpio->chip, offset, conf->bias_mode);
dev_dbg(gpio->dev, "set up pin %d as input, bias: %04x\n", dev_dbg(gpio->dev, "set up pin %d as input, bias: %04x\n",
offset, conf->bias_mode); offset, conf->bias_mode);
...@@ -705,7 +736,6 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio) ...@@ -705,7 +736,6 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio)
list_for_each_safe(p, n, &gpio->port_list) { list_for_each_safe(p, n, &gpio->port_list) {
port = list_entry(p, struct u300_gpio_port, node); port = list_entry(p, struct u300_gpio_port, node);
list_del(&port->node); list_del(&port->node);
free_irq(port->irq, port);
kfree(port); kfree(port);
} }
} }
...@@ -861,10 +891,18 @@ static int __init u300_gpio_probe(struct platform_device *pdev) ...@@ -861,10 +891,18 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
goto err_no_chip; 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); platform_set_drvdata(pdev, gpio);
return 0; return 0;
err_no_pinctrl:
err = gpiochip_remove(&gpio->chip);
err_no_chip: err_no_chip:
err_no_port: err_no_port:
u300_gpio_free_ports(gpio); u300_gpio_free_ports(gpio);
...@@ -919,7 +957,6 @@ static struct platform_driver u300_gpio_driver = { ...@@ -919,7 +957,6 @@ static struct platform_driver u300_gpio_driver = {
.remove = __exit_p(u300_gpio_remove), .remove = __exit_p(u300_gpio_remove),
}; };
static int __init u300_gpio_init(void) static int __init u300_gpio_init(void)
{ {
return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe); return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe);
......
int u300_gpio_config_get(struct gpio_chip *chip,
unsigned offset,
unsigned long *config);
int u300_gpio_config_set(struct gpio_chip *chip, unsigned offset,
enum pin_config_param param);
/*
* 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");
/*
* 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");
/*
* 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");
/*
* 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 */
/*
* 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");
/*
* Driver for the NVIDIA Tegra pinmux
*
* Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved.
*
* Derived from code:
* Copyright (C) 2010 Google, Inc.
* Copyright (C) 2010 NVIDIA Corporation
* Copyright (C) 2009-2011 ST-Ericsson AB
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#include <linux/err.h>
#include <linux/init.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/of_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <mach/pinconf-tegra.h>
#include "pinctrl-tegra.h"
#define DRIVER_NAME "tegra-pinmux-disabled"
struct tegra_pmx {
struct device *dev;
struct pinctrl_dev *pctl;
const struct tegra_pinctrl_soc_data *soc;
int nbanks;
void __iomem **regs;
};
static inline u32 pmx_readl(struct tegra_pmx *pmx, u32 bank, u32 reg)
{
return readl(pmx->regs[bank] + reg);
}
static inline void pmx_writel(struct tegra_pmx *pmx, u32 val, u32 bank, u32 reg)
{
writel(val, pmx->regs[bank] + reg);
}
static int tegra_pinctrl_list_groups(struct pinctrl_dev *pctldev,
unsigned group)
{
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
if (group >= pmx->soc->ngroups)
return -EINVAL;
return 0;
}
static const char *tegra_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
unsigned group)
{
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
if (group >= pmx->soc->ngroups)
return NULL;
return pmx->soc->groups[group].name;
}
static int tegra_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
unsigned group,
const unsigned **pins,
unsigned *num_pins)
{
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
if (group >= pmx->soc->ngroups)
return -EINVAL;
*pins = pmx->soc->groups[group].pins;
*num_pins = pmx->soc->groups[group].npins;
return 0;
}
static void tegra_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s,
unsigned offset)
{
seq_printf(s, " " DRIVER_NAME);
}
static struct pinctrl_ops tegra_pinctrl_ops = {
.list_groups = tegra_pinctrl_list_groups,
.get_group_name = tegra_pinctrl_get_group_name,
.get_group_pins = tegra_pinctrl_get_group_pins,
.pin_dbg_show = tegra_pinctrl_pin_dbg_show,
};
static int tegra_pinctrl_list_funcs(struct pinctrl_dev *pctldev,
unsigned function)
{
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
if (function >= pmx->soc->nfunctions)
return -EINVAL;
return 0;
}
static const char *tegra_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
unsigned function)
{
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
if (function >= pmx->soc->nfunctions)
return NULL;
return pmx->soc->functions[function].name;
}
static int tegra_pinctrl_get_func_groups(struct pinctrl_dev *pctldev,
unsigned function,
const char * const **groups,
unsigned * const num_groups)
{
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
if (function >= pmx->soc->nfunctions)
return -EINVAL;
*groups = pmx->soc->functions[function].groups;
*num_groups = pmx->soc->functions[function].ngroups;
return 0;
}
static int tegra_pinctrl_enable(struct pinctrl_dev *pctldev, unsigned function,
unsigned group)
{
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
const struct tegra_pingroup *g;
int i;
u32 val;
if (group >= pmx->soc->ngroups)
return -EINVAL;
g = &pmx->soc->groups[group];
if (g->mux_reg < 0)
return -EINVAL;
for (i = 0; i < ARRAY_SIZE(g->funcs); i++) {
if (g->funcs[i] == function)
break;
}
if (i == ARRAY_SIZE(g->funcs))
return -EINVAL;
val = pmx_readl(pmx, g->mux_bank, g->mux_reg);
val &= ~(0x3 << g->mux_bit);
val |= i << g->mux_bit;
pmx_writel(pmx, val, g->mux_bank, g->mux_reg);
return 0;
}
static void tegra_pinctrl_disable(struct pinctrl_dev *pctldev,
unsigned function, unsigned group)
{
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
const struct tegra_pingroup *g;
u32 val;
if (group >= pmx->soc->ngroups)
return;
g = &pmx->soc->groups[group];
if (g->mux_reg < 0)
return;
val = pmx_readl(pmx, g->mux_bank, g->mux_reg);
val &= ~(0x3 << g->mux_bit);
val |= g->func_safe << g->mux_bit;
pmx_writel(pmx, val, g->mux_bank, g->mux_reg);
}
static struct pinmux_ops tegra_pinmux_ops = {
.list_functions = tegra_pinctrl_list_funcs,
.get_function_name = tegra_pinctrl_get_func_name,
.get_function_groups = tegra_pinctrl_get_func_groups,
.enable = tegra_pinctrl_enable,
.disable = tegra_pinctrl_disable,
};
static int tegra_pinconf_reg(struct tegra_pmx *pmx,
const struct tegra_pingroup *g,
enum tegra_pinconf_param param,
s8 *bank, s16 *reg, s8 *bit, s8 *width)
{
switch (param) {
case TEGRA_PINCONF_PARAM_PULL:
*bank = g->pupd_bank;
*reg = g->pupd_reg;
*bit = g->pupd_bit;
*width = 2;
break;
case TEGRA_PINCONF_PARAM_TRISTATE:
*bank = g->tri_bank;
*reg = g->tri_reg;
*bit = g->tri_bit;
*width = 1;
break;
case TEGRA_PINCONF_PARAM_ENABLE_INPUT:
*bank = g->einput_bank;
*reg = g->einput_reg;
*bit = g->einput_bit;
*width = 1;
break;
case TEGRA_PINCONF_PARAM_OPEN_DRAIN:
*bank = g->odrain_bank;
*reg = g->odrain_reg;
*bit = g->odrain_bit;
*width = 1;
break;
case TEGRA_PINCONF_PARAM_LOCK:
*bank = g->lock_bank;
*reg = g->lock_reg;
*bit = g->lock_bit;
*width = 1;
break;
case TEGRA_PINCONF_PARAM_IORESET:
*bank = g->ioreset_bank;
*reg = g->ioreset_reg;
*bit = g->ioreset_bit;
*width = 1;
break;
case TEGRA_PINCONF_PARAM_HIGH_SPEED_MODE:
*bank = g->drv_bank;
*reg = g->drv_reg;
*bit = g->hsm_bit;
*width = 1;
break;
case TEGRA_PINCONF_PARAM_SCHMITT:
*bank = g->drv_bank;
*reg = g->drv_reg;
*bit = g->schmitt_bit;
*width = 1;
break;
case TEGRA_PINCONF_PARAM_LOW_POWER_MODE:
*bank = g->drv_bank;
*reg = g->drv_reg;
*bit = g->lpmd_bit;
*width = 1;
break;
case TEGRA_PINCONF_PARAM_DRIVE_DOWN_STRENGTH:
*bank = g->drv_bank;
*reg = g->drv_reg;
*bit = g->drvdn_bit;
*width = g->drvdn_width;
break;
case TEGRA_PINCONF_PARAM_DRIVE_UP_STRENGTH:
*bank = g->drv_bank;
*reg = g->drv_reg;
*bit = g->drvup_bit;
*width = g->drvup_width;
break;
case TEGRA_PINCONF_PARAM_SLEW_RATE_FALLING:
*bank = g->drv_bank;
*reg = g->drv_reg;
*bit = g->slwf_bit;
*width = g->slwf_width;
break;
case TEGRA_PINCONF_PARAM_SLEW_RATE_RISING:
*bank = g->drv_bank;
*reg = g->drv_reg;
*bit = g->slwr_bit;
*width = g->slwr_width;
break;
default:
dev_err(pmx->dev, "Invalid config param %04x\n", param);
return -ENOTSUPP;
}
if (*reg < 0) {
dev_err(pmx->dev,
"Config param %04x not supported on group %s\n",
param, g->name);
return -ENOTSUPP;
}
return 0;
}
static int tegra_pinconf_get(struct pinctrl_dev *pctldev,
unsigned pin, unsigned long *config)
{
return -ENOTSUPP;
}
static int tegra_pinconf_set(struct pinctrl_dev *pctldev,
unsigned pin, unsigned long config)
{
return -ENOTSUPP;
}
static int tegra_pinconf_group_get(struct pinctrl_dev *pctldev,
unsigned group, unsigned long *config)
{
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(*config);
u16 arg;
const struct tegra_pingroup *g;
int ret;
s8 bank, bit, width;
s16 reg;
u32 val, mask;
if (group >= pmx->soc->ngroups)
return -EINVAL;
g = &pmx->soc->groups[group];
ret = tegra_pinconf_reg(pmx, g, param, &bank, &reg, &bit, &width);
if (ret < 0)
return ret;
val = pmx_readl(pmx, bank, reg);
mask = (1 << width) - 1;
arg = (val >> bit) & mask;
*config = TEGRA_PINCONF_PACK(param, arg);
return 0;
}
static int tegra_pinconf_group_set(struct pinctrl_dev *pctldev,
unsigned group, unsigned long config)
{
struct tegra_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
enum tegra_pinconf_param param = TEGRA_PINCONF_UNPACK_PARAM(config);
u16 arg = TEGRA_PINCONF_UNPACK_ARG(config);
const struct tegra_pingroup *g;
int ret;
s8 bank, bit, width;
s16 reg;
u32 val, mask;
if (group >= pmx->soc->ngroups)
return -EINVAL;
g = &pmx->soc->groups[group];
ret = tegra_pinconf_reg(pmx, g, param, &bank, &reg, &bit, &width);
if (ret < 0)
return ret;
val = pmx_readl(pmx, bank, reg);
/* LOCK can't be cleared */
if (param == TEGRA_PINCONF_PARAM_LOCK) {
if ((val & BIT(bit)) && !arg)
return -EINVAL;
}
/* Special-case Boolean values; allow any non-zero as true */
if (width == 1)
arg = !!arg;
/* Range-check user-supplied value */
mask = (1 << width) - 1;
if (arg & ~mask)
return -EINVAL;
/* Update register */
val &= ~(mask << bit);
val |= arg << bit;
pmx_writel(pmx, val, bank, reg);
return 0;
}
static void tegra_pinconf_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned offset)
{
}
static void tegra_pinconf_group_dbg_show(struct pinctrl_dev *pctldev,
struct seq_file *s, unsigned selector)
{
}
struct pinconf_ops tegra_pinconf_ops = {
.pin_config_get = tegra_pinconf_get,
.pin_config_set = tegra_pinconf_set,
.pin_config_group_get = tegra_pinconf_group_get,
.pin_config_group_set = tegra_pinconf_group_set,
.pin_config_dbg_show = tegra_pinconf_dbg_show,
.pin_config_group_dbg_show = tegra_pinconf_group_dbg_show,
};
static struct pinctrl_gpio_range tegra_pinctrl_gpio_range = {
.name = "Tegra GPIOs",
.id = 0,
.base = 0,
};
static struct pinctrl_desc tegra_pinctrl_desc = {
.name = DRIVER_NAME,
.pctlops = &tegra_pinctrl_ops,
.pmxops = &tegra_pinmux_ops,
.confops = &tegra_pinconf_ops,
.owner = THIS_MODULE,
};
static struct of_device_id tegra_pinctrl_of_match[] __devinitdata = {
#ifdef CONFIG_PINCTRL_TEGRA20
{
.compatible = "nvidia,tegra20-pinmux-disabled",
.data = tegra20_pinctrl_init,
},
#endif
#ifdef CONFIG_PINCTRL_TEGRA30
{
.compatible = "nvidia,tegra30-pinmux-disabled",
.data = tegra30_pinctrl_init,
},
#endif
{},
};
static int __devinit tegra_pinctrl_probe(struct platform_device *pdev)
{
const struct of_device_id *match;
tegra_pinctrl_soc_initf initf = NULL;
struct tegra_pmx *pmx;
struct resource *res;
int i;
match = of_match_device(tegra_pinctrl_of_match, &pdev->dev);
if (match)
initf = (tegra_pinctrl_soc_initf)match->data;
#ifdef CONFIG_PINCTRL_TEGRA20
if (!initf)
initf = tegra20_pinctrl_init;
#endif
if (!initf) {
dev_err(&pdev->dev,
"Could not determine SoC-specific init func\n");
return -EINVAL;
}
pmx = devm_kzalloc(&pdev->dev, sizeof(*pmx), GFP_KERNEL);
if (!pmx) {
dev_err(&pdev->dev, "Can't alloc tegra_pmx\n");
return -ENOMEM;
}
pmx->dev = &pdev->dev;
(*initf)(&pmx->soc);
tegra_pinctrl_gpio_range.npins = pmx->soc->ngpios;
tegra_pinctrl_desc.pins = pmx->soc->pins;
tegra_pinctrl_desc.npins = pmx->soc->npins;
for (i = 0; ; i++) {
res = platform_get_resource(pdev, IORESOURCE_MEM, i);
if (!res)
break;
}
pmx->nbanks = i;
pmx->regs = devm_kzalloc(&pdev->dev, pmx->nbanks * sizeof(*pmx->regs),
GFP_KERNEL);
if (!pmx->regs) {
dev_err(&pdev->dev, "Can't alloc regs pointer\n");
return -ENODEV;
}
for (i = 0; i < pmx->nbanks; i++) {
res = platform_get_resource(pdev, IORESOURCE_MEM, i);
if (!res) {
dev_err(&pdev->dev, "Missing MEM resource\n");
return -ENODEV;
}
if (!devm_request_mem_region(&pdev->dev, res->start,
resource_size(res),
dev_name(&pdev->dev))) {
dev_err(&pdev->dev,
"Couldn't request MEM resource %d\n", i);
return -ENODEV;
}
pmx->regs[i] = devm_ioremap(&pdev->dev, res->start,
resource_size(res));
if (!pmx->regs[i]) {
dev_err(&pdev->dev, "Couldn't ioremap regs %d\n", i);
return -ENODEV;
}
}
pmx->pctl = pinctrl_register(&tegra_pinctrl_desc, &pdev->dev, pmx);
if (IS_ERR(pmx->pctl)) {
dev_err(&pdev->dev, "Couldn't register pinctrl driver\n");
return PTR_ERR(pmx->pctl);
}
pinctrl_add_gpio_range(pmx->pctl, &tegra_pinctrl_gpio_range);
platform_set_drvdata(pdev, pmx);
dev_dbg(&pdev->dev, "Probed Tegra pinctrl driver\n");
return 0;
}
static int __devexit tegra_pinctrl_remove(struct platform_device *pdev)
{
struct tegra_pmx *pmx = platform_get_drvdata(pdev);
pinctrl_remove_gpio_range(pmx->pctl, &tegra_pinctrl_gpio_range);
pinctrl_unregister(pmx->pctl);
return 0;
}
static struct platform_driver tegra_pinctrl_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
.of_match_table = tegra_pinctrl_of_match,
},
.probe = tegra_pinctrl_probe,
.remove = __devexit_p(tegra_pinctrl_remove),
};
static int __init tegra_pinctrl_init(void)
{
return platform_driver_register(&tegra_pinctrl_driver);
}
arch_initcall(tegra_pinctrl_init);
static void __exit tegra_pinctrl_exit(void)
{
platform_driver_unregister(&tegra_pinctrl_driver);
}
module_exit(tegra_pinctrl_exit);
MODULE_AUTHOR("Stephen Warren <swarren@nvidia.com>");
MODULE_DESCRIPTION("NVIDIA Tegra pinctrl driver");
MODULE_LICENSE("GPL v2");
MODULE_DEVICE_TABLE(of, tegra_pinctrl_of_match);
/*
* Driver for the NVIDIA Tegra pinmux
*
* Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#ifndef __PINMUX_TEGRA_H__
#define __PINMUX_TEGRA_H__
/**
* struct tegra_function - Tegra pinctrl mux function
* @name: The name of the function, exported to pinctrl core.
* @groups: An array of pin groups that may select this function.
* @ngroups: The number of entries in @groups.
*/
struct tegra_function {
const char *name;
const char * const *groups;
unsigned ngroups;
};
/**
* struct tegra_pingroup - Tegra pin group
* @mux_reg: Mux register offset. -1 if unsupported.
* @mux_bank: Mux register bank. 0 if unsupported.
* @mux_bit: Mux register bit. 0 if unsupported.
* @pupd_reg: Pull-up/down register offset. -1 if unsupported.
* @pupd_bank: Pull-up/down register bank. 0 if unsupported.
* @pupd_bit: Pull-up/down register bit. 0 if unsupported.
* @tri_reg: Tri-state register offset. -1 if unsupported.
* @tri_bank: Tri-state register bank. 0 if unsupported.
* @tri_bit: Tri-state register bit. 0 if unsupported.
* @einput_reg: Enable-input register offset. -1 if unsupported.
* @einput_bank: Enable-input register bank. 0 if unsupported.
* @einput_bit: Enable-input register bit. 0 if unsupported.
* @odrain_reg: Open-drain register offset. -1 if unsupported.
* @odrain_bank: Open-drain register bank. 0 if unsupported.
* @odrain_bit: Open-drain register bit. 0 if unsupported.
* @lock_reg: Lock register offset. -1 if unsupported.
* @lock_bank: Lock register bank. 0 if unsupported.
* @lock_bit: Lock register bit. 0 if unsupported.
* @ioreset_reg: IO reset register offset. -1 if unsupported.
* @ioreset_bank: IO reset register bank. 0 if unsupported.
* @ioreset_bit: IO reset register bit. 0 if unsupported.
* @drv_reg: Drive fields register offset. -1 if unsupported.
* This register contains the hsm, schmitt, lpmd, drvdn,
* drvup, slwr, and slwf parameters.
* @drv_bank: Drive fields register bank. 0 if unsupported.
* @hsm_bit: High Speed Mode register bit. 0 if unsupported.
* @schmitt_bit: Scmitt register bit. 0 if unsupported.
* @lpmd_bit: Low Power Mode register bit. 0 if unsupported.
* @drvdn_bit: Drive Down register bit. 0 if unsupported.
* @drvdn_width: Drive Down field width. 0 if unsupported.
* @drvup_bit: Drive Up register bit. 0 if unsupported.
* @drvup_width: Drive Up field width. 0 if unsupported.
* @slwr_bit: Slew Rising register bit. 0 if unsupported.
* @slwr_width: Slew Rising field width. 0 if unsupported.
* @slwf_bit: Slew Falling register bit. 0 if unsupported.
* @slwf_width: Slew Falling field width. 0 if unsupported.
*
* A representation of a group of pins (possibly just one pin) in the Tegra
* pin controller. Each group allows some parameter or parameters to be
* configured. The most common is mux function selection. Many others exist
* such as pull-up/down, tri-state, etc. Tegra's pin controller is complex;
* certain groups may only support configuring certain parameters, hence
* each parameter is optional, represented by a -1 "reg" value.
*/
struct tegra_pingroup {
const char *name;
const unsigned *pins;
unsigned npins;
unsigned funcs[4];
unsigned func_safe;
s16 mux_reg;
s16 pupd_reg;
s16 tri_reg;
s16 einput_reg;
s16 odrain_reg;
s16 lock_reg;
s16 ioreset_reg;
s16 drv_reg;
u32 mux_bank:2;
u32 pupd_bank:2;
u32 tri_bank:2;
u32 einput_bank:2;
u32 odrain_bank:2;
u32 ioreset_bank:2;
u32 lock_bank:2;
u32 drv_bank:2;
u32 mux_bit:5;
u32 pupd_bit:5;
u32 tri_bit:5;
u32 einput_bit:5;
u32 odrain_bit:5;
u32 lock_bit:5;
u32 ioreset_bit:5;
u32 hsm_bit:5;
u32 schmitt_bit:5;
u32 lpmd_bit:5;
u32 drvdn_bit:5;
u32 drvup_bit:5;
u32 slwr_bit:5;
u32 slwf_bit:5;
u32 drvdn_width:6;
u32 drvup_width:6;
u32 slwr_width:6;
u32 slwf_width:6;
};
/**
* struct tegra_pinctrl_soc_data - Tegra pin controller driver configuration
* @ngpios: The number of GPIO pins the pin controller HW affects.
* @pins: An array describing all pins the pin controller affects.
* All pins which are also GPIOs must be listed first within the
* array, and be numbered identically to the GPIO controller's
* numbering.
* @npins: The numbmer of entries in @pins.
* @functions: An array describing all mux functions the SoC supports.
* @nfunctions: The numbmer of entries in @functions.
* @groups: An array describing all pin groups the pin SoC supports.
* @ngroups: The numbmer of entries in @groups.
*/
struct tegra_pinctrl_soc_data {
unsigned ngpios;
const struct pinctrl_pin_desc *pins;
unsigned npins;
const struct tegra_function *functions;
unsigned nfunctions;
const struct tegra_pingroup *groups;
unsigned ngroups;
};
/**
* tegra_pinctrl_soc_initf() - Retrieve pin controller details for a SoC.
* @soc_data: This pointer must be updated to point at a struct containing
* details of the SoC.
*/
typedef void (*tegra_pinctrl_soc_initf)(
const struct tegra_pinctrl_soc_data **soc_data);
/**
* tegra20_pinctrl_init() - Retrieve pin controller details for Tegra20
* @soc_data: This pointer will be updated to point at a struct containing
* details of Tegra20's pin controller.
*/
void tegra20_pinctrl_init(const struct tegra_pinctrl_soc_data **soc_data);
/**
* tegra30_pinctrl_init() - Retrieve pin controller details for Tegra20
* @soc_data: This pointer will be updated to point at a struct containing
* details of Tegra30's pin controller.
*/
void tegra30_pinctrl_init(const struct tegra_pinctrl_soc_data **soc_data);
#endif
/*
* Pinctrl data for the NVIDIA Tegra20 pinmux
*
* Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved.
*
* Derived from code:
* Copyright (C) 2010 Google, Inc.
* Copyright (C) 2010 NVIDIA Corporation
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
* version 2, as published by the Free Software Foundation.
*
* This program is distributed in the hope it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*/
#include <linux/platform_device.h>
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#include "pinctrl-tegra.h"
/*
* Most pins affected by the pinmux can also be GPIOs. Define these first.
* These must match how the GPIO driver names/numbers its pins.
*/
#define _GPIO(offset) (offset)
#define TEGRA_PIN_VI_GP6_PA0 _GPIO(0)
#define TEGRA_PIN_UART3_CTS_N_PA1 _GPIO(1)
#define TEGRA_PIN_DAP2_FS_PA2 _GPIO(2)
#define TEGRA_PIN_DAP2_SCLK_PA3 _GPIO(3)
#define TEGRA_PIN_DAP2_DIN_PA4 _GPIO(4)
#define TEGRA_PIN_DAP2_DOUT_PA5 _GPIO(5)
#define TEGRA_PIN_SDIO3_CLK_PA6 _GPIO(6)
#define TEGRA_PIN_SDIO3_CMD_PA7 _GPIO(7)
#define TEGRA_PIN_GMI_AD17_PB0 _GPIO(8)
#define TEGRA_PIN_GMI_AD18_PB1 _GPIO(9)
#define TEGRA_PIN_LCD_PWR0_PB2 _GPIO(10)
#define TEGRA_PIN_LCD_PCLK_PB3 _GPIO(11)
#define TEGRA_PIN_SDIO3_DAT3_PB4 _GPIO(12)
#define TEGRA_PIN_SDIO3_DAT2_PB5 _GPIO(13)
#define TEGRA_PIN_SDIO3_DAT1_PB6 _GPIO(14)
#define TEGRA_PIN_SDIO3_DAT0_PB7 _GPIO(15)
#define TEGRA_PIN_UART3_RTS_N_PC0 _GPIO(16)
#define TEGRA_PIN_LCD_PWR1_PC1 _GPIO(17)
#define TEGRA_PIN_UART2_TXD_PC2 _GPIO(18)
#define TEGRA_PIN_UART2_RXD_PC3 _GPIO(19)
#define TEGRA_PIN_GEN1_I2C_SCL_PC4 _GPIO(20)
#define TEGRA_PIN_GEN1_I2C_SDA_PC5 _GPIO(21)
#define TEGRA_PIN_LCD_PWR2_PC6 _GPIO(22)
#define TEGRA_PIN_GMI_WP_N_PC7 _GPIO(23)
#define TEGRA_PIN_SDIO3_DAT5_PD0 _GPIO(24)
#define TEGRA_PIN_SDIO3_DAT4_PD1 _GPIO(25)
#define TEGRA_PIN_VI_GP5_PD2 _GPIO(26)
#define TEGRA_PIN_SDIO3_DAT6_PD3 _GPIO(27)
#define TEGRA_PIN_SDIO3_DAT7_PD4 _GPIO(28)
#define TEGRA_PIN_VI_D1_PD5 _GPIO(29)
#define TEGRA_PIN_VI_VSYNC_PD6 _GPIO(30)
#define TEGRA_PIN_VI_HSYNC_PD7 _GPIO(31)
#define TEGRA_PIN_LCD_D0_PE0 _GPIO(32)
#define TEGRA_PIN_LCD_D1_PE1 _GPIO(33)
#define TEGRA_PIN_LCD_D2_PE2 _GPIO(34)
#define TEGRA_PIN_LCD_D3_PE3 _GPIO(35)
#define TEGRA_PIN_LCD_D4_PE4 _GPIO(36)
#define TEGRA_PIN_LCD_D5_PE5 _GPIO(37)
#define TEGRA_PIN_LCD_D6_PE6 _GPIO(38)
#define TEGRA_PIN_LCD_D7_PE7 _GPIO(39)
#define TEGRA_PIN_LCD_D8_PF0 _GPIO(40)
#define TEGRA_PIN_LCD_D9_PF1 _GPIO(41)
#define TEGRA_PIN_LCD_D10_PF2 _GPIO(42)
#define TEGRA_PIN_LCD_D11_PF3 _GPIO(43)
#define TEGRA_PIN_LCD_D12_PF4 _GPIO(44)
#define TEGRA_PIN_LCD_D13_PF5 _GPIO(45)
#define TEGRA_PIN_LCD_D14_PF6 _GPIO(46)
#define TEGRA_PIN_LCD_D15_PF7 _GPIO(47)
#define TEGRA_PIN_GMI_AD0_PG0 _GPIO(48)
#define TEGRA_PIN_GMI_AD1_PG1 _GPIO(49)
#define TEGRA_PIN_GMI_AD2_PG2 _GPIO(50)
#define TEGRA_PIN_GMI_AD3_PG3 _GPIO(51)
#define TEGRA_PIN_GMI_AD4_PG4 _GPIO(52)
#define TEGRA_PIN_GMI_AD5_PG5 _GPIO(53)
#define TEGRA_PIN_GMI_AD6_PG6 _GPIO(54)
#define TEGRA_PIN_GMI_AD7_PG7 _GPIO(55)
#define TEGRA_PIN_GMI_AD8_PH0 _GPIO(56)
#define TEGRA_PIN_GMI_AD9_PH1 _GPIO(57)
#define TEGRA_PIN_GMI_AD10_PH2 _GPIO(58)
#define TEGRA_PIN_GMI_AD11_PH3 _GPIO(59)
#define TEGRA_PIN_GMI_AD12_PH4 _GPIO(60)
#define TEGRA_PIN_GMI_AD13_PH5 _GPIO(61)
#define TEGRA_PIN_GMI_AD14_PH6 _GPIO(62)
#define TEGRA_PIN_GMI_AD15_PH7 _GPIO(63)
#define TEGRA_PIN_GMI_HIOW_N_PI0 _GPIO(64)
#define TEGRA_PIN_GMI_HIOR_N_PI1 _GPIO(65)
#define TEGRA_PIN_GMI_CS5_N_PI2 _GPIO(66)
#define TEGRA_PIN_GMI_CS6_N_PI3 _GPIO(67)
#define TEGRA_PIN_GMI_RST_N_PI4 _GPIO(68)
#define TEGRA_PIN_GMI_IORDY_PI5 _GPIO(69)
#define TEGRA_PIN_GMI_CS7_N_PI6 _GPIO(70)
#define TEGRA_PIN_GMI_WAIT_PI7 _GPIO(71)
#define TEGRA_PIN_GMI_CS0_N_PJ0 _GPIO(72)
#define TEGRA_PIN_LCD_DE_PJ1 _GPIO(73)
#define TEGRA_PIN_GMI_CS1_N_PJ2 _GPIO(74)
#define TEGRA_PIN_LCD_HSYNC_PJ3 _GPIO(75)
#define TEGRA_PIN_LCD_VSYNC_PJ4 _GPIO(76)
#define TEGRA_PIN_UART2_CTS_N_PJ5 _GPIO(77)
#define TEGRA_PIN_UART2_RTS_N_PJ6 _GPIO(78)
#define TEGRA_PIN_GMI_AD16_PJ7 _GPIO(79)
#define TEGRA_PIN_GMI_ADV_N_PK0 _GPIO(80)
#define TEGRA_PIN_GMI_CLK_PK1 _GPIO(81)
#define TEGRA_PIN_GMI_CS4_N_PK2 _GPIO(82)
#define TEGRA_PIN_GMI_CS2_N_PK3 _GPIO(83)
#define TEGRA_PIN_GMI_CS3_N_PK4 _GPIO(84)
#define TEGRA_PIN_SPDIF_OUT_PK5 _GPIO(85)
#define TEGRA_PIN_SPDIF_IN_PK6 _GPIO(86)
#define TEGRA_PIN_GMI_AD19_PK7 _GPIO(87)
#define TEGRA_PIN_VI_D2_PL0 _GPIO(88)
#define TEGRA_PIN_VI_D3_PL1 _GPIO(89)
#define TEGRA_PIN_VI_D4_PL2 _GPIO(90)
#define TEGRA_PIN_VI_D5_PL3 _GPIO(91)
#define TEGRA_PIN_VI_D6_PL4 _GPIO(92)
#define TEGRA_PIN_VI_D7_PL5 _GPIO(93)
#define TEGRA_PIN_VI_D8_PL6 _GPIO(94)
#define TEGRA_PIN_VI_D9_PL7 _GPIO(95)
#define TEGRA_PIN_LCD_D16_PM0 _GPIO(96)
#define TEGRA_PIN_LCD_D17_PM1 _GPIO(97)
#define TEGRA_PIN_LCD_D18_PM2 _GPIO(98)
#define TEGRA_PIN_LCD_D19_PM3 _GPIO(99)
#define TEGRA_PIN_LCD_D20_PM4 _GPIO(100)
#define TEGRA_PIN_LCD_D21_PM5 _GPIO(101)
#define TEGRA_PIN_LCD_D22_PM6 _GPIO(102)
#define TEGRA_PIN_LCD_D23_PM7 _GPIO(103)
#define TEGRA_PIN_DAP1_FS_PN0 _GPIO(104)
#define TEGRA_PIN_DAP1_DIN_PN1 _GPIO(105)
#define TEGRA_PIN_DAP1_DOUT_PN2 _GPIO(106)
#define TEGRA_PIN_DAP1_SCLK_PN3 _GPIO(107)
#define TEGRA_PIN_LCD_CS0_N_PN4 _GPIO(108)
#define TEGRA_PIN_LCD_SDOUT_PN5 _GPIO(109)
#define TEGRA_PIN_LCD_DC0_PN6 _GPIO(110)
#define TEGRA_PIN_HDMI_INT_N_PN7 _GPIO(111)
#define TEGRA_PIN_ULPI_DATA7_PO0 _GPIO(112)
#define TEGRA_PIN_ULPI_DATA0_PO1 _GPIO(113)
#define TEGRA_PIN_ULPI_DATA1_PO2 _GPIO(114)
#define TEGRA_PIN_ULPI_DATA2_PO3 _GPIO(115)
#define TEGRA_PIN_ULPI_DATA3_PO4 _GPIO(116)
#define TEGRA_PIN_ULPI_DATA4_PO5 _GPIO(117)
#define TEGRA_PIN_ULPI_DATA5_PO6 _GPIO(118)
#define TEGRA_PIN_ULPI_DATA6_PO7 _GPIO(119)
#define TEGRA_PIN_DAP3_FS_PP0 _GPIO(120)
#define TEGRA_PIN_DAP3_DIN_PP1 _GPIO(121)
#define TEGRA_PIN_DAP3_DOUT_PP2 _GPIO(122)
#define TEGRA_PIN_DAP3_SCLK_PP3 _GPIO(123)
#define TEGRA_PIN_DAP4_FS_PP4 _GPIO(124)
#define TEGRA_PIN_DAP4_DIN_PP5 _GPIO(125)
#define TEGRA_PIN_DAP4_DOUT_PP6 _GPIO(126)
#define TEGRA_PIN_DAP4_SCLK_PP7 _GPIO(127)
#define TEGRA_PIN_KB_COL0_PQ0 _GPIO(128)
#define TEGRA_PIN_KB_COL1_PQ1 _GPIO(129)
#define TEGRA_PIN_KB_COL2_PQ2 _GPIO(130)
#define TEGRA_PIN_KB_COL3_PQ3 _GPIO(131)
#define TEGRA_PIN_KB_COL4_PQ4 _GPIO(132)
#define TEGRA_PIN_KB_COL5_PQ5 _GPIO(133)
#define TEGRA_PIN_KB_COL6_PQ6 _GPIO(134)
#define TEGRA_PIN_KB_COL7_PQ7 _GPIO(135)
#define TEGRA_PIN_KB_ROW0_PR0 _GPIO(136)
#define TEGRA_PIN_KB_ROW1_PR1 _GPIO(137)
#define TEGRA_PIN_KB_ROW2_PR2 _GPIO(138)
#define TEGRA_PIN_KB_ROW3_PR3 _GPIO(139)
#define TEGRA_PIN_KB_ROW4_PR4 _GPIO(140)
#define TEGRA_PIN_KB_ROW5_PR5 _GPIO(141)
#define TEGRA_PIN_KB_ROW6_PR6 _GPIO(142)
#define TEGRA_PIN_KB_ROW7_PR7 _GPIO(143)
#define TEGRA_PIN_KB_ROW8_PS0 _GPIO(144)
#define TEGRA_PIN_KB_ROW9_PS1 _GPIO(145)
#define TEGRA_PIN_KB_ROW10_PS2 _GPIO(146)
#define TEGRA_PIN_KB_ROW11_PS3 _GPIO(147)
#define TEGRA_PIN_KB_ROW12_PS4 _GPIO(148)
#define TEGRA_PIN_KB_ROW13_PS5 _GPIO(149)
#define TEGRA_PIN_KB_ROW14_PS6 _GPIO(150)
#define TEGRA_PIN_KB_ROW15_PS7 _GPIO(151)
#define TEGRA_PIN_VI_PCLK_PT0 _GPIO(152)
#define TEGRA_PIN_VI_MCLK_PT1 _GPIO(153)
#define TEGRA_PIN_VI_D10_PT2 _GPIO(154)
#define TEGRA_PIN_VI_D11_PT3 _GPIO(155)
#define TEGRA_PIN_VI_D0_PT4 _GPIO(156)
#define TEGRA_PIN_GEN2_I2C_SCL_PT5 _GPIO(157)
#define TEGRA_PIN_GEN2_I2C_SDA_PT6 _GPIO(158)
#define TEGRA_PIN_GMI_DPD_PT7 _GPIO(159)
#define TEGRA_PIN_PU0 _GPIO(160)
#define TEGRA_PIN_PU1 _GPIO(161)
#define TEGRA_PIN_PU2 _GPIO(162)
#define TEGRA_PIN_PU3 _GPIO(163)
#define TEGRA_PIN_PU4 _GPIO(164)
#define TEGRA_PIN_PU5 _GPIO(165)
#define TEGRA_PIN_PU6 _GPIO(166)
#define TEGRA_PIN_JTAG_RTCK_PU7 _GPIO(167)
#define TEGRA_PIN_PV0 _GPIO(168)
#define TEGRA_PIN_PV1 _GPIO(169)
#define TEGRA_PIN_PV2 _GPIO(170)
#define TEGRA_PIN_PV3 _GPIO(171)
#define TEGRA_PIN_PV4 _GPIO(172)
#define TEGRA_PIN_PV5 _GPIO(173)
#define TEGRA_PIN_PV6 _GPIO(174)
#define TEGRA_PIN_LCD_DC1_PV7 _GPIO(175)
#define TEGRA_PIN_LCD_CS1_N_PW0 _GPIO(176)
#define TEGRA_PIN_LCD_M1_PW1 _GPIO(177)
#define TEGRA_PIN_SPI2_CS1_N_PW2 _GPIO(178)
#define TEGRA_PIN_SPI2_CS2_N_PW3 _GPIO(179)
#define TEGRA_PIN_DAP_MCLK1_PW4 _GPIO(180)
#define TEGRA_PIN_DAP_MCLK2_PW5 _GPIO(181)
#define TEGRA_PIN_UART3_TXD_PW6 _GPIO(182)
#define TEGRA_PIN_UART3_RXD_PW7 _GPIO(183)
#define TEGRA_PIN_SPI2_MOSI_PX0 _GPIO(184)
#define TEGRA_PIN_SPI2_MISO_PX1 _GPIO(185)
#define TEGRA_PIN_SPI2_SCK_PX2 _GPIO(186)
#define TEGRA_PIN_SPI2_CS0_N_PX3 _GPIO(187)
#define TEGRA_PIN_SPI1_MOSI_PX4 _GPIO(188)
#define TEGRA_PIN_SPI1_SCK_PX5 _GPIO(189)
#define TEGRA_PIN_SPI1_CS0_N_PX6 _GPIO(190)
#define TEGRA_PIN_SPI1_MISO_PX7 _GPIO(191)
#define TEGRA_PIN_ULPI_CLK_PY0 _GPIO(192)
#define TEGRA_PIN_ULPI_DIR_PY1 _GPIO(193)
#define TEGRA_PIN_ULPI_NXT_PY2 _GPIO(194)
#define TEGRA_PIN_ULPI_STP_PY3 _GPIO(195)
#define TEGRA_PIN_SDIO1_DAT3_PY4 _GPIO(196)
#define TEGRA_PIN_SDIO1_DAT2_PY5 _GPIO(197)
#define TEGRA_PIN_SDIO1_DAT1_PY6 _GPIO(198)
#define TEGRA_PIN_SDIO1_DAT0_PY7 _GPIO(199)
#define TEGRA_PIN_SDIO1_CLK_PZ0 _GPIO(200)
#define TEGRA_PIN_SDIO1_CMD_PZ1 _GPIO(201)
#define TEGRA_PIN_LCD_SDIN_PZ2 _GPIO(202)
#define TEGRA_PIN_LCD_WR_N_PZ3 _GPIO(203)
#define TEGRA_PIN_LCD_SCK_PZ4 _GPIO(204)
#define TEGRA_PIN_SYS_CLK_REQ_PZ5 _GPIO(205)
#define TEGRA_PIN_PWR_I2C_SCL_PZ6 _GPIO(206)
#define TEGRA_PIN_PWR_I2C_SDA_PZ7 _GPIO(207)
#define TEGRA_PIN_GMI_AD20_PAA0 _GPIO(208)
#define TEGRA_PIN_GMI_AD21_PAA1 _GPIO(209)
#define TEGRA_PIN_GMI_AD22_PAA2 _GPIO(210)
#define TEGRA_PIN_GMI_AD23_PAA3 _GPIO(211)
#define TEGRA_PIN_GMI_AD24_PAA4 _GPIO(212)
#define TEGRA_PIN_GMI_AD25_PAA5 _GPIO(213)
#define TEGRA_PIN_GMI_AD26_PAA6 _GPIO(214)
#define TEGRA_PIN_GMI_AD27_PAA7 _GPIO(215)
#define TEGRA_PIN_LED_BLINK_PBB0 _GPIO(216)
#define TEGRA_PIN_VI_GP0_PBB1 _GPIO(217)
#define TEGRA_PIN_CAM_I2C_SCL_PBB2 _GPIO(218)
#define TEGRA_PIN_CAM_I2C_SDA_PBB3 _GPIO(219)
#define TEGRA_PIN_VI_GP3_PBB4 _GPIO(220)
#define TEGRA_PIN_VI_GP4_PBB5 _GPIO(221)
#define TEGRA_PIN_PBB6 _GPIO(222)
#define TEGRA_PIN_PBB7 _GPIO(223)
/* All non-GPIO pins follow */
#define NUM_GPIOS (TEGRA_PIN_PBB7 + 1)
#define _PIN(offset) (NUM_GPIOS + (offset))
#define TEGRA_PIN_CRT_HSYNC _PIN(30)
#define TEGRA_PIN_CRT_VSYNC _PIN(31)
#define TEGRA_PIN_DDC_SCL _PIN(32)
#define TEGRA_PIN_DDC_SDA _PIN(33)
#define TEGRA_PIN_OWC _PIN(34)
#define TEGRA_PIN_CORE_PWR_REQ _PIN(35)
#define TEGRA_PIN_CPU_PWR_REQ _PIN(36)
#define TEGRA_PIN_PWR_INT_N _PIN(37)
#define TEGRA_PIN_CLK_32_K_IN _PIN(38)
#define TEGRA_PIN_DDR_COMP_PD _PIN(39)
#define TEGRA_PIN_DDR_COMP_PU _PIN(40)
#define TEGRA_PIN_DDR_A0 _PIN(41)
#define TEGRA_PIN_DDR_A1 _PIN(42)
#define TEGRA_PIN_DDR_A2 _PIN(43)
#define TEGRA_PIN_DDR_A3 _PIN(44)
#define TEGRA_PIN_DDR_A4 _PIN(45)
#define TEGRA_PIN_DDR_A5 _PIN(46)
#define TEGRA_PIN_DDR_A6 _PIN(47)
#define TEGRA_PIN_DDR_A7 _PIN(48)
#define TEGRA_PIN_DDR_A8 _PIN(49)
#define TEGRA_PIN_DDR_A9 _PIN(50)
#define TEGRA_PIN_DDR_A10 _PIN(51)
#define TEGRA_PIN_DDR_A11 _PIN(52)
#define TEGRA_PIN_DDR_A12 _PIN(53)
#define TEGRA_PIN_DDR_A13 _PIN(54)
#define TEGRA_PIN_DDR_A14 _PIN(55)
#define TEGRA_PIN_DDR_CAS_N _PIN(56)
#define TEGRA_PIN_DDR_BA0 _PIN(57)
#define TEGRA_PIN_DDR_BA1 _PIN(58)
#define TEGRA_PIN_DDR_BA2 _PIN(59)
#define TEGRA_PIN_DDR_DQS0P _PIN(60)
#define TEGRA_PIN_DDR_DQS0N _PIN(61)
#define TEGRA_PIN_DDR_DQS1P _PIN(62)
#define TEGRA_PIN_DDR_DQS1N _PIN(63)
#define TEGRA_PIN_DDR_DQS2P _PIN(64)
#define TEGRA_PIN_DDR_DQS2N _PIN(65)
#define TEGRA_PIN_DDR_DQS3P _PIN(66)
#define TEGRA_PIN_DDR_DQS3N _PIN(67)
#define TEGRA_PIN_DDR_CKE0 _PIN(68)
#define TEGRA_PIN_DDR_CKE1 _PIN(69)
#define TEGRA_PIN_DDR_CLK _PIN(70)
#define TEGRA_PIN_DDR_CLK_N _PIN(71)
#define TEGRA_PIN_DDR_DM0 _PIN(72)
#define TEGRA_PIN_DDR_DM1 _PIN(73)
#define TEGRA_PIN_DDR_DM2 _PIN(74)
#define TEGRA_PIN_DDR_DM3 _PIN(75)
#define TEGRA_PIN_DDR_ODT _PIN(76)
#define TEGRA_PIN_DDR_QUSE0 _PIN(77)
#define TEGRA_PIN_DDR_QUSE1 _PIN(78)
#define TEGRA_PIN_DDR_QUSE2 _PIN(79)
#define TEGRA_PIN_DDR_QUSE3 _PIN(80)
#define TEGRA_PIN_DDR_RAS_N _PIN(81)
#define TEGRA_PIN_DDR_WE_N _PIN(82)
#define TEGRA_PIN_DDR_DQ0 _PIN(83)
#define TEGRA_PIN_DDR_DQ1 _PIN(84)
#define TEGRA_PIN_DDR_DQ2 _PIN(85)
#define TEGRA_PIN_DDR_DQ3 _PIN(86)
#define TEGRA_PIN_DDR_DQ4 _PIN(87)
#define TEGRA_PIN_DDR_DQ5 _PIN(88)
#define TEGRA_PIN_DDR_DQ6 _PIN(89)
#define TEGRA_PIN_DDR_DQ7 _PIN(90)
#define TEGRA_PIN_DDR_DQ8 _PIN(91)
#define TEGRA_PIN_DDR_DQ9 _PIN(92)
#define TEGRA_PIN_DDR_DQ10 _PIN(93)
#define TEGRA_PIN_DDR_DQ11 _PIN(94)
#define TEGRA_PIN_DDR_DQ12 _PIN(95)
#define TEGRA_PIN_DDR_DQ13 _PIN(96)
#define TEGRA_PIN_DDR_DQ14 _PIN(97)
#define TEGRA_PIN_DDR_DQ15 _PIN(98)
#define TEGRA_PIN_DDR_DQ16 _PIN(99)
#define TEGRA_PIN_DDR_DQ17 _PIN(100)
#define TEGRA_PIN_DDR_DQ18 _PIN(101)
#define TEGRA_PIN_DDR_DQ19 _PIN(102)
#define TEGRA_PIN_DDR_DQ20 _PIN(103)
#define TEGRA_PIN_DDR_DQ21 _PIN(104)
#define TEGRA_PIN_DDR_DQ22 _PIN(105)
#define TEGRA_PIN_DDR_DQ23 _PIN(106)
#define TEGRA_PIN_DDR_DQ24 _PIN(107)
#define TEGRA_PIN_DDR_DQ25 _PIN(108)
#define TEGRA_PIN_DDR_DQ26 _PIN(109)
#define TEGRA_PIN_DDR_DQ27 _PIN(110)
#define TEGRA_PIN_DDR_DQ28 _PIN(111)
#define TEGRA_PIN_DDR_DQ29 _PIN(112)
#define TEGRA_PIN_DDR_DQ30 _PIN(113)
#define TEGRA_PIN_DDR_DQ31 _PIN(114)
#define TEGRA_PIN_DDR_CS0_N _PIN(115)
#define TEGRA_PIN_DDR_CS1_N _PIN(116)
#define TEGRA_PIN_SYS_RESET _PIN(117)
#define TEGRA_PIN_JTAG_TRST_N _PIN(118)
#define TEGRA_PIN_JTAG_TDO _PIN(119)
#define TEGRA_PIN_JTAG_TMS _PIN(120)
#define TEGRA_PIN_JTAG_TCK _PIN(121)
#define TEGRA_PIN_JTAG_TDI _PIN(122)
#define TEGRA_PIN_TEST_MODE_EN _PIN(123)
static const struct pinctrl_pin_desc tegra20_pins[] = {
PINCTRL_PIN(TEGRA_PIN_VI_GP6_PA0, "VI_GP6 PA0"),
PINCTRL_PIN(TEGRA_PIN_UART3_CTS_N_PA1, "UART3_CTS_N PA1"),
PINCTRL_PIN(TEGRA_PIN_DAP2_FS_PA2, "DAP2_FS PA2"),
PINCTRL_PIN(TEGRA_PIN_DAP2_SCLK_PA3, "DAP2_SCLK PA3"),
PINCTRL_PIN(TEGRA_PIN_DAP2_DIN_PA4, "DAP2_DIN PA4"),
PINCTRL_PIN(TEGRA_PIN_DAP2_DOUT_PA5, "DAP2_DOUT PA5"),
PINCTRL_PIN(TEGRA_PIN_SDIO3_CLK_PA6, "SDIO3_CLK PA6"),
PINCTRL_PIN(TEGRA_PIN_SDIO3_CMD_PA7, "SDIO3_CMD PA7"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD17_PB0, "GMI_AD17 PB0"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD18_PB1, "GMI_AD18 PB1"),
PINCTRL_PIN(TEGRA_PIN_LCD_PWR0_PB2, "LCD_PWR0 PB2"),
PINCTRL_PIN(TEGRA_PIN_LCD_PCLK_PB3, "LCD_PCLK PB3"),
PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT3_PB4, "SDIO3_DAT3 PB4"),
PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT2_PB5, "SDIO3_DAT2 PB5"),
PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT1_PB6, "SDIO3_DAT1 PB6"),
PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT0_PB7, "SDIO3_DAT0 PB7"),
PINCTRL_PIN(TEGRA_PIN_UART3_RTS_N_PC0, "UART3_RTS_N PC0"),
PINCTRL_PIN(TEGRA_PIN_LCD_PWR1_PC1, "LCD_PWR1 PC1"),
PINCTRL_PIN(TEGRA_PIN_UART2_TXD_PC2, "UART2_TXD PC2"),
PINCTRL_PIN(TEGRA_PIN_UART2_RXD_PC3, "UART2_RXD PC3"),
PINCTRL_PIN(TEGRA_PIN_GEN1_I2C_SCL_PC4, "GEN1_I2C_SCL PC4"),
PINCTRL_PIN(TEGRA_PIN_GEN1_I2C_SDA_PC5, "GEN1_I2C_SDA PC5"),
PINCTRL_PIN(TEGRA_PIN_LCD_PWR2_PC6, "LCD_PWR2 PC6"),
PINCTRL_PIN(TEGRA_PIN_GMI_WP_N_PC7, "GMI_WP_N PC7"),
PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT5_PD0, "SDIO3_DAT5 PD0"),
PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT4_PD1, "SDIO3_DAT4 PD1"),
PINCTRL_PIN(TEGRA_PIN_VI_GP5_PD2, "VI_GP5 PD2"),
PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT6_PD3, "SDIO3_DAT6 PD3"),
PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT7_PD4, "SDIO3_DAT7 PD4"),
PINCTRL_PIN(TEGRA_PIN_VI_D1_PD5, "VI_D1 PD5"),
PINCTRL_PIN(TEGRA_PIN_VI_VSYNC_PD6, "VI_VSYNC PD6"),
PINCTRL_PIN(TEGRA_PIN_VI_HSYNC_PD7, "VI_HSYNC PD7"),
PINCTRL_PIN(TEGRA_PIN_LCD_D0_PE0, "LCD_D0 PE0"),
PINCTRL_PIN(TEGRA_PIN_LCD_D1_PE1, "LCD_D1 PE1"),
PINCTRL_PIN(TEGRA_PIN_LCD_D2_PE2, "LCD_D2 PE2"),
PINCTRL_PIN(TEGRA_PIN_LCD_D3_PE3, "LCD_D3 PE3"),
PINCTRL_PIN(TEGRA_PIN_LCD_D4_PE4, "LCD_D4 PE4"),
PINCTRL_PIN(TEGRA_PIN_LCD_D5_PE5, "LCD_D5 PE5"),
PINCTRL_PIN(TEGRA_PIN_LCD_D6_PE6, "LCD_D6 PE6"),
PINCTRL_PIN(TEGRA_PIN_LCD_D7_PE7, "LCD_D7 PE7"),
PINCTRL_PIN(TEGRA_PIN_LCD_D8_PF0, "LCD_D8 PF0"),
PINCTRL_PIN(TEGRA_PIN_LCD_D9_PF1, "LCD_D9 PF1"),
PINCTRL_PIN(TEGRA_PIN_LCD_D10_PF2, "LCD_D10 PF2"),
PINCTRL_PIN(TEGRA_PIN_LCD_D11_PF3, "LCD_D11 PF3"),
PINCTRL_PIN(TEGRA_PIN_LCD_D12_PF4, "LCD_D12 PF4"),
PINCTRL_PIN(TEGRA_PIN_LCD_D13_PF5, "LCD_D13 PF5"),
PINCTRL_PIN(TEGRA_PIN_LCD_D14_PF6, "LCD_D14 PF6"),
PINCTRL_PIN(TEGRA_PIN_LCD_D15_PF7, "LCD_D15 PF7"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD0_PG0, "GMI_AD0 PG0"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD1_PG1, "GMI_AD1 PG1"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD2_PG2, "GMI_AD2 PG2"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD3_PG3, "GMI_AD3 PG3"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD4_PG4, "GMI_AD4 PG4"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD5_PG5, "GMI_AD5 PG5"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD6_PG6, "GMI_AD6 PG6"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD7_PG7, "GMI_AD7 PG7"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD8_PH0, "GMI_AD8 PH0"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD9_PH1, "GMI_AD9 PH1"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD10_PH2, "GMI_AD10 PH2"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD11_PH3, "GMI_AD11 PH3"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD12_PH4, "GMI_AD12 PH4"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD13_PH5, "GMI_AD13 PH5"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD14_PH6, "GMI_AD14 PH6"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD15_PH7, "GMI_AD15 PH7"),
PINCTRL_PIN(TEGRA_PIN_GMI_HIOW_N_PI0, "GMI_HIOW_N PI0"),
PINCTRL_PIN(TEGRA_PIN_GMI_HIOR_N_PI1, "GMI_HIOR_N PI1"),
PINCTRL_PIN(TEGRA_PIN_GMI_CS5_N_PI2, "GMI_CS5_N PI2"),
PINCTRL_PIN(TEGRA_PIN_GMI_CS6_N_PI3, "GMI_CS6_N PI3"),
PINCTRL_PIN(TEGRA_PIN_GMI_RST_N_PI4, "GMI_RST_N PI4"),
PINCTRL_PIN(TEGRA_PIN_GMI_IORDY_PI5, "GMI_IORDY PI5"),
PINCTRL_PIN(TEGRA_PIN_GMI_CS7_N_PI6, "GMI_CS7_N PI6"),
PINCTRL_PIN(TEGRA_PIN_GMI_WAIT_PI7, "GMI_WAIT PI7"),
PINCTRL_PIN(TEGRA_PIN_GMI_CS0_N_PJ0, "GMI_CS0_N PJ0"),
PINCTRL_PIN(TEGRA_PIN_LCD_DE_PJ1, "LCD_DE PJ1"),
PINCTRL_PIN(TEGRA_PIN_GMI_CS1_N_PJ2, "GMI_CS1_N PJ2"),
PINCTRL_PIN(TEGRA_PIN_LCD_HSYNC_PJ3, "LCD_HSYNC PJ3"),
PINCTRL_PIN(TEGRA_PIN_LCD_VSYNC_PJ4, "LCD_VSYNC PJ4"),
PINCTRL_PIN(TEGRA_PIN_UART2_CTS_N_PJ5, "UART2_CTS_N PJ5"),
PINCTRL_PIN(TEGRA_PIN_UART2_RTS_N_PJ6, "UART2_RTS_N PJ6"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD16_PJ7, "GMI_AD16 PJ7"),
PINCTRL_PIN(TEGRA_PIN_GMI_ADV_N_PK0, "GMI_ADV_N PK0"),
PINCTRL_PIN(TEGRA_PIN_GMI_CLK_PK1, "GMI_CLK PK1"),
PINCTRL_PIN(TEGRA_PIN_GMI_CS4_N_PK2, "GMI_CS4_N PK2"),
PINCTRL_PIN(TEGRA_PIN_GMI_CS2_N_PK3, "GMI_CS2_N PK3"),
PINCTRL_PIN(TEGRA_PIN_GMI_CS3_N_PK4, "GMI_CS3_N PK4"),
PINCTRL_PIN(TEGRA_PIN_SPDIF_OUT_PK5, "SPDIF_OUT PK5"),
PINCTRL_PIN(TEGRA_PIN_SPDIF_IN_PK6, "SPDIF_IN PK6"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD19_PK7, "GMI_AD19 PK7"),
PINCTRL_PIN(TEGRA_PIN_VI_D2_PL0, "VI_D2 PL0"),
PINCTRL_PIN(TEGRA_PIN_VI_D3_PL1, "VI_D3 PL1"),
PINCTRL_PIN(TEGRA_PIN_VI_D4_PL2, "VI_D4 PL2"),
PINCTRL_PIN(TEGRA_PIN_VI_D5_PL3, "VI_D5 PL3"),
PINCTRL_PIN(TEGRA_PIN_VI_D6_PL4, "VI_D6 PL4"),
PINCTRL_PIN(TEGRA_PIN_VI_D7_PL5, "VI_D7 PL5"),
PINCTRL_PIN(TEGRA_PIN_VI_D8_PL6, "VI_D8 PL6"),
PINCTRL_PIN(TEGRA_PIN_VI_D9_PL7, "VI_D9 PL7"),
PINCTRL_PIN(TEGRA_PIN_LCD_D16_PM0, "LCD_D16 PM0"),
PINCTRL_PIN(TEGRA_PIN_LCD_D17_PM1, "LCD_D17 PM1"),
PINCTRL_PIN(TEGRA_PIN_LCD_D18_PM2, "LCD_D18 PM2"),
PINCTRL_PIN(TEGRA_PIN_LCD_D19_PM3, "LCD_D19 PM3"),
PINCTRL_PIN(TEGRA_PIN_LCD_D20_PM4, "LCD_D20 PM4"),
PINCTRL_PIN(TEGRA_PIN_LCD_D21_PM5, "LCD_D21 PM5"),
PINCTRL_PIN(TEGRA_PIN_LCD_D22_PM6, "LCD_D22 PM6"),
PINCTRL_PIN(TEGRA_PIN_LCD_D23_PM7, "LCD_D23 PM7"),
PINCTRL_PIN(TEGRA_PIN_DAP1_FS_PN0, "DAP1_FS PN0"),
PINCTRL_PIN(TEGRA_PIN_DAP1_DIN_PN1, "DAP1_DIN PN1"),
PINCTRL_PIN(TEGRA_PIN_DAP1_DOUT_PN2, "DAP1_DOUT PN2"),
PINCTRL_PIN(TEGRA_PIN_DAP1_SCLK_PN3, "DAP1_SCLK PN3"),
PINCTRL_PIN(TEGRA_PIN_LCD_CS0_N_PN4, "LCD_CS0_N PN4"),
PINCTRL_PIN(TEGRA_PIN_LCD_SDOUT_PN5, "LCD_SDOUT PN5"),
PINCTRL_PIN(TEGRA_PIN_LCD_DC0_PN6, "LCD_DC0 PN6"),
PINCTRL_PIN(TEGRA_PIN_HDMI_INT_N_PN7, "HDMI_INT_N PN7"),
PINCTRL_PIN(TEGRA_PIN_ULPI_DATA7_PO0, "ULPI_DATA7 PO0"),
PINCTRL_PIN(TEGRA_PIN_ULPI_DATA0_PO1, "ULPI_DATA0 PO1"),
PINCTRL_PIN(TEGRA_PIN_ULPI_DATA1_PO2, "ULPI_DATA1 PO2"),
PINCTRL_PIN(TEGRA_PIN_ULPI_DATA2_PO3, "ULPI_DATA2 PO3"),
PINCTRL_PIN(TEGRA_PIN_ULPI_DATA3_PO4, "ULPI_DATA3 PO4"),
PINCTRL_PIN(TEGRA_PIN_ULPI_DATA4_PO5, "ULPI_DATA4 PO5"),
PINCTRL_PIN(TEGRA_PIN_ULPI_DATA5_PO6, "ULPI_DATA5 PO6"),
PINCTRL_PIN(TEGRA_PIN_ULPI_DATA6_PO7, "ULPI_DATA6 PO7"),
PINCTRL_PIN(TEGRA_PIN_DAP3_FS_PP0, "DAP3_FS PP0"),
PINCTRL_PIN(TEGRA_PIN_DAP3_DIN_PP1, "DAP3_DIN PP1"),
PINCTRL_PIN(TEGRA_PIN_DAP3_DOUT_PP2, "DAP3_DOUT PP2"),
PINCTRL_PIN(TEGRA_PIN_DAP3_SCLK_PP3, "DAP3_SCLK PP3"),
PINCTRL_PIN(TEGRA_PIN_DAP4_FS_PP4, "DAP4_FS PP4"),
PINCTRL_PIN(TEGRA_PIN_DAP4_DIN_PP5, "DAP4_DIN PP5"),
PINCTRL_PIN(TEGRA_PIN_DAP4_DOUT_PP6, "DAP4_DOUT PP6"),
PINCTRL_PIN(TEGRA_PIN_DAP4_SCLK_PP7, "DAP4_SCLK PP7"),
PINCTRL_PIN(TEGRA_PIN_KB_COL0_PQ0, "KB_COL0 PQ0"),
PINCTRL_PIN(TEGRA_PIN_KB_COL1_PQ1, "KB_COL1 PQ1"),
PINCTRL_PIN(TEGRA_PIN_KB_COL2_PQ2, "KB_COL2 PQ2"),
PINCTRL_PIN(TEGRA_PIN_KB_COL3_PQ3, "KB_COL3 PQ3"),
PINCTRL_PIN(TEGRA_PIN_KB_COL4_PQ4, "KB_COL4 PQ4"),
PINCTRL_PIN(TEGRA_PIN_KB_COL5_PQ5, "KB_COL5 PQ5"),
PINCTRL_PIN(TEGRA_PIN_KB_COL6_PQ6, "KB_COL6 PQ6"),
PINCTRL_PIN(TEGRA_PIN_KB_COL7_PQ7, "KB_COL7 PQ7"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW0_PR0, "KB_ROW0 PR0"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW1_PR1, "KB_ROW1 PR1"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW2_PR2, "KB_ROW2 PR2"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW3_PR3, "KB_ROW3 PR3"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW4_PR4, "KB_ROW4 PR4"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW5_PR5, "KB_ROW5 PR5"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW6_PR6, "KB_ROW6 PR6"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW7_PR7, "KB_ROW7 PR7"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW8_PS0, "KB_ROW8 PS0"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW9_PS1, "KB_ROW9 PS1"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW10_PS2, "KB_ROW10 PS2"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW11_PS3, "KB_ROW11 PS3"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW12_PS4, "KB_ROW12 PS4"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW13_PS5, "KB_ROW13 PS5"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW14_PS6, "KB_ROW14 PS6"),
PINCTRL_PIN(TEGRA_PIN_KB_ROW15_PS7, "KB_ROW15 PS7"),
PINCTRL_PIN(TEGRA_PIN_VI_PCLK_PT0, "VI_PCLK PT0"),
PINCTRL_PIN(TEGRA_PIN_VI_MCLK_PT1, "VI_MCLK PT1"),
PINCTRL_PIN(TEGRA_PIN_VI_D10_PT2, "VD_D10 PT2"),
PINCTRL_PIN(TEGRA_PIN_VI_D11_PT3, "VI_D11 PT3"),
PINCTRL_PIN(TEGRA_PIN_VI_D0_PT4, "VI_D0 PT4"),
PINCTRL_PIN(TEGRA_PIN_GEN2_I2C_SCL_PT5, "GEN2_I2C_SCL PT5"),
PINCTRL_PIN(TEGRA_PIN_GEN2_I2C_SDA_PT6, "GEN2_I2C_SDA PT6"),
PINCTRL_PIN(TEGRA_PIN_GMI_DPD_PT7, "GMI_DPD PT7"),
/* PU0..6: GPIO only */
PINCTRL_PIN(TEGRA_PIN_PU0, "PU0"),
PINCTRL_PIN(TEGRA_PIN_PU1, "PU1"),
PINCTRL_PIN(TEGRA_PIN_PU2, "PU2"),
PINCTRL_PIN(TEGRA_PIN_PU3, "PU3"),
PINCTRL_PIN(TEGRA_PIN_PU4, "PU4"),
PINCTRL_PIN(TEGRA_PIN_PU5, "PU5"),
PINCTRL_PIN(TEGRA_PIN_PU6, "PU6"),
PINCTRL_PIN(TEGRA_PIN_JTAG_RTCK_PU7, "JTAG_RTCK PU7"),
/* PV0..1: GPIO only */
PINCTRL_PIN(TEGRA_PIN_PV0, "PV0"),
PINCTRL_PIN(TEGRA_PIN_PV1, "PV1"),
/* PV2..3: Balls are named after GPIO not function */
PINCTRL_PIN(TEGRA_PIN_PV2, "PV2"),
PINCTRL_PIN(TEGRA_PIN_PV3, "PV3"),
/* PV4..6: GPIO only */
PINCTRL_PIN(TEGRA_PIN_PV4, "PV4"),
PINCTRL_PIN(TEGRA_PIN_PV5, "PV5"),
PINCTRL_PIN(TEGRA_PIN_PV6, "PV6"),
PINCTRL_PIN(TEGRA_PIN_LCD_DC1_PV7, "LCD_DC1 PV7"),
PINCTRL_PIN(TEGRA_PIN_LCD_CS1_N_PW0, "LCD_CS1_N PW0"),
PINCTRL_PIN(TEGRA_PIN_LCD_M1_PW1, "LCD_M1 PW1"),
PINCTRL_PIN(TEGRA_PIN_SPI2_CS1_N_PW2, "SPI2_CS1_N PW2"),
PINCTRL_PIN(TEGRA_PIN_SPI2_CS2_N_PW3, "SPI2_CS2_N PW3"),
PINCTRL_PIN(TEGRA_PIN_DAP_MCLK1_PW4, "DAP_MCLK1 PW4"),
PINCTRL_PIN(TEGRA_PIN_DAP_MCLK2_PW5, "DAP_MCLK2 PW5"),
PINCTRL_PIN(TEGRA_PIN_UART3_TXD_PW6, "UART3_TXD PW6"),
PINCTRL_PIN(TEGRA_PIN_UART3_RXD_PW7, "UART3_RXD PW7"),
PINCTRL_PIN(TEGRA_PIN_SPI2_MOSI_PX0, "SPI2_MOSI PX0"),
PINCTRL_PIN(TEGRA_PIN_SPI2_MISO_PX1, "SPI2_MISO PX1"),
PINCTRL_PIN(TEGRA_PIN_SPI2_SCK_PX2, "SPI2_SCK PX2"),
PINCTRL_PIN(TEGRA_PIN_SPI2_CS0_N_PX3, "SPI2_CS0_N PX3"),
PINCTRL_PIN(TEGRA_PIN_SPI1_MOSI_PX4, "SPI1_MOSI PX4"),
PINCTRL_PIN(TEGRA_PIN_SPI1_SCK_PX5, "SPI1_SCK PX5"),
PINCTRL_PIN(TEGRA_PIN_SPI1_CS0_N_PX6, "SPI1_CS0_N PX6"),
PINCTRL_PIN(TEGRA_PIN_SPI1_MISO_PX7, "SPI1_MISO PX7"),
PINCTRL_PIN(TEGRA_PIN_ULPI_CLK_PY0, "ULPI_CLK PY0"),
PINCTRL_PIN(TEGRA_PIN_ULPI_DIR_PY1, "ULPI_DIR PY1"),
PINCTRL_PIN(TEGRA_PIN_ULPI_NXT_PY2, "ULPI_NXT PY2"),
PINCTRL_PIN(TEGRA_PIN_ULPI_STP_PY3, "ULPI_STP PY3"),
PINCTRL_PIN(TEGRA_PIN_SDIO1_DAT3_PY4, "SDIO1_DAT3 PY4"),
PINCTRL_PIN(TEGRA_PIN_SDIO1_DAT2_PY5, "SDIO1_DAT2 PY5"),
PINCTRL_PIN(TEGRA_PIN_SDIO1_DAT1_PY6, "SDIO1_DAT1 PY6"),
PINCTRL_PIN(TEGRA_PIN_SDIO1_DAT0_PY7, "SDIO1_DAT0 PY7"),
PINCTRL_PIN(TEGRA_PIN_SDIO1_CLK_PZ0, "SDIO1_CLK PZ0"),
PINCTRL_PIN(TEGRA_PIN_SDIO1_CMD_PZ1, "SDIO1_CMD PZ1"),
PINCTRL_PIN(TEGRA_PIN_LCD_SDIN_PZ2, "LCD_SDIN PZ2"),
PINCTRL_PIN(TEGRA_PIN_LCD_WR_N_PZ3, "LCD_WR_N PZ3"),
PINCTRL_PIN(TEGRA_PIN_LCD_SCK_PZ4, "LCD_SCK PZ4"),
PINCTRL_PIN(TEGRA_PIN_SYS_CLK_REQ_PZ5, "SYS_CLK_REQ PZ5"),
PINCTRL_PIN(TEGRA_PIN_PWR_I2C_SCL_PZ6, "PWR_I2C_SCL PZ6"),
PINCTRL_PIN(TEGRA_PIN_PWR_I2C_SDA_PZ7, "PWR_I2C_SDA PZ7"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD20_PAA0, "GMI_AD20 PAA0"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD21_PAA1, "GMI_AD21 PAA1"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD22_PAA2, "GMI_AD22 PAA2"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD23_PAA3, "GMI_AD23 PAA3"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD24_PAA4, "GMI_AD24 PAA4"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD25_PAA5, "GMI_AD25 PAA5"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD26_PAA6, "GMI_AD26 PAA6"),
PINCTRL_PIN(TEGRA_PIN_GMI_AD27_PAA7, "GMI_AD27 PAA7"),
PINCTRL_PIN(TEGRA_PIN_LED_BLINK_PBB0, "LED_BLINK PBB0"),
PINCTRL_PIN(TEGRA_PIN_VI_GP0_PBB1, "VI_GP0 PBB1"),
PINCTRL_PIN(TEGRA_PIN_CAM_I2C_SCL_PBB2, "CAM_I2C_SCL PBB2"),
PINCTRL_PIN(TEGRA_PIN_CAM_I2C_SDA_PBB3, "CAM_I2C_SDA PBB3"),
PINCTRL_PIN(TEGRA_PIN_VI_GP3_PBB4, "VI_GP3 PBB4"),
PINCTRL_PIN(TEGRA_PIN_VI_GP4_PBB5, "VI_GP4 PBB5"),
PINCTRL_PIN(TEGRA_PIN_PBB6, "PBB6"),
PINCTRL_PIN(TEGRA_PIN_PBB7, "PBB7"),
PINCTRL_PIN(TEGRA_PIN_CRT_HSYNC, "CRT_HSYNC"),
PINCTRL_PIN(TEGRA_PIN_CRT_VSYNC, "CRT_VSYNC"),
PINCTRL_PIN(TEGRA_PIN_DDC_SCL, "DDC_SCL"),
PINCTRL_PIN(TEGRA_PIN_DDC_SDA, "DDC_SDA"),
PINCTRL_PIN(TEGRA_PIN_OWC, "OWC"),
PINCTRL_PIN(TEGRA_PIN_CORE_PWR_REQ, "CORE_PWR_REQ"),
PINCTRL_PIN(TEGRA_PIN_CPU_PWR_REQ, "CPU_PWR_REQ"),
PINCTRL_PIN(TEGRA_PIN_PWR_INT_N, "PWR_INT_N"),
PINCTRL_PIN(TEGRA_PIN_CLK_32_K_IN, "CLK_32_K_IN"),
PINCTRL_PIN(TEGRA_PIN_DDR_COMP_PD, "DDR_COMP_PD"),
PINCTRL_PIN(TEGRA_PIN_DDR_COMP_PU, "DDR_COMP_PU"),
PINCTRL_PIN(TEGRA_PIN_DDR_A0, "DDR_A0"),
PINCTRL_PIN(TEGRA_PIN_DDR_A1, "DDR_A1"),
PINCTRL_PIN(TEGRA_PIN_DDR_A2, "DDR_A2"),
PINCTRL_PIN(TEGRA_PIN_DDR_A3, "DDR_A3"),
PINCTRL_PIN(TEGRA_PIN_DDR_A4, "DDR_A4"),
PINCTRL_PIN(TEGRA_PIN_DDR_A5, "DDR_A5"),
PINCTRL_PIN(TEGRA_PIN_DDR_A6, "DDR_A6"),
PINCTRL_PIN(TEGRA_PIN_DDR_A7, "DDR_A7"),
PINCTRL_PIN(TEGRA_PIN_DDR_A8, "DDR_A8"),
PINCTRL_PIN(TEGRA_PIN_DDR_A9, "DDR_A9"),
PINCTRL_PIN(TEGRA_PIN_DDR_A10, "DDR_A10"),
PINCTRL_PIN(TEGRA_PIN_DDR_A11, "DDR_A11"),
PINCTRL_PIN(TEGRA_PIN_DDR_A12, "DDR_A12"),
PINCTRL_PIN(TEGRA_PIN_DDR_A13, "DDR_A13"),
PINCTRL_PIN(TEGRA_PIN_DDR_A14, "DDR_A14"),
PINCTRL_PIN(TEGRA_PIN_DDR_CAS_N, "DDR_CAS_N"),
PINCTRL_PIN(TEGRA_PIN_DDR_BA0, "DDR_BA0"),
PINCTRL_PIN(TEGRA_PIN_DDR_BA1, "DDR_BA1"),
PINCTRL_PIN(TEGRA_PIN_DDR_BA2, "DDR_BA2"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQS0P, "DDR_DQS0P"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQS0N, "DDR_DQS0N"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQS1P, "DDR_DQS1P"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQS1N, "DDR_DQS1N"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQS2P, "DDR_DQS2P"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQS2N, "DDR_DQS2N"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQS3P, "DDR_DQS3P"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQS3N, "DDR_DQS3N"),
PINCTRL_PIN(TEGRA_PIN_DDR_CKE0, "DDR_CKE0"),
PINCTRL_PIN(TEGRA_PIN_DDR_CKE1, "DDR_CKE1"),
PINCTRL_PIN(TEGRA_PIN_DDR_CLK, "DDR_CLK"),
PINCTRL_PIN(TEGRA_PIN_DDR_CLK_N, "DDR_CLK_N"),
PINCTRL_PIN(TEGRA_PIN_DDR_DM0, "DDR_DM0"),
PINCTRL_PIN(TEGRA_PIN_DDR_DM1, "DDR_DM1"),
PINCTRL_PIN(TEGRA_PIN_DDR_DM2, "DDR_DM2"),
PINCTRL_PIN(TEGRA_PIN_DDR_DM3, "DDR_DM3"),
PINCTRL_PIN(TEGRA_PIN_DDR_ODT, "DDR_ODT"),
PINCTRL_PIN(TEGRA_PIN_DDR_QUSE0, "DDR_QUSE0"),
PINCTRL_PIN(TEGRA_PIN_DDR_QUSE1, "DDR_QUSE1"),
PINCTRL_PIN(TEGRA_PIN_DDR_QUSE2, "DDR_QUSE2"),
PINCTRL_PIN(TEGRA_PIN_DDR_QUSE3, "DDR_QUSE3"),
PINCTRL_PIN(TEGRA_PIN_DDR_RAS_N, "DDR_RAS_N"),
PINCTRL_PIN(TEGRA_PIN_DDR_WE_N, "DDR_WE_N"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ0, "DDR_DQ0"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ1, "DDR_DQ1"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ2, "DDR_DQ2"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ3, "DDR_DQ3"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ4, "DDR_DQ4"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ5, "DDR_DQ5"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ6, "DDR_DQ6"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ7, "DDR_DQ7"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ8, "DDR_DQ8"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ9, "DDR_DQ9"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ10, "DDR_DQ10"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ11, "DDR_DQ11"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ12, "DDR_DQ12"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ13, "DDR_DQ13"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ14, "DDR_DQ14"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ15, "DDR_DQ15"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ16, "DDR_DQ16"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ17, "DDR_DQ17"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ18, "DDR_DQ18"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ19, "DDR_DQ19"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ20, "DDR_DQ20"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ21, "DDR_DQ21"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ22, "DDR_DQ22"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ23, "DDR_DQ23"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ24, "DDR_DQ24"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ25, "DDR_DQ25"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ26, "DDR_DQ26"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ27, "DDR_DQ27"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ28, "DDR_DQ28"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ29, "DDR_DQ29"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ30, "DDR_DQ30"),
PINCTRL_PIN(TEGRA_PIN_DDR_DQ31, "DDR_DQ31"),
PINCTRL_PIN(TEGRA_PIN_DDR_CS0_N, "DDR_CS0_N"),
PINCTRL_PIN(TEGRA_PIN_DDR_CS1_N, "DDR_CS1_N"),
PINCTRL_PIN(TEGRA_PIN_SYS_RESET, "SYS_RESET"),
PINCTRL_PIN(TEGRA_PIN_JTAG_TRST_N, "JTAG_TRST_N"),
PINCTRL_PIN(TEGRA_PIN_JTAG_TDO, "JTAG_TDO"),
PINCTRL_PIN(TEGRA_PIN_JTAG_TMS, "JTAG_TMS"),
PINCTRL_PIN(TEGRA_PIN_JTAG_TCK, "JTAG_TCK"),
PINCTRL_PIN(TEGRA_PIN_JTAG_TDI, "JTAG_TDI"),
PINCTRL_PIN(TEGRA_PIN_TEST_MODE_EN, "TEST_MODE_EN"),
};
static const unsigned ata_pins[] = {
TEGRA_PIN_GMI_CS6_N_PI3,
TEGRA_PIN_GMI_CS7_N_PI6,
TEGRA_PIN_GMI_RST_N_PI4,
};
static const unsigned atb_pins[] = {
TEGRA_PIN_GMI_CS5_N_PI2,
TEGRA_PIN_GMI_DPD_PT7,
};
static const unsigned atc_pins[] = {
TEGRA_PIN_GMI_IORDY_PI5,
TEGRA_PIN_GMI_WAIT_PI7,
TEGRA_PIN_GMI_ADV_N_PK0,
TEGRA_PIN_GMI_CLK_PK1,
TEGRA_PIN_GMI_CS2_N_PK3,
TEGRA_PIN_GMI_CS3_N_PK4,
TEGRA_PIN_GMI_CS4_N_PK2,
TEGRA_PIN_GMI_AD0_PG0,
TEGRA_PIN_GMI_AD1_PG1,
TEGRA_PIN_GMI_AD2_PG2,
TEGRA_PIN_GMI_AD3_PG3,
TEGRA_PIN_GMI_AD4_PG4,
TEGRA_PIN_GMI_AD5_PG5,
TEGRA_PIN_GMI_AD6_PG6,
TEGRA_PIN_GMI_AD7_PG7,
TEGRA_PIN_GMI_HIOW_N_PI0,
TEGRA_PIN_GMI_HIOR_N_PI1,
};
static const unsigned atd_pins[] = {
TEGRA_PIN_GMI_AD8_PH0,
TEGRA_PIN_GMI_AD9_PH1,
TEGRA_PIN_GMI_AD10_PH2,
TEGRA_PIN_GMI_AD11_PH3,
};
static const unsigned ate_pins[] = {
TEGRA_PIN_GMI_AD12_PH4,
TEGRA_PIN_GMI_AD13_PH5,
TEGRA_PIN_GMI_AD14_PH6,
TEGRA_PIN_GMI_AD15_PH7,
};
static const unsigned cdev1_pins[] = {
TEGRA_PIN_DAP_MCLK1_PW4,
};
static const unsigned cdev2_pins[] = {
TEGRA_PIN_DAP_MCLK2_PW5,
};
static const unsigned crtp_pins[] = {
TEGRA_PIN_CRT_HSYNC,
TEGRA_PIN_CRT_VSYNC,
};
static const unsigned csus_pins[] = {
TEGRA_PIN_VI_MCLK_PT1,
};
static const unsigned dap1_pins[] = {
TEGRA_PIN_DAP1_FS_PN0,
TEGRA_PIN_DAP1_DIN_PN1,
TEGRA_PIN_DAP1_DOUT_PN2,
TEGRA_PIN_DAP1_SCLK_PN3,
};
static const unsigned dap2_pins[] = {
TEGRA_PIN_DAP2_FS_PA2,
TEGRA_PIN_DAP2_SCLK_PA3,
TEGRA_PIN_DAP2_DIN_PA4,
TEGRA_PIN_DAP2_DOUT_PA5,
};
static const unsigned dap3_pins[] = {
TEGRA_PIN_DAP3_FS_PP0,
TEGRA_PIN_DAP3_DIN_PP1,
TEGRA_PIN_DAP3_DOUT_PP2,
TEGRA_PIN_DAP3_SCLK_PP3,
};
static const unsigned dap4_pins[] = {
TEGRA_PIN_DAP4_FS_PP4,
TEGRA_PIN_DAP4_DIN_PP5,
TEGRA_PIN_DAP4_DOUT_PP6,
TEGRA_PIN_DAP4_SCLK_PP7,
};
static const unsigned ddc_pins[] = {
TEGRA_PIN_DDC_SCL,
TEGRA_PIN_DDC_SDA,
};
static const unsigned dta_pins[] = {
TEGRA_PIN_VI_D0_PT4,
TEGRA_PIN_VI_D1_PD5,
};
static const unsigned dtb_pins[] = {
TEGRA_PIN_VI_D10_PT2,
TEGRA_PIN_VI_D11_PT3,
};
static const unsigned dtc_pins[] = {
TEGRA_PIN_VI_HSYNC_PD7,
TEGRA_PIN_VI_VSYNC_PD6,
};
static const unsigned dtd_pins[] = {
TEGRA_PIN_VI_PCLK_PT0,
TEGRA_PIN_VI_D2_PL0,
TEGRA_PIN_VI_D3_PL1,
TEGRA_PIN_VI_D4_PL2,
TEGRA_PIN_VI_D5_PL3,
TEGRA_PIN_VI_D6_PL4,
TEGRA_PIN_VI_D7_PL5,
TEGRA_PIN_VI_D8_PL6,
TEGRA_PIN_VI_D9_PL7,
};
static const unsigned dte_pins[] = {
TEGRA_PIN_VI_GP0_PBB1,
TEGRA_PIN_VI_GP3_PBB4,
TEGRA_PIN_VI_GP4_PBB5,
TEGRA_PIN_VI_GP5_PD2,
TEGRA_PIN_VI_GP6_PA0,
};
static const unsigned dtf_pins[] = {
TEGRA_PIN_CAM_I2C_SCL_PBB2,
TEGRA_PIN_CAM_I2C_SDA_PBB3,
};
static const unsigned gma_pins[] = {
TEGRA_PIN_GMI_AD20_PAA0,
TEGRA_PIN_GMI_AD21_PAA1,
TEGRA_PIN_GMI_AD22_PAA2,
TEGRA_PIN_GMI_AD23_PAA3,
};
static const unsigned gmb_pins[] = {
TEGRA_PIN_GMI_WP_N_PC7,
};
static const unsigned gmc_pins[] = {
TEGRA_PIN_GMI_AD16_PJ7,
TEGRA_PIN_GMI_AD17_PB0,
TEGRA_PIN_GMI_AD18_PB1,
TEGRA_PIN_GMI_AD19_PK7,
};
static const unsigned gmd_pins[] = {
TEGRA_PIN_GMI_CS0_N_PJ0,
TEGRA_PIN_GMI_CS1_N_PJ2,
};
static const unsigned gme_pins[] = {
TEGRA_PIN_GMI_AD24_PAA4,
TEGRA_PIN_GMI_AD25_PAA5,
TEGRA_PIN_GMI_AD26_PAA6,
TEGRA_PIN_GMI_AD27_PAA7,
};
static const unsigned gpu_pins[] = {
TEGRA_PIN_PU0,
TEGRA_PIN_PU1,
TEGRA_PIN_PU2,
TEGRA_PIN_PU3,
TEGRA_PIN_PU4,
TEGRA_PIN_PU5,
TEGRA_PIN_PU6,
};
static const unsigned gpu7_pins[] = {
TEGRA_PIN_JTAG_RTCK_PU7,
};
static const unsigned gpv_pins[] = {
TEGRA_PIN_PV4,
TEGRA_PIN_PV5,
TEGRA_PIN_PV6,
};
static const unsigned hdint_pins[] = {
TEGRA_PIN_HDMI_INT_N_PN7,
};
static const unsigned i2cp_pins[] = {
TEGRA_PIN_PWR_I2C_SCL_PZ6,
TEGRA_PIN_PWR_I2C_SDA_PZ7,
};
static const unsigned irrx_pins[] = {
TEGRA_PIN_UART2_RTS_N_PJ6,
};
static const unsigned irtx_pins[] = {
TEGRA_PIN_UART2_CTS_N_PJ5,
};
static const unsigned kbca_pins[] = {
TEGRA_PIN_KB_ROW0_PR0,
TEGRA_PIN_KB_ROW1_PR1,
TEGRA_PIN_KB_ROW2_PR2,
};
static const unsigned kbcb_pins[] = {
TEGRA_PIN_KB_ROW7_PR7,
TEGRA_PIN_KB_ROW8_PS0,
TEGRA_PIN_KB_ROW9_PS1,
TEGRA_PIN_KB_ROW10_PS2,
TEGRA_PIN_KB_ROW11_PS3,
TEGRA_PIN_KB_ROW12_PS4,
TEGRA_PIN_KB_ROW13_PS5,
TEGRA_PIN_KB_ROW14_PS6,
TEGRA_PIN_KB_ROW15_PS7,
};
static const unsigned kbcc_pins[] = {
TEGRA_PIN_KB_COL0_PQ0,
TEGRA_PIN_KB_COL1_PQ1,
};
static const unsigned kbcd_pins[] = {
TEGRA_PIN_KB_ROW3_PR3,
TEGRA_PIN_KB_ROW4_PR4,
TEGRA_PIN_KB_ROW5_PR5,
TEGRA_PIN_KB_ROW6_PR6,
};
static const unsigned kbce_pins[] = {
TEGRA_PIN_KB_COL7_PQ7,
};
static const unsigned kbcf_pins[] = {
TEGRA_PIN_KB_COL2_PQ2,
TEGRA_PIN_KB_COL3_PQ3,
TEGRA_PIN_KB_COL4_PQ4,
TEGRA_PIN_KB_COL5_PQ5,
TEGRA_PIN_KB_COL6_PQ6,
};
static const unsigned lcsn_pins[] = {
TEGRA_PIN_LCD_CS0_N_PN4,
};
static const unsigned ld0_pins[] = {
TEGRA_PIN_LCD_D0_PE0,
};
static const unsigned ld1_pins[] = {
TEGRA_PIN_LCD_D1_PE1,
};
static const unsigned ld2_pins[] = {
TEGRA_PIN_LCD_D2_PE2,
};
static const unsigned ld3_pins[] = {
TEGRA_PIN_LCD_D3_PE3,
};
static const unsigned ld4_pins[] = {
TEGRA_PIN_LCD_D4_PE4,
};
static const unsigned ld5_pins[] = {
TEGRA_PIN_LCD_D5_PE5,
};
static const unsigned ld6_pins[] = {
TEGRA_PIN_LCD_D6_PE6,
};
static const unsigned ld7_pins[] = {
TEGRA_PIN_LCD_D7_PE7,
};
static const unsigned ld8_pins[] = {
TEGRA_PIN_LCD_D8_PF0,
};
static const unsigned ld9_pins[] = {
TEGRA_PIN_LCD_D9_PF1,
};
static const unsigned ld10_pins[] = {
TEGRA_PIN_LCD_D10_PF2,
};
static const unsigned ld11_pins[] = {
TEGRA_PIN_LCD_D11_PF3,
};
static const unsigned ld12_pins[] = {
TEGRA_PIN_LCD_D12_PF4,
};
static const unsigned ld13_pins[] = {
TEGRA_PIN_LCD_D13_PF5,
};
static const unsigned ld14_pins[] = {
TEGRA_PIN_LCD_D14_PF6,
};
static const unsigned ld15_pins[] = {
TEGRA_PIN_LCD_D15_PF7,
};
static const unsigned ld16_pins[] = {
TEGRA_PIN_LCD_D16_PM0,
};
static const unsigned ld17_pins[] = {
TEGRA_PIN_LCD_D17_PM1,
};
static const unsigned ldc_pins[] = {
TEGRA_PIN_LCD_DC0_PN6,
};
static const unsigned ldi_pins[] = {
TEGRA_PIN_LCD_D22_PM6,
};
static const unsigned lhp0_pins[] = {
TEGRA_PIN_LCD_D21_PM5,
};
static const unsigned lhp1_pins[] = {
TEGRA_PIN_LCD_D18_PM2,
};
static const unsigned lhp2_pins[] = {
TEGRA_PIN_LCD_D19_PM3,
};
static const unsigned lhs_pins[] = {
TEGRA_PIN_LCD_HSYNC_PJ3,
};
static const unsigned lm0_pins[] = {
TEGRA_PIN_LCD_CS1_N_PW0,
};
static const unsigned lm1_pins[] = {
TEGRA_PIN_LCD_M1_PW1,
};
static const unsigned lpp_pins[] = {
TEGRA_PIN_LCD_D23_PM7,
};
static const unsigned lpw0_pins[] = {
TEGRA_PIN_LCD_PWR0_PB2,
};
static const unsigned lpw1_pins[] = {
TEGRA_PIN_LCD_PWR1_PC1,
};
static const unsigned lpw2_pins[] = {
TEGRA_PIN_LCD_PWR2_PC6,
};
static const unsigned lsc0_pins[] = {
TEGRA_PIN_LCD_PCLK_PB3,
};
static const unsigned lsc1_pins[] = {
TEGRA_PIN_LCD_WR_N_PZ3,
};
static const unsigned lsck_pins[] = {
TEGRA_PIN_LCD_SCK_PZ4,
};
static const unsigned lsda_pins[] = {
TEGRA_PIN_LCD_SDOUT_PN5,
};
static const unsigned lsdi_pins[] = {
TEGRA_PIN_LCD_SDIN_PZ2,
};
static const unsigned lspi_pins[] = {
TEGRA_PIN_LCD_DE_PJ1,
};
static const unsigned lvp0_pins[] = {
TEGRA_PIN_LCD_DC1_PV7,
};
static const unsigned lvp1_pins[] = {
TEGRA_PIN_LCD_D20_PM4,
};
static const unsigned lvs_pins[] = {
TEGRA_PIN_LCD_VSYNC_PJ4,
};
static const unsigned ls_pins[] = {
TEGRA_PIN_LCD_PWR0_PB2,
TEGRA_PIN_LCD_PWR1_PC1,
TEGRA_PIN_LCD_PWR2_PC6,
TEGRA_PIN_LCD_SDIN_PZ2,
TEGRA_PIN_LCD_SDOUT_PN5,
TEGRA_PIN_LCD_WR_N_PZ3,
TEGRA_PIN_LCD_CS0_N_PN4,
TEGRA_PIN_LCD_DC0_PN6,
TEGRA_PIN_LCD_SCK_PZ4,
};
static const unsigned lc_pins[] = {
TEGRA_PIN_LCD_PCLK_PB3,
TEGRA_PIN_LCD_DE_PJ1,
TEGRA_PIN_LCD_HSYNC_PJ3,
TEGRA_PIN_LCD_VSYNC_PJ4,
TEGRA_PIN_LCD_CS1_N_PW0,
TEGRA_PIN_LCD_M1_PW1,
TEGRA_PIN_LCD_DC1_PV7,
TEGRA_PIN_HDMI_INT_N_PN7,
};
static const unsigned ld17_0_pins[] = {
TEGRA_PIN_LCD_D0_PE0,
TEGRA_PIN_LCD_D1_PE1,
TEGRA_PIN_LCD_D2_PE2,
TEGRA_PIN_LCD_D3_PE3,
TEGRA_PIN_LCD_D4_PE4,
TEGRA_PIN_LCD_D5_PE5,
TEGRA_PIN_LCD_D6_PE6,
TEGRA_PIN_LCD_D7_PE7,
TEGRA_PIN_LCD_D8_PF0,
TEGRA_PIN_LCD_D9_PF1,
TEGRA_PIN_LCD_D10_PF2,
TEGRA_PIN_LCD_D11_PF3,
TEGRA_PIN_LCD_D12_PF4,
TEGRA_PIN_LCD_D13_PF5,
TEGRA_PIN_LCD_D14_PF6,
TEGRA_PIN_LCD_D15_PF7,
TEGRA_PIN_LCD_D16_PM0,
TEGRA_PIN_LCD_D17_PM1,
};
static const unsigned ld19_18_pins[] = {
TEGRA_PIN_LCD_D18_PM2,
TEGRA_PIN_LCD_D19_PM3,
};
static const unsigned ld21_20_pins[] = {
TEGRA_PIN_LCD_D20_PM4,
TEGRA_PIN_LCD_D21_PM5,
};
static const unsigned ld23_22_pins[] = {
TEGRA_PIN_LCD_D22_PM6,
TEGRA_PIN_LCD_D23_PM7,
};
static const unsigned owc_pins[] = {
TEGRA_PIN_OWC,
};
static const unsigned pmc_pins[] = {
TEGRA_PIN_LED_BLINK_PBB0,
TEGRA_PIN_SYS_CLK_REQ_PZ5,
TEGRA_PIN_CORE_PWR_REQ,
TEGRA_PIN_CPU_PWR_REQ,
TEGRA_PIN_PWR_INT_N,
};
static const unsigned pta_pins[] = {
TEGRA_PIN_GEN2_I2C_SCL_PT5,
TEGRA_PIN_GEN2_I2C_SDA_PT6,
};
static const unsigned rm_pins[] = {
TEGRA_PIN_GEN1_I2C_SCL_PC4,
TEGRA_PIN_GEN1_I2C_SDA_PC5,
};
static const unsigned sdb_pins[] = {
TEGRA_PIN_SDIO3_CMD_PA7,
};
static const unsigned sdc_pins[] = {
TEGRA_PIN_SDIO3_DAT0_PB7,
TEGRA_PIN_SDIO3_DAT1_PB6,
TEGRA_PIN_SDIO3_DAT2_PB5,
TEGRA_PIN_SDIO3_DAT3_PB4,
};
static const unsigned sdd_pins[] = {
TEGRA_PIN_SDIO3_CLK_PA6,
};
static const unsigned sdio1_pins[] = {
TEGRA_PIN_SDIO1_CLK_PZ0,
TEGRA_PIN_SDIO1_CMD_PZ1,
TEGRA_PIN_SDIO1_DAT0_PY7,
TEGRA_PIN_SDIO1_DAT1_PY6,
TEGRA_PIN_SDIO1_DAT2_PY5,
TEGRA_PIN_SDIO1_DAT3_PY4,
};
static const unsigned slxa_pins[] = {
TEGRA_PIN_SDIO3_DAT4_PD1,
};
static const unsigned slxc_pins[] = {
TEGRA_PIN_SDIO3_DAT6_PD3,
};
static const unsigned slxd_pins[] = {
TEGRA_PIN_SDIO3_DAT7_PD4,
};
static const unsigned slxk_pins[] = {
TEGRA_PIN_SDIO3_DAT5_PD0,
};
static const unsigned spdi_pins[] = {
TEGRA_PIN_SPDIF_IN_PK6,
};
static const unsigned spdo_pins[] = {
TEGRA_PIN_SPDIF_OUT_PK5,
};
static const unsigned spia_pins[] = {
TEGRA_PIN_SPI2_MOSI_PX0,
};
static const unsigned spib_pins[] = {
TEGRA_PIN_SPI2_MISO_PX1,
};
static const unsigned spic_pins[] = {
TEGRA_PIN_SPI2_CS0_N_PX3,
TEGRA_PIN_SPI2_SCK_PX2,
};
static const unsigned spid_pins[] = {
TEGRA_PIN_SPI1_MOSI_PX4,
};
static const unsigned spie_pins[] = {
TEGRA_PIN_SPI1_CS0_N_PX6,
TEGRA_PIN_SPI1_SCK_PX5,
};
static const unsigned spif_pins[] = {
TEGRA_PIN_SPI1_MISO_PX7,
};
static const unsigned spig_pins[] = {
TEGRA_PIN_SPI2_CS1_N_PW2,
};
static const unsigned spih_pins[] = {
TEGRA_PIN_SPI2_CS2_N_PW3,
};
static const unsigned uaa_pins[] = {
TEGRA_PIN_ULPI_DATA0_PO1,
TEGRA_PIN_ULPI_DATA1_PO2,
TEGRA_PIN_ULPI_DATA2_PO3,
TEGRA_PIN_ULPI_DATA3_PO4,
};
static const unsigned uab_pins[] = {
TEGRA_PIN_ULPI_DATA4_PO5,
TEGRA_PIN_ULPI_DATA5_PO6,
TEGRA_PIN_ULPI_DATA6_PO7,
TEGRA_PIN_ULPI_DATA7_PO0,
};
static const unsigned uac_pins[] = {
TEGRA_PIN_PV0,
TEGRA_PIN_PV1,
TEGRA_PIN_PV2,
TEGRA_PIN_PV3,
};
static const unsigned ck32_pins[] = {
TEGRA_PIN_CLK_32_K_IN,
};
static const unsigned uad_pins[] = {
TEGRA_PIN_UART2_RXD_PC3,
TEGRA_PIN_UART2_TXD_PC2,
};
static const unsigned uca_pins[] = {
TEGRA_PIN_UART3_RXD_PW7,
TEGRA_PIN_UART3_TXD_PW6,
};
static const unsigned ucb_pins[] = {
TEGRA_PIN_UART3_CTS_N_PA1,
TEGRA_PIN_UART3_RTS_N_PC0,
};
static const unsigned uda_pins[] = {
TEGRA_PIN_ULPI_CLK_PY0,
TEGRA_PIN_ULPI_DIR_PY1,
TEGRA_PIN_ULPI_NXT_PY2,
TEGRA_PIN_ULPI_STP_PY3,
};
static const unsigned ddrc_pins[] = {
TEGRA_PIN_DDR_COMP_PD,
TEGRA_PIN_DDR_COMP_PU,
};
static const unsigned pmca_pins[] = {
TEGRA_PIN_LED_BLINK_PBB0,
};
static const unsigned pmcb_pins[] = {
TEGRA_PIN_SYS_CLK_REQ_PZ5,
};
static const unsigned pmcc_pins[] = {
TEGRA_PIN_CORE_PWR_REQ,
};
static const unsigned pmcd_pins[] = {
TEGRA_PIN_CPU_PWR_REQ,
};
static const unsigned pmce_pins[] = {
TEGRA_PIN_PWR_INT_N,
};
static const unsigned xm2c_pins[] = {
TEGRA_PIN_DDR_A0,
TEGRA_PIN_DDR_A1,
TEGRA_PIN_DDR_A2,
TEGRA_PIN_DDR_A3,
TEGRA_PIN_DDR_A4,
TEGRA_PIN_DDR_A5,
TEGRA_PIN_DDR_A6,
TEGRA_PIN_DDR_A7,
TEGRA_PIN_DDR_A8,
TEGRA_PIN_DDR_A9,
TEGRA_PIN_DDR_A10,
TEGRA_PIN_DDR_A11,
TEGRA_PIN_DDR_A12,
TEGRA_PIN_DDR_A13,
TEGRA_PIN_DDR_A14,
TEGRA_PIN_DDR_CAS_N,
TEGRA_PIN_DDR_BA0,
TEGRA_PIN_DDR_BA1,
TEGRA_PIN_DDR_BA2,
TEGRA_PIN_DDR_DQS0P,
TEGRA_PIN_DDR_DQS0N,
TEGRA_PIN_DDR_DQS1P,
TEGRA_PIN_DDR_DQS1N,
TEGRA_PIN_DDR_DQS2P,
TEGRA_PIN_DDR_DQS2N,
TEGRA_PIN_DDR_DQS3P,
TEGRA_PIN_DDR_DQS3N,
TEGRA_PIN_DDR_CS0_N,
TEGRA_PIN_DDR_CS1_N,
TEGRA_PIN_DDR_CKE0,
TEGRA_PIN_DDR_CKE1,
TEGRA_PIN_DDR_CLK,
TEGRA_PIN_DDR_CLK_N,
TEGRA_PIN_DDR_DM0,
TEGRA_PIN_DDR_DM1,
TEGRA_PIN_DDR_DM2,
TEGRA_PIN_DDR_DM3,
TEGRA_PIN_DDR_ODT,
TEGRA_PIN_DDR_RAS_N,
TEGRA_PIN_DDR_WE_N,
TEGRA_PIN_DDR_QUSE0,
TEGRA_PIN_DDR_QUSE1,
TEGRA_PIN_DDR_QUSE2,
TEGRA_PIN_DDR_QUSE3,
};
static const unsigned xm2d_pins[] = {
TEGRA_PIN_DDR_DQ0,
TEGRA_PIN_DDR_DQ1,
TEGRA_PIN_DDR_DQ2,
TEGRA_PIN_DDR_DQ3,
TEGRA_PIN_DDR_DQ4,
TEGRA_PIN_DDR_DQ5,
TEGRA_PIN_DDR_DQ6,
TEGRA_PIN_DDR_DQ7,
TEGRA_PIN_DDR_DQ8,
TEGRA_PIN_DDR_DQ9,
TEGRA_PIN_DDR_DQ10,
TEGRA_PIN_DDR_DQ11,
TEGRA_PIN_DDR_DQ12,
TEGRA_PIN_DDR_DQ13,
TEGRA_PIN_DDR_DQ14,
TEGRA_PIN_DDR_DQ15,
TEGRA_PIN_DDR_DQ16,
TEGRA_PIN_DDR_DQ17,
TEGRA_PIN_DDR_DQ18,
TEGRA_PIN_DDR_DQ19,
TEGRA_PIN_DDR_DQ20,
TEGRA_PIN_DDR_DQ21,
TEGRA_PIN_DDR_DQ22,
TEGRA_PIN_DDR_DQ23,
TEGRA_PIN_DDR_DQ24,
TEGRA_PIN_DDR_DQ25,
TEGRA_PIN_DDR_DQ26,
TEGRA_PIN_DDR_DQ27,
TEGRA_PIN_DDR_DQ28,
TEGRA_PIN_DDR_DQ29,
TEGRA_PIN_DDR_DQ30,
TEGRA_PIN_DDR_DQ31,
};
static const unsigned drive_ao1_pins[] = {
TEGRA_PIN_SYS_RESET,
TEGRA_PIN_PWR_I2C_SCL_PZ6,
TEGRA_PIN_PWR_I2C_SDA_PZ7,
TEGRA_PIN_KB_ROW0_PR0,
TEGRA_PIN_KB_ROW1_PR1,
TEGRA_PIN_KB_ROW2_PR2,
TEGRA_PIN_KB_ROW3_PR3,
TEGRA_PIN_KB_ROW4_PR4,
TEGRA_PIN_KB_ROW5_PR5,
TEGRA_PIN_KB_ROW6_PR6,
TEGRA_PIN_KB_ROW7_PR7,
};
static const unsigned drive_ao2_pins[] = {
TEGRA_PIN_KB_ROW8_PS0,
TEGRA_PIN_KB_ROW9_PS1,
TEGRA_PIN_KB_ROW10_PS2,
TEGRA_PIN_KB_ROW11_PS3,
TEGRA_PIN_KB_ROW12_PS4,
TEGRA_PIN_KB_ROW13_PS5,
TEGRA_PIN_KB_ROW14_PS6,
TEGRA_PIN_KB_ROW15_PS7,
TEGRA_PIN_KB_COL0_PQ0,
TEGRA_PIN_KB_COL1_PQ1,
TEGRA_PIN_KB_COL2_PQ2,
TEGRA_PIN_KB_COL3_PQ3,
TEGRA_PIN_KB_COL4_PQ4,
TEGRA_PIN_KB_COL5_PQ5,
TEGRA_PIN_KB_COL6_PQ6,
TEGRA_PIN_KB_COL7_PQ7,
TEGRA_PIN_LED_BLINK_PBB0,
TEGRA_PIN_SYS_CLK_REQ_PZ5,
TEGRA_PIN_CORE_PWR_REQ,
TEGRA_PIN_CPU_PWR_REQ,
TEGRA_PIN_PWR_INT_N,
TEGRA_PIN_CLK_32_K_IN,
};
static const unsigned drive_at1_pins[] = {
TEGRA_PIN_GMI_IORDY_PI5,
TEGRA_PIN_GMI_AD8_PH0,
TEGRA_PIN_GMI_AD9_PH1,
TEGRA_PIN_GMI_AD10_PH2,
TEGRA_PIN_GMI_AD11_PH3,
TEGRA_PIN_GMI_AD12_PH4,
TEGRA_PIN_GMI_AD13_PH5,
TEGRA_PIN_GMI_AD14_PH6,
TEGRA_PIN_GMI_AD15_PH7,
TEGRA_PIN_GMI_CS7_N_PI6,
TEGRA_PIN_GMI_DPD_PT7,
TEGRA_PIN_GEN2_I2C_SCL_PT5,
TEGRA_PIN_GEN2_I2C_SDA_PT6,
};
static const unsigned drive_at2_pins[] = {
TEGRA_PIN_GMI_WAIT_PI7,
TEGRA_PIN_GMI_ADV_N_PK0,
TEGRA_PIN_GMI_CLK_PK1,
TEGRA_PIN_GMI_CS6_N_PI3,
TEGRA_PIN_GMI_CS5_N_PI2,
TEGRA_PIN_GMI_CS4_N_PK2,
TEGRA_PIN_GMI_CS3_N_PK4,
TEGRA_PIN_GMI_CS2_N_PK3,
TEGRA_PIN_GMI_AD0_PG0,
TEGRA_PIN_GMI_AD1_PG1,
TEGRA_PIN_GMI_AD2_PG2,
TEGRA_PIN_GMI_AD3_PG3,
TEGRA_PIN_GMI_AD4_PG4,
TEGRA_PIN_GMI_AD5_PG5,
TEGRA_PIN_GMI_AD6_PG6,
TEGRA_PIN_GMI_AD7_PG7,
TEGRA_PIN_GMI_HIOW_N_PI0,
TEGRA_PIN_GMI_HIOR_N_PI1,
TEGRA_PIN_GMI_RST_N_PI4,
};
static const unsigned drive_cdev1_pins[] = {
TEGRA_PIN_DAP_MCLK1_PW4,
};
static const unsigned drive_cdev2_pins[] = {
TEGRA_PIN_DAP_MCLK2_PW5,
};
static const unsigned drive_csus_pins[] = {
TEGRA_PIN_VI_MCLK_PT1,
};
static const unsigned drive_dap1_pins[] = {
TEGRA_PIN_DAP1_FS_PN0,
TEGRA_PIN_DAP1_DIN_PN1,
TEGRA_PIN_DAP1_DOUT_PN2,
TEGRA_PIN_DAP1_SCLK_PN3,
TEGRA_PIN_SPDIF_OUT_PK5,
TEGRA_PIN_SPDIF_IN_PK6,
};
static const unsigned drive_dap2_pins[] = {
TEGRA_PIN_DAP2_FS_PA2,
TEGRA_PIN_DAP2_SCLK_PA3,
TEGRA_PIN_DAP2_DIN_PA4,
TEGRA_PIN_DAP2_DOUT_PA5,
};
static const unsigned drive_dap3_pins[] = {
TEGRA_PIN_DAP3_FS_PP0,
TEGRA_PIN_DAP3_DIN_PP1,
TEGRA_PIN_DAP3_DOUT_PP2,
TEGRA_PIN_DAP3_SCLK_PP3,
};
static const unsigned drive_dap4_pins[] = {
TEGRA_PIN_DAP4_FS_PP4,
TEGRA_PIN_DAP4_DIN_PP5,
TEGRA_PIN_DAP4_DOUT_PP6,
TEGRA_PIN_DAP4_SCLK_PP7,
};
static const unsigned drive_dbg_pins[] = {
TEGRA_PIN_PU0,
TEGRA_PIN_PU1,
TEGRA_PIN_PU2,
TEGRA_PIN_PU3,
TEGRA_PIN_PU4,
TEGRA_PIN_PU5,
TEGRA_PIN_PU6,
TEGRA_PIN_JTAG_RTCK_PU7,
TEGRA_PIN_GEN1_I2C_SDA_PC5,
TEGRA_PIN_GEN1_I2C_SCL_PC4,
TEGRA_PIN_JTAG_TRST_N,
TEGRA_PIN_JTAG_TDO,
TEGRA_PIN_JTAG_TMS,
TEGRA_PIN_JTAG_TCK,
TEGRA_PIN_JTAG_TDI,
TEGRA_PIN_TEST_MODE_EN,
};
static const unsigned drive_lcd1_pins[] = {
TEGRA_PIN_LCD_PWR1_PC1,
TEGRA_PIN_LCD_PWR2_PC6,
TEGRA_PIN_LCD_SDIN_PZ2,
TEGRA_PIN_LCD_SDOUT_PN5,
TEGRA_PIN_LCD_WR_N_PZ3,
TEGRA_PIN_LCD_CS0_N_PN4,
TEGRA_PIN_LCD_DC0_PN6,
TEGRA_PIN_LCD_SCK_PZ4,
};
static const unsigned drive_lcd2_pins[] = {
TEGRA_PIN_LCD_PWR0_PB2,
TEGRA_PIN_LCD_PCLK_PB3,
TEGRA_PIN_LCD_DE_PJ1,
TEGRA_PIN_LCD_HSYNC_PJ3,
TEGRA_PIN_LCD_VSYNC_PJ4,
TEGRA_PIN_LCD_D0_PE0,
TEGRA_PIN_LCD_D1_PE1,
TEGRA_PIN_LCD_D2_PE2,
TEGRA_PIN_LCD_D3_PE3,
TEGRA_PIN_LCD_D4_PE4,
TEGRA_PIN_LCD_D5_PE5,
TEGRA_PIN_LCD_D6_PE6,
TEGRA_PIN_LCD_D7_PE7,
TEGRA_PIN_LCD_D8_PF0,
TEGRA_PIN_LCD_D9_PF1,
TEGRA_PIN_LCD_D10_PF2,
TEGRA_PIN_LCD_D11_PF3,
TEGRA_PIN_LCD_D12_PF4,
TEGRA_PIN_LCD_D13_PF5,
TEGRA_PIN_LCD_D14_PF6,
TEGRA_PIN_LCD_D15_PF7,
TEGRA_PIN_LCD_D16_PM0,
TEGRA_PIN_LCD_D17_PM1,
TEGRA_PIN_LCD_D18_PM2,
TEGRA_PIN_LCD_D19_PM3,
TEGRA_PIN_LCD_D20_PM4,
TEGRA_PIN_LCD_D21_PM5,
TEGRA_PIN_LCD_D22_PM6,
TEGRA_PIN_LCD_D23_PM7,
TEGRA_PIN_LCD_CS1_N_PW0,
TEGRA_PIN_LCD_M1_PW1,
TEGRA_PIN_LCD_DC1_PV7,
TEGRA_PIN_HDMI_INT_N_PN7,
};
static const unsigned drive_sdmmc2_pins[] = {
TEGRA_PIN_SDIO3_DAT4_PD1,
TEGRA_PIN_SDIO3_DAT5_PD0,
TEGRA_PIN_SDIO3_DAT6_PD3,
TEGRA_PIN_SDIO3_DAT7_PD4,
};
static const unsigned drive_sdmmc3_pins[] = {
TEGRA_PIN_SDIO3_CLK_PA6,
TEGRA_PIN_SDIO3_CMD_PA7,
TEGRA_PIN_SDIO3_DAT0_PB7,
TEGRA_PIN_SDIO3_DAT1_PB6,
TEGRA_PIN_SDIO3_DAT2_PB5,
TEGRA_PIN_SDIO3_DAT3_PB4,
TEGRA_PIN_PV4,
TEGRA_PIN_PV5,
TEGRA_PIN_PV6,
};
static const unsigned drive_spi_pins[] = {
TEGRA_PIN_SPI2_MOSI_PX0,
TEGRA_PIN_SPI2_MISO_PX1,
TEGRA_PIN_SPI2_SCK_PX2,
TEGRA_PIN_SPI2_CS0_N_PX3,
TEGRA_PIN_SPI1_MOSI_PX4,
TEGRA_PIN_SPI1_SCK_PX5,
TEGRA_PIN_SPI1_CS0_N_PX6,
TEGRA_PIN_SPI1_MISO_PX7,
TEGRA_PIN_SPI2_CS1_N_PW2,
TEGRA_PIN_SPI2_CS2_N_PW3,
};
static const unsigned drive_uaa_pins[] = {
TEGRA_PIN_ULPI_DATA0_PO1,
TEGRA_PIN_ULPI_DATA1_PO2,
TEGRA_PIN_ULPI_DATA2_PO3,
TEGRA_PIN_ULPI_DATA3_PO4,
};
static const unsigned drive_uab_pins[] = {
TEGRA_PIN_ULPI_DATA4_PO5,
TEGRA_PIN_ULPI_DATA5_PO6,
TEGRA_PIN_ULPI_DATA6_PO7,
TEGRA_PIN_ULPI_DATA7_PO0,
TEGRA_PIN_PV0,
TEGRA_PIN_PV1,
TEGRA_PIN_PV2,
TEGRA_PIN_PV3,
};
static const unsigned drive_uart2_pins[] = {
TEGRA_PIN_UART2_TXD_PC2,
TEGRA_PIN_UART2_RXD_PC3,
TEGRA_PIN_UART2_RTS_N_PJ6,
TEGRA_PIN_UART2_CTS_N_PJ5,
};
static const unsigned drive_uart3_pins[] = {
TEGRA_PIN_UART3_TXD_PW6,
TEGRA_PIN_UART3_RXD_PW7,
TEGRA_PIN_UART3_RTS_N_PC0,
TEGRA_PIN_UART3_CTS_N_PA1,
};
static const unsigned drive_vi1_pins[] = {
TEGRA_PIN_VI_D0_PT4,
TEGRA_PIN_VI_D1_PD5,
TEGRA_PIN_VI_D2_PL0,
TEGRA_PIN_VI_D3_PL1,
TEGRA_PIN_VI_D4_PL2,
TEGRA_PIN_VI_D5_PL3,
TEGRA_PIN_VI_D6_PL4,
TEGRA_PIN_VI_D7_PL5,
TEGRA_PIN_VI_D8_PL6,
TEGRA_PIN_VI_D9_PL7,
TEGRA_PIN_VI_D10_PT2,
TEGRA_PIN_VI_D11_PT3,
TEGRA_PIN_VI_PCLK_PT0,
TEGRA_PIN_VI_VSYNC_PD6,
TEGRA_PIN_VI_HSYNC_PD7,
};
static const unsigned drive_vi2_pins[] = {
TEGRA_PIN_VI_GP0_PBB1,
TEGRA_PIN_CAM_I2C_SCL_PBB2,
TEGRA_PIN_CAM_I2C_SDA_PBB3,
TEGRA_PIN_VI_GP3_PBB4,
TEGRA_PIN_VI_GP4_PBB5,
TEGRA_PIN_VI_GP5_PD2,
TEGRA_PIN_VI_GP6_PA0,
};
static const unsigned drive_xm2a_pins[] = {
TEGRA_PIN_DDR_A0,
TEGRA_PIN_DDR_A1,
TEGRA_PIN_DDR_A2,
TEGRA_PIN_DDR_A3,
TEGRA_PIN_DDR_A4,
TEGRA_PIN_DDR_A5,
TEGRA_PIN_DDR_A6,
TEGRA_PIN_DDR_A7,
TEGRA_PIN_DDR_A8,
TEGRA_PIN_DDR_A9,
TEGRA_PIN_DDR_A10,
TEGRA_PIN_DDR_A11,
TEGRA_PIN_DDR_A12,
TEGRA_PIN_DDR_A13,
TEGRA_PIN_DDR_A14,
TEGRA_PIN_DDR_BA0,
TEGRA_PIN_DDR_BA1,
TEGRA_PIN_DDR_BA2,
TEGRA_PIN_DDR_CS0_N,
TEGRA_PIN_DDR_CS1_N,
TEGRA_PIN_DDR_ODT,
TEGRA_PIN_DDR_RAS_N,
TEGRA_PIN_DDR_CAS_N,
TEGRA_PIN_DDR_WE_N,
TEGRA_PIN_DDR_CKE0,
TEGRA_PIN_DDR_CKE1,
};
static const unsigned drive_xm2c_pins[] = {
TEGRA_PIN_DDR_DQS0P,
TEGRA_PIN_DDR_DQS0N,
TEGRA_PIN_DDR_DQS1P,
TEGRA_PIN_DDR_DQS1N,
TEGRA_PIN_DDR_DQS2P,
TEGRA_PIN_DDR_DQS2N,
TEGRA_PIN_DDR_DQS3P,
TEGRA_PIN_DDR_DQS3N,
TEGRA_PIN_DDR_QUSE0,
TEGRA_PIN_DDR_QUSE1,
TEGRA_PIN_DDR_QUSE2,
TEGRA_PIN_DDR_QUSE3,
};
static const unsigned drive_xm2d_pins[] = {
TEGRA_PIN_DDR_DQ0,
TEGRA_PIN_DDR_DQ1,
TEGRA_PIN_DDR_DQ2,
TEGRA_PIN_DDR_DQ3,
TEGRA_PIN_DDR_DQ4,
TEGRA_PIN_DDR_DQ5,
TEGRA_PIN_DDR_DQ6,
TEGRA_PIN_DDR_DQ7,
TEGRA_PIN_DDR_DQ8,
TEGRA_PIN_DDR_DQ9,
TEGRA_PIN_DDR_DQ10,
TEGRA_PIN_DDR_DQ11,
TEGRA_PIN_DDR_DQ12,
TEGRA_PIN_DDR_DQ13,
TEGRA_PIN_DDR_DQ14,
TEGRA_PIN_DDR_DQ15,
TEGRA_PIN_DDR_DQ16,
TEGRA_PIN_DDR_DQ17,
TEGRA_PIN_DDR_DQ18,
TEGRA_PIN_DDR_DQ19,
TEGRA_PIN_DDR_DQ20,
TEGRA_PIN_DDR_DQ21,
TEGRA_PIN_DDR_DQ22,
TEGRA_PIN_DDR_DQ23,
TEGRA_PIN_DDR_DQ24,
TEGRA_PIN_DDR_DQ25,
TEGRA_PIN_DDR_DQ26,
TEGRA_PIN_DDR_DQ27,
TEGRA_PIN_DDR_DQ28,
TEGRA_PIN_DDR_DQ29,
TEGRA_PIN_DDR_DQ30,
TEGRA_PIN_DDR_DQ31,
TEGRA_PIN_DDR_DM0,
TEGRA_PIN_DDR_DM1,
TEGRA_PIN_DDR_DM2,
TEGRA_PIN_DDR_DM3,
};
static const unsigned drive_xm2clk_pins[] = {
TEGRA_PIN_DDR_CLK,
TEGRA_PIN_DDR_CLK_N,
};
static const unsigned drive_sdio1_pins[] = {
TEGRA_PIN_SDIO1_CLK_PZ0,
TEGRA_PIN_SDIO1_CMD_PZ1,
TEGRA_PIN_SDIO1_DAT0_PY7,
TEGRA_PIN_SDIO1_DAT1_PY6,
TEGRA_PIN_SDIO1_DAT2_PY5,
TEGRA_PIN_SDIO1_DAT3_PY4,
};
static const unsigned drive_crt_pins[] = {
TEGRA_PIN_CRT_HSYNC,
TEGRA_PIN_CRT_VSYNC,
};
static const unsigned drive_ddc_pins[] = {
TEGRA_PIN_DDC_SCL,
TEGRA_PIN_DDC_SDA,
};
static const unsigned drive_gma_pins[] = {
TEGRA_PIN_GMI_AD20_PAA0,
TEGRA_PIN_GMI_AD21_PAA1,
TEGRA_PIN_GMI_AD22_PAA2,
TEGRA_PIN_GMI_AD23_PAA3,
};
static const unsigned drive_gmb_pins[] = {
TEGRA_PIN_GMI_WP_N_PC7,
};
static const unsigned drive_gmc_pins[] = {
TEGRA_PIN_GMI_AD16_PJ7,
TEGRA_PIN_GMI_AD17_PB0,
TEGRA_PIN_GMI_AD18_PB1,
TEGRA_PIN_GMI_AD19_PK7,
};
static const unsigned drive_gmd_pins[] = {
TEGRA_PIN_GMI_CS0_N_PJ0,
TEGRA_PIN_GMI_CS1_N_PJ2,
};
static const unsigned drive_gme_pins[] = {
TEGRA_PIN_GMI_AD24_PAA4,
TEGRA_PIN_GMI_AD25_PAA5,
TEGRA_PIN_GMI_AD26_PAA6,
TEGRA_PIN_GMI_AD27_PAA7,
};
static const unsigned drive_owr_pins[] = {
TEGRA_PIN_OWC,
};
static const unsigned drive_uda_pins[] = {
TEGRA_PIN_ULPI_CLK_PY0,
TEGRA_PIN_ULPI_DIR_PY1,
TEGRA_PIN_ULPI_NXT_PY2,
TEGRA_PIN_ULPI_STP_PY3,
};
enum tegra_mux {
TEGRA_MUX_AHB_CLK,
TEGRA_MUX_APB_CLK,
TEGRA_MUX_AUDIO_SYNC,
TEGRA_MUX_CRT,
TEGRA_MUX_DAP1,
TEGRA_MUX_DAP2,
TEGRA_MUX_DAP3,
TEGRA_MUX_DAP4,
TEGRA_MUX_DAP5,
TEGRA_MUX_DISPLAYA,
TEGRA_MUX_DISPLAYB,
TEGRA_MUX_EMC_TEST0_DLL,
TEGRA_MUX_EMC_TEST1_DLL,
TEGRA_MUX_GMI,
TEGRA_MUX_GMI_INT,
TEGRA_MUX_HDMI,
TEGRA_MUX_I2CP,
TEGRA_MUX_I2C1,
TEGRA_MUX_I2C2,
TEGRA_MUX_I2C3,
TEGRA_MUX_IDE,
TEGRA_MUX_IRDA,
TEGRA_MUX_KBC,
TEGRA_MUX_MIO,
TEGRA_MUX_MIPI_HS,
TEGRA_MUX_NAND,
TEGRA_MUX_OSC,
TEGRA_MUX_OWR,
TEGRA_MUX_PCIE,
TEGRA_MUX_PLLA_OUT,
TEGRA_MUX_PLLC_OUT1,
TEGRA_MUX_PLLM_OUT1,
TEGRA_MUX_PLLP_OUT2,
TEGRA_MUX_PLLP_OUT3,
TEGRA_MUX_PLLP_OUT4,
TEGRA_MUX_PWM,
TEGRA_MUX_PWR_INTR,
TEGRA_MUX_PWR_ON,
TEGRA_MUX_RSVD1,
TEGRA_MUX_RSVD2,
TEGRA_MUX_RSVD3,
TEGRA_MUX_RSVD4,
TEGRA_MUX_RTCK,
TEGRA_MUX_SDIO1,
TEGRA_MUX_SDIO2,
TEGRA_MUX_SDIO3,
TEGRA_MUX_SDIO4,
TEGRA_MUX_SFLASH,
TEGRA_MUX_SPDIF,
TEGRA_MUX_SPI1,
TEGRA_MUX_SPI2,
TEGRA_MUX_SPI2_ALT,
TEGRA_MUX_SPI3,
TEGRA_MUX_SPI4,
TEGRA_MUX_TRACE,
TEGRA_MUX_TWC,
TEGRA_MUX_UARTA,
TEGRA_MUX_UARTB,
TEGRA_MUX_UARTC,
TEGRA_MUX_UARTD,
TEGRA_MUX_UARTE,
TEGRA_MUX_ULPI,
TEGRA_MUX_VI,
TEGRA_MUX_VI_SENSOR_CLK,
TEGRA_MUX_XIO,
};
static const char * const ahb_clk_groups[] = {
"cdev2",
};
static const char * const apb_clk_groups[] = {
"cdev2",
};
static const char * const audio_sync_groups[] = {
"cdev1",
};
static const char * const crt_groups[] = {
"crtp",
"lm1",
};
static const char * const dap1_groups[] = {
"dap1",
};
static const char * const dap2_groups[] = {
"dap2",
};
static const char * const dap3_groups[] = {
"dap3",
};
static const char * const dap4_groups[] = {
"dap4",
};
static const char * const dap5_groups[] = {
"gme",
};
static const char * const displaya_groups[] = {
"lcsn",
"ld0",
"ld1",
"ld10",
"ld11",
"ld12",
"ld13",
"ld14",
"ld15",
"ld16",
"ld17",
"ld2",
"ld3",
"ld4",
"ld5",
"ld6",
"ld7",
"ld8",
"ld9",
"ldc",
"ldi",
"lhp0",
"lhp1",
"lhp2",
"lhs",
"lm0",
"lm1",
"lpp",
"lpw0",
"lpw1",
"lpw2",
"lsc0",
"lsc1",
"lsck",
"lsda",
"lsdi",
"lspi",
"lvp0",
"lvp1",
"lvs",
};
static const char * const displayb_groups[] = {
"lcsn",
"ld0",
"ld1",
"ld10",
"ld11",
"ld12",
"ld13",
"ld14",
"ld15",
"ld16",
"ld17",
"ld2",
"ld3",
"ld4",
"ld5",
"ld6",
"ld7",
"ld8",
"ld9",
"ldc",
"ldi",
"lhp0",
"lhp1",
"lhp2",
"lhs",
"lm0",
"lm1",
"lpp",
"lpw0",
"lpw1",
"lpw2",
"lsc0",
"lsc1",
"lsck",
"lsda",
"lsdi",
"lspi",
"lvp0",
"lvp1",
"lvs",
};
static const char * const emc_test0_dll_groups[] = {
"kbca",
};
static const char * const emc_test1_dll_groups[] = {
"kbcc",
};
static const char * const gmi_groups[] = {
"ata",
"atb",
"atc",
"atd",
"ate",
"dap1",
"dap2",
"dap4",
"gma",
"gmb",
"gmc",
"gmd",
"gme",
"gpu",
"irrx",
"irtx",
"pta",
"spia",
"spib",
"spic",
"spid",
"spie",
"uca",
"ucb",
};
static const char * const gmi_int_groups[] = {
"gmb",
};
static const char * const hdmi_groups[] = {
"hdint",
"lpw0",
"lpw2",
"lsc1",
"lsck",
"lsda",
"lspi",
"pta",
};
static const char * const i2cp_groups[] = {
"i2cp",
};
static const char * const i2c1_groups[] = {
"rm",
"spdi",
"spdo",
"spig",
"spih",
};
static const char * const i2c2_groups[] = {
"ddc",
"pta",
};
static const char * const i2c3_groups[] = {
"dtf",
};
static const char * const ide_groups[] = {
"ata",
"atb",
"atc",
"atd",
"ate",
"gmb",
};
static const char * const irda_groups[] = {
"uad",
};
static const char * const kbc_groups[] = {
"kbca",
"kbcb",
"kbcc",
"kbcd",
"kbce",
"kbcf",
};
static const char * const mio_groups[] = {
"kbcb",
"kbcd",
"kbcf",
};
static const char * const mipi_hs_groups[] = {
"uaa",
"uab",
};
static const char * const nand_groups[] = {
"ata",
"atb",
"atc",
"atd",
"ate",
"gmb",
"gmd",
"kbca",
"kbcb",
"kbcc",
"kbcd",
"kbce",
"kbcf",
};
static const char * const osc_groups[] = {
"cdev1",
"cdev2",
};
static const char * const owr_groups[] = {
"kbce",
"owc",
"uac",
};
static const char * const pcie_groups[] = {
"gpv",
"slxa",
"slxk",
};
static const char * const plla_out_groups[] = {
"cdev1",
};
static const char * const pllc_out1_groups[] = {
"csus",
};
static const char * const pllm_out1_groups[] = {
"cdev1",
};
static const char * const pllp_out2_groups[] = {
"csus",
};
static const char * const pllp_out3_groups[] = {
"csus",
};
static const char * const pllp_out4_groups[] = {
"cdev2",
};
static const char * const pwm_groups[] = {
"gpu",
"sdb",
"sdc",
"sdd",
"ucb",
};
static const char * const pwr_intr_groups[] = {
"pmc",
};
static const char * const pwr_on_groups[] = {
"pmc",
};
static const char * const rsvd1_groups[] = {
"dta",
"dtb",
"dtc",
"dtd",
"dte",
"gmd",
"gme",
};
static const char * const rsvd2_groups[] = {
"crtp",
"dap1",
"dap3",
"dap4",
"ddc",
"dtb",
"dtc",
"dte",
"dtf",
"gpu7",
"gpv",
"hdint",
"i2cp",
"owc",
"rm",
"sdio1",
"spdi",
"spdo",
"uac",
"uca",
"uda",
};
static const char * const rsvd3_groups[] = {
"crtp",
"dap2",
"dap3",
"ddc",
"gpu7",
"gpv",
"hdint",
"i2cp",
"ld17",
"ldc",
"ldi",
"lhp0",
"lhp1",
"lhp2",
"lm1",
"lpp",
"lpw1",
"lvp0",
"lvp1",
"owc",
"pmc",
"rm",
"uac",
};
static const char * const rsvd4_groups[] = {
"ata",
"ate",
"crtp",
"dap3",
"dap4",
"ddc",
"dta",
"dtc",
"dtd",
"dtf",
"gpu",
"gpu7",
"gpv",
"hdint",
"i2cp",
"kbce",
"lcsn",
"ld0",
"ld1",
"ld2",
"ld3",
"ld4",
"ld5",
"ld6",
"ld7",
"ld8",
"ld9",
"ld10",
"ld11",
"ld12",
"ld13",
"ld14",
"ld15",
"ld16",
"ld17",
"ldc",
"ldi",
"lhp0",
"lhp1",
"lhp2",
"lhs",
"lm0",
"lpp",
"lpw1",
"lsc0",
"lsdi",
"lvp0",
"lvp1",
"lvs",
"owc",
"pmc",
"pta",
"rm",
"spif",
"uac",
"uca",
"ucb",
};
static const char * const rtck_groups[] = {
"gpu7",
};
static const char * const sdio1_groups[] = {
"sdio1",
};
static const char * const sdio2_groups[] = {
"dap1",
"dta",
"dtd",
"kbca",
"kbcb",
"kbcd",
"spdi",
"spdo",
};
static const char * const sdio3_groups[] = {
"sdb",
"sdc",
"sdd",
"slxa",
"slxc",
"slxd",
"slxk",
};
static const char * const sdio4_groups[] = {
"atb",
"atc",
"atd",
"gma",
"gme",
};
static const char * const sflash_groups[] = {
"gmc",
"gmd",
};
static const char * const spdif_groups[] = {
"slxc",
"slxd",
"spdi",
"spdo",
"uad",
};
static const char * const spi1_groups[] = {
"dtb",
"dte",
"spia",
"spib",
"spic",
"spid",
"spie",
"spif",
"uda",
};
static const char * const spi2_groups[] = {
"sdb",
"slxa",
"slxc",
"slxd",
"slxk",
"spia",
"spib",
"spic",
"spid",
"spie",
"spif",
"spig",
"spih",
"uab",
};
static const char * const spi2_alt_groups[] = {
"spid",
"spie",
"spig",
"spih",
};
static const char * const spi3_groups[] = {
"gma",
"lcsn",
"lm0",
"lpw0",
"lpw2",
"lsc1",
"lsck",
"lsda",
"lsdi",
"sdc",
"sdd",
"spia",
"spib",
"spic",
"spif",
"spig",
"spih",
"uaa",
};
static const char * const spi4_groups[] = {
"gmc",
"irrx",
"irtx",
"slxa",
"slxc",
"slxd",
"slxk",
"uad",
};
static const char * const trace_groups[] = {
"kbcc",
"kbcf",
};
static const char * const twc_groups[] = {
"dap2",
"sdc",
};
static const char * const uarta_groups[] = {
"gpu",
"irrx",
"irtx",
"sdb",
"sdd",
"sdio1",
"uaa",
"uab",
"uad",
};
static const char * const uartb_groups[] = {
"irrx",
"irtx",
};
static const char * const uartc_groups[] = {
"uca",
"ucb",
};
static const char * const uartd_groups[] = {
"gmc",
"uda",
};
static const char * const uarte_groups[] = {
"gma",
"sdio1",
};
static const char * const ulpi_groups[] = {
"uaa",
"uab",
"uda",
};
static const char * const vi_groups[] = {
"dta",
"dtb",
"dtc",
"dtd",
"dte",
"dtf",
};
static const char * const vi_sensor_clk_groups[] = {
"csus",
};
static const char * const xio_groups[] = {
"ld0",
"ld1",
"ld10",
"ld11",
"ld12",
"ld13",
"ld14",
"ld15",
"ld16",
"ld2",
"ld3",
"ld4",
"ld5",
"ld6",
"ld7",
"ld8",
"ld9",
"lhs",
"lsc0",
"lspi",
"lvs",
};
#define FUNCTION(fname) \
{ \
.name = #fname, \
.groups = fname##_groups, \
.ngroups = ARRAY_SIZE(fname##_groups), \
}
static const struct tegra_function tegra20_functions[] = {
FUNCTION(ahb_clk),
FUNCTION(apb_clk),
FUNCTION(audio_sync),
FUNCTION(crt),
FUNCTION(dap1),
FUNCTION(dap2),
FUNCTION(dap3),
FUNCTION(dap4),
FUNCTION(dap5),
FUNCTION(displaya),
FUNCTION(displayb),
FUNCTION(emc_test0_dll),
FUNCTION(emc_test1_dll),
FUNCTION(gmi),
FUNCTION(gmi_int),
FUNCTION(hdmi),
FUNCTION(i2cp),
FUNCTION(i2c1),
FUNCTION(i2c2),
FUNCTION(i2c3),
FUNCTION(ide),
FUNCTION(irda),
FUNCTION(kbc),
FUNCTION(mio),
FUNCTION(mipi_hs),
FUNCTION(nand),
FUNCTION(osc),
FUNCTION(owr),
FUNCTION(pcie),
FUNCTION(plla_out),
FUNCTION(pllc_out1),
FUNCTION(pllm_out1),
FUNCTION(pllp_out2),
FUNCTION(pllp_out3),
FUNCTION(pllp_out4),
FUNCTION(pwm),
FUNCTION(pwr_intr),
FUNCTION(pwr_on),
FUNCTION(rsvd1),
FUNCTION(rsvd2),
FUNCTION(rsvd3),
FUNCTION(rsvd4),
FUNCTION(rtck),
FUNCTION(sdio1),
FUNCTION(sdio2),
FUNCTION(sdio3),
FUNCTION(sdio4),
FUNCTION(sflash),
FUNCTION(spdif),
FUNCTION(spi1),
FUNCTION(spi2),
FUNCTION(spi2_alt),
FUNCTION(spi3),
FUNCTION(spi4),
FUNCTION(trace),
FUNCTION(twc),
FUNCTION(uarta),
FUNCTION(uartb),
FUNCTION(uartc),
FUNCTION(uartd),
FUNCTION(uarte),
FUNCTION(ulpi),
FUNCTION(vi),
FUNCTION(vi_sensor_clk),
FUNCTION(xio),
};
#define TRISTATE_REG_A 0x14
#define PIN_MUX_CTL_REG_A 0x80
#define PULLUPDOWN_REG_A 0xa0
#define PINGROUP_REG_A 0x868
/* Pin group with mux control, and typically tri-state and pull-up/down too */
#define MUX_PG(pg_name, f0, f1, f2, f3, f_safe, \
tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b) \
{ \
.name = #pg_name, \
.pins = pg_name##_pins, \
.npins = ARRAY_SIZE(pg_name##_pins), \
.funcs = { \
TEGRA_MUX_ ## f0, \
TEGRA_MUX_ ## f1, \
TEGRA_MUX_ ## f2, \
TEGRA_MUX_ ## f3, \
}, \
.func_safe = TEGRA_MUX_ ## f_safe, \
.mux_reg = ((mux_r) - PIN_MUX_CTL_REG_A), \
.mux_bank = 1, \
.mux_bit = mux_b, \
.pupd_reg = ((pupd_r) - PULLUPDOWN_REG_A), \
.pupd_bank = 2, \
.pupd_bit = pupd_b, \
.tri_reg = ((tri_r) - TRISTATE_REG_A), \
.tri_bank = 0, \
.tri_bit = tri_b, \
.einput_reg = -1, \
.odrain_reg = -1, \
.lock_reg = -1, \
.ioreset_reg = -1, \
.drv_reg = -1, \
}
/* Pin groups with only pull up and pull down control */
#define PULL_PG(pg_name, pupd_r, pupd_b) \
{ \
.name = #pg_name, \
.pins = pg_name##_pins, \
.npins = ARRAY_SIZE(pg_name##_pins), \
.mux_reg = -1, \
.pupd_reg = ((pupd_r) - PULLUPDOWN_REG_A), \
.pupd_bank = 2, \
.pupd_bit = pupd_b, \
.tri_reg = -1, \
.einput_reg = -1, \
.odrain_reg = -1, \
.lock_reg = -1, \
.ioreset_reg = -1, \
.drv_reg = -1, \
}
/* Pin groups for drive strength registers (configurable version) */
#define DRV_PG_EXT(pg_name, r, hsm_b, schmitt_b, lpmd_b, \
drvdn_b, drvup_b, \
slwr_b, slwr_w, slwf_b, slwf_w) \
{ \
.name = "drive_" #pg_name, \
.pins = drive_##pg_name##_pins, \
.npins = ARRAY_SIZE(drive_##pg_name##_pins), \
.mux_reg = -1, \
.pupd_reg = -1, \
.tri_reg = -1, \
.einput_reg = -1, \
.odrain_reg = -1, \
.lock_reg = -1, \
.ioreset_reg = -1, \
.drv_reg = ((r) - PINGROUP_REG_A), \
.drv_bank = 3, \
.hsm_bit = hsm_b, \
.schmitt_bit = schmitt_b, \
.lpmd_bit = lpmd_b, \
.drvdn_bit = drvdn_b, \
.drvdn_width = 5, \
.drvup_bit = drvup_b, \
.drvup_width = 5, \
.slwr_bit = slwr_b, \
.slwr_width = slwr_w, \
.slwf_bit = slwf_b, \
.slwf_width = slwf_w, \
}
/* Pin groups for drive strength registers (simple version) */
#define DRV_PG(pg_name, r) \
DRV_PG_EXT(pg_name, r, 2, 3, 4, 12, 20, 28, 2, 30, 2)
static const struct tegra_pingroup tegra20_groups[] = {
/* name, f0, f1, f2, f3, f_safe, tri r/b, mux r/b, pupd r/b */
MUX_PG(ata, IDE, NAND, GMI, RSVD4, IDE, 0x14, 0, 0x80, 24, 0xa0, 0),
MUX_PG(atb, IDE, NAND, GMI, SDIO4, IDE, 0x14, 1, 0x80, 16, 0xa0, 2),
MUX_PG(atc, IDE, NAND, GMI, SDIO4, IDE, 0x14, 2, 0x80, 22, 0xa0, 4),
MUX_PG(atd, IDE, NAND, GMI, SDIO4, IDE, 0x14, 3, 0x80, 20, 0xa0, 6),
MUX_PG(ate, IDE, NAND, GMI, RSVD4, IDE, 0x18, 25, 0x80, 12, 0xa0, 8),
MUX_PG(cdev1, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, OSC, 0x14, 4, 0x88, 2, 0xa8, 0),
MUX_PG(cdev2, OSC, AHB_CLK, APB_CLK, PLLP_OUT4, OSC, 0x14, 5, 0x88, 4, 0xa8, 2),
MUX_PG(crtp, CRT, RSVD2, RSVD3, RSVD4, RSVD2, 0x20, 14, 0x98, 20, 0xa4, 24),
MUX_PG(csus, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, PLLC_OUT1, 0x14, 6, 0x88, 6, 0xac, 24),
MUX_PG(dap1, DAP1, RSVD2, GMI, SDIO2, DAP1, 0x14, 7, 0x88, 20, 0xa0, 10),
MUX_PG(dap2, DAP2, TWC, RSVD3, GMI, DAP2, 0x14, 8, 0x88, 22, 0xa0, 12),
MUX_PG(dap3, DAP3, RSVD2, RSVD3, RSVD4, DAP3, 0x14, 9, 0x88, 24, 0xa0, 14),
MUX_PG(dap4, DAP4, RSVD2, GMI, RSVD4, DAP4, 0x14, 10, 0x88, 26, 0xa0, 16),
MUX_PG(ddc, I2C2, RSVD2, RSVD3, RSVD4, RSVD4, 0x18, 31, 0x88, 0, 0xb0, 28),
MUX_PG(dta, RSVD1, SDIO2, VI, RSVD4, RSVD4, 0x14, 11, 0x84, 20, 0xa0, 18),
MUX_PG(dtb, RSVD1, RSVD2, VI, SPI1, RSVD1, 0x14, 12, 0x84, 22, 0xa0, 20),
MUX_PG(dtc, RSVD1, RSVD2, VI, RSVD4, RSVD1, 0x14, 13, 0x84, 26, 0xa0, 22),
MUX_PG(dtd, RSVD1, SDIO2, VI, RSVD4, RSVD1, 0x14, 14, 0x84, 28, 0xa0, 24),
MUX_PG(dte, RSVD1, RSVD2, VI, SPI1, RSVD1, 0x14, 15, 0x84, 30, 0xa0, 26),
MUX_PG(dtf, I2C3, RSVD2, VI, RSVD4, RSVD4, 0x20, 12, 0x98, 30, 0xa0, 28),
MUX_PG(gma, UARTE, SPI3, GMI, SDIO4, SPI3, 0x14, 28, 0x84, 0, 0xb0, 20),
MUX_PG(gmb, IDE, NAND, GMI, GMI_INT, GMI, 0x18, 29, 0x88, 28, 0xb0, 22),
MUX_PG(gmc, UARTD, SPI4, GMI, SFLASH, SPI4, 0x14, 29, 0x84, 2, 0xb0, 24),
MUX_PG(gmd, RSVD1, NAND, GMI, SFLASH, GMI, 0x18, 30, 0x88, 30, 0xb0, 26),
MUX_PG(gme, RSVD1, DAP5, GMI, SDIO4, GMI, 0x18, 0, 0x8c, 0, 0xa8, 24),
MUX_PG(gpu, PWM, UARTA, GMI, RSVD4, RSVD4, 0x14, 16, 0x8c, 4, 0xa4, 20),
MUX_PG(gpu7, RTCK, RSVD2, RSVD3, RSVD4, RTCK, 0x20, 11, 0x98, 28, 0xa4, 6),
MUX_PG(gpv, PCIE, RSVD2, RSVD3, RSVD4, PCIE, 0x14, 17, 0x8c, 2, 0xa0, 30),
MUX_PG(hdint, HDMI, RSVD2, RSVD3, RSVD4, HDMI, 0x1c, 23, 0x84, 4, -1, -1),
MUX_PG(i2cp, I2CP, RSVD2, RSVD3, RSVD4, RSVD4, 0x14, 18, 0x88, 8, 0xa4, 2),
MUX_PG(irrx, UARTA, UARTB, GMI, SPI4, UARTB, 0x14, 20, 0x88, 18, 0xa8, 22),
MUX_PG(irtx, UARTA, UARTB, GMI, SPI4, UARTB, 0x14, 19, 0x88, 16, 0xa8, 20),
MUX_PG(kbca, KBC, NAND, SDIO2, EMC_TEST0_DLL, KBC, 0x14, 22, 0x88, 10, 0xa4, 8),
MUX_PG(kbcb, KBC, NAND, SDIO2, MIO, KBC, 0x14, 21, 0x88, 12, 0xa4, 10),
MUX_PG(kbcc, KBC, NAND, TRACE, EMC_TEST1_DLL, KBC, 0x18, 26, 0x88, 14, 0xa4, 12),
MUX_PG(kbcd, KBC, NAND, SDIO2, MIO, KBC, 0x20, 10, 0x98, 26, 0xa4, 14),
MUX_PG(kbce, KBC, NAND, OWR, RSVD4, KBC, 0x14, 26, 0x80, 28, 0xb0, 2),
MUX_PG(kbcf, KBC, NAND, TRACE, MIO, KBC, 0x14, 27, 0x80, 26, 0xb0, 0),
MUX_PG(lcsn, DISPLAYA, DISPLAYB, SPI3, RSVD4, RSVD4, 0x1c, 31, 0x90, 12, -1, -1),
MUX_PG(ld0, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 0, 0x94, 0, -1, -1),
MUX_PG(ld1, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 1, 0x94, 2, -1, -1),
MUX_PG(ld2, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 2, 0x94, 4, -1, -1),
MUX_PG(ld3, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 3, 0x94, 6, -1, -1),
MUX_PG(ld4, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 4, 0x94, 8, -1, -1),
MUX_PG(ld5, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 5, 0x94, 10, -1, -1),
MUX_PG(ld6, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 6, 0x94, 12, -1, -1),
MUX_PG(ld7, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 7, 0x94, 14, -1, -1),
MUX_PG(ld8, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 8, 0x94, 16, -1, -1),
MUX_PG(ld9, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 9, 0x94, 18, -1, -1),
MUX_PG(ld10, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 10, 0x94, 20, -1, -1),
MUX_PG(ld11, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 11, 0x94, 22, -1, -1),
MUX_PG(ld12, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 12, 0x94, 24, -1, -1),
MUX_PG(ld13, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 13, 0x94, 26, -1, -1),
MUX_PG(ld14, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 14, 0x94, 28, -1, -1),
MUX_PG(ld15, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 15, 0x94, 30, -1, -1),
MUX_PG(ld16, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 16, 0x98, 0, -1, -1),
MUX_PG(ld17, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x1c, 17, 0x98, 2, -1, -1),
MUX_PG(ldc, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x1c, 30, 0x90, 14, -1, -1),
MUX_PG(ldi, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x20, 6, 0x98, 16, -1, -1),
MUX_PG(lhp0, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x1c, 18, 0x98, 10, -1, -1),
MUX_PG(lhp1, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x1c, 19, 0x98, 4, -1, -1),
MUX_PG(lhp2, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x1c, 20, 0x98, 6, -1, -1),
MUX_PG(lhs, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x20, 7, 0x90, 22, -1, -1),
MUX_PG(lm0, DISPLAYA, DISPLAYB, SPI3, RSVD4, RSVD4, 0x1c, 24, 0x90, 26, -1, -1),
MUX_PG(lm1, DISPLAYA, DISPLAYB, RSVD3, CRT, RSVD3, 0x1c, 25, 0x90, 28, -1, -1),
MUX_PG(lpp, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x20, 8, 0x98, 14, -1, -1),
MUX_PG(lpw0, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 3, 0x90, 0, -1, -1),
MUX_PG(lpw1, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x20, 4, 0x90, 2, -1, -1),
MUX_PG(lpw2, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 5, 0x90, 4, -1, -1),
MUX_PG(lsc0, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 27, 0x90, 18, -1, -1),
MUX_PG(lsc1, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x1c, 28, 0x90, 20, -1, -1),
MUX_PG(lsck, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x1c, 29, 0x90, 16, -1, -1),
MUX_PG(lsda, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 1, 0x90, 8, -1, -1),
MUX_PG(lsdi, DISPLAYA, DISPLAYB, SPI3, RSVD4, DISPLAYA, 0x20, 2, 0x90, 6, -1, -1),
MUX_PG(lspi, DISPLAYA, DISPLAYB, XIO, HDMI, DISPLAYA, 0x20, 0, 0x90, 10, -1, -1),
MUX_PG(lvp0, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x1c, 21, 0x90, 30, -1, -1),
MUX_PG(lvp1, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x1c, 22, 0x98, 8, -1, -1),
MUX_PG(lvs, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 26, 0x90, 24, -1, -1),
MUX_PG(owc, OWR, RSVD2, RSVD3, RSVD4, OWR, 0x14, 31, 0x84, 8, 0xb0, 30),
MUX_PG(pmc, PWR_ON, PWR_INTR, RSVD3, RSVD4, PWR_ON, 0x14, 23, 0x98, 18, -1, -1),
MUX_PG(pta, I2C2, HDMI, GMI, RSVD4, RSVD4, 0x14, 24, 0x98, 22, 0xa4, 4),
MUX_PG(rm, I2C1, RSVD2, RSVD3, RSVD4, RSVD4, 0x14, 25, 0x80, 14, 0xa4, 0),
MUX_PG(sdb, UARTA, PWM, SDIO3, SPI2, PWM, 0x20, 15, 0x8c, 10, -1, -1),
MUX_PG(sdc, PWM, TWC, SDIO3, SPI3, TWC, 0x18, 1, 0x8c, 12, 0xac, 28),
MUX_PG(sdd, UARTA, PWM, SDIO3, SPI3, PWM, 0x18, 2, 0x8c, 14, 0xac, 30),
MUX_PG(sdio1, SDIO1, RSVD2, UARTE, UARTA, RSVD2, 0x14, 30, 0x80, 30, 0xb0, 18),
MUX_PG(slxa, PCIE, SPI4, SDIO3, SPI2, PCIE, 0x18, 3, 0x84, 6, 0xa4, 22),
MUX_PG(slxc, SPDIF, SPI4, SDIO3, SPI2, SPI4, 0x18, 5, 0x84, 10, 0xa4, 26),
MUX_PG(slxd, SPDIF, SPI4, SDIO3, SPI2, SPI4, 0x18, 6, 0x84, 12, 0xa4, 28),
MUX_PG(slxk, PCIE, SPI4, SDIO3, SPI2, PCIE, 0x18, 7, 0x84, 14, 0xa4, 30),
MUX_PG(spdi, SPDIF, RSVD2, I2C1, SDIO2, RSVD2, 0x18, 8, 0x8c, 8, 0xa4, 16),
MUX_PG(spdo, SPDIF, RSVD2, I2C1, SDIO2, RSVD2, 0x18, 9, 0x8c, 6, 0xa4, 18),
MUX_PG(spia, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 10, 0x8c, 30, 0xa8, 4),
MUX_PG(spib, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 11, 0x8c, 28, 0xa8, 6),
MUX_PG(spic, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 12, 0x8c, 26, 0xa8, 8),
MUX_PG(spid, SPI2, SPI1, SPI2_ALT, GMI, GMI, 0x18, 13, 0x8c, 24, 0xa8, 10),
MUX_PG(spie, SPI2, SPI1, SPI2_ALT, GMI, GMI, 0x18, 14, 0x8c, 22, 0xa8, 12),
MUX_PG(spif, SPI3, SPI1, SPI2, RSVD4, RSVD4, 0x18, 15, 0x8c, 20, 0xa8, 14),
MUX_PG(spig, SPI3, SPI2, SPI2_ALT, I2C1, SPI2_ALT, 0x18, 16, 0x8c, 18, 0xa8, 16),
MUX_PG(spih, SPI3, SPI2, SPI2_ALT, I2C1, SPI2_ALT, 0x18, 17, 0x8c, 16, 0xa8, 18),
MUX_PG(uaa, SPI3, MIPI_HS, UARTA, ULPI, MIPI_HS, 0x18, 18, 0x80, 0, 0xac, 0),
MUX_PG(uab, SPI2, MIPI_HS, UARTA, ULPI, MIPI_HS, 0x18, 19, 0x80, 2, 0xac, 2),
MUX_PG(uac, OWR, RSVD2, RSVD3, RSVD4, RSVD4, 0x18, 20, 0x80, 4, 0xac, 4),
MUX_PG(uad, IRDA, SPDIF, UARTA, SPI4, SPDIF, 0x18, 21, 0x80, 6, 0xac, 6),
MUX_PG(uca, UARTC, RSVD2, GMI, RSVD4, RSVD4, 0x18, 22, 0x84, 16, 0xac, 8),
MUX_PG(ucb, UARTC, PWM, GMI, RSVD4, RSVD4, 0x18, 23, 0x84, 18, 0xac, 10),
MUX_PG(uda, SPI1, RSVD2, UARTD, ULPI, RSVD2, 0x20, 13, 0x80, 8, 0xb0, 16),
/* pg_name, pupd_r/b */
PULL_PG(ck32, 0xb0, 14),
PULL_PG(ddrc, 0xac, 26),
PULL_PG(pmca, 0xb0, 4),
PULL_PG(pmcb, 0xb0, 6),
PULL_PG(pmcc, 0xb0, 8),
PULL_PG(pmcd, 0xb0, 10),
PULL_PG(pmce, 0xb0, 12),
PULL_PG(xm2c, 0xa8, 30),
PULL_PG(xm2d, 0xa8, 28),
PULL_PG(ls, 0xac, 20),
PULL_PG(lc, 0xac, 22),
PULL_PG(ld17_0, 0xac, 12),
PULL_PG(ld19_18, 0xac, 14),
PULL_PG(ld21_20, 0xac, 16),
PULL_PG(ld23_22, 0xac, 18),
/* pg_name, r */
DRV_PG(ao1, 0x868),
DRV_PG(ao2, 0x86c),
DRV_PG(at1, 0x870),
DRV_PG(at2, 0x874),
DRV_PG(cdev1, 0x878),
DRV_PG(cdev2, 0x87c),
DRV_PG(csus, 0x880),
DRV_PG(dap1, 0x884),
DRV_PG(dap2, 0x888),
DRV_PG(dap3, 0x88c),
DRV_PG(dap4, 0x890),
DRV_PG(dbg, 0x894),
DRV_PG(lcd1, 0x898),
DRV_PG(lcd2, 0x89c),
DRV_PG(sdmmc2, 0x8a0),
DRV_PG(sdmmc3, 0x8a4),
DRV_PG(spi, 0x8a8),
DRV_PG(uaa, 0x8ac),
DRV_PG(uab, 0x8b0),
DRV_PG(uart2, 0x8b4),
DRV_PG(uart3, 0x8b8),
DRV_PG(vi1, 0x8bc),
DRV_PG(vi2, 0x8c0),
/* pg_name, r, hsm_b, schmitt_b, lpmd_b, drvdn_b, drvup_b, slwr_b, slwr_w, slwf_b, slwf_w */
DRV_PG_EXT(xm2a, 0x8c4, -1, -1, 4, 14, 19, 24, 4, 28, 4),
DRV_PG_EXT(xm2c, 0x8c8, -1, 3, -1, 14, 19, 24, 4, 28, 4),
DRV_PG_EXT(xm2d, 0x8cc, -1, 3, -1, 14, 19, 24, 4, 28, 4),
DRV_PG_EXT(xm2clk, 0x8d0, -1, -1, -1, 14, 19, 24, 4, 28, 4),
/* pg_name, r */
DRV_PG(sdio1, 0x8e0),
DRV_PG(crt, 0x8ec),
DRV_PG(ddc, 0x8f0),
DRV_PG(gma, 0x8f4),
DRV_PG(gmb, 0x8f8),
DRV_PG(gmc, 0x8fc),
DRV_PG(gmd, 0x900),
DRV_PG(gme, 0x904),
DRV_PG(owr, 0x908),
DRV_PG(uda, 0x90c),
};
static const struct tegra_pinctrl_soc_data tegra20_pinctrl = {
.ngpios = NUM_GPIOS,
.pins = tegra20_pins,
.npins = ARRAY_SIZE(tegra20_pins),
.functions = tegra20_functions,
.nfunctions = ARRAY_SIZE(tegra20_functions),
.groups = tegra20_groups,
.ngroups = ARRAY_SIZE(tegra20_groups),
};
void __devinit tegra20_pinctrl_init(const struct tegra_pinctrl_soc_data **soc)
{
*soc = &tegra20_pinctrl;
}
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -19,6 +19,9 @@ ...@@ -19,6 +19,9 @@
#include <linux/err.h> #include <linux/err.h>
#include <linux/pinctrl/pinctrl.h> #include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h> #include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/pinconf-generic.h>
#include "pinctrl-coh901.h"
/* /*
* Register definitions for the U300 Padmux control registers in the * Register definitions for the U300 Padmux control registers in the
...@@ -162,7 +165,7 @@ ...@@ -162,7 +165,7 @@
#define U300_SYSCON_PMC4R_APP_MISC_16_APP_UART1_CTS 0x0100 #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 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 * The DB3350 has 467 pads, I have enumerated the pads clockwise around the
...@@ -1044,22 +1047,82 @@ static struct pinctrl_gpio_range u300_gpio_ranges[] = { ...@@ -1044,22 +1047,82 @@ static struct pinctrl_gpio_range u300_gpio_ranges[] = {
U300_GPIO_RANGE(25, 181, 1), U300_GPIO_RANGE(25, 181, 1),
}; };
static struct pinctrl_gpio_range *u300_match_gpio_range(unsigned pin)
{
int i;
for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) {
struct pinctrl_gpio_range *range;
range = &u300_gpio_ranges[i];
if (pin >= range->pin_base &&
pin <= (range->pin_base + range->npins - 1))
return range;
}
return NULL;
}
int u300_pin_config_get(struct pinctrl_dev *pctldev,
unsigned pin,
unsigned long *config)
{
struct pinctrl_gpio_range *range = u300_match_gpio_range(pin);
/* We get config for those pins we CAN get it for and that's it */
if (!range)
return -ENOTSUPP;
return u300_gpio_config_get(range->gc,
(pin - range->pin_base + range->base),
config);
}
int u300_pin_config_set(struct pinctrl_dev *pctldev,
unsigned pin,
unsigned long config)
{
struct pinctrl_gpio_range *range = u300_match_gpio_range(pin);
int ret;
if (!range)
return -EINVAL;
/* Note: none of these configurations take any argument */
ret = u300_gpio_config_set(range->gc,
(pin - range->pin_base + range->base),
pinconf_to_config_param(config));
if (ret)
return ret;
return 0;
}
static struct pinconf_ops u300_pconf_ops = {
.is_generic = true,
.pin_config_get = u300_pin_config_get,
.pin_config_set = u300_pin_config_set,
};
static struct pinctrl_desc u300_pmx_desc = { static struct pinctrl_desc u300_pmx_desc = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.pins = u300_pads, .pins = u300_pads,
.npins = ARRAY_SIZE(u300_pads), .npins = ARRAY_SIZE(u300_pads),
.pctlops = &u300_pctrl_ops, .pctlops = &u300_pctrl_ops,
.pmxops = &u300_pmx_ops, .pmxops = &u300_pmx_ops,
.confops = &u300_pconf_ops,
.owner = THIS_MODULE, .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 u300_pmx *upmx;
struct resource *res; struct resource *res;
struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev);
int ret; int ret;
int i; int i;
pr_err("U300 PMX PROBE\n");
/* Create state holders etc for this driver */ /* Create state holders etc for this driver */
upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL); upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL);
if (!upmx) if (!upmx)
...@@ -1095,12 +1158,14 @@ static int __init u300_pmx_probe(struct platform_device *pdev) ...@@ -1095,12 +1158,14 @@ static int __init u300_pmx_probe(struct platform_device *pdev)
} }
/* We will handle a range of GPIO pins */ /* 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]); pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]);
}
platform_set_drvdata(pdev, upmx); 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; return 0;
...@@ -1115,7 +1180,7 @@ static int __init u300_pmx_probe(struct platform_device *pdev) ...@@ -1115,7 +1180,7 @@ static int __init u300_pmx_probe(struct platform_device *pdev)
return ret; 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); struct u300_pmx *upmx = platform_get_drvdata(pdev);
int i; int i;
...@@ -1136,12 +1201,13 @@ static struct platform_driver u300_pmx_driver = { ...@@ -1136,12 +1201,13 @@ static struct platform_driver u300_pmx_driver = {
.name = DRIVER_NAME, .name = DRIVER_NAME,
.owner = THIS_MODULE, .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) 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); arch_initcall(u300_pmx_init);
......
/* /*
* Core driver for the pin muxing portions of the pin control subsystem * 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 * Written on behalf of Linaro for ST-Ericsson
* Based on bits of regulator core, gpio core and clk core * Based on bits of regulator core, gpio core and clk core
* *
* Author: Linus Walleij <linus.walleij@linaro.org> * Author: Linus Walleij <linus.walleij@linaro.org>
* *
* Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved.
*
* License terms: GNU General Public License (GPL) version 2 * License terms: GNU General Public License (GPL) version 2
*/ */
#define pr_fmt(fmt) "pinmux core: " fmt #define pr_fmt(fmt) "pinmux core: " fmt
...@@ -19,8 +21,6 @@ ...@@ -19,8 +21,6 @@
#include <linux/radix-tree.h> #include <linux/radix-tree.h>
#include <linux/err.h> #include <linux/err.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/mutex.h>
#include <linux/spinlock.h>
#include <linux/string.h> #include <linux/string.h>
#include <linux/sysfs.h> #include <linux/sysfs.h>
#include <linux/debugfs.h> #include <linux/debugfs.h>
...@@ -28,80 +28,64 @@ ...@@ -28,80 +28,64 @@
#include <linux/pinctrl/machine.h> #include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinmux.h> #include <linux/pinctrl/pinmux.h>
#include "core.h" #include "core.h"
#include "pinmux.h"
/* List of pinmuxes */ int pinmux_check_ops(struct pinctrl_dev *pctldev)
static DEFINE_MUTEX(pinmux_list_mutex); {
static LIST_HEAD(pinmux_list); const struct pinmux_ops *ops = pctldev->desc->pmxops;
unsigned selector = 0;
/* Global pinmux maps */ /* Check that we implement required operations */
static struct pinmux_map *pinmux_maps; if (!ops->list_functions ||
static unsigned pinmux_maps_num; !ops->get_function_name ||
!ops->get_function_groups ||
!ops->enable ||
!ops->disable)
return -EINVAL;
/** /* Check that all functions registered have names */
* struct pinmux_group - group list item for pinmux groups while (ops->list_functions(pctldev, selector) >= 0) {
* @node: pinmux group list node const char *fname = ops->get_function_name(pctldev,
* @group_selector: the group selector for this group selector);
*/ if (!fname) {
struct pinmux_group { pr_err("pinmux ops has no name for function%u\n",
struct list_head node; selector);
unsigned group_selector; return -EINVAL;
}; }
selector++;
}
/** return 0;
* 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;
};
/** int pinmux_validate_map(struct pinctrl_map const *map, int i)
* struct pinmux_hog - a list item to stash mux hogs {
* @node: pinmux hog list node if (!map->data.mux.function) {
* @map: map entry responsible for this hogging pr_err("failed to register map %s (%d): no function given\n",
* @pmx: the pinmux hogged by this item map->name, i);
*/ return -EINVAL;
struct pinmux_hog { }
struct list_head node;
struct pinmux_map const *map; return 0;
struct pinmux *pmx; }
};
/** /**
* pin_request() - request a single pin to be muxed in, typically for GPIO * pin_request() - request a single pin to be muxed in, typically for GPIO
* @pin: the pin number in the global pin space * @pin: the pin number in the global pin space
* @function: a functional name to give to this pin, passed to the driver * @owner: a representation of the owner of this pin; typically the device
* so it knows what function to mux in, e.g. the string "gpioNN" * name that controls its mux function, or the requested GPIO name
* means that you want to mux in the pin for use as GPIO number NN
* @gpio_range: the range matching the GPIO pin if this is a request for a * @gpio_range: the range matching the GPIO pin if this is a request for a
* single GPIO pin * single GPIO pin
*/ */
static int pin_request(struct pinctrl_dev *pctldev, 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 pinctrl_gpio_range *gpio_range)
{ {
struct pin_desc *desc; struct pin_desc *desc;
const struct pinmux_ops *ops = pctldev->desc->pmxops; const struct pinmux_ops *ops = pctldev->desc->pmxops;
int status = -EINVAL; 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); desc = pin_desc_get(pctldev, pin);
if (desc == NULL) { if (desc == NULL) {
...@@ -110,20 +94,28 @@ static int pin_request(struct pinctrl_dev *pctldev, ...@@ -110,20 +94,28 @@ static int pin_request(struct pinctrl_dev *pctldev,
goto out; goto out;
} }
if (!function) { if (gpio_range) {
dev_err(pctldev->dev, "no function name given\n"); /* There's no need to support multiple GPIO requests */
return -EINVAL; if (desc->gpio_owner) {
} dev_err(pctldev->dev,
"pin already requested\n");
goto out;
}
spin_lock(&desc->lock); desc->gpio_owner = owner;
if (desc->mux_function) { } else {
spin_unlock(&desc->lock); if (desc->mux_usecount && strcmp(desc->mux_owner, owner)) {
dev_err(pctldev->dev, dev_err(pctldev->dev,
"pin already requested\n"); "pin already requested\n");
goto out; goto out;
}
desc->mux_usecount++;
if (desc->mux_usecount > 1)
return 0;
desc->mux_owner = owner;
} }
desc->mux_function = function;
spin_unlock(&desc->lock);
/* Let each pin increase references to this module */ /* Let each pin increase references to this module */
if (!try_module_get(pctldev->owner)) { if (!try_module_get(pctldev->owner)) {
...@@ -146,19 +138,26 @@ static int pin_request(struct pinctrl_dev *pctldev, ...@@ -146,19 +138,26 @@ static int pin_request(struct pinctrl_dev *pctldev,
else else
status = 0; status = 0;
if (status) if (status) {
dev_err(pctldev->dev, "->request on device %s failed for pin %d\n", dev_err(pctldev->dev, "->request on device %s failed for pin %d\n",
pctldev->desc->name, pin); pctldev->desc->name, pin);
module_put(pctldev->owner);
}
out_free_pin: out_free_pin:
if (status) { if (status) {
spin_lock(&desc->lock); if (gpio_range) {
desc->mux_function = NULL; desc->gpio_owner = NULL;
spin_unlock(&desc->lock); } else {
desc->mux_usecount--;
if (!desc->mux_usecount)
desc->mux_owner = NULL;
}
} }
out: out:
if (status) if (status)
dev_err(pctldev->dev, "pin-%d (%s) status %d\n", dev_err(pctldev->dev, "pin-%d (%s) status %d\n",
pin, function ? : "?", status); pin, owner, status);
return status; return status;
} }
...@@ -170,8 +169,8 @@ static int pin_request(struct pinctrl_dev *pctldev, ...@@ -170,8 +169,8 @@ static int pin_request(struct pinctrl_dev *pctldev,
* @gpio_range: the range matching the GPIO pin if this is a request for a * @gpio_range: the range matching the GPIO pin if this is a request for a
* single GPIO pin * single GPIO pin
* *
* This function returns a pointer to the function name in use. This is used * This function returns a pointer to the previous owner. This is used
* for callers that dynamically allocate a function name so it can be freed * 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. * once the pin is free. This is done for GPIO request functions.
*/ */
static const char *pin_free(struct pinctrl_dev *pctldev, int pin, static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
...@@ -179,7 +178,7 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, ...@@ -179,7 +178,7 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
{ {
const struct pinmux_ops *ops = pctldev->desc->pmxops; const struct pinmux_ops *ops = pctldev->desc->pmxops;
struct pin_desc *desc; struct pin_desc *desc;
const char *func; const char *owner;
desc = pin_desc_get(pctldev, pin); desc = pin_desc_get(pctldev, pin);
if (desc == NULL) { if (desc == NULL) {
...@@ -188,6 +187,12 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, ...@@ -188,6 +187,12 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
return NULL; return NULL;
} }
if (!gpio_range) {
desc->mux_usecount--;
if (desc->mux_usecount)
return NULL;
}
/* /*
* If there is no kind of request function for the pin we just assume * If there is no kind of request function for the pin we just assume
* we got it by default and proceed. * we got it by default and proceed.
...@@ -197,99 +202,79 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, ...@@ -197,99 +202,79 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin,
else if (ops->free) else if (ops->free)
ops->free(pctldev, pin); ops->free(pctldev, pin);
spin_lock(&desc->lock); if (gpio_range) {
func = desc->mux_function; owner = desc->gpio_owner;
desc->mux_function = NULL; desc->gpio_owner = NULL;
spin_unlock(&desc->lock); } else {
owner = desc->mux_owner;
desc->mux_owner = NULL;
desc->mux_setting = NULL;
}
module_put(pctldev->owner); module_put(pctldev->owner);
return func; return owner;
} }
/** /**
* pinmux_request_gpio() - request a single pin to be muxed in as GPIO * pinmux_request_gpio() - request pinmuxing for a GPIO pin
* @gpio: the GPIO pin number from the GPIO subsystem number space * @pctldev: pin controller device affected
* * @pin: the pin to mux in for GPIO
* This function should *ONLY* be used from gpiolib-based GPIO drivers, * @range: the applicable GPIO range
* as part of their gpio_request() semantics, platforms and individual drivers
* shall *NOT* request GPIO pins to be muxed in.
*/ */
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]; char gpiostr[16];
const char *function; const char *owner;
struct pinctrl_dev *pctldev;
struct pinctrl_gpio_range *range;
int ret; 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 */ /* Conjure some name stating what chip and pin this is taken by */
snprintf(gpiostr, 15, "%s:%d", range->name, gpio); snprintf(gpiostr, 15, "%s:%d", range->name, gpio);
function = kstrdup(gpiostr, GFP_KERNEL); owner = kstrdup(gpiostr, GFP_KERNEL);
if (!function) if (!owner)
return -EINVAL; return -EINVAL;
ret = pin_request(pctldev, pin, function, range); ret = pin_request(pctldev, pin, owner, range);
if (ret < 0) if (ret < 0)
kfree(function); kfree(owner);
return ret; return ret;
} }
EXPORT_SYMBOL_GPL(pinmux_request_gpio);
/** /**
* pinmux_free_gpio() - free a single pin, currently used as GPIO * pinmux_free_gpio() - release a pin from GPIO muxing
* @gpio: the GPIO pin number from the GPIO subsystem number space * @pctldev: the pin controller device for the pin
* * @pin: the affected currently GPIO-muxed in pin
* This function should *ONLY* be used from gpiolib-based GPIO drivers, * @range: applicable GPIO range
* as part of their gpio_free() semantics, platforms and individual drivers
* shall *NOT* request GPIO pins to be muxed out.
*/ */
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; const char *owner;
struct pinctrl_gpio_range *range;
int ret;
int pin;
const char *func;
ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); owner = pin_free(pctldev, pin, range);
if (ret) kfree(owner);
return;
/* Convert to the pin controllers number space */
pin = gpio - range->base + range->pin_base;
func = pin_free(pctldev, pin, range);
kfree(func);
} }
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; const struct pinmux_ops *ops;
int ret; int ret;
int pin;
ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range);
if (ret)
return ret;
ops = pctldev->desc->pmxops; ops = pctldev->desc->pmxops;
/* Convert to the pin controllers number space */
pin = gpio - range->base + range->pin_base;
if (ops->gpio_set_direction) if (ops->gpio_set_direction)
ret = ops->gpio_set_direction(pctldev, range, pin, input); ret = ops->gpio_set_direction(pctldev, range, pin, input);
else else
...@@ -298,146 +283,89 @@ static int pinmux_gpio_direction(unsigned gpio, bool input) ...@@ -298,146 +283,89 @@ static int pinmux_gpio_direction(unsigned gpio, bool input)
return ret; return ret;
} }
/** static int pinmux_func_name_to_selector(struct pinctrl_dev *pctldev,
* pinmux_gpio_direction_input() - request a GPIO pin to go into input mode const char *function)
* @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)
{ {
void *tmp_maps; const struct pinmux_ops *ops = pctldev->desc->pmxops;
int i; unsigned selector = 0;
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;
}
if (!maps[i].function) { /* See if this pctldev has this function */
pr_err("failed to register map %s (%d): no function ID given\n", while (ops->list_functions(pctldev, selector) >= 0) {
maps[i].name, i); const char *fname = ops->get_function_name(pctldev,
return -EINVAL; selector);
}
if (!maps[i].dev && !maps[i].dev_name) if (!strcmp(function, fname))
pr_debug("add system map %s function %s with no device\n", return selector;
maps[i].name,
maps[i].function);
else
pr_debug("register map %s, function %s\n",
maps[i].name,
maps[i].function);
}
/* 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);
} }
pinmux_maps = tmp_maps; pr_err("%s does not support function %s\n",
pinmux_maps_num += num_maps; pinctrl_dev_get_name(pctldev), function);
return 0; return -EINVAL;
} }
/** int pinmux_map_to_setting(struct pinctrl_map const *map,
* acquire_pins() - acquire all the pins for a certain function on a pinmux struct pinctrl_setting *setting)
* @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)
{ {
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinmux_ops *pmxops = pctldev->desc->pmxops; const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
const char *func = pmxops->get_function_name(pctldev, const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
func_selector); char const * const *groups;
const unsigned *pins; unsigned num_groups;
unsigned num_pins;
int ret; int ret;
const char *group;
int i; int i;
const unsigned *pins;
unsigned num_pins;
ret = pctlops->get_group_pins(pctldev, group_selector, setting->data.mux.func =
&pins, &num_pins); pinmux_func_name_to_selector(pctldev, map->data.mux.function);
if (ret) 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; return ret;
if (!num_groups)
return -EINVAL;
dev_dbg(pctldev->dev, "requesting the %u pins from group %u\n", if (map->data.mux.group) {
num_pins, group_selector); 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;
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 */ /* Try to allocate all pins in this group, one by one */
for (i = 0; i < num_pins; i++) { 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) { if (ret) {
dev_err(pctldev->dev, dev_err(pctldev->dev,
"could not get pin %d for function %s on device %s - conflicting mux mappings?\n", "could not get request pin %d on device %s\n",
pins[i], func ? : "(undefined)", pins[i], pinctrl_dev_get_name(pctldev));
pinctrl_dev_get_name(pctldev));
/* On error release all taken pins */ /* On error release all taken pins */
i--; /* this pin just failed */ i--; /* this pin just failed */
for (; i >= 0; i--) for (; i >= 0; i--)
...@@ -445,587 +373,101 @@ static int acquire_pins(struct pinctrl_dev *pctldev, ...@@ -445,587 +373,101 @@ static int acquire_pins(struct pinctrl_dev *pctldev,
return -ENODEV; return -ENODEV;
} }
} }
return 0; return 0;
} }
/** void pinmux_free_setting(struct pinctrl_setting const *setting)
* 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)
{ {
struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
const unsigned *pins; const unsigned *pins;
unsigned num_pins; unsigned num_pins;
int ret; int ret;
int i; int i;
ret = pctlops->get_group_pins(pctldev, group_selector, ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
&pins, &num_pins); &pins, &num_pins);
if (ret) { if (ret) {
dev_err(pctldev->dev, "could not get pins to release for group selector %d\n", dev_err(pctldev->dev,
group_selector); "could not get pins for device %s group selector %d\n",
pinctrl_dev_get_name(pctldev), setting->data.mux.group);
return; return;
} }
for (i = 0; i < num_pins; i++) for (i = 0; i < num_pins; i++)
pin_free(pctldev, pins[i], NULL); pin_free(pctldev, pins[i], NULL);
} }
/** int pinmux_enable_setting(struct pinctrl_setting const *setting)
* 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)
{ {
const struct pinmux_ops *pmxops = pctldev->desc->pmxops; struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; 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; 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; int ret;
const unsigned *pins;
unsigned num_pins;
int i;
struct pin_desc *desc;
/* ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
* Note that we're not locking the pinmux mutex here, because &pins, &num_pins);
* 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);
if (ret) { if (ret) {
kfree(grp); /* errors only affect debug data, so just warn */
return ret; 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)");
/* for (i = 0; i < num_pins; i++) {
* create the state cookie holder struct pinmux for each desc = pin_desc_get(pctldev, pins[i]);
* mapping, this is what consumers will get when requesting if (desc == NULL) {
* a pinmux handle with pinmux_get() dev_warn(pctldev->dev,
*/ "could not get pin desc for pin %d\n",
pmx = kzalloc(sizeof(struct pinmux), GFP_KERNEL); pins[i]);
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... */
continue; continue;
} }
desc->mux_setting = &(setting->data.mux);
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", return ops->enable(pctldev, setting->data.mux.func,
num_maps, setting->data.mux.group);
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);
/** void pinmux_disable_setting(struct pinctrl_setting const *setting)
* 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;
}
}
}
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);
}
EXPORT_SYMBOL_GPL(pinmux_disable);
int pinmux_check_ops(struct pinctrl_dev *pctldev)
{ {
struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
const struct pinmux_ops *ops = pctldev->desc->pmxops; 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; int ret;
const unsigned *pins;
unsigned num_pins;
int i;
struct pin_desc *desc;
if (map->dev || map->dev_name) { ret = pctlops->get_group_pins(pctldev, setting->data.mux.group,
/* &pins, &num_pins);
* 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);
if (ret) { if (ret) {
pinmux_put(pmx); /* errors only affect debug data, so just warn */
kfree(hog); dev_warn(pctldev->dev,
dev_err(pctldev->dev, "could not get pins for group selector %d\n",
"could not enable the %s pinmux mapping for hogging\n", setting->data.mux.group);
map->name); num_pins = 0;
return ret;
} }
hog->map = map; for (i = 0; i < num_pins; i++) {
hog->pmx = pmx; desc = pin_desc_get(pctldev, pins[i]);
if (desc == NULL) {
dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name, dev_warn(pctldev->dev,
map->function); "could not get pin desc for pin %d\n",
mutex_lock(&pctldev->pinmux_hogs_lock); pins[i]);
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)
continue; 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;
}
/** ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group);
* 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);
} }
#ifdef CONFIG_DEBUG_FS #ifdef CONFIG_DEBUG_FS
...@@ -1037,6 +479,8 @@ static int pinmux_functions_show(struct seq_file *s, void *what) ...@@ -1037,6 +479,8 @@ static int pinmux_functions_show(struct seq_file *s, void *what)
const struct pinmux_ops *pmxops = pctldev->desc->pmxops; const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
unsigned func_selector = 0; unsigned func_selector = 0;
mutex_lock(&pinctrl_mutex);
while (pmxops->list_functions(pctldev, func_selector) >= 0) { while (pmxops->list_functions(pctldev, func_selector) >= 0) {
const char *func = pmxops->get_function_name(pctldev, const char *func = pmxops->get_function_name(pctldev,
func_selector); func_selector);
...@@ -1057,24 +501,29 @@ static int pinmux_functions_show(struct seq_file *s, void *what) ...@@ -1057,24 +501,29 @@ static int pinmux_functions_show(struct seq_file *s, void *what)
seq_puts(s, "]\n"); seq_puts(s, "]\n");
func_selector++; func_selector++;
} }
mutex_unlock(&pinctrl_mutex);
return 0; return 0;
} }
static int pinmux_pins_show(struct seq_file *s, void *what) static int pinmux_pins_show(struct seq_file *s, void *what)
{ {
struct pinctrl_dev *pctldev = s->private; 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; unsigned i, pin;
seq_puts(s, "Pinmux settings per pin\n"); seq_puts(s, "Pinmux settings per pin\n");
seq_puts(s, "Format: pin (name): pinmuxfunction\n"); seq_puts(s, "Format: pin (name): mux_owner gpio_owner hog?\n");
mutex_lock(&pinctrl_mutex);
/* The pin number can be retrived from the pin controller descriptor */ /* The pin number can be retrived from the pin controller descriptor */
for (i = 0; i < pctldev->desc->npins; i++) { for (i = 0; i < pctldev->desc->npins; i++) {
struct pin_desc *desc; struct pin_desc *desc;
bool is_hog = false;
pin = pctldev->desc->pins[i].number; pin = pctldev->desc->pins[i].number;
desc = pin_desc_get(pctldev, pin); desc = pin_desc_get(pctldev, pin);
...@@ -1082,94 +531,52 @@ static int pinmux_pins_show(struct seq_file *s, void *what) ...@@ -1082,94 +531,52 @@ static int pinmux_pins_show(struct seq_file *s, void *what)
if (desc == NULL) if (desc == NULL)
continue; continue;
seq_printf(s, "pin %d (%s): %s\n", pin, if (desc->mux_owner &&
!strcmp(desc->mux_owner, pinctrl_dev_get_name(pctldev)))
is_hog = true;
seq_printf(s, "pin %d (%s): %s %s%s", pin,
desc->name ? desc->name : "unnamed", desc->name ? desc->name : "unnamed",
desc->mux_function ? desc->mux_function desc->mux_owner ? desc->mux_owner
: "UNCLAIMED"); : "(MUX UNCLAIMED)",
desc->gpio_owner ? desc->gpio_owner
: "(GPIO UNCLAIMED)",
is_hog ? " (HOG)" : "");
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");
} }
return 0; mutex_unlock(&pinctrl_mutex);
}
static int pinmux_hogs_show(struct seq_file *s, void *what)
{
struct pinctrl_dev *pctldev = s->private;
struct pinmux_hog *hog;
seq_puts(s, "Pinmux map hogs held by device\n");
list_for_each_entry(hog, &pctldev->pinmux_hogs, node)
seq_printf(s, "%s\n", hog->map->name);
return 0; 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_printf(s, "group %s\nfunction %s\n",
map->data.mux.group ? map->data.mux.group : "(default)",
seq_puts(s, "Requested pinmuxes and their maps:\n"); map->data.mux.function);
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;
} }
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; struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinmux_ops *pmxops = pctldev->desc->pmxops;
seq_puts(s, "Pinmux maps:\n"); const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
for (i = 0; i < pinmux_maps_num; i++) {
struct pinmux_map const *map = &pinmux_maps[i];
seq_printf(s, "%s:\n", map->name); seq_printf(s, "group: %s (%u) function: %s (%u)\n",
if (map->dev || map->dev_name) pctlops->get_group_name(pctldev, setting->data.mux.group),
seq_printf(s, " device: %s\n", setting->data.mux.group,
map->dev ? dev_name(map->dev) : pmxops->get_function_name(pctldev, setting->data.mux.func),
map->dev_name); setting->data.mux.func);
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;
} }
static int pinmux_functions_open(struct inode *inode, struct file *file) static int pinmux_functions_open(struct inode *inode, struct file *file)
...@@ -1182,21 +589,6 @@ static int pinmux_pins_open(struct inode *inode, struct file *file) ...@@ -1182,21 +589,6 @@ static int pinmux_pins_open(struct inode *inode, struct file *file)
return single_open(file, pinmux_pins_show, inode->i_private); 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 = { static const struct file_operations pinmux_functions_ops = {
.open = pinmux_functions_open, .open = pinmux_functions_open,
.read = seq_read, .read = seq_read,
...@@ -1211,27 +603,6 @@ static const struct file_operations pinmux_pins_ops = { ...@@ -1211,27 +603,6 @@ static const struct file_operations pinmux_pins_ops = {
.release = single_release, .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, void pinmux_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev) struct pinctrl_dev *pctldev)
{ {
...@@ -1239,16 +610,6 @@ void pinmux_init_device_debugfs(struct dentry *devroot, ...@@ -1239,16 +610,6 @@ void pinmux_init_device_debugfs(struct dentry *devroot,
devroot, pctldev, &pinmux_functions_ops); devroot, pctldev, &pinmux_functions_ops);
debugfs_create_file("pinmux-pins", S_IFREG | S_IRUGO, debugfs_create_file("pinmux-pins", S_IFREG | S_IRUGO,
devroot, pctldev, &pinmux_pins_ops); 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 */ #endif /* CONFIG_DEBUG_FS */
...@@ -13,11 +13,29 @@ ...@@ -13,11 +13,29 @@
#ifdef CONFIG_PINMUX #ifdef CONFIG_PINMUX
int pinmux_check_ops(struct pinctrl_dev *pctldev); 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, void pinmux_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev); 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 #else
...@@ -26,21 +44,63 @@ static inline int pinmux_check_ops(struct pinctrl_dev *pctldev) ...@@ -26,21 +44,63 @@ static inline int pinmux_check_ops(struct pinctrl_dev *pctldev)
return 0; return 0;
} }
static inline void pinmux_init_device_debugfs(struct dentry *devroot, static inline int pinmux_validate_map(struct pinctrl_map const *map, int i)
struct pinctrl_dev *pctldev)
{ {
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; 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)
{ {
} }
......
...@@ -22,7 +22,7 @@ ...@@ -22,7 +22,7 @@
#include <linux/io.h> #include <linux/io.h>
#include <asm/irq.h> #include <asm/irq.h>
#include <asm/mach/irq.h> #include <asm/mach/irq.h>
#include <linux/pinctrl/pinmux.h> #include <linux/pinctrl/consumer.h>
#include "sirfsoc_uart.h" #include "sirfsoc_uart.h"
...@@ -673,12 +673,10 @@ int sirfsoc_uart_probe(struct platform_device *pdev) ...@@ -673,12 +673,10 @@ int sirfsoc_uart_probe(struct platform_device *pdev)
port->irq = res->start; port->irq = res->start;
if (sirfport->hw_flow_ctrl) { if (sirfport->hw_flow_ctrl) {
sirfport->pmx = pinmux_get(&pdev->dev, NULL); sirfport->p = pinctrl_get_select_default(&pdev->dev);
ret = IS_ERR(sirfport->pmx); ret = IS_ERR(sirfport->p);
if (ret) if (ret)
goto pmx_err; goto pin_err;
pinmux_enable(sirfport->pmx);
} }
port->ops = &sirfsoc_uart_ops; port->ops = &sirfsoc_uart_ops;
...@@ -695,11 +693,9 @@ int sirfsoc_uart_probe(struct platform_device *pdev) ...@@ -695,11 +693,9 @@ int sirfsoc_uart_probe(struct platform_device *pdev)
port_err: port_err:
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
if (sirfport->hw_flow_ctrl) { if (sirfport->hw_flow_ctrl)
pinmux_disable(sirfport->pmx); pinctrl_put(sirfport->p);
pinmux_put(sirfport->pmx); pin_err:
}
pmx_err:
irq_err: irq_err:
devm_iounmap(&pdev->dev, port->membase); devm_iounmap(&pdev->dev, port->membase);
err: err:
...@@ -711,10 +707,8 @@ static int sirfsoc_uart_remove(struct platform_device *pdev) ...@@ -711,10 +707,8 @@ static int sirfsoc_uart_remove(struct platform_device *pdev)
struct sirfsoc_uart_port *sirfport = platform_get_drvdata(pdev); struct sirfsoc_uart_port *sirfport = platform_get_drvdata(pdev);
struct uart_port *port = &sirfport->port; struct uart_port *port = &sirfport->port;
platform_set_drvdata(pdev, NULL); platform_set_drvdata(pdev, NULL);
if (sirfport->hw_flow_ctrl) { if (sirfport->hw_flow_ctrl)
pinmux_disable(sirfport->pmx); pinctrl_put(sirfport->p);
pinmux_put(sirfport->pmx);
}
devm_iounmap(&pdev->dev, port->membase); devm_iounmap(&pdev->dev, port->membase);
uart_remove_one_port(&sirfsoc_uart_drv, port); uart_remove_one_port(&sirfsoc_uart_drv, port);
return 0; return 0;
......
...@@ -162,7 +162,7 @@ struct sirfsoc_uart_port { ...@@ -162,7 +162,7 @@ struct sirfsoc_uart_port {
unsigned char ms_enabled; unsigned char ms_enabled;
struct uart_port port; struct uart_port port;
struct pinmux *pmx; struct pinctrl *p;
}; };
/* Hardware Flow Control */ /* Hardware Flow Control */
......
/*
* 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 */
...@@ -9,87 +9,153 @@ ...@@ -9,87 +9,153 @@
* *
* License terms: GNU General Public License (GPL) version 2 * License terms: GNU General Public License (GPL) version 2
*/ */
#ifndef __LINUX_PINMUX_MACHINE_H #ifndef __LINUX_PINCTRL_MACHINE_H
#define __LINUX_PINMUX_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. * @name: the name of this specific map entry for the particular machine.
* This is the second parameter passed to pinmux_get() when you want * This is the parameter passed to pinmux_lookup_state()
* to have several mappings to the same device * @type: the type of mapping table entry
* @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)
* @ctrl_dev_name: the name of the device controlling this specific mapping, * @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 * the name must be the same as in your struct device*. This field is not
* you provide .ctrl_dev instead * used for PIN_MAP_TYPE_DUMMY_STATE
* @function: a function in the driver to use for this mapping, the driver * @data: Data specific to the mapping type
* 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.
*/ */
struct pinmux_map { struct pinctrl_map {
const char *dev_name;
const char *name; const char *name;
struct device *ctrl_dev; enum pinctrl_map_type type;
const char *ctrl_dev_name; const char *ctrl_dev_name;
const char *function; union {
const char *group; struct pinctrl_map_mux mux;
struct device *dev; struct pinctrl_map_configs configs;
const char *dev_name; } data;
bool hog_on_boot;
}; };
/* /* Convenience macros to create mapping table entries */
* 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 }
/* #define PIN_MAP_DUMMY_STATE(dev, state) \
* Convenience macro to map a system function onto a certain pinctrl device. { \
* System functions are not assigned to a particular device. .dev_name = dev, \
*/ .name = state, \
#define PINMUX_MAP_SYS(a, b, c) \ .type = PIN_MAP_TYPE_DUMMY_STATE, \
{ .name = a, .ctrl_dev_name = b, .function = c } }
/* #define PIN_MAP_MUX_GROUP(dev, state, pinctrl, grp, func) \
* Convenience macro to map a system function onto a certain pinctrl device, { \
* to be hogged by the pinmux core until the system shuts down. .dev_name = dev, \
*/ .name = state, \
#define PINMUX_MAP_SYS_HOG(a, b, c) \ .type = PIN_MAP_TYPE_MUX_GROUP, \
{ .name = a, .ctrl_dev_name = b, .function = c, \ .ctrl_dev_name = pinctrl, \
.hog_on_boot = true } .data.mux = { \
.group = grp, \
.function = func, \
}, \
}
/* #define PIN_MAP_MUX_GROUP_DEFAULT(dev, pinctrl, grp, func) \
* Convenience macro to map a system function onto a certain pinctrl device PIN_MAP_MUX_GROUP(dev, PINCTRL_STATE_DEFAULT, pinctrl, grp, func)
* using a specified group, to be hogged by the pinmux core until the system
* shuts down. #define PIN_MAP_MUX_GROUP_HOG(dev, state, grp, func) \
*/ PIN_MAP_MUX_GROUP(dev, state, dev, grp, func)
#define PINMUX_MAP_SYS_HOG_GROUP(a, b, c, d) \
{ .name = a, .ctrl_dev_name = b, .function = c, .group = d, \ #define PIN_MAP_MUX_GROUP_HOG_DEFAULT(dev, grp, func) \
.hog_on_boot = true } 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 #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); unsigned num_maps);
#else #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) unsigned num_maps)
{ {
return 0; return 0;
......
/*
* Interface the generic pinconfig portions of the pinctrl subsystem
*
* Copyright (C) 2011 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
* This interface is used in the core to keep track of pins.
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
* License terms: GNU General Public License (GPL) version 2
*/
#ifndef __LINUX_PINCTRL_PINCONF_GENERIC_H
#define __LINUX_PINCTRL_PINCONF_GENERIC_H
/*
* You shouldn't even be able to compile with these enums etc unless you're
* using generic pin config. That is why this is defined out.
*/
#ifdef CONFIG_GENERIC_PINCONF
/**
* enum pin_config_param - possible pin configuration parameters
* @PIN_CONFIG_BIAS_DISABLE: disable any pin bias on the pin, a
* transition from say pull-up to pull-down implies that you disable
* pull-up in the process, this setting disables all biasing.
* @PIN_CONFIG_BIAS_HIGH_IMPEDANCE: the pin will be set to a high impedance
* mode, also know as "third-state" (tristate) or "high-Z" or "floating".
* On output pins this effectively disconnects the pin, which is useful
* if for example some other pin is going to drive the signal connected
* to it for a while. Pins used for input are usually always high
* impedance.
* @PIN_CONFIG_BIAS_PULL_UP: the pin will be pulled up (usually with high
* impedance to VDD). If the argument is != 0 pull-up is enabled,
* if it is 0, pull-up is disabled.
* @PIN_CONFIG_BIAS_PULL_DOWN: the pin will be pulled down (usually with high
* impedance to GROUND). If the argument is != 0 pull-down is enabled,
* if it is 0, pull-down is disabled.
* @PIN_CONFIG_DRIVE_PUSH_PULL: the pin will be driven actively high and
* low, this is the most typical case and is typically achieved with two
* active transistors on the output. Sending this config will enabale
* push-pull mode, the argument is ignored.
* @PIN_CONFIG_DRIVE_OPEN_DRAIN: the pin will be driven with open drain (open
* collector) which means it is usually wired with other output ports
* which are then pulled up with an external resistor. Sending this
* config will enabale open drain mode, the argument is ignored.
* @PIN_CONFIG_DRIVE_OPEN_SOURCE: the pin will be driven with open source
* (open emitter). Sending this config will enabale open drain mode, the
* argument is ignored.
* @PIN_CONFIG_INPUT_SCHMITT: this will configure an input pin to run in
* schmitt-trigger mode. If the schmitt-trigger has adjustable hysteresis,
* the threshold value is given on a custom format as argument when
* setting pins to this mode. The argument zero turns the schmitt trigger
* off.
* @PIN_CONFIG_INPUT_DEBOUNCE: this will configure the pin to debounce mode,
* which means it will wait for signals to settle when reading inputs. The
* argument gives the debounce time on a custom format. Setting the
* argument to zero turns debouncing off.
* @PIN_CONFIG_POWER_SOURCE: if the pin can select between different power
* supplies, the argument to this parameter (on a custom format) tells
* the driver which alternative power source to use.
* @PIN_CONFIG_LOW_POWER_MODE: this will configure the pin for low power
* operation, if several modes of operation are supported these can be
* passed in the argument on a custom form, else just use argument 1
* to indicate low power mode, argument 0 turns low power mode off.
* @PIN_CONFIG_END: this is the last enumerator for pin configurations, if
* you need to pass in custom configurations to the pin controller, use
* PIN_CONFIG_END+1 as the base offset.
*/
enum pin_config_param {
PIN_CONFIG_BIAS_DISABLE,
PIN_CONFIG_BIAS_HIGH_IMPEDANCE,
PIN_CONFIG_BIAS_PULL_UP,
PIN_CONFIG_BIAS_PULL_DOWN,
PIN_CONFIG_DRIVE_PUSH_PULL,
PIN_CONFIG_DRIVE_OPEN_DRAIN,
PIN_CONFIG_DRIVE_OPEN_SOURCE,
PIN_CONFIG_INPUT_SCHMITT,
PIN_CONFIG_INPUT_DEBOUNCE,
PIN_CONFIG_POWER_SOURCE,
PIN_CONFIG_LOW_POWER_MODE,
PIN_CONFIG_END = 0x7FFF,
};
/*
* Helpful configuration macro to be used in tables etc.
*/
#define PIN_CONF_PACKED(p, a) ((a << 16) | ((unsigned long) p & 0xffffUL))
/*
* The following inlines stuffs a configuration parameter and data value
* into and out of an unsigned long argument, as used by the generic pin config
* system. We put the parameter in the lower 16 bits and the argument in the
* upper 16 bits.
*/
static inline enum pin_config_param pinconf_to_config_param(unsigned long config)
{
return (enum pin_config_param) (config & 0xffffUL);
}
static inline u16 pinconf_to_config_argument(unsigned long config)
{
return (enum pin_config_param) ((config >> 16) & 0xffffUL);
}
static inline unsigned long pinconf_to_config_packed(enum pin_config_param param,
u16 argument)
{
return PIN_CONF_PACKED(param, argument);
}
#endif /* CONFIG_GENERIC_PINCONF */
#endif /* __LINUX_PINCTRL_PINCONF_GENERIC_H */
...@@ -20,6 +20,8 @@ struct seq_file; ...@@ -20,6 +20,8 @@ struct seq_file;
/** /**
* struct pinconf_ops - pin config operations, to be implemented by * struct pinconf_ops - pin config operations, to be implemented by
* pin configuration capable drivers. * pin configuration capable drivers.
* @is_generic: for pin controllers that want to use the generic interface,
* this flag tells the framework that it's generic.
* @pin_config_get: get the config of a certain pin, if the requested config * @pin_config_get: get the config of a certain pin, if the requested config
* is not available on this controller this should return -ENOTSUPP * is not available on this controller this should return -ENOTSUPP
* and if it is available but disabled it should return -EINVAL * and if it is available but disabled it should return -EINVAL
...@@ -33,6 +35,9 @@ struct seq_file; ...@@ -33,6 +35,9 @@ struct seq_file;
* per-device info for a certain group in debugfs * per-device info for a certain group in debugfs
*/ */
struct pinconf_ops { struct pinconf_ops {
#ifdef CONFIG_GENERIC_PINCONF
bool is_generic;
#endif
int (*pin_config_get) (struct pinctrl_dev *pctldev, int (*pin_config_get) (struct pinctrl_dev *pctldev,
unsigned pin, unsigned pin,
unsigned long *config); unsigned long *config);
...@@ -53,45 +58,6 @@ struct pinconf_ops { ...@@ -53,45 +58,6 @@ struct pinconf_ops {
unsigned selector); 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
#endif /* __LINUX_PINCTRL_PINCONF_H */ #endif /* __LINUX_PINCTRL_PINCONF_H */
/*
* Standard pin control state definitions
*/
#define PINCTRL_STATE_DEFAULT "default"
#define PINCTRL_STATE_IDLE "idle"
...@@ -15,10 +15,11 @@ ...@@ -15,10 +15,11 @@
#ifdef CONFIG_PINCTRL #ifdef CONFIG_PINCTRL
#include <linux/radix-tree.h> #include <linux/radix-tree.h>
#include <linux/spinlock.h>
#include <linux/list.h> #include <linux/list.h>
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include "pinctrl-state.h"
struct device;
struct pinctrl_dev; struct pinctrl_dev;
struct pinmux_ops; struct pinmux_ops;
struct pinconf_ops; struct pinconf_ops;
......
...@@ -16,9 +16,6 @@ ...@@ -16,9 +16,6 @@
#include <linux/seq_file.h> #include <linux/seq_file.h>
#include "pinctrl.h" #include "pinctrl.h"
/* This struct is private to the core and should be regarded as a cookie */
struct pinmux;
#ifdef CONFIG_PINMUX #ifdef CONFIG_PINMUX
struct pinctrl_dev; struct pinctrl_dev;
...@@ -88,55 +85,6 @@ struct pinmux_ops { ...@@ -88,55 +85,6 @@ struct pinmux_ops {
bool input); 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 /* CONFIG_PINMUX */
#endif /* __LINUX_PINCTRL_PINMUX_H */ #endif /* __LINUX_PINCTRL_PINMUX_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment