Pinctrl updates for v3.4:

- 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
 -----BEGIN PGP SIGNATURE-----
 Version: GnuPG v1.4.12 (GNU/Linux)
 
 iQIcBAABAgAGBQJPazYTAAoJEEEQszewGV1z09IQAIcsnFO5s7XfvfXhwNCliiKp
 myVMJdYcx8GSOg5Oif9uektcBi0gB2ppegxVYDxDq8FZqZQ4d3pYDZel3tDBGKJI
 9ZXemh1iIeXwLZBXSENxn0NZokAZVDiyBqi50zsINV+riFfyzL9Ai7o3YkEx9xBG
 nJ6S9wthzeF2qF8/NBvMYgCefZXIKJ8miwVrb9MusWUBfeAY7F8jVNlK9Asp9ruv
 XEC+WcrWRttB/8+5z3FkPPtEnJ+0Y2p6e6+hn8Cel0UWb4+WDijumO+hTyIiNYSc
 ryzFMqX18L8taaDhxQZ1kRDL5S7Qu7N3HYu+4wBvPI3D81MroS5frJbUwPcD8WsK
 Pw/NZtAwJhp4B9/LVOOoAyBoRTfeIwrbp+ou2zF5m70hpBD5D1mN/2xVBBQgjm9T
 oY9jNoJ2PhZP74fO4jdf4iMW1j5ZmzwxLXlpT3vGJeONIUg2hE0FJjzoeOjRsUtO
 iC0m7Q1AbJpIcjJlcK+gV/ZclaOWy4iDXDXFs4A3XA+ryf/ylDL5G+c/1Qu6CMyF
 4AhKs78Fg7agtVYX/QYuie9BbasRjipxiPc0t3/46Abs7WRzvpmBWWktFE4yy980
 93jLyog0VROHIOl974Fn0GrNJeNUTavc5DEd32zlc7AiAibOzyuRztwJ5GZbuZAN
 SE0VyQBIIdkaF51XV+IO
 =Gg7v
 -----END PGP SIGNATURE-----

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.
This commit is contained in:
Linus Torvalds 2012-03-22 20:25:50 -07:00
commit 7fc86a7908
35 changed files with 12981 additions and 1623 deletions

View File

@ -206,12 +206,21 @@ using a certain resistor value - pull up and pull down - so that the pin has a
stable value when nothing is driving the rail it is connected to, or when it's
unconnected.
For example, a platform may do this:
Pin configuration can be programmed either using the explicit APIs described
immediately below, or by adding configuration entries into the mapping table;
see section "Board/machine configuration" below.
For example, a platform may do the following to pull up a pin to VDD:
#include <linux/pinctrl/consumer.h>
ret = pin_config_set("foo-dev", "FOO_GPIO_PIN", PLATFORM_X_PULL_UP);
To pull up a pin to VDD. The pin configuration driver implements callbacks for
changing pin configuration in the pin controller ops like this:
The format and meaning of the configuration parameter, PLATFORM_X_PULL_UP
above, is entirely defined by the pin controller driver.
The pin configuration driver implements callbacks for changing pin
configuration in the pin controller ops like this:
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinconf.h>
@ -492,14 +501,10 @@ Definitions:
{"map-i2c0", i2c0, pinctrl0, fi2c0, gi2c0}
}
Every map must be assigned a symbolic name, pin controller and function.
The group is not compulsory - if it is omitted the first group presented by
the driver as applicable for the function will be selected, which is
useful for simple cases.
The device name is present in map entries tied to specific devices. Maps
without device names are referred to as SYSTEM pinmuxes, such as can be taken
by the machine implementation on boot and not tied to any specific device.
Every map must be assigned a state name, pin controller, device and
function. The group is not compulsory - if it is omitted the first group
presented by the driver as applicable for the function will be selected,
which is useful for simple cases.
It is possible to map several groups to the same combination of device,
pin controller and function. This is for cases where a certain function on
@ -726,19 +731,19 @@ same time.
All the above functions are mandatory to implement for a pinmux driver.
Pinmux interaction with the GPIO subsystem
==========================================
Pin control interaction with the GPIO subsystem
===============================================
The public pinmux API contains two functions named pinmux_request_gpio()
and pinmux_free_gpio(). These two functions shall *ONLY* be called from
The public pinmux API contains two functions named pinctrl_request_gpio()
and pinctrl_free_gpio(). These two functions shall *ONLY* be called from
gpiolib-based drivers as part of their gpio_request() and
gpio_free() semantics. Likewise the pinmux_gpio_direction_[input|output]
gpio_free() semantics. Likewise the pinctrl_gpio_direction_[input|output]
shall only be called from within respective gpio_direction_[input|output]
gpiolib implementation.
NOTE that platforms and individual drivers shall *NOT* request GPIO pins to be
muxed in. Instead, implement a proper gpiolib driver and have that driver
request proper muxing for its pins.
controlled e.g. muxed in. Instead, implement a proper gpiolib driver and have
that driver request proper muxing and other control for its pins.
The function list could become long, especially if you can convert every
individual pin into a GPIO pin independent of any other pins, and then try
@ -747,7 +752,7 @@ the approach to define every pin as a function.
In this case, the function array would become 64 entries for each GPIO
setting and then the device functions.
For this reason there are two functions a pinmux driver can implement
For this reason there are two functions a pin control driver can implement
to enable only GPIO on an individual pin: .gpio_request_enable() and
.gpio_disable_free().
@ -762,12 +767,12 @@ gpiolib driver and the affected GPIO range, pin offset and desired direction
will be passed along to this function.
Alternatively to using these special functions, it is fully allowed to use
named functions for each GPIO pin, the pinmux_request_gpio() will attempt to
named functions for each GPIO pin, the pinctrl_request_gpio() will attempt to
obtain the function "gpioN" where "N" is the global GPIO pin number if no
special GPIO-handler is registered.
Pinmux board/machine configuration
Board/machine configuration
==================================
Boards and machines define how a certain complete running system is put
@ -775,27 +780,33 @@ together, including how GPIOs and devices are muxed, how regulators are
constrained and how the clock tree looks. Of course pinmux settings are also
part of this.
A pinmux config for a machine looks pretty much like a simple regulator
configuration, so for the example array above we want to enable i2c and
spi on the second function mapping:
A pin controller configuration for a machine looks pretty much like a simple
regulator configuration, so for the example array above we want to enable i2c
and spi on the second function mapping:
#include <linux/pinctrl/machine.h>
static const struct pinmux_map __initdata pmx_mapping[] = {
static const struct pinctrl_map __initdata mapping[] = {
{
.ctrl_dev_name = "pinctrl-foo",
.function = "spi0",
.dev_name = "foo-spi.0",
.name = PINCTRL_STATE_DEFAULT,
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.data.mux.function = "spi0",
},
{
.ctrl_dev_name = "pinctrl-foo",
.function = "i2c0",
.dev_name = "foo-i2c.0",
.name = PINCTRL_STATE_DEFAULT,
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.data.mux.function = "i2c0",
},
{
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.dev_name = "foo-mmc.0",
.name = PINCTRL_STATE_DEFAULT,
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.data.mux.function = "mmc0",
},
};
@ -805,21 +816,51 @@ must match a function provided by the pinmux driver handling this pin range.
As you can see we may have several pin controllers on the system and thus
we need to specify which one of them that contain the functions we wish
to map. The map can also use struct device * directly, so there is no
inherent need to use strings to specify .dev_name or .ctrl_dev_name, these
are for the situation where you do not have a handle to the struct device *,
for example if they are not yet instantiated or cumbersome to obtain.
to map.
You register this pinmux mapping to the pinmux subsystem by simply:
ret = pinmux_register_mappings(pmx_mapping, ARRAY_SIZE(pmx_mapping));
ret = pinctrl_register_mappings(mapping, ARRAY_SIZE(mapping));
Since the above construct is pretty common there is a helper macro to make
it even more compact which assumes you want to use pinctrl-foo and position
0 for mapping, for example:
static struct pinmux_map __initdata pmx_mapping[] = {
PINMUX_MAP("I2CMAP", "pinctrl-foo", "i2c0", "foo-i2c.0"),
static struct pinctrl_map __initdata mapping[] = {
PIN_MAP_MUX_GROUP("foo-i2c.o", PINCTRL_STATE_DEFAULT, "pinctrl-foo", NULL, "i2c0"),
};
The mapping table may also contain pin configuration entries. It's common for
each pin/group to have a number of configuration entries that affect it, so
the table entries for configuration reference an array of config parameters
and values. An example using the convenience macros is shown below:
static unsigned long i2c_grp_configs[] = {
FOO_PIN_DRIVEN,
FOO_PIN_PULLUP,
};
static unsigned long i2c_pin_configs[] = {
FOO_OPEN_COLLECTOR,
FOO_SLEW_RATE_SLOW,
};
static struct pinctrl_map __initdata mapping[] = {
PIN_MAP_MUX_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", "i2c0"),
PIN_MAP_MUX_CONFIGS_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", i2c_grp_configs),
PIN_MAP_MUX_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0scl", i2c_pin_configs),
PIN_MAP_MUX_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0sda", i2c_pin_configs),
};
Finally, some devices expect the mapping table to contain certain specific
named states. When running on hardware that doesn't need any pin controller
configuration, the mapping table must still contain those named states, in
order to explicitly indicate that the states were provided and intended to
be empty. Table entry macro PIN_MAP_DUMMY_STATE serves the purpose of defining
a named state without causing any pin controller to be programmed:
static struct pinctrl_map __initdata mapping[] = {
PIN_MAP_DUMMY_STATE("foo-i2c.0", PINCTRL_STATE_DEFAULT),
};
@ -831,81 +872,96 @@ As it is possible to map a function to different groups of pins an optional
...
{
.dev_name = "foo-spi.0",
.name = "spi0-pos-A",
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "spi0",
.group = "spi0_0_grp",
.dev_name = "foo-spi.0",
},
{
.dev_name = "foo-spi.0",
.name = "spi0-pos-B",
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "spi0",
.group = "spi0_1_grp",
.dev_name = "foo-spi.0",
},
...
This example mapping is used to switch between two positions for spi0 at
runtime, as described further below under the heading "Runtime pinmuxing".
Further it is possible to match several groups of pins to the same function
for a single device, say for example in the mmc0 example above, where you can
Further it is possible for one named state to affect the muxing of several
groups of pins, say for example in the mmc0 example above, where you can
additively expand the mmc0 bus from 2 to 4 to 8 pins. If we want to use all
three groups for a total of 2+2+4 = 8 pins (for an 8-bit MMC bus as is the
case), we define a mapping like this:
...
{
.dev_name = "foo-mmc.0",
.name = "2bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_1_grp",
.dev_name = "foo-mmc.0",
},
{
.dev_name = "foo-mmc.0",
.name = "4bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_1_grp",
.dev_name = "foo-mmc.0",
},
{
.dev_name = "foo-mmc.0",
.name = "4bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_2_grp",
.dev_name = "foo-mmc.0",
},
{
.dev_name = "foo-mmc.0",
.name = "8bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_1_grp",
.dev_name = "foo-mmc.0",
},
{
.dev_name = "foo-mmc.0",
.name = "8bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_2_grp",
.dev_name = "foo-mmc.0",
},
{
.dev_name = "foo-mmc.0",
.name = "8bit"
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "mmc0",
.group = "mmc0_3_grp",
.dev_name = "foo-mmc.0",
},
...
The result of grabbing this mapping from the device with something like
this (see next paragraph):
pmx = pinmux_get(&device, "8bit");
p = pinctrl_get(dev);
s = pinctrl_lookup_state(p, "8bit");
ret = pinctrl_select_state(p, s);
or more simply:
p = pinctrl_get_select(dev, "8bit");
Will be that you activate all the three bottom records in the mapping at
once. Since they share the same name, pin controller device, funcion and
once. Since they share the same name, pin controller device, function and
device, and since we allow multiple groups to match to a single device, they
all get selected, and they all get enabled and disable simultaneously by the
pinmux core.
@ -914,97 +970,111 @@ pinmux core.
Pinmux requests from drivers
============================
Generally it is discouraged to let individual drivers get and enable pinmuxes.
So if possible, handle the pinmuxes in platform code or some other place where
you have access to all the affected struct device * pointers. In some cases
where a driver needs to switch between different mux mappings at runtime
this is not possible.
Generally it is discouraged to let individual drivers get and enable pin
control. So if possible, handle the pin control in platform code or some other
place where you have access to all the affected struct device * pointers. In
some cases where a driver needs to e.g. switch between different mux mappings
at runtime this is not possible.
A driver may request a certain mux to be activated, usually just the default
mux like this:
A driver may request a certain control state to be activated, usually just the
default state like this:
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/consumer.h>
struct foo_state {
struct pinmux *pmx;
struct pinctrl *p;
struct pinctrl_state *s;
...
};
foo_probe()
{
/* Allocate a state holder named "state" etc */
struct pinmux pmx;
/* Allocate a state holder named "foo" etc */
struct foo_state *foo = ...;
pmx = pinmux_get(&device, NULL);
if IS_ERR(pmx)
return PTR_ERR(pmx);
pinmux_enable(pmx);
foo->p = pinctrl_get(&device);
if (IS_ERR(foo->p)) {
/* FIXME: clean up "foo" here */
return PTR_ERR(foo->p);
}
state->pmx = pmx;
foo->s = pinctrl_lookup_state(foo->p, PINCTRL_STATE_DEFAULT);
if (IS_ERR(foo->s)) {
pinctrl_put(foo->p);
/* FIXME: clean up "foo" here */
return PTR_ERR(s);
}
ret = pinctrl_select_state(foo->s);
if (ret < 0) {
pinctrl_put(foo->p);
/* FIXME: clean up "foo" here */
return ret;
}
}
foo_remove()
{
pinmux_disable(state->pmx);
pinmux_put(state->pmx);
pinctrl_put(state->p);
}
If you want to grab a specific mux mapping and not just the first one found for
this device you can specify a specific mapping name, for example in the above
example the second i2c0 setting: pinmux_get(&device, "spi0-pos-B");
This get/enable/disable/put sequence can just as well be handled by bus drivers
This get/lookup/select/put sequence can just as well be handled by bus drivers
if you don't want each and every driver to handle it and you know the
arrangement on your bus.
The semantics of the get/enable respective disable/put is as follows:
The semantics of the pinctrl APIs are:
- pinmux_get() is called in process context to reserve the pins affected with
a certain mapping and set up the pinmux core and the driver. It will allocate
a struct from the kernel memory to hold the pinmux state.
- pinctrl_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_enable()/pinmux_disable() is quick and can be called from fastpath
(irq context) when you quickly want to set up/tear down the hardware muxing
when running a device driver. Usually it will just poke some values into a
register.
- pinctrl_lookup_state() is called in process context to obtain a handle to a
specific state for a the client device. This operation may be slow too.
- pinmux_disable() is called in process context to tear down the pin requests
and release the state holder struct for the mux setting.
- pinctrl_select_state() programs pin controller hardware according to the
definition of the state as given by the mapping table. In theory this is a
fast-path operation, since it only involved blasting some register settings
into hardware. However, note that some pin controllers may have their
registers on a slow/IRQ-based bus, so client devices should not assume they
can call pinctrl_select_state() from non-blocking contexts.
Usually the pinmux core handled the get/put pair and call out to the device
drivers bookkeeping operations, like checking available functions and the
associated pins, whereas the enable/disable pass on to the pin controller
- pinctrl_put() frees all information associated with a pinctrl handle.
Usually the pin control core handled the get/put pair and call out to the
device drivers bookkeeping operations, like checking available functions and
the associated pins, whereas the enable/disable pass on to the pin controller
driver which takes care of activating and/or deactivating the mux setting by
quickly poking some registers.
The pins are allocated for your device when you issue the pinmux_get() call,
The pins are allocated for your device when you issue the pinctrl_get() call,
after this you should be able to see this in the debugfs listing of all pins.
System pinmux hogging
=====================
System pin control hogging
==========================
A system pinmux map entry, i.e. a pinmux setting that does not have a device
associated with it, can be hogged by the core when the pin controller is
registered. This means that the core will attempt to call pinmux_get() and
pinmux_enable() on it immediately after the pin control device has been
registered.
Pin control map entries can be hogged by the core when the pin controller
is registered. This means that the core will attempt to call pinctrl_get(),
lookup_state() and select_state() on it immediately after the pin control
device has been registered.
This is enabled by simply setting the .hog_on_boot field in the map to true,
like this:
This occurs for mapping table entries where the client device name is equal
to the pin controller device name, and the state name is PINCTRL_STATE_DEFAULT.
{
.name = "POWERMAP"
.dev_name = "pinctrl-foo",
.name = PINCTRL_STATE_DEFAULT,
.type = PIN_MAP_TYPE_MUX_GROUP,
.ctrl_dev_name = "pinctrl-foo",
.function = "power_func",
.hog_on_boot = true,
},
Since it may be common to request the core to hog a few always-applicable
mux settings on the primary pin controller, there is a convenience macro for
this:
PINMUX_MAP_PRIMARY_SYS_HOG("POWERMAP", "power_func")
PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-foo", NULL /* group */, "power_func")
This gives the exact same result as the above construction.
@ -1016,32 +1086,47 @@ It is possible to mux a certain function in and out at runtime, say to move
an SPI port from one set of pins to another set of pins. Say for example for
spi0 in the example above, we expose two different groups of pins for the same
function, but with different named in the mapping as described under
"Advanced mapping" above. So we have two mappings named "spi0-pos-A" and
"spi0-pos-B".
"Advanced mapping" above. So that for an SPI device, we have two states named
"pos-A" and "pos-B".
This snippet first muxes the function in the pins defined by group A, enables
it, disables and releases it, and muxes it in on the pins defined by group B:
#include <linux/pinctrl/consumer.h>
foo_switch()
{
struct pinmux *pmx;
struct pinctrl *p;
struct pinctrl_state *s1, *s2;
/* Setup */
p = pinctrl_get(&device);
if (IS_ERR(p))
...
s1 = pinctrl_lookup_state(foo->p, "pos-A");
if (IS_ERR(s1))
...
s2 = pinctrl_lookup_state(foo->p, "pos-B");
if (IS_ERR(s2))
...
/* Enable on position A */
pmx = pinmux_get(&device, "spi0-pos-A");
if IS_ERR(pmx)
return PTR_ERR(pmx);
pinmux_enable(pmx);
ret = pinctrl_select_state(s1);
if (ret < 0)
...
/* This releases the pins again */
pinmux_disable(pmx);
pinmux_put(pmx);
...
/* Enable on position B */
pmx = pinmux_get(&device, "spi0-pos-B");
if IS_ERR(pmx)
return PTR_ERR(pmx);
pinmux_enable(pmx);
ret = pinctrl_select_state(s2);
if (ret < 0)
...
...
pinctrl_put(p);
}
The above has to be done from process context.

View File

@ -7,6 +7,8 @@ config ARCH_TEGRA_2x_SOC
select CPU_V7
select ARM_GIC
select ARCH_REQUIRE_GPIOLIB
select PINCTRL
select PINCTRL_TEGRA20
select USB_ARCH_HAS_EHCI if USB_SUPPORT
select USB_ULPI if USB_SUPPORT
select USB_ULPI_VIEWPORT if USB_SUPPORT
@ -19,6 +21,8 @@ config ARCH_TEGRA_3x_SOC
select CPU_V7
select ARM_GIC
select ARCH_REQUIRE_GPIOLIB
select PINCTRL
select PINCTRL_TEGRA30
select USB_ARCH_HAS_EHCI if USB_SUPPORT
select USB_ULPI if USB_SUPPORT
select USB_ULPI_VIEWPORT if USB_SUPPORT

View File

@ -0,0 +1,63 @@
/*
* 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

View File

@ -26,7 +26,8 @@
#include <linux/mtd/nand.h>
#include <linux/mtd/fsmc.h>
#include <linux/pinctrl/machine.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/consumer.h>
#include <linux/pinctrl/pinconf-generic.h>
#include <linux/dma-mapping.h>
#include <asm/types.h>
@ -1477,7 +1478,7 @@ static struct coh901318_platform coh901318_platform = {
.max_channels = U300_DMA_CHANNELS,
};
static struct resource pinmux_resources[] = {
static struct resource pinctrl_resources[] = {
{
.start = U300_SYSCON_BASE,
.end = U300_SYSCON_BASE + SZ_4K - 1,
@ -1506,6 +1507,13 @@ static struct platform_device i2c1_device = {
.resource = i2c1_resources,
};
static struct platform_device pinctrl_device = {
.name = "pinctrl-u300",
.id = -1,
.num_resources = ARRAY_SIZE(pinctrl_resources),
.resource = pinctrl_resources,
};
/*
* The different variants have a few different versions of the
* GPIO block, with different number of ports.
@ -1525,6 +1533,7 @@ static struct u300_gpio_platform u300_gpio_plat = {
#endif
.gpio_base = 0,
.gpio_irq_base = IRQ_U300_GPIO_BASE,
.pinctrl_device = &pinctrl_device,
};
static struct platform_device gpio_device = {
@ -1597,71 +1606,67 @@ static struct platform_device dma_device = {
},
};
static struct platform_device pinmux_device = {
.name = "pinmux-u300",
.id = -1,
.num_resources = ARRAY_SIZE(pinmux_resources),
.resource = pinmux_resources,
static unsigned long pin_pullup_conf[] = {
PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 1),
};
/* Pinmux settings */
static struct pinmux_map __initdata u300_pinmux_map[] = {
static unsigned long pin_highz_conf[] = {
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 */
PINMUX_MAP_SYS_HOG("POWER", "pinmux-u300", "power"),
PINMUX_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"),
PINMUX_MAP_SYS_HOG("EMIF1", "pinmux-u300", "emif1"),
PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "power"),
PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif0"),
PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "emif1"),
/* per-device maps for MMC/SD, SPI and UART */
PINMUX_MAP("MMCSD", "pinmux-u300", "mmc0", "mmci"),
PINMUX_MAP("SPI", "pinmux-u300", "spi0", "pl022"),
PINMUX_MAP("UART0", "pinmux-u300", "uart0", "uart0"),
PIN_MAP_MUX_GROUP_DEFAULT("mmci", "pinctrl-u300", NULL, "mmc0"),
PIN_MAP_MUX_GROUP_DEFAULT("pl022", "pinctrl-u300", NULL, "spi0"),
PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-u300", NULL, "uart0"),
/* 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 {
const char *name;
struct device *dev;
struct pinmux *pmx;
struct pinctrl *p;
};
static struct u300_mux_hog u300_mux_hogs[] = {
{
.name = "uart0",
.dev = &uart0_device.dev,
},
{
.name = "spi0",
.dev = &pl022_device.dev,
},
{
.name = "mmc0",
.dev = &mmcsd_device.dev,
},
};
static int __init u300_pinmux_fetch(void)
static int __init u300_pinctrl_fetch(void)
{
int i;
for (i = 0; i < ARRAY_SIZE(u300_mux_hogs); i++) {
struct pinmux *pmx;
int ret;
struct pinctrl *p;
pmx = pinmux_get(u300_mux_hogs[i].dev, NULL);
if (IS_ERR(pmx)) {
pr_err("u300: could not get pinmux hog %s\n",
u300_mux_hogs[i].name);
p = pinctrl_get_select_default(u300_mux_hogs[i].dev);
if (IS_ERR(p)) {
pr_err("u300: could not get pinmux hog for dev %s\n",
dev_name(u300_mux_hogs[i].dev));
continue;
}
ret = pinmux_enable(pmx);
if (ret) {
pr_err("u300: could enable pinmux hog %s\n",
u300_mux_hogs[i].name);
continue;
}
u300_mux_hogs[i].pmx = pmx;
u300_mux_hogs[i].p = p;
}
return 0;
}
subsys_initcall(u300_pinmux_fetch);
subsys_initcall(u300_pinctrl_fetch);
/*
* Notice that AMBA devices are initialized before platform devices.
@ -1676,7 +1681,6 @@ static struct platform_device *platform_devs[] __initdata = {
&gpio_device,
&nand_device,
&wdog_device,
&pinmux_device,
};
/*
@ -1861,8 +1865,8 @@ void __init u300_init_devices(void)
u300_assign_physmem();
/* Initialize pinmuxing */
pinmux_register_mappings(u300_pinmux_map,
ARRAY_SIZE(u300_pinmux_map));
pinctrl_register_mappings(u300_pinmux_map,
ARRAY_SIZE(u300_pinmux_map));
/* Register subdevices on the I2C buses */
u300_i2c_register_board_devices();

View File

@ -24,12 +24,14 @@ enum u300_gpio_variant {
* @ports: number of GPIO block ports
* @gpio_base: first GPIO number for this block (use a free range)
* @gpio_irq_base: first GPIO IRQ number for this block (use a free range)
* @pinctrl_device: pin control device to spawn as child
*/
struct u300_gpio_platform {
enum u300_gpio_variant variant;
u8 ports;
int gpio_base;
int gpio_irq_base;
struct platform_device *pinctrl_device;
};
#endif /* __MACH_U300_GPIO_U300_H */

View File

@ -17,21 +17,63 @@ config PINMUX
config PINCONF
bool "Support pin configuration controllers"
config GENERIC_PINCONF
bool
select PINCONF
config DEBUG_PINCTRL
bool "Debug PINCTRL calls"
depends on DEBUG_KERNEL
help
Say Y here to add some extra checks and diagnostics to PINCTRL calls.
config PINCTRL_PXA3xx
bool
select PINMUX
config PINCTRL_MMP2
bool "MMP2 pin controller driver"
depends on ARCH_MMP
select PINCTRL_PXA3xx
select PINCONF
config PINCTRL_PXA168
bool "PXA168 pin controller driver"
depends on ARCH_MMP
select PINCTRL_PXA3xx
select PINCONF
config PINCTRL_PXA910
bool "PXA910 pin controller driver"
depends on ARCH_MMP
select PINCTRL_PXA3xx
select PINCONF
config PINCTRL_SIRF
bool "CSR SiRFprimaII pin controller driver"
depends on ARCH_PRIMA2
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
bool "U300 pin controller driver"
depends on ARCH_U300
select PINMUX
select GENERIC_PINCONF
config PINCTRL_COH901
bool "ST-Ericsson U300 COH 901 335/571 GPIO"

View File

@ -5,6 +5,14 @@ ccflags-$(CONFIG_DEBUG_PINCTRL) += -DDEBUG
obj-$(CONFIG_PINCTRL) += core.o
obj-$(CONFIG_PINMUX) += pinmux.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_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_COH901) += pinctrl-coh901.o

File diff suppressed because it is too large Load Diff

View File

@ -9,7 +9,10 @@
* License terms: GNU General Public License (GPL) version 2
*/
#include <linux/mutex.h>
#include <linux/radix-tree.h>
#include <linux/pinctrl/pinconf.h>
#include <linux/pinctrl/machine.h>
struct pinctrl_gpio_range;
@ -20,34 +23,94 @@ struct pinctrl_gpio_range;
* controller
* @pin_desc_tree: each pin descriptor for this pin controller is stored in
* this radix tree
* @pin_desc_tree_lock: lock for the descriptor tree
* @gpio_ranges: a list of GPIO ranges that is handled by this pin controller,
* ranges are added to this list at runtime
* @gpio_ranges_lock: lock for the GPIO ranges list
* @dev: the device entry for this pin controller
* @owner: module providing the pin controller, used for refcounting
* @driver_data: driver data for drivers registering to the pin controller
* subsystem
* @pinmux_hogs_lock: lock for the pinmux hog list
* @pinmux_hogs: list of pinmux maps hogged by this device
* @p: result of pinctrl_get() for this device
* @device_root: debugfs root for this device
*/
struct pinctrl_dev {
struct list_head node;
struct pinctrl_desc *desc;
struct radix_tree_root pin_desc_tree;
spinlock_t pin_desc_tree_lock;
struct list_head gpio_ranges;
struct mutex gpio_ranges_lock;
struct device *dev;
struct module *owner;
void *driver_data;
struct pinctrl *p;
#ifdef CONFIG_DEBUG_FS
struct dentry *device_root;
#endif
#ifdef CONFIG_PINMUX
struct mutex pinmux_hogs_lock;
struct list_head pinmux_hogs;
#endif
};
/**
* struct pinctrl - per-device pin control state holder
* @node: global list node
* @dev: the device using this pin control handle
* @states: a list of states for this device
* @state: the current state
*/
struct pinctrl {
struct list_head node;
struct device *dev;
struct list_head states;
struct pinctrl_state *state;
};
/**
* struct pinctrl_state - a pinctrl state for a device
* @node: list not for struct pinctrl's @states field
* @name: the name of this state
* @settings: a list of settings for this state
*/
struct pinctrl_state {
struct list_head node;
const char *name;
struct list_head settings;
};
/**
* struct pinctrl_setting_mux - setting data for MAP_TYPE_MUX_GROUP
* @group: the group selector to program
* @func: the function selector to program
*/
struct pinctrl_setting_mux {
unsigned group;
unsigned func;
};
/**
* struct pinctrl_setting_configs - setting data for MAP_TYPE_CONFIGS_*
* @group_or_pin: the group selector or pin ID to program
* @configs: a pointer to an array of config parameters/values to program into
* hardware. Each individual pin controller defines the format and meaning
* of config parameters.
* @num_configs: the number of entries in array @configs
*/
struct pinctrl_setting_configs {
unsigned group_or_pin;
unsigned long *configs;
unsigned num_configs;
};
/**
* struct pinctrl_setting - an individual mux or config setting
* @node: list node for struct pinctrl_settings's @settings field
* @type: the type of setting
* @pctldev: pin control device handling to be programmed
* @data: Data specific to the setting type
*/
struct pinctrl_setting {
struct list_head node;
enum pinctrl_map_type type;
struct pinctrl_dev *pctldev;
union {
struct pinctrl_setting_mux mux;
struct pinctrl_setting_configs configs;
} data;
};
/**
@ -56,28 +119,38 @@ struct pinctrl_dev {
* @name: a name for the pin, e.g. the name of the pin/pad/finger on a
* datasheet or such
* @dynamic_name: if the name of this pin was dynamically allocated
* @lock: a lock to protect the descriptor structure
* @mux_requested: whether the pin is already requested by pinmux or not
* @mux_function: a named muxing function for the pin that will be passed to
* subdrivers and shown in debugfs etc
* @mux_usecount: If zero, the pin is not claimed, and @owner should be NULL.
* If non-zero, this pin is claimed by @owner. This field is an integer
* rather than a boolean, since pinctrl_get() might process multiple
* mapping table entries that refer to, and hence claim, the same group
* or pin, and each of these will increment the @usecount.
* @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 pinctrl_dev *pctldev;
const char *name;
bool dynamic_name;
spinlock_t lock;
/* These fields only added when supporting pinmux drivers */
#ifdef CONFIG_PINMUX
const char *mux_function;
unsigned mux_usecount;
const char *mux_owner;
const struct pinctrl_setting_mux *mux_setting;
const char *gpio_owner;
#endif
};
struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev,
const char *dev_name);
struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin);
struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name);
int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name);
int pinctrl_get_device_gpio_range(unsigned gpio,
struct pinctrl_dev **outdev,
struct pinctrl_gpio_range **outrange);
int pinctrl_get_group_selector(struct pinctrl_dev *pctldev,
const char *pin_group);
static inline struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev,
unsigned int pin)
{
return radix_tree_lookup(&pctldev->pin_desc_tree, pin);
}
extern struct mutex pinctrl_mutex;

View File

@ -0,0 +1,120 @@
/*
* 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

View File

@ -23,6 +23,37 @@
#include "core.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,
unsigned long *config)
{
@ -51,19 +82,27 @@ int pin_config_get(const char *dev_name, const char *name,
struct pinctrl_dev *pctldev;
int pin;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
if (!pctldev)
return -EINVAL;
mutex_lock(&pinctrl_mutex);
pctldev = get_pinctrl_dev_from_devname(dev_name);
if (!pctldev) {
pin = -EINVAL;
goto unlock;
}
pin = pin_get_from_name(pctldev, name);
if (pin < 0)
return pin;
goto unlock;
return pin_config_get_for_pin(pctldev, pin, config);
pin = pin_config_get_for_pin(pctldev, pin, config);
unlock:
mutex_unlock(&pinctrl_mutex);
return pin;
}
EXPORT_SYMBOL(pin_config_get);
int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
static int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long config)
{
const struct pinconf_ops *ops = pctldev->desc->confops;
@ -97,17 +136,27 @@ int pin_config_set(const char *dev_name, const char *name,
unsigned long config)
{
struct pinctrl_dev *pctldev;
int pin;
int pin, ret;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
if (!pctldev)
return -EINVAL;
mutex_lock(&pinctrl_mutex);
pctldev = get_pinctrl_dev_from_devname(dev_name);
if (!pctldev) {
ret = -EINVAL;
goto unlock;
}
pin = pin_get_from_name(pctldev, name);
if (pin < 0)
return pin;
if (pin < 0) {
ret = pin;
goto unlock;
}
return pin_config_set_for_pin(pctldev, pin, config);
ret = pin_config_set_for_pin(pctldev, pin, config);
unlock:
mutex_unlock(&pinctrl_mutex);
return ret;
}
EXPORT_SYMBOL(pin_config_set);
@ -116,29 +165,39 @@ int pin_config_group_get(const char *dev_name, const char *pin_group,
{
struct pinctrl_dev *pctldev;
const struct pinconf_ops *ops;
int selector;
int selector, ret;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
if (!pctldev)
return -EINVAL;
mutex_lock(&pinctrl_mutex);
pctldev = get_pinctrl_dev_from_devname(dev_name);
if (!pctldev) {
ret = -EINVAL;
goto unlock;
}
ops = pctldev->desc->confops;
if (!ops || !ops->pin_config_group_get) {
dev_err(pctldev->dev, "cannot get configuration for pin "
"group, missing group config get function in "
"driver\n");
return -EINVAL;
ret = -EINVAL;
goto unlock;
}
selector = pinctrl_get_group_selector(pctldev, pin_group);
if (selector < 0)
return selector;
if (selector < 0) {
ret = selector;
goto unlock;
}
return ops->pin_config_group_get(pctldev, selector, config);
ret = ops->pin_config_group_get(pctldev, selector, config);
unlock:
mutex_unlock(&pinctrl_mutex);
return ret;
}
EXPORT_SYMBOL(pin_config_group_get);
int pin_config_group_set(const char *dev_name, const char *pin_group,
unsigned long config)
{
@ -151,27 +210,34 @@ int pin_config_group_set(const char *dev_name, const char *pin_group,
int ret;
int i;
pctldev = get_pinctrl_dev_from_dev(NULL, dev_name);
if (!pctldev)
return -EINVAL;
mutex_lock(&pinctrl_mutex);
pctldev = get_pinctrl_dev_from_devname(dev_name);
if (!pctldev) {
ret = -EINVAL;
goto unlock;
}
ops = pctldev->desc->confops;
pctlops = pctldev->desc->pctlops;
if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) {
dev_err(pctldev->dev, "cannot configure pin group, missing "
"config function in driver\n");
return -EINVAL;
ret = -EINVAL;
goto unlock;
}
selector = pinctrl_get_group_selector(pctldev, pin_group);
if (selector < 0)
return selector;
if (selector < 0) {
ret = selector;
goto unlock;
}
ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins);
if (ret) {
dev_err(pctldev->dev, "cannot configure pin group, error "
"getting pins\n");
return ret;
goto unlock;
}
/*
@ -185,46 +251,196 @@ int pin_config_group_set(const char *dev_name, const char *pin_group,
* pin-by-pin as well, it returns -EAGAIN.
*/
if (ret != -EAGAIN)
return ret;
goto unlock;
}
/*
* If the controller cannot handle entire groups, we configure each pin
* individually.
*/
if (!ops->pin_config_set)
return 0;
if (!ops->pin_config_set) {
ret = 0;
goto unlock;
}
for (i = 0; i < num_pins; i++) {
ret = ops->pin_config_set(pctldev, pins[i], config);
if (ret < 0)
return ret;
goto unlock;
}
ret = 0;
unlock:
mutex_unlock(&pinctrl_mutex);
return ret;
}
EXPORT_SYMBOL(pin_config_group_set);
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;
int i, ret;
if (!ops) {
dev_err(pctldev->dev, "missing confops\n");
return -EINVAL;
}
switch (setting->type) {
case PIN_MAP_TYPE_CONFIGS_PIN:
if (!ops->pin_config_set) {
dev_err(pctldev->dev, "missing pin_config_set op\n");
return -EINVAL;
}
for (i = 0; i < setting->data.configs.num_configs; i++) {
ret = ops->pin_config_set(pctldev,
setting->data.configs.group_or_pin,
setting->data.configs.configs[i]);
if (ret < 0) {
dev_err(pctldev->dev,
"pin_config_set op failed for pin %d config %08lx\n",
setting->data.configs.group_or_pin,
setting->data.configs.configs[i]);
return ret;
}
}
break;
case PIN_MAP_TYPE_CONFIGS_GROUP:
if (!ops->pin_config_group_set) {
dev_err(pctldev->dev,
"missing pin_config_group_set op\n");
return -EINVAL;
}
for (i = 0; i < setting->data.configs.num_configs; i++) {
ret = ops->pin_config_group_set(pctldev,
setting->data.configs.group_or_pin,
setting->data.configs.configs[i]);
if (ret < 0) {
dev_err(pctldev->dev,
"pin_config_group_set op failed for group %d config %08lx\n",
setting->data.configs.group_or_pin,
setting->data.configs.configs[i]);
return ret;
}
}
break;
default:
return -EINVAL;
}
return 0;
}
EXPORT_SYMBOL(pin_config_group_set);
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;
}
#ifdef CONFIG_DEBUG_FS
void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map)
{
int i;
switch (map->type) {
case PIN_MAP_TYPE_CONFIGS_PIN:
seq_printf(s, "pin ");
break;
case PIN_MAP_TYPE_CONFIGS_GROUP:
seq_printf(s, "group ");
break;
default:
break;
}
seq_printf(s, "%s\n", map->data.configs.group_or_pin);
for (i = 0; i < map->data.configs.num_configs; i++)
seq_printf(s, "config %08lx\n", map->data.configs.configs[i]);
}
void pinconf_show_setting(struct seq_file *s,
struct pinctrl_setting const *setting)
{
struct pinctrl_dev *pctldev = setting->pctldev;
const struct pinctrl_ops *pctlops = pctldev->desc->pctlops;
struct pin_desc *desc;
int i;
switch (setting->type) {
case PIN_MAP_TYPE_CONFIGS_PIN:
desc = pin_desc_get(setting->pctldev,
setting->data.configs.group_or_pin);
seq_printf(s, "pin %s (%d)",
desc->name ? desc->name : "unnamed",
setting->data.configs.group_or_pin);
break;
case PIN_MAP_TYPE_CONFIGS_GROUP:
seq_printf(s, "group %s (%d)",
pctlops->get_group_name(pctldev,
setting->data.configs.group_or_pin),
setting->data.configs.group_or_pin);
break;
default:
break;
}
/*
* FIXME: We should really get the pin controler to dump the config
* values, so they can be decoded to something meaningful.
*/
for (i = 0; i < setting->data.configs.num_configs; i++)
seq_printf(s, " %08lx", setting->data.configs.configs[i]);
seq_printf(s, "\n");
}
static void pinconf_dump_pin(struct pinctrl_dev *pctldev,
struct seq_file *s, int pin)
{
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)
ops->pin_config_dbg_show(pctldev, s, pin);
}
@ -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, "Format: pin (name): pinmux setting array\n");
mutex_lock(&pinctrl_mutex);
/* The pin number can be retrived from the pin controller descriptor */
for (i = 0; i < pctldev->desc->npins; i++) {
struct pin_desc *desc;
@ -255,6 +473,8 @@ static int pinconf_pins_show(struct seq_file *s, void *what)
seq_printf(s, "\n");
}
mutex_unlock(&pinctrl_mutex);
return 0;
}
@ -264,6 +484,8 @@ static void pinconf_dump_group(struct pinctrl_dev *pctldev,
{
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)
ops->pin_config_group_dbg_show(pctldev, s, selector);
}
@ -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, "Format: group (name): pinmux setting array\n");
mutex_lock(&pinctrl_mutex);
while (pctlops->list_groups(pctldev, selector) >= 0) {
const char *gname = pctlops->get_group_name(pctldev, selector);
seq_printf(s, "%u (%s):", selector, gname);
pinconf_dump_group(pctldev, s, selector, gname);
seq_printf(s, "\n");
selector++;
}
mutex_unlock(&pinctrl_mutex);
return 0;
}

View File

@ -14,12 +14,25 @@
#ifdef CONFIG_PINCONF
int pinconf_check_ops(struct pinctrl_dev *pctldev);
int pinconf_validate_map(struct pinctrl_map const *map, int i);
int pinconf_map_to_setting(struct pinctrl_map const *map,
struct pinctrl_setting *setting);
void pinconf_free_setting(struct pinctrl_setting const *setting);
int pinconf_apply_setting(struct pinctrl_setting const *setting);
void pinconf_show_map(struct seq_file *s, struct pinctrl_map const *map);
void pinconf_show_setting(struct seq_file *s,
struct pinctrl_setting const *setting);
void pinconf_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev);
/*
* 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,
unsigned long *config);
int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin,
unsigned long config);
int pin_config_group_get(const char *dev_name, const char *pin_group,
unsigned long *config);
#else
@ -28,9 +41,70 @@ static inline int pinconf_check_ops(struct pinctrl_dev *pctldev)
return 0;
}
static inline int pinconf_validate_map(struct pinctrl_map const *map, int i)
{
return 0;
}
static inline int pinconf_map_to_setting(struct pinctrl_map const *map,
struct pinctrl_setting *setting)
{
return 0;
}
static inline void pinconf_free_setting(struct pinctrl_setting const *setting)
{
}
static inline int pinconf_apply_setting(struct pinctrl_setting const *setting)
{
return 0;
}
static inline void pinconf_show_map(struct seq_file *s,
struct pinctrl_map const *map)
{
}
static inline void pinconf_show_setting(struct seq_file *s,
struct pinctrl_setting const *setting)
{
}
static inline void pinconf_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev)
{
}
#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

View File

@ -22,38 +22,10 @@
#include <linux/gpio.h>
#include <linux/list.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>
/*
* 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
#include "pinctrl-coh901.h"
/*
* Register definitions for COH 901 335 variant
@ -181,12 +153,12 @@ struct u300_gpio_confdata {
#define BS365_GPIO_NUM_PORTS 5
#define U300_FLOATING_INPUT { \
.bias_mode = GPIO_U300_CONFIG_BIAS_FLOAT, \
.bias_mode = PIN_CONFIG_BIAS_HIGH_IMPEDANCE, \
.output = false, \
}
#define U300_PULL_UP_INPUT { \
.bias_mode = GPIO_U300_CONFIG_BIAS_PULL_UP, \
.bias_mode = PIN_CONFIG_BIAS_PULL_UP, \
.output = false, \
}
@ -360,14 +332,14 @@ static int u300_gpio_request(struct gpio_chip *chip, unsigned offset)
*/
int gpio = chip->base + offset;
return pinmux_request_gpio(gpio);
return pinctrl_request_gpio(gpio);
}
static void u300_gpio_free(struct gpio_chip *chip, unsigned offset)
{
int gpio = chip->base + offset;
pinmux_free_gpio(gpio);
pinctrl_free_gpio(gpio);
}
static int u300_gpio_get(struct gpio_chip *chip, unsigned offset)
@ -448,8 +420,68 @@ static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
return retirq;
}
static int u300_gpio_config(struct gpio_chip *chip, unsigned offset,
u16 param, unsigned long *data)
/* Returning -EINVAL means "supported but not available" */
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);
unsigned long flags;
@ -457,16 +489,16 @@ static int u300_gpio_config(struct gpio_chip *chip, unsigned offset,
local_irq_save(flags);
switch (param) {
case GPIO_U300_CONFIG_BIAS_UNKNOWN:
case GPIO_U300_CONFIG_BIAS_FLOAT:
case PIN_CONFIG_BIAS_DISABLE:
case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
val = readl(U300_PIN_REG(offset, per));
writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, per));
break;
case GPIO_U300_CONFIG_BIAS_PULL_UP:
case PIN_CONFIG_BIAS_PULL_UP:
val = readl(U300_PIN_REG(offset, per));
writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, per));
break;
case GPIO_U300_CONFIG_DRIVE_PUSH_PULL:
case PIN_CONFIG_DRIVE_PUSH_PULL:
val = readl(U300_PIN_REG(offset, pcr));
val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK
<< ((offset & 0x07) << 1));
@ -474,7 +506,7 @@ static int u300_gpio_config(struct gpio_chip *chip, unsigned offset,
<< ((offset & 0x07) << 1));
writel(val, U300_PIN_REG(offset, pcr));
break;
case GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN:
case PIN_CONFIG_DRIVE_OPEN_DRAIN:
val = readl(U300_PIN_REG(offset, pcr));
val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK
<< ((offset & 0x07) << 1));
@ -482,7 +514,7 @@ static int u300_gpio_config(struct gpio_chip *chip, unsigned offset,
<< ((offset & 0x07) << 1));
writel(val, U300_PIN_REG(offset, pcr));
break;
case GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE:
case PIN_CONFIG_DRIVE_OPEN_SOURCE:
val = readl(U300_PIN_REG(offset, pcr));
val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK
<< ((offset & 0x07) << 1));
@ -650,13 +682,12 @@ static void __init u300_gpio_init_pin(struct u300_gpio *gpio,
u300_gpio_direction_output(&gpio->chip, offset, conf->outval);
/* Deactivate bias mode for output */
u300_gpio_config(&gpio->chip, offset,
GPIO_U300_CONFIG_BIAS_FLOAT,
NULL);
u300_gpio_config_set(&gpio->chip, offset,
PIN_CONFIG_BIAS_HIGH_IMPEDANCE);
/* Set drive mode for output */
u300_gpio_config(&gpio->chip, offset,
GPIO_U300_CONFIG_DRIVE_PUSH_PULL, NULL);
u300_gpio_config_set(&gpio->chip, offset,
PIN_CONFIG_DRIVE_PUSH_PULL);
dev_dbg(gpio->dev, "set up pin %d as output, value: %d\n",
offset, conf->outval);
@ -667,7 +698,7 @@ static void __init u300_gpio_init_pin(struct u300_gpio *gpio,
u300_gpio_set(&gpio->chip, offset, 0);
/* 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",
offset, conf->bias_mode);
@ -705,7 +736,6 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio)
list_for_each_safe(p, n, &gpio->port_list) {
port = list_entry(p, struct u300_gpio_port, node);
list_del(&port->node);
free_irq(port->irq, port);
kfree(port);
}
}
@ -861,10 +891,18 @@ static int __init u300_gpio_probe(struct platform_device *pdev)
goto err_no_chip;
}
/* Spawn pin controller device as child of the GPIO, pass gpio chip */
plat->pinctrl_device->dev.platform_data = &gpio->chip;
err = platform_device_register(plat->pinctrl_device);
if (err)
goto err_no_pinctrl;
platform_set_drvdata(pdev, gpio);
return 0;
err_no_pinctrl:
err = gpiochip_remove(&gpio->chip);
err_no_chip:
err_no_port:
u300_gpio_free_ports(gpio);
@ -919,7 +957,6 @@ static struct platform_driver u300_gpio_driver = {
.remove = __exit_p(u300_gpio_remove),
};
static int __init u300_gpio_init(void)
{
return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe);

View File

@ -0,0 +1,5 @@
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);

View File

@ -0,0 +1,722 @@
/*
* linux/drivers/pinctrl/pinmux-mmp2.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* publishhed by the Free Software Foundation.
*
* Copyright (C) 2011, Marvell Technology Group Ltd.
*
* Author: Haojian Zhuang <haojian.zhuang@marvell.com>
*
*/
#include <linux/device.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include "pinctrl-pxa3xx.h"
#define MMP2_DS_MASK 0x1800
#define MMP2_DS_SHIFT 11
#define MMP2_SLEEP_MASK 0x38
#define MMP2_SLEEP_SELECT (1 << 9)
#define MMP2_SLEEP_DATA (1 << 8)
#define MMP2_SLEEP_DIR (1 << 7)
#define MFPR_MMP2(a, r, f0, f1, f2, f3, f4, f5, f6, f7) \
{ \
.name = #a, \
.pin = a, \
.mfpr = r, \
.func = { \
MMP2_MUX_##f0, \
MMP2_MUX_##f1, \
MMP2_MUX_##f2, \
MMP2_MUX_##f3, \
MMP2_MUX_##f4, \
MMP2_MUX_##f5, \
MMP2_MUX_##f6, \
MMP2_MUX_##f7, \
}, \
}
#define GRP_MMP2(a, m, p) \
{ .name = a, .mux = MMP2_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), }
/* 174 pins */
enum mmp2_pin_list {
/* 0~168: GPIO0~GPIO168 */
TWSI4_SCL = 169,
TWSI4_SDA, /* 170 */
G_CLKREQ,
VCXO_REQ,
VCXO_OUT,
};
enum mmp2_mux {
/* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */
MMP2_MUX_GPIO = 0,
MMP2_MUX_G_CLKREQ,
MMP2_MUX_VCXO_REQ,
MMP2_MUX_VCXO_OUT,
MMP2_MUX_KP_MK,
MMP2_MUX_KP_DK,
MMP2_MUX_CCIC1,
MMP2_MUX_CCIC2,
MMP2_MUX_SPI,
MMP2_MUX_SSPA2,
MMP2_MUX_ROT,
MMP2_MUX_I2S,
MMP2_MUX_TB,
MMP2_MUX_CAM2,
MMP2_MUX_HDMI,
MMP2_MUX_TWSI2,
MMP2_MUX_TWSI3,
MMP2_MUX_TWSI4,
MMP2_MUX_TWSI5,
MMP2_MUX_TWSI6,
MMP2_MUX_UART1,
MMP2_MUX_UART2,
MMP2_MUX_UART3,
MMP2_MUX_UART4,
MMP2_MUX_SSP1_RX,
MMP2_MUX_SSP1_FRM,
MMP2_MUX_SSP1_TXRX,
MMP2_MUX_SSP2_RX,
MMP2_MUX_SSP2_FRM,
MMP2_MUX_SSP1,
MMP2_MUX_SSP2,
MMP2_MUX_SSP3,
MMP2_MUX_SSP4,
MMP2_MUX_MMC1,
MMP2_MUX_MMC2,
MMP2_MUX_MMC3,
MMP2_MUX_MMC4,
MMP2_MUX_ULPI,
MMP2_MUX_AC,
MMP2_MUX_CA,
MMP2_MUX_PWM,
MMP2_MUX_USIM,
MMP2_MUX_TIPU,
MMP2_MUX_PLL,
MMP2_MUX_NAND,
MMP2_MUX_FSIC,
MMP2_MUX_SLEEP_IND,
MMP2_MUX_EXT_DMA,
MMP2_MUX_ONE_WIRE,
MMP2_MUX_LCD,
MMP2_MUX_SMC,
MMP2_MUX_SMC_INT,
MMP2_MUX_MSP,
MMP2_MUX_G_CLKOUT,
MMP2_MUX_32K_CLKOUT,
MMP2_MUX_PRI_JTAG,
MMP2_MUX_AAS_JTAG,
MMP2_MUX_AAS_GPIO,
MMP2_MUX_AAS_SPI,
MMP2_MUX_AAS_TWSI,
MMP2_MUX_AAS_DEU_EX,
MMP2_MUX_NONE = 0xffff,
};
static struct pinctrl_pin_desc mmp2_pads[] = {
/*
* The name indicates function 0 of this pin.
* After reset, function 0 is the default function of pin.
*/
PINCTRL_PIN(GPIO0, "GPIO0"),
PINCTRL_PIN(GPIO1, "GPIO1"),
PINCTRL_PIN(GPIO2, "GPIO2"),
PINCTRL_PIN(GPIO3, "GPIO3"),
PINCTRL_PIN(GPIO4, "GPIO4"),
PINCTRL_PIN(GPIO5, "GPIO5"),
PINCTRL_PIN(GPIO6, "GPIO6"),
PINCTRL_PIN(GPIO7, "GPIO7"),
PINCTRL_PIN(GPIO8, "GPIO8"),
PINCTRL_PIN(GPIO9, "GPIO9"),
PINCTRL_PIN(GPIO10, "GPIO10"),
PINCTRL_PIN(GPIO11, "GPIO11"),
PINCTRL_PIN(GPIO12, "GPIO12"),
PINCTRL_PIN(GPIO13, "GPIO13"),
PINCTRL_PIN(GPIO14, "GPIO14"),
PINCTRL_PIN(GPIO15, "GPIO15"),
PINCTRL_PIN(GPIO16, "GPIO16"),
PINCTRL_PIN(GPIO17, "GPIO17"),
PINCTRL_PIN(GPIO18, "GPIO18"),
PINCTRL_PIN(GPIO19, "GPIO19"),
PINCTRL_PIN(GPIO20, "GPIO20"),
PINCTRL_PIN(GPIO21, "GPIO21"),
PINCTRL_PIN(GPIO22, "GPIO22"),
PINCTRL_PIN(GPIO23, "GPIO23"),
PINCTRL_PIN(GPIO24, "GPIO24"),
PINCTRL_PIN(GPIO25, "GPIO25"),
PINCTRL_PIN(GPIO26, "GPIO26"),
PINCTRL_PIN(GPIO27, "GPIO27"),
PINCTRL_PIN(GPIO28, "GPIO28"),
PINCTRL_PIN(GPIO29, "GPIO29"),
PINCTRL_PIN(GPIO30, "GPIO30"),
PINCTRL_PIN(GPIO31, "GPIO31"),
PINCTRL_PIN(GPIO32, "GPIO32"),
PINCTRL_PIN(GPIO33, "GPIO33"),
PINCTRL_PIN(GPIO34, "GPIO34"),
PINCTRL_PIN(GPIO35, "GPIO35"),
PINCTRL_PIN(GPIO36, "GPIO36"),
PINCTRL_PIN(GPIO37, "GPIO37"),
PINCTRL_PIN(GPIO38, "GPIO38"),
PINCTRL_PIN(GPIO39, "GPIO39"),
PINCTRL_PIN(GPIO40, "GPIO40"),
PINCTRL_PIN(GPIO41, "GPIO41"),
PINCTRL_PIN(GPIO42, "GPIO42"),
PINCTRL_PIN(GPIO43, "GPIO43"),
PINCTRL_PIN(GPIO44, "GPIO44"),
PINCTRL_PIN(GPIO45, "GPIO45"),
PINCTRL_PIN(GPIO46, "GPIO46"),
PINCTRL_PIN(GPIO47, "GPIO47"),
PINCTRL_PIN(GPIO48, "GPIO48"),
PINCTRL_PIN(GPIO49, "GPIO49"),
PINCTRL_PIN(GPIO50, "GPIO50"),
PINCTRL_PIN(GPIO51, "GPIO51"),
PINCTRL_PIN(GPIO52, "GPIO52"),
PINCTRL_PIN(GPIO53, "GPIO53"),
PINCTRL_PIN(GPIO54, "GPIO54"),
PINCTRL_PIN(GPIO55, "GPIO55"),
PINCTRL_PIN(GPIO56, "GPIO56"),
PINCTRL_PIN(GPIO57, "GPIO57"),
PINCTRL_PIN(GPIO58, "GPIO58"),
PINCTRL_PIN(GPIO59, "GPIO59"),
PINCTRL_PIN(GPIO60, "GPIO60"),
PINCTRL_PIN(GPIO61, "GPIO61"),
PINCTRL_PIN(GPIO62, "GPIO62"),
PINCTRL_PIN(GPIO63, "GPIO63"),
PINCTRL_PIN(GPIO64, "GPIO64"),
PINCTRL_PIN(GPIO65, "GPIO65"),
PINCTRL_PIN(GPIO66, "GPIO66"),
PINCTRL_PIN(GPIO67, "GPIO67"),
PINCTRL_PIN(GPIO68, "GPIO68"),
PINCTRL_PIN(GPIO69, "GPIO69"),
PINCTRL_PIN(GPIO70, "GPIO70"),
PINCTRL_PIN(GPIO71, "GPIO71"),
PINCTRL_PIN(GPIO72, "GPIO72"),
PINCTRL_PIN(GPIO73, "GPIO73"),
PINCTRL_PIN(GPIO74, "GPIO74"),
PINCTRL_PIN(GPIO75, "GPIO75"),
PINCTRL_PIN(GPIO76, "GPIO76"),
PINCTRL_PIN(GPIO77, "GPIO77"),
PINCTRL_PIN(GPIO78, "GPIO78"),
PINCTRL_PIN(GPIO79, "GPIO79"),
PINCTRL_PIN(GPIO80, "GPIO80"),
PINCTRL_PIN(GPIO81, "GPIO81"),
PINCTRL_PIN(GPIO82, "GPIO82"),
PINCTRL_PIN(GPIO83, "GPIO83"),
PINCTRL_PIN(GPIO84, "GPIO84"),
PINCTRL_PIN(GPIO85, "GPIO85"),
PINCTRL_PIN(GPIO86, "GPIO86"),
PINCTRL_PIN(GPIO87, "GPIO87"),
PINCTRL_PIN(GPIO88, "GPIO88"),
PINCTRL_PIN(GPIO89, "GPIO89"),
PINCTRL_PIN(GPIO90, "GPIO90"),
PINCTRL_PIN(GPIO91, "GPIO91"),
PINCTRL_PIN(GPIO92, "GPIO92"),
PINCTRL_PIN(GPIO93, "GPIO93"),
PINCTRL_PIN(GPIO94, "GPIO94"),
PINCTRL_PIN(GPIO95, "GPIO95"),
PINCTRL_PIN(GPIO96, "GPIO96"),
PINCTRL_PIN(GPIO97, "GPIO97"),
PINCTRL_PIN(GPIO98, "GPIO98"),
PINCTRL_PIN(GPIO99, "GPIO99"),
PINCTRL_PIN(GPIO100, "GPIO100"),
PINCTRL_PIN(GPIO101, "GPIO101"),
PINCTRL_PIN(GPIO102, "GPIO102"),
PINCTRL_PIN(GPIO103, "GPIO103"),
PINCTRL_PIN(GPIO104, "GPIO104"),
PINCTRL_PIN(GPIO105, "GPIO105"),
PINCTRL_PIN(GPIO106, "GPIO106"),
PINCTRL_PIN(GPIO107, "GPIO107"),
PINCTRL_PIN(GPIO108, "GPIO108"),
PINCTRL_PIN(GPIO109, "GPIO109"),
PINCTRL_PIN(GPIO110, "GPIO110"),
PINCTRL_PIN(GPIO111, "GPIO111"),
PINCTRL_PIN(GPIO112, "GPIO112"),
PINCTRL_PIN(GPIO113, "GPIO113"),
PINCTRL_PIN(GPIO114, "GPIO114"),
PINCTRL_PIN(GPIO115, "GPIO115"),
PINCTRL_PIN(GPIO116, "GPIO116"),
PINCTRL_PIN(GPIO117, "GPIO117"),
PINCTRL_PIN(GPIO118, "GPIO118"),
PINCTRL_PIN(GPIO119, "GPIO119"),
PINCTRL_PIN(GPIO120, "GPIO120"),
PINCTRL_PIN(GPIO121, "GPIO121"),
PINCTRL_PIN(GPIO122, "GPIO122"),
PINCTRL_PIN(GPIO123, "GPIO123"),
PINCTRL_PIN(GPIO124, "GPIO124"),
PINCTRL_PIN(GPIO125, "GPIO125"),
PINCTRL_PIN(GPIO126, "GPIO126"),
PINCTRL_PIN(GPIO127, "GPIO127"),
PINCTRL_PIN(GPIO128, "GPIO128"),
PINCTRL_PIN(GPIO129, "GPIO129"),
PINCTRL_PIN(GPIO130, "GPIO130"),
PINCTRL_PIN(GPIO131, "GPIO131"),
PINCTRL_PIN(GPIO132, "GPIO132"),
PINCTRL_PIN(GPIO133, "GPIO133"),
PINCTRL_PIN(GPIO134, "GPIO134"),
PINCTRL_PIN(GPIO135, "GPIO135"),
PINCTRL_PIN(GPIO136, "GPIO136"),
PINCTRL_PIN(GPIO137, "GPIO137"),
PINCTRL_PIN(GPIO138, "GPIO138"),
PINCTRL_PIN(GPIO139, "GPIO139"),
PINCTRL_PIN(GPIO140, "GPIO140"),
PINCTRL_PIN(GPIO141, "GPIO141"),
PINCTRL_PIN(GPIO142, "GPIO142"),
PINCTRL_PIN(GPIO143, "GPIO143"),
PINCTRL_PIN(GPIO144, "GPIO144"),
PINCTRL_PIN(GPIO145, "GPIO145"),
PINCTRL_PIN(GPIO146, "GPIO146"),
PINCTRL_PIN(GPIO147, "GPIO147"),
PINCTRL_PIN(GPIO148, "GPIO148"),
PINCTRL_PIN(GPIO149, "GPIO149"),
PINCTRL_PIN(GPIO150, "GPIO150"),
PINCTRL_PIN(GPIO151, "GPIO151"),
PINCTRL_PIN(GPIO152, "GPIO152"),
PINCTRL_PIN(GPIO153, "GPIO153"),
PINCTRL_PIN(GPIO154, "GPIO154"),
PINCTRL_PIN(GPIO155, "GPIO155"),
PINCTRL_PIN(GPIO156, "GPIO156"),
PINCTRL_PIN(GPIO157, "GPIO157"),
PINCTRL_PIN(GPIO158, "GPIO158"),
PINCTRL_PIN(GPIO159, "GPIO159"),
PINCTRL_PIN(GPIO160, "GPIO160"),
PINCTRL_PIN(GPIO161, "GPIO161"),
PINCTRL_PIN(GPIO162, "GPIO162"),
PINCTRL_PIN(GPIO163, "GPIO163"),
PINCTRL_PIN(GPIO164, "GPIO164"),
PINCTRL_PIN(GPIO165, "GPIO165"),
PINCTRL_PIN(GPIO166, "GPIO166"),
PINCTRL_PIN(GPIO167, "GPIO167"),
PINCTRL_PIN(GPIO168, "GPIO168"),
PINCTRL_PIN(TWSI4_SCL, "TWSI4_SCL"),
PINCTRL_PIN(TWSI4_SDA, "TWSI4_SDA"),
PINCTRL_PIN(G_CLKREQ, "G_CLKREQ"),
PINCTRL_PIN(VCXO_REQ, "VCXO_REQ"),
PINCTRL_PIN(VCXO_OUT, "VCXO_OUT"),
};
struct pxa3xx_mfp_pin mmp2_mfp[] = {
/* pin offs f0 f1 f2 f3 f4 f5 f6 f7 */
MFPR_MMP2(GPIO0, 0x054, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO1, 0x058, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO2, 0x05C, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO3, 0x060, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO4, 0x064, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO5, 0x068, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO6, 0x06C, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO7, 0x070, GPIO, KP_MK, NONE, SPI, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO8, 0x074, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO9, 0x078, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO10, 0x07C, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO11, 0x080, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO12, 0x084, GPIO, KP_MK, NONE, CCIC1, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO13, 0x088, GPIO, KP_MK, NONE, CCIC1, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO14, 0x08C, GPIO, KP_MK, NONE, CCIC1, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO15, 0x090, GPIO, KP_MK, KP_DK, CCIC1, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO16, 0x094, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO17, 0x098, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO18, 0x09C, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO19, 0x0A0, GPIO, KP_DK, ROT, CCIC1, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO20, 0x0A4, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO21, 0x0A8, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO22, 0x0AC, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO23, 0x0B0, GPIO, KP_DK, TB, CCIC1, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO24, 0x0B4, GPIO, I2S, VCXO_OUT, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO25, 0x0B8, GPIO, I2S, HDMI, SSPA2, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO26, 0x0BC, GPIO, I2S, HDMI, SSPA2, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO27, 0x0C0, GPIO, I2S, HDMI, SSPA2, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO28, 0x0C4, GPIO, I2S, NONE, SSPA2, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO29, 0x0C8, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE),
MFPR_MMP2(GPIO30, 0x0CC, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE),
MFPR_MMP2(GPIO31, 0x0D0, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE),
MFPR_MMP2(GPIO32, 0x0D4, GPIO, UART1, KP_MK, NONE, NONE, NONE, AAS_SPI, NONE),
MFPR_MMP2(GPIO33, 0x0D8, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO34, 0x0DC, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO35, 0x0E0, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO36, 0x0E4, GPIO, SSPA2, I2S, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO37, 0x0E8, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI),
MFPR_MMP2(GPIO38, 0x0EC, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI),
MFPR_MMP2(GPIO39, 0x0F0, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI),
MFPR_MMP2(GPIO40, 0x0F4, GPIO, MMC2, SSP1, TWSI2, UART2, UART3, AAS_SPI, AAS_TWSI),
MFPR_MMP2(GPIO41, 0x0F8, GPIO, MMC2, TWSI5, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO42, 0x0FC, GPIO, MMC2, TWSI5, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO43, 0x100, GPIO, TWSI2, UART4, SSP1, UART2, UART3, NONE, AAS_TWSI),
MFPR_MMP2(GPIO44, 0x104, GPIO, TWSI2, UART4, SSP1, UART2, UART3, NONE, AAS_TWSI),
MFPR_MMP2(GPIO45, 0x108, GPIO, UART1, UART4, SSP1, UART2, UART3, NONE, NONE),
MFPR_MMP2(GPIO46, 0x10C, GPIO, UART1, UART4, SSP1, UART2, UART3, NONE, NONE),
MFPR_MMP2(GPIO47, 0x110, GPIO, UART2, SSP2, TWSI6, CAM2, AAS_SPI, AAS_GPIO, NONE),
MFPR_MMP2(GPIO48, 0x114, GPIO, UART2, SSP2, TWSI6, CAM2, AAS_SPI, AAS_GPIO, NONE),
MFPR_MMP2(GPIO49, 0x118, GPIO, UART2, SSP2, PWM, CCIC2, AAS_SPI, NONE, NONE),
MFPR_MMP2(GPIO50, 0x11C, GPIO, UART2, SSP2, PWM, CCIC2, AAS_SPI, NONE, NONE),
MFPR_MMP2(GPIO51, 0x120, GPIO, UART3, ROT, AAS_GPIO, PWM, NONE, NONE, NONE),
MFPR_MMP2(GPIO52, 0x124, GPIO, UART3, ROT, AAS_GPIO, PWM, NONE, NONE, NONE),
MFPR_MMP2(GPIO53, 0x128, GPIO, UART3, TWSI2, VCXO_REQ, NONE, PWM, NONE, AAS_TWSI),
MFPR_MMP2(GPIO54, 0x12C, GPIO, UART3, TWSI2, VCXO_OUT, HDMI, PWM, NONE, AAS_TWSI),
MFPR_MMP2(GPIO55, 0x130, GPIO, SSP2, SSP1, UART2, ROT, TWSI2, SSP3, AAS_TWSI),
MFPR_MMP2(GPIO56, 0x134, GPIO, SSP2, SSP1, UART2, ROT, TWSI2, KP_DK, AAS_TWSI),
MFPR_MMP2(GPIO57, 0x138, GPIO, SSP2_RX, SSP1_TXRX, SSP2_FRM, SSP1_RX, VCXO_REQ, KP_DK, NONE),
MFPR_MMP2(GPIO58, 0x13C, GPIO, SSP2, SSP1_RX, SSP1_FRM, SSP1_TXRX, VCXO_REQ, KP_DK, NONE),
MFPR_MMP2(GPIO59, 0x280, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, UART4, NONE),
MFPR_MMP2(GPIO60, 0x284, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, UART4, NONE),
MFPR_MMP2(GPIO61, 0x288, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, HDMI, NONE),
MFPR_MMP2(GPIO62, 0x28C, GPIO, CCIC1, ULPI, MMC3, CCIC2, UART3, NONE, NONE),
MFPR_MMP2(GPIO63, 0x290, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE),
MFPR_MMP2(GPIO64, 0x294, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE),
MFPR_MMP2(GPIO65, 0x298, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE),
MFPR_MMP2(GPIO66, 0x29C, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, UART4, NONE),
MFPR_MMP2(GPIO67, 0x2A0, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, NONE, NONE),
MFPR_MMP2(GPIO68, 0x2A4, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, LCD, NONE),
MFPR_MMP2(GPIO69, 0x2A8, GPIO, CCIC1, ULPI, MMC3, CCIC2, NONE, LCD, NONE),
MFPR_MMP2(GPIO70, 0x2AC, GPIO, CCIC1, ULPI, MMC3, CCIC2, MSP, LCD, NONE),
MFPR_MMP2(GPIO71, 0x2B0, GPIO, TWSI3, NONE, PWM, NONE, NONE, LCD, AAS_TWSI),
MFPR_MMP2(GPIO72, 0x2B4, GPIO, TWSI3, HDMI, PWM, NONE, NONE, LCD, AAS_TWSI),
MFPR_MMP2(GPIO73, 0x2B8, GPIO, VCXO_REQ, 32K_CLKOUT, PWM, VCXO_OUT, NONE, LCD, NONE),
MFPR_MMP2(GPIO74, 0x170, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU),
MFPR_MMP2(GPIO75, 0x174, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU),
MFPR_MMP2(GPIO76, 0x178, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU),
MFPR_MMP2(GPIO77, 0x17C, GPIO, LCD, SMC, MMC4, SSP3, UART2, UART4, TIPU),
MFPR_MMP2(GPIO78, 0x180, GPIO, LCD, HDMI, MMC4, NONE, SSP4, AAS_SPI, TIPU),
MFPR_MMP2(GPIO79, 0x184, GPIO, LCD, AAS_GPIO, MMC4, NONE, SSP4, AAS_SPI, TIPU),
MFPR_MMP2(GPIO80, 0x188, GPIO, LCD, AAS_GPIO, MMC4, NONE, SSP4, AAS_SPI, TIPU),
MFPR_MMP2(GPIO81, 0x18C, GPIO, LCD, AAS_GPIO, MMC4, NONE, SSP4, AAS_SPI, TIPU),
MFPR_MMP2(GPIO82, 0x190, GPIO, LCD, NONE, MMC4, NONE, NONE, CCIC2, TIPU),
MFPR_MMP2(GPIO83, 0x194, GPIO, LCD, NONE, MMC4, NONE, NONE, CCIC2, TIPU),
MFPR_MMP2(GPIO84, 0x198, GPIO, LCD, SMC, MMC2, NONE, TWSI5, AAS_TWSI, TIPU),
MFPR_MMP2(GPIO85, 0x19C, GPIO, LCD, SMC, MMC2, NONE, TWSI5, AAS_TWSI, TIPU),
MFPR_MMP2(GPIO86, 0x1A0, GPIO, LCD, SMC, MMC2, NONE, TWSI6, CCIC2, TIPU),
MFPR_MMP2(GPIO87, 0x1A4, GPIO, LCD, SMC, MMC2, NONE, TWSI6, CCIC2, TIPU),
MFPR_MMP2(GPIO88, 0x1A8, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU),
MFPR_MMP2(GPIO89, 0x1AC, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU),
MFPR_MMP2(GPIO90, 0x1B0, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU),
MFPR_MMP2(GPIO91, 0x1B4, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU),
MFPR_MMP2(GPIO92, 0x1B8, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU),
MFPR_MMP2(GPIO93, 0x1BC, GPIO, LCD, AAS_GPIO, MMC2, NONE, NONE, CCIC2, TIPU),
MFPR_MMP2(GPIO94, 0x1C0, GPIO, LCD, AAS_GPIO, SPI, NONE, AAS_SPI, CCIC2, TIPU),
MFPR_MMP2(GPIO95, 0x1C4, GPIO, LCD, TWSI3, SPI, AAS_DEU_EX, AAS_SPI, CCIC2, TIPU),
MFPR_MMP2(GPIO96, 0x1C8, GPIO, LCD, TWSI3, SPI, AAS_DEU_EX, AAS_SPI, NONE, TIPU),
MFPR_MMP2(GPIO97, 0x1CC, GPIO, LCD, TWSI6, SPI, AAS_DEU_EX, AAS_SPI, NONE, TIPU),
MFPR_MMP2(GPIO98, 0x1D0, GPIO, LCD, TWSI6, SPI, ONE_WIRE, NONE, NONE, TIPU),
MFPR_MMP2(GPIO99, 0x1D4, GPIO, LCD, SMC, SPI, TWSI5, NONE, NONE, TIPU),
MFPR_MMP2(GPIO100, 0x1D8, GPIO, LCD, SMC, SPI, TWSI5, NONE, NONE, TIPU),
MFPR_MMP2(GPIO101, 0x1DC, GPIO, LCD, SMC, SPI, NONE, NONE, NONE, TIPU),
MFPR_MMP2(GPIO102, 0x000, USIM, GPIO, FSIC, KP_DK, LCD, NONE, NONE, NONE),
MFPR_MMP2(GPIO103, 0x004, USIM, GPIO, FSIC, KP_DK, LCD, NONE, NONE, NONE),
MFPR_MMP2(GPIO104, 0x1FC, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO105, 0x1F8, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO106, 0x1F4, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO107, 0x1F0, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO108, 0x21C, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO109, 0x218, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO110, 0x214, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO111, 0x200, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO112, 0x244, NAND, GPIO, MMC3, SMC, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO113, 0x25C, SMC, GPIO, EXT_DMA, MMC3, SMC, HDMI, NONE, NONE),
MFPR_MMP2(GPIO114, 0x164, G_CLKOUT, 32K_CLKOUT, HDMI, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO115, 0x260, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE),
MFPR_MMP2(GPIO116, 0x264, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE),
MFPR_MMP2(GPIO117, 0x268, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE),
MFPR_MMP2(GPIO118, 0x26C, GPIO, NONE, AC, UART4, UART3, SSP1, NONE, NONE),
MFPR_MMP2(GPIO119, 0x270, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO120, 0x274, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO121, 0x278, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO122, 0x27C, GPIO, NONE, CA, SSP3, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO123, 0x148, GPIO, SLEEP_IND, ONE_WIRE, 32K_CLKOUT, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO124, 0x00C, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO125, 0x010, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO126, 0x014, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO127, 0x018, GPIO, NONE, LCD, MMC3, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO128, 0x01C, GPIO, NONE, LCD, MMC3, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO129, 0x020, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO130, 0x024, GPIO, MMC1, LCD, MMC3, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO131, 0x028, GPIO, MMC1, NONE, MSP, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO132, 0x02C, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE),
MFPR_MMP2(GPIO133, 0x030, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE),
MFPR_MMP2(GPIO134, 0x034, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE),
MFPR_MMP2(GPIO135, 0x038, GPIO, NONE, LCD, MMC3, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO136, 0x03C, GPIO, MMC1, PRI_JTAG, MSP, SSP3, AAS_JTAG, NONE, NONE),
MFPR_MMP2(GPIO137, 0x040, GPIO, HDMI, LCD, MSP, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO138, 0x044, GPIO, NONE, LCD, MMC3, SMC, NONE, NONE, NONE),
MFPR_MMP2(GPIO139, 0x048, GPIO, MMC1, PRI_JTAG, MSP, NONE, AAS_JTAG, NONE, NONE),
MFPR_MMP2(GPIO140, 0x04C, GPIO, MMC1, LCD, NONE, NONE, UART2, UART1, NONE),
MFPR_MMP2(GPIO141, 0x050, GPIO, MMC1, LCD, NONE, NONE, UART2, UART1, NONE),
MFPR_MMP2(GPIO142, 0x008, USIM, GPIO, FSIC, KP_DK, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO143, 0x220, NAND, GPIO, SMC, NONE, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO144, 0x224, NAND, GPIO, SMC_INT, SMC, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO145, 0x228, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE),
MFPR_MMP2(GPIO146, 0x22C, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE),
MFPR_MMP2(GPIO147, 0x230, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO148, 0x234, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO149, 0x238, NAND, GPIO, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO150, 0x23C, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO151, 0x240, SMC, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO152, 0x248, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE),
MFPR_MMP2(GPIO153, 0x24C, SMC, GPIO, NONE, NONE, SMC, NONE, NONE, NONE),
MFPR_MMP2(GPIO154, 0x254, SMC_INT, GPIO, SMC, NONE, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO155, 0x258, EXT_DMA, GPIO, SMC, NONE, EXT_DMA, NONE, NONE, NONE),
MFPR_MMP2(GPIO156, 0x14C, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO157, 0x150, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO158, 0x154, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO159, 0x158, PRI_JTAG, GPIO, PWM, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO160, 0x250, NAND, GPIO, SMC, NONE, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO161, 0x210, NAND, GPIO, NONE, NONE, NAND, NONE, NONE, NONE),
MFPR_MMP2(GPIO162, 0x20C, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO163, 0x208, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO164, 0x204, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO165, 0x1EC, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO166, 0x1E8, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO167, 0x1E4, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(GPIO168, 0x1E0, NAND, GPIO, MMC3, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(TWSI4_SCL, 0x2BC, TWSI4, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(TWSI4_SDA, 0x2C0, TWSI4, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(G_CLKREQ, 0x160, G_CLKREQ, ONE_WIRE, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(VCXO_REQ, 0x168, VCXO_REQ, ONE_WIRE, PLL, NONE, NONE, NONE, NONE, NONE),
MFPR_MMP2(VCXO_OUT, 0x16C, VCXO_OUT, 32K_CLKOUT, NONE, NONE, NONE, NONE, NONE, NONE),
};
static const unsigned mmp2_uart1_pin1[] = {GPIO29, GPIO30, GPIO31, GPIO32};
static const unsigned mmp2_uart1_pin2[] = {GPIO45, GPIO46};
static const unsigned mmp2_uart1_pin3[] = {GPIO140, GPIO141};
static const unsigned mmp2_uart2_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40};
static const unsigned mmp2_uart2_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46};
static const unsigned mmp2_uart2_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50};
static const unsigned mmp2_uart2_pin4[] = {GPIO74, GPIO75, GPIO76, GPIO77};
static const unsigned mmp2_uart2_pin5[] = {GPIO55, GPIO56};
static const unsigned mmp2_uart2_pin6[] = {GPIO140, GPIO141};
static const unsigned mmp2_uart3_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40};
static const unsigned mmp2_uart3_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46};
static const unsigned mmp2_uart3_pin3[] = {GPIO51, GPIO52, GPIO53, GPIO54};
static const unsigned mmp2_uart3_pin4[] = {GPIO59, GPIO60, GPIO61, GPIO62};
static const unsigned mmp2_uart3_pin5[] = {GPIO115, GPIO116, GPIO117, GPIO118};
static const unsigned mmp2_uart3_pin6[] = {GPIO51, GPIO52};
static const unsigned mmp2_uart4_pin1[] = {GPIO43, GPIO44, GPIO45, GPIO46};
static const unsigned mmp2_uart4_pin2[] = {GPIO63, GPIO64, GPIO65, GPIO66};
static const unsigned mmp2_uart4_pin3[] = {GPIO74, GPIO75, GPIO76, GPIO77};
static const unsigned mmp2_uart4_pin4[] = {GPIO115, GPIO116, GPIO117, GPIO118};
static const unsigned mmp2_uart4_pin5[] = {GPIO59, GPIO60};
static const unsigned mmp2_kpdk_pin1[] = {GPIO16, GPIO17, GPIO18, GPIO19};
static const unsigned mmp2_kpdk_pin2[] = {GPIO16, GPIO17};
static const unsigned mmp2_twsi2_pin1[] = {GPIO37, GPIO38};
static const unsigned mmp2_twsi2_pin2[] = {GPIO39, GPIO40};
static const unsigned mmp2_twsi2_pin3[] = {GPIO43, GPIO44};
static const unsigned mmp2_twsi2_pin4[] = {GPIO53, GPIO54};
static const unsigned mmp2_twsi2_pin5[] = {GPIO55, GPIO56};
static const unsigned mmp2_twsi3_pin1[] = {GPIO71, GPIO72};
static const unsigned mmp2_twsi3_pin2[] = {GPIO95, GPIO96};
static const unsigned mmp2_twsi4_pin1[] = {TWSI4_SCL, TWSI4_SDA};
static const unsigned mmp2_twsi5_pin1[] = {GPIO41, GPIO42};
static const unsigned mmp2_twsi5_pin2[] = {GPIO84, GPIO85};
static const unsigned mmp2_twsi5_pin3[] = {GPIO99, GPIO100};
static const unsigned mmp2_twsi6_pin1[] = {GPIO47, GPIO48};
static const unsigned mmp2_twsi6_pin2[] = {GPIO86, GPIO87};
static const unsigned mmp2_twsi6_pin3[] = {GPIO97, GPIO98};
static const unsigned mmp2_ccic1_pin1[] = {GPIO12, GPIO13, GPIO14, GPIO15,
GPIO16, GPIO17, GPIO18, GPIO19, GPIO20, GPIO21, GPIO22, GPIO23};
static const unsigned mmp2_ccic1_pin2[] = {GPIO59, GPIO60, GPIO61, GPIO62,
GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70};
static const unsigned mmp2_ccic2_pin1[] = {GPIO59, GPIO60, GPIO61, GPIO62,
GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70};
static const unsigned mmp2_ccic2_pin2[] = {GPIO82, GPIO83, GPIO86, GPIO87,
GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, GPIO93, GPIO94, GPIO95};
static const unsigned mmp2_ulpi_pin1[] = {GPIO59, GPIO60, GPIO61, GPIO62,
GPIO63, GPIO64, GPIO65, GPIO66, GPIO67, GPIO68, GPIO69, GPIO70};
static const unsigned mmp2_ro_pin1[] = {GPIO16, GPIO17};
static const unsigned mmp2_ro_pin2[] = {GPIO18, GPIO19};
static const unsigned mmp2_ro_pin3[] = {GPIO51, GPIO52};
static const unsigned mmp2_ro_pin4[] = {GPIO55, GPIO56};
static const unsigned mmp2_i2s_pin1[] = {GPIO24, GPIO25, GPIO26, GPIO27,
GPIO28};
static const unsigned mmp2_i2s_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36};
static const unsigned mmp2_ssp1_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40};
static const unsigned mmp2_ssp1_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46};
static const unsigned mmp2_ssp1_pin3[] = {GPIO115, GPIO116, GPIO117, GPIO118};
static const unsigned mmp2_ssp2_pin1[] = {GPIO47, GPIO48, GPIO49, GPIO50};
static const unsigned mmp2_ssp3_pin1[] = {GPIO119, GPIO120, GPIO121, GPIO122};
static const unsigned mmp2_ssp3_pin2[] = {GPIO132, GPIO133, GPIO133, GPIO136};
static const unsigned mmp2_sspa2_pin1[] = {GPIO25, GPIO26, GPIO27, GPIO28};
static const unsigned mmp2_sspa2_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36};
static const unsigned mmp2_mmc1_pin1[] = {GPIO131, GPIO132, GPIO133, GPIO134,
GPIO136, GPIO139, GPIO140, GPIO141};
static const unsigned mmp2_mmc2_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40,
GPIO41, GPIO42};
static const unsigned mmp2_mmc3_pin1[] = {GPIO111, GPIO112, GPIO151, GPIO162,
GPIO163, GPIO164, GPIO165, GPIO166, GPIO167, GPIO168};
static struct pxa3xx_pin_group mmp2_grps[] = {
GRP_MMP2("uart1 4p1", UART1, mmp2_uart1_pin1),
GRP_MMP2("uart1 2p2", UART1, mmp2_uart1_pin2),
GRP_MMP2("uart1 2p3", UART1, mmp2_uart1_pin3),
GRP_MMP2("uart2 4p1", UART2, mmp2_uart2_pin1),
GRP_MMP2("uart2 4p2", UART2, mmp2_uart2_pin2),
GRP_MMP2("uart2 4p3", UART2, mmp2_uart2_pin3),
GRP_MMP2("uart2 4p4", UART2, mmp2_uart2_pin4),
GRP_MMP2("uart2 2p5", UART2, mmp2_uart2_pin5),
GRP_MMP2("uart2 2p6", UART2, mmp2_uart2_pin6),
GRP_MMP2("uart3 4p1", UART3, mmp2_uart3_pin1),
GRP_MMP2("uart3 4p2", UART3, mmp2_uart3_pin2),
GRP_MMP2("uart3 4p3", UART3, mmp2_uart3_pin3),
GRP_MMP2("uart3 4p4", UART3, mmp2_uart3_pin4),
GRP_MMP2("uart3 4p5", UART3, mmp2_uart3_pin5),
GRP_MMP2("uart3 2p6", UART3, mmp2_uart3_pin6),
GRP_MMP2("uart4 4p1", UART4, mmp2_uart4_pin1),
GRP_MMP2("uart4 4p2", UART4, mmp2_uart4_pin2),
GRP_MMP2("uart4 4p3", UART4, mmp2_uart4_pin3),
GRP_MMP2("uart4 4p4", UART4, mmp2_uart4_pin4),
GRP_MMP2("uart4 2p5", UART4, mmp2_uart4_pin5),
GRP_MMP2("kpdk 4p1", KP_DK, mmp2_kpdk_pin1),
GRP_MMP2("kpdk 4p2", KP_DK, mmp2_kpdk_pin2),
GRP_MMP2("twsi2-1", TWSI2, mmp2_twsi2_pin1),
GRP_MMP2("twsi2-2", TWSI2, mmp2_twsi2_pin2),
GRP_MMP2("twsi2-3", TWSI2, mmp2_twsi2_pin3),
GRP_MMP2("twsi2-4", TWSI2, mmp2_twsi2_pin4),
GRP_MMP2("twsi2-5", TWSI2, mmp2_twsi2_pin5),
GRP_MMP2("twsi3-1", TWSI3, mmp2_twsi3_pin1),
GRP_MMP2("twsi3-2", TWSI3, mmp2_twsi3_pin2),
GRP_MMP2("twsi4", TWSI4, mmp2_twsi4_pin1),
GRP_MMP2("twsi5-1", TWSI5, mmp2_twsi5_pin1),
GRP_MMP2("twsi5-2", TWSI5, mmp2_twsi5_pin2),
GRP_MMP2("twsi5-3", TWSI5, mmp2_twsi5_pin3),
GRP_MMP2("twsi6-1", TWSI6, mmp2_twsi6_pin1),
GRP_MMP2("twsi6-2", TWSI6, mmp2_twsi6_pin2),
GRP_MMP2("twsi6-3", TWSI6, mmp2_twsi6_pin3),
GRP_MMP2("ccic1-1", CCIC1, mmp2_ccic1_pin1),
GRP_MMP2("ccic1-2", CCIC1, mmp2_ccic1_pin2),
GRP_MMP2("ccic2-1", CCIC2, mmp2_ccic2_pin1),
GRP_MMP2("ccic2-1", CCIC2, mmp2_ccic2_pin2),
GRP_MMP2("ulpi", ULPI, mmp2_ulpi_pin1),
GRP_MMP2("ro-1", ROT, mmp2_ro_pin1),
GRP_MMP2("ro-2", ROT, mmp2_ro_pin2),
GRP_MMP2("ro-3", ROT, mmp2_ro_pin3),
GRP_MMP2("ro-4", ROT, mmp2_ro_pin4),
GRP_MMP2("i2s 5p1", I2S, mmp2_i2s_pin1),
GRP_MMP2("i2s 4p2", I2S, mmp2_i2s_pin2),
GRP_MMP2("ssp1 4p1", SSP1, mmp2_ssp1_pin1),
GRP_MMP2("ssp1 4p2", SSP1, mmp2_ssp1_pin2),
GRP_MMP2("ssp1 4p3", SSP1, mmp2_ssp1_pin3),
GRP_MMP2("ssp2 4p1", SSP2, mmp2_ssp2_pin1),
GRP_MMP2("ssp3 4p1", SSP3, mmp2_ssp3_pin1),
GRP_MMP2("ssp3 4p2", SSP3, mmp2_ssp3_pin2),
GRP_MMP2("sspa2 4p1", SSPA2, mmp2_sspa2_pin1),
GRP_MMP2("sspa2 4p2", SSPA2, mmp2_sspa2_pin2),
GRP_MMP2("mmc1 8p1", MMC1, mmp2_mmc1_pin1),
GRP_MMP2("mmc2 6p1", MMC2, mmp2_mmc2_pin1),
GRP_MMP2("mmc3 10p1", MMC3, mmp2_mmc3_pin1),
};
static const char * const mmp2_uart1_grps[] = {"uart1 4p1", "uart1 2p2",
"uart1 2p3"};
static const char * const mmp2_uart2_grps[] = {"uart2 4p1", "uart2 4p2",
"uart2 4p3", "uart2 4p4", "uart2 4p5", "uart2 4p6"};
static const char * const mmp2_uart3_grps[] = {"uart3 4p1", "uart3 4p2",
"uart3 4p3", "uart3 4p4", "uart3 4p5", "uart3 2p6"};
static const char * const mmp2_uart4_grps[] = {"uart4 4p1", "uart4 4p2",
"uart4 4p3", "uart4 4p4", "uart4 2p5"};
static const char * const mmp2_kpdk_grps[] = {"kpdk 4p1", "kpdk 4p2"};
static const char * const mmp2_twsi2_grps[] = {"twsi2-1", "twsi2-2",
"twsi2-3", "twsi2-4", "twsi2-5"};
static const char * const mmp2_twsi3_grps[] = {"twsi3-1", "twsi3-2"};
static const char * const mmp2_twsi4_grps[] = {"twsi4"};
static const char * const mmp2_twsi5_grps[] = {"twsi5-1", "twsi5-2",
"twsi5-3"};
static const char * const mmp2_twsi6_grps[] = {"twsi6-1", "twsi6-2",
"twsi6-3"};
static const char * const mmp2_ccic1_grps[] = {"ccic1-1", "ccic1-2"};
static const char * const mmp2_ccic2_grps[] = {"ccic2-1", "ccic2-2"};
static const char * const mmp2_ulpi_grps[] = {"ulpi"};
static const char * const mmp2_ro_grps[] = {"ro-1", "ro-2", "ro-3", "ro-4"};
static const char * const mmp2_i2s_grps[] = {"i2s 5p1", "i2s 4p2"};
static const char * const mmp2_ssp1_grps[] = {"ssp1 4p1", "ssp1 4p2",
"ssp1 4p3"};
static const char * const mmp2_ssp2_grps[] = {"ssp2 4p1"};
static const char * const mmp2_ssp3_grps[] = {"ssp3 4p1", "ssp3 4p2"};
static const char * const mmp2_sspa2_grps[] = {"sspa2 4p1", "sspa2 4p2"};
static const char * const mmp2_mmc1_grps[] = {"mmc1 8p1"};
static const char * const mmp2_mmc2_grps[] = {"mmc2 6p1"};
static const char * const mmp2_mmc3_grps[] = {"mmc3 10p1"};
static struct pxa3xx_pmx_func mmp2_funcs[] = {
{"uart1", ARRAY_AND_SIZE(mmp2_uart1_grps)},
{"uart2", ARRAY_AND_SIZE(mmp2_uart2_grps)},
{"uart3", ARRAY_AND_SIZE(mmp2_uart3_grps)},
{"uart4", ARRAY_AND_SIZE(mmp2_uart4_grps)},
{"kpdk", ARRAY_AND_SIZE(mmp2_kpdk_grps)},
{"twsi2", ARRAY_AND_SIZE(mmp2_twsi2_grps)},
{"twsi3", ARRAY_AND_SIZE(mmp2_twsi3_grps)},
{"twsi4", ARRAY_AND_SIZE(mmp2_twsi4_grps)},
{"twsi5", ARRAY_AND_SIZE(mmp2_twsi5_grps)},
{"twsi6", ARRAY_AND_SIZE(mmp2_twsi6_grps)},
{"ccic1", ARRAY_AND_SIZE(mmp2_ccic1_grps)},
{"ccic2", ARRAY_AND_SIZE(mmp2_ccic2_grps)},
{"ulpi", ARRAY_AND_SIZE(mmp2_ulpi_grps)},
{"ro", ARRAY_AND_SIZE(mmp2_ro_grps)},
{"i2s", ARRAY_AND_SIZE(mmp2_i2s_grps)},
{"ssp1", ARRAY_AND_SIZE(mmp2_ssp1_grps)},
{"ssp2", ARRAY_AND_SIZE(mmp2_ssp2_grps)},
{"ssp3", ARRAY_AND_SIZE(mmp2_ssp3_grps)},
{"sspa2", ARRAY_AND_SIZE(mmp2_sspa2_grps)},
{"mmc1", ARRAY_AND_SIZE(mmp2_mmc1_grps)},
{"mmc2", ARRAY_AND_SIZE(mmp2_mmc2_grps)},
{"mmc3", ARRAY_AND_SIZE(mmp2_mmc3_grps)},
};
static struct pinctrl_desc mmp2_pctrl_desc = {
.name = "mmp2-pinctrl",
.owner = THIS_MODULE,
};
static struct pxa3xx_pinmux_info mmp2_info = {
.mfp = mmp2_mfp,
.num_mfp = ARRAY_SIZE(mmp2_mfp),
.grps = mmp2_grps,
.num_grps = ARRAY_SIZE(mmp2_grps),
.funcs = mmp2_funcs,
.num_funcs = ARRAY_SIZE(mmp2_funcs),
.num_gpio = 169,
.desc = &mmp2_pctrl_desc,
.pads = mmp2_pads,
.num_pads = ARRAY_SIZE(mmp2_pads),
.cputype = PINCTRL_MMP2,
.ds_mask = MMP2_DS_MASK,
.ds_shift = MMP2_DS_SHIFT,
};
static int __devinit mmp2_pinmux_probe(struct platform_device *pdev)
{
return pxa3xx_pinctrl_register(pdev, &mmp2_info);
}
static int __devexit mmp2_pinmux_remove(struct platform_device *pdev)
{
return pxa3xx_pinctrl_unregister(pdev);
}
static struct platform_driver mmp2_pinmux_driver = {
.driver = {
.name = "mmp2-pinmux",
.owner = THIS_MODULE,
},
.probe = mmp2_pinmux_probe,
.remove = __devexit_p(mmp2_pinmux_remove),
};
static int __init mmp2_pinmux_init(void)
{
return platform_driver_register(&mmp2_pinmux_driver);
}
core_initcall_sync(mmp2_pinmux_init);
static void __exit mmp2_pinmux_exit(void)
{
platform_driver_unregister(&mmp2_pinmux_driver);
}
module_exit(mmp2_pinmux_exit);
MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
MODULE_DESCRIPTION("PXA3xx pin control driver");
MODULE_LICENSE("GPL v2");

View File

@ -0,0 +1,651 @@
/*
* linux/drivers/pinctrl/pinmux-pxa168.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* publishhed by the Free Software Foundation.
*
* Copyright (C) 2011, Marvell Technology Group Ltd.
*
* Author: Haojian Zhuang <haojian.zhuang@marvell.com>
*
*/
#include <linux/device.h>
#include <linux/module.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include "pinctrl-pxa3xx.h"
#define PXA168_DS_MASK 0x1800
#define PXA168_DS_SHIFT 11
#define PXA168_SLEEP_MASK 0x38
#define PXA168_SLEEP_SELECT (1 << 9)
#define PXA168_SLEEP_DATA (1 << 8)
#define PXA168_SLEEP_DIR (1 << 7)
#define MFPR_168(a, r, f0, f1, f2, f3, f4, f5, f6, f7) \
{ \
.name = #a, \
.pin = a, \
.mfpr = r, \
.func = { \
PXA168_MUX_##f0, \
PXA168_MUX_##f1, \
PXA168_MUX_##f2, \
PXA168_MUX_##f3, \
PXA168_MUX_##f4, \
PXA168_MUX_##f5, \
PXA168_MUX_##f6, \
PXA168_MUX_##f7, \
}, \
}
#define GRP_168(a, m, p) \
{ .name = a, .mux = PXA168_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), }
/* 131 pins */
enum pxa168_pin_list {
/* 0~122: GPIO0~GPIO122 */
PWR_SCL = 123,
PWR_SDA,
TDI,
TMS,
TCK,
TDO,
TRST,
WAKEUP = 130,
};
enum pxa168_mux {
/* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */
PXA168_MUX_GPIO = 0,
PXA168_MUX_DFIO,
PXA168_MUX_NAND,
PXA168_MUX_SMC,
PXA168_MUX_SMC_CS0,
PXA168_MUX_SMC_CS1,
PXA168_MUX_SMC_INT,
PXA168_MUX_SMC_RDY,
PXA168_MUX_MMC1,
PXA168_MUX_MMC2,
PXA168_MUX_MMC2_CMD,
PXA168_MUX_MMC2_CLK,
PXA168_MUX_MMC3,
PXA168_MUX_MMC3_CMD,
PXA168_MUX_MMC3_CLK,
PXA168_MUX_MMC4,
PXA168_MUX_MSP,
PXA168_MUX_MSP_DAT3,
PXA168_MUX_MSP_INS,
PXA168_MUX_I2C,
PXA168_MUX_PWRI2C,
PXA168_MUX_AC97,
PXA168_MUX_AC97_SYSCLK,
PXA168_MUX_PWM,
PXA168_MUX_PWM1,
PXA168_MUX_XD,
PXA168_MUX_XP,
PXA168_MUX_LCD,
PXA168_MUX_CCIC,
PXA168_MUX_CF,
PXA168_MUX_CF_RDY,
PXA168_MUX_CF_nINPACK,
PXA168_MUX_CF_nWAIT,
PXA168_MUX_KP_MKOUT,
PXA168_MUX_KP_MKIN,
PXA168_MUX_KP_DK,
PXA168_MUX_ETH,
PXA168_MUX_ETH_TX,
PXA168_MUX_ETH_RX,
PXA168_MUX_ONE_WIRE,
PXA168_MUX_UART1,
PXA168_MUX_UART1_TX,
PXA168_MUX_UART1_CTS,
PXA168_MUX_UART1_nRI,
PXA168_MUX_UART1_DTR,
PXA168_MUX_UART2,
PXA168_MUX_UART2_TX,
PXA168_MUX_UART3,
PXA168_MUX_UART3_TX,
PXA168_MUX_UART3_CTS,
PXA168_MUX_SSP1,
PXA168_MUX_SSP1_TX,
PXA168_MUX_SSP2,
PXA168_MUX_SSP2_TX,
PXA168_MUX_SSP3,
PXA168_MUX_SSP3_TX,
PXA168_MUX_SSP4,
PXA168_MUX_SSP4_TX,
PXA168_MUX_SSP5,
PXA168_MUX_SSP5_TX,
PXA168_MUX_USB,
PXA168_MUX_JTAG,
PXA168_MUX_RESET,
PXA168_MUX_WAKEUP,
PXA168_MUX_EXT_32K_IN,
PXA168_MUX_NONE = 0xffff,
};
static struct pinctrl_pin_desc pxa168_pads[] = {
PINCTRL_PIN(GPIO0, "GPIO0"),
PINCTRL_PIN(GPIO1, "GPIO1"),
PINCTRL_PIN(GPIO2, "GPIO2"),
PINCTRL_PIN(GPIO3, "GPIO3"),
PINCTRL_PIN(GPIO4, "GPIO4"),
PINCTRL_PIN(GPIO5, "GPIO5"),
PINCTRL_PIN(GPIO6, "GPIO6"),
PINCTRL_PIN(GPIO7, "GPIO7"),
PINCTRL_PIN(GPIO8, "GPIO8"),
PINCTRL_PIN(GPIO9, "GPIO9"),
PINCTRL_PIN(GPIO10, "GPIO10"),
PINCTRL_PIN(GPIO11, "GPIO11"),
PINCTRL_PIN(GPIO12, "GPIO12"),
PINCTRL_PIN(GPIO13, "GPIO13"),
PINCTRL_PIN(GPIO14, "GPIO14"),
PINCTRL_PIN(GPIO15, "GPIO15"),
PINCTRL_PIN(GPIO16, "GPIO16"),
PINCTRL_PIN(GPIO17, "GPIO17"),
PINCTRL_PIN(GPIO18, "GPIO18"),
PINCTRL_PIN(GPIO19, "GPIO19"),
PINCTRL_PIN(GPIO20, "GPIO20"),
PINCTRL_PIN(GPIO21, "GPIO21"),
PINCTRL_PIN(GPIO22, "GPIO22"),
PINCTRL_PIN(GPIO23, "GPIO23"),
PINCTRL_PIN(GPIO24, "GPIO24"),
PINCTRL_PIN(GPIO25, "GPIO25"),
PINCTRL_PIN(GPIO26, "GPIO26"),
PINCTRL_PIN(GPIO27, "GPIO27"),
PINCTRL_PIN(GPIO28, "GPIO28"),
PINCTRL_PIN(GPIO29, "GPIO29"),
PINCTRL_PIN(GPIO30, "GPIO30"),
PINCTRL_PIN(GPIO31, "GPIO31"),
PINCTRL_PIN(GPIO32, "GPIO32"),
PINCTRL_PIN(GPIO33, "GPIO33"),
PINCTRL_PIN(GPIO34, "GPIO34"),
PINCTRL_PIN(GPIO35, "GPIO35"),
PINCTRL_PIN(GPIO36, "GPIO36"),
PINCTRL_PIN(GPIO37, "GPIO37"),
PINCTRL_PIN(GPIO38, "GPIO38"),
PINCTRL_PIN(GPIO39, "GPIO39"),
PINCTRL_PIN(GPIO40, "GPIO40"),
PINCTRL_PIN(GPIO41, "GPIO41"),
PINCTRL_PIN(GPIO42, "GPIO42"),
PINCTRL_PIN(GPIO43, "GPIO43"),
PINCTRL_PIN(GPIO44, "GPIO44"),
PINCTRL_PIN(GPIO45, "GPIO45"),
PINCTRL_PIN(GPIO46, "GPIO46"),
PINCTRL_PIN(GPIO47, "GPIO47"),
PINCTRL_PIN(GPIO48, "GPIO48"),
PINCTRL_PIN(GPIO49, "GPIO49"),
PINCTRL_PIN(GPIO50, "GPIO50"),
PINCTRL_PIN(GPIO51, "GPIO51"),
PINCTRL_PIN(GPIO52, "GPIO52"),
PINCTRL_PIN(GPIO53, "GPIO53"),
PINCTRL_PIN(GPIO54, "GPIO54"),
PINCTRL_PIN(GPIO55, "GPIO55"),
PINCTRL_PIN(GPIO56, "GPIO56"),
PINCTRL_PIN(GPIO57, "GPIO57"),
PINCTRL_PIN(GPIO58, "GPIO58"),
PINCTRL_PIN(GPIO59, "GPIO59"),
PINCTRL_PIN(GPIO60, "GPIO60"),
PINCTRL_PIN(GPIO61, "GPIO61"),
PINCTRL_PIN(GPIO62, "GPIO62"),
PINCTRL_PIN(GPIO63, "GPIO63"),
PINCTRL_PIN(GPIO64, "GPIO64"),
PINCTRL_PIN(GPIO65, "GPIO65"),
PINCTRL_PIN(GPIO66, "GPIO66"),
PINCTRL_PIN(GPIO67, "GPIO67"),
PINCTRL_PIN(GPIO68, "GPIO68"),
PINCTRL_PIN(GPIO69, "GPIO69"),
PINCTRL_PIN(GPIO70, "GPIO70"),
PINCTRL_PIN(GPIO71, "GPIO71"),
PINCTRL_PIN(GPIO72, "GPIO72"),
PINCTRL_PIN(GPIO73, "GPIO73"),
PINCTRL_PIN(GPIO74, "GPIO74"),
PINCTRL_PIN(GPIO75, "GPIO75"),
PINCTRL_PIN(GPIO76, "GPIO76"),
PINCTRL_PIN(GPIO77, "GPIO77"),
PINCTRL_PIN(GPIO78, "GPIO78"),
PINCTRL_PIN(GPIO79, "GPIO79"),
PINCTRL_PIN(GPIO80, "GPIO80"),
PINCTRL_PIN(GPIO81, "GPIO81"),
PINCTRL_PIN(GPIO82, "GPIO82"),
PINCTRL_PIN(GPIO83, "GPIO83"),
PINCTRL_PIN(GPIO84, "GPIO84"),
PINCTRL_PIN(GPIO85, "GPIO85"),
PINCTRL_PIN(GPIO86, "GPIO86"),
PINCTRL_PIN(GPIO87, "GPIO87"),
PINCTRL_PIN(GPIO88, "GPIO88"),
PINCTRL_PIN(GPIO89, "GPIO89"),
PINCTRL_PIN(GPIO90, "GPIO90"),
PINCTRL_PIN(GPIO91, "GPIO91"),
PINCTRL_PIN(GPIO92, "GPIO92"),
PINCTRL_PIN(GPIO93, "GPIO93"),
PINCTRL_PIN(GPIO94, "GPIO94"),
PINCTRL_PIN(GPIO95, "GPIO95"),
PINCTRL_PIN(GPIO96, "GPIO96"),
PINCTRL_PIN(GPIO97, "GPIO97"),
PINCTRL_PIN(GPIO98, "GPIO98"),
PINCTRL_PIN(GPIO99, "GPIO99"),
PINCTRL_PIN(GPIO100, "GPIO100"),
PINCTRL_PIN(GPIO101, "GPIO101"),
PINCTRL_PIN(GPIO102, "GPIO102"),
PINCTRL_PIN(GPIO103, "GPIO103"),
PINCTRL_PIN(GPIO104, "GPIO104"),
PINCTRL_PIN(GPIO105, "GPIO105"),
PINCTRL_PIN(GPIO106, "GPIO106"),
PINCTRL_PIN(GPIO107, "GPIO107"),
PINCTRL_PIN(GPIO108, "GPIO108"),
PINCTRL_PIN(GPIO109, "GPIO109"),
PINCTRL_PIN(GPIO110, "GPIO110"),
PINCTRL_PIN(GPIO111, "GPIO111"),
PINCTRL_PIN(GPIO112, "GPIO112"),
PINCTRL_PIN(GPIO113, "GPIO113"),
PINCTRL_PIN(GPIO114, "GPIO114"),
PINCTRL_PIN(GPIO115, "GPIO115"),
PINCTRL_PIN(GPIO116, "GPIO116"),
PINCTRL_PIN(GPIO117, "GPIO117"),
PINCTRL_PIN(GPIO118, "GPIO118"),
PINCTRL_PIN(GPIO119, "GPIO119"),
PINCTRL_PIN(GPIO120, "GPIO120"),
PINCTRL_PIN(GPIO121, "GPIO121"),
PINCTRL_PIN(GPIO122, "GPIO122"),
PINCTRL_PIN(PWR_SCL, "PWR_SCL"),
PINCTRL_PIN(PWR_SDA, "PWR_SDA"),
PINCTRL_PIN(TDI, "TDI"),
PINCTRL_PIN(TMS, "TMS"),
PINCTRL_PIN(TCK, "TCK"),
PINCTRL_PIN(TDO, "TDO"),
PINCTRL_PIN(TRST, "TRST"),
PINCTRL_PIN(WAKEUP, "WAKEUP"),
};
struct pxa3xx_mfp_pin pxa168_mfp[] = {
/* pin offs f0 f1 f2 f3 f4 f5 f6 f7 */
MFPR_168(GPIO0, 0x04C, DFIO, NONE, NONE, MSP, MMC3_CMD, GPIO, MMC3, NONE),
MFPR_168(GPIO1, 0x050, DFIO, NONE, NONE, MSP, MMC3_CLK, GPIO, MMC3, NONE),
MFPR_168(GPIO2, 0x054, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE),
MFPR_168(GPIO3, 0x058, DFIO, NONE, NONE, NONE, NONE, GPIO, MMC3, NONE),
MFPR_168(GPIO4, 0x05C, DFIO, NONE, NONE, MSP_DAT3, NONE, GPIO, MMC3, NONE),
MFPR_168(GPIO5, 0x060, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE),
MFPR_168(GPIO6, 0x064, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE),
MFPR_168(GPIO7, 0x068, DFIO, NONE, NONE, MSP, NONE, GPIO, MMC3, NONE),
MFPR_168(GPIO8, 0x06C, DFIO, MMC2, UART3_TX, NONE, MMC2_CMD, GPIO, MMC3_CLK, NONE),
MFPR_168(GPIO9, 0x070, DFIO, MMC2, UART3, NONE, MMC2_CLK, GPIO, MMC3_CMD, NONE),
MFPR_168(GPIO10, 0x074, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP_DAT3, NONE),
MFPR_168(GPIO11, 0x078, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP, NONE),
MFPR_168(GPIO12, 0x07C, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP, NONE),
MFPR_168(GPIO13, 0x080, DFIO, MMC2, UART3, NONE, NONE, GPIO, MSP, NONE),
MFPR_168(GPIO14, 0x084, DFIO, MMC2, NONE, NONE, NONE, GPIO, MSP, NONE),
MFPR_168(GPIO15, 0x088, DFIO, MMC2, NONE, NONE, NONE, GPIO, MSP, NONE),
MFPR_168(GPIO16, 0x08C, GPIO, NAND, SMC_CS0, SMC_CS1, NONE, NONE, MMC3, NONE),
MFPR_168(GPIO17, 0x090, NAND, NONE, NONE, NONE, NONE, GPIO, MSP, NONE),
MFPR_168(GPIO18, 0x094, GPIO, NAND, SMC_CS1, SMC_CS0, NONE, NONE, NONE, NONE),
MFPR_168(GPIO19, 0x098, SMC_CS0, NONE, NONE, CF, NONE, GPIO, NONE, NONE),
MFPR_168(GPIO20, 0x09C, GPIO, NONE, SMC_CS1, CF, CF_RDY, NONE, NONE, NONE),
MFPR_168(GPIO21, 0x0A0, NAND, MMC2_CLK, NONE, NONE, NONE, GPIO, NONE, NONE),
MFPR_168(GPIO22, 0x0A4, NAND, MMC2_CMD, NONE, NONE, NONE, GPIO, NONE, NONE),
MFPR_168(GPIO23, 0x0A8, SMC, NAND, NONE, CF, NONE, GPIO, NONE, NONE),
MFPR_168(GPIO24, 0x0AC, NAND, NONE, NONE, NONE, NONE, GPIO, NONE, NONE),
MFPR_168(GPIO25, 0x0B0, SMC, NAND, NONE, CF, NONE, GPIO, NONE, NONE),
MFPR_168(GPIO26, 0x0B4, GPIO, NAND, NONE, NONE, CF, NONE, NONE, NONE),
MFPR_168(GPIO27, 0x0B8, SMC_INT, NAND, SMC, NONE, SMC_RDY, GPIO, NONE, NONE),
MFPR_168(GPIO28, 0x0BC, SMC_RDY, MMC4, SMC, CF_RDY, NONE, GPIO, MMC2_CMD, NONE),
MFPR_168(GPIO29, 0x0C0, SMC, MMC4, NONE, CF, NONE, GPIO, MMC2_CLK, KP_DK),
MFPR_168(GPIO30, 0x0C4, SMC, MMC4, UART3_TX, CF, NONE, GPIO, MMC2, KP_DK),
MFPR_168(GPIO31, 0x0C8, SMC, MMC4, UART3, CF, NONE, GPIO, MMC2, KP_DK),
MFPR_168(GPIO32, 0x0CC, SMC, MMC4, UART3, CF, NONE, GPIO, MMC2, KP_DK),
MFPR_168(GPIO33, 0x0D0, SMC, MMC4, UART3, CF, CF_nINPACK, GPIO, MMC2, KP_DK),
MFPR_168(GPIO34, 0x0D4, GPIO, NONE, SMC_CS1, CF, CF_nWAIT, NONE, MMC3, KP_DK),
MFPR_168(GPIO35, 0x0D8, GPIO, NONE, SMC, CF_nINPACK, NONE, NONE, MMC3_CMD, KP_DK),
MFPR_168(GPIO36, 0x0DC, GPIO, NONE, SMC, CF_nWAIT, NONE, NONE, MMC3_CLK, KP_DK),
MFPR_168(GPIO37, 0x000, GPIO, MMC1, NONE, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK),
MFPR_168(GPIO38, 0x004, GPIO, MMC1, NONE, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK),
MFPR_168(GPIO39, 0x008, GPIO, NONE, NONE, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK),
MFPR_168(GPIO40, 0x00C, GPIO, MMC1, MSP, KP_MKOUT, CCIC, XP, KP_MKIN, KP_DK),
MFPR_168(GPIO41, 0x010, GPIO, MMC1, MSP, NONE, CCIC, XP, KP_MKIN, KP_DK),
MFPR_168(GPIO42, 0x014, GPIO, I2C, NONE, MSP, CCIC, XP, KP_MKIN, KP_DK),
MFPR_168(GPIO43, 0x018, GPIO, MMC1, MSP, MSP_INS, NONE, NONE, KP_MKIN, KP_DK),
MFPR_168(GPIO44, 0x01C, GPIO, MMC1, MSP_DAT3, MSP, CCIC, XP, KP_MKIN, KP_DK),
MFPR_168(GPIO45, 0x020, GPIO, NONE, NONE, MSP, CCIC, XP, NONE, KP_DK),
MFPR_168(GPIO46, 0x024, GPIO, MMC1, MSP_INS, MSP, CCIC, NONE, KP_MKOUT, KP_DK),
MFPR_168(GPIO47, 0x028, GPIO, NONE, NONE, MSP_INS, NONE, XP, NONE, KP_DK),
MFPR_168(GPIO48, 0x02C, GPIO, MMC1, NONE, MSP_DAT3, CCIC, NONE, NONE, KP_DK),
MFPR_168(GPIO49, 0x030, GPIO, MMC1, NONE, MSP, NONE, XD, KP_MKOUT, NONE),
MFPR_168(GPIO50, 0x034, GPIO, I2C, NONE, MSP, CCIC, XD, KP_MKOUT, NONE),
MFPR_168(GPIO51, 0x038, GPIO, MMC1, NONE, MSP, NONE, XD, KP_MKOUT, NONE),
MFPR_168(GPIO52, 0x03C, GPIO, MMC1, NONE, MSP, NONE, XD, KP_MKOUT, NONE),
MFPR_168(GPIO53, 0x040, GPIO, MMC1, NONE, NONE, NONE, XD, KP_MKOUT, NONE),
MFPR_168(GPIO54, 0x044, GPIO, MMC1, NONE, NONE, CCIC, XD, KP_MKOUT, NONE),
MFPR_168(GPIO55, 0x048, GPIO, NONE, NONE, MSP, CCIC, XD, KP_MKOUT, NONE),
MFPR_168(GPIO56, 0x0E0, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_168(GPIO57, 0x0E4, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_168(GPIO58, 0x0E8, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_168(GPIO59, 0x0EC, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_168(GPIO60, 0x0F0, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_168(GPIO61, 0x0F4, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_168(GPIO62, 0x0F8, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_168(GPIO63, 0x0FC, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_168(GPIO64, 0x100, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_168(GPIO65, 0x104, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_168(GPIO66, 0x108, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_168(GPIO67, 0x10C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE),
MFPR_168(GPIO68, 0x110, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE),
MFPR_168(GPIO69, 0x114, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE),
MFPR_168(GPIO70, 0x118, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE),
MFPR_168(GPIO71, 0x11C, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE),
MFPR_168(GPIO72, 0x120, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE),
MFPR_168(GPIO73, 0x124, GPIO, LCD, NONE, XD, NONE, NONE, NONE, NONE),
MFPR_168(GPIO74, 0x128, GPIO, LCD, PWM, XD, NONE, NONE, NONE, NONE),
MFPR_168(GPIO75, 0x12C, GPIO, LCD, PWM, XD, ONE_WIRE, NONE, NONE, NONE),
MFPR_168(GPIO76, 0x130, GPIO, LCD, PWM, I2C, NONE, NONE, MSP_INS, NONE),
MFPR_168(GPIO77, 0x134, GPIO, LCD, PWM1, I2C, ONE_WIRE, NONE, XD, NONE),
MFPR_168(GPIO78, 0x138, GPIO, LCD, NONE, NONE, NONE, MMC4, NONE, NONE),
MFPR_168(GPIO79, 0x13C, GPIO, LCD, NONE, NONE, ONE_WIRE, MMC4, NONE, NONE),
MFPR_168(GPIO80, 0x140, GPIO, LCD, NONE, I2C, NONE, MMC4, NONE, NONE),
MFPR_168(GPIO81, 0x144, GPIO, LCD, NONE, I2C, ONE_WIRE, MMC4, NONE, NONE),
MFPR_168(GPIO82, 0x148, GPIO, LCD, PWM, NONE, NONE, MMC4, NONE, NONE),
MFPR_168(GPIO83, 0x14C, GPIO, LCD, PWM, NONE, RESET, MMC4, NONE, NONE),
MFPR_168(GPIO84, 0x150, GPIO, NONE, PWM, ONE_WIRE, PWM1, NONE, NONE, EXT_32K_IN),
MFPR_168(GPIO85, 0x154, GPIO, NONE, PWM1, NONE, NONE, NONE, NONE, USB),
MFPR_168(GPIO86, 0x158, GPIO, MMC2, UART2, NONE, JTAG, ETH_TX, SSP5_TX, SSP5),
MFPR_168(GPIO87, 0x15C, GPIO, MMC2, UART2, NONE, JTAG, ETH_TX, SSP5, SSP5_TX),
MFPR_168(GPIO88, 0x160, GPIO, MMC2, UART2, UART2_TX, JTAG, ETH_TX, ETH_RX, SSP5),
MFPR_168(GPIO89, 0x164, GPIO, MMC2, UART2_TX, UART2, JTAG, ETH_TX, ETH_RX, SSP5),
MFPR_168(GPIO90, 0x168, GPIO, MMC2, NONE, SSP3, JTAG, ETH_TX, ETH_RX, NONE),
MFPR_168(GPIO91, 0x16C, GPIO, MMC2, NONE, SSP3, SSP4, ETH_TX, ETH_RX, NONE),
MFPR_168(GPIO92, 0x170, GPIO, MMC2, NONE, SSP3, SSP3_TX, ETH, NONE, NONE),
MFPR_168(GPIO93, 0x174, GPIO, MMC2, NONE, SSP3_TX, SSP3, ETH, NONE, NONE),
MFPR_168(GPIO94, 0x178, GPIO, MMC2_CMD, SSP3, AC97_SYSCLK, AC97, ETH, NONE, NONE),
MFPR_168(GPIO95, 0x17C, GPIO, MMC2_CLK, NONE, NONE, AC97, ETH, NONE, NONE),
MFPR_168(GPIO96, 0x180, GPIO, PWM, NONE, MMC2, NONE, ETH_RX, ETH_TX, NONE),
MFPR_168(GPIO97, 0x184, GPIO, PWM, ONE_WIRE, NONE, NONE, ETH_RX, ETH_TX, NONE),
MFPR_168(GPIO98, 0x188, GPIO, PWM1, UART3_TX, UART3, NONE, ETH_RX, ETH_TX, NONE),
MFPR_168(GPIO99, 0x18C, GPIO, ONE_WIRE, UART3, UART3_TX, NONE, ETH_RX, ETH_TX, NONE),
MFPR_168(GPIO100, 0x190, GPIO, NONE, UART3_CTS, UART3, NONE, ETH, NONE, NONE),
MFPR_168(GPIO101, 0x194, GPIO, NONE, UART3, UART3_CTS, NONE, ETH, NONE, NONE),
MFPR_168(GPIO102, 0x198, GPIO, I2C, UART3, SSP4, NONE, NONE, NONE, NONE),
MFPR_168(GPIO103, 0x19C, GPIO, I2C, UART3, SSP4, SSP2, ETH, NONE, NONE),
MFPR_168(GPIO104, 0x1A0, GPIO, PWM, UART1, SSP4, SSP4_TX, AC97, KP_MKOUT, NONE),
MFPR_168(GPIO105, 0x1A4, GPIO, I2C, UART1, SSP4_TX, SSP4, AC97, KP_MKOUT, NONE),
MFPR_168(GPIO106, 0x1A8, GPIO, I2C, PWM1, AC97_SYSCLK, MMC2, NONE, KP_MKOUT, NONE),
MFPR_168(GPIO107, 0x1AC, GPIO, UART1_TX, UART1, NONE, SSP2, MSP_DAT3, NONE, KP_MKIN),
MFPR_168(GPIO108, 0x1B0, GPIO, UART1, UART1_TX, NONE, SSP2_TX, MSP, NONE, KP_MKIN),
MFPR_168(GPIO109, 0x1B4, GPIO, UART1_CTS, UART1, NONE, AC97_SYSCLK, MSP, NONE, KP_MKIN),
MFPR_168(GPIO110, 0x1B8, GPIO, UART1, UART1_CTS, NONE, SMC_RDY, MSP, NONE, KP_MKIN),
MFPR_168(GPIO111, 0x1BC, GPIO, UART1_nRI, UART1, SSP3, SSP2, MSP, XD, KP_MKOUT),
MFPR_168(GPIO112, 0x1C0, GPIO, UART1_DTR, UART1, ONE_WIRE, SSP2, MSP, XD, KP_MKOUT),
MFPR_168(GPIO113, 0x1C4, GPIO, NONE, NONE, NONE, NONE, NONE, AC97_SYSCLK, NONE),
MFPR_168(GPIO114, 0x1C8, GPIO, SSP1, NONE, NONE, NONE, NONE, AC97, NONE),
MFPR_168(GPIO115, 0x1CC, GPIO, SSP1, NONE, NONE, NONE, NONE, AC97, NONE),
MFPR_168(GPIO116, 0x1D0, GPIO, SSP1_TX, SSP1, NONE, NONE, NONE, AC97, NONE),
MFPR_168(GPIO117, 0x1D4, GPIO, SSP1, SSP1_TX, NONE, MMC2_CMD, NONE, AC97, NONE),
MFPR_168(GPIO118, 0x1D8, GPIO, SSP2, NONE, NONE, MMC2_CLK, NONE, AC97, KP_MKIN),
MFPR_168(GPIO119, 0x1DC, GPIO, SSP2, NONE, NONE, MMC2, NONE, AC97, KP_MKIN),
MFPR_168(GPIO120, 0x1E0, GPIO, SSP2, SSP2_TX, NONE, MMC2, NONE, NONE, KP_MKIN),
MFPR_168(GPIO121, 0x1E4, GPIO, SSP2_TX, SSP2, NONE, MMC2, NONE, NONE, KP_MKIN),
MFPR_168(GPIO122, 0x1E8, GPIO, AC97_SYSCLK, SSP2, PWM, MMC2, NONE, NONE, NONE),
MFPR_168(PWR_SCL, 0x1EC, PWRI2C, NONE, NONE, NONE, NONE, NONE, GPIO, MMC4),
MFPR_168(PWR_SDA, 0x1F0, PWRI2C, NONE, NONE, NONE, NONE, NONE, GPIO, NONE),
MFPR_168(TDI, 0x1F4, JTAG, PWM1, UART2, MMC4, SSP5, NONE, XD, MMC4),
MFPR_168(TMS, 0x1F8, JTAG, PWM, UART2, NONE, SSP5, NONE, XD, MMC4),
MFPR_168(TCK, 0x1FC, JTAG, PWM, UART2, UART2_TX, SSP5, NONE, XD, MMC4),
MFPR_168(TDO, 0x200, JTAG, PWM, UART2_TX, UART2, SSP5_TX, NONE, XD, MMC4),
MFPR_168(TRST, 0x204, JTAG, ONE_WIRE, SSP2, SSP3, AC97_SYSCLK, NONE, XD, MMC4),
MFPR_168(WAKEUP, 0x208, WAKEUP, ONE_WIRE, PWM1, PWM, SSP2, NONE, GPIO, MMC4),
};
static const unsigned p168_jtag_pin1[] = {TDI, TMS, TCK, TDO, TRST};
static const unsigned p168_wakeup_pin1[] = {WAKEUP};
static const unsigned p168_ssp1rx_pin1[] = {GPIO114, GPIO115, GPIO116};
static const unsigned p168_ssp1tx_pin1[] = {GPIO117};
static const unsigned p168_ssp4rx_pin1[] = {GPIO102, GPIO103, GPIO104};
static const unsigned p168_ssp4tx_pin1[] = {GPIO105};
static const unsigned p168_ssp5rx_pin1[] = {GPIO86, GPIO88, GPIO89};
static const unsigned p168_ssp5tx_pin1[] = {GPIO87};
static const unsigned p168_i2c_pin1[] = {GPIO105, GPIO106};
static const unsigned p168_pwri2c_pin1[] = {PWR_SCL, PWR_SDA};
static const unsigned p168_mmc1_pin1[] = {GPIO40, GPIO41, GPIO43, GPIO46,
GPIO49, GPIO51, GPIO52, GPIO53};
static const unsigned p168_mmc2_data_pin1[] = {GPIO90, GPIO91, GPIO92, GPIO93};
static const unsigned p168_mmc2_cmd_pin1[] = {GPIO94};
static const unsigned p168_mmc2_clk_pin1[] = {GPIO95};
static const unsigned p168_mmc3_data_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3,
GPIO4, GPIO5, GPIO6, GPIO7};
static const unsigned p168_mmc3_cmd_pin1[] = {GPIO9};
static const unsigned p168_mmc3_clk_pin1[] = {GPIO8};
static const unsigned p168_eth_pin1[] = {GPIO92, GPIO93, GPIO100, GPIO101,
GPIO103};
static const unsigned p168_ethtx_pin1[] = {GPIO86, GPIO87, GPIO88, GPIO89,
GPIO90, GPIO91};
static const unsigned p168_ethrx_pin1[] = {GPIO94, GPIO95, GPIO96, GPIO97,
GPIO98, GPIO99};
static const unsigned p168_uart1rx_pin1[] = {GPIO107};
static const unsigned p168_uart1tx_pin1[] = {GPIO108};
static const unsigned p168_uart3rx_pin1[] = {GPIO98, GPIO100, GPIO101};
static const unsigned p168_uart3tx_pin1[] = {GPIO99};
static const unsigned p168_msp_pin1[] = {GPIO40, GPIO41, GPIO42, GPIO43,
GPIO44, GPIO50};
static const unsigned p168_ccic_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40,
GPIO41, GPIO42, GPIO44, GPIO45, GPIO46, GPIO48, GPIO54, GPIO55};
static const unsigned p168_xd_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40,
GPIO41, GPIO42, GPIO44, GPIO45, GPIO47, GPIO48, GPIO49, GPIO50,
GPIO51, GPIO52};
static const unsigned p168_lcd_pin1[] = {GPIO56, GPIO57, GPIO58, GPIO59,
GPIO60, GPIO61, GPIO62, GPIO63, GPIO64, GPIO65, GPIO66, GPIO67,
GPIO68, GPIO69, GPIO70, GPIO71, GPIO72, GPIO73, GPIO74, GPIO75,
GPIO76, GPIO77, GPIO78, GPIO79, GPIO80, GPIO81, GPIO82, GPIO83};
static const unsigned p168_dfio_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3,
GPIO4, GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12,
GPIO13, GPIO14, GPIO15};
static const unsigned p168_nand_pin1[] = {GPIO16, GPIO17, GPIO21, GPIO22,
GPIO24, GPIO26};
static const unsigned p168_smc_pin1[] = {GPIO23, GPIO25, GPIO29, GPIO35,
GPIO36};
static const unsigned p168_smccs0_pin1[] = {GPIO18};
static const unsigned p168_smccs1_pin1[] = {GPIO34};
static const unsigned p168_smcrdy_pin1[] = {GPIO28};
static const unsigned p168_ac97sysclk_pin1[] = {GPIO113};
static const unsigned p168_ac97_pin1[] = {GPIO114, GPIO115, GPIO117, GPIO118,
GPIO119};
static const unsigned p168_cf_pin1[] = {GPIO19, GPIO20, GPIO23, GPIO25,
GPIO28, GPIO29, GPIO30, GPIO31, GPIO32, GPIO33, GPIO34, GPIO35,
GPIO36};
static const unsigned p168_kpmkin_pin1[] = {GPIO109, GPIO110, GPIO121};
static const unsigned p168_kpmkout_pin1[] = {GPIO111, GPIO112};
static const unsigned p168_gpio86_pin1[] = {WAKEUP};
static const unsigned p168_gpio86_pin2[] = {GPIO86};
static const unsigned p168_gpio87_pin1[] = {GPIO87};
static const unsigned p168_gpio87_pin2[] = {PWR_SDA};
static const unsigned p168_gpio88_pin1[] = {GPIO88};
static const unsigned p168_gpio88_pin2[] = {PWR_SCL};
static struct pxa3xx_pin_group pxa168_grps[] = {
GRP_168("uart1rx-1", UART1, p168_uart1rx_pin1),
GRP_168("uart1tx-1", UART1_TX, p168_uart1tx_pin1),
GRP_168("uart3rx-1", UART3, p168_uart3rx_pin1),
GRP_168("uart3tx-1", UART3_TX, p168_uart3tx_pin1),
GRP_168("ssp1rx-1", SSP1, p168_ssp1rx_pin1),
GRP_168("ssp1tx-1", SSP1_TX, p168_ssp1tx_pin1),
GRP_168("ssp4rx-1", SSP4, p168_ssp4rx_pin1),
GRP_168("ssp4tx-1", SSP4_TX, p168_ssp4tx_pin1),
GRP_168("ssp5rx-1", SSP5, p168_ssp5rx_pin1),
GRP_168("ssp5tx-1", SSP5_TX, p168_ssp5tx_pin1),
GRP_168("jtag", JTAG, p168_jtag_pin1),
GRP_168("wakeup", WAKEUP, p168_wakeup_pin1),
GRP_168("i2c", I2C, p168_i2c_pin1),
GRP_168("pwri2c", PWRI2C, p168_pwri2c_pin1),
GRP_168("mmc1 8p1", MMC1, p168_mmc1_pin1),
GRP_168("mmc2 4p1", MMC2, p168_mmc2_data_pin1),
GRP_168("mmc2 cmd1", MMC2_CMD, p168_mmc2_cmd_pin1),
GRP_168("mmc2 clk1", MMC2_CLK, p168_mmc2_clk_pin1),
GRP_168("mmc3 8p1", MMC3, p168_mmc3_data_pin1),
GRP_168("mmc3 cmd1", MMC3_CMD, p168_mmc3_cmd_pin1),
GRP_168("mmc3 clk1", MMC3_CLK, p168_mmc3_clk_pin1),
GRP_168("eth", ETH, p168_eth_pin1),
GRP_168("eth rx", ETH_RX, p168_ethrx_pin1),
GRP_168("eth tx", ETH_TX, p168_ethtx_pin1),
GRP_168("msp", MSP, p168_msp_pin1),
GRP_168("ccic", CCIC, p168_ccic_pin1),
GRP_168("xd", XD, p168_xd_pin1),
GRP_168("lcd", LCD, p168_lcd_pin1),
GRP_168("dfio", DFIO, p168_dfio_pin1),
GRP_168("nand", NAND, p168_nand_pin1),
GRP_168("smc", SMC, p168_smc_pin1),
GRP_168("smc cs0", SMC_CS0, p168_smccs0_pin1),
GRP_168("smc cs1", SMC_CS1, p168_smccs1_pin1),
GRP_168("smc rdy", SMC_RDY, p168_smcrdy_pin1),
GRP_168("ac97 sysclk", AC97_SYSCLK, p168_ac97sysclk_pin1),
GRP_168("ac97", AC97, p168_ac97_pin1),
GRP_168("cf", CF, p168_cf_pin1),
GRP_168("kp mkin 3p1", KP_MKIN, p168_kpmkin_pin1),
GRP_168("kp mkout 2p1", KP_MKOUT, p168_kpmkout_pin1),
GRP_168("gpio86-1", GPIO, p168_gpio86_pin1),
GRP_168("gpio86-2", GPIO, p168_gpio86_pin2),
GRP_168("gpio87-1", GPIO, p168_gpio87_pin1),
GRP_168("gpio87-2", GPIO, p168_gpio87_pin2),
GRP_168("gpio88-1", GPIO, p168_gpio88_pin1),
GRP_168("gpio88-2", GPIO, p168_gpio88_pin2),
};
static const char * const p168_uart1rx_grps[] = {"uart1rx-1"};
static const char * const p168_uart1tx_grps[] = {"uart1tx-1"};
static const char * const p168_uart3rx_grps[] = {"uart3rx-1"};
static const char * const p168_uart3tx_grps[] = {"uart3tx-1"};
static const char * const p168_ssp1rx_grps[] = {"ssp1rx-1"};
static const char * const p168_ssp1tx_grps[] = {"ssp1tx-1"};
static const char * const p168_ssp4rx_grps[] = {"ssp4rx-1"};
static const char * const p168_ssp4tx_grps[] = {"ssp4tx-1"};
static const char * const p168_ssp5rx_grps[] = {"ssp5rx-1"};
static const char * const p168_ssp5tx_grps[] = {"ssp5tx-1"};
static const char * const p168_i2c_grps[] = {"i2c"};
static const char * const p168_pwri2c_grps[] = {"pwri2c"};
static const char * const p168_mmc1_grps[] = {"mmc1 8p1"};
static const char * const p168_mmc2_data_grps[] = {"mmc2 4p1"};
static const char * const p168_mmc2_cmd_grps[] = {"mmc2 cmd1"};
static const char * const p168_mmc2_clk_grps[] = {"mmc2 clk1"};
static const char * const p168_mmc3_data_grps[] = {"mmc3 8p1"};
static const char * const p168_mmc3_cmd_grps[] = {"mmc3 cmd1"};
static const char * const p168_mmc3_clk_grps[] = {"mmc3 clk1"};
static const char * const p168_eth_grps[] = {"eth"};
static const char * const p168_ethrx_grps[] = {"eth rx"};
static const char * const p168_ethtx_grps[] = {"eth tx"};
static const char * const p168_msp_grps[] = {"msp"};
static const char * const p168_ccic_grps[] = {"ccic"};
static const char * const p168_xd_grps[] = {"xd"};
static const char * const p168_lcd_grps[] = {"lcd"};
static const char * const p168_dfio_grps[] = {"dfio"};
static const char * const p168_nand_grps[] = {"nand"};
static const char * const p168_smc_grps[] = {"smc"};
static const char * const p168_smccs0_grps[] = {"smc cs0"};
static const char * const p168_smccs1_grps[] = {"smc cs1"};
static const char * const p168_smcrdy_grps[] = {"smc rdy"};
static const char * const p168_ac97sysclk_grps[] = {"ac97 sysclk"};
static const char * const p168_ac97_grps[] = {"ac97"};
static const char * const p168_cf_grps[] = {"cf"};
static const char * const p168_kpmkin_grps[] = {"kp mkin 3p1"};
static const char * const p168_kpmkout_grps[] = {"kp mkout 2p1"};
static const char * const p168_gpio86_grps[] = {"gpio86-1", "gpio86-2"};
static const char * const p168_gpio87_grps[] = {"gpio87-1", "gpio87-2"};
static const char * const p168_gpio88_grps[] = {"gpio88-1", "gpio88-2"};
static struct pxa3xx_pmx_func pxa168_funcs[] = {
{"uart1 rx", ARRAY_AND_SIZE(p168_uart1rx_grps)},
{"uart1 tx", ARRAY_AND_SIZE(p168_uart1tx_grps)},
{"uart3 rx", ARRAY_AND_SIZE(p168_uart3rx_grps)},
{"uart3 tx", ARRAY_AND_SIZE(p168_uart3tx_grps)},
{"ssp1 rx", ARRAY_AND_SIZE(p168_ssp1rx_grps)},
{"ssp1 tx", ARRAY_AND_SIZE(p168_ssp1tx_grps)},
{"ssp4 rx", ARRAY_AND_SIZE(p168_ssp4rx_grps)},
{"ssp4 tx", ARRAY_AND_SIZE(p168_ssp4tx_grps)},
{"ssp5 rx", ARRAY_AND_SIZE(p168_ssp5rx_grps)},
{"ssp5 tx", ARRAY_AND_SIZE(p168_ssp5tx_grps)},
{"i2c", ARRAY_AND_SIZE(p168_i2c_grps)},
{"pwri2c", ARRAY_AND_SIZE(p168_pwri2c_grps)},
{"mmc1", ARRAY_AND_SIZE(p168_mmc1_grps)},
{"mmc2", ARRAY_AND_SIZE(p168_mmc2_data_grps)},
{"mmc2 cmd", ARRAY_AND_SIZE(p168_mmc2_cmd_grps)},
{"mmc2 clk", ARRAY_AND_SIZE(p168_mmc2_clk_grps)},
{"mmc3", ARRAY_AND_SIZE(p168_mmc3_data_grps)},
{"mmc3 cmd", ARRAY_AND_SIZE(p168_mmc3_cmd_grps)},
{"mmc3 clk", ARRAY_AND_SIZE(p168_mmc3_clk_grps)},
{"eth", ARRAY_AND_SIZE(p168_eth_grps)},
{"eth rx", ARRAY_AND_SIZE(p168_ethrx_grps)},
{"eth tx", ARRAY_AND_SIZE(p168_ethtx_grps)},
{"msp", ARRAY_AND_SIZE(p168_msp_grps)},
{"ccic", ARRAY_AND_SIZE(p168_ccic_grps)},
{"xd", ARRAY_AND_SIZE(p168_xd_grps)},
{"lcd", ARRAY_AND_SIZE(p168_lcd_grps)},
{"dfio", ARRAY_AND_SIZE(p168_dfio_grps)},
{"nand", ARRAY_AND_SIZE(p168_nand_grps)},
{"smc", ARRAY_AND_SIZE(p168_smc_grps)},
{"smc cs0", ARRAY_AND_SIZE(p168_smccs0_grps)},
{"smc cs1", ARRAY_AND_SIZE(p168_smccs1_grps)},
{"smc rdy", ARRAY_AND_SIZE(p168_smcrdy_grps)},
{"ac97", ARRAY_AND_SIZE(p168_ac97_grps)},
{"ac97 sysclk", ARRAY_AND_SIZE(p168_ac97sysclk_grps)},
{"cf", ARRAY_AND_SIZE(p168_cf_grps)},
{"kpmkin", ARRAY_AND_SIZE(p168_kpmkin_grps)},
{"kpmkout", ARRAY_AND_SIZE(p168_kpmkout_grps)},
{"gpio86", ARRAY_AND_SIZE(p168_gpio86_grps)},
{"gpio87", ARRAY_AND_SIZE(p168_gpio87_grps)},
{"gpio88", ARRAY_AND_SIZE(p168_gpio88_grps)},
};
static struct pinctrl_desc pxa168_pctrl_desc = {
.name = "pxa168-pinctrl",
.owner = THIS_MODULE,
};
static struct pxa3xx_pinmux_info pxa168_info = {
.mfp = pxa168_mfp,
.num_mfp = ARRAY_SIZE(pxa168_mfp),
.grps = pxa168_grps,
.num_grps = ARRAY_SIZE(pxa168_grps),
.funcs = pxa168_funcs,
.num_funcs = ARRAY_SIZE(pxa168_funcs),
.num_gpio = 128,
.desc = &pxa168_pctrl_desc,
.pads = pxa168_pads,
.num_pads = ARRAY_SIZE(pxa168_pads),
.cputype = PINCTRL_PXA168,
.ds_mask = PXA168_DS_MASK,
.ds_shift = PXA168_DS_SHIFT,
};
static int __devinit pxa168_pinmux_probe(struct platform_device *pdev)
{
return pxa3xx_pinctrl_register(pdev, &pxa168_info);
}
static int __devexit pxa168_pinmux_remove(struct platform_device *pdev)
{
return pxa3xx_pinctrl_unregister(pdev);
}
static struct platform_driver pxa168_pinmux_driver = {
.driver = {
.name = "pxa168-pinmux",
.owner = THIS_MODULE,
},
.probe = pxa168_pinmux_probe,
.remove = __devexit_p(pxa168_pinmux_remove),
};
static int __init pxa168_pinmux_init(void)
{
return platform_driver_register(&pxa168_pinmux_driver);
}
core_initcall_sync(pxa168_pinmux_init);
static void __exit pxa168_pinmux_exit(void)
{
platform_driver_unregister(&pxa168_pinmux_driver);
}
module_exit(pxa168_pinmux_exit);
MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
MODULE_DESCRIPTION("PXA3xx pin control driver");
MODULE_LICENSE("GPL v2");

View File

@ -0,0 +1,244 @@
/*
* linux/drivers/pinctrl/pinctrl-pxa3xx.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* publishhed by the Free Software Foundation.
*
* Copyright (C) 2011, Marvell Technology Group Ltd.
*
* Author: Haojian Zhuang <haojian.zhuang@marvell.com>
*
*/
#include <linux/module.h>
#include <linux/device.h>
#include <linux/io.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include "pinctrl-pxa3xx.h"
static struct pinctrl_gpio_range pxa3xx_pinctrl_gpio_range = {
.name = "PXA3xx GPIO",
.id = 0,
.base = 0,
.pin_base = 0,
};
static int pxa3xx_list_groups(struct pinctrl_dev *pctrldev, unsigned selector)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
if (selector >= info->num_grps)
return -EINVAL;
return 0;
}
static const char *pxa3xx_get_group_name(struct pinctrl_dev *pctrldev,
unsigned selector)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
if (selector >= info->num_grps)
return NULL;
return info->grps[selector].name;
}
static int pxa3xx_get_group_pins(struct pinctrl_dev *pctrldev,
unsigned selector,
const unsigned **pins,
unsigned *num_pins)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
if (selector >= info->num_grps)
return -EINVAL;
*pins = info->grps[selector].pins;
*num_pins = info->grps[selector].npins;
return 0;
}
static struct pinctrl_ops pxa3xx_pctrl_ops = {
.list_groups = pxa3xx_list_groups,
.get_group_name = pxa3xx_get_group_name,
.get_group_pins = pxa3xx_get_group_pins,
};
static int pxa3xx_pmx_list_func(struct pinctrl_dev *pctrldev, unsigned func)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
if (func >= info->num_funcs)
return -EINVAL;
return 0;
}
static const char *pxa3xx_pmx_get_func_name(struct pinctrl_dev *pctrldev,
unsigned func)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
return info->funcs[func].name;
}
static int pxa3xx_pmx_get_groups(struct pinctrl_dev *pctrldev, unsigned func,
const char * const **groups,
unsigned * const num_groups)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
*groups = info->funcs[func].groups;
*num_groups = info->funcs[func].num_groups;
return 0;
}
/* Return function number. If failure, return negative value. */
static int match_mux(struct pxa3xx_mfp_pin *mfp, unsigned mux)
{
int i;
for (i = 0; i < PXA3xx_MAX_MUX; i++) {
if (mfp->func[i] == mux)
break;
}
if (i >= PXA3xx_MAX_MUX)
return -EINVAL;
return i;
}
/* check whether current pin configuration is valid. Negative for failure */
static int match_group_mux(struct pxa3xx_pin_group *grp,
struct pxa3xx_pinmux_info *info,
unsigned mux)
{
int i, pin, ret = 0;
for (i = 0; i < grp->npins; i++) {
pin = grp->pins[i];
ret = match_mux(&info->mfp[pin], mux);
if (ret < 0) {
dev_err(info->dev, "Can't find mux %d on pin%d\n",
mux, pin);
break;
}
}
return ret;
}
static int pxa3xx_pmx_enable(struct pinctrl_dev *pctrldev, unsigned func,
unsigned group)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
struct pxa3xx_pin_group *pin_grp = &info->grps[group];
unsigned int data;
int i, mfpr, pin, pin_func;
if (!pin_grp->npins ||
(match_group_mux(pin_grp, info, pin_grp->mux) < 0)) {
dev_err(info->dev, "Failed to set the pin group: %d\n", group);
return -EINVAL;
}
for (i = 0; i < pin_grp->npins; i++) {
pin = pin_grp->pins[i];
pin_func = match_mux(&info->mfp[pin], pin_grp->mux);
mfpr = info->mfp[pin].mfpr;
data = readl_relaxed(info->virt_base + mfpr);
data &= ~MFPR_FUNC_MASK;
data |= pin_func;
writel_relaxed(data, info->virt_base + mfpr);
}
return 0;
}
static void pxa3xx_pmx_disable(struct pinctrl_dev *pctrldev, unsigned func,
unsigned group)
{
}
static int pxa3xx_pmx_request_gpio(struct pinctrl_dev *pctrldev,
struct pinctrl_gpio_range *range,
unsigned pin)
{
struct pxa3xx_pinmux_info *info = pinctrl_dev_get_drvdata(pctrldev);
unsigned int data;
int pin_func, mfpr;
pin_func = match_mux(&info->mfp[pin], PXA3xx_MUX_GPIO);
if (pin_func < 0) {
dev_err(info->dev, "No GPIO function on pin%d (%s)\n",
pin, info->pads[pin].name);
return -EINVAL;
}
mfpr = info->mfp[pin].mfpr;
/* write gpio function into mfpr register */
data = readl_relaxed(info->virt_base + mfpr) & ~MFPR_FUNC_MASK;
data |= pin_func;
writel_relaxed(data, info->virt_base + mfpr);
return 0;
}
static struct pinmux_ops pxa3xx_pmx_ops = {
.list_functions = pxa3xx_pmx_list_func,
.get_function_name = pxa3xx_pmx_get_func_name,
.get_function_groups = pxa3xx_pmx_get_groups,
.enable = pxa3xx_pmx_enable,
.disable = pxa3xx_pmx_disable,
.gpio_request_enable = pxa3xx_pmx_request_gpio,
};
int pxa3xx_pinctrl_register(struct platform_device *pdev,
struct pxa3xx_pinmux_info *info)
{
struct pinctrl_desc *desc;
struct resource *res;
int ret = 0;
if (!info || !info->cputype)
return -EINVAL;
desc = info->desc;
desc->pins = info->pads;
desc->npins = info->num_pads;
desc->pctlops = &pxa3xx_pctrl_ops;
desc->pmxops = &pxa3xx_pmx_ops;
info->dev = &pdev->dev;
pxa3xx_pinctrl_gpio_range.npins = info->num_gpio;
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res)
return -ENOENT;
info->phy_base = res->start;
info->phy_size = resource_size(res);
info->virt_base = ioremap(info->phy_base, info->phy_size);
if (!info->virt_base)
return -ENOMEM;
info->pctrl = pinctrl_register(desc, &pdev->dev, info);
if (!info->pctrl) {
dev_err(&pdev->dev, "failed to register PXA pinmux driver\n");
ret = -EINVAL;
goto err;
}
pinctrl_add_gpio_range(info->pctrl, &pxa3xx_pinctrl_gpio_range);
platform_set_drvdata(pdev, info);
return 0;
err:
iounmap(info->virt_base);
return ret;
}
int pxa3xx_pinctrl_unregister(struct platform_device *pdev)
{
struct pxa3xx_pinmux_info *info = platform_get_drvdata(pdev);
pinctrl_unregister(info->pctrl);
iounmap(info->virt_base);
platform_set_drvdata(pdev, NULL);
return 0;
}
static int __init pxa3xx_pinctrl_init(void)
{
pr_info("pxa3xx-pinctrl: PXA3xx pinctrl driver initializing\n");
return 0;
}
core_initcall_sync(pxa3xx_pinctrl_init);
static void __exit pxa3xx_pinctrl_exit(void)
{
}
module_exit(pxa3xx_pinctrl_exit);
MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
MODULE_DESCRIPTION("PXA3xx pin control driver");
MODULE_LICENSE("GPL v2");

View File

@ -0,0 +1,264 @@
/*
* linux/drivers/pinctrl/pinctrl-pxa3xx.h
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* publishhed by the Free Software Foundation.
*
* Copyright (C) 2011, Marvell Technology Group Ltd.
*
* Author: Haojian Zhuang <haojian.zhuang@marvell.com>
*
*/
#ifndef __PINCTRL_PXA3XX_H
#include <linux/pinctrl/pinctrl.h>
#include <linux/pinctrl/pinmux.h>
#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x)
#define PXA3xx_MUX_GPIO 0
#define PXA3xx_MAX_MUX 8
#define MFPR_FUNC_MASK 0x7
enum pxa_cpu_type {
PINCTRL_INVALID = 0,
PINCTRL_PXA300,
PINCTRL_PXA310,
PINCTRL_PXA320,
PINCTRL_PXA168,
PINCTRL_PXA910,
PINCTRL_PXA930,
PINCTRL_PXA955,
PINCTRL_MMP2,
PINCTRL_MAX,
};
struct pxa3xx_mfp_pin {
const char *name;
const unsigned int pin;
const unsigned int mfpr; /* register offset */
const unsigned short func[8];
};
struct pxa3xx_pin_group {
const char *name;
const unsigned mux;
const unsigned *pins;
const unsigned npins;
};
struct pxa3xx_pmx_func {
const char *name;
const char * const * groups;
const unsigned num_groups;
};
struct pxa3xx_pinmux_info {
struct device *dev;
struct pinctrl_dev *pctrl;
enum pxa_cpu_type cputype;
unsigned int phy_base;
unsigned int phy_size;
void __iomem *virt_base;
struct pxa3xx_mfp_pin *mfp;
unsigned int num_mfp;
struct pxa3xx_pin_group *grps;
unsigned int num_grps;
struct pxa3xx_pmx_func *funcs;
unsigned int num_funcs;
unsigned int num_gpio;
struct pinctrl_desc *desc;
struct pinctrl_pin_desc *pads;
unsigned int num_pads;
unsigned ds_mask; /* drive strength mask */
unsigned ds_shift; /* drive strength shift */
unsigned slp_mask; /* sleep mask */
unsigned slp_input_low;
unsigned slp_input_high;
unsigned slp_output_low;
unsigned slp_output_high;
unsigned slp_float;
};
enum pxa3xx_pin_list {
GPIO0 = 0,
GPIO1,
GPIO2,
GPIO3,
GPIO4,
GPIO5,
GPIO6,
GPIO7,
GPIO8,
GPIO9,
GPIO10, /* 10 */
GPIO11,
GPIO12,
GPIO13,
GPIO14,
GPIO15,
GPIO16,
GPIO17,
GPIO18,
GPIO19,
GPIO20, /* 20 */
GPIO21,
GPIO22,
GPIO23,
GPIO24,
GPIO25,
GPIO26,
GPIO27,
GPIO28,
GPIO29,
GPIO30, /* 30 */
GPIO31,
GPIO32,
GPIO33,
GPIO34,
GPIO35,
GPIO36,
GPIO37,
GPIO38,
GPIO39,
GPIO40, /* 40 */
GPIO41,
GPIO42,
GPIO43,
GPIO44,
GPIO45,
GPIO46,
GPIO47,
GPIO48,
GPIO49,
GPIO50, /* 50 */
GPIO51,
GPIO52,
GPIO53,
GPIO54,
GPIO55,
GPIO56,
GPIO57,
GPIO58,
GPIO59,
GPIO60, /* 60 */
GPIO61,
GPIO62,
GPIO63,
GPIO64,
GPIO65,
GPIO66,
GPIO67,
GPIO68,
GPIO69,
GPIO70, /* 70 */
GPIO71,
GPIO72,
GPIO73,
GPIO74,
GPIO75,
GPIO76,
GPIO77,
GPIO78,
GPIO79,
GPIO80, /* 80 */
GPIO81,
GPIO82,
GPIO83,
GPIO84,
GPIO85,
GPIO86,
GPIO87,
GPIO88,
GPIO89,
GPIO90, /* 90 */
GPIO91,
GPIO92,
GPIO93,
GPIO94,
GPIO95,
GPIO96,
GPIO97,
GPIO98,
GPIO99,
GPIO100, /* 100 */
GPIO101,
GPIO102,
GPIO103,
GPIO104,
GPIO105,
GPIO106,
GPIO107,
GPIO108,
GPIO109,
GPIO110, /* 110 */
GPIO111,
GPIO112,
GPIO113,
GPIO114,
GPIO115,
GPIO116,
GPIO117,
GPIO118,
GPIO119,
GPIO120, /* 120 */
GPIO121,
GPIO122,
GPIO123,
GPIO124,
GPIO125,
GPIO126,
GPIO127,
GPIO128,
GPIO129,
GPIO130, /* 130 */
GPIO131,
GPIO132,
GPIO133,
GPIO134,
GPIO135,
GPIO136,
GPIO137,
GPIO138,
GPIO139,
GPIO140, /* 140 */
GPIO141,
GPIO142,
GPIO143,
GPIO144,
GPIO145,
GPIO146,
GPIO147,
GPIO148,
GPIO149,
GPIO150, /* 150 */
GPIO151,
GPIO152,
GPIO153,
GPIO154,
GPIO155,
GPIO156,
GPIO157,
GPIO158,
GPIO159,
GPIO160, /* 160 */
GPIO161,
GPIO162,
GPIO163,
GPIO164,
GPIO165,
GPIO166,
GPIO167,
GPIO168,
GPIO169,
};
extern int pxa3xx_pinctrl_register(struct platform_device *pdev,
struct pxa3xx_pinmux_info *info);
extern int pxa3xx_pinctrl_unregister(struct platform_device *pdev);
#endif /* __PINCTRL_PXA3XX_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,559 @@
/*
* 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);

View File

@ -0,0 +1,163 @@
/*
* 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

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -19,6 +19,9 @@
#include <linux/err.h>
#include <linux/pinctrl/pinctrl.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
@ -162,7 +165,7 @@
#define U300_SYSCON_PMC4R_APP_MISC_16_APP_UART1_CTS 0x0100
#define U300_SYSCON_PMC4R_APP_MISC_16_EMIF_1_STATIC_CS5_N 0x0200
#define DRIVER_NAME "pinmux-u300"
#define DRIVER_NAME "pinctrl-u300"
/*
* The DB3350 has 467 pads, I have enumerated the pads clockwise around the
@ -1044,22 +1047,82 @@ static struct pinctrl_gpio_range u300_gpio_ranges[] = {
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 = {
.name = DRIVER_NAME,
.pins = u300_pads,
.npins = ARRAY_SIZE(u300_pads),
.pctlops = &u300_pctrl_ops,
.pmxops = &u300_pmx_ops,
.confops = &u300_pconf_ops,
.owner = THIS_MODULE,
};
static int __init u300_pmx_probe(struct platform_device *pdev)
static int __devinit u300_pmx_probe(struct platform_device *pdev)
{
struct u300_pmx *upmx;
struct resource *res;
struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev);
int ret;
int i;
pr_err("U300 PMX PROBE\n");
/* Create state holders etc for this driver */
upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL);
if (!upmx)
@ -1095,12 +1158,14 @@ static int __init u300_pmx_probe(struct platform_device *pdev)
}
/* We will handle a range of GPIO pins */
for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++)
for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) {
u300_gpio_ranges[i].gc = gpio_chip;
pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]);
}
platform_set_drvdata(pdev, upmx);
dev_info(&pdev->dev, "initialized U300 pinmux driver\n");
dev_info(&pdev->dev, "initialized U300 pin control driver\n");
return 0;
@ -1115,7 +1180,7 @@ out_no_resource:
return ret;
}
static int __exit u300_pmx_remove(struct platform_device *pdev)
static int __devexit u300_pmx_remove(struct platform_device *pdev)
{
struct u300_pmx *upmx = platform_get_drvdata(pdev);
int i;
@ -1136,12 +1201,13 @@ static struct platform_driver u300_pmx_driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
},
.remove = __exit_p(u300_pmx_remove),
.probe = u300_pmx_probe,
.remove = __devexit_p(u300_pmx_remove),
};
static int __init u300_pmx_init(void)
{
return platform_driver_probe(&u300_pmx_driver, u300_pmx_probe);
return platform_driver_register(&u300_pmx_driver);
}
arch_initcall(u300_pmx_init);

File diff suppressed because it is too large Load Diff

View File

@ -13,11 +13,29 @@
#ifdef CONFIG_PINMUX
int pinmux_check_ops(struct pinctrl_dev *pctldev);
int pinmux_validate_map(struct pinctrl_map const *map, int i);
int pinmux_request_gpio(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned pin, unsigned gpio);
void pinmux_free_gpio(struct pinctrl_dev *pctldev, unsigned pin,
struct pinctrl_gpio_range *range);
int pinmux_gpio_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned pin, bool input);
int pinmux_map_to_setting(struct pinctrl_map const *map,
struct pinctrl_setting *setting);
void pinmux_free_setting(struct pinctrl_setting const *setting);
int pinmux_enable_setting(struct pinctrl_setting const *setting);
void pinmux_disable_setting(struct pinctrl_setting const *setting);
void pinmux_show_map(struct seq_file *s, struct pinctrl_map const *map);
void pinmux_show_setting(struct seq_file *s,
struct pinctrl_setting const *setting);
void pinmux_init_device_debugfs(struct dentry *devroot,
struct pinctrl_dev *pctldev);
void pinmux_init_debugfs(struct dentry *subsys_root);
int pinmux_hog_maps(struct pinctrl_dev *pctldev);
void pinmux_unhog_maps(struct pinctrl_dev *pctldev);
#else
@ -26,22 +44,64 @@ static inline int pinmux_check_ops(struct pinctrl_dev *pctldev)
return 0;
}
static inline int pinmux_validate_map(struct pinctrl_map const *map, int i)
{
return 0;
}
static inline int pinmux_request_gpio(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned pin, unsigned gpio)
{
return 0;
}
static inline void pinmux_free_gpio(struct pinctrl_dev *pctldev,
unsigned pin,
struct pinctrl_gpio_range *range)
{
}
static inline int pinmux_gpio_direction(struct pinctrl_dev *pctldev,
struct pinctrl_gpio_range *range,
unsigned pin, bool input)
{
return 0;
}
static inline int pinmux_map_to_setting(struct pinctrl_map const *map,
struct pinctrl_setting *setting)
{
return 0;
}
static inline void pinmux_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)
{
}
static inline void pinmux_init_debugfs(struct dentry *subsys_root)
{
}
static inline int pinmux_hog_maps(struct pinctrl_dev *pctldev)
{
return 0;
}
static inline void pinmux_unhog_maps(struct pinctrl_dev *pctldev)
{
}
#endif

View File

@ -22,7 +22,7 @@
#include <linux/io.h>
#include <asm/irq.h>
#include <asm/mach/irq.h>
#include <linux/pinctrl/pinmux.h>
#include <linux/pinctrl/consumer.h>
#include "sirfsoc_uart.h"
@ -673,12 +673,10 @@ int sirfsoc_uart_probe(struct platform_device *pdev)
port->irq = res->start;
if (sirfport->hw_flow_ctrl) {
sirfport->pmx = pinmux_get(&pdev->dev, NULL);
ret = IS_ERR(sirfport->pmx);
sirfport->p = pinctrl_get_select_default(&pdev->dev);
ret = IS_ERR(sirfport->p);
if (ret)
goto pmx_err;
pinmux_enable(sirfport->pmx);
goto pin_err;
}
port->ops = &sirfsoc_uart_ops;
@ -695,11 +693,9 @@ int sirfsoc_uart_probe(struct platform_device *pdev)
port_err:
platform_set_drvdata(pdev, NULL);
if (sirfport->hw_flow_ctrl) {
pinmux_disable(sirfport->pmx);
pinmux_put(sirfport->pmx);
}
pmx_err:
if (sirfport->hw_flow_ctrl)
pinctrl_put(sirfport->p);
pin_err:
irq_err:
devm_iounmap(&pdev->dev, port->membase);
err:
@ -711,10 +707,8 @@ static int sirfsoc_uart_remove(struct platform_device *pdev)
struct sirfsoc_uart_port *sirfport = platform_get_drvdata(pdev);
struct uart_port *port = &sirfport->port;
platform_set_drvdata(pdev, NULL);
if (sirfport->hw_flow_ctrl) {
pinmux_disable(sirfport->pmx);
pinmux_put(sirfport->pmx);
}
if (sirfport->hw_flow_ctrl)
pinctrl_put(sirfport->p);
devm_iounmap(&pdev->dev, port->membase);
uart_remove_one_port(&sirfsoc_uart_drv, port);
return 0;

View File

@ -162,7 +162,7 @@ struct sirfsoc_uart_port {
unsigned char ms_enabled;
struct uart_port port;
struct pinmux *pmx;
struct pinctrl *p;
};
/* Hardware Flow Control */

View File

@ -0,0 +1,159 @@
/*
* Consumer interface the pin control subsystem
*
* Copyright (C) 2012 ST-Ericsson SA
* Written on behalf of Linaro for ST-Ericsson
* Based on bits of regulator core, gpio core and clk core
*
* Author: Linus Walleij <linus.walleij@linaro.org>
*
* License terms: GNU General Public License (GPL) version 2
*/
#ifndef __LINUX_PINCTRL_CONSUMER_H
#define __LINUX_PINCTRL_CONSUMER_H
#include <linux/err.h>
#include <linux/list.h>
#include <linux/seq_file.h>
#include "pinctrl-state.h"
/* This struct is private to the core and should be regarded as a cookie */
struct pinctrl;
struct pinctrl_state;
#ifdef CONFIG_PINCTRL
/* External interface to pin control */
extern int pinctrl_request_gpio(unsigned gpio);
extern void pinctrl_free_gpio(unsigned gpio);
extern int pinctrl_gpio_direction_input(unsigned gpio);
extern int pinctrl_gpio_direction_output(unsigned gpio);
extern struct pinctrl * __must_check pinctrl_get(struct device *dev);
extern void pinctrl_put(struct pinctrl *p);
extern struct pinctrl_state * __must_check pinctrl_lookup_state(
struct pinctrl *p,
const char *name);
extern int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *s);
#else /* !CONFIG_PINCTRL */
static inline int pinctrl_request_gpio(unsigned gpio)
{
return 0;
}
static inline void pinctrl_free_gpio(unsigned gpio)
{
}
static inline int pinctrl_gpio_direction_input(unsigned gpio)
{
return 0;
}
static inline int pinctrl_gpio_direction_output(unsigned gpio)
{
return 0;
}
static inline struct pinctrl * __must_check pinctrl_get(struct device *dev)
{
return NULL;
}
static inline void pinctrl_put(struct pinctrl *p)
{
}
static inline struct pinctrl_state * __must_check pinctrl_lookup_state(
struct pinctrl *p,
const char *name)
{
return NULL;
}
static inline int pinctrl_select_state(struct pinctrl *p,
struct pinctrl_state *s)
{
return 0;
}
#endif /* CONFIG_PINCTRL */
static inline struct pinctrl * __must_check pinctrl_get_select(
struct device *dev, const char *name)
{
struct pinctrl *p;
struct pinctrl_state *s;
int ret;
p = pinctrl_get(dev);
if (IS_ERR(p))
return p;
s = pinctrl_lookup_state(p, name);
if (IS_ERR(s)) {
pinctrl_put(p);
return ERR_PTR(PTR_ERR(s));
}
ret = pinctrl_select_state(p, s);
if (ret < 0) {
pinctrl_put(p);
return ERR_PTR(ret);
}
return p;
}
static inline struct pinctrl * __must_check pinctrl_get_select_default(
struct device *dev)
{
return pinctrl_get_select(dev, PINCTRL_STATE_DEFAULT);
}
#ifdef CONFIG_PINCONF
extern int pin_config_get(const char *dev_name, const char *name,
unsigned long *config);
extern int pin_config_set(const char *dev_name, const char *name,
unsigned long config);
extern int pin_config_group_get(const char *dev_name,
const char *pin_group,
unsigned long *config);
extern int pin_config_group_set(const char *dev_name,
const char *pin_group,
unsigned long config);
#else
static inline int pin_config_get(const char *dev_name, const char *name,
unsigned long *config)
{
return 0;
}
static inline int pin_config_set(const char *dev_name, const char *name,
unsigned long config)
{
return 0;
}
static inline int pin_config_group_get(const char *dev_name,
const char *pin_group,
unsigned long *config)
{
return 0;
}
static inline int pin_config_group_set(const char *dev_name,
const char *pin_group,
unsigned long config)
{
return 0;
}
#endif
#endif /* __LINUX_PINCTRL_CONSUMER_H */

View File

@ -9,87 +9,153 @@
*
* License terms: GNU General Public License (GPL) version 2
*/
#ifndef __LINUX_PINMUX_MACHINE_H
#define __LINUX_PINMUX_MACHINE_H
#ifndef __LINUX_PINCTRL_MACHINE_H
#define __LINUX_PINCTRL_MACHINE_H
/**
* struct pinmux_map - boards/machines shall provide this map for devices
* @name: the name of this specific map entry for the particular machine.
* This is the second parameter passed to pinmux_get() when you want
* to have several mappings to the same device
* @ctrl_dev: the pin control device to be used by this mapping, may be NULL
* if you provide .ctrl_dev_name instead (this is more common)
* @ctrl_dev_name: the name of the device controlling this specific mapping,
* the name must be the same as in your struct device*, may be NULL if
* you provide .ctrl_dev instead
* @function: a function in the driver to use for this mapping, the driver
* will lookup the function referenced by this ID on the specified
* pin control device
* @group: sometimes a function can map to different pin groups, so this
* selects a certain specific pin group to activate for the function, if
* left as NULL, the first applicable group will be used
* @dev: the device using this specific mapping, may be NULL if you provide
* .dev_name instead (this is more common)
* @dev_name: the name of the device using this specific mapping, the name
* must be the same as in your struct device*, may be NULL if you
* provide .dev instead
* @hog_on_boot: if this is set to true, the pin control subsystem will itself
* hog the mappings as the pinmux device drivers are attached, so this is
* typically used with system maps (mux mappings without an assigned
* device) that you want to get hogged and enabled by default as soon as
* a pinmux device supporting it is registered. These maps will not be
* disabled and put until the system shuts down.
*/
struct pinmux_map {
const char *name;
struct device *ctrl_dev;
const char *ctrl_dev_name;
const char *function;
const char *group;
struct device *dev;
const char *dev_name;
bool hog_on_boot;
#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,
};
/*
* Convenience macro to set a simple map from a certain pin controller and a
* certain function to a named device
/**
* 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
*/
#define PINMUX_MAP(a, b, c, d) \
{ .name = a, .ctrl_dev_name = b, .function = c, .dev_name = d }
struct pinctrl_map_mux {
const char *group;
const char *function;
};
/*
* Convenience macro to map a system function onto a certain pinctrl device.
* System functions are not assigned to a particular device.
/**
* 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
*/
#define PINMUX_MAP_SYS(a, b, c) \
{ .name = a, .ctrl_dev_name = b, .function = c }
struct pinctrl_map_configs {
const char *group_or_pin;
unsigned long *configs;
unsigned num_configs;
};
/*
* Convenience macro to map a system function onto a certain pinctrl device,
* to be hogged by the pinmux core until the system shuts down.
/**
* struct pinctrl_map - boards/machines shall provide this map for devices
* @dev_name: the name of the device using this specific mapping, the name
* must be the same as in your struct device*. If this name is set to the
* same name as the pin controllers own dev_name(), the map entry will be
* hogged by the driver itself upon registration
* @name: the name of this specific map entry for the particular machine.
* This is the parameter passed to pinmux_lookup_state()
* @type: the type of mapping table entry
* @ctrl_dev_name: the name of the device controlling this specific mapping,
* the name must be the same as in your struct device*. This field is not
* used for PIN_MAP_TYPE_DUMMY_STATE
* @data: Data specific to the mapping type
*/
#define PINMUX_MAP_SYS_HOG(a, b, c) \
{ .name = a, .ctrl_dev_name = b, .function = c, \
.hog_on_boot = true }
struct pinctrl_map {
const char *dev_name;
const char *name;
enum pinctrl_map_type type;
const char *ctrl_dev_name;
union {
struct pinctrl_map_mux mux;
struct pinctrl_map_configs configs;
} data;
};
/*
* Convenience macro to map a system function onto a certain pinctrl device
* using a specified group, to be hogged by the pinmux core until the system
* shuts down.
*/
#define PINMUX_MAP_SYS_HOG_GROUP(a, b, c, d) \
{ .name = a, .ctrl_dev_name = b, .function = c, .group = d, \
.hog_on_boot = true }
/* Convenience macros to create mapping table entries */
#define PIN_MAP_DUMMY_STATE(dev, state) \
{ \
.dev_name = dev, \
.name = state, \
.type = PIN_MAP_TYPE_DUMMY_STATE, \
}
#define PIN_MAP_MUX_GROUP(dev, state, pinctrl, grp, func) \
{ \
.dev_name = dev, \
.name = state, \
.type = PIN_MAP_TYPE_MUX_GROUP, \
.ctrl_dev_name = pinctrl, \
.data.mux = { \
.group = grp, \
.function = func, \
}, \
}
#define PIN_MAP_MUX_GROUP_DEFAULT(dev, pinctrl, grp, func) \
PIN_MAP_MUX_GROUP(dev, PINCTRL_STATE_DEFAULT, pinctrl, grp, func)
#define PIN_MAP_MUX_GROUP_HOG(dev, state, grp, func) \
PIN_MAP_MUX_GROUP(dev, state, dev, grp, func)
#define PIN_MAP_MUX_GROUP_HOG_DEFAULT(dev, grp, func) \
PIN_MAP_MUX_GROUP(dev, PINCTRL_STATE_DEFAULT, dev, grp, func)
#define PIN_MAP_CONFIGS_PIN(dev, state, pinctrl, pin, cfgs) \
{ \
.dev_name = dev, \
.name = state, \
.type = PIN_MAP_TYPE_CONFIGS_PIN, \
.ctrl_dev_name = pinctrl, \
.data.configs = { \
.group_or_pin = pin, \
.configs = cfgs, \
.num_configs = ARRAY_SIZE(cfgs), \
}, \
}
#define PIN_MAP_CONFIGS_PIN_DEFAULT(dev, pinctrl, pin, cfgs) \
PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_DEFAULT, pinctrl, pin, cfgs)
#define PIN_MAP_CONFIGS_PIN_HOG(dev, state, pin, cfgs) \
PIN_MAP_CONFIGS_PIN(dev, state, dev, pin, cfgs)
#define PIN_MAP_CONFIGS_PIN_HOG_DEFAULT(dev, pin, cfgs) \
PIN_MAP_CONFIGS_PIN(dev, PINCTRL_STATE_DEFAULT, dev, pin, cfgs)
#define PIN_MAP_CONFIGS_GROUP(dev, state, pinctrl, grp, cfgs) \
{ \
.dev_name = dev, \
.name = state, \
.type = PIN_MAP_TYPE_CONFIGS_GROUP, \
.ctrl_dev_name = pinctrl, \
.data.configs = { \
.group_or_pin = grp, \
.configs = cfgs, \
.num_configs = ARRAY_SIZE(cfgs), \
}, \
}
#define PIN_MAP_CONFIGS_GROUP_DEFAULT(dev, pinctrl, grp, cfgs) \
PIN_MAP_CONFIGS_GROUP(dev, PINCTRL_STATE_DEFAULT, pinctrl, grp, cfgs)
#define PIN_MAP_CONFIGS_GROUP_HOG(dev, state, grp, cfgs) \
PIN_MAP_CONFIGS_GROUP(dev, state, dev, grp, cfgs)
#define PIN_MAP_CONFIGS_GROUP_HOG_DEFAULT(dev, grp, cfgs) \
PIN_MAP_CONFIGS_GROUP(dev, PINCTRL_STATE_DEFAULT, dev, grp, cfgs)
#ifdef CONFIG_PINMUX
extern int pinmux_register_mappings(struct pinmux_map const *map,
extern int pinctrl_register_mappings(struct pinctrl_map const *map,
unsigned num_maps);
#else
static inline int pinmux_register_mappings(struct pinmux_map const *map,
static inline int pinctrl_register_mappings(struct pinctrl_map const *map,
unsigned num_maps)
{
return 0;

View File

@ -0,0 +1,114 @@
/*
* 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 */

View File

@ -20,6 +20,8 @@ struct seq_file;
/**
* struct pinconf_ops - pin config operations, to be implemented by
* 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
* is not available on this controller this should return -ENOTSUPP
* and if it is available but disabled it should return -EINVAL
@ -33,6 +35,9 @@ struct seq_file;
* per-device info for a certain group in debugfs
*/
struct pinconf_ops {
#ifdef CONFIG_GENERIC_PINCONF
bool is_generic;
#endif
int (*pin_config_get) (struct pinctrl_dev *pctldev,
unsigned pin,
unsigned long *config);
@ -53,45 +58,6 @@ struct pinconf_ops {
unsigned selector);
};
extern int pin_config_get(const char *dev_name, const char *name,
unsigned long *config);
extern int pin_config_set(const char *dev_name, const char *name,
unsigned long config);
extern int pin_config_group_get(const char *dev_name,
const char *pin_group,
unsigned long *config);
extern int pin_config_group_set(const char *dev_name,
const char *pin_group,
unsigned long config);
#else
static inline int pin_config_get(const char *dev_name, const char *name,
unsigned long *config)
{
return 0;
}
static inline int pin_config_set(const char *dev_name, const char *name,
unsigned long config)
{
return 0;
}
static inline int pin_config_group_get(const char *dev_name,
const char *pin_group,
unsigned long *config)
{
return 0;
}
static inline int pin_config_group_set(const char *dev_name,
const char *pin_group,
unsigned long config)
{
return 0;
}
#endif
#endif /* __LINUX_PINCTRL_PINCONF_H */

View File

@ -0,0 +1,6 @@
/*
* Standard pin control state definitions
*/
#define PINCTRL_STATE_DEFAULT "default"
#define PINCTRL_STATE_IDLE "idle"

View File

@ -15,10 +15,11 @@
#ifdef CONFIG_PINCTRL
#include <linux/radix-tree.h>
#include <linux/spinlock.h>
#include <linux/list.h>
#include <linux/seq_file.h>
#include "pinctrl-state.h"
struct device;
struct pinctrl_dev;
struct pinmux_ops;
struct pinconf_ops;

View File

@ -16,9 +16,6 @@
#include <linux/seq_file.h>
#include "pinctrl.h"
/* This struct is private to the core and should be regarded as a cookie */
struct pinmux;
#ifdef CONFIG_PINMUX
struct pinctrl_dev;
@ -88,55 +85,6 @@ struct pinmux_ops {
bool input);
};
/* External interface to pinmux */
extern int pinmux_request_gpio(unsigned gpio);
extern void pinmux_free_gpio(unsigned gpio);
extern int pinmux_gpio_direction_input(unsigned gpio);
extern int pinmux_gpio_direction_output(unsigned gpio);
extern struct pinmux * __must_check pinmux_get(struct device *dev, const char *name);
extern void pinmux_put(struct pinmux *pmx);
extern int pinmux_enable(struct pinmux *pmx);
extern void pinmux_disable(struct pinmux *pmx);
#else /* !CONFIG_PINMUX */
static inline int pinmux_request_gpio(unsigned gpio)
{
return 0;
}
static inline void pinmux_free_gpio(unsigned gpio)
{
}
static inline int pinmux_gpio_direction_input(unsigned gpio)
{
return 0;
}
static inline int pinmux_gpio_direction_output(unsigned gpio)
{
return 0;
}
static inline struct pinmux * __must_check pinmux_get(struct device *dev, const char *name)
{
return NULL;
}
static inline void pinmux_put(struct pinmux *pmx)
{
}
static inline int pinmux_enable(struct pinmux *pmx)
{
return 0;
}
static inline void pinmux_disable(struct pinmux *pmx)
{
}
#endif /* CONFIG_PINMUX */
#endif /* __LINUX_PINCTRL_PINMUX_H */