From 9dfac4fd7f8cdcdf734dff2ccc7ca467f53f1cfd Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 1 Feb 2012 18:02:47 +0100 Subject: pinctrl: delete raw device pointers in pinmux maps After discussion with Mark Brown in an unrelated thread about ADC lookups, it came to my knowledge that the ability to pass a struct device * in the regulator consumers is just a historical artifact, and not really recommended. Since there are no in-kernel users of these pointers, we just kill them right now, before someone starts to use them. Reviewed-by: Mark Brown Signed-off-by: Linus Walleij diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 150fd38..14aecd2 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -805,10 +805,7 @@ 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: diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 894cd5e..4f10476 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -48,31 +48,23 @@ void *pinctrl_dev_get_drvdata(struct pinctrl_dev *pctldev) EXPORT_SYMBOL_GPL(pinctrl_dev_get_drvdata); /** - * get_pinctrl_dev_from_dev() - look up pin controller device - * @dev: a device pointer, this may be NULL but then devname needs to be - * defined instead - * @devname: the name of a device instance, as returned by dev_name(), this - * may be NULL but then dev needs to be defined instead + * get_pinctrl_dev_from_devname() - look up pin controller device + * @devname: the name of a device instance, as returned by dev_name() * * Looks up a pin control device matching a certain device name or pure device * pointer, the pure device pointer will take precedence. */ -struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, - const char *devname) +struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname) { struct pinctrl_dev *pctldev = NULL; bool found = false; + if (!devname) + return NULL; + mutex_lock(&pinctrldev_list_mutex); list_for_each_entry(pctldev, &pinctrldev_list, node) { - if (dev && pctldev->dev == dev) { - /* Matched on device pointer */ - found = true; - break; - } - - if (devname && - !strcmp(dev_name(pctldev->dev), devname)) { + if (!strcmp(dev_name(pctldev->dev), devname)) { /* Matched on device name */ found = true; break; diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index cfa86da..8a8b02e 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -72,8 +72,7 @@ struct pin_desc { #endif }; -struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, - const char *dev_name); +struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name); struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin); int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name); int pinctrl_get_device_gpio_range(unsigned gpio, diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 9fb7545..b74f64a 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -51,7 +51,7 @@ 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); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) return -EINVAL; @@ -99,7 +99,7 @@ int pin_config_set(const char *dev_name, const char *name, struct pinctrl_dev *pctldev; int pin; - pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) return -EINVAL; @@ -118,7 +118,7 @@ int pin_config_group_get(const char *dev_name, const char *pin_group, const struct pinconf_ops *ops; int selector; - pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) return -EINVAL; ops = pctldev->desc->confops; @@ -151,7 +151,7 @@ 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); + pctldev = get_pinctrl_dev_from_devname(dev_name); if (!pctldev) return -EINVAL; ops = pctldev->desc->confops; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 7c3193f..1311f1d 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -354,7 +354,7 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps, return -EINVAL; } - if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) { + if (!maps[i].ctrl_dev_name) { pr_err("failed to register map %s (%d): no pin control device given\n", maps[i].name, i); return -EINVAL; @@ -366,7 +366,7 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps, return -EINVAL; } - if (!maps[i].dev && !maps[i].dev_name) + if (!maps[i].dev_name) pr_debug("add system map %s function %s with no device\n", maps[i].name, maps[i].function); @@ -721,20 +721,12 @@ struct pinmux *pinmux_get(struct device *dev, const char *name) /* * First, try to find the pctldev given in the map */ - pctldev = get_pinctrl_dev_from_dev(map->ctrl_dev, - map->ctrl_dev_name); + pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); if (!pctldev) { - const char *devname = NULL; - - if (map->ctrl_dev) - devname = dev_name(map->ctrl_dev); - else if (map->ctrl_dev_name) - devname = map->ctrl_dev_name; - pr_warning("could not find a pinctrl device for pinmux function %s, fishy, they shall all have one\n", map->function); pr_warning("given pinctrl device name: %s", - devname ? devname : "UNDEFINED"); + map->ctrl_dev_name); /* Continue to check the other mappings anyway... */ continue; @@ -925,7 +917,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, struct pinmux *pmx; int ret; - if (map->dev || map->dev_name) { + if (map->dev_name) { /* * TODO: the day we have device tree support, we can * traverse the device tree and hog to specific device nodes @@ -996,9 +988,8 @@ int pinmux_hog_maps(struct pinctrl_dev *pctldev) if (!map->hog_on_boot) continue; - if ((map->ctrl_dev == dev) || - (map->ctrl_dev_name && - !strcmp(map->ctrl_dev_name, devname))) { + if (map->ctrl_dev_name && + !strcmp(map->ctrl_dev_name, devname)) { /* OK time to hog! */ ret = pinmux_hog_map(pctldev, map); if (ret) @@ -1156,14 +1147,12 @@ static int pinmux_maps_show(struct seq_file *s, void *what) struct pinmux_map const *map = &pinmux_maps[i]; seq_printf(s, "%s:\n", map->name); - if (map->dev || map->dev_name) + if (map->dev_name) seq_printf(s, " device: %s\n", - map->dev ? dev_name(map->dev) : map->dev_name); else seq_printf(s, " SYSTEM MUX\n"); seq_printf(s, " controlling device %s\n", - map->ctrl_dev ? dev_name(map->ctrl_dev) : map->ctrl_dev_name); seq_printf(s, " function: %s\n", map->function); seq_printf(s, " group: %s\n", map->group ? map->group : diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index d0aecb7..f8593fd 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -17,22 +17,16 @@ * @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 + * the name must be the same as in your struct device* * @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 + * must be the same as in your struct device* * @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 @@ -42,11 +36,9 @@ */ 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; }; -- cgit v0.10.2 From f4e66983293f78e177bb210d19a46f083f5e8197 Mon Sep 17 00:00:00 2001 From: Haojian Zhuang Date: Wed, 4 Jan 2012 10:26:33 +0800 Subject: pinctrl: enable pinmux for mmp series Support PXA168/PXA910/MMP2 pinmux. Now only support function switch. Signed-off-by: Haojian Zhuang [Rebase and fix some whitespace issues] Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index afaf885..3bea79f 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -23,6 +23,28 @@ config DEBUG_PINCTRL help Say Y here to add some extra checks and diagnostics to PINCTRL calls. +config PINCTRL_PXA3xx + bool + select PINMUX + +config PINCTRL_MMP2 + bool "MMP2 pin controller driver" + depends on ARCH_MMP + select PINCTRL_PXA3xx + select PINCONF + +config PINCTRL_PXA168 + bool "PXA168 pin controller driver" + depends on ARCH_MMP + select PINCTRL_PXA3xx + select PINCONF + +config PINCTRL_PXA910 + bool "PXA910 pin controller driver" + depends on ARCH_MMP + select PINCTRL_PXA3xx + select PINCONF + config PINCTRL_SIRF bool "CSR SiRFprimaII pin controller driver" depends on ARCH_PRIMA2 diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 827601c..c95d91e 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -5,6 +5,10 @@ ccflags-$(CONFIG_DEBUG_PINCTRL) += -DDEBUG obj-$(CONFIG_PINCTRL) += core.o obj-$(CONFIG_PINMUX) += pinmux.o obj-$(CONFIG_PINCONF) += pinconf.o +obj-$(CONFIG_PINCTRL_PXA3xx) += pinctrl-pxa3xx.o +obj-$(CONFIG_PINCTRL_MMP2) += pinctrl-mmp2.o +obj-$(CONFIG_PINCTRL_PXA168) += pinctrl-pxa168.o +obj-$(CONFIG_PINCTRL_PXA910) += pinctrl-pxa910.o obj-$(CONFIG_PINCTRL_SIRF) += pinctrl-sirf.o obj-$(CONFIG_PINCTRL_U300) += pinctrl-u300.o obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o diff --git a/drivers/pinctrl/pinctrl-mmp2.c b/drivers/pinctrl/pinctrl-mmp2.c new file mode 100644 index 0000000..2cfed55 --- /dev/null +++ b/drivers/pinctrl/pinctrl-mmp2.c @@ -0,0 +1,722 @@ +/* + * linux/drivers/pinctrl/pinmux-mmp2.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#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 "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-pxa168.c b/drivers/pinctrl/pinctrl-pxa168.c new file mode 100644 index 0000000..c1997fa --- /dev/null +++ b/drivers/pinctrl/pinctrl-pxa168.c @@ -0,0 +1,651 @@ +/* + * linux/drivers/pinctrl/pinmux-pxa168.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#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 "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-pxa3xx.c b/drivers/pinctrl/pinctrl-pxa3xx.c new file mode 100644 index 0000000..079dce0 --- /dev/null +++ b/drivers/pinctrl/pinctrl-pxa3xx.c @@ -0,0 +1,244 @@ +/* + * linux/drivers/pinctrl/pinctrl-pxa3xx.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#include +#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 "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinctrl-pxa3xx.h b/drivers/pinctrl/pinctrl-pxa3xx.h new file mode 100644 index 0000000..8135744 --- /dev/null +++ b/drivers/pinctrl/pinctrl-pxa3xx.h @@ -0,0 +1,264 @@ +/* + * linux/drivers/pinctrl/pinctrl-pxa3xx.h + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#ifndef __PINCTRL_PXA3XX_H + +#include +#include + +#define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) + +#define PXA3xx_MUX_GPIO 0 + +#define PXA3xx_MAX_MUX 8 +#define MFPR_FUNC_MASK 0x7 + +enum pxa_cpu_type { + PINCTRL_INVALID = 0, + PINCTRL_PXA300, + PINCTRL_PXA310, + PINCTRL_PXA320, + PINCTRL_PXA168, + PINCTRL_PXA910, + PINCTRL_PXA930, + PINCTRL_PXA955, + PINCTRL_MMP2, + PINCTRL_MAX, +}; + +struct pxa3xx_mfp_pin { + const char *name; + const unsigned int pin; + const unsigned int mfpr; /* register offset */ + const unsigned short func[8]; +}; + +struct pxa3xx_pin_group { + const char *name; + const unsigned mux; + const unsigned *pins; + const unsigned npins; +}; + +struct pxa3xx_pmx_func { + const char *name; + const char * const * groups; + const unsigned num_groups; +}; + +struct pxa3xx_pinmux_info { + struct device *dev; + struct pinctrl_dev *pctrl; + enum pxa_cpu_type cputype; + unsigned int phy_base; + unsigned int phy_size; + void __iomem *virt_base; + + struct pxa3xx_mfp_pin *mfp; + unsigned int num_mfp; + struct pxa3xx_pin_group *grps; + unsigned int num_grps; + struct pxa3xx_pmx_func *funcs; + unsigned int num_funcs; + unsigned int num_gpio; + struct pinctrl_desc *desc; + struct pinctrl_pin_desc *pads; + unsigned int num_pads; + + unsigned ds_mask; /* drive strength mask */ + unsigned ds_shift; /* drive strength shift */ + unsigned slp_mask; /* sleep mask */ + unsigned slp_input_low; + unsigned slp_input_high; + unsigned slp_output_low; + unsigned slp_output_high; + unsigned slp_float; +}; + +enum pxa3xx_pin_list { + GPIO0 = 0, + GPIO1, + GPIO2, + GPIO3, + GPIO4, + GPIO5, + GPIO6, + GPIO7, + GPIO8, + GPIO9, + GPIO10, /* 10 */ + GPIO11, + GPIO12, + GPIO13, + GPIO14, + GPIO15, + GPIO16, + GPIO17, + GPIO18, + GPIO19, + GPIO20, /* 20 */ + GPIO21, + GPIO22, + GPIO23, + GPIO24, + GPIO25, + GPIO26, + GPIO27, + GPIO28, + GPIO29, + GPIO30, /* 30 */ + GPIO31, + GPIO32, + GPIO33, + GPIO34, + GPIO35, + GPIO36, + GPIO37, + GPIO38, + GPIO39, + GPIO40, /* 40 */ + GPIO41, + GPIO42, + GPIO43, + GPIO44, + GPIO45, + GPIO46, + GPIO47, + GPIO48, + GPIO49, + GPIO50, /* 50 */ + GPIO51, + GPIO52, + GPIO53, + GPIO54, + GPIO55, + GPIO56, + GPIO57, + GPIO58, + GPIO59, + GPIO60, /* 60 */ + GPIO61, + GPIO62, + GPIO63, + GPIO64, + GPIO65, + GPIO66, + GPIO67, + GPIO68, + GPIO69, + GPIO70, /* 70 */ + GPIO71, + GPIO72, + GPIO73, + GPIO74, + GPIO75, + GPIO76, + GPIO77, + GPIO78, + GPIO79, + GPIO80, /* 80 */ + GPIO81, + GPIO82, + GPIO83, + GPIO84, + GPIO85, + GPIO86, + GPIO87, + GPIO88, + GPIO89, + GPIO90, /* 90 */ + GPIO91, + GPIO92, + GPIO93, + GPIO94, + GPIO95, + GPIO96, + GPIO97, + GPIO98, + GPIO99, + GPIO100, /* 100 */ + GPIO101, + GPIO102, + GPIO103, + GPIO104, + GPIO105, + GPIO106, + GPIO107, + GPIO108, + GPIO109, + GPIO110, /* 110 */ + GPIO111, + GPIO112, + GPIO113, + GPIO114, + GPIO115, + GPIO116, + GPIO117, + GPIO118, + GPIO119, + GPIO120, /* 120 */ + GPIO121, + GPIO122, + GPIO123, + GPIO124, + GPIO125, + GPIO126, + GPIO127, + GPIO128, + GPIO129, + GPIO130, /* 130 */ + GPIO131, + GPIO132, + GPIO133, + GPIO134, + GPIO135, + GPIO136, + GPIO137, + GPIO138, + GPIO139, + GPIO140, /* 140 */ + GPIO141, + GPIO142, + GPIO143, + GPIO144, + GPIO145, + GPIO146, + GPIO147, + GPIO148, + GPIO149, + GPIO150, /* 150 */ + GPIO151, + GPIO152, + GPIO153, + GPIO154, + GPIO155, + GPIO156, + GPIO157, + GPIO158, + GPIO159, + GPIO160, /* 160 */ + GPIO161, + GPIO162, + GPIO163, + GPIO164, + GPIO165, + GPIO166, + GPIO167, + GPIO168, + GPIO169, +}; + +extern int pxa3xx_pinctrl_register(struct platform_device *pdev, + struct pxa3xx_pinmux_info *info); +extern int pxa3xx_pinctrl_unregister(struct platform_device *pdev); +#endif /* __PINCTRL_PXA3XX_H */ diff --git a/drivers/pinctrl/pinctrl-pxa910.c b/drivers/pinctrl/pinctrl-pxa910.c new file mode 100644 index 0000000..c72ab4b --- /dev/null +++ b/drivers/pinctrl/pinctrl-pxa910.c @@ -0,0 +1,1007 @@ +/* + * linux/drivers/pinctrl/pinmux-pxa910.c + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * publishhed by the Free Software Foundation. + * + * Copyright (C) 2011, Marvell Technology Group Ltd. + * + * Author: Haojian Zhuang + * + */ + +#include +#include +#include +#include +#include "pinctrl-pxa3xx.h" + +#define PXA910_DS_MASK 0x1800 +#define PXA910_DS_SHIFT 11 +#define PXA910_SLEEP_MASK 0x38 +#define PXA910_SLEEP_SELECT (1 << 9) +#define PXA910_SLEEP_DATA (1 << 8) +#define PXA910_SLEEP_DIR (1 << 7) + +#define MFPR_910(a, r, f0, f1, f2, f3, f4, f5, f6, f7) \ + { \ + .name = #a, \ + .pin = a, \ + .mfpr = r, \ + .func = { \ + PXA910_MUX_##f0, \ + PXA910_MUX_##f1, \ + PXA910_MUX_##f2, \ + PXA910_MUX_##f3, \ + PXA910_MUX_##f4, \ + PXA910_MUX_##f5, \ + PXA910_MUX_##f6, \ + PXA910_MUX_##f7, \ + }, \ + } + +#define GRP_910(a, m, p) \ + { .name = a, .mux = PXA910_MUX_##m, .pins = p, .npins = ARRAY_SIZE(p), } + +/* 170 pins */ +enum pxa910_pin_list { + /* 0~127: GPIO0~GPIO127 */ + ND_IO15 = 128, + ND_IO14, + ND_IO13, /* 130 */ + ND_IO12, + ND_IO11, + ND_IO10, + ND_IO9, + ND_IO8, + ND_IO7, + ND_IO6, + ND_IO5, + ND_IO4, + ND_IO3, /* 140 */ + ND_IO2, + ND_IO1, + ND_IO0, + ND_NCS0, + ND_NCS1, + SM_NCS0, + SM_NCS1, + ND_NWE, + ND_NRE, + ND_CLE, /* 150 */ + ND_ALE, + SM_SCLK, + ND_RDY0, + SM_ADV, + ND_RDY1, + SM_ADVMUX, + SM_RDY, + MMC1_DAT7, + MMC1_DAT6, + MMC1_DAT5, /* 160 */ + MMC1_DAT4, + MMC1_DAT3, + MMC1_DAT2, + MMC1_DAT1, + MMC1_DAT0, + MMC1_CMD, + MMC1_CLK, + MMC1_CD, + VCXO_OUT, +}; + +enum pxa910_mux { + /* PXA3xx_MUX_GPIO = 0 (predefined in pinctrl-pxa3xx.h) */ + PXA910_MUX_GPIO = 0, + PXA910_MUX_NAND, + PXA910_MUX_USIM2, + PXA910_MUX_EXT_DMA, + PXA910_MUX_EXT_INT, + PXA910_MUX_MMC1, + PXA910_MUX_MMC2, + PXA910_MUX_MMC3, + PXA910_MUX_SM_INT, + PXA910_MUX_PRI_JTAG, + PXA910_MUX_SEC1_JTAG, + PXA910_MUX_SEC2_JTAG, + PXA910_MUX_RESET, /* SLAVE RESET OUT */ + PXA910_MUX_CLK_REQ, + PXA910_MUX_VCXO_REQ, + PXA910_MUX_VCXO_OUT, + PXA910_MUX_VCXO_REQ2, + PXA910_MUX_VCXO_OUT2, + PXA910_MUX_SPI, + PXA910_MUX_SPI2, + PXA910_MUX_GSSP, + PXA910_MUX_SSP0, + PXA910_MUX_SSP1, + PXA910_MUX_SSP2, + PXA910_MUX_DSSP2, + PXA910_MUX_DSSP3, + PXA910_MUX_UART0, + PXA910_MUX_UART1, + PXA910_MUX_UART2, + PXA910_MUX_TWSI, + PXA910_MUX_CCIC, + PXA910_MUX_PWM0, + PXA910_MUX_PWM1, + PXA910_MUX_PWM2, + PXA910_MUX_PWM3, + PXA910_MUX_HSL, + PXA910_MUX_ONE_WIRE, + PXA910_MUX_LCD, + PXA910_MUX_DAC_ST23, + PXA910_MUX_ULPI, + PXA910_MUX_TB, + PXA910_MUX_KP_MK, + PXA910_MUX_KP_DK, + PXA910_MUX_TCU_GPOA, + PXA910_MUX_TCU_GPOB, + PXA910_MUX_ROT, + PXA910_MUX_TDS, + PXA910_MUX_32K_CLK, /* 32KHz CLK OUT */ + PXA910_MUX_MN_CLK, /* MN CLK OUT */ + PXA910_MUX_SMC, + PXA910_MUX_SM_ADDR18, + PXA910_MUX_SM_ADDR19, + PXA910_MUX_SM_ADDR20, + PXA910_MUX_NONE = 0xffff, +}; + + +static struct pinctrl_pin_desc pxa910_pads[] = { + PINCTRL_PIN(GPIO0, "GPIO0"), + PINCTRL_PIN(GPIO1, "GPIO1"), + PINCTRL_PIN(GPIO2, "GPIO2"), + PINCTRL_PIN(GPIO3, "GPIO3"), + PINCTRL_PIN(GPIO4, "GPIO4"), + PINCTRL_PIN(GPIO5, "GPIO5"), + PINCTRL_PIN(GPIO6, "GPIO6"), + PINCTRL_PIN(GPIO7, "GPIO7"), + PINCTRL_PIN(GPIO8, "GPIO8"), + PINCTRL_PIN(GPIO9, "GPIO9"), + PINCTRL_PIN(GPIO10, "GPIO10"), + PINCTRL_PIN(GPIO11, "GPIO11"), + PINCTRL_PIN(GPIO12, "GPIO12"), + PINCTRL_PIN(GPIO13, "GPIO13"), + PINCTRL_PIN(GPIO14, "GPIO14"), + PINCTRL_PIN(GPIO15, "GPIO15"), + PINCTRL_PIN(GPIO16, "GPIO16"), + PINCTRL_PIN(GPIO17, "GPIO17"), + PINCTRL_PIN(GPIO18, "GPIO18"), + PINCTRL_PIN(GPIO19, "GPIO19"), + PINCTRL_PIN(GPIO20, "GPIO20"), + PINCTRL_PIN(GPIO21, "GPIO21"), + PINCTRL_PIN(GPIO22, "GPIO22"), + PINCTRL_PIN(GPIO23, "GPIO23"), + PINCTRL_PIN(GPIO24, "GPIO24"), + PINCTRL_PIN(GPIO25, "GPIO25"), + PINCTRL_PIN(GPIO26, "GPIO26"), + PINCTRL_PIN(GPIO27, "GPIO27"), + PINCTRL_PIN(GPIO28, "GPIO28"), + PINCTRL_PIN(GPIO29, "GPIO29"), + PINCTRL_PIN(GPIO30, "GPIO30"), + PINCTRL_PIN(GPIO31, "GPIO31"), + PINCTRL_PIN(GPIO32, "GPIO32"), + PINCTRL_PIN(GPIO33, "GPIO33"), + PINCTRL_PIN(GPIO34, "GPIO34"), + PINCTRL_PIN(GPIO35, "GPIO35"), + PINCTRL_PIN(GPIO36, "GPIO36"), + PINCTRL_PIN(GPIO37, "GPIO37"), + PINCTRL_PIN(GPIO38, "GPIO38"), + PINCTRL_PIN(GPIO39, "GPIO39"), + PINCTRL_PIN(GPIO40, "GPIO40"), + PINCTRL_PIN(GPIO41, "GPIO41"), + PINCTRL_PIN(GPIO42, "GPIO42"), + PINCTRL_PIN(GPIO43, "GPIO43"), + PINCTRL_PIN(GPIO44, "GPIO44"), + PINCTRL_PIN(GPIO45, "GPIO45"), + PINCTRL_PIN(GPIO46, "GPIO46"), + PINCTRL_PIN(GPIO47, "GPIO47"), + PINCTRL_PIN(GPIO48, "GPIO48"), + PINCTRL_PIN(GPIO49, "GPIO49"), + PINCTRL_PIN(GPIO50, "GPIO50"), + PINCTRL_PIN(GPIO51, "GPIO51"), + PINCTRL_PIN(GPIO52, "GPIO52"), + PINCTRL_PIN(GPIO53, "GPIO53"), + PINCTRL_PIN(GPIO54, "GPIO54"), + PINCTRL_PIN(GPIO55, "GPIO55"), + PINCTRL_PIN(GPIO56, "GPIO56"), + PINCTRL_PIN(GPIO57, "GPIO57"), + PINCTRL_PIN(GPIO58, "GPIO58"), + PINCTRL_PIN(GPIO59, "GPIO59"), + PINCTRL_PIN(GPIO60, "GPIO60"), + PINCTRL_PIN(GPIO61, "GPIO61"), + PINCTRL_PIN(GPIO62, "GPIO62"), + PINCTRL_PIN(GPIO63, "GPIO63"), + PINCTRL_PIN(GPIO64, "GPIO64"), + PINCTRL_PIN(GPIO65, "GPIO65"), + PINCTRL_PIN(GPIO66, "GPIO66"), + PINCTRL_PIN(GPIO67, "GPIO67"), + PINCTRL_PIN(GPIO68, "GPIO68"), + PINCTRL_PIN(GPIO69, "GPIO69"), + PINCTRL_PIN(GPIO70, "GPIO70"), + PINCTRL_PIN(GPIO71, "GPIO71"), + PINCTRL_PIN(GPIO72, "GPIO72"), + PINCTRL_PIN(GPIO73, "GPIO73"), + PINCTRL_PIN(GPIO74, "GPIO74"), + PINCTRL_PIN(GPIO75, "GPIO75"), + PINCTRL_PIN(GPIO76, "GPIO76"), + PINCTRL_PIN(GPIO77, "GPIO77"), + PINCTRL_PIN(GPIO78, "GPIO78"), + PINCTRL_PIN(GPIO79, "GPIO79"), + PINCTRL_PIN(GPIO80, "GPIO80"), + PINCTRL_PIN(GPIO81, "GPIO81"), + PINCTRL_PIN(GPIO82, "GPIO82"), + PINCTRL_PIN(GPIO83, "GPIO83"), + PINCTRL_PIN(GPIO84, "GPIO84"), + PINCTRL_PIN(GPIO85, "GPIO85"), + PINCTRL_PIN(GPIO86, "GPIO86"), + PINCTRL_PIN(GPIO87, "GPIO87"), + PINCTRL_PIN(GPIO88, "GPIO88"), + PINCTRL_PIN(GPIO89, "GPIO89"), + PINCTRL_PIN(GPIO90, "GPIO90"), + PINCTRL_PIN(GPIO91, "GPIO91"), + PINCTRL_PIN(GPIO92, "GPIO92"), + PINCTRL_PIN(GPIO93, "GPIO93"), + PINCTRL_PIN(GPIO94, "GPIO94"), + PINCTRL_PIN(GPIO95, "GPIO95"), + PINCTRL_PIN(GPIO96, "GPIO96"), + PINCTRL_PIN(GPIO97, "GPIO97"), + PINCTRL_PIN(GPIO98, "GPIO98"), + PINCTRL_PIN(GPIO99, "GPIO99"), + PINCTRL_PIN(GPIO100, "GPIO100"), + PINCTRL_PIN(GPIO101, "GPIO101"), + PINCTRL_PIN(GPIO102, "GPIO102"), + PINCTRL_PIN(GPIO103, "GPIO103"), + PINCTRL_PIN(GPIO104, "GPIO104"), + PINCTRL_PIN(GPIO105, "GPIO105"), + PINCTRL_PIN(GPIO106, "GPIO106"), + PINCTRL_PIN(GPIO107, "GPIO107"), + PINCTRL_PIN(GPIO108, "GPIO108"), + PINCTRL_PIN(GPIO109, "GPIO109"), + PINCTRL_PIN(GPIO110, "GPIO110"), + PINCTRL_PIN(GPIO111, "GPIO111"), + PINCTRL_PIN(GPIO112, "GPIO112"), + PINCTRL_PIN(GPIO113, "GPIO113"), + PINCTRL_PIN(GPIO114, "GPIO114"), + PINCTRL_PIN(GPIO115, "GPIO115"), + PINCTRL_PIN(GPIO116, "GPIO116"), + PINCTRL_PIN(GPIO117, "GPIO117"), + PINCTRL_PIN(GPIO118, "GPIO118"), + PINCTRL_PIN(GPIO119, "GPIO119"), + PINCTRL_PIN(GPIO120, "GPIO120"), + PINCTRL_PIN(GPIO121, "GPIO121"), + PINCTRL_PIN(GPIO122, "GPIO122"), + PINCTRL_PIN(GPIO123, "GPIO123"), + PINCTRL_PIN(GPIO124, "GPIO124"), + PINCTRL_PIN(GPIO125, "GPIO125"), + PINCTRL_PIN(GPIO126, "GPIO126"), + PINCTRL_PIN(GPIO127, "GPIO127"), + PINCTRL_PIN(ND_IO15, "ND_IO15"), + PINCTRL_PIN(ND_IO14, "ND_IO14"), + PINCTRL_PIN(ND_IO13, "ND_IO13"), + PINCTRL_PIN(ND_IO12, "ND_IO12"), + PINCTRL_PIN(ND_IO11, "ND_IO11"), + PINCTRL_PIN(ND_IO10, "ND_IO10"), + PINCTRL_PIN(ND_IO9, "ND_IO9"), + PINCTRL_PIN(ND_IO8, "ND_IO8"), + PINCTRL_PIN(ND_IO7, "ND_IO7"), + PINCTRL_PIN(ND_IO6, "ND_IO6"), + PINCTRL_PIN(ND_IO5, "ND_IO5"), + PINCTRL_PIN(ND_IO4, "ND_IO4"), + PINCTRL_PIN(ND_IO3, "ND_IO3"), + PINCTRL_PIN(ND_IO2, "ND_IO2"), + PINCTRL_PIN(ND_IO1, "ND_IO1"), + PINCTRL_PIN(ND_IO0, "ND_IO0"), + PINCTRL_PIN(ND_NCS0, "ND_NCS0_SM_NCS2"), + PINCTRL_PIN(ND_NCS1, "ND_NCS1_SM_NCS3"), + PINCTRL_PIN(SM_NCS0, "SM_NCS0"), + PINCTRL_PIN(SM_NCS1, "SM_NCS1"), + PINCTRL_PIN(ND_NWE, "ND_NWE"), + PINCTRL_PIN(ND_NRE, "ND_NRE"), + PINCTRL_PIN(ND_CLE, "ND_CLE_SM_NOE"), + PINCTRL_PIN(ND_ALE, "ND_ALE_SM_NWE"), + PINCTRL_PIN(SM_SCLK, "SM_SCLK"), + PINCTRL_PIN(ND_RDY0, "ND_RDY0"), + PINCTRL_PIN(SM_ADV, "SM_ADV"), + PINCTRL_PIN(ND_RDY1, "ND_RDY1"), + PINCTRL_PIN(SM_RDY, "SM_RDY"), + PINCTRL_PIN(MMC1_DAT7, "MMC1_DAT7"), + PINCTRL_PIN(MMC1_DAT6, "MMC1_DAT6"), + PINCTRL_PIN(MMC1_DAT5, "MMC1_DAT5"), + PINCTRL_PIN(MMC1_DAT4, "MMC1_DAT4"), + PINCTRL_PIN(MMC1_DAT3, "MMC1_DAT3"), + PINCTRL_PIN(MMC1_DAT2, "MMC1_DAT2"), + PINCTRL_PIN(MMC1_DAT1, "MMC1_DAT1"), + PINCTRL_PIN(MMC1_DAT0, "MMC1_DAT0"), + PINCTRL_PIN(MMC1_CMD, "MMC1 CMD"), + PINCTRL_PIN(MMC1_CLK, "MMC1 CLK"), + PINCTRL_PIN(MMC1_CD, "MMC1 CD"), + PINCTRL_PIN(VCXO_OUT, "VCXO_OUT"), +}; + +struct pxa3xx_mfp_pin pxa910_mfp[] = { + /* pin offs f0 f1 f2 f3 f4 f5 f6 f7 */ + MFPR_910(GPIO0, 0x0DC, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO1, 0x0E0, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO2, 0x0E4, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO3, 0x0E8, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO4, 0x0EC, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO5, 0x0F0, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO6, 0x0F4, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO7, 0x0F8, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO8, 0x0FC, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO9, 0x100, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO10, 0x104, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO11, 0x108, GPIO, KP_MK, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO12, 0x10C, GPIO, KP_MK, NONE, NONE, KP_DK, NONE, NONE, NONE), + MFPR_910(GPIO13, 0x110, GPIO, KP_MK, NONE, NONE, KP_DK, NONE, NONE, NONE), + MFPR_910(GPIO14, 0x114, GPIO, KP_MK, NONE, NONE, KP_DK, TB, NONE, NONE), + MFPR_910(GPIO15, 0x118, GPIO, KP_MK, NONE, NONE, KP_DK, TB, NONE, NONE), + MFPR_910(GPIO16, 0x11C, GPIO, KP_DK, NONE, NONE, NONE, TB, NONE, NONE), + MFPR_910(GPIO17, 0x120, GPIO, KP_DK, NONE, NONE, NONE, TB, NONE, NONE), + MFPR_910(GPIO18, 0x124, GPIO, KP_DK, NONE, NONE, ROT, NONE, NONE, NONE), + MFPR_910(GPIO19, 0x128, GPIO, KP_DK, NONE, NONE, ROT, NONE, NONE, NONE), + MFPR_910(GPIO20, 0x12C, GPIO, SSP1, NONE, NONE, VCXO_OUT, NONE, NONE, NONE), + MFPR_910(GPIO21, 0x130, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO22, 0x134, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO23, 0x138, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO24, 0x13C, GPIO, SSP1, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO25, 0x140, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO26, 0x144, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO27, 0x148, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO28, 0x14C, GPIO, GSSP, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO29, 0x150, GPIO, UART0, NONE, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO30, 0x154, GPIO, UART0, NONE, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO31, 0x158, GPIO, UART0, NONE, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO32, 0x15C, GPIO, UART0, DAC_ST23, NONE, UART1, NONE, NONE, NONE), + MFPR_910(GPIO33, 0x160, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO34, 0x164, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO35, 0x168, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO36, 0x16C, GPIO, MMC2, SSP0, SSP2, NONE, SPI, NONE, MMC3), + MFPR_910(GPIO37, 0x170, GPIO, MMC2, NONE, NONE, NONE, SPI, HSL, NONE), + MFPR_910(GPIO38, 0x174, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO39, 0x178, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO40, 0x17C, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO41, 0x180, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO42, 0x184, GPIO, MMC2, NONE, NONE, NONE, NONE, HSL, NONE), + MFPR_910(GPIO43, 0x188, GPIO, UART1, NONE, DAC_ST23, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO44, 0x18C, GPIO, UART1, NONE, EXT_INT, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO45, 0x190, GPIO, UART1, NONE, EXT_INT, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO46, 0x194, GPIO, UART1, NONE, EXT_INT, NONE, DSSP2, SPI, UART2), + MFPR_910(GPIO47, 0x198, GPIO, SSP0, NONE, NONE, NONE, SSP2, UART1, NONE), + MFPR_910(GPIO48, 0x19C, GPIO, SSP0, NONE, NONE, NONE, SSP2, UART1, NONE), + MFPR_910(GPIO49, 0x1A0, GPIO, SSP0, UART0, VCXO_REQ, NONE, SSP2, NONE, MMC3), + MFPR_910(GPIO50, 0x1A4, GPIO, SSP0, UART0, VCXO_OUT, NONE, SSP2, NONE, MMC3), + MFPR_910(GPIO51, 0x1A8, GPIO, UART2, PWM1, TWSI, SSP0, NONE, DSSP3, NONE), + MFPR_910(GPIO52, 0x1AC, GPIO, UART2, DAC_ST23, TWSI, SSP0, NONE, DSSP3, NONE), + MFPR_910(GPIO53, 0x1B0, GPIO, UART2, TWSI, NONE, SSP0, NONE, DSSP3, NONE), + MFPR_910(GPIO54, 0x1B4, GPIO, UART2, TWSI, SSP0, NONE, NONE, DSSP3, NONE), + MFPR_910(GPIO55, 0x2F0, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO56, 0x2F4, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO57, 0x2F8, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO58, 0x2FC, TDS, GPIO, TB, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO59, 0x300, TDS, GPIO, TCU_GPOA, TCU_GPOB, ONE_WIRE, NONE, NONE, NONE), + MFPR_910(GPIO60, 0x304, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO61, 0x308, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO62, 0x30C, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO63, 0x310, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO64, 0x314, GPIO, SPI2, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO65, 0x318, GPIO, SPI2, NONE, NONE, NONE, NONE, ONE_WIRE, HSL), + MFPR_910(GPIO66, 0x31C, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, HSL), + MFPR_910(GPIO67, 0x1B8, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, USIM2), + MFPR_910(GPIO68, 0x1BC, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, USIM2), + MFPR_910(GPIO69, 0x1C0, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, USIM2), + MFPR_910(GPIO70, 0x1C4, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO71, 0x1C8, GPIO, CCIC, SPI, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO72, 0x1CC, GPIO, CCIC, EXT_DMA, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO73, 0x1D0, GPIO, CCIC, EXT_DMA, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO74, 0x1D4, GPIO, CCIC, EXT_DMA, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO75, 0x1D8, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO76, 0x1DC, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO77, 0x1E0, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO78, 0x1E4, GPIO, CCIC, NONE, NONE, NONE, ULPI, NONE, NONE), + MFPR_910(GPIO79, 0x1E8, GPIO, TWSI, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO80, 0x1EC, GPIO, TWSI, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO81, 0x1F0, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO82, 0x1F4, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO83, 0x1F8, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO84, 0x1FC, GPIO, LCD, VCXO_REQ2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO85, 0x200, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO86, 0x204, GPIO, LCD, VCXO_OUT2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO87, 0x208, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO88, 0x20C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO89, 0x210, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO90, 0x214, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO91, 0x218, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO92, 0x21C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO93, 0x220, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO94, 0x224, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO95, 0x228, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO96, 0x22C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO97, 0x230, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO98, 0x234, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO99, 0x0B0, MMC1, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO100, 0x238, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO101, 0x23C, GPIO, LCD, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO102, 0x240, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, SPI2), + MFPR_910(GPIO103, 0x244, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, SPI2), + MFPR_910(GPIO104, 0x248, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO105, 0x24C, GPIO, LCD, DSSP2, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO106, 0x250, GPIO, LCD, DSSP3, ONE_WIRE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO107, 0x254, GPIO, LCD, DSSP3, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO108, 0x258, GPIO, LCD, DSSP3, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO109, 0x25C, GPIO, LCD, DSSP3, SPI, NONE, NONE, NONE, NONE), + MFPR_910(GPIO110, 0x298, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO111, 0x29C, GPIO, NONE, DSSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO112, 0x2A0, GPIO, NONE, DSSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO113, 0x2A4, GPIO, NONE, DSSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO114, 0x2A8, GPIO, NONE, DSSP3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO115, 0x2AC, GPIO, NONE, DSSP3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO116, 0x2B0, GPIO, NONE, DSSP3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO117, 0x0B4, PRI_JTAG, GPIO, PWM0, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO118, 0x0B8, PRI_JTAG, GPIO, PWM1, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO119, 0x0BC, PRI_JTAG, GPIO, PWM2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO120, 0x0C0, PRI_JTAG, GPIO, PWM3, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO121, 0x32C, GPIO, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO122, 0x0C8, RESET, GPIO, 32K_CLK, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO123, 0x0CC, CLK_REQ, GPIO, ONE_WIRE, EXT_DMA, NONE, NONE, NONE, NONE), + MFPR_910(GPIO124, 0x0D0, GPIO, MN_CLK, DAC_ST23, NONE, NONE, NONE, NONE, NONE), + MFPR_910(GPIO125, 0x0D4, VCXO_REQ, GPIO, NONE, EXT_INT, NONE, NONE, NONE, NONE), + MFPR_910(GPIO126, 0x06C, GPIO, SMC, NONE, SM_ADDR18, NONE, EXT_DMA, NONE, NONE), + MFPR_910(GPIO127, 0x070, GPIO, SMC, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO15, 0x004, NAND, GPIO, USIM2, EXT_DMA, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO14, 0x008, NAND, GPIO, USIM2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO13, 0x00C, NAND, GPIO, USIM2, EXT_INT, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO12, 0x010, NAND, GPIO, SSP2, EXT_INT, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO11, 0x014, NAND, GPIO, SSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO10, 0x018, NAND, GPIO, SSP2, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO9, 0x01C, NAND, GPIO, SSP2, NONE, VCXO_OUT2, NONE, NONE, NONE), + MFPR_910(ND_IO8, 0x020, NAND, GPIO, NONE, NONE, PWM3, NONE, NONE, NONE), + MFPR_910(ND_IO7, 0x024, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO6, 0x028, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO5, 0x02C, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO4, 0x030, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO3, 0x034, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO2, 0x038, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO1, 0x03C, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_IO0, 0x040, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_NCS0, 0x044, NAND, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_NCS1, 0x048, NAND, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(SM_NCS0, 0x04C, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(SM_NCS1, 0x050, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_NWE, 0x054, GPIO, NAND, NONE, SM_ADDR20, NONE, SMC, NONE, NONE), + MFPR_910(ND_NRE, 0x058, GPIO, NAND, NONE, SMC, NONE, EXT_DMA, NONE, NONE), + MFPR_910(ND_CLE, 0x05C, NAND, MMC3, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_ALE, 0x060, GPIO, NAND, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(SM_SCLK, 0x064, MMC3, NONE, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_RDY0, 0x068, NAND, GPIO, NONE, SMC, NONE, NONE, NONE, NONE), + MFPR_910(SM_ADV, 0x074, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(ND_RDY1, 0x078, NAND, GPIO, NONE, SMC, NONE, NONE, NONE, NONE), + MFPR_910(SM_ADVMUX, 0x07C, SMC, GPIO, NONE, SM_ADDR19, NONE, NONE, NONE, NONE), + MFPR_910(SM_RDY, 0x080, SMC, GPIO, NONE, NONE, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT7, 0x084, MMC1, GPIO, SEC1_JTAG, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT6, 0x088, MMC1, GPIO, SEC1_JTAG, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT5, 0x08C, MMC1, GPIO, SEC1_JTAG, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT4, 0x090, MMC1, GPIO, NONE, TB, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT3, 0x094, MMC1, HSL, SEC2_JTAG, SSP0, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_DAT2, 0x098, MMC1, HSL, SEC2_JTAG, SSP2, SSP0, NONE, NONE, NONE), + MFPR_910(MMC1_DAT1, 0x09C, MMC1, HSL, SEC2_JTAG, SSP2, SSP0, NONE, NONE, NONE), + MFPR_910(MMC1_DAT0, 0x0A0, MMC1, HSL, SEC2_JTAG, SSP2, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_CMD, 0x0A4, MMC1, HSL, SEC1_JTAG, SSP2, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_CLK, 0x0A8, MMC1, HSL, SEC2_JTAG, SSP0, NONE, NONE, NONE, NONE), + MFPR_910(MMC1_CD, 0x0AC, MMC1, GPIO, SEC1_JTAG, NONE, NONE, NONE, NONE, NONE), + MFPR_910(VCXO_OUT, 0x0D8, VCXO_OUT, PWM3, NONE, NONE, NONE, NONE, NONE, NONE), +}; + + +static const unsigned p910_usim2_pin1[] = {GPIO67, GPIO68, GPIO69}; +static const unsigned p910_usim2_pin2[] = {ND_IO15, ND_IO14, ND_IO13}; +static const unsigned p910_mmc1_pin1[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5, + MMC1_DAT4, MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, MMC1_DAT0, MMC1_CMD, + MMC1_CLK, MMC1_CD, GPIO99}; +static const unsigned p910_mmc2_pin1[] = {GPIO33, GPIO34, GPIO35, GPIO36, + GPIO37, GPIO38, GPIO39, GPIO40, GPIO41, GPIO42}; +static const unsigned p910_mmc3_pin1[] = {GPIO33, GPIO34, GPIO35, GPIO36, + GPIO49, GPIO50}; +static const unsigned p910_mmc3_pin2[] = {ND_IO7, ND_IO6, ND_IO5, ND_IO4, + ND_IO3, ND_IO2, ND_IO1, ND_IO0, ND_CLE, SM_SCLK}; +static const unsigned p910_uart0_pin1[] = {GPIO29, GPIO30, GPIO31, GPIO32}; +static const unsigned p910_uart1_pin1[] = {GPIO47, GPIO48}; +static const unsigned p910_uart1_pin2[] = {GPIO31, GPIO32}; +static const unsigned p910_uart1_pin3[] = {GPIO45, GPIO46}; +static const unsigned p910_uart1_pin4[] = {GPIO29, GPIO30, GPIO31, GPIO32}; +static const unsigned p910_uart1_pin5[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_uart2_pin1[] = {GPIO43, GPIO44}; +static const unsigned p910_uart2_pin2[] = {GPIO51, GPIO52}; +static const unsigned p910_uart2_pin3[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_uart2_pin4[] = {GPIO51, GPIO52, GPIO53, GPIO54}; +static const unsigned p910_twsi_pin1[] = {GPIO51, GPIO52}; +static const unsigned p910_twsi_pin2[] = {GPIO53, GPIO54}; +static const unsigned p910_twsi_pin3[] = {GPIO79, GPIO80}; +static const unsigned p910_ccic_pin1[] = {GPIO67, GPIO68, GPIO69, GPIO70, + GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78}; +static const unsigned p910_lcd_pin1[] = {GPIO81, GPIO82, GPIO83, GPIO84, + GPIO85, GPIO86, GPIO87, GPIO88, GPIO89, GPIO90, GPIO91, GPIO92, + GPIO93, GPIO94, GPIO95, GPIO96, GPIO97, GPIO98, GPIO100, GPIO101, + GPIO102, GPIO103}; +static const unsigned p910_spi_pin1[] = {GPIO104, GPIO105, GPIO107, GPIO108}; +static const unsigned p910_spi_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_spi_pin3[] = {GPIO33, GPIO34, GPIO35, GPIO36, + GPIO37}; +static const unsigned p910_spi_pin4[] = {GPIO67, GPIO68, GPIO69, GPIO70, + GPIO71}; +static const unsigned p910_spi2_pin1[] = {GPIO64, GPIO65}; +static const unsigned p910_spi2_pin2[] = {GPIO102, GPIO103}; +static const unsigned p910_dssp2_pin1[] = {GPIO102, GPIO103, GPIO104, GPIO105}; +static const unsigned p910_dssp2_pin2[] = {GPIO43, GPIO44, GPIO45, GPIO46}; +static const unsigned p910_dssp2_pin3[] = {GPIO111, GPIO112, GPIO113}; +static const unsigned p910_dssp3_pin1[] = {GPIO106, GPIO107, GPIO108, GPIO109}; +static const unsigned p910_dssp3_pin2[] = {GPIO51, GPIO52, GPIO53, GPIO54}; +static const unsigned p910_dssp3_pin3[] = {GPIO114, GPIO115, GPIO116}; +static const unsigned p910_ssp0_pin1[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, + MMC1_CLK}; +static const unsigned p910_ssp0_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36}; +static const unsigned p910_ssp0_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50}; +static const unsigned p910_ssp0_pin4[] = {GPIO51, GPIO52, GPIO53, GPIO54}; +static const unsigned p910_ssp1_pin1[] = {GPIO21, GPIO22, GPIO23, GPIO24}; +static const unsigned p910_ssp1_pin2[] = {GPIO20, GPIO21, GPIO22, GPIO23, + GPIO24}; +static const unsigned p910_ssp2_pin1[] = {MMC1_DAT2, MMC1_DAT1, MMC1_DAT0, + MMC1_CMD}; +static const unsigned p910_ssp2_pin2[] = {GPIO33, GPIO34, GPIO35, GPIO36}; +static const unsigned p910_ssp2_pin3[] = {GPIO47, GPIO48, GPIO49, GPIO50}; +static const unsigned p910_ssp2_pin4[] = {ND_IO12, ND_IO11, ND_IO10, ND_IO9}; +static const unsigned p910_gssp_pin1[] = {GPIO25, GPIO26, GPIO27, GPIO28}; +static const unsigned p910_pwm0_pin1[] = {GPIO117}; +static const unsigned p910_pwm1_pin1[] = {GPIO118}; +static const unsigned p910_pwm1_pin2[] = {GPIO51}; +static const unsigned p910_pwm2_pin1[] = {GPIO119}; +static const unsigned p910_pwm3_pin1[] = {GPIO120}; +static const unsigned p910_pwm3_pin2[] = {ND_IO8}; +static const unsigned p910_pwm3_pin3[] = {VCXO_OUT}; +static const unsigned p910_pri_jtag_pin1[] = {GPIO117, GPIO118, GPIO119, + GPIO120}; +static const unsigned p910_sec1_jtag_pin1[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5, + MMC1_CMD, MMC1_CD}; +static const unsigned p910_sec2_jtag_pin1[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, + MMC1_DAT0, MMC1_CLK}; +static const unsigned p910_hsl_pin1[] = {GPIO37, GPIO38, GPIO39, GPIO40, + GPIO41, GPIO42}; +static const unsigned p910_hsl_pin2[] = {GPIO61, GPIO62, GPIO63, GPIO64, + GPIO65, GPIO66}; +static const unsigned p910_hsl_pin3[] = {MMC1_DAT3, MMC1_DAT2, MMC1_DAT1, + MMC1_DAT0, MMC1_CMD, MMC1_CLK}; +static const unsigned p910_w1_pin1[] = {GPIO59}; +static const unsigned p910_w1_pin2[] = {GPIO65}; +static const unsigned p910_w1_pin3[] = {GPIO106}; +static const unsigned p910_w1_pin4[] = {GPIO123}; +static const unsigned p910_kpmk_pin1[] = {GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, + GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO10, GPIO11, GPIO12, GPIO13, + GPIO14, GPIO15}; +static const unsigned p910_kpmk_pin2[] = {GPIO0, GPIO1, GPIO2, GPIO3, GPIO4, + GPIO5, GPIO6, GPIO7, GPIO8, GPIO9, GPIO12}; +static const unsigned p910_kpdk_pin1[] = {GPIO12, GPIO13, GPIO14, GPIO15, + GPIO16, GPIO17, GPIO18, GPIO19}; +static const unsigned p910_tds_pin1[] = {GPIO55, GPIO56, GPIO57, GPIO58, + GPIO59}; +static const unsigned p910_tds_pin2[] = {GPIO55, GPIO57, GPIO58, GPIO59}; +static const unsigned p910_tb_pin1[] = {GPIO14, GPIO15, GPIO16, GPIO17}; +static const unsigned p910_tb_pin2[] = {GPIO55, GPIO56, GPIO57, GPIO58}; +static const unsigned p910_tb_pin3[] = {MMC1_DAT7, MMC1_DAT6, MMC1_DAT5, + MMC1_DAT4}; +static const unsigned p910_ext_dma0_pin1[] = {GPIO72}; +static const unsigned p910_ext_dma0_pin2[] = {ND_IO15}; +static const unsigned p910_ext_dma0_pin3[] = {ND_NRE}; +static const unsigned p910_ext_dma1_pin1[] = {GPIO73}; +static const unsigned p910_ext_dma1_pin2[] = {GPIO123}; +static const unsigned p910_ext_dma1_pin3[] = {GPIO126}; +static const unsigned p910_ext_dma2_pin1[] = {GPIO74}; +static const unsigned p910_ext0_int_pin1[] = {GPIO44}; +static const unsigned p910_ext0_int_pin2[] = {ND_IO13}; +static const unsigned p910_ext1_int_pin1[] = {GPIO45}; +static const unsigned p910_ext1_int_pin2[] = {ND_IO12}; +static const unsigned p910_ext2_int_pin1[] = {GPIO46}; +static const unsigned p910_ext2_int_pin2[] = {GPIO125}; +static const unsigned p910_dac_st23_pin1[] = {GPIO32}; +static const unsigned p910_dac_st23_pin2[] = {GPIO43}; +static const unsigned p910_dac_st23_pin3[] = {GPIO52}; +static const unsigned p910_dac_st23_pin4[] = {GPIO124}; +static const unsigned p910_vcxo_out_pin1[] = {GPIO50}; +static const unsigned p910_vcxo_out_pin2[] = {VCXO_OUT}; +static const unsigned p910_vcxo_out_pin3[] = {GPIO20}; +static const unsigned p910_vcxo_req_pin1[] = {GPIO49}; +static const unsigned p910_vcxo_req_pin2[] = {GPIO125}; +static const unsigned p910_vcxo_out2_pin1[] = {GPIO86}; +static const unsigned p910_vcxo_out2_pin2[] = {ND_IO9}; +static const unsigned p910_vcxo_req2_pin1[] = {GPIO84}; +static const unsigned p910_ulpi_pin1[] = {GPIO67, GPIO68, GPIO69, GPIO70, + GPIO71, GPIO72, GPIO73, GPIO74, GPIO75, GPIO76, GPIO77, GPIO78}; +static const unsigned p910_nand_pin1[] = {ND_IO15, ND_IO14, ND_IO13, ND_IO12, + ND_IO11, ND_IO10, ND_IO9, ND_IO8, ND_IO7, ND_IO6, ND_IO5, ND_IO4, + ND_IO3, ND_IO2, ND_IO1, ND_IO0, ND_NCS0, ND_NWE, ND_NRE, ND_CLE, + ND_ALE, ND_RDY0}; +static const unsigned p910_gpio0_pin1[] = {GPIO0}; +static const unsigned p910_gpio0_pin2[] = {SM_ADV}; +static const unsigned p910_gpio1_pin1[] = {GPIO1}; +static const unsigned p910_gpio1_pin2[] = {ND_RDY1}; +static const unsigned p910_gpio2_pin1[] = {GPIO2}; +static const unsigned p910_gpio2_pin2[] = {SM_ADVMUX}; +static const unsigned p910_gpio3_pin1[] = {GPIO3}; +static const unsigned p910_gpio3_pin2[] = {SM_RDY}; +static const unsigned p910_gpio20_pin1[] = {GPIO20}; +static const unsigned p910_gpio20_pin2[] = {ND_IO15}; +static const unsigned p910_gpio20_pin3[] = {MMC1_DAT6}; +static const unsigned p910_gpio21_pin1[] = {GPIO21}; +static const unsigned p910_gpio21_pin2[] = {ND_IO14}; +static const unsigned p910_gpio21_pin3[] = {MMC1_DAT5}; +static const unsigned p910_gpio22_pin1[] = {GPIO22}; +static const unsigned p910_gpio22_pin2[] = {ND_IO13}; +static const unsigned p910_gpio22_pin3[] = {MMC1_DAT4}; +static const unsigned p910_gpio23_pin1[] = {GPIO23}; +static const unsigned p910_gpio23_pin2[] = {ND_IO12}; +static const unsigned p910_gpio23_pin3[] = {MMC1_CD}; +static const unsigned p910_gpio24_pin1[] = {GPIO24}; +static const unsigned p910_gpio24_pin2[] = {ND_IO11}; +static const unsigned p910_gpio24_pin3[] = {MMC1_DAT7}; +static const unsigned p910_gpio25_pin1[] = {GPIO25}; +static const unsigned p910_gpio25_pin2[] = {ND_IO10}; +static const unsigned p910_gpio26_pin1[] = {GPIO26}; +static const unsigned p910_gpio26_pin2[] = {ND_IO9}; +static const unsigned p910_gpio27_pin1[] = {GPIO27}; +static const unsigned p910_gpio27_pin2[] = {ND_IO8}; +static const unsigned p910_gpio85_pin1[] = {GPIO85}; +static const unsigned p910_gpio85_pin2[] = {ND_NCS0}; +static const unsigned p910_gpio86_pin1[] = {GPIO86}; +static const unsigned p910_gpio86_pin2[] = {ND_NCS1}; +static const unsigned p910_gpio87_pin1[] = {GPIO87}; +static const unsigned p910_gpio87_pin2[] = {SM_NCS0}; +static const unsigned p910_gpio88_pin1[] = {GPIO88}; +static const unsigned p910_gpio88_pin2[] = {SM_NCS1}; +static const unsigned p910_gpio89_pin1[] = {GPIO89}; +static const unsigned p910_gpio89_pin2[] = {ND_NWE}; +static const unsigned p910_gpio90_pin1[] = {GPIO90}; +static const unsigned p910_gpio90_pin2[] = {ND_NRE}; +static const unsigned p910_gpio91_pin1[] = {GPIO91}; +static const unsigned p910_gpio91_pin2[] = {ND_ALE}; +static const unsigned p910_gpio92_pin1[] = {GPIO92}; +static const unsigned p910_gpio92_pin2[] = {ND_RDY0}; + +static struct pxa3xx_pin_group pxa910_grps[] = { + GRP_910("usim2 3p1", USIM2, p910_usim2_pin1), + GRP_910("usim2 3p2", USIM2, p910_usim2_pin2), + GRP_910("mmc1 12p", MMC1, p910_mmc1_pin1), + GRP_910("mmc2 10p", MMC2, p910_mmc2_pin1), + GRP_910("mmc3 6p", MMC3, p910_mmc3_pin1), + GRP_910("mmc3 10p", MMC3, p910_mmc3_pin2), + GRP_910("uart0 4p", UART0, p910_uart0_pin1), + GRP_910("uart1 2p1", UART1, p910_uart1_pin1), + GRP_910("uart1 2p2", UART1, p910_uart1_pin2), + GRP_910("uart1 2p3", UART1, p910_uart1_pin3), + GRP_910("uart1 4p4", UART1, p910_uart1_pin4), + GRP_910("uart1 4p5", UART1, p910_uart1_pin5), + GRP_910("uart2 2p1", UART2, p910_uart2_pin1), + GRP_910("uart2 2p2", UART2, p910_uart2_pin2), + GRP_910("uart2 4p3", UART2, p910_uart2_pin3), + GRP_910("uart2 4p4", UART2, p910_uart2_pin4), + GRP_910("twsi 2p1", TWSI, p910_twsi_pin1), + GRP_910("twsi 2p2", TWSI, p910_twsi_pin2), + GRP_910("twsi 2p3", TWSI, p910_twsi_pin3), + GRP_910("ccic", CCIC, p910_ccic_pin1), + GRP_910("lcd", LCD, p910_lcd_pin1), + GRP_910("spi 4p1", SPI, p910_spi_pin1), + GRP_910("spi 4p2", SPI, p910_spi_pin2), + GRP_910("spi 5p3", SPI, p910_spi_pin3), + GRP_910("spi 5p4", SPI, p910_spi_pin4), + GRP_910("dssp2 4p1", DSSP2, p910_dssp2_pin1), + GRP_910("dssp2 4p2", DSSP2, p910_dssp2_pin2), + GRP_910("dssp2 3p3", DSSP2, p910_dssp2_pin3), + GRP_910("dssp3 4p1", DSSP3, p910_dssp3_pin1), + GRP_910("dssp3 4p2", DSSP3, p910_dssp3_pin2), + GRP_910("dssp3 3p3", DSSP3, p910_dssp3_pin3), + GRP_910("ssp0 4p1", SSP0, p910_ssp0_pin1), + GRP_910("ssp0 4p2", SSP0, p910_ssp0_pin2), + GRP_910("ssp0 4p3", SSP0, p910_ssp0_pin3), + GRP_910("ssp0 4p4", SSP0, p910_ssp0_pin4), + GRP_910("ssp1 4p1", SSP1, p910_ssp1_pin1), + GRP_910("ssp1 5p2", SSP1, p910_ssp1_pin2), + GRP_910("ssp2 4p1", SSP2, p910_ssp2_pin1), + GRP_910("ssp2 4p2", SSP2, p910_ssp2_pin2), + GRP_910("ssp2 4p3", SSP2, p910_ssp2_pin3), + GRP_910("ssp2 4p4", SSP2, p910_ssp2_pin4), + GRP_910("gssp", GSSP, p910_gssp_pin1), + GRP_910("pwm0", PWM0, p910_pwm0_pin1), + GRP_910("pwm1-1", PWM1, p910_pwm1_pin1), + GRP_910("pwm1-2", PWM1, p910_pwm1_pin2), + GRP_910("pwm2", PWM2, p910_pwm2_pin1), + GRP_910("pwm3-1", PWM3, p910_pwm3_pin1), + GRP_910("pwm3-2", PWM3, p910_pwm3_pin2), + GRP_910("pwm3-3", PWM3, p910_pwm3_pin3), + GRP_910("pri jtag", PRI_JTAG, p910_pri_jtag_pin1), + GRP_910("sec1 jtag", SEC1_JTAG, p910_sec1_jtag_pin1), + GRP_910("sec2 jtag", SEC2_JTAG, p910_sec2_jtag_pin1), + GRP_910("hsl 6p1", HSL, p910_hsl_pin1), + GRP_910("hsl 6p2", HSL, p910_hsl_pin2), + GRP_910("hsl 6p3", HSL, p910_hsl_pin3), + GRP_910("w1-1", ONE_WIRE, p910_w1_pin1), + GRP_910("w1-2", ONE_WIRE, p910_w1_pin2), + GRP_910("w1-3", ONE_WIRE, p910_w1_pin3), + GRP_910("w1-4", ONE_WIRE, p910_w1_pin4), + GRP_910("kpmk 16p1", KP_MK, p910_kpmk_pin1), + GRP_910("kpmk 11p2", KP_MK, p910_kpmk_pin2), + GRP_910("kpdk 8p1", KP_DK, p910_kpdk_pin1), + GRP_910("tds 5p1", TDS, p910_tds_pin1), + GRP_910("tds 4p2", TDS, p910_tds_pin2), + GRP_910("tb 4p1", TB, p910_tb_pin1), + GRP_910("tb 4p2", TB, p910_tb_pin2), + GRP_910("tb 4p3", TB, p910_tb_pin3), + GRP_910("ext dma0-1", EXT_DMA, p910_ext_dma0_pin1), + GRP_910("ext dma0-2", EXT_DMA, p910_ext_dma0_pin2), + GRP_910("ext dma0-3", EXT_DMA, p910_ext_dma0_pin3), + GRP_910("ext dma1-1", EXT_DMA, p910_ext_dma1_pin1), + GRP_910("ext dma1-2", EXT_DMA, p910_ext_dma1_pin2), + GRP_910("ext dma1-3", EXT_DMA, p910_ext_dma1_pin3), + GRP_910("ext dma2", EXT_DMA, p910_ext_dma2_pin1), + GRP_910("ext0 int-1", EXT_INT, p910_ext0_int_pin1), + GRP_910("ext0 int-2", EXT_INT, p910_ext0_int_pin2), + GRP_910("ext1 int-1", EXT_INT, p910_ext1_int_pin1), + GRP_910("ext1 int-2", EXT_INT, p910_ext1_int_pin2), + GRP_910("ext2 int-1", EXT_INT, p910_ext2_int_pin1), + GRP_910("ext2 int-2", EXT_INT, p910_ext2_int_pin2), + GRP_910("dac st23-1", DAC_ST23, p910_dac_st23_pin1), + GRP_910("dac st23-2", DAC_ST23, p910_dac_st23_pin2), + GRP_910("dac st23-3", DAC_ST23, p910_dac_st23_pin3), + GRP_910("dac st23-4", DAC_ST23, p910_dac_st23_pin4), + GRP_910("vcxo out-1", VCXO_OUT, p910_vcxo_out_pin1), + GRP_910("vcxo out-2", VCXO_OUT, p910_vcxo_out_pin2), + GRP_910("vcxo out-3", VCXO_OUT, p910_vcxo_out_pin3), + GRP_910("vcxo req-1", VCXO_REQ, p910_vcxo_req_pin1), + GRP_910("vcxo req-2", VCXO_REQ, p910_vcxo_req_pin2), + GRP_910("vcxo out2-1", VCXO_OUT2, p910_vcxo_out2_pin1), + GRP_910("vcxo out2-2", VCXO_OUT2, p910_vcxo_out2_pin2), + GRP_910("vcxo req2", VCXO_REQ2, p910_vcxo_req2_pin1), + GRP_910("ulpi", ULPI, p910_ulpi_pin1), + GRP_910("nand", NAND, p910_nand_pin1), + GRP_910("gpio0-1", GPIO, p910_gpio0_pin1), + GRP_910("gpio0-2", GPIO, p910_gpio0_pin2), + GRP_910("gpio1-1", GPIO, p910_gpio1_pin1), + GRP_910("gpio1-2", GPIO, p910_gpio1_pin2), + GRP_910("gpio2-1", GPIO, p910_gpio2_pin1), + GRP_910("gpio2-2", GPIO, p910_gpio2_pin2), + GRP_910("gpio3-1", GPIO, p910_gpio3_pin1), + GRP_910("gpio3-2", GPIO, p910_gpio3_pin2), + GRP_910("gpio20-1", GPIO, p910_gpio20_pin1), + GRP_910("gpio20-2", GPIO, p910_gpio20_pin2), + GRP_910("gpio21-1", GPIO, p910_gpio21_pin1), + GRP_910("gpio21-2", GPIO, p910_gpio21_pin2), + GRP_910("gpio22-1", GPIO, p910_gpio22_pin1), + GRP_910("gpio22-2", GPIO, p910_gpio22_pin2), + GRP_910("gpio23-1", GPIO, p910_gpio23_pin1), + GRP_910("gpio23-2", GPIO, p910_gpio23_pin2), + GRP_910("gpio24-1", GPIO, p910_gpio24_pin1), + GRP_910("gpio24-2", GPIO, p910_gpio24_pin2), + GRP_910("gpio25-1", GPIO, p910_gpio25_pin1), + GRP_910("gpio25-2", GPIO, p910_gpio25_pin2), + GRP_910("gpio26-1", GPIO, p910_gpio26_pin1), + GRP_910("gpio26-2", GPIO, p910_gpio26_pin2), + GRP_910("gpio27-1", GPIO, p910_gpio27_pin1), + GRP_910("gpio27-2", GPIO, p910_gpio27_pin2), + GRP_910("gpio85-1", GPIO, p910_gpio85_pin1), + GRP_910("gpio85-2", GPIO, p910_gpio85_pin2), + GRP_910("gpio86-1", GPIO, p910_gpio86_pin1), + GRP_910("gpio86-2", GPIO, p910_gpio86_pin2), + GRP_910("gpio87-1", GPIO, p910_gpio87_pin1), + GRP_910("gpio87-2", GPIO, p910_gpio87_pin2), + GRP_910("gpio88-1", GPIO, p910_gpio88_pin1), + GRP_910("gpio88-2", GPIO, p910_gpio88_pin2), + GRP_910("gpio89-1", GPIO, p910_gpio89_pin1), + GRP_910("gpio89-2", GPIO, p910_gpio89_pin2), + GRP_910("gpio90-1", GPIO, p910_gpio90_pin1), + GRP_910("gpio90-2", GPIO, p910_gpio90_pin2), + GRP_910("gpio91-1", GPIO, p910_gpio91_pin1), + GRP_910("gpio91-2", GPIO, p910_gpio91_pin2), + GRP_910("gpio92-1", GPIO, p910_gpio92_pin1), + GRP_910("gpio92-2", GPIO, p910_gpio92_pin2), +}; + +static const char * const p910_usim2_grps[] = {"usim2 3p1", "usim2 3p2"}; +static const char * const p910_mmc1_grps[] = {"mmc1 12p"}; +static const char * const p910_mmc2_grps[] = {"mmc2 10p"}; +static const char * const p910_mmc3_grps[] = {"mmc3 6p", "mmc3 10p"}; +static const char * const p910_uart0_grps[] = {"uart0 4p"}; +static const char * const p910_uart1_grps[] = {"uart1 2p1", "uart1 2p2", + "uart1 2p3", "uart1 4p4", "uart1 4p5"}; +static const char * const p910_uart2_grps[] = {"uart2 2p1", "uart2 2p2", + "uart2 4p3", "uart2 4p4"}; +static const char * const p910_twsi_grps[] = {"twsi 2p1", "twsi 2p2", + "twsi 2p3"}; +static const char * const p910_ccic_grps[] = {"ccic"}; +static const char * const p910_lcd_grps[] = {"lcd"}; +static const char * const p910_spi_grps[] = {"spi 4p1", "spi 4p2", "spi 5p3", + "spi 5p4"}; +static const char * const p910_dssp2_grps[] = {"dssp2 4p1", "dssp2 4p2", + "dssp2 3p3"}; +static const char * const p910_dssp3_grps[] = {"dssp3 4p1", "dssp3 4p2", + "dssp3 3p3"}; +static const char * const p910_ssp0_grps[] = {"ssp0 4p1", "ssp0 4p2", + "ssp0 4p3", "ssp0 4p4"}; +static const char * const p910_ssp1_grps[] = {"ssp1 4p1", "ssp1 5p2"}; +static const char * const p910_ssp2_grps[] = {"ssp2 4p1", "ssp2 4p2", + "ssp2 4p3", "ssp2 4p4"}; +static const char * const p910_gssp_grps[] = {"gssp"}; +static const char * const p910_pwm0_grps[] = {"pwm0"}; +static const char * const p910_pwm1_grps[] = {"pwm1-1", "pwm1-2"}; +static const char * const p910_pwm2_grps[] = {"pwm2"}; +static const char * const p910_pwm3_grps[] = {"pwm3-1", "pwm3-2", "pwm3-3"}; +static const char * const p910_pri_jtag_grps[] = {"pri jtag"}; +static const char * const p910_sec1_jtag_grps[] = {"sec1 jtag"}; +static const char * const p910_sec2_jtag_grps[] = {"sec2 jtag"}; +static const char * const p910_hsl_grps[] = {"hsl 6p1", "hsl 6p2", "hsl 6p3"}; +static const char * const p910_w1_grps[] = {"w1-1", "w1-2", "w1-3", "w1-4"}; +static const char * const p910_kpmk_grps[] = {"kpmk 16p1", "kpmk 11p2"}; +static const char * const p910_kpdk_grps[] = {"kpdk 8p1"}; +static const char * const p910_tds_grps[] = {"tds 5p1", "tds 4p2"}; +static const char * const p910_tb_grps[] = {"tb 4p1", "tb 4p2", "tb 4p3"}; +static const char * const p910_dma0_grps[] = {"ext dma0-1", "ext dma0-2", + "ext dma0-3"}; +static const char * const p910_dma1_grps[] = {"ext dma1-1", "ext dma1-2", + "ext dma1-3"}; +static const char * const p910_dma2_grps[] = {"ext dma2"}; +static const char * const p910_int0_grps[] = {"ext0 int-1", "ext0 int-2"}; +static const char * const p910_int1_grps[] = {"ext1 int-1", "ext1 int-2"}; +static const char * const p910_int2_grps[] = {"ext2 int-1", "ext2 int-2"}; +static const char * const p910_dac_st23_grps[] = {"dac st23-1", "dac st23-2", + "dac st23-3", "dac st23-4"}; +static const char * const p910_vcxo_out_grps[] = {"vcxo out-1", "vcxo out-2", + "vcxo out-3"}; +static const char * const p910_vcxo_req_grps[] = {"vcxo req-1", "vcxo req-2"}; +static const char * const p910_vcxo_out2_grps[] = {"vcxo out2-1", + "vcxo out2-2"}; +static const char * const p910_vcxo_req2_grps[] = {"vcxo req2"}; +static const char * const p910_ulpi_grps[] = {"ulpi"}; +static const char * const p910_nand_grps[] = {"nand"}; +static const char * const p910_gpio0_grps[] = {"gpio0-1", "gpio0-2"}; +static const char * const p910_gpio1_grps[] = {"gpio1-1", "gpio1-2"}; +static const char * const p910_gpio2_grps[] = {"gpio2-1", "gpio2-2"}; +static const char * const p910_gpio3_grps[] = {"gpio3-1", "gpio3-2"}; +static const char * const p910_gpio20_grps[] = {"gpio20-1", "gpio20-2"}; +static const char * const p910_gpio21_grps[] = {"gpio21-1", "gpio21-2"}; +static const char * const p910_gpio22_grps[] = {"gpio22-1", "gpio22-2"}; +static const char * const p910_gpio23_grps[] = {"gpio23-1", "gpio23-2"}; +static const char * const p910_gpio24_grps[] = {"gpio24-1", "gpio24-2"}; +static const char * const p910_gpio25_grps[] = {"gpio25-1", "gpio25-2"}; +static const char * const p910_gpio26_grps[] = {"gpio26-1", "gpio26-2"}; +static const char * const p910_gpio27_grps[] = {"gpio27-1", "gpio27-2"}; +static const char * const p910_gpio85_grps[] = {"gpio85-1", "gpio85-2"}; +static const char * const p910_gpio86_grps[] = {"gpio86-1", "gpio86-2"}; +static const char * const p910_gpio87_grps[] = {"gpio87-1", "gpio87-2"}; +static const char * const p910_gpio88_grps[] = {"gpio88-1", "gpio88-2"}; +static const char * const p910_gpio89_grps[] = {"gpio89-1", "gpio89-2"}; +static const char * const p910_gpio90_grps[] = {"gpio90-1", "gpio90-2"}; +static const char * const p910_gpio91_grps[] = {"gpio91-1", "gpio91-2"}; +static const char * const p910_gpio92_grps[] = {"gpio92-1", "gpio92-2"}; + +static struct pxa3xx_pmx_func pxa910_funcs[] = { + {"usim2", ARRAY_AND_SIZE(p910_usim2_grps)}, + {"mmc1", ARRAY_AND_SIZE(p910_mmc1_grps)}, + {"mmc2", ARRAY_AND_SIZE(p910_mmc2_grps)}, + {"mmc3", ARRAY_AND_SIZE(p910_mmc3_grps)}, + {"uart0", ARRAY_AND_SIZE(p910_uart0_grps)}, + {"uart1", ARRAY_AND_SIZE(p910_uart1_grps)}, + {"uart2", ARRAY_AND_SIZE(p910_uart2_grps)}, + {"twsi", ARRAY_AND_SIZE(p910_twsi_grps)}, + {"ccic", ARRAY_AND_SIZE(p910_ccic_grps)}, + {"lcd", ARRAY_AND_SIZE(p910_lcd_grps)}, + {"spi", ARRAY_AND_SIZE(p910_spi_grps)}, + {"dssp2", ARRAY_AND_SIZE(p910_dssp2_grps)}, + {"dssp3", ARRAY_AND_SIZE(p910_dssp3_grps)}, + {"ssp0", ARRAY_AND_SIZE(p910_ssp0_grps)}, + {"ssp1", ARRAY_AND_SIZE(p910_ssp1_grps)}, + {"ssp2", ARRAY_AND_SIZE(p910_ssp2_grps)}, + {"gssp", ARRAY_AND_SIZE(p910_gssp_grps)}, + {"pwm0", ARRAY_AND_SIZE(p910_pwm0_grps)}, + {"pwm1", ARRAY_AND_SIZE(p910_pwm1_grps)}, + {"pwm2", ARRAY_AND_SIZE(p910_pwm2_grps)}, + {"pwm3", ARRAY_AND_SIZE(p910_pwm3_grps)}, + {"pri_jtag", ARRAY_AND_SIZE(p910_pri_jtag_grps)}, + {"sec1_jtag", ARRAY_AND_SIZE(p910_sec1_jtag_grps)}, + {"sec2_jtag", ARRAY_AND_SIZE(p910_sec2_jtag_grps)}, + {"hsl", ARRAY_AND_SIZE(p910_hsl_grps)}, + {"w1", ARRAY_AND_SIZE(p910_w1_grps)}, + {"kpmk", ARRAY_AND_SIZE(p910_kpmk_grps)}, + {"kpdk", ARRAY_AND_SIZE(p910_kpdk_grps)}, + {"tds", ARRAY_AND_SIZE(p910_tds_grps)}, + {"tb", ARRAY_AND_SIZE(p910_tb_grps)}, + {"dma0", ARRAY_AND_SIZE(p910_dma0_grps)}, + {"dma1", ARRAY_AND_SIZE(p910_dma1_grps)}, + {"dma2", ARRAY_AND_SIZE(p910_dma2_grps)}, + {"int0", ARRAY_AND_SIZE(p910_int0_grps)}, + {"int1", ARRAY_AND_SIZE(p910_int1_grps)}, + {"int2", ARRAY_AND_SIZE(p910_int2_grps)}, + {"dac_st23", ARRAY_AND_SIZE(p910_dac_st23_grps)}, + {"vcxo_out", ARRAY_AND_SIZE(p910_vcxo_out_grps)}, + {"vcxo_req", ARRAY_AND_SIZE(p910_vcxo_req_grps)}, + {"vcxo_out2", ARRAY_AND_SIZE(p910_vcxo_out2_grps)}, + {"vcxo_req2", ARRAY_AND_SIZE(p910_vcxo_req2_grps)}, + {"ulpi", ARRAY_AND_SIZE(p910_ulpi_grps)}, + {"nand", ARRAY_AND_SIZE(p910_nand_grps)}, + {"gpio0", ARRAY_AND_SIZE(p910_gpio0_grps)}, + {"gpio1", ARRAY_AND_SIZE(p910_gpio1_grps)}, + {"gpio2", ARRAY_AND_SIZE(p910_gpio2_grps)}, + {"gpio3", ARRAY_AND_SIZE(p910_gpio3_grps)}, + {"gpio20", ARRAY_AND_SIZE(p910_gpio20_grps)}, + {"gpio21", ARRAY_AND_SIZE(p910_gpio21_grps)}, + {"gpio22", ARRAY_AND_SIZE(p910_gpio22_grps)}, + {"gpio23", ARRAY_AND_SIZE(p910_gpio23_grps)}, + {"gpio24", ARRAY_AND_SIZE(p910_gpio24_grps)}, + {"gpio25", ARRAY_AND_SIZE(p910_gpio25_grps)}, + {"gpio26", ARRAY_AND_SIZE(p910_gpio26_grps)}, + {"gpio27", ARRAY_AND_SIZE(p910_gpio27_grps)}, + {"gpio85", ARRAY_AND_SIZE(p910_gpio85_grps)}, + {"gpio86", ARRAY_AND_SIZE(p910_gpio86_grps)}, + {"gpio87", ARRAY_AND_SIZE(p910_gpio87_grps)}, + {"gpio88", ARRAY_AND_SIZE(p910_gpio88_grps)}, + {"gpio89", ARRAY_AND_SIZE(p910_gpio89_grps)}, + {"gpio90", ARRAY_AND_SIZE(p910_gpio90_grps)}, + {"gpio91", ARRAY_AND_SIZE(p910_gpio91_grps)}, + {"gpio92", ARRAY_AND_SIZE(p910_gpio92_grps)}, +}; + +static struct pinctrl_desc pxa910_pctrl_desc = { + .name = "pxa910-pinctrl", + .owner = THIS_MODULE, +}; + +static struct pxa3xx_pinmux_info pxa910_info = { + .mfp = pxa910_mfp, + .num_mfp = ARRAY_SIZE(pxa910_mfp), + .grps = pxa910_grps, + .num_grps = ARRAY_SIZE(pxa910_grps), + .funcs = pxa910_funcs, + .num_funcs = ARRAY_SIZE(pxa910_funcs), + .num_gpio = 128, + .desc = &pxa910_pctrl_desc, + .pads = pxa910_pads, + .num_pads = ARRAY_SIZE(pxa910_pads), + + .cputype = PINCTRL_PXA910, + .ds_mask = PXA910_DS_MASK, + .ds_shift = PXA910_DS_SHIFT, +}; + +static int __devinit pxa910_pinmux_probe(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_register(pdev, &pxa910_info); +} + +static int __devexit pxa910_pinmux_remove(struct platform_device *pdev) +{ + return pxa3xx_pinctrl_unregister(pdev); +} + +static struct platform_driver pxa910_pinmux_driver = { + .driver = { + .name = "pxa910-pinmux", + .owner = THIS_MODULE, + }, + .probe = pxa910_pinmux_probe, + .remove = __devexit_p(pxa910_pinmux_remove), +}; + +static int __init pxa910_pinmux_init(void) +{ + return platform_driver_register(&pxa910_pinmux_driver); +} +core_initcall_sync(pxa910_pinmux_init); + +static void __exit pxa910_pinmux_exit(void) +{ + platform_driver_unregister(&pxa910_pinmux_driver); +} +module_exit(pxa910_pinmux_exit); + +MODULE_AUTHOR("Haojian Zhuang "); +MODULE_DESCRIPTION("PXA3xx pin control driver"); +MODULE_LICENSE("GPL v2"); -- cgit v0.10.2 From 28a8d14cc74a0180323d9150c3d3dbf9dd60d55a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 9 Feb 2012 01:52:22 +0100 Subject: pinctrl: break out a pinctrl consumer header This breaks out a header to be used by all pinmux and pinconfig alike, so drivers needing services from pinctrl does not need to include different headers. This is similar to the approach taken by the regulator API. Acked-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 14aecd2..b268832 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -208,6 +208,8 @@ unconnected. For example, a platform may do this: +#include + 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 @@ -920,7 +922,7 @@ this is not possible. A driver may request a certain mux to be activated, usually just the default mux like this: -#include +#include struct foo_state { struct pinmux *pmx; @@ -1019,6 +1021,8 @@ function, but with different named in the mapping as described under 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 + foo_switch() { struct pinmux *pmx; diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index b4c6926..1429e52 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -26,7 +26,7 @@ #include #include #include -#include +#include #include #include diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index 69fb707..8bac3f0 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include /* diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h new file mode 100644 index 0000000..9c8513d --- /dev/null +++ b/include/linux/pinctrl/consumer.h @@ -0,0 +1,118 @@ +/* + * 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 + * + * License terms: GNU General Public License (GPL) version 2 + */ +#ifndef __LINUX_PINCTRL_CONSUMER_H +#define __LINUX_PINCTRL_CONSUMER_H + +#include +#include +#include "pinctrl.h" + +/* This struct is private to the core and should be regarded as a cookie */ +struct pinmux; + +#ifdef CONFIG_PINMUX + +/* 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 */ + +#ifdef CONFIG_PINCONF + +extern int pin_config_get(const char *dev_name, const char *name, + unsigned long *config); +extern int pin_config_set(const char *dev_name, const char *name, + unsigned long config); +extern int pin_config_group_get(const char *dev_name, + const char *pin_group, + unsigned long *config); +extern int pin_config_group_set(const char *dev_name, + const char *pin_group, + unsigned long config); + +#else + +static inline int pin_config_get(const char *dev_name, const char *name, + unsigned long *config) +{ + return 0; +} + +static inline int pin_config_set(const char *dev_name, const char *name, + unsigned long config) +{ + return 0; +} + +static inline int pin_config_group_get(const char *dev_name, + const char *pin_group, + unsigned long *config) +{ + return 0; +} + +static inline int pin_config_group_set(const char *dev_name, + const char *pin_group, + unsigned long config) +{ + return 0; +} + +#endif + +#endif /* __LINUX_PINCTRL_CONSUMER_H */ diff --git a/include/linux/pinctrl/pinconf.h b/include/linux/pinctrl/pinconf.h index 477922c..f8cf156 100644 --- a/include/linux/pinctrl/pinconf.h +++ b/include/linux/pinctrl/pinconf.h @@ -53,45 +53,6 @@ struct pinconf_ops { unsigned selector); }; -extern int pin_config_get(const char *dev_name, const char *name, - unsigned long *config); -extern int pin_config_set(const char *dev_name, const char *name, - unsigned long config); -extern int pin_config_group_get(const char *dev_name, - const char *pin_group, - unsigned long *config); -extern int pin_config_group_set(const char *dev_name, - const char *pin_group, - unsigned long config); - -#else - -static inline int pin_config_get(const char *dev_name, const char *name, - unsigned long *config) -{ - return 0; -} - -static inline int pin_config_set(const char *dev_name, const char *name, - unsigned long config) -{ - return 0; -} - -static inline int pin_config_group_get(const char *dev_name, - const char *pin_group, - unsigned long *config) -{ - return 0; -} - -static inline int pin_config_group_set(const char *dev_name, - const char *pin_group, - unsigned long config) -{ - return 0; -} - #endif #endif /* __LINUX_PINCTRL_PINCONF_H */ diff --git a/include/linux/pinctrl/pinmux.h b/include/linux/pinctrl/pinmux.h index 937b3e2..47e9237 100644 --- a/include/linux/pinctrl/pinmux.h +++ b/include/linux/pinctrl/pinmux.h @@ -16,9 +16,6 @@ #include #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 */ -- cgit v0.10.2 From e93bcee00c43e2bd4037291262111016f4c05793 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 9 Feb 2012 07:23:28 +0100 Subject: pinctrl: move generic functions to the pinctrl_ namespace Since we want to use the former pinmux handles and mapping tables for generic control involving both muxing and configuration we begin refactoring by renaming them from pinmux_* to pinctrl_*. ChangeLog v1->v2: - Also rename the PINMUX_* macros in machine.h to PIN_ as indicated in the documentation so as to reflect the generic nature of these mapping entries from now on. Acked-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index b268832..2e71323 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -728,19 +728,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 @@ -749,7 +749,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(). @@ -764,7 +764,7 @@ 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. @@ -783,7 +783,7 @@ spi on the second function mapping: #include -static const struct pinmux_map __initdata pmx_mapping[] = { +static const struct pinctrl_map __initdata mapping[] = { { .ctrl_dev_name = "pinctrl-foo", .function = "spi0", @@ -811,14 +811,14 @@ 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("I2CMAP", "pinctrl-foo", "i2c0", "foo-i2c.0"), }; @@ -901,7 +901,7 @@ case), we define a mapping like this: The result of grabbing this mapping from the device with something like this (see next paragraph): - pmx = pinmux_get(&device, "8bit"); + p = pinctrl_get(&device, "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 @@ -913,44 +913,44 @@ 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 struct foo_state { - struct pinmux *pmx; + struct pinctrl *p; ... }; foo_probe() { /* Allocate a state holder named "state" etc */ - struct pinmux pmx; + struct pinctrl p; - pmx = pinmux_get(&device, NULL); - if IS_ERR(pmx) - return PTR_ERR(pmx); - pinmux_enable(pmx); + p = pinctrl_get(&device, NULL); + if IS_ERR(p) + return PTR_ERR(p); + pinctrl_enable(p); - state->pmx = pmx; + state->p = p; } foo_remove() { - pinmux_disable(state->pmx); - pinmux_put(state->pmx); + pinctrl_disable(state->p); + 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"); +If you want to grab a specific control 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: pinctrl_get(&device, "spi0-pos-B"); This get/enable/disable/put sequence can just as well be handled by bus drivers if you don't want each and every driver to handle it and you know the @@ -958,35 +958,35 @@ arrangement on your bus. The semantics of the get/enable respective disable/put is as follows: -- pinmux_get() is called in process context to reserve the pins affected with +- pinctrl_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. -- pinmux_enable()/pinmux_disable() is quick and can be called from fastpath +- pinctrl_enable()/pinctrl_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. -- pinmux_disable() is called in process context to tear down the pin requests - and release the state holder struct for the mux setting. +- pinctrl_disable() is called in process context to tear down the pin requests + and release the state holder struct for the mux setting etc. -Usually the pinmux core handled the get/put pair and call out to the device -drivers bookkeeping operations, like checking available functions and the -associated pins, whereas the enable/disable pass on to the pin controller +Usually the pin control core handled the get/put pair and call out to the +device drivers bookkeeping operations, like checking available functions and +the associated pins, whereas the enable/disable pass on to the pin controller driver which takes care of activating and/or deactivating the mux setting by quickly poking some registers. -The pins are allocated for your device when you issue the pinmux_get() call, +The pins are allocated for your device when you issue the pinctrl_get() call, after this you should be able to see this in the debugfs listing of all pins. -System pinmux hogging -===================== +System pin control hogging +========================== -A system pinmux map entry, i.e. a pinmux setting that does not have a device -associated with it, can be hogged by the core when the pin controller is -registered. This means that the core will attempt to call pinmux_get() and -pinmux_enable() on it immediately after the pin control device has been +A system pin control map entry, i.e. a pin control 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 pinctrl_get() and +pinctrl_enable() 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, @@ -1003,7 +1003,7 @@ 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_PRIMARY_SYS_HOG("POWERMAP", "power_func") This gives the exact same result as the above construction. @@ -1025,23 +1025,23 @@ it, disables and releases it, and muxes it in on the pins defined by group B: foo_switch() { - struct pinmux *pmx; + struct pinctrl *p; /* Enable on position A */ - pmx = pinmux_get(&device, "spi0-pos-A"); - if IS_ERR(pmx) - return PTR_ERR(pmx); - pinmux_enable(pmx); + p = pinctrl_get(&device, "spi0-pos-A"); + if IS_ERR(p) + return PTR_ERR(p); + pinctrl_enable(p); /* This releases the pins again */ - pinmux_disable(pmx); - pinmux_put(pmx); + pinctrl_disable(p); + pinctrl_put(p); /* Enable on position B */ - pmx = pinmux_get(&device, "spi0-pos-B"); - if IS_ERR(pmx) - return PTR_ERR(pmx); - pinmux_enable(pmx); + p = pinctrl_get(&device, "spi0-pos-B"); + if IS_ERR(p) + return PTR_ERR(p); + pinctrl_enable(p); ... } diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index 1429e52..bb1034f 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -1605,21 +1605,21 @@ static struct platform_device pinmux_device = { }; /* Pinmux settings */ -static struct pinmux_map __initdata u300_pinmux_map[] = { +static struct pinctrl_map __initdata u300_pinmux_map[] = { /* anonymous maps for chip power and EMIFs */ - PINMUX_MAP_SYS_HOG("POWER", "pinmux-u300", "power"), - PINMUX_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"), - PINMUX_MAP_SYS_HOG("EMIF1", "pinmux-u300", "emif1"), + PIN_MAP_SYS_HOG("POWER", "pinmux-u300", "power"), + PIN_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"), + PIN_MAP_SYS_HOG("EMIF1", "pinmux-u300", "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("MMCSD", "pinmux-u300", "mmc0", "mmci"), + PIN_MAP("SPI", "pinmux-u300", "spi0", "pl022"), + PIN_MAP("UART0", "pinmux-u300", "uart0", "uart0"), }; struct u300_mux_hog { const char *name; struct device *dev; - struct pinmux *pmx; + struct pinctrl *p; }; static struct u300_mux_hog u300_mux_hogs[] = { @@ -1637,31 +1637,31 @@ static struct u300_mux_hog u300_mux_hogs[] = { }, }; -static int __init u300_pinmux_fetch(void) +static int __init u300_pinctrl_fetch(void) { int i; for (i = 0; i < ARRAY_SIZE(u300_mux_hogs); i++) { - struct pinmux *pmx; + struct pinctrl *p; int ret; - pmx = pinmux_get(u300_mux_hogs[i].dev, NULL); - if (IS_ERR(pmx)) { + p = pinctrl_get(u300_mux_hogs[i].dev, NULL); + if (IS_ERR(p)) { pr_err("u300: could not get pinmux hog %s\n", u300_mux_hogs[i].name); continue; } - ret = pinmux_enable(pmx); + ret = pinctrl_enable(p); 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. @@ -1861,8 +1861,8 @@ void __init u300_init_devices(void) u300_assign_physmem(); /* Initialize pinmuxing */ - pinmux_register_mappings(u300_pinmux_map, - ARRAY_SIZE(u300_pinmux_map)); + pinctrl_register_mappings(u300_pinmux_map, + ARRAY_SIZE(u300_pinmux_map)); /* Register subdevices on the I2C buses */ u300_i2c_register_board_devices(); diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 4f10476..75c6a6b 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -624,7 +624,7 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, mutex_lock(&pinctrldev_list_mutex); list_add(&pctldev->node, &pinctrldev_list); mutex_unlock(&pinctrldev_list_mutex); - pinmux_hog_maps(pctldev); + pinctrl_hog_maps(pctldev); return pctldev; out_err: @@ -645,7 +645,7 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) return; pinctrl_remove_device_debugfs(pctldev); - pinmux_unhog_maps(pctldev); + pinctrl_unhog_maps(pctldev); /* TODO: check that no pinmuxes are still active? */ mutex_lock(&pinctrldev_list_mutex); list_del(&pctldev->node); diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 8a8b02e..7a89888 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -28,8 +28,8 @@ struct pinctrl_gpio_range; * @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 + * @pinctrl_hogs_lock: lock for the pin control hog list + * @pinctrl_hogs: list of pin control maps hogged by this device */ struct pinctrl_dev { struct list_head node; @@ -45,8 +45,8 @@ struct pinctrl_dev { struct dentry *device_root; #endif #ifdef CONFIG_PINMUX - struct mutex pinmux_hogs_lock; - struct list_head pinmux_hogs; + struct mutex pinctrl_hogs_lock; + struct list_head pinctrl_hogs; #endif }; diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index 8bac3f0..eba232a 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -360,14 +360,14 @@ static int u300_gpio_request(struct gpio_chip *chip, unsigned offset) */ int gpio = chip->base + offset; - return pinmux_request_gpio(gpio); + return pinctrl_request_gpio(gpio); } static void u300_gpio_free(struct gpio_chip *chip, unsigned offset) { int gpio = chip->base + offset; - pinmux_free_gpio(gpio); + pinctrl_free_gpio(gpio); } static int u300_gpio_get(struct gpio_chip *chip, unsigned offset) diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 1311f1d..773835d 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -1,7 +1,7 @@ /* * Core driver for the pin muxing portions of the pin control subsystem * - * Copyright (C) 2011 ST-Ericsson SA + * Copyright (C) 2011-2012 ST-Ericsson SA * Written on behalf of Linaro for ST-Ericsson * Based on bits of regulator core, gpio core and clk core * @@ -29,13 +29,13 @@ #include #include "core.h" -/* List of pinmuxes */ -static DEFINE_MUTEX(pinmux_list_mutex); -static LIST_HEAD(pinmux_list); +/* List of pin controller handles */ +static DEFINE_MUTEX(pinctrl_list_mutex); +static LIST_HEAD(pinctrl_list); -/* Global pinmux maps */ -static struct pinmux_map *pinmux_maps; -static unsigned pinmux_maps_num; +/* Global pinctrl maps */ +static struct pinctrl_map *pinctrl_maps; +static unsigned pinctrl_maps_num; /** * struct pinmux_group - group list item for pinmux groups @@ -48,12 +48,12 @@ struct pinmux_group { }; /** - * struct pinmux - per-device pinmux state holder + * struct pinctrl - per-device pin control state holder * @node: global list node - * @dev: the device using this pinmux - * @usecount: the number of active users of this mux setting, used to keep - * track of nested use cases - * @pctldev: pin control device handling this pinmux + * @dev: the device using this pin control handle + * @usecount: the number of active users of this pin controller setting, used + * to keep track of nested use cases + * @pctldev: pin control device handling this pin control handle * @func_selector: the function selector for the pinmux device handling * this pinmux * @groups: the group selectors for the pinmux device and @@ -62,7 +62,7 @@ struct pinmux_group { * get/put/enable/disable * @mutex: a lock for the pinmux state holder */ -struct pinmux { +struct pinctrl { struct list_head node; struct device *dev; unsigned usecount; @@ -73,15 +73,15 @@ struct pinmux { }; /** - * struct pinmux_hog - a list item to stash mux hogs - * @node: pinmux hog list node + * struct pinctrl_hog - a list item to stash control hogs + * @node: pin control hog list node * @map: map entry responsible for this hogging - * @pmx: the pinmux hogged by this item + * @pmx: the pin control hogged by this item */ -struct pinmux_hog { +struct pinctrl_hog { struct list_head node; - struct pinmux_map const *map; - struct pinmux *pmx; + struct pinctrl_map const *map; + struct pinctrl *p; }; /** @@ -207,14 +207,14 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, } /** - * pinmux_request_gpio() - request a single pin to be muxed in as GPIO + * pinctrl_request_gpio() - request a single pin to be used in as GPIO * @gpio: the GPIO pin number from the GPIO subsystem number space * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_request() semantics, platforms and individual drivers * shall *NOT* request GPIO pins to be muxed in. */ -int pinmux_request_gpio(unsigned gpio) +int pinctrl_request_gpio(unsigned gpio) { char gpiostr[16]; const char *function; @@ -243,17 +243,17 @@ int pinmux_request_gpio(unsigned gpio) return ret; } -EXPORT_SYMBOL_GPL(pinmux_request_gpio); +EXPORT_SYMBOL_GPL(pinctrl_request_gpio); /** - * pinmux_free_gpio() - free a single pin, currently used as GPIO + * pinctrl_free_gpio() - free control on a single pin, currently used as GPIO * @gpio: the GPIO pin number from the GPIO subsystem number space * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_free() semantics, platforms and individual drivers * shall *NOT* request GPIO pins to be muxed out. */ -void pinmux_free_gpio(unsigned gpio) +void pinctrl_free_gpio(unsigned gpio) { struct pinctrl_dev *pctldev; struct pinctrl_gpio_range *range; @@ -271,9 +271,9 @@ void pinmux_free_gpio(unsigned gpio) func = pin_free(pctldev, pin, range); kfree(func); } -EXPORT_SYMBOL_GPL(pinmux_free_gpio); +EXPORT_SYMBOL_GPL(pinctrl_free_gpio); -static int pinmux_gpio_direction(unsigned gpio, bool input) +static int pinctrl_gpio_direction(unsigned gpio, bool input) { struct pinctrl_dev *pctldev; struct pinctrl_gpio_range *range; @@ -299,36 +299,36 @@ static int pinmux_gpio_direction(unsigned gpio, bool input) } /** - * pinmux_gpio_direction_input() - request a GPIO pin to go into input mode + * pinctrl_gpio_direction_input() - request a GPIO pin to go into input mode * @gpio: the GPIO pin number from the GPIO subsystem number space * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_direction_input() semantics, platforms and individual - * drivers shall *NOT* touch pinmux GPIO calls. + * drivers shall *NOT* touch pin control GPIO calls. */ -int pinmux_gpio_direction_input(unsigned gpio) +int pinctrl_gpio_direction_input(unsigned gpio) { - return pinmux_gpio_direction(gpio, true); + return pinctrl_gpio_direction(gpio, true); } -EXPORT_SYMBOL_GPL(pinmux_gpio_direction_input); +EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input); /** - * pinmux_gpio_direction_output() - request a GPIO pin to go into output mode + * pinctrl_gpio_direction_output() - request a GPIO pin to go into output mode * @gpio: the GPIO pin number from the GPIO subsystem number space * * This function should *ONLY* be used from gpiolib-based GPIO drivers, * as part of their gpio_direction_output() semantics, platforms and individual - * drivers shall *NOT* touch pinmux GPIO calls. + * drivers shall *NOT* touch pin control GPIO calls. */ -int pinmux_gpio_direction_output(unsigned gpio) +int pinctrl_gpio_direction_output(unsigned gpio) { - return pinmux_gpio_direction(gpio, false); + return pinctrl_gpio_direction(gpio, false); } -EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output); +EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); /** - * pinmux_register_mappings() - register a set of pinmux mappings - * @maps: the pinmux mappings table to register, this should be marked with + * pinctrl_register_mappings() - register a set of pin controller mappings + * @maps: the pincontrol mappings table to register, this should be marked with * __initdata so it can be discarded after boot, this function will * perform a shallow copy for the mapping entries. * @num_maps: the number of maps in the mapping table @@ -338,8 +338,8 @@ EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output); * passed into this function will be owned by the pinmux core and cannot be * freed. */ -int __init pinmux_register_mappings(struct pinmux_map const *maps, - unsigned num_maps) +int __init pinctrl_register_mappings(struct pinctrl_map const *maps, + unsigned num_maps) { void *tmp_maps; int i; @@ -380,26 +380,27 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps, * Make a copy of the map array - string pointers will end up in the * kernel const section anyway so these do not need to be deep copied. */ - if (!pinmux_maps_num) { + if (!pinctrl_maps_num) { /* On first call, just copy them */ tmp_maps = kmemdup(maps, - sizeof(struct pinmux_map) * num_maps, + sizeof(struct pinctrl_map) * num_maps, GFP_KERNEL); if (!tmp_maps) return -ENOMEM; } else { /* Subsequent calls, reallocate array to new size */ - size_t oldsize = sizeof(struct pinmux_map) * pinmux_maps_num; - size_t newsize = sizeof(struct pinmux_map) * num_maps; + size_t oldsize = sizeof(struct pinctrl_map) * pinctrl_maps_num; + size_t newsize = sizeof(struct pinctrl_map) * num_maps; - tmp_maps = krealloc(pinmux_maps, oldsize + newsize, GFP_KERNEL); + tmp_maps = krealloc(pinctrl_maps, + oldsize + newsize, GFP_KERNEL); if (!tmp_maps) return -ENOMEM; memcpy((tmp_maps + oldsize), maps, newsize); } - pinmux_maps = tmp_maps; - pinmux_maps_num += num_maps; + pinctrl_maps = tmp_maps; + pinctrl_maps_num += num_maps; return 0; } @@ -560,7 +561,7 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, * negative otherwise */ static int pinmux_search_function(struct pinctrl_dev *pctldev, - struct pinmux_map const *map, + struct pinctrl_map const *map, unsigned *func_selector, unsigned *group_selector) { @@ -598,10 +599,10 @@ static int pinmux_search_function(struct pinctrl_dev *pctldev, * pinmux_enable_muxmap() - enable a map entry for a certain pinmux */ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, - struct pinmux *pmx, + struct pinctrl *p, struct device *dev, const char *devname, - struct pinmux_map const *map) + struct pinctrl_map const *map) { unsigned func_selector; unsigned group_selector; @@ -615,14 +616,14 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, * by anyone else. */ - if (pmx->pctldev && pmx->pctldev != pctldev) { + if (p->pctldev && p->pctldev != pctldev) { dev_err(pctldev->dev, "different pin control devices given for device %s, function %s\n", devname, map->function); return -EINVAL; } - pmx->dev = dev; - pmx->pctldev = pctldev; + p->dev = dev; + p->pctldev = pctldev; /* Now go into the driver and try to match a function and group */ ret = pinmux_search_function(pctldev, map, &func_selector, @@ -635,14 +636,14 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, * we support several groups with one function but not several * functions with one or several groups in the same pinmux. */ - if (pmx->func_selector != UINT_MAX && - pmx->func_selector != func_selector) { + if (p->func_selector != UINT_MAX && + p->func_selector != func_selector) { dev_err(pctldev->dev, "dual function defines in the map for device %s\n", devname); return -EINVAL; } - pmx->func_selector = func_selector; + p->func_selector = func_selector; /* Now add this group selector, we may have many of them */ grp = kmalloc(sizeof(struct pinmux_group), GFP_KERNEL); @@ -654,38 +655,38 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, kfree(grp); return ret; } - list_add(&grp->node, &pmx->groups); + list_add(&grp->node, &p->groups); return 0; } -static void pinmux_free_groups(struct pinmux *pmx) +static void pinmux_free_groups(struct pinctrl *p) { struct list_head *node, *tmp; - list_for_each_safe(node, tmp, &pmx->groups) { + list_for_each_safe(node, tmp, &p->groups) { struct pinmux_group *grp = list_entry(node, struct pinmux_group, node); /* Release all pins taken by this group */ - release_pins(pmx->pctldev, grp->group_selector); + release_pins(p->pctldev, grp->group_selector); list_del(node); kfree(grp); } } /** - * pinmux_get() - retrieves the pinmux for a certain device - * @dev: the device to get the pinmux for - * @name: an optional specific mux mapping name or NULL, the name is only + * pinctrl_get() - retrieves the pin controller handle for a certain device + * @dev: the device to get the pin controller handle for + * @name: an optional specific control mapping name or NULL, the name is only * needed if you want to have more than one mapping per device, or if you - * need an anonymous pinmux (not tied to any specific device) + * need an anonymous pin control (not tied to any specific device) */ -struct pinmux *pinmux_get(struct device *dev, const char *name) +struct pinctrl *pinctrl_get(struct device *dev, const char *name) { - struct pinmux_map const *map = NULL; + struct pinctrl_map const *map = NULL; struct pinctrl_dev *pctldev = NULL; const char *devname = NULL; - struct pinmux *pmx; + struct pinctrl *p; bool found_map; unsigned num_maps = 0; int ret = -ENODEV; @@ -706,16 +707,16 @@ struct pinmux *pinmux_get(struct device *dev, const char *name) * mapping, this is what consumers will get when requesting * a pinmux handle with pinmux_get() */ - pmx = kzalloc(sizeof(struct pinmux), GFP_KERNEL); - if (pmx == NULL) + p = kzalloc(sizeof(struct pinctrl), GFP_KERNEL); + if (p == NULL) return ERR_PTR(-ENOMEM); - mutex_init(&pmx->mutex); - pmx->func_selector = UINT_MAX; - INIT_LIST_HEAD(&pmx->groups); + mutex_init(&p->mutex); + p->func_selector = UINT_MAX; + INIT_LIST_HEAD(&p->groups); - /* Iterate over the pinmux maps to locate the right ones */ - for (i = 0; i < pinmux_maps_num; i++) { - map = &pinmux_maps[i]; + /* Iterate over the pin control maps to locate the right ones */ + for (i = 0; i < pinctrl_maps_num; i++) { + map = &pinctrl_maps[i]; found_map = false; /* @@ -763,11 +764,11 @@ struct pinmux *pinmux_get(struct device *dev, const char *name) /* If this map is applicable, then apply it */ if (found_map) { - ret = pinmux_enable_muxmap(pctldev, pmx, dev, + ret = pinmux_enable_muxmap(pctldev, p, dev, devname, map); if (ret) { - pinmux_free_groups(pmx); - kfree(pmx); + pinmux_free_groups(p); + kfree(p); return ERR_PTR(ret); } num_maps++; @@ -780,7 +781,7 @@ struct pinmux *pinmux_get(struct device *dev, const char *name) pr_err("could not find any mux maps for device %s, ID %s\n", devname ? devname : "(anonymous)", name ? name : "(undefined)"); - kfree(pmx); + kfree(p); return ERR_PTR(-EINVAL); } @@ -790,96 +791,96 @@ struct pinmux *pinmux_get(struct device *dev, const char *name) name ? name : "(undefined)"); /* Add the pinmux to the global list */ - mutex_lock(&pinmux_list_mutex); - list_add(&pmx->node, &pinmux_list); - mutex_unlock(&pinmux_list_mutex); + mutex_lock(&pinctrl_list_mutex); + list_add(&p->node, &pinctrl_list); + mutex_unlock(&pinctrl_list_mutex); - return pmx; + return p; } -EXPORT_SYMBOL_GPL(pinmux_get); +EXPORT_SYMBOL_GPL(pinctrl_get); /** - * pinmux_put() - release a previously claimed pinmux - * @pmx: a pinmux previously claimed by pinmux_get() + * pinctrl_put() - release a previously claimed pin control handle + * @p: a pin control handle previously claimed by pinctrl_get() */ -void pinmux_put(struct pinmux *pmx) +void pinctrl_put(struct pinctrl *p) { - if (pmx == NULL) + if (p == NULL) return; - mutex_lock(&pmx->mutex); - if (pmx->usecount) - pr_warn("releasing pinmux with active users!\n"); + mutex_lock(&p->mutex); + if (p->usecount) + pr_warn("releasing pin control handle with active users!\n"); /* Free the groups and all acquired pins */ - pinmux_free_groups(pmx); - mutex_unlock(&pmx->mutex); + pinmux_free_groups(p); + mutex_unlock(&p->mutex); /* Remove from list */ - mutex_lock(&pinmux_list_mutex); - list_del(&pmx->node); - mutex_unlock(&pinmux_list_mutex); + mutex_lock(&pinctrl_list_mutex); + list_del(&p->node); + mutex_unlock(&pinctrl_list_mutex); - kfree(pmx); + kfree(p); } -EXPORT_SYMBOL_GPL(pinmux_put); +EXPORT_SYMBOL_GPL(pinctrl_put); /** - * pinmux_enable() - enable a certain pinmux setting - * @pmx: the pinmux to enable, previously claimed by pinmux_get() + * pinctrl_enable() - enable a certain pin controller setting + * @p: the pin control handle to enable, previously claimed by pinctrl_get() */ -int pinmux_enable(struct pinmux *pmx) +int pinctrl_enable(struct pinctrl *p) { int ret = 0; - if (pmx == NULL) + if (p == NULL) return -EINVAL; - mutex_lock(&pmx->mutex); - if (pmx->usecount++ == 0) { - struct pinctrl_dev *pctldev = pmx->pctldev; + mutex_lock(&p->mutex); + if (p->usecount++ == 0) { + struct pinctrl_dev *pctldev = p->pctldev; const struct pinmux_ops *ops = pctldev->desc->pmxops; struct pinmux_group *grp; - list_for_each_entry(grp, &pmx->groups, node) { - ret = ops->enable(pctldev, pmx->func_selector, + list_for_each_entry(grp, &p->groups, node) { + ret = ops->enable(pctldev, p->func_selector, grp->group_selector); if (ret) { /* * TODO: call disable() on all groups we called * enable() on to this point? */ - pmx->usecount--; + p->usecount--; break; } } } - mutex_unlock(&pmx->mutex); + mutex_unlock(&p->mutex); return ret; } -EXPORT_SYMBOL_GPL(pinmux_enable); +EXPORT_SYMBOL_GPL(pinctrl_enable); /** - * pinmux_disable() - disable a certain pinmux setting - * @pmx: the pinmux to disable, previously claimed by pinmux_get() + * pinctrl_disable() - disable a certain pin control setting + * @p: the pin control handle to disable, previously claimed by pinctrl_get() */ -void pinmux_disable(struct pinmux *pmx) +void pinctrl_disable(struct pinctrl *p) { - if (pmx == NULL) + if (p == NULL) return; - mutex_lock(&pmx->mutex); - if (--pmx->usecount == 0) { - struct pinctrl_dev *pctldev = pmx->pctldev; + mutex_lock(&p->mutex); + if (--p->usecount == 0) { + struct pinctrl_dev *pctldev = p->pctldev; const struct pinmux_ops *ops = pctldev->desc->pmxops; struct pinmux_group *grp; - list_for_each_entry(grp, &pmx->groups, node) { - ops->disable(pctldev, pmx->func_selector, + list_for_each_entry(grp, &p->groups, node) { + ops->disable(pctldev, p->func_selector, grp->group_selector); } } - mutex_unlock(&pmx->mutex); + mutex_unlock(&p->mutex); } -EXPORT_SYMBOL_GPL(pinmux_disable); +EXPORT_SYMBOL_GPL(pinctrl_disable); int pinmux_check_ops(struct pinctrl_dev *pctldev) { @@ -910,11 +911,11 @@ int pinmux_check_ops(struct pinctrl_dev *pctldev) } /* Hog a single map entry and add to the hoglist */ -static int pinmux_hog_map(struct pinctrl_dev *pctldev, - struct pinmux_map const *map) +static int pinctrl_hog_map(struct pinctrl_dev *pctldev, + struct pinctrl_map const *map) { - struct pinmux_hog *hog; - struct pinmux *pmx; + struct pinctrl_hog *hog; + struct pinctrl *p; int ret; if (map->dev_name) { @@ -929,61 +930,61 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, return -EINVAL; } - hog = kzalloc(sizeof(struct pinmux_hog), GFP_KERNEL); + hog = kzalloc(sizeof(struct pinctrl_hog), GFP_KERNEL); if (!hog) return -ENOMEM; - pmx = pinmux_get(NULL, map->name); - if (IS_ERR(pmx)) { + p = pinctrl_get(NULL, map->name); + if (IS_ERR(p)) { kfree(hog); dev_err(pctldev->dev, - "could not get the %s pinmux mapping for hogging\n", + "could not get the %s pin control mapping for hogging\n", map->name); - return PTR_ERR(pmx); + return PTR_ERR(p); } - ret = pinmux_enable(pmx); + ret = pinctrl_enable(p); if (ret) { - pinmux_put(pmx); + pinctrl_put(p); kfree(hog); dev_err(pctldev->dev, - "could not enable the %s pinmux mapping for hogging\n", + "could not enable the %s pin control mapping for hogging\n", map->name); return ret; } hog->map = map; - hog->pmx = pmx; + hog->p = p; dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name, map->function); - mutex_lock(&pctldev->pinmux_hogs_lock); - list_add(&hog->node, &pctldev->pinmux_hogs); - mutex_unlock(&pctldev->pinmux_hogs_lock); + mutex_lock(&pctldev->pinctrl_hogs_lock); + list_add(&hog->node, &pctldev->pinctrl_hogs); + mutex_unlock(&pctldev->pinctrl_hogs_lock); return 0; } /** - * pinmux_hog_maps() - hog specific map entries on controller device + * pinctrl_hog_maps() - hog specific map entries on controller device * @pctldev: the pin control device to hog entries on * * When the pin controllers are registered, there may be some specific pinmux * map entries that need to be hogged, i.e. get+enabled until the system shuts * down. */ -int pinmux_hog_maps(struct pinctrl_dev *pctldev) +int pinctrl_hog_maps(struct pinctrl_dev *pctldev) { struct device *dev = pctldev->dev; const char *devname = dev_name(dev); int ret; int i; - INIT_LIST_HEAD(&pctldev->pinmux_hogs); - mutex_init(&pctldev->pinmux_hogs_lock); + INIT_LIST_HEAD(&pctldev->pinctrl_hogs); + mutex_init(&pctldev->pinctrl_hogs_lock); - for (i = 0; i < pinmux_maps_num; i++) { - struct pinmux_map const *map = &pinmux_maps[i]; + for (i = 0; i < pinctrl_maps_num; i++) { + struct pinctrl_map const *map = &pinctrl_maps[i]; if (!map->hog_on_boot) continue; @@ -991,7 +992,7 @@ int pinmux_hog_maps(struct pinctrl_dev *pctldev) if (map->ctrl_dev_name && !strcmp(map->ctrl_dev_name, devname)) { /* OK time to hog! */ - ret = pinmux_hog_map(pctldev, map); + ret = pinctrl_hog_map(pctldev, map); if (ret) return ret; } @@ -1000,23 +1001,23 @@ int pinmux_hog_maps(struct pinctrl_dev *pctldev) } /** - * pinmux_unhog_maps() - unhog specific map entries on controller device + * pinctrl_unhog_maps() - unhog specific map entries on controller device * @pctldev: the pin control device to unhog entries on */ -void pinmux_unhog_maps(struct pinctrl_dev *pctldev) +void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) { struct list_head *node, *tmp; - mutex_lock(&pctldev->pinmux_hogs_lock); - list_for_each_safe(node, tmp, &pctldev->pinmux_hogs) { - struct pinmux_hog *hog = - list_entry(node, struct pinmux_hog, node); - pinmux_disable(hog->pmx); - pinmux_put(hog->pmx); + mutex_lock(&pctldev->pinctrl_hogs_lock); + list_for_each_safe(node, tmp, &pctldev->pinctrl_hogs) { + struct pinctrl_hog *hog = + list_entry(node, struct pinctrl_hog, node); + pinctrl_disable(hog->p); + pinctrl_put(hog->p); list_del(node); kfree(hog); } - mutex_unlock(&pctldev->pinmux_hogs_lock); + mutex_unlock(&pctldev->pinctrl_hogs_lock); } #ifdef CONFIG_DEBUG_FS @@ -1085,11 +1086,11 @@ static int pinmux_pins_show(struct seq_file *s, void *what) static int pinmux_hogs_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev = s->private; - struct pinmux_hog *hog; + struct pinctrl_hog *hog; - seq_puts(s, "Pinmux map hogs held by device\n"); + seq_puts(s, "Pin control map hogs held by device\n"); - list_for_each_entry(hog, &pctldev->pinmux_hogs, node) + list_for_each_entry(hog, &pctldev->pinctrl_hogs, node) seq_printf(s, "%s\n", hog->map->name); return 0; @@ -1097,11 +1098,11 @@ static int pinmux_hogs_show(struct seq_file *s, void *what) static int pinmux_show(struct seq_file *s, void *what) { - struct pinmux *pmx; + struct pinctrl *p; seq_puts(s, "Requested pinmuxes and their maps:\n"); - list_for_each_entry(pmx, &pinmux_list, node) { - struct pinctrl_dev *pctldev = pmx->pctldev; + list_for_each_entry(p, &pinctrl_list, node) { + struct pinctrl_dev *pctldev = p->pctldev; const struct pinmux_ops *pmxops; const struct pinctrl_ops *pctlops; struct pinmux_group *grp; @@ -1115,13 +1116,13 @@ static int pinmux_show(struct seq_file *s, void *what) pctlops = pctldev->desc->pctlops; seq_printf(s, "device: %s function: %s (%u),", - pinctrl_dev_get_name(pmx->pctldev), + pinctrl_dev_get_name(p->pctldev), pmxops->get_function_name(pctldev, - pmx->func_selector), - pmx->func_selector); + p->func_selector), + p->func_selector); seq_printf(s, " groups: ["); - list_for_each_entry(grp, &pmx->groups, node) { + list_for_each_entry(grp, &p->groups, node) { seq_printf(s, " %s (%u)", pctlops->get_group_name(pctldev, grp->group_selector), @@ -1130,21 +1131,21 @@ static int pinmux_show(struct seq_file *s, void *what) seq_printf(s, " ]"); seq_printf(s, " users: %u map-> %s\n", - pmx->usecount, - pmx->dev ? dev_name(pmx->dev) : "(system)"); + p->usecount, + p->dev ? dev_name(p->dev) : "(system)"); } return 0; } -static int pinmux_maps_show(struct seq_file *s, void *what) +static int pinctrl_maps_show(struct seq_file *s, void *what) { int i; - seq_puts(s, "Pinmux maps:\n"); + seq_puts(s, "Pinctrl maps:\n"); - for (i = 0; i < pinmux_maps_num; i++) { - struct pinmux_map const *map = &pinmux_maps[i]; + for (i = 0; i < pinctrl_maps_num; i++) { + struct pinctrl_map const *map = &pinctrl_maps[i]; seq_printf(s, "%s:\n", map->name); if (map->dev_name) @@ -1181,9 +1182,9 @@ static int pinmux_open(struct inode *inode, struct file *file) return single_open(file, pinmux_show, NULL); } -static int pinmux_maps_open(struct inode *inode, struct file *file) +static int pinctrl_maps_open(struct inode *inode, struct file *file) { - return single_open(file, pinmux_maps_show, NULL); + return single_open(file, pinctrl_maps_show, NULL); } static const struct file_operations pinmux_functions_ops = { @@ -1214,8 +1215,8 @@ static const struct file_operations pinmux_ops = { .release = single_release, }; -static const struct file_operations pinmux_maps_ops = { - .open = pinmux_maps_open, +static const struct file_operations pinctrl_maps_ops = { + .open = pinctrl_maps_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, @@ -1236,8 +1237,8 @@ void pinmux_init_debugfs(struct dentry *subsys_root) { debugfs_create_file("pinmuxes", S_IFREG | S_IRUGO, subsys_root, NULL, &pinmux_ops); - debugfs_create_file("pinmux-maps", S_IFREG | S_IRUGO, - subsys_root, NULL, &pinmux_maps_ops); + debugfs_create_file("pinctrl-maps", S_IFREG | S_IRUGO, + subsys_root, NULL, &pinctrl_maps_ops); } #endif /* CONFIG_DEBUG_FS */ diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h index 97f5222..dfe8172 100644 --- a/drivers/pinctrl/pinmux.h +++ b/drivers/pinctrl/pinmux.h @@ -16,8 +16,8 @@ int pinmux_check_ops(struct pinctrl_dev *pctldev); 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); +int pinctrl_hog_maps(struct pinctrl_dev *pctldev); +void pinctrl_unhog_maps(struct pinctrl_dev *pctldev); #else @@ -35,12 +35,12 @@ static inline void pinmux_init_debugfs(struct dentry *subsys_root) { } -static inline int pinmux_hog_maps(struct pinctrl_dev *pctldev) +static inline int pinctrl_hog_maps(struct pinctrl_dev *pctldev) { return 0; } -static inline void pinmux_unhog_maps(struct pinctrl_dev *pctldev) +static inline void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) { } diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h index 9c8513d..c7d0617 100644 --- a/include/linux/pinctrl/consumer.h +++ b/include/linux/pinctrl/consumer.h @@ -17,56 +17,56 @@ #include "pinctrl.h" /* This struct is private to the core and should be regarded as a cookie */ -struct pinmux; +struct pinctrl; #ifdef CONFIG_PINMUX /* 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); +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, const char *name); +extern void pinctrl_put(struct pinctrl *p); +extern int pinctrl_enable(struct pinctrl *p); +extern void pinctrl_disable(struct pinctrl *p); #else /* !CONFIG_PINMUX */ -static inline int pinmux_request_gpio(unsigned gpio) +static inline int pinctrl_request_gpio(unsigned gpio) { return 0; } -static inline void pinmux_free_gpio(unsigned gpio) +static inline void pinctrl_free_gpio(unsigned gpio) { } -static inline int pinmux_gpio_direction_input(unsigned gpio) +static inline int pinctrl_gpio_direction_input(unsigned gpio) { return 0; } -static inline int pinmux_gpio_direction_output(unsigned gpio) +static inline int pinctrl_gpio_direction_output(unsigned gpio) { return 0; } -static inline struct pinmux * __must_check pinmux_get(struct device *dev, const char *name) +static inline struct pinctrl * __must_check pinctrl_get(struct device *dev, const char *name) { return NULL; } -static inline void pinmux_put(struct pinmux *pmx) +static inline void pinctrl_put(struct pinctrl *p) { } -static inline int pinmux_enable(struct pinmux *pmx) +static inline int pinctrl_enable(struct pinctrl *p) { return 0; } -static inline void pinmux_disable(struct pinmux *pmx) +static inline void pinctrl_disable(struct pinctrl *p) { } diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index f8593fd..a2ab524 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -9,11 +9,11 @@ * * 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 + * struct pinctrl_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 @@ -34,7 +34,7 @@ * a pinmux device supporting it is registered. These maps will not be * disabled and put until the system shuts down. */ -struct pinmux_map { +struct pinctrl_map { const char *name; const char *ctrl_dev_name; const char *function; @@ -47,41 +47,41 @@ struct pinmux_map { * Convenience macro to set a simple map from a certain pin controller and a * certain function to a named device */ -#define PINMUX_MAP(a, b, c, d) \ +#define PIN_MAP(a, b, c, d) \ { .name = a, .ctrl_dev_name = b, .function = c, .dev_name = d } /* * Convenience macro to map a system function onto a certain pinctrl device. * System functions are not assigned to a particular device. */ -#define PINMUX_MAP_SYS(a, b, c) \ +#define PIN_MAP_SYS(a, b, c) \ { .name = a, .ctrl_dev_name = b, .function = c } /* * Convenience macro to map a system function onto a certain pinctrl device, - * to be hogged by the pinmux core until the system shuts down. + * to be hogged by the pin control core until the system shuts down. */ -#define PINMUX_MAP_SYS_HOG(a, b, c) \ +#define PIN_MAP_SYS_HOG(a, b, c) \ { .name = a, .ctrl_dev_name = b, .function = c, \ .hog_on_boot = true } /* * 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. + * using a specified group, to be hogged by the pin control core until the + * system shuts down. */ -#define PINMUX_MAP_SYS_HOG_GROUP(a, b, c, d) \ +#define PIN_MAP_SYS_HOG_GROUP(a, b, c, d) \ { .name = a, .ctrl_dev_name = b, .function = c, .group = d, \ .hog_on_boot = true } #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; -- cgit v0.10.2 From befe5bdfbb698b3bc57c58d0bd7ca3391c9275ed Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 9 Feb 2012 19:47:48 +0100 Subject: pinctrl: factor pin control handles over to the core This moves the per-devices struct pinctrl handles and device map over from the pinmux part of the subsystem to the core pinctrl part. This makes the device handles core infrastructure with the goal of using these handles also for pin configuration, so that device drivers (or boards etc) will need one and only one handle to the pin control core. Acked-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 75c6a6b..ec32c54 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -1,7 +1,7 @@ /* * Core driver for the pin control subsystem * - * Copyright (C) 2011 ST-Ericsson SA + * Copyright (C) 2011-2012 ST-Ericsson SA * Written on behalf of Linaro for ST-Ericsson * Based on bits of regulator core, gpio core and clk core * @@ -30,10 +30,30 @@ #include "pinmux.h" #include "pinconf.h" +/** + * struct pinctrl_hog - a list item to stash control hogs + * @node: pin control hog list node + * @map: map entry responsible for this hogging + * @pmx: the pin control hogged by this item + */ +struct pinctrl_hog { + struct list_head node; + struct pinctrl_map const *map; + struct pinctrl *p; +}; + /* Global list of pin control devices */ static DEFINE_MUTEX(pinctrldev_list_mutex); static LIST_HEAD(pinctrldev_list); +/* List of pin controller handles */ +static DEFINE_MUTEX(pinctrl_list_mutex); +static LIST_HEAD(pinctrl_list); + +/* Global pinctrl maps */ +static struct pinctrl_map *pinctrl_maps; +static unsigned pinctrl_maps_num; + const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev) { /* We're not allowed to register devices without name */ @@ -337,6 +357,476 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev, return -EINVAL; } +/** + * pinctrl_request_gpio() - request a single pin to be used in as GPIO + * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_request() semantics, platforms and individual drivers + * shall *NOT* request GPIO pins to be muxed in. + */ +int pinctrl_request_gpio(unsigned gpio) +{ + struct pinctrl_dev *pctldev; + struct pinctrl_gpio_range *range; + int ret; + int pin; + + ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); + if (ret) + return -EINVAL; + + /* Convert to the pin controllers number space */ + pin = gpio - range->base + range->pin_base; + + return pinmux_request_gpio(pctldev, range, pin, gpio); +} +EXPORT_SYMBOL_GPL(pinctrl_request_gpio); + +/** + * pinctrl_free_gpio() - free control on a single pin, currently used as GPIO + * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_free() semantics, platforms and individual drivers + * shall *NOT* request GPIO pins to be muxed out. + */ +void pinctrl_free_gpio(unsigned gpio) +{ + struct pinctrl_dev *pctldev; + struct pinctrl_gpio_range *range; + int ret; + int pin; + + ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); + if (ret) + return; + + /* Convert to the pin controllers number space */ + pin = gpio - range->base + range->pin_base; + + return pinmux_free_gpio(pctldev, pin, range); +} +EXPORT_SYMBOL_GPL(pinctrl_free_gpio); + +static int pinctrl_gpio_direction(unsigned gpio, bool input) +{ + struct pinctrl_dev *pctldev; + struct pinctrl_gpio_range *range; + int ret; + int pin; + + ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); + if (ret) + return ret; + + /* Convert to the pin controllers number space */ + pin = gpio - range->base + range->pin_base; + + return pinmux_gpio_direction(pctldev, range, pin, input); +} + +/** + * pinctrl_gpio_direction_input() - request a GPIO pin to go into input mode + * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_direction_input() semantics, platforms and individual + * drivers shall *NOT* touch pin control GPIO calls. + */ +int pinctrl_gpio_direction_input(unsigned gpio) +{ + return pinctrl_gpio_direction(gpio, true); +} +EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input); + +/** + * pinctrl_gpio_direction_output() - request a GPIO pin to go into output mode + * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_direction_output() semantics, platforms and individual + * drivers shall *NOT* touch pin control GPIO calls. + */ +int pinctrl_gpio_direction_output(unsigned gpio) +{ + return pinctrl_gpio_direction(gpio, false); +} +EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); + +/** + * pinctrl_get() - retrieves the pin controller handle for a certain device + * @dev: the device to get the pin controller handle for + * @name: an optional specific control mapping name or NULL, the name is only + * needed if you want to have more than one mapping per device, or if you + * need an anonymous pin control (not tied to any specific device) + */ +struct pinctrl *pinctrl_get(struct device *dev, const char *name) +{ + struct pinctrl_map const *map = NULL; + struct pinctrl_dev *pctldev = NULL; + const char *devname = NULL; + struct pinctrl *p; + bool found_map; + unsigned num_maps = 0; + int ret = -ENODEV; + int i; + + /* We must have dev or ID or both */ + if (!dev && !name) + return ERR_PTR(-EINVAL); + + if (dev) + devname = dev_name(dev); + + pr_debug("get pin control handle %s for device %s\n", name, + devname ? devname : "(none)"); + + /* + * create the state cookie holder struct pinctrl for each + * mapping, this is what consumers will get when requesting + * a pin control handle with pinctrl_get() + */ + p = kzalloc(sizeof(struct pinctrl), GFP_KERNEL); + if (p == NULL) + return ERR_PTR(-ENOMEM); + mutex_init(&p->mutex); + pinmux_init_pinctrl_handle(p); + + /* Iterate over the pin control maps to locate the right ones */ + for (i = 0; i < pinctrl_maps_num; i++) { + map = &pinctrl_maps[i]; + found_map = false; + + /* + * First, try to find the pctldev given in the map + */ + pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); + if (!pctldev) { + pr_warning("could not find a pinctrl device for pinmux function %s, fishy, they shall all have one\n", + map->function); + pr_warning("given pinctrl device name: %s", + map->ctrl_dev_name); + + /* Continue to check the other mappings anyway... */ + continue; + } + + pr_debug("in map, found pctldev %s to handle function %s", + dev_name(pctldev->dev), map->function); + + + /* + * If we're looking for a specific named map, this must match, + * else we loop and look for the next. + */ + if (name != NULL) { + if (map->name == NULL) + continue; + if (strcmp(map->name, name)) + continue; + } + + /* + * This is for the case where no device name is given, we + * already know that the function name matches from above + * code. + */ + if (!map->dev_name && (name != NULL)) + found_map = true; + + /* If the mapping has a device set up it must match */ + if (map->dev_name && + (!devname || !strcmp(map->dev_name, devname))) + /* MATCH! */ + found_map = true; + + /* If this map is applicable, then apply it */ + if (found_map) { + ret = pinmux_apply_muxmap(pctldev, p, dev, + devname, map); + if (ret) { + kfree(p); + return ERR_PTR(ret); + } + num_maps++; + } + } + + /* We should have atleast one map, right */ + if (!num_maps) { + pr_err("could not find any mux maps for device %s, ID %s\n", + devname ? devname : "(anonymous)", + name ? name : "(undefined)"); + kfree(p); + return ERR_PTR(-EINVAL); + } + + pr_debug("found %u mux maps for device %s, UD %s\n", + num_maps, + devname ? devname : "(anonymous)", + name ? name : "(undefined)"); + + /* Add the pinmux to the global list */ + mutex_lock(&pinctrl_list_mutex); + list_add(&p->node, &pinctrl_list); + mutex_unlock(&pinctrl_list_mutex); + + return p; +} +EXPORT_SYMBOL_GPL(pinctrl_get); + +/** + * pinctrl_put() - release a previously claimed pin control handle + * @p: a pin control handle previously claimed by pinctrl_get() + */ +void pinctrl_put(struct pinctrl *p) +{ + if (p == NULL) + return; + + mutex_lock(&p->mutex); + if (p->usecount) + pr_warn("releasing pin control handle with active users!\n"); + /* Free the groups and all acquired pins */ + pinmux_put(p); + mutex_unlock(&p->mutex); + + /* Remove from list */ + mutex_lock(&pinctrl_list_mutex); + list_del(&p->node); + mutex_unlock(&pinctrl_list_mutex); + + kfree(p); +} +EXPORT_SYMBOL_GPL(pinctrl_put); + +/** + * pinctrl_enable() - enable a certain pin controller setting + * @p: the pin control handle to enable, previously claimed by pinctrl_get() + */ +int pinctrl_enable(struct pinctrl *p) +{ + int ret = 0; + + if (p == NULL) + return -EINVAL; + mutex_lock(&p->mutex); + if (p->usecount++ == 0) { + ret = pinmux_enable(p); + if (ret) + p->usecount--; + } + mutex_unlock(&p->mutex); + return ret; +} +EXPORT_SYMBOL_GPL(pinctrl_enable); + +/** + * pinctrl_disable() - disable a certain pin control setting + * @p: the pin control handle to disable, previously claimed by pinctrl_get() + */ +void pinctrl_disable(struct pinctrl *p) +{ + if (p == NULL) + return; + + mutex_lock(&p->mutex); + if (--p->usecount == 0) { + pinmux_disable(p); + } + mutex_unlock(&p->mutex); +} +EXPORT_SYMBOL_GPL(pinctrl_disable); + +/** + * pinctrl_register_mappings() - register a set of pin controller mappings + * @maps: the pincontrol mappings table to register, this should be marked with + * __initdata so it can be discarded after boot, this function will + * perform a shallow copy for the mapping entries. + * @num_maps: the number of maps in the mapping table + * + * Only call this once during initialization of your machine, the function is + * tagged as __init and won't be callable after init has completed. The map + * passed into this function will be owned by the pinmux core and cannot be + * freed. + */ +int __init pinctrl_register_mappings(struct pinctrl_map const *maps, + unsigned num_maps) +{ + void *tmp_maps; + int i; + + pr_debug("add %d pinmux maps\n", num_maps); + + /* First sanity check the new mapping */ + for (i = 0; i < num_maps; i++) { + if (!maps[i].name) { + pr_err("failed to register map %d: no map name given\n", + i); + return -EINVAL; + } + + if (!maps[i].ctrl_dev_name) { + pr_err("failed to register map %s (%d): no pin control device given\n", + maps[i].name, i); + return -EINVAL; + } + + if (!maps[i].function) { + pr_err("failed to register map %s (%d): no function ID given\n", + maps[i].name, i); + return -EINVAL; + } + + if (!maps[i].dev_name) + pr_debug("add system map %s function %s with no device\n", + maps[i].name, + maps[i].function); + else + pr_debug("register map %s, function %s\n", + maps[i].name, + maps[i].function); + } + + /* + * Make a copy of the map array - string pointers will end up in the + * kernel const section anyway so these do not need to be deep copied. + */ + if (!pinctrl_maps_num) { + /* On first call, just copy them */ + tmp_maps = kmemdup(maps, + sizeof(struct pinctrl_map) * num_maps, + GFP_KERNEL); + if (!tmp_maps) + return -ENOMEM; + } else { + /* Subsequent calls, reallocate array to new size */ + size_t oldsize = sizeof(struct pinctrl_map) * pinctrl_maps_num; + size_t newsize = sizeof(struct pinctrl_map) * num_maps; + + tmp_maps = krealloc(pinctrl_maps, + oldsize + newsize, GFP_KERNEL); + if (!tmp_maps) + return -ENOMEM; + memcpy((tmp_maps + oldsize), maps, newsize); + } + + pinctrl_maps = tmp_maps; + pinctrl_maps_num += num_maps; + return 0; +} + +/* Hog a single map entry and add to the hoglist */ +static int pinctrl_hog_map(struct pinctrl_dev *pctldev, + struct pinctrl_map const *map) +{ + struct pinctrl_hog *hog; + struct pinctrl *p; + int ret; + + if (map->dev_name) { + /* + * TODO: the day we have device tree support, we can + * traverse the device tree and hog to specific device nodes + * without any problems, so then we can hog pinmuxes for + * all devices that just want a static pin mux at this point. + */ + dev_err(pctldev->dev, "map %s wants to hog a non-system pinmux, this is not going to work\n", + map->name); + return -EINVAL; + } + + hog = kzalloc(sizeof(struct pinctrl_hog), GFP_KERNEL); + if (!hog) + return -ENOMEM; + + p = pinctrl_get(NULL, map->name); + if (IS_ERR(p)) { + kfree(hog); + dev_err(pctldev->dev, + "could not get the %s pin control mapping for hogging\n", + map->name); + return PTR_ERR(p); + } + + ret = pinctrl_enable(p); + if (ret) { + pinctrl_put(p); + kfree(hog); + dev_err(pctldev->dev, + "could not enable the %s pin control mapping for hogging\n", + map->name); + return ret; + } + + hog->map = map; + hog->p = p; + + dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name, + map->function); + mutex_lock(&pctldev->pinctrl_hogs_lock); + list_add(&hog->node, &pctldev->pinctrl_hogs); + mutex_unlock(&pctldev->pinctrl_hogs_lock); + + return 0; +} + +/** + * pinctrl_hog_maps() - hog specific map entries on controller device + * @pctldev: the pin control device to hog entries on + * + * When the pin controllers are registered, there may be some specific pinmux + * map entries that need to be hogged, i.e. get+enabled until the system shuts + * down. + */ +int pinctrl_hog_maps(struct pinctrl_dev *pctldev) +{ + struct device *dev = pctldev->dev; + const char *devname = dev_name(dev); + int ret; + int i; + + INIT_LIST_HEAD(&pctldev->pinctrl_hogs); + mutex_init(&pctldev->pinctrl_hogs_lock); + + for (i = 0; i < pinctrl_maps_num; i++) { + struct pinctrl_map const *map = &pinctrl_maps[i]; + + if (!map->hog_on_boot) + continue; + + if (map->ctrl_dev_name && + !strcmp(map->ctrl_dev_name, devname)) { + /* OK time to hog! */ + ret = pinctrl_hog_map(pctldev, map); + if (ret) + return ret; + } + } + return 0; +} + +/** + * pinctrl_unhog_maps() - unhog specific map entries on controller device + * @pctldev: the pin control device to unhog entries on + */ +void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) +{ + struct list_head *node, *tmp; + + mutex_lock(&pctldev->pinctrl_hogs_lock); + list_for_each_safe(node, tmp, &pctldev->pinctrl_hogs) { + struct pinctrl_hog *hog = + list_entry(node, struct pinctrl_hog, node); + pinctrl_disable(hog->p); + pinctrl_put(hog->p); + list_del(node); + kfree(hog); + } + mutex_unlock(&pctldev->pinctrl_hogs_lock); +} + #ifdef CONFIG_DEBUG_FS static int pinctrl_pins_show(struct seq_file *s, void *what) @@ -427,6 +917,43 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) return 0; } +static int pinctrl_maps_show(struct seq_file *s, void *what) +{ + int i; + + seq_puts(s, "Pinctrl maps:\n"); + + for (i = 0; i < pinctrl_maps_num; i++) { + struct pinctrl_map const *map = &pinctrl_maps[i]; + + seq_printf(s, "%s:\n", map->name); + if (map->dev_name) + seq_printf(s, " device: %s\n", + map->dev_name); + else + seq_printf(s, " SYSTEM MUX\n"); + seq_printf(s, " controlling device %s\n", + map->ctrl_dev_name); + seq_printf(s, " function: %s\n", map->function); + seq_printf(s, " group: %s\n", map->group ? map->group : + "(default)"); + } + return 0; +} + +static int pinmux_hogs_show(struct seq_file *s, void *what) +{ + struct pinctrl_dev *pctldev = s->private; + struct pinctrl_hog *hog; + + seq_puts(s, "Pin control map hogs held by device\n"); + + list_for_each_entry(hog, &pctldev->pinctrl_hogs, node) + seq_printf(s, "%s\n", hog->map->name); + + return 0; +} + static int pinctrl_devices_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev; @@ -450,6 +977,32 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) return 0; } +static int pinctrl_show(struct seq_file *s, void *what) +{ + struct pinctrl *p; + + seq_puts(s, "Requested pin control handlers their pinmux maps:\n"); + list_for_each_entry(p, &pinctrl_list, node) { + struct pinctrl_dev *pctldev = p->pctldev; + + if (!pctldev) { + seq_puts(s, "NO PIN CONTROLLER DEVICE\n"); + continue; + } + + seq_printf(s, "device: %s", + pinctrl_dev_get_name(p->pctldev)); + + pinmux_dbg_show(s, p); + + seq_printf(s, " users: %u map-> %s\n", + p->usecount, + p->dev ? dev_name(p->dev) : "(system)"); + } + + return 0; +} + static int pinctrl_pins_open(struct inode *inode, struct file *file) { return single_open(file, pinctrl_pins_show, inode->i_private); @@ -465,11 +1018,26 @@ static int pinctrl_gpioranges_open(struct inode *inode, struct file *file) return single_open(file, pinctrl_gpioranges_show, inode->i_private); } +static int pinctrl_maps_open(struct inode *inode, struct file *file) +{ + return single_open(file, pinctrl_maps_show, inode->i_private); +} + +static int pinmux_hogs_open(struct inode *inode, struct file *file) +{ + return single_open(file, pinmux_hogs_show, inode->i_private); +} + static int pinctrl_devices_open(struct inode *inode, struct file *file) { return single_open(file, pinctrl_devices_show, NULL); } +static int pinctrl_open(struct inode *inode, struct file *file) +{ + return single_open(file, pinctrl_show, NULL); +} + static const struct file_operations pinctrl_pins_ops = { .open = pinctrl_pins_open, .read = seq_read, @@ -491,6 +1059,20 @@ static const struct file_operations pinctrl_gpioranges_ops = { .release = single_release, }; +static const struct file_operations pinctrl_maps_ops = { + .open = pinctrl_maps_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static const struct file_operations pinmux_hogs_ops = { + .open = pinmux_hogs_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static const struct file_operations pinctrl_devices_ops = { .open = pinctrl_devices_open, .read = seq_read, @@ -498,6 +1080,13 @@ static const struct file_operations pinctrl_devices_ops = { .release = single_release, }; +static const struct file_operations pinctrl_ops = { + .open = pinctrl_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static struct dentry *debugfs_root; static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) @@ -519,6 +1108,10 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) device_root, pctldev, &pinctrl_groups_ops); debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO, device_root, pctldev, &pinctrl_gpioranges_ops); + debugfs_create_file("pinctrl-maps", S_IFREG | S_IRUGO, + device_root, pctldev, &pinctrl_maps_ops); + debugfs_create_file("pinmux-hogs", S_IFREG | S_IRUGO, + device_root, pctldev, &pinmux_hogs_ops); pinmux_init_device_debugfs(device_root, pctldev); pinconf_init_device_debugfs(device_root, pctldev); } @@ -539,7 +1132,8 @@ static void pinctrl_init_debugfs(void) debugfs_create_file("pinctrl-devices", S_IFREG | S_IRUGO, debugfs_root, NULL, &pinctrl_devices_ops); - pinmux_init_debugfs(debugfs_root); + debugfs_create_file("pinctrl-handles", S_IFREG | S_IRUGO, + debugfs_root, NULL, &pinctrl_ops); } #else /* CONFIG_DEBUG_FS */ diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 7a89888..a50cdb0 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -30,6 +30,7 @@ struct pinctrl_gpio_range; * subsystem * @pinctrl_hogs_lock: lock for the pin control hog list * @pinctrl_hogs: list of pin control maps hogged by this device + * @device_root: debugfs root for this device */ struct pinctrl_dev { struct list_head node; @@ -41,12 +42,37 @@ struct pinctrl_dev { struct device *dev; struct module *owner; void *driver_data; + struct mutex pinctrl_hogs_lock; + struct list_head pinctrl_hogs; #ifdef CONFIG_DEBUG_FS struct dentry *device_root; #endif +}; + +/** + * struct pinctrl - per-device pin control state holder + * @node: global list node + * @dev: the device using this pin control handle + * @usecount: the number of active users of this pin controller setting, used + * to keep track of nested use cases + * @pctldev: pin control device handling this pin control handle + * @mutex: a lock for the pin control state holder + * @func_selector: the function selector for the pinmux device handling + * this pinmux + * @groups: the group selectors for the pinmux device and + * selector combination handling this pinmux, this is a list that + * will be traversed on all pinmux operations such as + * get/put/enable/disable + */ +struct pinctrl { + struct list_head node; + struct device *dev; + unsigned usecount; + struct pinctrl_dev *pctldev; + struct mutex mutex; #ifdef CONFIG_PINMUX - struct mutex pinctrl_hogs_lock; - struct list_head pinctrl_hogs; + unsigned func_selector; + struct list_head groups; #endif }; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 773835d..fe4a007 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -28,14 +28,7 @@ #include #include #include "core.h" - -/* List of pin controller handles */ -static DEFINE_MUTEX(pinctrl_list_mutex); -static LIST_HEAD(pinctrl_list); - -/* Global pinctrl maps */ -static struct pinctrl_map *pinctrl_maps; -static unsigned pinctrl_maps_num; +#include "pinmux.h" /** * struct pinmux_group - group list item for pinmux groups @@ -48,43 +41,6 @@ struct pinmux_group { }; /** - * struct pinctrl - per-device pin control state holder - * @node: global list node - * @dev: the device using this pin control handle - * @usecount: the number of active users of this pin controller setting, used - * to keep track of nested use cases - * @pctldev: pin control device handling this pin control handle - * @func_selector: the function selector for the pinmux device handling - * this pinmux - * @groups: the group selectors for the pinmux device and - * selector combination handling this pinmux, this is a list that - * will be traversed on all pinmux operations such as - * get/put/enable/disable - * @mutex: a lock for the pinmux state holder - */ -struct pinctrl { - struct list_head node; - struct device *dev; - unsigned usecount; - struct pinctrl_dev *pctldev; - unsigned func_selector; - struct list_head groups; - struct mutex mutex; -}; - -/** - * struct pinctrl_hog - a list item to stash control hogs - * @node: pin control hog list node - * @map: map entry responsible for this hogging - * @pmx: the pin control hogged by this item - */ -struct pinctrl_hog { - struct list_head node; - struct pinctrl_map const *map; - struct pinctrl *p; -}; - -/** * pin_request() - request a single pin to be muxed in, typically for GPIO * @pin: the pin number in the global pin space * @function: a functional name to give to this pin, passed to the driver @@ -207,28 +163,18 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, } /** - * pinctrl_request_gpio() - request a single pin to be used in as GPIO - * @gpio: the GPIO pin number from the GPIO subsystem number space - * - * This function should *ONLY* be used from gpiolib-based GPIO drivers, - * as part of their gpio_request() semantics, platforms and individual drivers - * shall *NOT* request GPIO pins to be muxed in. + * pinmux_request_gpio() - request pinmuxing for a GPIO pin + * @pctldev: pin controller device affected + * @pin: the pin to mux in for GPIO + * @range: the applicable GPIO range */ -int pinctrl_request_gpio(unsigned gpio) +int pinmux_request_gpio(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned pin, unsigned gpio) { char gpiostr[16]; const char *function; - struct pinctrl_dev *pctldev; - struct pinctrl_gpio_range *range; int ret; - int pin; - - ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); - if (ret) - return -EINVAL; - - /* Convert to the pin controllers number space */ - pin = gpio - range->base + range->pin_base; /* Conjure some name stating what chip and pin this is taken by */ snprintf(gpiostr, 15, "%s:%d", range->name, gpio); @@ -243,53 +189,38 @@ int pinctrl_request_gpio(unsigned gpio) return ret; } -EXPORT_SYMBOL_GPL(pinctrl_request_gpio); /** - * pinctrl_free_gpio() - free control on a single pin, currently used as GPIO - * @gpio: the GPIO pin number from the GPIO subsystem number space - * - * This function should *ONLY* be used from gpiolib-based GPIO drivers, - * as part of their gpio_free() semantics, platforms and individual drivers - * shall *NOT* request GPIO pins to be muxed out. + * pinmux_free_gpio() - release a pin from GPIO muxing + * @pctldev: the pin controller device for the pin + * @pin: the affected currently GPIO-muxed in pin + * @range: applicable GPIO range */ -void pinctrl_free_gpio(unsigned gpio) +void pinmux_free_gpio(struct pinctrl_dev *pctldev, unsigned pin, + struct pinctrl_gpio_range *range) { - struct pinctrl_dev *pctldev; - struct pinctrl_gpio_range *range; - int ret; - int pin; const char *func; - ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); - if (ret) - return; - - /* Convert to the pin controllers number space */ - pin = gpio - range->base + range->pin_base; - func = pin_free(pctldev, pin, range); kfree(func); } -EXPORT_SYMBOL_GPL(pinctrl_free_gpio); -static int pinctrl_gpio_direction(unsigned gpio, bool input) +/** + * pinmux_gpio_direction() - set the direction of a single muxed-in GPIO pin + * @pctldev: the pin controller handling this pin + * @range: applicable GPIO range + * @pin: the affected GPIO pin in this controller + * @input: true if we set the pin as input, false for output + */ +int pinmux_gpio_direction(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned pin, bool input) { - struct pinctrl_dev *pctldev; - struct pinctrl_gpio_range *range; const struct pinmux_ops *ops; int ret; - int pin; - - ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); - if (ret) - return ret; ops = pctldev->desc->pmxops; - /* Convert to the pin controllers number space */ - pin = gpio - range->base + range->pin_base; - if (ops->gpio_set_direction) ret = ops->gpio_set_direction(pctldev, range, pin, input); else @@ -299,112 +230,6 @@ static int pinctrl_gpio_direction(unsigned gpio, bool input) } /** - * pinctrl_gpio_direction_input() - request a GPIO pin to go into input mode - * @gpio: the GPIO pin number from the GPIO subsystem number space - * - * This function should *ONLY* be used from gpiolib-based GPIO drivers, - * as part of their gpio_direction_input() semantics, platforms and individual - * drivers shall *NOT* touch pin control GPIO calls. - */ -int pinctrl_gpio_direction_input(unsigned gpio) -{ - return pinctrl_gpio_direction(gpio, true); -} -EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input); - -/** - * pinctrl_gpio_direction_output() - request a GPIO pin to go into output mode - * @gpio: the GPIO pin number from the GPIO subsystem number space - * - * This function should *ONLY* be used from gpiolib-based GPIO drivers, - * as part of their gpio_direction_output() semantics, platforms and individual - * drivers shall *NOT* touch pin control GPIO calls. - */ -int pinctrl_gpio_direction_output(unsigned gpio) -{ - return pinctrl_gpio_direction(gpio, false); -} -EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); - -/** - * pinctrl_register_mappings() - register a set of pin controller mappings - * @maps: the pincontrol mappings table to register, this should be marked with - * __initdata so it can be discarded after boot, this function will - * perform a shallow copy for the mapping entries. - * @num_maps: the number of maps in the mapping table - * - * Only call this once during initialization of your machine, the function is - * tagged as __init and won't be callable after init has completed. The map - * passed into this function will be owned by the pinmux core and cannot be - * freed. - */ -int __init pinctrl_register_mappings(struct pinctrl_map const *maps, - unsigned num_maps) -{ - void *tmp_maps; - int i; - - pr_debug("add %d pinmux maps\n", num_maps); - - /* First sanity check the new mapping */ - for (i = 0; i < num_maps; i++) { - if (!maps[i].name) { - pr_err("failed to register map %d: no map name given\n", - i); - return -EINVAL; - } - - if (!maps[i].ctrl_dev_name) { - pr_err("failed to register map %s (%d): no pin control device given\n", - maps[i].name, i); - return -EINVAL; - } - - if (!maps[i].function) { - pr_err("failed to register map %s (%d): no function ID given\n", - maps[i].name, i); - return -EINVAL; - } - - if (!maps[i].dev_name) - pr_debug("add system map %s function %s with no device\n", - maps[i].name, - maps[i].function); - else - pr_debug("register map %s, function %s\n", - maps[i].name, - maps[i].function); - } - - /* - * Make a copy of the map array - string pointers will end up in the - * kernel const section anyway so these do not need to be deep copied. - */ - if (!pinctrl_maps_num) { - /* On first call, just copy them */ - tmp_maps = kmemdup(maps, - sizeof(struct pinctrl_map) * num_maps, - GFP_KERNEL); - if (!tmp_maps) - return -ENOMEM; - } else { - /* Subsequent calls, reallocate array to new size */ - size_t oldsize = sizeof(struct pinctrl_map) * pinctrl_maps_num; - size_t newsize = sizeof(struct pinctrl_map) * num_maps; - - tmp_maps = krealloc(pinctrl_maps, - oldsize + newsize, GFP_KERNEL); - if (!tmp_maps) - return -ENOMEM; - memcpy((tmp_maps + oldsize), maps, newsize); - } - - pinctrl_maps = tmp_maps; - pinctrl_maps_num += num_maps; - return 0; -} - -/** * acquire_pins() - acquire all the pins for a certain function on a pinmux * @pctldev: the device to take the pins on * @func_selector: the function selector to acquire the pins for @@ -660,227 +485,81 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, return 0; } -static void pinmux_free_groups(struct pinctrl *p) -{ - struct list_head *node, *tmp; - - list_for_each_safe(node, tmp, &p->groups) { - struct pinmux_group *grp = - list_entry(node, struct pinmux_group, node); - /* Release all pins taken by this group */ - release_pins(p->pctldev, grp->group_selector); - list_del(node); - kfree(grp); - } -} - /** - * pinctrl_get() - retrieves the pin controller handle for a certain device - * @dev: the device to get the pin controller handle for - * @name: an optional specific control mapping name or NULL, the name is only - * needed if you want to have more than one mapping per device, or if you - * need an anonymous pin control (not tied to any specific device) + * pinmux_apply_muxmap() - apply a certain mux mapping entry */ -struct pinctrl *pinctrl_get(struct device *dev, const char *name) +int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, + struct pinctrl *p, + struct device *dev, + const char *devname, + struct pinctrl_map const *map) { - struct pinctrl_map const *map = NULL; - struct pinctrl_dev *pctldev = NULL; - const char *devname = NULL; - struct pinctrl *p; - bool found_map; - unsigned num_maps = 0; - int ret = -ENODEV; - int i; - - /* We must have dev or ID or both */ - if (!dev && !name) - return ERR_PTR(-EINVAL); - - if (dev) - devname = dev_name(dev); - - pr_debug("get mux %s for device %s\n", name, - devname ? devname : "(none)"); - - /* - * create the state cookie holder struct pinmux for each - * mapping, this is what consumers will get when requesting - * a pinmux handle with pinmux_get() - */ - p = kzalloc(sizeof(struct pinctrl), GFP_KERNEL); - if (p == NULL) - return ERR_PTR(-ENOMEM); - mutex_init(&p->mutex); - p->func_selector = UINT_MAX; - INIT_LIST_HEAD(&p->groups); - - /* Iterate over the pin control maps to locate the right ones */ - for (i = 0; i < pinctrl_maps_num; i++) { - map = &pinctrl_maps[i]; - found_map = false; - - /* - * First, try to find the pctldev given in the map - */ - pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); - if (!pctldev) { - pr_warning("could not find a pinctrl device for pinmux function %s, fishy, they shall all have one\n", - map->function); - pr_warning("given pinctrl device name: %s", - map->ctrl_dev_name); - - /* Continue to check the other mappings anyway... */ - continue; - } - - pr_debug("in map, found pctldev %s to handle function %s", - dev_name(pctldev->dev), map->function); - - - /* - * If we're looking for a specific named map, this must match, - * else we loop and look for the next. - */ - if (name != NULL) { - if (map->name == NULL) - continue; - if (strcmp(map->name, name)) - continue; - } - - /* - * This is for the case where no device name is given, we - * already know that the function name matches from above - * code. - */ - if (!map->dev_name && (name != NULL)) - found_map = true; - - /* If the mapping has a device set up it must match */ - if (map->dev_name && - (!devname || !strcmp(map->dev_name, devname))) - /* MATCH! */ - found_map = true; - - /* If this map is applicable, then apply it */ - if (found_map) { - ret = pinmux_enable_muxmap(pctldev, p, dev, - devname, map); - if (ret) { - pinmux_free_groups(p); - kfree(p); - return ERR_PTR(ret); - } - num_maps++; - } - } - + int ret; - /* We should have atleast one map, right */ - if (!num_maps) { - pr_err("could not find any mux maps for device %s, ID %s\n", - devname ? devname : "(anonymous)", - name ? name : "(undefined)"); - kfree(p); - return ERR_PTR(-EINVAL); + ret = pinmux_enable_muxmap(pctldev, p, dev, + devname, map); + if (ret) { + pinmux_put(p); + return ret; } - pr_debug("found %u mux maps for device %s, UD %s\n", - num_maps, - devname ? devname : "(anonymous)", - name ? name : "(undefined)"); - - /* Add the pinmux to the global list */ - mutex_lock(&pinctrl_list_mutex); - list_add(&p->node, &pinctrl_list); - mutex_unlock(&pinctrl_list_mutex); - - return p; + return 0; } -EXPORT_SYMBOL_GPL(pinctrl_get); /** - * pinctrl_put() - release a previously claimed pin control handle - * @p: a pin control handle previously claimed by pinctrl_get() + * pinmux_put() - free up the pinmux portions of a pin controller handle */ -void pinctrl_put(struct pinctrl *p) +void pinmux_put(struct pinctrl *p) { - if (p == NULL) - return; - - mutex_lock(&p->mutex); - if (p->usecount) - pr_warn("releasing pin control handle with active users!\n"); - /* Free the groups and all acquired pins */ - pinmux_free_groups(p); - mutex_unlock(&p->mutex); - - /* Remove from list */ - mutex_lock(&pinctrl_list_mutex); - list_del(&p->node); - mutex_unlock(&pinctrl_list_mutex); + struct list_head *node, *tmp; - kfree(p); + list_for_each_safe(node, tmp, &p->groups) { + struct pinmux_group *grp = + list_entry(node, struct pinmux_group, node); + /* Release all pins taken by this group */ + release_pins(p->pctldev, grp->group_selector); + list_del(node); + kfree(grp); + } } -EXPORT_SYMBOL_GPL(pinctrl_put); /** - * pinctrl_enable() - enable a certain pin controller setting - * @p: the pin control handle to enable, previously claimed by pinctrl_get() + * pinmux_enable() - enable the pinmux portion of a pin control handle */ -int pinctrl_enable(struct pinctrl *p) +int pinmux_enable(struct pinctrl *p) { - int ret = 0; + struct pinctrl_dev *pctldev = p->pctldev; + const struct pinmux_ops *ops = pctldev->desc->pmxops; + struct pinmux_group *grp; + int ret; - if (p == NULL) - return -EINVAL; - mutex_lock(&p->mutex); - if (p->usecount++ == 0) { - struct pinctrl_dev *pctldev = p->pctldev; - const struct pinmux_ops *ops = pctldev->desc->pmxops; - struct pinmux_group *grp; - - list_for_each_entry(grp, &p->groups, node) { - ret = ops->enable(pctldev, p->func_selector, - grp->group_selector); - if (ret) { - /* - * TODO: call disable() on all groups we called - * enable() on to this point? - */ - p->usecount--; - break; - } - } + list_for_each_entry(grp, &p->groups, node) { + ret = ops->enable(pctldev, p->func_selector, + grp->group_selector); + if (ret) + /* + * TODO: call disable() on all groups we called + * enable() on to this point? + */ + return ret; } - mutex_unlock(&p->mutex); - return ret; + return 0; } -EXPORT_SYMBOL_GPL(pinctrl_enable); /** - * pinctrl_disable() - disable a certain pin control setting - * @p: the pin control handle to disable, previously claimed by pinctrl_get() + * pinmux_disable() - disable the pinmux portions of a pin control handle */ -void pinctrl_disable(struct pinctrl *p) +void pinmux_disable(struct pinctrl *p) { - if (p == NULL) - return; - - mutex_lock(&p->mutex); - if (--p->usecount == 0) { - struct pinctrl_dev *pctldev = p->pctldev; - const struct pinmux_ops *ops = pctldev->desc->pmxops; - struct pinmux_group *grp; + struct pinctrl_dev *pctldev = p->pctldev; + const struct pinmux_ops *ops = pctldev->desc->pmxops; + struct pinmux_group *grp; - list_for_each_entry(grp, &p->groups, node) { - ops->disable(pctldev, p->func_selector, - grp->group_selector); - } + list_for_each_entry(grp, &p->groups, node) { + ops->disable(pctldev, p->func_selector, + grp->group_selector); } - mutex_unlock(&p->mutex); } -EXPORT_SYMBOL_GPL(pinctrl_disable); int pinmux_check_ops(struct pinctrl_dev *pctldev) { @@ -910,116 +589,6 @@ int pinmux_check_ops(struct pinctrl_dev *pctldev) return 0; } -/* Hog a single map entry and add to the hoglist */ -static int pinctrl_hog_map(struct pinctrl_dev *pctldev, - struct pinctrl_map const *map) -{ - struct pinctrl_hog *hog; - struct pinctrl *p; - int ret; - - if (map->dev_name) { - /* - * TODO: the day we have device tree support, we can - * traverse the device tree and hog to specific device nodes - * without any problems, so then we can hog pinmuxes for - * all devices that just want a static pin mux at this point. - */ - dev_err(pctldev->dev, "map %s wants to hog a non-system pinmux, this is not going to work\n", - map->name); - return -EINVAL; - } - - hog = kzalloc(sizeof(struct pinctrl_hog), GFP_KERNEL); - if (!hog) - return -ENOMEM; - - p = pinctrl_get(NULL, map->name); - if (IS_ERR(p)) { - kfree(hog); - dev_err(pctldev->dev, - "could not get the %s pin control mapping for hogging\n", - map->name); - return PTR_ERR(p); - } - - ret = pinctrl_enable(p); - if (ret) { - pinctrl_put(p); - kfree(hog); - dev_err(pctldev->dev, - "could not enable the %s pin control mapping for hogging\n", - map->name); - return ret; - } - - hog->map = map; - hog->p = p; - - dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name, - map->function); - mutex_lock(&pctldev->pinctrl_hogs_lock); - list_add(&hog->node, &pctldev->pinctrl_hogs); - mutex_unlock(&pctldev->pinctrl_hogs_lock); - - return 0; -} - -/** - * pinctrl_hog_maps() - hog specific map entries on controller device - * @pctldev: the pin control device to hog entries on - * - * When the pin controllers are registered, there may be some specific pinmux - * map entries that need to be hogged, i.e. get+enabled until the system shuts - * down. - */ -int pinctrl_hog_maps(struct pinctrl_dev *pctldev) -{ - struct device *dev = pctldev->dev; - const char *devname = dev_name(dev); - int ret; - int i; - - INIT_LIST_HEAD(&pctldev->pinctrl_hogs); - mutex_init(&pctldev->pinctrl_hogs_lock); - - for (i = 0; i < pinctrl_maps_num; i++) { - struct pinctrl_map const *map = &pinctrl_maps[i]; - - if (!map->hog_on_boot) - continue; - - if (map->ctrl_dev_name && - !strcmp(map->ctrl_dev_name, devname)) { - /* OK time to hog! */ - ret = pinctrl_hog_map(pctldev, map); - if (ret) - return ret; - } - } - return 0; -} - -/** - * pinctrl_unhog_maps() - unhog specific map entries on controller device - * @pctldev: the pin control device to unhog entries on - */ -void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) -{ - struct list_head *node, *tmp; - - mutex_lock(&pctldev->pinctrl_hogs_lock); - list_for_each_safe(node, tmp, &pctldev->pinctrl_hogs) { - struct pinctrl_hog *hog = - list_entry(node, struct pinctrl_hog, node); - pinctrl_disable(hog->p); - pinctrl_put(hog->p); - list_del(node); - kfree(hog); - } - mutex_unlock(&pctldev->pinctrl_hogs_lock); -} - #ifdef CONFIG_DEBUG_FS /* Called from pincontrol core */ @@ -1083,83 +652,29 @@ static int pinmux_pins_show(struct seq_file *s, void *what) return 0; } -static int pinmux_hogs_show(struct seq_file *s, void *what) -{ - struct pinctrl_dev *pctldev = s->private; - struct pinctrl_hog *hog; - - seq_puts(s, "Pin control map hogs held by device\n"); - - list_for_each_entry(hog, &pctldev->pinctrl_hogs, node) - seq_printf(s, "%s\n", hog->map->name); - - return 0; -} - -static int pinmux_show(struct seq_file *s, void *what) +void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p) { - struct pinctrl *p; - - seq_puts(s, "Requested pinmuxes and their maps:\n"); - list_for_each_entry(p, &pinctrl_list, node) { - struct pinctrl_dev *pctldev = p->pctldev; - const struct pinmux_ops *pmxops; - const struct pinctrl_ops *pctlops; - struct pinmux_group *grp; - - if (!pctldev) { - seq_puts(s, "NO PIN CONTROLLER DEVICE\n"); - continue; - } - - pmxops = pctldev->desc->pmxops; - pctlops = pctldev->desc->pctlops; - - seq_printf(s, "device: %s function: %s (%u),", - pinctrl_dev_get_name(p->pctldev), - pmxops->get_function_name(pctldev, - p->func_selector), - p->func_selector); - - seq_printf(s, " groups: ["); - list_for_each_entry(grp, &p->groups, node) { - seq_printf(s, " %s (%u)", - pctlops->get_group_name(pctldev, - grp->group_selector), - grp->group_selector); - } - seq_printf(s, " ]"); + struct pinctrl_dev *pctldev = p->pctldev; + const struct pinmux_ops *pmxops; + const struct pinctrl_ops *pctlops; + struct pinmux_group *grp; - seq_printf(s, " users: %u map-> %s\n", - p->usecount, - p->dev ? dev_name(p->dev) : "(system)"); - } + pmxops = pctldev->desc->pmxops; + pctlops = pctldev->desc->pctlops; - return 0; -} - -static int pinctrl_maps_show(struct seq_file *s, void *what) -{ - int i; + seq_printf(s, " function: %s (%u),", + pmxops->get_function_name(pctldev, + p->func_selector), + p->func_selector); - seq_puts(s, "Pinctrl maps:\n"); - - for (i = 0; i < pinctrl_maps_num; i++) { - struct pinctrl_map const *map = &pinctrl_maps[i]; - - seq_printf(s, "%s:\n", map->name); - if (map->dev_name) - seq_printf(s, " device: %s\n", - map->dev_name); - else - seq_printf(s, " SYSTEM MUX\n"); - seq_printf(s, " controlling device %s\n", - map->ctrl_dev_name); - seq_printf(s, " function: %s\n", map->function); - seq_printf(s, " group: %s\n", map->group ? map->group : - "(default)"); + seq_printf(s, " groups: ["); + list_for_each_entry(grp, &p->groups, node) { + seq_printf(s, " %s (%u)", + pctlops->get_group_name(pctldev, + grp->group_selector), + grp->group_selector); } - return 0; + seq_printf(s, " ]"); } static int pinmux_functions_open(struct inode *inode, struct file *file) @@ -1172,21 +687,6 @@ static int pinmux_pins_open(struct inode *inode, struct file *file) return single_open(file, pinmux_pins_show, inode->i_private); } -static int pinmux_hogs_open(struct inode *inode, struct file *file) -{ - return single_open(file, pinmux_hogs_show, inode->i_private); -} - -static int pinmux_open(struct inode *inode, struct file *file) -{ - return single_open(file, pinmux_show, NULL); -} - -static int pinctrl_maps_open(struct inode *inode, struct file *file) -{ - return single_open(file, pinctrl_maps_show, NULL); -} - static const struct file_operations pinmux_functions_ops = { .open = pinmux_functions_open, .read = seq_read, @@ -1201,27 +701,6 @@ static const struct file_operations pinmux_pins_ops = { .release = single_release, }; -static const struct file_operations pinmux_hogs_ops = { - .open = pinmux_hogs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations pinmux_ops = { - .open = pinmux_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - -static const struct file_operations pinctrl_maps_ops = { - .open = pinctrl_maps_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - void pinmux_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev) { @@ -1229,16 +708,6 @@ void pinmux_init_device_debugfs(struct dentry *devroot, devroot, pctldev, &pinmux_functions_ops); debugfs_create_file("pinmux-pins", S_IFREG | S_IRUGO, devroot, pctldev, &pinmux_pins_ops); - debugfs_create_file("pinmux-hogs", S_IFREG | S_IRUGO, - devroot, pctldev, &pinmux_hogs_ops); -} - -void pinmux_init_debugfs(struct dentry *subsys_root) -{ - debugfs_create_file("pinmuxes", S_IFREG | S_IRUGO, - subsys_root, NULL, &pinmux_ops); - debugfs_create_file("pinctrl-maps", S_IFREG | S_IRUGO, - subsys_root, NULL, &pinctrl_maps_ops); } #endif /* CONFIG_DEBUG_FS */ diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h index dfe8172..7680a17 100644 --- a/drivers/pinctrl/pinmux.h +++ b/drivers/pinctrl/pinmux.h @@ -15,9 +15,28 @@ int pinmux_check_ops(struct pinctrl_dev *pctldev); void pinmux_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev); -void pinmux_init_debugfs(struct dentry *subsys_root); -int pinctrl_hog_maps(struct pinctrl_dev *pctldev); -void pinctrl_unhog_maps(struct pinctrl_dev *pctldev); +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); +static inline void pinmux_init_pinctrl_handle(struct pinctrl *p) +{ + p->func_selector = UINT_MAX; + INIT_LIST_HEAD(&p->groups); +} +int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, + struct pinctrl *p, + struct device *dev, + const char *devname, + struct pinctrl_map const *map); +void pinmux_put(struct pinctrl *p); +int pinmux_enable(struct pinctrl *p); +void pinmux_disable(struct pinctrl *p); +void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p); #else @@ -31,16 +50,52 @@ static inline void pinmux_init_device_debugfs(struct dentry *devroot, { } -static inline void pinmux_init_debugfs(struct dentry *subsys_root) +static inline int pinmux_request_gpio(struct pinctrl_dev *pctldev, + struct pinctrl_gpio_range *range, + unsigned pin, unsigned gpio) +{ + return 0; +} + +static inline 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 void pinmux_init_pinctrl_handle(struct pinctrl *p) { } -static inline int pinctrl_hog_maps(struct pinctrl_dev *pctldev) +static inline int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, + struct pinctrl *p, + struct device *dev, + const char *devname, + struct pinctrl_map const *map) { return 0; } -static inline void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) +static inline void pinmux_put(struct pinctrl *p) +{ +} + +static inline int pinmux_enable(struct pinctrl *p) +{ +} + +static inline void pinmux_disable(struct pinctrl *p) +{ +} + +void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p) { } diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h index c7d0617..3086594 100644 --- a/include/linux/pinctrl/consumer.h +++ b/include/linux/pinctrl/consumer.h @@ -19,9 +19,9 @@ /* This struct is private to the core and should be regarded as a cookie */ struct pinctrl; -#ifdef CONFIG_PINMUX +#ifdef CONFIG_PINCTRL -/* External interface to pinmux */ +/* 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); @@ -31,7 +31,7 @@ extern void pinctrl_put(struct pinctrl *p); extern int pinctrl_enable(struct pinctrl *p); extern void pinctrl_disable(struct pinctrl *p); -#else /* !CONFIG_PINMUX */ +#else /* !CONFIG_PINCTRL */ static inline int pinctrl_request_gpio(unsigned gpio) { @@ -70,7 +70,7 @@ static inline void pinctrl_disable(struct pinctrl *p) { } -#endif /* CONFIG_PINMUX */ +#endif /* CONFIG_PINCTRL */ #ifdef CONFIG_PINCONF -- cgit v0.10.2 From 77a5988355f993840928d195f790a939200a4ff0 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 10 Feb 2012 01:34:12 +0100 Subject: pinctrl: changes hog mechanism to be self-referential Instead of a specific boolean field to indicate if a map entry shall be hogged, treat self-reference as an indication of desired hogging. This drops one field off the map struct and has a nice Douglas R. Hofstadter-feel to it. Acked-by: Dong Aisheng Acked-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 2e71323..ee3266b 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -989,21 +989,21 @@ is registered. This means that the core will attempt to call pinctrl_get() and pinctrl_enable() 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 is enabled by simply setting the .dev_name field in the map to the name +of the pin controller itself, like this: { .name = "POWERMAP" .ctrl_dev_name = "pinctrl-foo", .function = "power_func", - .hog_on_boot = true, + .dev_name = "pinctrl-foo", }, 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: -PIN_MAP_PRIMARY_SYS_HOG("POWERMAP", "power_func") +PIN_MAP_PRIMARY_SYS_HOG("POWERMAP", "pinctrl-foo", "power_func") This gives the exact same result as the above construction. diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index ec32c54..c5f76ad 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -793,11 +793,9 @@ int pinctrl_hog_maps(struct pinctrl_dev *pctldev) for (i = 0; i < pinctrl_maps_num; i++) { struct pinctrl_map const *map = &pinctrl_maps[i]; - if (!map->hog_on_boot) - continue; - if (map->ctrl_dev_name && - !strcmp(map->ctrl_dev_name, devname)) { + !strcmp(map->ctrl_dev_name, devname) && + !strcmp(map->dev_name, devname)) { /* OK time to hog! */ ret = pinctrl_hog_map(pctldev, map); if (ret) diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index a2ab524..af145d5 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -26,13 +26,9 @@ * selects a certain specific pin group to activate for the function, if * left as NULL, the first applicable group will be used * @dev_name: the name of the device using this specific mapping, the name - * must be the same as in your struct device* - * @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. + * 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 */ struct pinctrl_map { const char *name; @@ -40,7 +36,6 @@ struct pinctrl_map { const char *function; const char *group; const char *dev_name; - bool hog_on_boot; }; /* @@ -62,8 +57,7 @@ struct pinctrl_map { * to be hogged by the pin control core until the system shuts down. */ #define PIN_MAP_SYS_HOG(a, b, c) \ - { .name = a, .ctrl_dev_name = b, .function = c, \ - .hog_on_boot = true } + { .name = a, .ctrl_dev_name = b, .dev_name = b, .function = c, } /* * Convenience macro to map a system function onto a certain pinctrl device @@ -71,8 +65,8 @@ struct pinctrl_map { * system shuts down. */ #define PIN_MAP_SYS_HOG_GROUP(a, b, c, d) \ - { .name = a, .ctrl_dev_name = b, .function = c, .group = d, \ - .hog_on_boot = true } + { .name = a, .ctrl_dev_name = b, .dev_name = b, .function = c, \ + .group = d, } #ifdef CONFIG_PINMUX -- cgit v0.10.2 From 5c9bdc3f52d20c9bc6c2552c6d3ec5bfa4119f75 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 16 Feb 2012 19:36:21 +0100 Subject: serial/sirf: fixup for changes to pin control We changed the signature of the pin multiplexing functions to handle any pin business, so fix up the Sirf driver to call this new interface and rename some variables to make the semantics understandable. Cc: linux-serial@vger.kernel.org Acked-by: Greg Kroah-Hartman Acked-by: Barry Song Signed-off-by: Linus Walleij diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index a60523f..c1a871e 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c @@ -22,7 +22,7 @@ #include #include #include -#include +#include #include "sirfsoc_uart.h" @@ -673,12 +673,12 @@ 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(&pdev->dev, NULL); + ret = IS_ERR(sirfport->p); if (ret) - goto pmx_err; + goto pin_err; - pinmux_enable(sirfport->pmx); + pinctrl_enable(sirfport->p); } port->ops = &sirfsoc_uart_ops; @@ -696,10 +696,10 @@ 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); + pinctrl_disable(sirfport->p); + pinctrl_put(sirfport->p); } -pmx_err: +pin_err: irq_err: devm_iounmap(&pdev->dev, port->membase); err: @@ -712,8 +712,8 @@ static int sirfsoc_uart_remove(struct platform_device *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); + pinctrl_disable(sirfport->p); + pinctrl_put(sirfport->p); } devm_iounmap(&pdev->dev, port->membase); uart_remove_one_port(&sirfsoc_uart_drv, port); diff --git a/drivers/tty/serial/sirfsoc_uart.h b/drivers/tty/serial/sirfsoc_uart.h index fc64260..6e207fd 100644 --- a/drivers/tty/serial/sirfsoc_uart.h +++ b/drivers/tty/serial/sirfsoc_uart.h @@ -162,7 +162,7 @@ struct sirfsoc_uart_port { unsigned char ms_enabled; struct uart_port port; - struct pinmux *pmx; + struct pinctrl *p; }; /* Hardware Flow Control */ -- cgit v0.10.2 From 449d16b025ac38c7b62af5fb6ef4b833d78e690d Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 14 Feb 2012 10:50:41 -0700 Subject: pinctrl: make "hog" mapping table entries work Commit 77a5988 "pinctrl: changes hog mechanism to be self-referential" modified the way "hog" entries were represented in the mapping table. However, the new representation failed some error checks in pinctrl_hog_map(). Remove the now-bogus error-check, and fix the code to solve the issue the error-check used to avoid. Acked-by: Dong Aisheng Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index c5f76ad..8a91eb2 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -725,23 +725,11 @@ static int pinctrl_hog_map(struct pinctrl_dev *pctldev, struct pinctrl *p; int ret; - if (map->dev_name) { - /* - * TODO: the day we have device tree support, we can - * traverse the device tree and hog to specific device nodes - * without any problems, so then we can hog pinmuxes for - * all devices that just want a static pin mux at this point. - */ - dev_err(pctldev->dev, "map %s wants to hog a non-system pinmux, this is not going to work\n", - map->name); - return -EINVAL; - } - hog = kzalloc(sizeof(struct pinctrl_hog), GFP_KERNEL); if (!hog) return -ENOMEM; - p = pinctrl_get(NULL, map->name); + p = pinctrl_get(pctldev->dev, map->name); if (IS_ERR(p)) { kfree(hog); dev_err(pctldev->dev, -- cgit v0.10.2 From 13398a4b90c87f0250928f01b5735a157fcc0847 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Sun, 19 Feb 2012 23:45:41 -0700 Subject: pinctrl: pinctrl_register_mappings() shouldn't be __init It may be common for pinctrl_register_mappings() to be used from __init context, but there's no reason that additional mappings shouldn't be added at a later point, e.g. if loading modules that add pin controllers and their mapping tables. Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 8a91eb2..84a24a6 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -641,18 +641,13 @@ EXPORT_SYMBOL_GPL(pinctrl_disable); /** * pinctrl_register_mappings() - register a set of pin controller mappings - * @maps: the pincontrol mappings table to register, this should be marked with - * __initdata so it can be discarded after boot, this function will - * perform a shallow copy for the mapping entries. + * @maps: the pincontrol mappings table to register. This should probably be + * marked with __initdata so it can be discarded after boot. This + * function will perform a shallow copy for the mapping entries. * @num_maps: the number of maps in the mapping table - * - * Only call this once during initialization of your machine, the function is - * tagged as __init and won't be callable after init has completed. The map - * passed into this function will be owned by the pinmux core and cannot be - * freed. */ -int __init pinctrl_register_mappings(struct pinctrl_map const *maps, - unsigned num_maps) +int pinctrl_register_mappings(struct pinctrl_map const *maps, + unsigned num_maps) { void *tmp_maps; int i; -- cgit v0.10.2 From 8b9c139f166cd55d76728a5910fa862a4e16e833 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Sun, 19 Feb 2012 23:45:42 -0700 Subject: pinctrl: use list_add_tail instead of list_add This mostly makes debugfs files print things in the order that they were added or acquired, which just feels a little more consistent. Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 84a24a6..feadf1c 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -309,7 +309,7 @@ void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range) { mutex_lock(&pctldev->gpio_ranges_lock); - list_add(&range->node, &pctldev->gpio_ranges); + list_add_tail(&range->node, &pctldev->gpio_ranges); mutex_unlock(&pctldev->gpio_ranges_lock); } @@ -569,7 +569,7 @@ struct pinctrl *pinctrl_get(struct device *dev, const char *name) /* Add the pinmux to the global list */ mutex_lock(&pinctrl_list_mutex); - list_add(&p->node, &pinctrl_list); + list_add_tail(&p->node, &pinctrl_list); mutex_unlock(&pinctrl_list_mutex); return p; @@ -749,7 +749,7 @@ static int pinctrl_hog_map(struct pinctrl_dev *pctldev, dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name, map->function); mutex_lock(&pctldev->pinctrl_hogs_lock); - list_add(&hog->node, &pctldev->pinctrl_hogs); + list_add_tail(&hog->node, &pctldev->pinctrl_hogs); mutex_unlock(&pctldev->pinctrl_hogs_lock); return 0; @@ -1197,7 +1197,7 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, pinctrl_init_device_debugfs(pctldev); mutex_lock(&pinctrldev_list_mutex); - list_add(&pctldev->node, &pinctrldev_list); + list_add_tail(&pctldev->node, &pinctrldev_list); mutex_unlock(&pinctrldev_list_mutex); pinctrl_hog_maps(pctldev); return pctldev; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index fe4a007..5a09cd2 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -480,7 +480,7 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, kfree(grp); return ret; } - list_add(&grp->node, &p->groups); + list_add_tail(&grp->node, &p->groups); return 0; } -- cgit v0.10.2 From b2b3e66e40bb60b1aa222d2f712c019653215390 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Sun, 19 Feb 2012 23:45:43 -0700 Subject: pinctrl: Store mapping table as a list of chunks Instead of storing a single array of mapping table entries, which requires realloc()ing that array each time it's extended and copying the new data, simply store a list of pointers to the individual chunks. This also removes the need to copy the mapping table at all; a pointer is maintained to the original table, this saving memory. A macro for_each_maps() is introduced to hide the additional complexity of iterating over the map entries. This change will also simplify removing chunks of entries from the mapping table. This isn't important right now, but will be in the future, when mapping table entries are dynamically added when parsing them from the device tree, and removed when drivers no longer need to interact with pinctrl. Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index feadf1c..50bcc51 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -7,6 +7,8 @@ * * Author: Linus Walleij * + * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. + * * License terms: GNU General Public License (GPL) version 2 */ #define pr_fmt(fmt) "pinctrl core: " fmt @@ -31,6 +33,18 @@ #include "pinconf.h" /** + * struct pinctrl_maps - a list item containing part of the mapping table + * @node: mapping table list node + * @maps: array of mapping table entries + * @num_maps: the number of entries in @maps + */ +struct pinctrl_maps { + struct list_head node; + struct pinctrl_map const *maps; + unsigned num_maps; +}; + +/** * struct pinctrl_hog - a list item to stash control hogs * @node: pin control hog list node * @map: map entry responsible for this hogging @@ -51,8 +65,14 @@ static DEFINE_MUTEX(pinctrl_list_mutex); static LIST_HEAD(pinctrl_list); /* Global pinctrl maps */ -static struct pinctrl_map *pinctrl_maps; -static unsigned pinctrl_maps_num; +static DEFINE_MUTEX(pinctrl_maps_mutex); +static LIST_HEAD(pinctrl_maps); + +#define for_each_maps(_maps_node_, _i_, _map_) \ + list_for_each_entry(_maps_node_, &pinctrl_maps, node) \ + for (_i_ = 0, _map_ = &_maps_node_->maps[_i_]; \ + _i_ < _maps_node_->num_maps; \ + i++, _map_ = &_maps_node_->maps[_i_]) const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev) { @@ -454,23 +474,17 @@ int pinctrl_gpio_direction_output(unsigned gpio) } EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); -/** - * pinctrl_get() - retrieves the pin controller handle for a certain device - * @dev: the device to get the pin controller handle for - * @name: an optional specific control mapping name or NULL, the name is only - * needed if you want to have more than one mapping per device, or if you - * need an anonymous pin control (not tied to any specific device) - */ -struct pinctrl *pinctrl_get(struct device *dev, const char *name) +static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) { - struct pinctrl_map const *map = NULL; struct pinctrl_dev *pctldev = NULL; const char *devname = NULL; struct pinctrl *p; bool found_map; unsigned num_maps = 0; int ret = -ENODEV; + struct pinctrl_maps *maps_node; int i; + struct pinctrl_map const *map; /* We must have dev or ID or both */ if (!dev && !name) @@ -494,8 +508,7 @@ struct pinctrl *pinctrl_get(struct device *dev, const char *name) pinmux_init_pinctrl_handle(p); /* Iterate over the pin control maps to locate the right ones */ - for (i = 0; i < pinctrl_maps_num; i++) { - map = &pinctrl_maps[i]; + for_each_maps(maps_node, i, map) { found_map = false; /* @@ -515,7 +528,6 @@ struct pinctrl *pinctrl_get(struct device *dev, const char *name) pr_debug("in map, found pctldev %s to handle function %s", dev_name(pctldev->dev), map->function); - /* * If we're looking for a specific named map, this must match, * else we loop and look for the next. @@ -574,6 +586,24 @@ struct pinctrl *pinctrl_get(struct device *dev, const char *name) return p; } + +/** + * pinctrl_get() - retrieves the pin controller handle for a certain device + * @dev: the device to get the pin controller handle for + * @name: an optional specific control mapping name or NULL, the name is only + * needed if you want to have more than one mapping per device, or if you + * need an anonymous pin control (not tied to any specific device) + */ +struct pinctrl *pinctrl_get(struct device *dev, const char *name) +{ + struct pinctrl *p; + + mutex_lock(&pinctrl_maps_mutex); + p = pinctrl_get_locked(dev, name); + mutex_unlock(&pinctrl_maps_mutex); + + return p; +} EXPORT_SYMBOL_GPL(pinctrl_get); /** @@ -649,8 +679,8 @@ EXPORT_SYMBOL_GPL(pinctrl_disable); int pinctrl_register_mappings(struct pinctrl_map const *maps, unsigned num_maps) { - void *tmp_maps; int i; + struct pinctrl_maps *maps_node; pr_debug("add %d pinmux maps\n", num_maps); @@ -684,31 +714,23 @@ int pinctrl_register_mappings(struct pinctrl_map const *maps, maps[i].function); } - /* - * Make a copy of the map array - string pointers will end up in the - * kernel const section anyway so these do not need to be deep copied. - */ - if (!pinctrl_maps_num) { - /* On first call, just copy them */ - tmp_maps = kmemdup(maps, - sizeof(struct pinctrl_map) * num_maps, - GFP_KERNEL); - if (!tmp_maps) - return -ENOMEM; - } else { - /* Subsequent calls, reallocate array to new size */ - size_t oldsize = sizeof(struct pinctrl_map) * pinctrl_maps_num; - size_t newsize = sizeof(struct pinctrl_map) * num_maps; + maps_node = kzalloc(sizeof(*maps_node), GFP_KERNEL); + if (!maps_node) { + pr_err("failed to alloc struct pinctrl_maps\n"); + return -ENOMEM; + } - tmp_maps = krealloc(pinctrl_maps, - oldsize + newsize, GFP_KERNEL); - if (!tmp_maps) - return -ENOMEM; - memcpy((tmp_maps + oldsize), maps, newsize); + maps_node->num_maps = num_maps; + maps_node->maps = kmemdup(maps, sizeof(*maps) * num_maps, GFP_KERNEL); + if (!maps_node->maps) { + kfree(maps_node); + return -ENOMEM; } - pinctrl_maps = tmp_maps; - pinctrl_maps_num += num_maps; + mutex_lock(&pinctrl_maps_mutex); + list_add_tail(&maps_node->node, &pinctrl_maps); + mutex_unlock(&pinctrl_maps_mutex); + return 0; } @@ -724,7 +746,7 @@ static int pinctrl_hog_map(struct pinctrl_dev *pctldev, if (!hog) return -ENOMEM; - p = pinctrl_get(pctldev->dev, map->name); + p = pinctrl_get_locked(pctldev->dev, map->name); if (IS_ERR(p)) { kfree(hog); dev_err(pctldev->dev, @@ -768,23 +790,28 @@ int pinctrl_hog_maps(struct pinctrl_dev *pctldev) struct device *dev = pctldev->dev; const char *devname = dev_name(dev); int ret; + struct pinctrl_maps *maps_node; int i; + struct pinctrl_map const *map; INIT_LIST_HEAD(&pctldev->pinctrl_hogs); mutex_init(&pctldev->pinctrl_hogs_lock); - for (i = 0; i < pinctrl_maps_num; i++) { - struct pinctrl_map const *map = &pinctrl_maps[i]; - + mutex_lock(&pinctrl_maps_mutex); + for_each_maps(maps_node, i, map) { if (map->ctrl_dev_name && !strcmp(map->ctrl_dev_name, devname) && !strcmp(map->dev_name, devname)) { /* OK time to hog! */ ret = pinctrl_hog_map(pctldev, map); - if (ret) + if (ret) { + mutex_unlock(&pinctrl_maps_mutex); return ret; + } } } + mutex_unlock(&pinctrl_maps_mutex); + return 0; } @@ -900,13 +927,14 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) static int pinctrl_maps_show(struct seq_file *s, void *what) { + struct pinctrl_maps *maps_node; int i; + struct pinctrl_map const *map; seq_puts(s, "Pinctrl maps:\n"); - for (i = 0; i < pinctrl_maps_num; i++) { - struct pinctrl_map const *map = &pinctrl_maps[i]; - + mutex_lock(&pinctrl_maps_mutex); + for_each_maps(maps_node, i, map) { seq_printf(s, "%s:\n", map->name); if (map->dev_name) seq_printf(s, " device: %s\n", @@ -919,6 +947,8 @@ static int pinctrl_maps_show(struct seq_file *s, void *what) seq_printf(s, " group: %s\n", map->group ? map->group : "(default)"); } + mutex_unlock(&pinctrl_maps_mutex); + return 0; } -- cgit v0.10.2 From 03665e0f248d6b7542f72cd7c4ec521109f283c7 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Sun, 19 Feb 2012 23:45:45 -0700 Subject: pinctrl: Re-order pinmux.[ch] to match each-other Modify the two files so that the order of function prototypes in the header matches the order of implementations in the .c file. Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 5a09cd2..ea31c46 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -40,6 +40,34 @@ struct pinmux_group { unsigned group_selector; }; +int pinmux_check_ops(struct pinctrl_dev *pctldev) +{ + const struct pinmux_ops *ops = pctldev->desc->pmxops; + unsigned selector = 0; + + /* Check that we implement required operations */ + if (!ops->list_functions || + !ops->get_function_name || + !ops->get_function_groups || + !ops->enable || + !ops->disable) + return -EINVAL; + + /* Check that all functions registered have names */ + while (ops->list_functions(pctldev, selector) >= 0) { + const char *fname = ops->get_function_name(pctldev, + selector); + if (!fname) { + pr_err("pinmux ops has no name for function%u\n", + selector); + return -EINVAL; + } + selector++; + } + + return 0; +} + /** * pin_request() - request a single pin to be muxed in, typically for GPIO * @pin: the pin number in the global pin space @@ -561,34 +589,6 @@ void pinmux_disable(struct pinctrl *p) } } -int pinmux_check_ops(struct pinctrl_dev *pctldev) -{ - const struct pinmux_ops *ops = pctldev->desc->pmxops; - unsigned selector = 0; - - /* Check that we implement required operations */ - if (!ops->list_functions || - !ops->get_function_name || - !ops->get_function_groups || - !ops->enable || - !ops->disable) - return -EINVAL; - - /* Check that all functions registered have names */ - while (ops->list_functions(pctldev, selector) >= 0) { - const char *fname = ops->get_function_name(pctldev, - selector); - if (!fname) { - pr_err("pinmux ops has no name for function%u\n", - selector); - return -EINVAL; - } - selector++; - } - - return 0; -} - #ifdef CONFIG_DEBUG_FS /* Called from pincontrol core */ diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h index 7680a17..84b8fe9 100644 --- a/drivers/pinctrl/pinmux.h +++ b/drivers/pinctrl/pinmux.h @@ -13,8 +13,6 @@ #ifdef CONFIG_PINMUX int pinmux_check_ops(struct pinctrl_dev *pctldev); -void pinmux_init_device_debugfs(struct dentry *devroot, - struct pinctrl_dev *pctldev); int pinmux_request_gpio(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned pin, unsigned gpio); @@ -36,6 +34,8 @@ int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, void pinmux_put(struct pinctrl *p); int pinmux_enable(struct pinctrl *p); void pinmux_disable(struct pinctrl *p); +void pinmux_init_device_debugfs(struct dentry *devroot, + struct pinctrl_dev *pctldev); void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p); #else @@ -45,11 +45,6 @@ static inline int pinmux_check_ops(struct pinctrl_dev *pctldev) return 0; } -static inline void pinmux_init_device_debugfs(struct dentry *devroot, - struct pinctrl_dev *pctldev) -{ -} - static inline int pinmux_request_gpio(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned pin, unsigned gpio) @@ -95,7 +90,12 @@ static inline void pinmux_disable(struct pinctrl *p) { } -void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p) +static inline void pinmux_init_device_debugfs(struct dentry *devroot, + struct pinctrl_dev *pctldev) +{ +} + +static inline void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p) { } -- cgit v0.10.2 From 2b694250174980382bddcb00e1de7654ecdf6f1f Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Sun, 19 Feb 2012 23:45:46 -0700 Subject: pinctrl: Re-order pinconf.[ch] to match each-other Modify the two files so that the order of function prototypes in the header matches the order of implementations in the .c file. Don't prototype a couple of internal functions. Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index b74f64a..0c9d08d 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -23,7 +23,20 @@ #include "core.h" #include "pinconf.h" -int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, +int pinconf_check_ops(struct pinctrl_dev *pctldev) +{ + const struct pinconf_ops *ops = pctldev->desc->confops; + + /* We must be able to read out pin status */ + if (!ops->pin_config_get && !ops->pin_config_group_get) + return -EINVAL; + /* We have to be able to config the pins in SOME way */ + if (!ops->pin_config_set && !ops->pin_config_group_set) + return -EINVAL; + return 0; +} + +static int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, unsigned long *config) { const struct pinconf_ops *ops = pctldev->desc->confops; @@ -63,7 +76,7 @@ int pin_config_get(const char *dev_name, const char *name, } 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; @@ -138,7 +151,6 @@ int pin_config_group_get(const char *dev_name, const char *pin_group, } EXPORT_SYMBOL(pin_config_group_get); - int pin_config_group_set(const char *dev_name, const char *pin_group, unsigned long config) { @@ -205,19 +217,6 @@ int pin_config_group_set(const char *dev_name, const char *pin_group, } 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 static void pinconf_dump_pin(struct pinctrl_dev *pctldev, diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h index 006b77f..1d6ea9d 100644 --- a/drivers/pinctrl/pinconf.h +++ b/drivers/pinctrl/pinconf.h @@ -14,12 +14,9 @@ #ifdef CONFIG_PINCONF int pinconf_check_ops(struct pinctrl_dev *pctldev); + void pinconf_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev); -int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, - unsigned long *config); -int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin, - unsigned long config); #else -- cgit v0.10.2 From 4ecce45dd663f6945bed7e2e06c05b5d90f3a2a1 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Sun, 19 Feb 2012 23:45:47 -0700 Subject: pinctrl: core.c/h cleanups * Make all functions internal to core.c static. Remove any of these from core.h. * Add any missing EXPORT_SYMBOL_GPL(). Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 50bcc51..b6e3c35 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -293,9 +293,9 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio) * the GPIO subsystem, return the device and the matching GPIO range. Returns * negative if the GPIO range could not be found in any device. */ -int pinctrl_get_device_gpio_range(unsigned gpio, - struct pinctrl_dev **outdev, - struct pinctrl_gpio_range **outrange) +static int pinctrl_get_device_gpio_range(unsigned gpio, + struct pinctrl_dev **outdev, + struct pinctrl_gpio_range **outrange) { struct pinctrl_dev *pctldev = NULL; @@ -332,6 +332,7 @@ void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev, list_add_tail(&range->node, &pctldev->gpio_ranges); mutex_unlock(&pctldev->gpio_ranges_lock); } +EXPORT_SYMBOL_GPL(pinctrl_add_gpio_range); /** * pinctrl_remove_gpio_range() - remove a range of GPIOs fro a pin controller @@ -345,6 +346,7 @@ void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, list_del(&range->node); mutex_unlock(&pctldev->gpio_ranges_lock); } +EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range); /** * pinctrl_get_group_selector() - returns the group selector for a group @@ -785,7 +787,7 @@ static int pinctrl_hog_map(struct pinctrl_dev *pctldev, * map entries that need to be hogged, i.e. get+enabled until the system shuts * down. */ -int pinctrl_hog_maps(struct pinctrl_dev *pctldev) +static int pinctrl_hog_maps(struct pinctrl_dev *pctldev) { struct device *dev = pctldev->dev; const char *devname = dev_name(dev); @@ -819,7 +821,7 @@ int pinctrl_hog_maps(struct pinctrl_dev *pctldev) * pinctrl_unhog_maps() - unhog specific map entries on controller device * @pctldev: the pin control device to unhog entries on */ -void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) +static void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) { struct list_head *node, *tmp; diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index a50cdb0..7c30567 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -101,8 +101,5 @@ struct pin_desc { struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name); struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin); int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name); -int 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); -- cgit v0.10.2 From 128a06d4bb997d90158e668173a6944d376c84cb Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 21 Feb 2012 14:31:45 +0100 Subject: pinctrl: spawn U300 pinctrl from the COH901 GPIO This solves the riddle on how the U300 pin controller shall be able to reference the struct gpio_chip even though these are two separate drivers: spawn the pinctrl child from the GPIO driver and pass in the struct gpio_chip as platform data. In the process we rename the U300 "pinmux-u300" to "pinctrl-u300" so as not to confuse. Signed-off-by: Linus Walleij diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index bb1034f..030b2c0 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -1477,7 +1477,7 @@ static struct coh901318_platform coh901318_platform = { .max_channels = U300_DMA_CHANNELS, }; -static struct resource pinmux_resources[] = { +static struct resource pinctrl_resources[] = { { .start = U300_SYSCON_BASE, .end = U300_SYSCON_BASE + SZ_4K - 1, @@ -1506,6 +1506,13 @@ static struct platform_device i2c1_device = { .resource = i2c1_resources, }; +static struct platform_device pinctrl_device = { + .name = "pinctrl-u300", + .id = -1, + .num_resources = ARRAY_SIZE(pinctrl_resources), + .resource = pinctrl_resources, +}; + /* * The different variants have a few different versions of the * GPIO block, with different number of ports. @@ -1525,6 +1532,7 @@ static struct u300_gpio_platform u300_gpio_plat = { #endif .gpio_base = 0, .gpio_irq_base = IRQ_U300_GPIO_BASE, + .pinctrl_device = &pinctrl_device, }; static struct platform_device gpio_device = { @@ -1597,23 +1605,16 @@ static struct platform_device dma_device = { }, }; -static struct platform_device pinmux_device = { - .name = "pinmux-u300", - .id = -1, - .num_resources = ARRAY_SIZE(pinmux_resources), - .resource = pinmux_resources, -}; - /* Pinmux settings */ static struct pinctrl_map __initdata u300_pinmux_map[] = { /* anonymous maps for chip power and EMIFs */ - PIN_MAP_SYS_HOG("POWER", "pinmux-u300", "power"), - PIN_MAP_SYS_HOG("EMIF0", "pinmux-u300", "emif0"), - PIN_MAP_SYS_HOG("EMIF1", "pinmux-u300", "emif1"), + PIN_MAP_SYS_HOG("POWER", "pinctrl-u300", "power"), + PIN_MAP_SYS_HOG("EMIF0", "pinctrl-u300", "emif0"), + PIN_MAP_SYS_HOG("EMIF1", "pinctrl-u300", "emif1"), /* per-device maps for MMC/SD, SPI and UART */ - PIN_MAP("MMCSD", "pinmux-u300", "mmc0", "mmci"), - PIN_MAP("SPI", "pinmux-u300", "spi0", "pl022"), - PIN_MAP("UART0", "pinmux-u300", "uart0", "uart0"), + PIN_MAP("MMCSD", "pinctrl-u300", "mmc0", "mmci"), + PIN_MAP("SPI", "pinctrl-u300", "spi0", "pl022"), + PIN_MAP("UART0", "pinctrl-u300", "uart0", "uart0"), }; struct u300_mux_hog { @@ -1676,7 +1677,6 @@ static struct platform_device *platform_devs[] __initdata = { &gpio_device, &nand_device, &wdog_device, - &pinmux_device, }; /* diff --git a/arch/arm/mach-u300/include/mach/gpio-u300.h b/arch/arm/mach-u300/include/mach/gpio-u300.h index bf4c793..e81400c 100644 --- a/arch/arm/mach-u300/include/mach/gpio-u300.h +++ b/arch/arm/mach-u300/include/mach/gpio-u300.h @@ -24,12 +24,14 @@ enum u300_gpio_variant { * @ports: number of GPIO block ports * @gpio_base: first GPIO number for this block (use a free range) * @gpio_irq_base: first GPIO IRQ number for this block (use a free range) + * @pinctrl_device: pin control device to spawn as child */ struct u300_gpio_platform { enum u300_gpio_variant variant; u8 ports; int gpio_base; int gpio_irq_base; + struct platform_device *pinctrl_device; }; #endif /* __MACH_U300_GPIO_U300_H */ diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index eba232a..b90c011 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -705,7 +705,6 @@ static inline void u300_gpio_free_ports(struct u300_gpio *gpio) list_for_each_safe(p, n, &gpio->port_list) { port = list_entry(p, struct u300_gpio_port, node); list_del(&port->node); - free_irq(port->irq, port); kfree(port); } } @@ -861,10 +860,18 @@ static int __init u300_gpio_probe(struct platform_device *pdev) goto err_no_chip; } + /* Spawn pin controller device as child of the GPIO, pass gpio chip */ + plat->pinctrl_device->dev.platform_data = &gpio->chip; + err = platform_device_register(plat->pinctrl_device); + if (err) + goto err_no_pinctrl; + platform_set_drvdata(pdev, gpio); return 0; +err_no_pinctrl: + err = gpiochip_remove(&gpio->chip); err_no_chip: err_no_port: u300_gpio_free_ports(gpio); @@ -919,7 +926,6 @@ static struct platform_driver u300_gpio_driver = { .remove = __exit_p(u300_gpio_remove), }; - static int __init u300_gpio_init(void) { return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe); diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index c8d02f1..fc4a281 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c @@ -162,7 +162,7 @@ #define U300_SYSCON_PMC4R_APP_MISC_16_APP_UART1_CTS 0x0100 #define U300_SYSCON_PMC4R_APP_MISC_16_EMIF_1_STATIC_CS5_N 0x0200 -#define DRIVER_NAME "pinmux-u300" +#define DRIVER_NAME "pinctrl-u300" /* * The DB3350 has 467 pads, I have enumerated the pads clockwise around the @@ -1053,13 +1053,16 @@ static struct pinctrl_desc u300_pmx_desc = { .owner = THIS_MODULE, }; -static int __init u300_pmx_probe(struct platform_device *pdev) +static int __devinit u300_pmx_probe(struct platform_device *pdev) { struct u300_pmx *upmx; struct resource *res; + struct gpio_chip *gpio_chip = dev_get_platdata(&pdev->dev); int ret; int i; + pr_err("U300 PMX PROBE\n"); + /* Create state holders etc for this driver */ upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL); if (!upmx) @@ -1095,12 +1098,14 @@ static int __init u300_pmx_probe(struct platform_device *pdev) } /* We will handle a range of GPIO pins */ - for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) + for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) { + u300_gpio_ranges[i].gc = gpio_chip; pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]); + } platform_set_drvdata(pdev, upmx); - dev_info(&pdev->dev, "initialized U300 pinmux driver\n"); + dev_info(&pdev->dev, "initialized U300 pin control driver\n"); return 0; @@ -1115,7 +1120,7 @@ out_no_resource: return ret; } -static int __exit u300_pmx_remove(struct platform_device *pdev) +static int __devexit u300_pmx_remove(struct platform_device *pdev) { struct u300_pmx *upmx = platform_get_drvdata(pdev); int i; @@ -1136,12 +1141,13 @@ static struct platform_driver u300_pmx_driver = { .name = DRIVER_NAME, .owner = THIS_MODULE, }, - .remove = __exit_p(u300_pmx_remove), + .probe = u300_pmx_probe, + .remove = __devexit_p(u300_pmx_remove), }; static int __init u300_pmx_init(void) { - return platform_driver_probe(&u300_pmx_driver, u300_pmx_probe); + return platform_driver_register(&u300_pmx_driver); } arch_initcall(u300_pmx_init); -- cgit v0.10.2 From 9891d98c7ab5712807d87ab40f2a9acd9b317114 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Sun, 19 Feb 2012 23:45:50 -0700 Subject: pinctrl: assume map table entries can't have a NULL ctrl_dev_name field These are already disallowed. Clean up some code that doesn't assume this. Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index b6e3c35..552d8c1 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -801,8 +801,7 @@ static int pinctrl_hog_maps(struct pinctrl_dev *pctldev) mutex_lock(&pinctrl_maps_mutex); for_each_maps(maps_node, i, map) { - if (map->ctrl_dev_name && - !strcmp(map->ctrl_dev_name, devname) && + if (!strcmp(map->ctrl_dev_name, devname) && !strcmp(map->dev_name, devname)) { /* OK time to hog! */ ret = pinctrl_hog_map(pctldev, map); -- cgit v0.10.2 From f026fe3d102e9d7f0d040109353ef5a97b5ef92c Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Sun, 19 Feb 2012 23:45:51 -0700 Subject: pinctrl: downgrade pinctrl_get warning when no maps are found This may be perfectly legitimate. An IP block may get re-used across SoCs. Not all of those SoCs may need pinmux settings for the IP block, e.g. if one SoC dedicates pins to that function but another doesn't. The driver won't know this, and will always attempt to set up the pinmux. The mapping table defines whether any HW programming is actually needed. Acked-by: Shawn Guo Signed-off-by: Stephen Warren [rebased to fit the applied patch series] Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 552d8c1..e2d4abb 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -567,14 +567,16 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) } } - /* We should have atleast one map, right */ - if (!num_maps) { - pr_err("could not find any mux maps for device %s, ID %s\n", - devname ? devname : "(anonymous)", - name ? name : "(undefined)"); - kfree(p); - return ERR_PTR(-EINVAL); - } + /* + * This may be perfectly legitimate. An IP block may get re-used + * across SoCs. Not all of those SoCs may need pinmux settings for the + * IP block, e.g. if one SoC dedicates pins to that function but + * another doesn't. The driver won't know this, and will always + * attempt to set up the pinmux. The mapping table defines whether any + * HW programming is actually needed. + */ + if (!num_maps) + dev_info(dev, "zero maps found for mapping %s\n", name); pr_debug("found %u mux maps for device %s, UD %s\n", num_maps, -- cgit v0.10.2 From b1eed4ece7064c361d6e03f6706d90e4e9dd7e96 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Sun, 19 Feb 2012 23:45:53 -0700 Subject: pinctrl: error if mapping table's control dev can't be found This is a serious error, and the pin control system will not function correctly if it ends up not programing the mapping table entries into the HW. Instead of just ignoring this, error out. Signed-off-by: Stephen Warren [rebased to fit the applied patch series, cast error to pointer] Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index e2d4abb..fb3fbb7 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -518,13 +518,12 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) */ pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); if (!pctldev) { - pr_warning("could not find a pinctrl device for pinmux function %s, fishy, they shall all have one\n", - map->function); - pr_warning("given pinctrl device name: %s", - map->ctrl_dev_name); - - /* Continue to check the other mappings anyway... */ - continue; + dev_err(dev, "unknown pinctrl device %s in map entry", + map->ctrl_dev_name); + pinmux_put(p); + kfree(p); + /* Eventually, this should trigger deferred probe */ + return ERR_PTR(-ENODEV); } pr_debug("in map, found pctldev %s to handle function %s", -- cgit v0.10.2 From 3cc70ed32cd6c5cb57de17bde615148ed7eda88f Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Sun, 19 Feb 2012 23:45:44 -0700 Subject: pinctrl: record a pin owner, not mux function, when requesting pins When pins are requested/acquired/got, some device becomes the owner of their mux setting. At this point, it isn't certain which mux function will be selected for the pin, since this may vary between each of the device's states in the pinctrl mapping table. As such, we should record the owning device, not what we think the initial mux setting will be, when requesting pins. This doesn't make a lot of difference right now since pinctrl_get gets only one single device/state combination, but this will make a difference when pinctrl_get gets all states, and pinctrl_select_state can switch between states. Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 7c30567..061c57d 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -94,7 +94,7 @@ struct pin_desc { spinlock_t lock; /* These fields only added when supporting pinmux drivers */ #ifdef CONFIG_PINMUX - const char *mux_function; + const char *owner; #endif }; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index ea31c46..2887897 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -71,21 +71,20 @@ int pinmux_check_ops(struct pinctrl_dev *pctldev) /** * pin_request() - request a single pin to be muxed in, typically for GPIO * @pin: the pin number in the global pin space - * @function: a functional name to give to this pin, passed to the driver - * so it knows what function to mux in, e.g. the string "gpioNN" - * means that you want to mux in the pin for use as GPIO number NN + * @owner: a representation of the owner of this pin; typically the device + * name that controls its mux function, or the requested GPIO name * @gpio_range: the range matching the GPIO pin if this is a request for a * single GPIO pin */ static int pin_request(struct pinctrl_dev *pctldev, - int pin, const char *function, + int pin, const char *owner, struct pinctrl_gpio_range *gpio_range) { struct pin_desc *desc; const struct pinmux_ops *ops = pctldev->desc->pmxops; int status = -EINVAL; - dev_dbg(pctldev->dev, "request pin %d for %s\n", pin, function); + dev_dbg(pctldev->dev, "request pin %d for %s\n", pin, owner); desc = pin_desc_get(pctldev, pin); if (desc == NULL) { @@ -94,19 +93,14 @@ static int pin_request(struct pinctrl_dev *pctldev, goto out; } - if (!function) { - dev_err(pctldev->dev, "no function name given\n"); - return -EINVAL; - } - spin_lock(&desc->lock); - if (desc->mux_function) { + if (desc->owner && strcmp(desc->owner, owner)) { spin_unlock(&desc->lock); dev_err(pctldev->dev, "pin already requested\n"); goto out; } - desc->mux_function = function; + desc->owner = owner; spin_unlock(&desc->lock); /* Let each pin increase references to this module */ @@ -136,13 +130,13 @@ static int pin_request(struct pinctrl_dev *pctldev, out_free_pin: if (status) { spin_lock(&desc->lock); - desc->mux_function = NULL; + desc->owner = NULL; spin_unlock(&desc->lock); } out: if (status) dev_err(pctldev->dev, "pin-%d (%s) status %d\n", - pin, function ? : "?", status); + pin, owner, status); return status; } @@ -154,8 +148,8 @@ out: * @gpio_range: the range matching the GPIO pin if this is a request for a * single GPIO pin * - * This function returns a pointer to the function name in use. This is used - * for callers that dynamically allocate a function name so it can be freed + * This function returns a pointer to the previous owner. This is used + * for callers that dynamically allocate an owner name so it can be freed * once the pin is free. This is done for GPIO request functions. */ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, @@ -163,7 +157,7 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, { const struct pinmux_ops *ops = pctldev->desc->pmxops; struct pin_desc *desc; - const char *func; + const char *owner; desc = pin_desc_get(pctldev, pin); if (desc == NULL) { @@ -182,12 +176,12 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, ops->free(pctldev, pin); spin_lock(&desc->lock); - func = desc->mux_function; - desc->mux_function = NULL; + owner = desc->owner; + desc->owner = NULL; spin_unlock(&desc->lock); module_put(pctldev->owner); - return func; + return owner; } /** @@ -201,19 +195,19 @@ int pinmux_request_gpio(struct pinctrl_dev *pctldev, unsigned pin, unsigned gpio) { char gpiostr[16]; - const char *function; + const char *owner; int ret; /* Conjure some name stating what chip and pin this is taken by */ snprintf(gpiostr, 15, "%s:%d", range->name, gpio); - function = kstrdup(gpiostr, GFP_KERNEL); - if (!function) + owner = kstrdup(gpiostr, GFP_KERNEL); + if (!owner) return -EINVAL; - ret = pin_request(pctldev, pin, function, range); + ret = pin_request(pctldev, pin, owner, range); if (ret < 0) - kfree(function); + kfree(owner); return ret; } @@ -227,10 +221,10 @@ int pinmux_request_gpio(struct pinctrl_dev *pctldev, void pinmux_free_gpio(struct pinctrl_dev *pctldev, unsigned pin, struct pinctrl_gpio_range *range) { - const char *func; + const char *owner; - func = pin_free(pctldev, pin, range); - kfree(func); + owner = pin_free(pctldev, pin, range); + kfree(owner); } /** @@ -260,17 +254,15 @@ int pinmux_gpio_direction(struct pinctrl_dev *pctldev, /** * acquire_pins() - acquire all the pins for a certain function on a pinmux * @pctldev: the device to take the pins on - * @func_selector: the function selector to acquire the pins for + * @owner: a representation of the owner of this pin; typically the device + * name that controls its mux function * @group_selector: the group selector containing the pins to acquire */ static int acquire_pins(struct pinctrl_dev *pctldev, - unsigned func_selector, + const char *owner, unsigned group_selector) { const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; - const struct pinmux_ops *pmxops = pctldev->desc->pmxops; - const char *func = pmxops->get_function_name(pctldev, - func_selector); const unsigned *pins; unsigned num_pins; int ret; @@ -286,11 +278,11 @@ static int acquire_pins(struct pinctrl_dev *pctldev, /* Try to allocate all pins in this group, one by one */ for (i = 0; i < num_pins; i++) { - ret = pin_request(pctldev, pins[i], func, NULL); + ret = pin_request(pctldev, pins[i], owner, NULL); if (ret) { dev_err(pctldev->dev, - "could not get pin %d for function %s on device %s - conflicting mux mappings?\n", - pins[i], func ? : "(undefined)", + "could not get request pin %d on device %s - conflicting mux mappings?\n", + pins[i], pinctrl_dev_get_name(pctldev)); /* On error release all taken pins */ i--; /* this pin just failed */ @@ -503,7 +495,7 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, if (!grp) return -ENOMEM; grp->group_selector = group_selector; - ret = acquire_pins(pctldev, func_selector, group_selector); + ret = acquire_pins(pctldev, devname, group_selector); if (ret) { kfree(grp); return ret; @@ -630,7 +622,7 @@ static int pinmux_pins_show(struct seq_file *s, void *what) unsigned i, pin; seq_puts(s, "Pinmux settings per pin\n"); - seq_puts(s, "Format: pin (name): pinmuxfunction\n"); + seq_puts(s, "Format: pin (name): owner\n"); /* The pin number can be retrived from the pin controller descriptor */ for (i = 0; i < pctldev->desc->npins; i++) { @@ -645,8 +637,7 @@ static int pinmux_pins_show(struct seq_file *s, void *what) seq_printf(s, "pin %d (%s): %s\n", pin, desc->name ? desc->name : "unnamed", - desc->mux_function ? desc->mux_function - : "UNCLAIMED"); + desc->owner ? desc->owner : "UNCLAIMED"); } return 0; -- cgit v0.10.2 From f7b9006f4598dd252dca5225f3cf88179c36276f Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Sun, 19 Feb 2012 23:45:58 -0700 Subject: pinctrl: fix pinconf_groups_show() to emit newline pinconf_groups_show() wrote all debug information on one line. Fix it to match pinconf_pins_show() and be legible. Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 0c9d08d..3f018a1 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -285,6 +285,8 @@ static int pinconf_groups_show(struct seq_file *s, void *what) seq_printf(s, "%u (%s):", selector, gname); pinconf_dump_group(pctldev, s, selector, gname); + seq_printf(s, "\n"); + selector++; } -- cgit v0.10.2 From 1681f5ae4ca25bddb6f7b6d4f463cc83e3d1ad01 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 22 Feb 2012 14:25:58 -0700 Subject: pinctrl: disallow map table entries with NULL dev_name field Hog entries are mapping table entries with .ctrl_dev_name == .dev_name. All other mapping table entries need .dev_name set so that they will match some pinctrl_get() call. All extant PIN_MAP*() macros set .dev_name. So, there is no reason to allow mapping table entries without .dev_name set. Update the code and documentation to disallow this. Signed-off-by: Stephen Warren Acked-by: Dong Aisheng Signed-off-by: Linus Walleij diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index ee3266b..fa9163a 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -494,14 +494,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 @@ -983,8 +979,7 @@ after this you should be able to see this in the debugfs listing of all pins. System pin control hogging ========================== -A system pin control map entry, i.e. a pin control setting that does not have -a device associated with it, can be hogged by the core when the pin controller +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() and pinctrl_enable() on it immediately after the pin control device has been registered. diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index fb3fbb7..5411e32 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -479,24 +479,21 @@ EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) { struct pinctrl_dev *pctldev = NULL; - const char *devname = NULL; + const char *devname; struct pinctrl *p; - bool found_map; unsigned num_maps = 0; int ret = -ENODEV; struct pinctrl_maps *maps_node; int i; struct pinctrl_map const *map; - /* We must have dev or ID or both */ - if (!dev && !name) + /* We must have a dev name */ + if (WARN_ON(!dev)) return ERR_PTR(-EINVAL); - if (dev) - devname = dev_name(dev); + devname = dev_name(dev); - pr_debug("get pin control handle %s for device %s\n", name, - devname ? devname : "(none)"); + pr_debug("get pin control handle device %s state %s\n", devname, name); /* * create the state cookie holder struct pinctrl for each @@ -511,8 +508,6 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) /* Iterate over the pin control maps to locate the right ones */ for_each_maps(maps_node, i, map) { - found_map = false; - /* * First, try to find the pctldev given in the map */ @@ -529,6 +524,10 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) pr_debug("in map, found pctldev %s to handle function %s", dev_name(pctldev->dev), map->function); + /* Map must be for this device */ + if (strcmp(map->dev_name, devname)) + continue; + /* * If we're looking for a specific named map, this must match, * else we loop and look for the next. @@ -540,30 +539,12 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) continue; } - /* - * This is for the case where no device name is given, we - * already know that the function name matches from above - * code. - */ - if (!map->dev_name && (name != NULL)) - found_map = true; - - /* If the mapping has a device set up it must match */ - if (map->dev_name && - (!devname || !strcmp(map->dev_name, devname))) - /* MATCH! */ - found_map = true; - - /* If this map is applicable, then apply it */ - if (found_map) { - ret = pinmux_apply_muxmap(pctldev, p, dev, - devname, map); - if (ret) { - kfree(p); - return ERR_PTR(ret); - } - num_maps++; + ret = pinmux_apply_muxmap(pctldev, p, dev, devname, map); + if (ret) { + kfree(p); + return ERR_PTR(ret); } + num_maps++; } /* @@ -578,9 +559,7 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) dev_info(dev, "zero maps found for mapping %s\n", name); pr_debug("found %u mux maps for device %s, UD %s\n", - num_maps, - devname ? devname : "(anonymous)", - name ? name : "(undefined)"); + num_maps, devname, name ? name : "(undefined)"); /* Add the pinmux to the global list */ mutex_lock(&pinctrl_list_mutex); @@ -707,14 +686,11 @@ int pinctrl_register_mappings(struct pinctrl_map const *maps, return -EINVAL; } - if (!maps[i].dev_name) - pr_debug("add system map %s function %s with no device\n", - maps[i].name, - maps[i].function); - else - pr_debug("register map %s, function %s\n", - maps[i].name, - maps[i].function); + if (!maps[i].dev_name) { + pr_err("failed to register map %s (%d): no device given\n", + maps[i].name, i); + return -EINVAL; + } } maps_node = kzalloc(sizeof(*maps_node), GFP_KERNEL); @@ -938,13 +914,8 @@ static int pinctrl_maps_show(struct seq_file *s, void *what) mutex_lock(&pinctrl_maps_mutex); for_each_maps(maps_node, i, map) { seq_printf(s, "%s:\n", map->name); - if (map->dev_name) - seq_printf(s, " device: %s\n", - map->dev_name); - else - seq_printf(s, " SYSTEM MUX\n"); - seq_printf(s, " controlling device %s\n", - map->ctrl_dev_name); + seq_printf(s, " device: %s\n", map->dev_name); + seq_printf(s, " controlling device %s\n", map->ctrl_dev_name); seq_printf(s, " function: %s\n", map->function); seq_printf(s, " group: %s\n", map->group ? map->group : "(default)"); diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index af145d5..400f192 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -46,13 +46,6 @@ struct pinctrl_map { { .name = a, .ctrl_dev_name = b, .function = c, .dev_name = d } /* - * Convenience macro to map a system function onto a certain pinctrl device. - * System functions are not assigned to a particular device. - */ -#define PIN_MAP_SYS(a, b, c) \ - { .name = a, .ctrl_dev_name = b, .function = c } - -/* * Convenience macro to map a system function onto a certain pinctrl device, * to be hogged by the pin control core until the system shuts down. */ -- cgit v0.10.2 From 95dcd4aea57f1d449305f3032240bba0a839593b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 22 Feb 2012 14:25:59 -0700 Subject: pinctrl: use dev_*() instead of pr_*(), add some msgs, minor cleanups e.g. dev_err instead of pr_err prints messages in a slightly more standardized format. Also, add a few more error messages to track down errors. Also, some small cleanups of messages. Signed-off-by: Stephen Warren Acked-by: Dong Aisheng Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 5411e32..1d59430 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -212,8 +212,10 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, } pindesc = kzalloc(sizeof(*pindesc), GFP_KERNEL); - if (pindesc == NULL) + if (pindesc == NULL) { + dev_err(pctldev->dev, "failed to alloc struct pin_desc\n"); return -ENOMEM; + } spin_lock_init(&pindesc->lock); @@ -493,7 +495,7 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) devname = dev_name(dev); - pr_debug("get pin control handle device %s state %s\n", devname, name); + dev_dbg(dev, "pinctrl_get() for device %s state %s\n", devname, name); /* * create the state cookie holder struct pinctrl for each @@ -501,8 +503,10 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) * a pin control handle with pinctrl_get() */ p = kzalloc(sizeof(struct pinctrl), GFP_KERNEL); - if (p == NULL) + if (p == NULL) { + dev_err(dev, "failed to alloc struct pinctrl\n"); return ERR_PTR(-ENOMEM); + } mutex_init(&p->mutex); pinmux_init_pinctrl_handle(p); @@ -521,8 +525,8 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) return ERR_PTR(-ENODEV); } - pr_debug("in map, found pctldev %s to handle function %s", - dev_name(pctldev->dev), map->function); + dev_dbg(dev, "in map, found pctldev %s to handle function %s", + dev_name(pctldev->dev), map->function); /* Map must be for this device */ if (strcmp(map->dev_name, devname)) @@ -558,8 +562,8 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) if (!num_maps) dev_info(dev, "zero maps found for mapping %s\n", name); - pr_debug("found %u mux maps for device %s, UD %s\n", - num_maps, devname, name ? name : "(undefined)"); + dev_dbg(dev, "found %u maps for device %s state %s\n", + num_maps, devname, name ? name : "(undefined)"); /* Add the pinmux to the global list */ mutex_lock(&pinctrl_list_mutex); @@ -670,7 +674,7 @@ int pinctrl_register_mappings(struct pinctrl_map const *maps, for (i = 0; i < num_maps; i++) { if (!maps[i].name) { pr_err("failed to register map %d: no map name given\n", - i); + i); return -EINVAL; } @@ -682,13 +686,13 @@ int pinctrl_register_mappings(struct pinctrl_map const *maps, if (!maps[i].function) { pr_err("failed to register map %s (%d): no function ID given\n", - maps[i].name, i); + maps[i].name, i); return -EINVAL; } if (!maps[i].dev_name) { pr_err("failed to register map %s (%d): no device given\n", - maps[i].name, i); + maps[i].name, i); return -EINVAL; } } @@ -702,6 +706,7 @@ int pinctrl_register_mappings(struct pinctrl_map const *maps, maps_node->num_maps = num_maps; maps_node->maps = kmemdup(maps, sizeof(*maps) * num_maps, GFP_KERNEL); if (!maps_node->maps) { + pr_err("failed to duplicate mapping table\n"); kfree(maps_node); return -ENOMEM; } @@ -722,8 +727,10 @@ static int pinctrl_hog_map(struct pinctrl_dev *pctldev, int ret; hog = kzalloc(sizeof(struct pinctrl_hog), GFP_KERNEL); - if (!hog) + if (!hog) { + dev_err(pctldev->dev, "failed to alloc struct pinctrl_hog\n"); return -ENOMEM; + } p = pinctrl_get_locked(pctldev->dev, map->name); if (IS_ERR(p)) { @@ -1154,8 +1161,10 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, return NULL; pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL); - if (pctldev == NULL) + if (pctldev == NULL) { + dev_err(dev, "failed to alloc struct pinctrl_dev\n"); return NULL; + } /* Initialize pin control device struct */ pctldev->owner = pctldesc->owner; -- cgit v0.10.2 From 02f5b98951c631a3c4b3cc398dd2b14d274a6155 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 22 Feb 2012 14:26:00 -0700 Subject: pinctrl: allocate sizeof(*p) instead of sizeof(struct foo) This hopefully makes it harder to take the sizeof the wrong type. Signed-off-by: Stephen Warren Acked-by: Dong Aisheng Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 1d59430..2cc8f72 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -502,7 +502,7 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) * mapping, this is what consumers will get when requesting * a pin control handle with pinctrl_get() */ - p = kzalloc(sizeof(struct pinctrl), GFP_KERNEL); + p = kzalloc(sizeof(*p), GFP_KERNEL); if (p == NULL) { dev_err(dev, "failed to alloc struct pinctrl\n"); return ERR_PTR(-ENOMEM); @@ -726,7 +726,7 @@ static int pinctrl_hog_map(struct pinctrl_dev *pctldev, struct pinctrl *p; int ret; - hog = kzalloc(sizeof(struct pinctrl_hog), GFP_KERNEL); + hog = kzalloc(sizeof(*hog), GFP_KERNEL); if (!hog) { dev_err(pctldev->dev, "failed to alloc struct pinctrl_hog\n"); return -ENOMEM; @@ -1160,7 +1160,7 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, if (pctldesc->name == NULL) return NULL; - pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL); + pctldev = kzalloc(sizeof(*pctldev), GFP_KERNEL); if (pctldev == NULL) { dev_err(dev, "failed to alloc struct pinctrl_dev\n"); return NULL; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 2887897..98b89d6 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -491,7 +491,7 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, p->func_selector = func_selector; /* Now add this group selector, we may have many of them */ - grp = kmalloc(sizeof(struct pinmux_group), GFP_KERNEL); + grp = kmalloc(sizeof(*grp), GFP_KERNEL); if (!grp) return -ENOMEM; grp->group_selector = group_selector; -- cgit v0.10.2 From 2304b4737f492b6ee9b714d8129e153af0bef989 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 22 Feb 2012 14:26:01 -0700 Subject: pinctrl: remove pin and hogs locks from struct pinctrl_dev struct pinctrl_dev's pin_desc_tree_lock and pinctrl_hogs_lock aren't useful; the data they protect is read-only except when registering or unregistering a pinctrl_dev, and at those times, it doesn't make sense to protect one part of the structure independently from the rest. Move pinctrl_init_device_debugfs() to the end of pinctrl_register() so that debugfs can't access the struct pinctrl_dev until it's fully initialized, i.e. after the hogs are set up. Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 2cc8f72..633b97e 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -115,18 +115,6 @@ struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname) return found ? pctldev : NULL; } -struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin) -{ - struct pin_desc *pindesc; - unsigned long flags; - - spin_lock_irqsave(&pctldev->pin_desc_tree_lock, flags); - pindesc = radix_tree_lookup(&pctldev->pin_desc_tree, pin); - spin_unlock_irqrestore(&pctldev->pin_desc_tree_lock, flags); - - return pindesc; -} - /** * pin_get_from_name() - look up a pin number from a name * @pctldev: the pin control device to lookup the pin on @@ -182,7 +170,6 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev, { int i; - spin_lock(&pctldev->pin_desc_tree_lock); for (i = 0; i < num_pins; i++) { struct pin_desc *pindesc; @@ -196,7 +183,6 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev, } kfree(pindesc); } - spin_unlock(&pctldev->pin_desc_tree_lock); } static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, @@ -232,9 +218,7 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, pindesc->dynamic_name = true; } - spin_lock(&pctldev->pin_desc_tree_lock); radix_tree_insert(&pctldev->pin_desc_tree, number, pindesc); - spin_unlock(&pctldev->pin_desc_tree_lock); pr_debug("registered pin %d (%s) on %s\n", number, pindesc->name, pctldev->desc->name); return 0; @@ -756,9 +740,7 @@ static int pinctrl_hog_map(struct pinctrl_dev *pctldev, dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name, map->function); - mutex_lock(&pctldev->pinctrl_hogs_lock); list_add_tail(&hog->node, &pctldev->pinctrl_hogs); - mutex_unlock(&pctldev->pinctrl_hogs_lock); return 0; } @@ -781,7 +763,6 @@ static int pinctrl_hog_maps(struct pinctrl_dev *pctldev) struct pinctrl_map const *map; INIT_LIST_HEAD(&pctldev->pinctrl_hogs); - mutex_init(&pctldev->pinctrl_hogs_lock); mutex_lock(&pinctrl_maps_mutex); for_each_maps(maps_node, i, map) { @@ -808,7 +789,6 @@ static void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) { struct list_head *node, *tmp; - mutex_lock(&pctldev->pinctrl_hogs_lock); list_for_each_safe(node, tmp, &pctldev->pinctrl_hogs) { struct pinctrl_hog *hog = list_entry(node, struct pinctrl_hog, node); @@ -817,7 +797,6 @@ static void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) list_del(node); kfree(hog); } - mutex_unlock(&pctldev->pinctrl_hogs_lock); } #ifdef CONFIG_DEBUG_FS @@ -1171,7 +1150,6 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, pctldev->desc = pctldesc; pctldev->driver_data = driver_data; INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL); - spin_lock_init(&pctldev->pin_desc_tree_lock); INIT_LIST_HEAD(&pctldev->gpio_ranges); mutex_init(&pctldev->gpio_ranges_lock); pctldev->dev = dev; @@ -1207,11 +1185,12 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, goto out_err; } - pinctrl_init_device_debugfs(pctldev); mutex_lock(&pinctrldev_list_mutex); list_add_tail(&pctldev->node, &pinctrldev_list); mutex_unlock(&pinctrldev_list_mutex); pinctrl_hog_maps(pctldev); + pinctrl_init_device_debugfs(pctldev); + return pctldev; out_err: diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 061c57d..7551611 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -20,7 +20,6 @@ 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 @@ -28,7 +27,6 @@ struct pinctrl_gpio_range; * @owner: module providing the pin controller, used for refcounting * @driver_data: driver data for drivers registering to the pin controller * subsystem - * @pinctrl_hogs_lock: lock for the pin control hog list * @pinctrl_hogs: list of pin control maps hogged by this device * @device_root: debugfs root for this device */ @@ -36,13 +34,11 @@ 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 mutex pinctrl_hogs_lock; struct list_head pinctrl_hogs; #ifdef CONFIG_DEBUG_FS struct dentry *device_root; @@ -99,7 +95,12 @@ struct pin_desc { }; struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *dev_name); -struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin); int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name); int 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); +} -- cgit v0.10.2 From 1cf94c45ca31c0ad563e72b095782346cba26b6c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 24 Feb 2012 06:53:04 +0100 Subject: pinctrl: make the pinmux-pins more helpful The debugfs file pinmux-pins used to tell which function was enabled but now states simply which device owns the pin. Being owned by the pinctrl driver itself means just that it's hogged so be a bit more helpful by printing that. ChangeLog v1->v2: - Preserve the self-referential owner field, just clarify that when the pin controller states itself as owner this means that it's hogged. Acked-by: Dong Aisheng Acked-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 98b89d6..2a40561 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -626,8 +626,8 @@ static int pinmux_pins_show(struct seq_file *s, void *what) /* The pin number can be retrived from the pin controller descriptor */ for (i = 0; i < pctldev->desc->npins; i++) { - struct pin_desc *desc; + bool is_hog = false; pin = pctldev->desc->pins[i].number; desc = pin_desc_get(pctldev, pin); @@ -635,9 +635,14 @@ static int pinmux_pins_show(struct seq_file *s, void *what) if (desc == NULL) continue; - seq_printf(s, "pin %d (%s): %s\n", pin, + if (desc->owner && + !strcmp(desc->owner, pinctrl_dev_get_name(pctldev))) + is_hog = true; + + seq_printf(s, "pin %d (%s): %s%s\n", pin, desc->name ? desc->name : "unnamed", - desc->owner ? desc->owner : "UNCLAIMED"); + desc->owner ? desc->owner : "UNCLAIMED", + is_hog ? " (HOG)" : ""); } return 0; -- cgit v0.10.2 From 806d314325812fb8ffe7059bd84a23d334350c21 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 23 Feb 2012 17:04:39 -0700 Subject: pinctrl: re-order struct pinctrl_map The lookup key in struct pinctrl_map is (.dev_name, .name). Re-order the struct definition to put the lookup key fields first, and the result values afterwards. To me at least, this slightly better reflects the lookup process. Update the documentation in a similar fashion. Note: PIN_MAP*() macros aren't updated; I plan to update this once later when enhancing the mapping table format to support pin config to reduce churn. Signed-off-by: Stephen Warren Acked-by: Dong Aisheng [Rebased for cherry-picking] Signed-off-by: Linus Walleij diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index fa9163a..5e314ce 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -781,19 +781,19 @@ spi on the second function mapping: static const struct pinctrl_map __initdata mapping[] = { { + .dev_name = "foo-spi.0", .ctrl_dev_name = "pinctrl-foo", .function = "spi0", - .dev_name = "foo-spi.0", }, { + .dev_name = "foo-i2c.0", .ctrl_dev_name = "pinctrl-foo", .function = "i2c0", - .dev_name = "foo-i2c.0", }, { + .dev_name = "foo-mmc.0", .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", - .dev_name = "foo-mmc.0", }, }; @@ -826,18 +826,18 @@ As it is possible to map a function to different groups of pins an optional ... { + .dev_name = "foo-spi.0", .name = "spi0-pos-A", .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", .ctrl_dev_name = "pinctrl-foo", .function = "spi0", .group = "spi0_1_grp", - .dev_name = "foo-spi.0", }, ... @@ -852,45 +852,45 @@ case), we define a mapping like this: ... { + .dev_name = "foo-mmc.0", .name = "2bit" .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_1_grp", - .dev_name = "foo-mmc.0", }, { + .dev_name = "foo-mmc.0", .name = "4bit" .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_1_grp", - .dev_name = "foo-mmc.0", }, { + .dev_name = "foo-mmc.0", .name = "4bit" .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_2_grp", - .dev_name = "foo-mmc.0", }, { + .dev_name = "foo-mmc.0", .name = "8bit" .ctrl_dev_name = "pinctrl-foo", .group = "mmc0_1_grp", - .dev_name = "foo-mmc.0", }, { + .dev_name = "foo-mmc.0", .name = "8bit" .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_2_grp", - .dev_name = "foo-mmc.0", }, { + .dev_name = "foo-mmc.0", .name = "8bit" .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_3_grp", - .dev_name = "foo-mmc.0", }, ... @@ -988,10 +988,10 @@ This is enabled by simply setting the .dev_name field in the map to the name of the pin controller itself, like this: { + .dev_name = "pinctrl-foo", .name = "POWERMAP" .ctrl_dev_name = "pinctrl-foo", .function = "power_func", - .dev_name = "pinctrl-foo", }, Since it may be common to request the core to hog a few always-applicable diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index 400f192..73fbb27 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -14,6 +14,10 @@ /** * struct pinctrl_map - boards/machines shall provide this map for devices + * @dev_name: the name of the device using this specific mapping, the name + * must be the same as in your struct device*. If this name is set to the + * same name as the pin controllers own dev_name(), the map entry will be + * hogged by the driver itself upon registration * @name: the name of this specific map entry for the particular machine. * This is the second parameter passed to pinmux_get() when you want * to have several mappings to the same device @@ -25,17 +29,13 @@ * @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_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 */ struct pinctrl_map { + const char *dev_name; const char *name; const char *ctrl_dev_name; const char *function; const char *group; - const char *dev_name; }; /* -- cgit v0.10.2 From 3eedb4372354a70ce63c9f4ec294d2eba0d79d17 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 23 Feb 2012 17:04:40 -0700 Subject: pinctrl: move pinctrl-maps debugfs file to top-level The debugfs file pinctrl-maps is a system-wide file, not specific to any pin controller, so place it in the top-level directory. Also, move the code implementing the file to keep the order of all the functions matching the order they're created in pinctrl_init_*debugfs(). The only non-obvious change here is no private data is passed to debugfs_create_file() or single_open(). Signed-off-by: Stephen Warren Acked-by: Dong Aisheng Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 633b97e..376cede 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -889,28 +889,6 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) return 0; } -static int pinctrl_maps_show(struct seq_file *s, void *what) -{ - struct pinctrl_maps *maps_node; - int i; - struct pinctrl_map const *map; - - seq_puts(s, "Pinctrl maps:\n"); - - mutex_lock(&pinctrl_maps_mutex); - for_each_maps(maps_node, i, map) { - seq_printf(s, "%s:\n", map->name); - seq_printf(s, " device: %s\n", map->dev_name); - seq_printf(s, " controlling device %s\n", map->ctrl_dev_name); - seq_printf(s, " function: %s\n", map->function); - seq_printf(s, " group: %s\n", map->group ? map->group : - "(default)"); - } - mutex_unlock(&pinctrl_maps_mutex); - - return 0; -} - static int pinmux_hogs_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev = s->private; @@ -947,6 +925,28 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) return 0; } +static int pinctrl_maps_show(struct seq_file *s, void *what) +{ + struct pinctrl_maps *maps_node; + int i; + struct pinctrl_map const *map; + + seq_puts(s, "Pinctrl maps:\n"); + + mutex_lock(&pinctrl_maps_mutex); + for_each_maps(maps_node, i, map) { + seq_printf(s, "%s:\n", map->name); + seq_printf(s, " device: %s\n", map->dev_name); + seq_printf(s, " controlling device %s\n", map->ctrl_dev_name); + seq_printf(s, " function: %s\n", map->function); + seq_printf(s, " group: %s\n", map->group ? map->group : + "(default)"); + } + mutex_unlock(&pinctrl_maps_mutex); + + return 0; +} + static int pinctrl_show(struct seq_file *s, void *what) { struct pinctrl *p; @@ -988,11 +988,6 @@ static int pinctrl_gpioranges_open(struct inode *inode, struct file *file) return single_open(file, pinctrl_gpioranges_show, inode->i_private); } -static int pinctrl_maps_open(struct inode *inode, struct file *file) -{ - return single_open(file, pinctrl_maps_show, inode->i_private); -} - static int pinmux_hogs_open(struct inode *inode, struct file *file) { return single_open(file, pinmux_hogs_show, inode->i_private); @@ -1003,6 +998,11 @@ static int pinctrl_devices_open(struct inode *inode, struct file *file) return single_open(file, pinctrl_devices_show, NULL); } +static int pinctrl_maps_open(struct inode *inode, struct file *file) +{ + return single_open(file, pinctrl_maps_show, NULL); +} + static int pinctrl_open(struct inode *inode, struct file *file) { return single_open(file, pinctrl_show, NULL); @@ -1029,22 +1029,22 @@ static const struct file_operations pinctrl_gpioranges_ops = { .release = single_release, }; -static const struct file_operations pinctrl_maps_ops = { - .open = pinctrl_maps_open, +static const struct file_operations pinmux_hogs_ops = { + .open = pinmux_hogs_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; -static const struct file_operations pinmux_hogs_ops = { - .open = pinmux_hogs_open, +static const struct file_operations pinctrl_devices_ops = { + .open = pinctrl_devices_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, }; -static const struct file_operations pinctrl_devices_ops = { - .open = pinctrl_devices_open, +static const struct file_operations pinctrl_maps_ops = { + .open = pinctrl_maps_open, .read = seq_read, .llseek = seq_lseek, .release = single_release, @@ -1078,8 +1078,6 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) device_root, pctldev, &pinctrl_groups_ops); debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO, device_root, pctldev, &pinctrl_gpioranges_ops); - debugfs_create_file("pinctrl-maps", S_IFREG | S_IRUGO, - device_root, pctldev, &pinctrl_maps_ops); debugfs_create_file("pinmux-hogs", S_IFREG | S_IRUGO, device_root, pctldev, &pinmux_hogs_ops); pinmux_init_device_debugfs(device_root, pctldev); @@ -1102,6 +1100,8 @@ static void pinctrl_init_debugfs(void) debugfs_create_file("pinctrl-devices", S_IFREG | S_IRUGO, debugfs_root, NULL, &pinctrl_devices_ops); + debugfs_create_file("pinctrl-maps", S_IFREG | S_IRUGO, + debugfs_root, NULL, &pinctrl_maps_ops); debugfs_create_file("pinctrl-handles", S_IFREG | S_IRUGO, debugfs_root, NULL, &pinctrl_ops); } -- cgit v0.10.2 From d4e3198736d9d64e4ba4d2b46ab75cbcf5d0a4e0 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 1 Mar 2012 18:48:31 -0700 Subject: pinctrl: enhance pinctrl_get() to handle multiple functions At present, pinctrl_get() assumes that all matching mapping table entries have the same "function" value, albeit potentially applied to different pins/groups. This change removes this restriction; pinctrl_get() can now handle a set of mapping tables where different functions are applied to the various pins/groups. Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 7551611..8164e7b 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -53,8 +53,6 @@ struct pinctrl_dev { * to keep track of nested use cases * @pctldev: pin control device handling this pin control handle * @mutex: a lock for the pin control state holder - * @func_selector: the function selector for the pinmux device handling - * this pinmux * @groups: the group selectors for the pinmux device and * selector combination handling this pinmux, this is a list that * will be traversed on all pinmux operations such as @@ -67,7 +65,6 @@ struct pinctrl { struct pinctrl_dev *pctldev; struct mutex mutex; #ifdef CONFIG_PINMUX - unsigned func_selector; struct list_head groups; #endif }; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 2a40561..f409f16 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -33,10 +33,13 @@ /** * struct pinmux_group - group list item for pinmux groups * @node: pinmux group list node + * @func_selector: the function selector for the pinmux device handling + * this pinmux * @group_selector: the group selector for this group */ struct pinmux_group { struct list_head node; + unsigned func_selector; unsigned group_selector; }; @@ -476,24 +479,11 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, if (ret < 0) return ret; - /* - * If the function selector is already set, it needs to be identical, - * we support several groups with one function but not several - * functions with one or several groups in the same pinmux. - */ - if (p->func_selector != UINT_MAX && - p->func_selector != func_selector) { - dev_err(pctldev->dev, - "dual function defines in the map for device %s\n", - devname); - return -EINVAL; - } - p->func_selector = func_selector; - /* Now add this group selector, we may have many of them */ grp = kmalloc(sizeof(*grp), GFP_KERNEL); if (!grp) return -ENOMEM; + grp->func_selector = func_selector; grp->group_selector = group_selector; ret = acquire_pins(pctldev, devname, group_selector); if (ret) { @@ -554,7 +544,7 @@ int pinmux_enable(struct pinctrl *p) int ret; list_for_each_entry(grp, &p->groups, node) { - ret = ops->enable(pctldev, p->func_selector, + ret = ops->enable(pctldev, grp->func_selector, grp->group_selector); if (ret) /* @@ -576,7 +566,7 @@ void pinmux_disable(struct pinctrl *p) struct pinmux_group *grp; list_for_each_entry(grp, &p->groups, node) { - ops->disable(pctldev, p->func_selector, + ops->disable(pctldev, grp->func_selector, grp->group_selector); } } @@ -654,21 +644,22 @@ void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p) const struct pinmux_ops *pmxops; const struct pinctrl_ops *pctlops; struct pinmux_group *grp; + const char *sep = ""; pmxops = pctldev->desc->pmxops; pctlops = pctldev->desc->pctlops; - seq_printf(s, " function: %s (%u),", - pmxops->get_function_name(pctldev, - p->func_selector), - p->func_selector); - seq_printf(s, " groups: ["); list_for_each_entry(grp, &p->groups, node) { - seq_printf(s, " %s (%u)", + seq_printf(s, "%s%s (%u)=%s (%u)", + sep, pctlops->get_group_name(pctldev, grp->group_selector), - grp->group_selector); + grp->group_selector, + pmxops->get_function_name(pctldev, + grp->func_selector), + grp->func_selector); + sep = ", "; } seq_printf(s, " ]"); } diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h index 84b8fe9..822febb 100644 --- a/drivers/pinctrl/pinmux.h +++ b/drivers/pinctrl/pinmux.h @@ -23,7 +23,6 @@ int pinmux_gpio_direction(struct pinctrl_dev *pctldev, unsigned pin, bool input); static inline void pinmux_init_pinctrl_handle(struct pinctrl *p) { - p->func_selector = UINT_MAX; INIT_LIST_HEAD(&p->groups); } int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, -- cgit v0.10.2 From 46919ae63d4820e76724beb655274ce143f0da0b Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 1 Mar 2012 18:48:32 -0700 Subject: pinctrl: introduce PINCTRL_STATE_DEFAULT, define hogs as that state This provides a single centralized name for the default state. Update PIN_MAP_* macros to use this state name, instead of requiring the user to pass a state name in. With this change, hog entries in the mapping table are defined as those with state name PINCTRL_STATE_DEFAULT, i.e. all entries have the same name. This interacts badly with the nested iteration over mapping table entries in pinctrl_hog_maps() and pinctrl_hog_map() which would now attempt to claim each hog mapping table entry multiple times. Replacing the custom hog code with a simple pinctrl_get()/pinctrl_enable(). Update documentation and mapping tables to use this. Signed-off-by: Stephen Warren Acked-by: Dong Aisheng Signed-off-by: Linus Walleij diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 5e314ce..6fe3232 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -814,7 +814,7 @@ it even more compact which assumes you want to use pinctrl-foo and position 0 for mapping, for example: static struct pinctrl_map __initdata mapping[] = { - PIN_MAP("I2CMAP", "pinctrl-foo", "i2c0", "foo-i2c.0"), + PIN_MAP(PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", "foo-i2c.0"), }; @@ -930,7 +930,7 @@ foo_probe() /* Allocate a state holder named "state" etc */ struct pinctrl p; - p = pinctrl_get(&device, NULL); + p = pinctrl_get(&device, PINCTRL_STATE_DEFAULT); if IS_ERR(p) return PTR_ERR(p); pinctrl_enable(p); @@ -989,7 +989,7 @@ of the pin controller itself, like this: { .dev_name = "pinctrl-foo", - .name = "POWERMAP" + .name = PINCTRL_STATE_DEFAULT, .ctrl_dev_name = "pinctrl-foo", .function = "power_func", }, @@ -998,7 +998,7 @@ 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: -PIN_MAP_PRIMARY_SYS_HOG("POWERMAP", "pinctrl-foo", "power_func") +PIN_MAP_SYS_HOG("pinctrl-foo", "power_func") This gives the exact same result as the above construction. diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index 030b2c0..ea6c790 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -1608,9 +1608,9 @@ static struct platform_device dma_device = { /* Pinmux settings */ static struct pinctrl_map __initdata u300_pinmux_map[] = { /* anonymous maps for chip power and EMIFs */ - PIN_MAP_SYS_HOG("POWER", "pinctrl-u300", "power"), - PIN_MAP_SYS_HOG("EMIF0", "pinctrl-u300", "emif0"), - PIN_MAP_SYS_HOG("EMIF1", "pinctrl-u300", "emif1"), + PIN_MAP_SYS_HOG("pinctrl-u300", "power"), + PIN_MAP_SYS_HOG("pinctrl-u300", "emif0"), + PIN_MAP_SYS_HOG("pinctrl-u300", "emif1"), /* per-device maps for MMC/SD, SPI and UART */ PIN_MAP("MMCSD", "pinctrl-u300", "mmc0", "mmci"), PIN_MAP("SPI", "pinctrl-u300", "spi0", "pl022"), diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 376cede..f25307b 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -44,18 +44,6 @@ struct pinctrl_maps { unsigned num_maps; }; -/** - * struct pinctrl_hog - a list item to stash control hogs - * @node: pin control hog list node - * @map: map entry responsible for this hogging - * @pmx: the pin control hogged by this item - */ -struct pinctrl_hog { - struct list_head node; - struct pinctrl_map const *map; - struct pinctrl *p; -}; - /* Global list of pin control devices */ static DEFINE_MUTEX(pinctrldev_list_mutex); static LIST_HEAD(pinctrldev_list); @@ -702,103 +690,6 @@ int pinctrl_register_mappings(struct pinctrl_map const *maps, return 0; } -/* Hog a single map entry and add to the hoglist */ -static int pinctrl_hog_map(struct pinctrl_dev *pctldev, - struct pinctrl_map const *map) -{ - struct pinctrl_hog *hog; - struct pinctrl *p; - int ret; - - hog = kzalloc(sizeof(*hog), GFP_KERNEL); - if (!hog) { - dev_err(pctldev->dev, "failed to alloc struct pinctrl_hog\n"); - return -ENOMEM; - } - - p = pinctrl_get_locked(pctldev->dev, map->name); - if (IS_ERR(p)) { - kfree(hog); - dev_err(pctldev->dev, - "could not get the %s pin control mapping for hogging\n", - map->name); - return PTR_ERR(p); - } - - ret = pinctrl_enable(p); - if (ret) { - pinctrl_put(p); - kfree(hog); - dev_err(pctldev->dev, - "could not enable the %s pin control mapping for hogging\n", - map->name); - return ret; - } - - hog->map = map; - hog->p = p; - - dev_info(pctldev->dev, "hogged map %s, function %s\n", map->name, - map->function); - list_add_tail(&hog->node, &pctldev->pinctrl_hogs); - - return 0; -} - -/** - * pinctrl_hog_maps() - hog specific map entries on controller device - * @pctldev: the pin control device to hog entries on - * - * When the pin controllers are registered, there may be some specific pinmux - * map entries that need to be hogged, i.e. get+enabled until the system shuts - * down. - */ -static int pinctrl_hog_maps(struct pinctrl_dev *pctldev) -{ - struct device *dev = pctldev->dev; - const char *devname = dev_name(dev); - int ret; - struct pinctrl_maps *maps_node; - int i; - struct pinctrl_map const *map; - - INIT_LIST_HEAD(&pctldev->pinctrl_hogs); - - mutex_lock(&pinctrl_maps_mutex); - for_each_maps(maps_node, i, map) { - if (!strcmp(map->ctrl_dev_name, devname) && - !strcmp(map->dev_name, devname)) { - /* OK time to hog! */ - ret = pinctrl_hog_map(pctldev, map); - if (ret) { - mutex_unlock(&pinctrl_maps_mutex); - return ret; - } - } - } - mutex_unlock(&pinctrl_maps_mutex); - - return 0; -} - -/** - * pinctrl_unhog_maps() - unhog specific map entries on controller device - * @pctldev: the pin control device to unhog entries on - */ -static void pinctrl_unhog_maps(struct pinctrl_dev *pctldev) -{ - struct list_head *node, *tmp; - - list_for_each_safe(node, tmp, &pctldev->pinctrl_hogs) { - struct pinctrl_hog *hog = - list_entry(node, struct pinctrl_hog, node); - pinctrl_disable(hog->p); - pinctrl_put(hog->p); - list_del(node); - kfree(hog); - } -} - #ifdef CONFIG_DEBUG_FS static int pinctrl_pins_show(struct seq_file *s, void *what) @@ -889,19 +780,6 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) return 0; } -static int pinmux_hogs_show(struct seq_file *s, void *what) -{ - struct pinctrl_dev *pctldev = s->private; - struct pinctrl_hog *hog; - - seq_puts(s, "Pin control map hogs held by device\n"); - - list_for_each_entry(hog, &pctldev->pinctrl_hogs, node) - seq_printf(s, "%s\n", hog->map->name); - - return 0; -} - static int pinctrl_devices_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev; @@ -988,11 +866,6 @@ static int pinctrl_gpioranges_open(struct inode *inode, struct file *file) return single_open(file, pinctrl_gpioranges_show, inode->i_private); } -static int pinmux_hogs_open(struct inode *inode, struct file *file) -{ - return single_open(file, pinmux_hogs_show, inode->i_private); -} - static int pinctrl_devices_open(struct inode *inode, struct file *file) { return single_open(file, pinctrl_devices_show, NULL); @@ -1029,13 +902,6 @@ static const struct file_operations pinctrl_gpioranges_ops = { .release = single_release, }; -static const struct file_operations pinmux_hogs_ops = { - .open = pinmux_hogs_open, - .read = seq_read, - .llseek = seq_lseek, - .release = single_release, -}; - static const struct file_operations pinctrl_devices_ops = { .open = pinctrl_devices_open, .read = seq_read, @@ -1078,8 +944,6 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) device_root, pctldev, &pinctrl_groups_ops); debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO, device_root, pctldev, &pinctrl_gpioranges_ops); - debugfs_create_file("pinmux-hogs", S_IFREG | S_IRUGO, - device_root, pctldev, &pinmux_hogs_ops); pinmux_init_device_debugfs(device_root, pctldev); pinconf_init_device_debugfs(device_root, pctldev); } @@ -1188,7 +1052,9 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, mutex_lock(&pinctrldev_list_mutex); list_add_tail(&pctldev->node, &pinctrldev_list); mutex_unlock(&pinctrldev_list_mutex); - pinctrl_hog_maps(pctldev); + pctldev->p = pinctrl_get(pctldev->dev, PINCTRL_STATE_DEFAULT); + if (!IS_ERR(pctldev->p)) + pinctrl_enable(pctldev->p); pinctrl_init_device_debugfs(pctldev); return pctldev; @@ -1211,7 +1077,10 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) return; pinctrl_remove_device_debugfs(pctldev); - pinctrl_unhog_maps(pctldev); + if (!IS_ERR(pctldev->p)) { + pinctrl_disable(pctldev->p); + pinctrl_put(pctldev->p); + } /* TODO: check that no pinmuxes are still active? */ mutex_lock(&pinctrldev_list_mutex); list_del(&pctldev->node); diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 8164e7b..97f8124 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -27,7 +27,7 @@ struct pinctrl_gpio_range; * @owner: module providing the pin controller, used for refcounting * @driver_data: driver data for drivers registering to the pin controller * subsystem - * @pinctrl_hogs: list of pin control maps hogged by this device + * @p: result of pinctrl_get() for this device * @device_root: debugfs root for this device */ struct pinctrl_dev { @@ -39,7 +39,7 @@ struct pinctrl_dev { struct device *dev; struct module *owner; void *driver_data; - struct list_head pinctrl_hogs; + struct pinctrl *p; #ifdef CONFIG_DEBUG_FS struct dentry *device_root; #endif diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index 73fbb27..20e9735 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -12,6 +12,8 @@ #ifndef __LINUX_PINCTRL_MACHINE_H #define __LINUX_PINCTRL_MACHINE_H +#include "pinctrl.h" + /** * struct pinctrl_map - boards/machines shall provide this map for devices * @dev_name: the name of the device using this specific mapping, the name @@ -49,17 +51,18 @@ struct pinctrl_map { * Convenience macro to map a system function onto a certain pinctrl device, * to be hogged by the pin control core until the system shuts down. */ -#define PIN_MAP_SYS_HOG(a, b, c) \ - { .name = a, .ctrl_dev_name = b, .dev_name = b, .function = c, } +#define PIN_MAP_SYS_HOG(a, b) \ + { .name = PINCTRL_STATE_DEFAULT, .ctrl_dev_name = a, .dev_name = a, \ + .function = b, } /* * Convenience macro to map a system function onto a certain pinctrl device * using a specified group, to be hogged by the pin control core until the * system shuts down. */ -#define PIN_MAP_SYS_HOG_GROUP(a, b, c, d) \ - { .name = a, .ctrl_dev_name = b, .dev_name = b, .function = c, \ - .group = d, } +#define PIN_MAP_SYS_HOG_GROUP(a, b, c) \ + { .name = PINCTRL_STATE_DEFAULT, .ctrl_dev_name = a, .dev_name = a, \ + .function = b, .group = c, } #ifdef CONFIG_PINMUX diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 8bd22ee..411fe23 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -19,6 +19,8 @@ #include #include +#define PINCTRL_STATE_DEFAULT "default" + struct pinctrl_dev; struct pinmux_ops; struct pinconf_ops; -- cgit v0.10.2 From 110e4ec5a1cfe20190e7f8c2b8b4eef369de3c99 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 1 Mar 2012 18:48:33 -0700 Subject: pinctrl: assume map table entries can't have a NULL name field pinctrl_register_mappings() already requires that every mapping table entry have a non-NULL name field. Logically, this makes sense too; drivers should always request a specific named state so they know what they're getting. Relying on getting the first mentioned state in the mapping table is error-prone, and a nasty special case to implement, given that a given the mapping table may define multiple states for a device. Remove a small part of the documentation that talked about optionally requesting a specific state; it's mandatory now. Signed-off-by: Stephen Warren Acked-by: Dong Aisheng Signed-off-by: Linus Walleij diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 6fe3232..558aac5 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -782,16 +782,19 @@ spi on the second function mapping: static const struct pinctrl_map __initdata mapping[] = { { .dev_name = "foo-spi.0", + .name = PINCTRL_STATE_DEFAULT, .ctrl_dev_name = "pinctrl-foo", .function = "spi0", }, { .dev_name = "foo-i2c.0", + .name = PINCTRL_STATE_DEFAULT, .ctrl_dev_name = "pinctrl-foo", .function = "i2c0", }, { .dev_name = "foo-mmc.0", + .name = PINCTRL_STATE_DEFAULT, .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", }, @@ -944,10 +947,6 @@ foo_remove() pinctrl_put(state->p); } -If you want to grab a specific control 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: pinctrl_get(&device, "spi0-pos-B"); - This get/enable/disable/put sequence can just as well be handled by bus drivers if you don't want each and every driver to handle it and you know the arrangement on your bus. diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index ea6c790..f29565a 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -1612,9 +1612,9 @@ static struct pinctrl_map __initdata u300_pinmux_map[] = { PIN_MAP_SYS_HOG("pinctrl-u300", "emif0"), PIN_MAP_SYS_HOG("pinctrl-u300", "emif1"), /* per-device maps for MMC/SD, SPI and UART */ - PIN_MAP("MMCSD", "pinctrl-u300", "mmc0", "mmci"), - PIN_MAP("SPI", "pinctrl-u300", "spi0", "pl022"), - PIN_MAP("UART0", "pinctrl-u300", "uart0", "uart0"), + PIN_MAP(PINCTRL_STATE_DEFAULT, "pinctrl-u300", "mmc0", "mmci"), + PIN_MAP(PINCTRL_STATE_DEFAULT, "pinctrl-u300", "spi0", "pl022"), + PIN_MAP(PINCTRL_STATE_DEFAULT, "pinctrl-u300", "uart0", "uart0"), }; struct u300_mux_hog { @@ -1646,7 +1646,7 @@ static int __init u300_pinctrl_fetch(void) struct pinctrl *p; int ret; - p = pinctrl_get(u300_mux_hogs[i].dev, NULL); + p = pinctrl_get(u300_mux_hogs[i].dev, PINCTRL_STATE_DEFAULT); if (IS_ERR(p)) { pr_err("u300: could not get pinmux hog %s\n", u300_mux_hogs[i].name); diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index f25307b..6af6d8d 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -461,8 +461,8 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) int i; struct pinctrl_map const *map; - /* We must have a dev name */ - if (WARN_ON(!dev)) + /* We must have both a dev and state name */ + if (WARN_ON(!dev || !name)) return ERR_PTR(-EINVAL); devname = dev_name(dev); @@ -504,16 +504,9 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) if (strcmp(map->dev_name, devname)) continue; - /* - * If we're looking for a specific named map, this must match, - * else we loop and look for the next. - */ - if (name != NULL) { - if (map->name == NULL) - continue; - if (strcmp(map->name, name)) - continue; - } + /* State name must be the one we're looking for */ + if (strcmp(map->name, name)) + continue; ret = pinmux_apply_muxmap(pctldev, p, dev, devname, map); if (ret) { diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index c1a871e..3cabb65 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c @@ -673,7 +673,7 @@ int sirfsoc_uart_probe(struct platform_device *pdev) port->irq = res->start; if (sirfport->hw_flow_ctrl) { - sirfport->p = pinctrl_get(&pdev->dev, NULL); + sirfport->p = pinctrl_get(&pdev->dev, PINCTRL_STATE_DEFAULT); ret = IS_ERR(sirfport->p); if (ret) goto pin_err; -- cgit v0.10.2 From 962bcbc57aa244eeb1176fa2e9f65ac865cca68a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 2 Mar 2012 16:52:46 +0100 Subject: pinctrl: fix the pin descriptor kerneldoc The introduction of the owner field on the pin descriptor was not properly documented so fix this up. Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 97f8124..e1dfdb3 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -76,9 +76,7 @@ struct pinctrl { * 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 + * @owner: the device holding this pin or NULL of no device has claimed it */ struct pin_desc { struct pinctrl_dev *pctldev; -- cgit v0.10.2 From 57b676f9c1b7cd84397fe5a86c9bd2788ac4bd32 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 2 Mar 2012 13:05:44 -0700 Subject: pinctrl: fix and simplify locking There are many problems with the current pinctrl locking: struct pinctrl_dev's gpio_ranges_lock isn't effective; pinctrl_match_gpio_range() only holds this lock while searching for a gpio range, but the found range is return and manipulated after releading the lock. This could allow pinctrl_remove_gpio_range() for that range while it is in use, and the caller may very well delete the range after removing it, causing pinctrl code to touch the now-free range object. Solving this requires the introduction of a higher-level lock, at least a lock per pin controller, which both gpio range registration and pinctrl_get()/put() will acquire. There is missing locking on HW programming; pin controllers may pack the configuration for different pins/groups/config options/... into one register, and hence have to read-modify-write the register. This needs to be protected, but currently isn't. Related, a future change will add a "complete" op to the pin controller drivers, the idea being that each state's programming will be programmed into the pinctrl driver followed by the "complete" call, which may e.g. flush a register cache to HW. For this to work, it must not be possible to interleave the pinctrl driver calls for different devices. As above, solving this requires the introduction of a higher-level lock, at least a lock per pin controller, which will be held for the duration of any pinctrl_enable()/disable() call. However, each pinctrl mapping table entry may affect a different pin controller if necessary. Hence, with a per-pin-controller lock, almost any pinctrl API may need to acquire multiple locks, one per controller. To avoid deadlock, these would need to be acquired in the same order in all cases. This is extremely difficult to implement in the case of pinctrl_get(), which doesn't know which pin controllers to lock until it has parsed the entire mapping table, since it contains somewhat arbitrary data. The simplest solution here is to introduce a single lock that covers all pin controllers at once. This will be acquired by all pinctrl APIs. This then makes struct pinctrl's mutex irrelevant, since that single lock will always be held whenever this mutex is currently held. Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 6af6d8d..aefc339 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -18,11 +18,8 @@ #include #include #include -#include #include #include -#include -#include #include #include #include @@ -44,16 +41,16 @@ struct pinctrl_maps { unsigned num_maps; }; -/* Global list of pin control devices */ -static DEFINE_MUTEX(pinctrldev_list_mutex); +/* Mutex taken by all entry points */ +DEFINE_MUTEX(pinctrl_mutex); + +/* Global list of pin control devices (struct pinctrl_dev) */ static LIST_HEAD(pinctrldev_list); -/* List of pin controller handles */ -static DEFINE_MUTEX(pinctrl_list_mutex); +/* List of pin controller handles (struct pinctrl) */ static LIST_HEAD(pinctrl_list); -/* Global pinctrl maps */ -static DEFINE_MUTEX(pinctrl_maps_mutex); +/* List of pinctrl maps (struct pinctrl_maps) */ static LIST_HEAD(pinctrl_maps); #define for_each_maps(_maps_node_, _i_, _map_) \ @@ -90,7 +87,6 @@ struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname) if (!devname) return NULL; - mutex_lock(&pinctrldev_list_mutex); list_for_each_entry(pctldev, &pinctrldev_list, node) { if (!strcmp(dev_name(pctldev->dev), devname)) { /* Matched on device name */ @@ -98,7 +94,6 @@ struct pinctrl_dev *get_pinctrl_dev_from_devname(const char *devname) break; } } - mutex_unlock(&pinctrldev_list_mutex); return found ? pctldev : NULL; } @@ -143,11 +138,11 @@ bool pin_is_valid(struct pinctrl_dev *pctldev, int pin) if (pin < 0) return false; + mutex_lock(&pinctrl_mutex); pindesc = pin_desc_get(pctldev, pin); - if (pindesc == NULL) - return false; + mutex_unlock(&pinctrl_mutex); - return true; + return pindesc != NULL; } EXPORT_SYMBOL_GPL(pin_is_valid); @@ -191,8 +186,6 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, return -ENOMEM; } - spin_lock_init(&pindesc->lock); - /* Set owner */ pindesc->pctldev = pctldev; @@ -243,16 +236,13 @@ pinctrl_match_gpio_range(struct pinctrl_dev *pctldev, unsigned gpio) struct pinctrl_gpio_range *range = NULL; /* Loop over the ranges */ - mutex_lock(&pctldev->gpio_ranges_lock); list_for_each_entry(range, &pctldev->gpio_ranges, node) { /* Check if we're in the valid range */ if (gpio >= range->base && gpio < range->base + range->npins) { - mutex_unlock(&pctldev->gpio_ranges_lock); return range; } } - mutex_unlock(&pctldev->gpio_ranges_lock); return NULL; } @@ -274,7 +264,6 @@ static int pinctrl_get_device_gpio_range(unsigned gpio, struct pinctrl_dev *pctldev = NULL; /* Loop over the pin controllers */ - mutex_lock(&pinctrldev_list_mutex); list_for_each_entry(pctldev, &pinctrldev_list, node) { struct pinctrl_gpio_range *range; @@ -282,11 +271,9 @@ static int pinctrl_get_device_gpio_range(unsigned gpio, if (range != NULL) { *outdev = pctldev; *outrange = range; - mutex_unlock(&pinctrldev_list_mutex); return 0; } } - mutex_unlock(&pinctrldev_list_mutex); return -EINVAL; } @@ -302,9 +289,9 @@ static int pinctrl_get_device_gpio_range(unsigned gpio, void pinctrl_add_gpio_range(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range) { - mutex_lock(&pctldev->gpio_ranges_lock); + mutex_lock(&pinctrl_mutex); list_add_tail(&range->node, &pctldev->gpio_ranges); - mutex_unlock(&pctldev->gpio_ranges_lock); + mutex_unlock(&pinctrl_mutex); } EXPORT_SYMBOL_GPL(pinctrl_add_gpio_range); @@ -316,9 +303,9 @@ EXPORT_SYMBOL_GPL(pinctrl_add_gpio_range); void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range) { - mutex_lock(&pctldev->gpio_ranges_lock); + mutex_lock(&pinctrl_mutex); list_del(&range->node); - mutex_unlock(&pctldev->gpio_ranges_lock); + mutex_unlock(&pinctrl_mutex); } EXPORT_SYMBOL_GPL(pinctrl_remove_gpio_range); @@ -368,14 +355,21 @@ int pinctrl_request_gpio(unsigned gpio) int ret; int pin; + mutex_lock(&pinctrl_mutex); + ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); - if (ret) + if (ret) { + mutex_unlock(&pinctrl_mutex); return -EINVAL; + } /* Convert to the pin controllers number space */ pin = gpio - range->base + range->pin_base; - return pinmux_request_gpio(pctldev, range, pin, gpio); + ret = pinmux_request_gpio(pctldev, range, pin, gpio); + + mutex_unlock(&pinctrl_mutex); + return ret; } EXPORT_SYMBOL_GPL(pinctrl_request_gpio); @@ -394,14 +388,20 @@ void pinctrl_free_gpio(unsigned gpio) int ret; int pin; + mutex_lock(&pinctrl_mutex); + ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); - if (ret) + if (ret) { + mutex_unlock(&pinctrl_mutex); return; + } /* Convert to the pin controllers number space */ pin = gpio - range->base + range->pin_base; - return pinmux_free_gpio(pctldev, pin, range); + pinmux_free_gpio(pctldev, pin, range); + + mutex_unlock(&pinctrl_mutex); } EXPORT_SYMBOL_GPL(pinctrl_free_gpio); @@ -432,7 +432,11 @@ static int pinctrl_gpio_direction(unsigned gpio, bool input) */ int pinctrl_gpio_direction_input(unsigned gpio) { - return pinctrl_gpio_direction(gpio, true); + int ret; + mutex_lock(&pinctrl_mutex); + ret = pinctrl_gpio_direction(gpio, true); + mutex_unlock(&pinctrl_mutex); + return ret; } EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input); @@ -446,7 +450,11 @@ EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_input); */ int pinctrl_gpio_direction_output(unsigned gpio) { - return pinctrl_gpio_direction(gpio, false); + int ret; + mutex_lock(&pinctrl_mutex); + ret = pinctrl_gpio_direction(gpio, false); + mutex_unlock(&pinctrl_mutex); + return ret; } EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); @@ -479,7 +487,6 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) dev_err(dev, "failed to alloc struct pinctrl\n"); return ERR_PTR(-ENOMEM); } - mutex_init(&p->mutex); pinmux_init_pinctrl_handle(p); /* Iterate over the pin control maps to locate the right ones */ @@ -531,9 +538,7 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) num_maps, devname, name ? name : "(undefined)"); /* Add the pinmux to the global list */ - mutex_lock(&pinctrl_list_mutex); list_add_tail(&p->node, &pinctrl_list); - mutex_unlock(&pinctrl_list_mutex); return p; } @@ -549,74 +554,91 @@ struct pinctrl *pinctrl_get(struct device *dev, const char *name) { struct pinctrl *p; - mutex_lock(&pinctrl_maps_mutex); + mutex_lock(&pinctrl_mutex); p = pinctrl_get_locked(dev, name); - mutex_unlock(&pinctrl_maps_mutex); + mutex_unlock(&pinctrl_mutex); return p; } EXPORT_SYMBOL_GPL(pinctrl_get); -/** - * pinctrl_put() - release a previously claimed pin control handle - * @p: a pin control handle previously claimed by pinctrl_get() - */ -void pinctrl_put(struct pinctrl *p) +static void pinctrl_put_locked(struct pinctrl *p) { if (p == NULL) return; - mutex_lock(&p->mutex); if (p->usecount) pr_warn("releasing pin control handle with active users!\n"); /* Free the groups and all acquired pins */ pinmux_put(p); - mutex_unlock(&p->mutex); /* Remove from list */ - mutex_lock(&pinctrl_list_mutex); list_del(&p->node); - mutex_unlock(&pinctrl_list_mutex); kfree(p); } -EXPORT_SYMBOL_GPL(pinctrl_put); /** - * pinctrl_enable() - enable a certain pin controller setting - * @p: the pin control handle to enable, previously claimed by pinctrl_get() + * pinctrl_put() - release a previously claimed pin control handle + * @p: a pin control handle previously claimed by pinctrl_get() */ -int pinctrl_enable(struct pinctrl *p) +void pinctrl_put(struct pinctrl *p) +{ + mutex_lock(&pinctrl_mutex); + pinctrl_put(p); + mutex_unlock(&pinctrl_mutex); +} +EXPORT_SYMBOL_GPL(pinctrl_put); + +static int pinctrl_enable_locked(struct pinctrl *p) { int ret = 0; if (p == NULL) return -EINVAL; - mutex_lock(&p->mutex); + if (p->usecount++ == 0) { ret = pinmux_enable(p); if (ret) p->usecount--; } - mutex_unlock(&p->mutex); + return ret; } -EXPORT_SYMBOL_GPL(pinctrl_enable); /** - * pinctrl_disable() - disable a certain pin control setting - * @p: the pin control handle to disable, previously claimed by pinctrl_get() + * pinctrl_enable() - enable a certain pin controller setting + * @p: the pin control handle to enable, previously claimed by pinctrl_get() */ -void pinctrl_disable(struct pinctrl *p) +int pinctrl_enable(struct pinctrl *p) +{ + int ret; + mutex_lock(&pinctrl_mutex); + ret = pinctrl_enable_locked(p); + mutex_unlock(&pinctrl_mutex); + return ret; +} +EXPORT_SYMBOL_GPL(pinctrl_enable); + +static void pinctrl_disable_locked(struct pinctrl *p) { if (p == NULL) return; - mutex_lock(&p->mutex); if (--p->usecount == 0) { pinmux_disable(p); } - mutex_unlock(&p->mutex); +} + +/** + * pinctrl_disable() - disable a certain pin control setting + * @p: the pin control handle to disable, previously claimed by pinctrl_get() + */ +void pinctrl_disable(struct pinctrl *p) +{ + mutex_lock(&pinctrl_mutex); + pinctrl_disable_locked(p); + mutex_unlock(&pinctrl_mutex); } EXPORT_SYMBOL_GPL(pinctrl_disable); @@ -676,9 +698,9 @@ int pinctrl_register_mappings(struct pinctrl_map const *maps, return -ENOMEM; } - mutex_lock(&pinctrl_maps_mutex); + mutex_lock(&pinctrl_mutex); list_add_tail(&maps_node->node, &pinctrl_maps); - mutex_unlock(&pinctrl_maps_mutex); + mutex_unlock(&pinctrl_mutex); return 0; } @@ -693,6 +715,8 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) seq_printf(s, "registered pins: %d\n", pctldev->desc->npins); + mutex_lock(&pinctrl_mutex); + /* The pin number can be retrived from the pin controller descriptor */ for (i = 0; i < pctldev->desc->npins; i++) { struct pin_desc *desc; @@ -713,6 +737,8 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) seq_puts(s, "\n"); } + mutex_unlock(&pinctrl_mutex); + return 0; } @@ -726,6 +752,8 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) if (!ops) return 0; + mutex_lock(&pinctrl_mutex); + seq_puts(s, "registered pin groups:\n"); while (ops->list_groups(pctldev, selector) >= 0) { const unsigned *pins; @@ -748,6 +776,7 @@ static int pinctrl_groups_show(struct seq_file *s, void *what) selector++; } + mutex_unlock(&pinctrl_mutex); return 0; } @@ -759,8 +788,9 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) seq_puts(s, "GPIO ranges handled:\n"); + mutex_lock(&pinctrl_mutex); + /* Loop over the ranges */ - mutex_lock(&pctldev->gpio_ranges_lock); list_for_each_entry(range, &pctldev->gpio_ranges, node) { seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n", range->id, range->name, @@ -768,7 +798,8 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) range->pin_base, (range->pin_base + range->npins - 1)); } - mutex_unlock(&pctldev->gpio_ranges_lock); + + mutex_unlock(&pinctrl_mutex); return 0; } @@ -778,7 +809,9 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) struct pinctrl_dev *pctldev; seq_puts(s, "name [pinmux] [pinconf]\n"); - mutex_lock(&pinctrldev_list_mutex); + + mutex_lock(&pinctrl_mutex); + list_for_each_entry(pctldev, &pinctrldev_list, node) { seq_printf(s, "%s ", pctldev->desc->name); if (pctldev->desc->pmxops) @@ -791,7 +824,8 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) seq_puts(s, "no"); seq_puts(s, "\n"); } - mutex_unlock(&pinctrldev_list_mutex); + + mutex_unlock(&pinctrl_mutex); return 0; } @@ -804,7 +838,8 @@ static int pinctrl_maps_show(struct seq_file *s, void *what) seq_puts(s, "Pinctrl maps:\n"); - mutex_lock(&pinctrl_maps_mutex); + mutex_lock(&pinctrl_mutex); + for_each_maps(maps_node, i, map) { seq_printf(s, "%s:\n", map->name); seq_printf(s, " device: %s\n", map->dev_name); @@ -813,7 +848,8 @@ static int pinctrl_maps_show(struct seq_file *s, void *what) seq_printf(s, " group: %s\n", map->group ? map->group : "(default)"); } - mutex_unlock(&pinctrl_maps_mutex); + + mutex_unlock(&pinctrl_mutex); return 0; } @@ -823,6 +859,9 @@ static int pinctrl_show(struct seq_file *s, void *what) struct pinctrl *p; seq_puts(s, "Requested pin control handlers their pinmux maps:\n"); + + mutex_lock(&pinctrl_mutex); + list_for_each_entry(p, &pinctrl_list, node) { struct pinctrl_dev *pctldev = p->pctldev; @@ -841,6 +880,8 @@ static int pinctrl_show(struct seq_file *s, void *what) p->dev ? dev_name(p->dev) : "(system)"); } + mutex_unlock(&pinctrl_mutex); + return 0; } @@ -1008,7 +1049,6 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, pctldev->driver_data = driver_data; INIT_RADIX_TREE(&pctldev->pin_desc_tree, GFP_KERNEL); INIT_LIST_HEAD(&pctldev->gpio_ranges); - mutex_init(&pctldev->gpio_ranges_lock); pctldev->dev = dev; /* If we're implementing pinmuxing, check the ops for sanity */ @@ -1042,12 +1082,16 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, goto out_err; } - mutex_lock(&pinctrldev_list_mutex); + mutex_lock(&pinctrl_mutex); + list_add_tail(&pctldev->node, &pinctrldev_list); - mutex_unlock(&pinctrldev_list_mutex); - pctldev->p = pinctrl_get(pctldev->dev, PINCTRL_STATE_DEFAULT); + + pctldev->p = pinctrl_get_locked(pctldev->dev, PINCTRL_STATE_DEFAULT); if (!IS_ERR(pctldev->p)) - pinctrl_enable(pctldev->p); + pinctrl_enable_locked(pctldev->p); + + mutex_unlock(&pinctrl_mutex); + pinctrl_init_device_debugfs(pctldev); return pctldev; @@ -1070,18 +1114,22 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) return; pinctrl_remove_device_debugfs(pctldev); + + mutex_lock(&pinctrl_mutex); + if (!IS_ERR(pctldev->p)) { - pinctrl_disable(pctldev->p); - pinctrl_put(pctldev->p); + pinctrl_disable_locked(pctldev->p); + pinctrl_put_locked(pctldev->p); } + /* TODO: check that no pinmuxes are still active? */ - mutex_lock(&pinctrldev_list_mutex); list_del(&pctldev->node); - mutex_unlock(&pinctrldev_list_mutex); /* Destroy descriptor tree */ pinctrl_free_pindescs(pctldev, pctldev->desc->pins, pctldev->desc->npins); kfree(pctldev); + + mutex_unlock(&pinctrl_mutex); } EXPORT_SYMBOL_GPL(pinctrl_unregister); diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index e1dfdb3..8808f25 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -9,6 +9,8 @@ * License terms: GNU General Public License (GPL) version 2 */ +#include +#include #include struct pinctrl_gpio_range; @@ -22,7 +24,6 @@ struct pinctrl_gpio_range; * this radix 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 @@ -35,7 +36,6 @@ struct pinctrl_dev { struct pinctrl_desc *desc; struct radix_tree_root pin_desc_tree; struct list_head gpio_ranges; - struct mutex gpio_ranges_lock; struct device *dev; struct module *owner; void *driver_data; @@ -52,7 +52,6 @@ struct pinctrl_dev { * @usecount: the number of active users of this pin controller setting, used * to keep track of nested use cases * @pctldev: pin control device handling this pin control handle - * @mutex: a lock for the pin control state holder * @groups: the group selectors for the pinmux device and * selector combination handling this pinmux, this is a list that * will be traversed on all pinmux operations such as @@ -63,7 +62,6 @@ struct pinctrl { struct device *dev; unsigned usecount; struct pinctrl_dev *pctldev; - struct mutex mutex; #ifdef CONFIG_PINMUX struct list_head groups; #endif @@ -75,14 +73,12 @@ struct pinctrl { * @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 * @owner: the device holding this pin or NULL of no device has claimed it */ 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 *owner; @@ -99,3 +95,5 @@ static inline struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, { return radix_tree_lookup(&pctldev->pin_desc_tree, pin); } + +extern struct mutex pinctrl_mutex; diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 3f018a1..e0a4537 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -64,15 +64,23 @@ int pin_config_get(const char *dev_name, const char *name, struct pinctrl_dev *pctldev; int pin; + mutex_lock(&pinctrl_mutex); + pctldev = get_pinctrl_dev_from_devname(dev_name); - if (!pctldev) - return -EINVAL; + 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); @@ -110,17 +118,27 @@ int pin_config_set(const char *dev_name, const char *name, unsigned long config) { struct pinctrl_dev *pctldev; - int pin; + int pin, ret; + + mutex_lock(&pinctrl_mutex); pctldev = get_pinctrl_dev_from_devname(dev_name); - if (!pctldev) - return -EINVAL; + if (!pctldev) { + ret = -EINVAL; + goto unlock; + } pin = pin_get_from_name(pctldev, name); - if (pin < 0) - return pin; + if (pin < 0) { + ret = pin; + goto unlock; + } + + ret = pin_config_set_for_pin(pctldev, pin, config); - return pin_config_set_for_pin(pctldev, pin, config); +unlock: + mutex_unlock(&pinctrl_mutex); + return ret; } EXPORT_SYMBOL(pin_config_set); @@ -129,25 +147,36 @@ 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; + + mutex_lock(&pinctrl_mutex); pctldev = get_pinctrl_dev_from_devname(dev_name); - if (!pctldev) - return -EINVAL; + 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); @@ -163,27 +192,34 @@ int pin_config_group_set(const char *dev_name, const char *pin_group, int ret; int i; + mutex_lock(&pinctrl_mutex); + pctldev = get_pinctrl_dev_from_devname(dev_name); - if (!pctldev) - return -EINVAL; + 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; } /* @@ -197,23 +233,30 @@ int pin_config_group_set(const char *dev_name, const char *pin_group, * pin-by-pin as well, it returns -EAGAIN. */ if (ret != -EAGAIN) - return ret; + goto unlock; } /* * If the controller cannot handle entire groups, we configure each pin * individually. */ - if (!ops->pin_config_set) - return 0; + if (!ops->pin_config_set) { + ret = 0; + goto unlock; + } for (i = 0; i < num_pins; i++) { ret = ops->pin_config_set(pctldev, pins[i], config); if (ret < 0) - return ret; + goto unlock; } - return 0; + ret = 0; + +unlock: + mutex_unlock(&pinctrl_mutex); + + return ret; } EXPORT_SYMBOL(pin_config_group_set); @@ -236,6 +279,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; @@ -254,6 +299,8 @@ static int pinconf_pins_show(struct seq_file *s, void *what) seq_printf(s, "\n"); } + mutex_unlock(&pinctrl_mutex); + return 0; } @@ -280,6 +327,8 @@ 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); @@ -290,6 +339,8 @@ static int pinconf_groups_show(struct seq_file *s, void *what) selector++; } + mutex_unlock(&pinctrl_mutex); + return 0; } diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index f409f16..7342c26 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -19,8 +19,6 @@ #include #include #include -#include -#include #include #include #include @@ -96,15 +94,12 @@ static int pin_request(struct pinctrl_dev *pctldev, goto out; } - spin_lock(&desc->lock); if (desc->owner && strcmp(desc->owner, owner)) { - spin_unlock(&desc->lock); dev_err(pctldev->dev, "pin already requested\n"); goto out; } desc->owner = owner; - spin_unlock(&desc->lock); /* Let each pin increase references to this module */ if (!try_module_get(pctldev->owner)) { @@ -131,11 +126,8 @@ static int pin_request(struct pinctrl_dev *pctldev, dev_err(pctldev->dev, "->request on device %s failed for pin %d\n", pctldev->desc->name, pin); out_free_pin: - if (status) { - spin_lock(&desc->lock); + if (status) desc->owner = NULL; - spin_unlock(&desc->lock); - } out: if (status) dev_err(pctldev->dev, "pin-%d (%s) status %d\n", @@ -178,10 +170,8 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, else if (ops->free) ops->free(pctldev, pin); - spin_lock(&desc->lock); owner = desc->owner; desc->owner = NULL; - spin_unlock(&desc->lock); module_put(pctldev->owner); return owner; @@ -580,6 +570,8 @@ static int pinmux_functions_show(struct seq_file *s, void *what) const struct pinmux_ops *pmxops = pctldev->desc->pmxops; unsigned func_selector = 0; + mutex_lock(&pinctrl_mutex); + while (pmxops->list_functions(pctldev, func_selector) >= 0) { const char *func = pmxops->get_function_name(pctldev, func_selector); @@ -600,9 +592,10 @@ static int pinmux_functions_show(struct seq_file *s, void *what) seq_puts(s, "]\n"); func_selector++; - } + mutex_unlock(&pinctrl_mutex); + return 0; } @@ -614,6 +607,8 @@ static int pinmux_pins_show(struct seq_file *s, void *what) seq_puts(s, "Pinmux settings per pin\n"); seq_puts(s, "Format: pin (name): owner\n"); + mutex_lock(&pinctrl_mutex); + /* The pin number can be retrived from the pin controller descriptor */ for (i = 0; i < pctldev->desc->npins; i++) { struct pin_desc *desc; @@ -635,6 +630,8 @@ static int pinmux_pins_show(struct seq_file *s, void *what) is_hog ? " (HOG)" : ""); } + mutex_unlock(&pinctrl_mutex); + return 0; } diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index 411fe23..bbdd7e1 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -15,7 +15,6 @@ #ifdef CONFIG_PINCTRL #include -#include #include #include -- cgit v0.10.2 From 7ecdb16fe63e5b356335ebdc236adfb48cef31e1 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 2 Mar 2012 13:05:45 -0700 Subject: pinctrl: refactor struct pinctrl handling in core.c vs pinmux.c This change separates two aspects of struct pinctrl: a) The data representation of the parsed mapping table, into: 1) The top-level struct pinctrl object, a single entity returned by pinctrl_get(). 2) The parsed version of each mapping table entry, struct pinctrl_setting, of which there is one per mapping table entry. b) The code that handles this; the code for (1) above is in core.c, and the code to parse/execute each entry in (2) above is in pinmux.c, while the iteration over multiple settings is lifted to core.c. This will allow the following future changes: 1) pinctrl_get() API rework, so that struct pinctrl represents all states for the device, and the device can select between them without calling put()/get() again. 2) To support that, a struct pinctrl_state object will be inserted into the data model between the struct pinctrl and struct pinctrl_setting. 3) The mapping table will be extended to allow specification of pin config settings too. To support this, struct pinctrl_setting will be enhanced to store either mux settings or config settings, and functions will be added to pinconf.c to parse/execute pin configuration settings. Signed-off-by: Stephen Warren Acked-by: Linus Walleij Acked-by: Dong Aisheng Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index aefc339..535f8d5 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -460,14 +460,15 @@ EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) { - struct pinctrl_dev *pctldev = NULL; + struct pinctrl_dev *pctldev; const char *devname; struct pinctrl *p; unsigned num_maps = 0; - int ret = -ENODEV; + int ret; struct pinctrl_maps *maps_node; int i; struct pinctrl_map const *map; + struct pinctrl_setting *setting; /* We must have both a dev and state name */ if (WARN_ON(!dev || !name)) @@ -487,39 +488,50 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) dev_err(dev, "failed to alloc struct pinctrl\n"); return ERR_PTR(-ENOMEM); } - pinmux_init_pinctrl_handle(p); + p->dev = dev; + p->state = name; + INIT_LIST_HEAD(&p->settings); /* Iterate over the pin control maps to locate the right ones */ for_each_maps(maps_node, i, map) { + /* Map must be for this device */ + if (strcmp(map->dev_name, devname)) + continue; + + /* State name must be the one we're looking for */ + if (strcmp(map->name, name)) + continue; + /* - * First, try to find the pctldev given in the map + * Try to find the pctldev given in the map */ pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); if (!pctldev) { dev_err(dev, "unknown pinctrl device %s in map entry", map->ctrl_dev_name); - pinmux_put(p); - kfree(p); /* Eventually, this should trigger deferred probe */ - return ERR_PTR(-ENODEV); + ret = -ENODEV; + goto error; } dev_dbg(dev, "in map, found pctldev %s to handle function %s", dev_name(pctldev->dev), map->function); - /* Map must be for this device */ - if (strcmp(map->dev_name, devname)) - continue; + setting = kzalloc(sizeof(*setting), GFP_KERNEL); + if (setting == NULL) { + dev_err(dev, + "failed to alloc struct pinctrl_setting\n"); + ret = -ENOMEM; + goto error; + } - /* State name must be the one we're looking for */ - if (strcmp(map->name, name)) - continue; + setting->pctldev = pctldev; + ret = pinmux_map_to_setting(map, setting); + if (ret < 0) + goto error; + + list_add_tail(&setting->node, &p->settings); - ret = pinmux_apply_muxmap(pctldev, p, dev, devname, map); - if (ret) { - kfree(p); - return ERR_PTR(ret); - } num_maps++; } @@ -541,6 +553,14 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) list_add_tail(&p->node, &pinctrl_list); return p; + +error: + list_for_each_entry(setting, &p->settings, node) + pinmux_free_setting(setting); + + kfree(p); + + return ERR_PTR(ret); } /** @@ -564,13 +584,18 @@ EXPORT_SYMBOL_GPL(pinctrl_get); static void pinctrl_put_locked(struct pinctrl *p) { + struct pinctrl_setting *setting, *n; + if (p == NULL) return; if (p->usecount) pr_warn("releasing pin control handle with active users!\n"); - /* Free the groups and all acquired pins */ - pinmux_put(p); + list_for_each_entry_safe(setting, n, &p->settings, node) { + pinmux_free_setting(setting); + list_del(&setting->node); + kfree(setting); + } /* Remove from list */ list_del(&p->node); @@ -592,18 +617,24 @@ EXPORT_SYMBOL_GPL(pinctrl_put); static int pinctrl_enable_locked(struct pinctrl *p) { - int ret = 0; + struct pinctrl_setting *setting; + int ret; if (p == NULL) return -EINVAL; if (p->usecount++ == 0) { - ret = pinmux_enable(p); - if (ret) - p->usecount--; + list_for_each_entry(setting, &p->settings, node) { + ret = pinmux_enable_setting(setting); + if (ret < 0) { + /* FIXME: Difficult to return to prev state */ + p->usecount--; + return ret; + } + } } - return ret; + return 0; } /** @@ -622,11 +653,14 @@ EXPORT_SYMBOL_GPL(pinctrl_enable); static void pinctrl_disable_locked(struct pinctrl *p) { + struct pinctrl_setting *setting; + if (p == NULL) return; if (--p->usecount == 0) { - pinmux_disable(p); + list_for_each_entry(setting, &p->settings, node) + pinmux_disable_setting(setting); } } @@ -857,27 +891,20 @@ static int pinctrl_maps_show(struct seq_file *s, void *what) static int pinctrl_show(struct seq_file *s, void *what) { struct pinctrl *p; + struct pinctrl_setting *setting; seq_puts(s, "Requested pin control handlers their pinmux maps:\n"); mutex_lock(&pinctrl_mutex); list_for_each_entry(p, &pinctrl_list, node) { - struct pinctrl_dev *pctldev = p->pctldev; + seq_printf(s, "device: %s state: %s users: %u\n", + dev_name(p->dev), p->state, p->usecount); - if (!pctldev) { - seq_puts(s, "NO PIN CONTROLLER DEVICE\n"); - continue; + list_for_each_entry(setting, &p->settings, node) { + seq_printf(s, " "); + pinmux_dbg_show(s, setting); } - - seq_printf(s, "device: %s", - pinctrl_dev_get_name(p->pctldev)); - - pinmux_dbg_show(s, p); - - seq_printf(s, " users: %u map-> %s\n", - p->usecount, - p->dev ? dev_name(p->dev) : "(system)"); } mutex_unlock(&pinctrl_mutex); diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 8808f25..5f258b7 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -49,22 +49,31 @@ struct pinctrl_dev { * struct pinctrl - per-device pin control state holder * @node: global list node * @dev: the device using this pin control handle + * @state: the state name passed to pinctrl_get() * @usecount: the number of active users of this pin controller setting, used * to keep track of nested use cases - * @pctldev: pin control device handling this pin control handle - * @groups: the group selectors for the pinmux device and - * selector combination handling this pinmux, this is a list that - * will be traversed on all pinmux operations such as - * get/put/enable/disable + * @settings: a list of settings for this device/state */ struct pinctrl { struct list_head node; struct device *dev; + const char *state; unsigned usecount; + struct list_head settings; +}; + +/** + * struct pinctrl_setting - an individual mux setting + * @node: list node for struct pinctrl's @settings field + * @pctldev: pin control device handling to be programmed + * @group_selector: the group selector to program + * @func_selector: the function selector to program + */ +struct pinctrl_setting { + struct list_head node; struct pinctrl_dev *pctldev; -#ifdef CONFIG_PINMUX - struct list_head groups; -#endif + unsigned group_selector; + unsigned func_selector; }; /** diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 7342c26..f0fb98d 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -7,6 +7,8 @@ * * Author: Linus Walleij * + * Copyright (C) 2012 NVIDIA CORPORATION. All rights reserved. + * * License terms: GNU General Public License (GPL) version 2 */ #define pr_fmt(fmt) "pinmux core: " fmt @@ -28,19 +30,6 @@ #include "core.h" #include "pinmux.h" -/** - * struct pinmux_group - group list item for pinmux groups - * @node: pinmux group list node - * @func_selector: the function selector for the pinmux device handling - * this pinmux - * @group_selector: the group selector for this group - */ -struct pinmux_group { - struct list_head node; - unsigned func_selector; - unsigned group_selector; -}; - int pinmux_check_ops(struct pinctrl_dev *pctldev) { const struct pinmux_ops *ops = pctldev->desc->pmxops; @@ -244,164 +233,8 @@ int pinmux_gpio_direction(struct pinctrl_dev *pctldev, return ret; } -/** - * acquire_pins() - acquire all the pins for a certain function on a pinmux - * @pctldev: the device to take the pins on - * @owner: a representation of the owner of this pin; typically the device - * name that controls its mux function - * @group_selector: the group selector containing the pins to acquire - */ -static int acquire_pins(struct pinctrl_dev *pctldev, - const char *owner, - unsigned group_selector) -{ - const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; - const unsigned *pins; - unsigned num_pins; - int ret; - int i; - - ret = pctlops->get_group_pins(pctldev, group_selector, - &pins, &num_pins); - if (ret) - return ret; - - dev_dbg(pctldev->dev, "requesting the %u pins from group %u\n", - num_pins, group_selector); - - /* Try to allocate all pins in this group, one by one */ - for (i = 0; i < num_pins; i++) { - ret = pin_request(pctldev, pins[i], owner, NULL); - if (ret) { - dev_err(pctldev->dev, - "could not get request pin %d on device %s - conflicting mux mappings?\n", - pins[i], - pinctrl_dev_get_name(pctldev)); - /* On error release all taken pins */ - i--; /* this pin just failed */ - for (; i >= 0; i--) - pin_free(pctldev, pins[i], NULL); - return -ENODEV; - } - } - return 0; -} - -/** - * release_pins() - release pins taken by earlier acquirement - * @pctldev: the device to free the pins on - * @group_selector: the group selector containing the pins to free - */ -static void release_pins(struct pinctrl_dev *pctldev, - unsigned group_selector) -{ - const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; - const unsigned *pins; - unsigned num_pins; - int ret; - int i; - - ret = pctlops->get_group_pins(pctldev, group_selector, - &pins, &num_pins); - if (ret) { - dev_err(pctldev->dev, "could not get pins to release for group selector %d\n", - group_selector); - return; - } - for (i = 0; i < num_pins; i++) - pin_free(pctldev, pins[i], NULL); -} - -/** - * pinmux_check_pin_group() - check function and pin group combo - * @pctldev: device to check the pin group vs function for - * @func_selector: the function selector to check the pin group for, we have - * already looked this up in the calling function - * @pin_group: the pin group to match to the function - * - * This function will check that the pinmux driver can supply the - * selected pin group for a certain function, returns the group selector if - * the group and function selector will work fine together, else returns - * negative - */ -static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, - unsigned func_selector, - const char *pin_group) -{ - const struct pinmux_ops *pmxops = pctldev->desc->pmxops; - const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; - int ret; - - /* - * If the driver does not support different pin groups for the - * functions, we only support group 0, and assume this exists. - */ - if (!pctlops || !pctlops->list_groups) - return 0; - - /* - * Passing NULL (no specific group) will select the first and - * hopefully only group of pins available for this function. - */ - if (!pin_group) { - char const * const *groups; - unsigned num_groups; - - ret = pmxops->get_function_groups(pctldev, func_selector, - &groups, &num_groups); - if (ret) - return ret; - if (num_groups < 1) - return -EINVAL; - ret = pinctrl_get_group_selector(pctldev, groups[0]); - if (ret < 0) { - dev_err(pctldev->dev, - "function %s wants group %s but the pin controller does not seem to have that group\n", - pmxops->get_function_name(pctldev, func_selector), - groups[0]); - return ret; - } - - if (num_groups > 1) - dev_dbg(pctldev->dev, - "function %s support more than one group, default-selecting first group %s (%d)\n", - pmxops->get_function_name(pctldev, func_selector), - groups[0], - ret); - - return ret; - } - - dev_dbg(pctldev->dev, - "check if we have pin group %s on controller %s\n", - pin_group, pinctrl_dev_get_name(pctldev)); - - ret = pinctrl_get_group_selector(pctldev, pin_group); - if (ret < 0) { - dev_dbg(pctldev->dev, - "%s does not support pin group %s with function %s\n", - pinctrl_dev_get_name(pctldev), - pin_group, - pmxops->get_function_name(pctldev, func_selector)); - } - return ret; -} - -/** - * pinmux_search_function() - check pin control driver for a certain function - * @pctldev: device to check for function and position - * @map: function map containing the function and position to look for - * @func_selector: returns the applicable function selector if found - * @group_selector: returns the applicable group selector if found - * - * This will search the pinmux driver for an applicable - * function with a specific pin group, returns 0 if these can be mapped - * negative otherwise - */ -static int pinmux_search_function(struct pinctrl_dev *pctldev, - struct pinctrl_map const *map, - unsigned *func_selector, - unsigned *group_selector) +static int pinmux_func_name_to_selector(struct pinctrl_dev *pctldev, + const char *function) { const struct pinmux_ops *ops = pctldev->desc->pmxops; unsigned selector = 0; @@ -410,155 +243,128 @@ static int pinmux_search_function(struct pinctrl_dev *pctldev, while (ops->list_functions(pctldev, selector) >= 0) { const char *fname = ops->get_function_name(pctldev, selector); - int ret; - if (!strcmp(map->function, fname)) { - /* Found the function, check pin group */ - ret = pinmux_check_pin_group(pctldev, selector, - map->group); - if (ret < 0) - return ret; + if (!strcmp(function, fname)) + return selector; - /* This function and group selector can be used */ - *func_selector = selector; - *group_selector = ret; - return 0; - - } selector++; } pr_err("%s does not support function %s\n", - pinctrl_dev_get_name(pctldev), map->function); + pinctrl_dev_get_name(pctldev), function); return -EINVAL; } -/** - * pinmux_enable_muxmap() - enable a map entry for a certain pinmux - */ -static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, - struct pinctrl *p, - struct device *dev, - const char *devname, - struct pinctrl_map const *map) +int pinmux_map_to_setting(struct pinctrl_map const *map, + struct pinctrl_setting *setting) { - unsigned func_selector; - unsigned group_selector; - struct pinmux_group *grp; + struct pinctrl_dev *pctldev = setting->pctldev; + const struct pinmux_ops *pmxops = pctldev->desc->pmxops; + const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; + char const * const *groups; + unsigned num_groups; int ret; + const char *group; + int i; + const unsigned *pins; + unsigned num_pins; - /* - * Note that we're not locking the pinmux mutex here, because - * this is only called at pinmux initialization time when it - * has not been added to any list and thus is not reachable - * by anyone else. - */ + setting->func_selector = + pinmux_func_name_to_selector(pctldev, map->function); + if (setting->func_selector < 0) + return setting->func_selector; - if (p->pctldev && p->pctldev != pctldev) { - dev_err(pctldev->dev, - "different pin control devices given for device %s, function %s\n", - devname, map->function); + ret = pmxops->get_function_groups(pctldev, setting->func_selector, + &groups, &num_groups); + if (ret < 0) + return ret; + if (!num_groups) return -EINVAL; + + if (map->group) { + bool found = false; + group = map->group; + for (i = 0; i < num_groups; i++) { + if (!strcmp(group, groups[i])) { + found = true; + break; + } + } + if (!found) + return -EINVAL; + } else { + group = groups[0]; } - p->dev = dev; - p->pctldev = pctldev; - /* Now go into the driver and try to match a function and group */ - ret = pinmux_search_function(pctldev, map, &func_selector, - &group_selector); - if (ret < 0) - return ret; + setting->group_selector = + pinctrl_get_group_selector(pctldev, group); + if (setting->group_selector < 0) + return setting->group_selector; - /* Now add this group selector, we may have many of them */ - grp = kmalloc(sizeof(*grp), GFP_KERNEL); - if (!grp) - return -ENOMEM; - grp->func_selector = func_selector; - grp->group_selector = group_selector; - ret = acquire_pins(pctldev, devname, group_selector); + ret = pctlops->get_group_pins(pctldev, setting->group_selector, + &pins, &num_pins); if (ret) { - kfree(grp); - return ret; + dev_err(pctldev->dev, + "could not get pins for device %s group selector %d\n", + pinctrl_dev_get_name(pctldev), setting->group_selector); + return -ENODEV; + } + + /* Try to allocate all pins in this group, one by one */ + for (i = 0; i < num_pins; i++) { + ret = pin_request(pctldev, pins[i], map->dev_name, NULL); + if (ret) { + dev_err(pctldev->dev, + "could not get request pin %d on device %s\n", + pins[i], pinctrl_dev_get_name(pctldev)); + /* On error release all taken pins */ + i--; /* this pin just failed */ + for (; i >= 0; i--) + pin_free(pctldev, pins[i], NULL); + return -ENODEV; + } } - list_add_tail(&grp->node, &p->groups); return 0; } -/** - * pinmux_apply_muxmap() - apply a certain mux mapping entry - */ -int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, - struct pinctrl *p, - struct device *dev, - const char *devname, - struct pinctrl_map const *map) +void pinmux_free_setting(struct pinctrl_setting const *setting) { + struct pinctrl_dev *pctldev = setting->pctldev; + const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; + const unsigned *pins; + unsigned num_pins; int ret; + int i; - ret = pinmux_enable_muxmap(pctldev, p, dev, - devname, map); + ret = pctlops->get_group_pins(pctldev, setting->group_selector, + &pins, &num_pins); if (ret) { - pinmux_put(p); - return ret; + dev_err(pctldev->dev, + "could not get pins for device %s group selector %d\n", + pinctrl_dev_get_name(pctldev), setting->group_selector); + return; } - return 0; -} - -/** - * pinmux_put() - free up the pinmux portions of a pin controller handle - */ -void pinmux_put(struct pinctrl *p) -{ - struct list_head *node, *tmp; - - list_for_each_safe(node, tmp, &p->groups) { - struct pinmux_group *grp = - list_entry(node, struct pinmux_group, node); - /* Release all pins taken by this group */ - release_pins(p->pctldev, grp->group_selector); - list_del(node); - kfree(grp); - } + for (i = 0; i < num_pins; i++) + pin_free(pctldev, pins[i], NULL); } -/** - * pinmux_enable() - enable the pinmux portion of a pin control handle - */ -int pinmux_enable(struct pinctrl *p) +int pinmux_enable_setting(struct pinctrl_setting const *setting) { - struct pinctrl_dev *pctldev = p->pctldev; + struct pinctrl_dev *pctldev = setting->pctldev; const struct pinmux_ops *ops = pctldev->desc->pmxops; - struct pinmux_group *grp; - int ret; - list_for_each_entry(grp, &p->groups, node) { - ret = ops->enable(pctldev, grp->func_selector, - grp->group_selector); - if (ret) - /* - * TODO: call disable() on all groups we called - * enable() on to this point? - */ - return ret; - } - return 0; + return ops->enable(pctldev, setting->func_selector, + setting->group_selector); } -/** - * pinmux_disable() - disable the pinmux portions of a pin control handle - */ -void pinmux_disable(struct pinctrl *p) +void pinmux_disable_setting(struct pinctrl_setting const *setting) { - struct pinctrl_dev *pctldev = p->pctldev; + struct pinctrl_dev *pctldev = setting->pctldev; const struct pinmux_ops *ops = pctldev->desc->pmxops; - struct pinmux_group *grp; - list_for_each_entry(grp, &p->groups, node) { - ops->disable(pctldev, grp->func_selector, - grp->group_selector); - } + ops->disable(pctldev, setting->func_selector, setting->group_selector); } #ifdef CONFIG_DEBUG_FS @@ -635,30 +441,18 @@ static int pinmux_pins_show(struct seq_file *s, void *what) return 0; } -void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p) +void pinmux_dbg_show(struct seq_file *s, struct pinctrl_setting const *setting) { - struct pinctrl_dev *pctldev = p->pctldev; - const struct pinmux_ops *pmxops; - const struct pinctrl_ops *pctlops; - struct pinmux_group *grp; - const char *sep = ""; - - pmxops = pctldev->desc->pmxops; - pctlops = pctldev->desc->pctlops; - - seq_printf(s, " groups: ["); - list_for_each_entry(grp, &p->groups, node) { - seq_printf(s, "%s%s (%u)=%s (%u)", - sep, - pctlops->get_group_name(pctldev, - grp->group_selector), - grp->group_selector, - pmxops->get_function_name(pctldev, - grp->func_selector), - grp->func_selector); - sep = ", "; - } - seq_printf(s, " ]"); + struct pinctrl_dev *pctldev = setting->pctldev; + const struct pinmux_ops *pmxops = pctldev->desc->pmxops; + const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; + + seq_printf(s, "controller: %s group: %s (%u) function: %s (%u)\n", + pinctrl_dev_get_name(pctldev), + pctlops->get_group_name(pctldev, setting->group_selector), + setting->group_selector, + pmxops->get_function_name(pctldev, setting->func_selector), + setting->func_selector); } static int pinmux_functions_open(struct inode *inode, struct file *file) diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h index 822febb..1500ae8 100644 --- a/drivers/pinctrl/pinmux.h +++ b/drivers/pinctrl/pinmux.h @@ -13,6 +13,7 @@ #ifdef CONFIG_PINMUX int pinmux_check_ops(struct pinctrl_dev *pctldev); + int pinmux_request_gpio(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned pin, unsigned gpio); @@ -21,21 +22,16 @@ void pinmux_free_gpio(struct pinctrl_dev *pctldev, unsigned pin, int pinmux_gpio_direction(struct pinctrl_dev *pctldev, struct pinctrl_gpio_range *range, unsigned pin, bool input); -static inline void pinmux_init_pinctrl_handle(struct pinctrl *p) -{ - INIT_LIST_HEAD(&p->groups); -} -int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, - struct pinctrl *p, - struct device *dev, - const char *devname, - struct pinctrl_map const *map); -void pinmux_put(struct pinctrl *p); -int pinmux_enable(struct pinctrl *p); -void pinmux_disable(struct pinctrl *p); + +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_dbg_show(struct seq_file *s, struct pinctrl_setting const *setting); void pinmux_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev); -void pinmux_dbg_show(struct seq_file *s, struct pinctrl *p); #else @@ -64,28 +60,23 @@ static inline int pinmux_gpio_direction(struct pinctrl_dev *pctldev, return 0; } -static inline void pinmux_init_pinctrl_handle(struct pinctrl *p) -{ -} - -static inline int pinmux_apply_muxmap(struct pinctrl_dev *pctldev, - struct pinctrl *p, - struct device *dev, - const char *devname, - struct pinctrl_map const *map) +static inline int pinmux_map_to_setting(struct pinctrl_map const *map, + struct pinctrl_setting *setting) { return 0; } -static inline void pinmux_put(struct pinctrl *p) +static inline void pinmux_free_setting(struct pinctrl_setting const *setting) { } -static inline int pinmux_enable(struct pinctrl *p) +static inline int pinmux_enable_setting(struct pinctrl_setting const *setting) { + return 0; } -static inline void pinmux_disable(struct pinctrl *p) +static inline void pinmux_disable_setting( + struct pinctrl_setting const *setting) { } -- cgit v0.10.2 From 0e3db173e2b9fd3b82246516e72c17763eb5f98d Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 2 Mar 2012 13:05:46 -0700 Subject: pinctrl: add usecount to pins for muxing Multiple mapping table entries could reference the same pin, and hence "own" it. This would be unusual now that pinctrl_get() represents a single state for a client device, but in the future when it represents all known states for a device, this is quite likely. Implement reference counting for pin ownership to handle this. Signed-off-by: Stephen Warren Acked-by: Dong Aisheng Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 5f258b7..0bc52ec 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -82,7 +82,14 @@ struct pinctrl_setting { * @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 - * @owner: the device holding this pin or NULL of no device has claimed it + * @usecount: If zero, the pin is not claimed, and @owner should be NULL. + * If non-zero, this pin is claimed by @owner. This field is an integer + * rather than a boolean, since pinctrl_get() might process multiple + * mapping table entries that refer to, and hence claim, the same group + * or pin, and each of these will increment the @usecount. + * @owner: The name of the entity owning the pin. Typically, this is the name + * of the device that called pinctrl_get(). Alternatively, it may be the + * name of the GPIO passed to pinctrl_request_gpio(). */ struct pin_desc { struct pinctrl_dev *pctldev; @@ -90,6 +97,7 @@ struct pin_desc { bool dynamic_name; /* These fields only added when supporting pinmux drivers */ #ifdef CONFIG_PINMUX + unsigned usecount; const char *owner; #endif }; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index f0fb98d..56ca42e 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -83,11 +83,16 @@ static int pin_request(struct pinctrl_dev *pctldev, goto out; } - if (desc->owner && strcmp(desc->owner, owner)) { + if (desc->usecount && strcmp(desc->owner, owner)) { dev_err(pctldev->dev, "pin already requested\n"); goto out; } + + desc->usecount++; + if (desc->usecount > 1) + return 0; + desc->owner = owner; /* Let each pin increase references to this module */ @@ -111,12 +116,18 @@ static int pin_request(struct pinctrl_dev *pctldev, else status = 0; - if (status) + if (status) { dev_err(pctldev->dev, "->request on device %s failed for pin %d\n", pctldev->desc->name, pin); + module_put(pctldev->owner); + } + out_free_pin: - if (status) - desc->owner = NULL; + if (status) { + desc->usecount--; + if (!desc->usecount) + desc->owner = NULL; + } out: if (status) dev_err(pctldev->dev, "pin-%d (%s) status %d\n", @@ -150,6 +161,10 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, return NULL; } + desc->usecount--; + if (desc->usecount) + return NULL; + /* * If there is no kind of request function for the pin we just assume * we got it by default and proceed. -- cgit v0.10.2 From 6e5e959dde0d92d177f035652aeaa77f9330c9c6 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 2 Mar 2012 13:05:47 -0700 Subject: pinctrl: API changes to support multiple states per device The API model is changed from: p = pinctrl_get(dev, "state1"); pinctrl_enable(p); ... pinctrl_disable(p); pinctrl_put(p); p = pinctrl_get(dev, "state2"); pinctrl_enable(p); ... pinctrl_disable(p); pinctrl_put(p); to this: p = pinctrl_get(dev); s1 = pinctrl_lookup_state(p, "state1"); s2 = pinctrl_lookup_state(p, "state2"); pinctrl_select_state(p, s1); ... pinctrl_select_state(p, s2); ... pinctrl_put(p); This allows devices to directly transition between states without disabling the pin controller programming and put()/get()ing the configuration data each time. This model will also better suit pinconf programming, which doesn't have a concept of "disable". The special-case hogging feature of pin controllers is re-written to use the regular APIs instead of special-case code. Hence, the pinmux-hogs debugfs file is removed; see the top-level pinctrl-handles files for equivalent data. Signed-off-by: Stephen Warren Acked-by: Dong Aisheng Signed-off-by: Linus Walleij diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 558aac5..23426c7 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -847,8 +847,8 @@ As it is possible to map a function to different groups of pins an optional 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: @@ -879,6 +879,7 @@ case), we define a mapping like this: .dev_name = "foo-mmc.0", .name = "8bit" .ctrl_dev_name = "pinctrl-foo", + .function = "mmc0", .group = "mmc0_1_grp", }, { @@ -900,10 +901,16 @@ case), we define a mapping like this: The result of grabbing this mapping from the device with something like this (see next paragraph): - p = pinctrl_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. @@ -925,45 +932,63 @@ default state like this: struct foo_state { struct pinctrl *p; + struct pinctrl_state *s; ... }; foo_probe() { - /* Allocate a state holder named "state" etc */ - struct pinctrl p; + /* Allocate a state holder named "foo" etc */ + struct foo_state *foo = ...; + + foo->p = pinctrl_get(&device); + if (IS_ERR(foo->p)) { + /* FIXME: clean up "foo" here */ + return PTR_ERR(foo->p); + } - p = pinctrl_get(&device, PINCTRL_STATE_DEFAULT); - if IS_ERR(p) - return PTR_ERR(p); - pinctrl_enable(p); + foo->s = pinctrl_lookup_state(foo->p, PINCTRL_STATE_DEFAULT); + if (IS_ERR(foo->s)) { + pinctrl_put(foo->p); + /* FIXME: clean up "foo" here */ + return PTR_ERR(s); + } - state->p = p; + ret = pinctrl_select_state(foo->s); + if (ret < 0) { + pinctrl_put(foo->p); + /* FIXME: clean up "foo" here */ + return ret; + } } foo_remove() { - pinctrl_disable(state->p); pinctrl_put(state->p); } -This get/enable/disable/put sequence can just as well be handled by bus drivers +This get/lookup/select/put sequence can just as well be handled by bus drivers if you don't want each and every driver to handle it and you know the arrangement on your bus. -The semantics of the get/enable respective disable/put is as follows: +The semantics of the pinctrl APIs are: + +- pinctrl_get() is called in process context to obtain a handle to all pinctrl + information for a given client device. It will allocate a struct from the + kernel memory to hold the pinmux state. All mapping table parsing or similar + slow operations take place within this API. -- pinctrl_get() is called in process context to reserve the pins affected with - a certain mapping and set up the pinmux core and the driver. It will allocate - a struct from the kernel memory to hold the pinmux state. +- pinctrl_lookup_state() is called in process context to obtain a handle to a + specific state for a the client device. This operation may be slow too. -- pinctrl_enable()/pinctrl_disable() is quick and can be called from fastpath - (irq context) when you quickly want to set up/tear down the hardware muxing - when running a device driver. Usually it will just poke some values into a - register. +- pinctrl_select_state() programs pin controller hardware according to the + definition of the state as given by the mapping table. In theory this is a + fast-path operation, since it only involved blasting some register settings + into hardware. However, note that some pin controllers may have their + registers on a slow/IRQ-based bus, so client devices should not assume they + can call pinctrl_select_state() from non-blocking contexts. -- pinctrl_disable() is called in process context to tear down the pin requests - and release the state holder struct for the mux setting etc. +- 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 @@ -979,12 +1004,12 @@ System pin control hogging ========================== 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() and -pinctrl_enable() on it immediately after the pin control device has been -registered. +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 .dev_name field in the map to the name -of the pin controller itself, 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. { .dev_name = "pinctrl-foo", @@ -1009,8 +1034,8 @@ 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: @@ -1020,23 +1045,36 @@ it, disables and releases it, and muxes it in on the pins defined by group B: foo_switch() { 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 */ - p = pinctrl_get(&device, "spi0-pos-A"); - if IS_ERR(p) - return PTR_ERR(p); - pinctrl_enable(p); + ret = pinctrl_select_state(s1); + if (ret < 0) + ... - /* This releases the pins again */ - pinctrl_disable(p); - pinctrl_put(p); + ... /* Enable on position B */ - p = pinctrl_get(&device, "spi0-pos-B"); - if IS_ERR(p) - return PTR_ERR(p); - pinctrl_enable(p); + ret = pinctrl_select_state(s2); + if (ret < 0) + ... + ... + + pinctrl_put(p); } The above has to be done from process context. diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index f29565a..c092cf9 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -1618,22 +1618,18 @@ static struct pinctrl_map __initdata u300_pinmux_map[] = { }; struct u300_mux_hog { - const char *name; struct device *dev; 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, }, }; @@ -1646,16 +1642,10 @@ static int __init u300_pinctrl_fetch(void) struct pinctrl *p; int ret; - p = pinctrl_get(u300_mux_hogs[i].dev, PINCTRL_STATE_DEFAULT); + p = pinctrl_get_select_default(u300_mux_hogs[i].dev); if (IS_ERR(p)) { - pr_err("u300: could not get pinmux hog %s\n", - u300_mux_hogs[i].name); - continue; - } - ret = pinctrl_enable(p); - if (ret) { - pr_err("u300: could enable pinmux hog %s\n", - u300_mux_hogs[i].name); + pr_err("u300: could not get pinmux hog for dev %s\n", + dev_name(u300_mux_hogs[i].dev)); continue; } u300_mux_hogs[i].p = p; diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 535f8d5..c6f3ca3 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -458,25 +458,98 @@ int pinctrl_gpio_direction_output(unsigned gpio) } EXPORT_SYMBOL_GPL(pinctrl_gpio_direction_output); -static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) +static struct pinctrl_state *find_state(struct pinctrl *p, + const char *name) { - struct pinctrl_dev *pctldev; - const char *devname; - struct pinctrl *p; - unsigned num_maps = 0; - int ret; - struct pinctrl_maps *maps_node; - int i; - struct pinctrl_map const *map; + struct pinctrl_state *state; + + list_for_each_entry(state, &p->states, node) + if (!strcmp(state->name, name)) + return state; + + return NULL; +} + +static struct pinctrl_state *create_state(struct pinctrl *p, + const char *name) +{ + struct pinctrl_state *state; + + state = kzalloc(sizeof(*state), GFP_KERNEL); + if (state == NULL) { + dev_err(p->dev, + "failed to alloc struct pinctrl_state\n"); + return ERR_PTR(-ENOMEM); + } + + state->name = name; + INIT_LIST_HEAD(&state->settings); + + list_add_tail(&state->node, &p->states); + + return state; +} + +static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) +{ + struct pinctrl_state *state; struct pinctrl_setting *setting; + int ret; - /* We must have both a dev and state name */ - if (WARN_ON(!dev || !name)) - return ERR_PTR(-EINVAL); + state = find_state(p, map->name); + if (!state) + state = create_state(p, map->name); + if (IS_ERR(state)) + return PTR_ERR(state); - devname = dev_name(dev); + setting = kzalloc(sizeof(*setting), GFP_KERNEL); + if (setting == NULL) { + dev_err(p->dev, + "failed to alloc struct pinctrl_setting\n"); + return -ENOMEM; + } - dev_dbg(dev, "pinctrl_get() for device %s state %s\n", devname, name); + setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); + if (setting->pctldev == NULL) { + dev_err(p->dev, "unknown pinctrl device %s in map entry", + map->ctrl_dev_name); + kfree(setting); + /* Eventually, this should trigger deferred probe */ + return -ENODEV; + } + + ret = pinmux_map_to_setting(map, setting); + if (ret < 0) { + kfree(setting); + return ret; + } + + list_add_tail(&setting->node, &state->settings); + + return 0; +} + +static struct pinctrl *find_pinctrl(struct device *dev) +{ + struct pinctrl *p; + + list_for_each_entry(p, &pinctrldev_list, node) + if (p->dev == dev) + return p; + + return NULL; +} + +static void pinctrl_put_locked(struct pinctrl *p, bool inlist); + +static struct pinctrl *create_pinctrl(struct device *dev) +{ + struct pinctrl *p; + const char *devname; + struct pinctrl_maps *maps_node; + int i; + struct pinctrl_map const *map; + int ret; /* * create the state cookie holder struct pinctrl for each @@ -489,8 +562,9 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) return ERR_PTR(-ENOMEM); } p->dev = dev; - p->state = name; - INIT_LIST_HEAD(&p->settings); + INIT_LIST_HEAD(&p->states); + + devname = dev_name(dev); /* Iterate over the pin control maps to locate the right ones */ for_each_maps(maps_node, i, map) { @@ -498,183 +572,179 @@ static struct pinctrl *pinctrl_get_locked(struct device *dev, const char *name) if (strcmp(map->dev_name, devname)) continue; - /* State name must be the one we're looking for */ - if (strcmp(map->name, name)) - continue; - - /* - * Try to find the pctldev given in the map - */ - pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); - if (!pctldev) { - dev_err(dev, "unknown pinctrl device %s in map entry", - map->ctrl_dev_name); - /* Eventually, this should trigger deferred probe */ - ret = -ENODEV; - goto error; - } - - dev_dbg(dev, "in map, found pctldev %s to handle function %s", - dev_name(pctldev->dev), map->function); - - setting = kzalloc(sizeof(*setting), GFP_KERNEL); - if (setting == NULL) { - dev_err(dev, - "failed to alloc struct pinctrl_setting\n"); - ret = -ENOMEM; - goto error; + ret = add_setting(p, map); + if (ret < 0) { + pinctrl_put_locked(p, false); + return ERR_PTR(ret); } - - setting->pctldev = pctldev; - ret = pinmux_map_to_setting(map, setting); - if (ret < 0) - goto error; - - list_add_tail(&setting->node, &p->settings); - - num_maps++; } - /* - * This may be perfectly legitimate. An IP block may get re-used - * across SoCs. Not all of those SoCs may need pinmux settings for the - * IP block, e.g. if one SoC dedicates pins to that function but - * another doesn't. The driver won't know this, and will always - * attempt to set up the pinmux. The mapping table defines whether any - * HW programming is actually needed. - */ - if (!num_maps) - dev_info(dev, "zero maps found for mapping %s\n", name); - - dev_dbg(dev, "found %u maps for device %s state %s\n", - num_maps, devname, name ? name : "(undefined)"); - /* Add the pinmux to the global list */ list_add_tail(&p->node, &pinctrl_list); return p; +} -error: - list_for_each_entry(setting, &p->settings, node) - pinmux_free_setting(setting); +static struct pinctrl *pinctrl_get_locked(struct device *dev) +{ + struct pinctrl *p; - kfree(p); + if (WARN_ON(!dev)) + return ERR_PTR(-EINVAL); + + p = find_pinctrl(dev); + if (p != NULL) + return ERR_PTR(-EBUSY); - return ERR_PTR(ret); + p = create_pinctrl(dev); + if (IS_ERR(p)) + return p; + + return p; } /** - * pinctrl_get() - retrieves the pin controller handle for a certain device - * @dev: the device to get the pin controller handle for - * @name: an optional specific control mapping name or NULL, the name is only - * needed if you want to have more than one mapping per device, or if you - * need an anonymous pin control (not tied to any specific device) + * pinctrl_get() - retrieves the pinctrl handle for a device + * @dev: the device to obtain the handle for */ -struct pinctrl *pinctrl_get(struct device *dev, const char *name) +struct pinctrl *pinctrl_get(struct device *dev) { struct pinctrl *p; mutex_lock(&pinctrl_mutex); - p = pinctrl_get_locked(dev, name); + p = pinctrl_get_locked(dev); mutex_unlock(&pinctrl_mutex); return p; } EXPORT_SYMBOL_GPL(pinctrl_get); -static void pinctrl_put_locked(struct pinctrl *p) +static void pinctrl_put_locked(struct pinctrl *p, bool inlist) { - struct pinctrl_setting *setting, *n; - - if (p == NULL) - return; - - if (p->usecount) - pr_warn("releasing pin control handle with active users!\n"); - list_for_each_entry_safe(setting, n, &p->settings, node) { - pinmux_free_setting(setting); - list_del(&setting->node); - kfree(setting); + struct pinctrl_state *state, *n1; + struct pinctrl_setting *setting, *n2; + + list_for_each_entry_safe(state, n1, &p->states, node) { + list_for_each_entry_safe(setting, n2, &state->settings, node) { + if (state == p->state) + pinmux_disable_setting(setting); + pinmux_free_setting(setting); + list_del(&setting->node); + kfree(setting); + } + list_del(&state->node); + kfree(state); } - /* Remove from list */ - list_del(&p->node); - + if (inlist) + list_del(&p->node); kfree(p); } /** - * pinctrl_put() - release a previously claimed pin control handle - * @p: a pin control handle previously claimed by pinctrl_get() + * pinctrl_put() - release a previously claimed pinctrl handle + * @p: the pinctrl handle to release */ void pinctrl_put(struct pinctrl *p) { mutex_lock(&pinctrl_mutex); - pinctrl_put(p); + pinctrl_put_locked(p, true); mutex_unlock(&pinctrl_mutex); } EXPORT_SYMBOL_GPL(pinctrl_put); -static int pinctrl_enable_locked(struct pinctrl *p) +static struct pinctrl_state *pinctrl_lookup_state_locked(struct pinctrl *p, + const char *name) { - struct pinctrl_setting *setting; - int ret; + struct pinctrl_state *state; - if (p == NULL) - return -EINVAL; + state = find_state(p, name); + if (!state) + return ERR_PTR(-ENODEV); - if (p->usecount++ == 0) { - list_for_each_entry(setting, &p->settings, node) { - ret = pinmux_enable_setting(setting); - if (ret < 0) { - /* FIXME: Difficult to return to prev state */ - p->usecount--; - return ret; - } - } - } - - return 0; + return state; } /** - * pinctrl_enable() - enable a certain pin controller setting - * @p: the pin control handle to enable, previously claimed by pinctrl_get() + * pinctrl_lookup_state() - retrieves a state handle from a pinctrl handle + * @p: the pinctrl handle to retrieve the state from + * @name: the state name to retrieve */ -int pinctrl_enable(struct pinctrl *p) +struct pinctrl_state *pinctrl_lookup_state(struct pinctrl *p, const char *name) { - int ret; + struct pinctrl_state *s; + mutex_lock(&pinctrl_mutex); - ret = pinctrl_enable_locked(p); + s = pinctrl_lookup_state_locked(p, name); mutex_unlock(&pinctrl_mutex); - return ret; + + return s; } -EXPORT_SYMBOL_GPL(pinctrl_enable); +EXPORT_SYMBOL_GPL(pinctrl_lookup_state); -static void pinctrl_disable_locked(struct pinctrl *p) +static int pinctrl_select_state_locked(struct pinctrl *p, + struct pinctrl_state *state) { - struct pinctrl_setting *setting; + struct pinctrl_setting *setting, *setting2; + int ret; - if (p == NULL) - return; + if (p->state == state) + return 0; - if (--p->usecount == 0) { - list_for_each_entry(setting, &p->settings, node) - pinmux_disable_setting(setting); + if (p->state) { + /* + * The set of groups with a mux configuration in the old state + * may not be identical to the set of groups with a mux setting + * in the new state. While this might be unusual, it's entirely + * possible for the "user"-supplied mapping table to be written + * that way. For each group that was configured in the old state + * but not in the new state, this code puts that group into a + * safe/disabled state. + */ + list_for_each_entry(setting, &p->state->settings, node) { + bool found = false; + list_for_each_entry(setting2, &state->settings, node) { + if (setting2->group_selector == + setting->group_selector) { + found = true; + break; + } + } + if (!found) + pinmux_disable_setting(setting); + } + } + + p->state = state; + + /* Apply all the settings for the new state */ + list_for_each_entry(setting, &state->settings, node) { + ret = pinmux_enable_setting(setting); + if (ret < 0) { + /* FIXME: Difficult to return to prev state */ + return ret; + } } + + return 0; } /** - * pinctrl_disable() - disable a certain pin control setting - * @p: the pin control handle to disable, previously claimed by pinctrl_get() + * pinctrl_select() - select/activate/program a pinctrl state to HW + * @p: the pinctrl handle for the device that requests configuratio + * @state: the state handle to select/activate/program */ -void pinctrl_disable(struct pinctrl *p) +int pinctrl_select_state(struct pinctrl *p, struct pinctrl_state *state) { + int ret; + mutex_lock(&pinctrl_mutex); - pinctrl_disable_locked(p); + ret = pinctrl_select_state_locked(p, state); mutex_unlock(&pinctrl_mutex); + + return ret; } -EXPORT_SYMBOL_GPL(pinctrl_disable); +EXPORT_SYMBOL_GPL(pinctrl_select_state); /** * pinctrl_register_mappings() - register a set of pin controller mappings @@ -891,6 +961,7 @@ static int pinctrl_maps_show(struct seq_file *s, void *what) static int pinctrl_show(struct seq_file *s, void *what) { struct pinctrl *p; + struct pinctrl_state *state; struct pinctrl_setting *setting; seq_puts(s, "Requested pin control handlers their pinmux maps:\n"); @@ -898,12 +969,17 @@ static int pinctrl_show(struct seq_file *s, void *what) mutex_lock(&pinctrl_mutex); list_for_each_entry(p, &pinctrl_list, node) { - seq_printf(s, "device: %s state: %s users: %u\n", - dev_name(p->dev), p->state, p->usecount); + seq_printf(s, "device: %s current state: %s\n", + dev_name(p->dev), + p->state ? p->state->name : "none"); + + list_for_each_entry(state, &p->states, node) { + seq_printf(s, " state: %s\n", state->name); - list_for_each_entry(setting, &p->settings, node) { - seq_printf(s, " "); - pinmux_dbg_show(s, setting); + list_for_each_entry(setting, &state->settings, node) { + seq_printf(s, " "); + pinmux_dbg_show(s, setting); + } } } @@ -1113,9 +1189,14 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, list_add_tail(&pctldev->node, &pinctrldev_list); - pctldev->p = pinctrl_get_locked(pctldev->dev, PINCTRL_STATE_DEFAULT); - if (!IS_ERR(pctldev->p)) - pinctrl_enable_locked(pctldev->p); + pctldev->p = pinctrl_get_locked(pctldev->dev); + if (!IS_ERR(pctldev->p)) { + struct pinctrl_state *s = + pinctrl_lookup_state_locked(pctldev->p, + PINCTRL_STATE_DEFAULT); + if (!IS_ERR(s)) + pinctrl_select_state_locked(pctldev->p, s); + } mutex_unlock(&pinctrl_mutex); @@ -1144,10 +1225,8 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) mutex_lock(&pinctrl_mutex); - if (!IS_ERR(pctldev->p)) { - pinctrl_disable_locked(pctldev->p); - pinctrl_put_locked(pctldev->p); - } + if (!IS_ERR(pctldev->p)) + pinctrl_put_locked(pctldev->p, true); /* TODO: check that no pinmuxes are still active? */ list_del(&pctldev->node); diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 0bc52ec..5691d31 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -49,22 +49,31 @@ struct pinctrl_dev { * struct pinctrl - per-device pin control state holder * @node: global list node * @dev: the device using this pin control handle - * @state: the state name passed to pinctrl_get() - * @usecount: the number of active users of this pin controller setting, used - * to keep track of nested use cases - * @settings: a list of settings for this device/state + * @states: a list of states for this device + * @state: the current state */ struct pinctrl { struct list_head node; struct device *dev; - const char *state; - unsigned usecount; + 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 - an individual mux setting - * @node: list node for struct pinctrl's @settings field + * @node: list node for struct pinctrl_settings's @settings field * @pctldev: pin control device handling to be programmed * @group_selector: the group selector to program * @func_selector: the function selector to program diff --git a/drivers/tty/serial/sirfsoc_uart.c b/drivers/tty/serial/sirfsoc_uart.c index 3cabb65..5b3eda2 100644 --- a/drivers/tty/serial/sirfsoc_uart.c +++ b/drivers/tty/serial/sirfsoc_uart.c @@ -673,12 +673,10 @@ int sirfsoc_uart_probe(struct platform_device *pdev) port->irq = res->start; if (sirfport->hw_flow_ctrl) { - sirfport->p = pinctrl_get(&pdev->dev, PINCTRL_STATE_DEFAULT); + sirfport->p = pinctrl_get_select_default(&pdev->dev); ret = IS_ERR(sirfport->p); if (ret) goto pin_err; - - pinctrl_enable(sirfport->p); } port->ops = &sirfsoc_uart_ops; @@ -695,10 +693,8 @@ int sirfsoc_uart_probe(struct platform_device *pdev) port_err: platform_set_drvdata(pdev, NULL); - if (sirfport->hw_flow_ctrl) { - pinctrl_disable(sirfport->p); + if (sirfport->hw_flow_ctrl) pinctrl_put(sirfport->p); - } pin_err: irq_err: devm_iounmap(&pdev->dev, port->membase); @@ -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) { - pinctrl_disable(sirfport->p); + if (sirfport->hw_flow_ctrl) pinctrl_put(sirfport->p); - } devm_iounmap(&pdev->dev, port->membase); uart_remove_one_port(&sirfsoc_uart_drv, port); return 0; diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h index 3086594..9ad5896 100644 --- a/include/linux/pinctrl/consumer.h +++ b/include/linux/pinctrl/consumer.h @@ -12,12 +12,14 @@ #ifndef __LINUX_PINCTRL_CONSUMER_H #define __LINUX_PINCTRL_CONSUMER_H +#include #include #include #include "pinctrl.h" /* This struct is private to the core and should be regarded as a cookie */ struct pinctrl; +struct pinctrl_state; #ifdef CONFIG_PINCTRL @@ -26,10 +28,13 @@ 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, const char *name); + +extern struct pinctrl * __must_check pinctrl_get(struct device *dev); extern void pinctrl_put(struct pinctrl *p); -extern int pinctrl_enable(struct pinctrl *p); -extern void pinctrl_disable(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 */ @@ -52,7 +57,7 @@ static inline int pinctrl_gpio_direction_output(unsigned gpio) return 0; } -static inline struct pinctrl * __must_check pinctrl_get(struct device *dev, const char *name) +static inline struct pinctrl * __must_check pinctrl_get(struct device *dev) { return NULL; } @@ -61,17 +66,53 @@ static inline void pinctrl_put(struct pinctrl *p) { } -static inline int pinctrl_enable(struct pinctrl *p) +static inline struct pinctrl_state * __must_check pinctrl_lookup_state( + struct pinctrl *p, + const char *name) { - return 0; + return NULL; } -static inline void pinctrl_disable(struct pinctrl *p) +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, diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index 20e9735..05d25c8 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -21,23 +21,22 @@ * same name as the pin controllers own dev_name(), the map entry will be * hogged by the driver itself upon registration * @name: the name of this specific map entry for the particular machine. - * This is the second parameter passed to pinmux_get() when you want - * to have several mappings to the same device + * This is the parameter passed to pinmux_lookup_state() * @ctrl_dev_name: the name of the device controlling this specific mapping, * the name must be the same as in your struct device* - * @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 + * @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 */ struct pinctrl_map { const char *dev_name; const char *name; const char *ctrl_dev_name; - const char *function; const char *group; + const char *function; }; /* -- cgit v0.10.2 From 1e2082b520721734c358f776d34a069867214c8e Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 2 Mar 2012 13:05:48 -0700 Subject: pinctrl: enhance mapping table to support pin config operations The pinctrl mapping table can now contain entries to: * Set the mux function of a pin group * Apply a set of pin config options to a pin or a group This allows pinctrl_select_state() to apply pin configs settings as well as mux settings. v3: Fix find_pinctrl() to iterate over the correct list. s/_MUX_CONFIGS_/_CONFIGS_/ in mapping table macros. Fix documentation to use correct mapping table macro. v2: Added numerous extra PIN_MAP_*() special-case macros. Fixed kerneldoc typo. Delete pinctrl_get_pin_id() and replace it with pin_get_from_name(). Various minor fixes. Updates due to rebase. Signed-off-by: Stephen Warren Acked-by: Dong Aisheng Signed-off-by: Linus Walleij diff --git a/Documentation/pinctrl.txt b/Documentation/pinctrl.txt index 23426c7..d97bccf 100644 --- a/Documentation/pinctrl.txt +++ b/Documentation/pinctrl.txt @@ -206,14 +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 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 #include @@ -765,7 +772,7 @@ 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 @@ -773,9 +780,9 @@ 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 @@ -783,20 +790,23 @@ static const struct pinctrl_map __initdata mapping[] = { { .dev_name = "foo-spi.0", .name = PINCTRL_STATE_DEFAULT, + .type = PIN_MAP_TYPE_MUX_GROUP, .ctrl_dev_name = "pinctrl-foo", - .function = "spi0", + .data.mux.function = "spi0", }, { .dev_name = "foo-i2c.0", .name = PINCTRL_STATE_DEFAULT, + .type = PIN_MAP_TYPE_MUX_GROUP, .ctrl_dev_name = "pinctrl-foo", - .function = "i2c0", + .data.mux.function = "i2c0", }, { .dev_name = "foo-mmc.0", .name = PINCTRL_STATE_DEFAULT, + .type = PIN_MAP_TYPE_MUX_GROUP, .ctrl_dev_name = "pinctrl-foo", - .function = "mmc0", + .data.mux.function = "mmc0", }, }; @@ -817,7 +827,40 @@ it even more compact which assumes you want to use pinctrl-foo and position 0 for mapping, for example: static struct pinctrl_map __initdata mapping[] = { - PIN_MAP(PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", "foo-i2c.0"), + PIN_MAP_MUX_GROUP("foo-i2c.o", PINCTRL_STATE_DEFAULT, "pinctrl-foo", NULL, "i2c0"), +}; + +The mapping table may also contain pin configuration entries. It's common for +each pin/group to have a number of configuration entries that affect it, so +the table entries for configuration reference an array of config parameters +and values. An example using the convenience macros is shown below: + +static unsigned long i2c_grp_configs[] = { + FOO_PIN_DRIVEN, + FOO_PIN_PULLUP, +}; + +static unsigned long i2c_pin_configs[] = { + FOO_OPEN_COLLECTOR, + FOO_SLEW_RATE_SLOW, +}; + +static struct pinctrl_map __initdata mapping[] = { + PIN_MAP_MUX_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", "i2c0"), + PIN_MAP_MUX_CONFIGS_GROUP("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0", i2c_grp_configs), + PIN_MAP_MUX_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0scl", i2c_pin_configs), + PIN_MAP_MUX_CONFIGS_PIN("foo-i2c.0", PINCTRL_STATE_DEFAULT, "pinctrl-foo", "i2c0sda", i2c_pin_configs), +}; + +Finally, some devices expect the mapping table to contain certain specific +named states. When running on hardware that doesn't need any pin controller +configuration, the mapping table must still contain those named states, in +order to explicitly indicate that the states were provided and intended to +be empty. Table entry macro PIN_MAP_DUMMY_STATE serves the purpose of defining +a named state without causing any pin controller to be programmed: + +static struct pinctrl_map __initdata mapping[] = { + PIN_MAP_DUMMY_STATE("foo-i2c.0", PINCTRL_STATE_DEFAULT), }; @@ -831,6 +874,7 @@ 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", @@ -838,6 +882,7 @@ As it is possible to map a function to different groups of pins an optional { .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", @@ -857,6 +902,7 @@ 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", @@ -864,6 +910,7 @@ case), we define a mapping like this: { .dev_name = "foo-mmc.0", .name = "4bit" + .type = PIN_MAP_TYPE_MUX_GROUP, .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_1_grp", @@ -871,6 +918,7 @@ case), we define a mapping like this: { .dev_name = "foo-mmc.0", .name = "4bit" + .type = PIN_MAP_TYPE_MUX_GROUP, .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_2_grp", @@ -878,6 +926,7 @@ case), we define a mapping like this: { .dev_name = "foo-mmc.0", .name = "8bit" + .type = PIN_MAP_TYPE_MUX_GROUP, .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_1_grp", @@ -885,6 +934,7 @@ case), we define a mapping like this: { .dev_name = "foo-mmc.0", .name = "8bit" + .type = PIN_MAP_TYPE_MUX_GROUP, .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_2_grp", @@ -892,6 +942,7 @@ case), we define a mapping like this: { .dev_name = "foo-mmc.0", .name = "8bit" + .type = PIN_MAP_TYPE_MUX_GROUP, .ctrl_dev_name = "pinctrl-foo", .function = "mmc0", .group = "mmc0_3_grp", @@ -1014,6 +1065,7 @@ to the pin controller device name, and the state name is PINCTRL_STATE_DEFAULT. { .dev_name = "pinctrl-foo", .name = PINCTRL_STATE_DEFAULT, + .type = PIN_MAP_TYPE_MUX_GROUP, .ctrl_dev_name = "pinctrl-foo", .function = "power_func", }, @@ -1022,7 +1074,7 @@ 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: -PIN_MAP_SYS_HOG("pinctrl-foo", "power_func") +PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-foo", NULL /* group */, "power_func") This gives the exact same result as the above construction. diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index c092cf9..f326d31 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -1608,13 +1608,13 @@ static struct platform_device dma_device = { /* Pinmux settings */ static struct pinctrl_map __initdata u300_pinmux_map[] = { /* anonymous maps for chip power and EMIFs */ - PIN_MAP_SYS_HOG("pinctrl-u300", "power"), - PIN_MAP_SYS_HOG("pinctrl-u300", "emif0"), - PIN_MAP_SYS_HOG("pinctrl-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 */ - PIN_MAP(PINCTRL_STATE_DEFAULT, "pinctrl-u300", "mmc0", "mmci"), - PIN_MAP(PINCTRL_STATE_DEFAULT, "pinctrl-u300", "spi0", "pl022"), - PIN_MAP(PINCTRL_STATE_DEFAULT, "pinctrl-u300", "uart0", "uart0"), + PIN_MAP_MUX_GROUP_DEFAULT("mmci", "pinctrl-u300", NULL, "mmc0"), + PIN_MAP_MUX_GROUP_DEFAULT("pl022", "pinctrl-u300", NULL, "spi0"), + PIN_MAP_MUX_GROUP_DEFAULT("uart0", "pinctrl-u300", NULL, "uart0"), }; struct u300_mux_hog { diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index c6f3ca3..ec3b8cc 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -502,6 +502,9 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) if (IS_ERR(state)) return PTR_ERR(state); + if (map->type == PIN_MAP_TYPE_DUMMY_STATE) + return 0; + setting = kzalloc(sizeof(*setting), GFP_KERNEL); if (setting == NULL) { dev_err(p->dev, @@ -509,6 +512,8 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) return -ENOMEM; } + setting->type = map->type; + setting->pctldev = get_pinctrl_dev_from_devname(map->ctrl_dev_name); if (setting->pctldev == NULL) { dev_err(p->dev, "unknown pinctrl device %s in map entry", @@ -518,7 +523,18 @@ static int add_setting(struct pinctrl *p, struct pinctrl_map const *map) return -ENODEV; } - ret = pinmux_map_to_setting(map, setting); + switch (map->type) { + case PIN_MAP_TYPE_MUX_GROUP: + ret = pinmux_map_to_setting(map, setting); + break; + case PIN_MAP_TYPE_CONFIGS_PIN: + case PIN_MAP_TYPE_CONFIGS_GROUP: + ret = pinconf_map_to_setting(map, setting); + break; + default: + ret = -EINVAL; + break; + } if (ret < 0) { kfree(setting); return ret; @@ -533,7 +549,7 @@ static struct pinctrl *find_pinctrl(struct device *dev) { struct pinctrl *p; - list_for_each_entry(p, &pinctrldev_list, node) + list_for_each_entry(p, &pinctrl_list, node) if (p->dev == dev) return p; @@ -626,9 +642,19 @@ static void pinctrl_put_locked(struct pinctrl *p, bool inlist) list_for_each_entry_safe(state, n1, &p->states, node) { list_for_each_entry_safe(setting, n2, &state->settings, node) { - if (state == p->state) - pinmux_disable_setting(setting); - pinmux_free_setting(setting); + switch (setting->type) { + case PIN_MAP_TYPE_MUX_GROUP: + if (state == p->state) + pinmux_disable_setting(setting); + pinmux_free_setting(setting); + break; + case PIN_MAP_TYPE_CONFIGS_PIN: + case PIN_MAP_TYPE_CONFIGS_GROUP: + pinconf_free_setting(setting); + break; + default: + break; + } list_del(&setting->node); kfree(setting); } @@ -703,9 +729,13 @@ static int pinctrl_select_state_locked(struct pinctrl *p, */ list_for_each_entry(setting, &p->state->settings, node) { bool found = false; + if (setting->type != PIN_MAP_TYPE_MUX_GROUP) + continue; list_for_each_entry(setting2, &state->settings, node) { - if (setting2->group_selector == - setting->group_selector) { + if (setting2->type != PIN_MAP_TYPE_MUX_GROUP) + continue; + if (setting2->data.mux.group == + setting->data.mux.group) { found = true; break; } @@ -719,7 +749,18 @@ static int pinctrl_select_state_locked(struct pinctrl *p, /* Apply all the settings for the new state */ list_for_each_entry(setting, &state->settings, node) { - ret = pinmux_enable_setting(setting); + switch (setting->type) { + case PIN_MAP_TYPE_MUX_GROUP: + ret = pinmux_enable_setting(setting); + break; + case PIN_MAP_TYPE_CONFIGS_PIN: + case PIN_MAP_TYPE_CONFIGS_GROUP: + ret = pinconf_apply_setting(setting); + break; + default: + ret = -EINVAL; + break; + } if (ret < 0) { /* FIXME: Difficult to return to prev state */ return ret; @@ -756,33 +797,48 @@ EXPORT_SYMBOL_GPL(pinctrl_select_state); int pinctrl_register_mappings(struct pinctrl_map const *maps, unsigned num_maps) { - int i; + int i, ret; struct pinctrl_maps *maps_node; pr_debug("add %d pinmux maps\n", num_maps); /* First sanity check the new mapping */ for (i = 0; i < num_maps; i++) { + if (!maps[i].dev_name) { + pr_err("failed to register map %s (%d): no device given\n", + maps[i].name, i); + return -EINVAL; + } + if (!maps[i].name) { pr_err("failed to register map %d: no map name given\n", i); return -EINVAL; } - if (!maps[i].ctrl_dev_name) { + if (maps[i].type != PIN_MAP_TYPE_DUMMY_STATE && + !maps[i].ctrl_dev_name) { pr_err("failed to register map %s (%d): no pin control device given\n", maps[i].name, i); return -EINVAL; } - if (!maps[i].function) { - pr_err("failed to register map %s (%d): no function ID given\n", - maps[i].name, i); - return -EINVAL; - } - - if (!maps[i].dev_name) { - pr_err("failed to register map %s (%d): no device given\n", + switch (maps[i].type) { + case PIN_MAP_TYPE_DUMMY_STATE: + break; + case PIN_MAP_TYPE_MUX_GROUP: + ret = pinmux_validate_map(&maps[i], i); + if (ret < 0) + return 0; + break; + case PIN_MAP_TYPE_CONFIGS_PIN: + case PIN_MAP_TYPE_CONFIGS_GROUP: + ret = pinconf_validate_map(&maps[i], i); + if (ret < 0) + return 0; + break; + default: + pr_err("failed to register map %s (%d): invalid type given\n", maps[i].name, i); return -EINVAL; } @@ -934,6 +990,22 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) return 0; } +static inline const char *map_type(enum pinctrl_map_type type) +{ + static const char * const names[] = { + "INVALID", + "DUMMY_STATE", + "MUX_GROUP", + "CONFIGS_PIN", + "CONFIGS_GROUP", + }; + + if (type >= ARRAY_SIZE(names)) + return "UNKNOWN"; + + return names[type]; +} + static int pinctrl_maps_show(struct seq_file *s, void *what) { struct pinctrl_maps *maps_node; @@ -945,12 +1017,27 @@ static int pinctrl_maps_show(struct seq_file *s, void *what) mutex_lock(&pinctrl_mutex); for_each_maps(maps_node, i, map) { - seq_printf(s, "%s:\n", map->name); - seq_printf(s, " device: %s\n", map->dev_name); - seq_printf(s, " controlling device %s\n", map->ctrl_dev_name); - seq_printf(s, " function: %s\n", map->function); - seq_printf(s, " group: %s\n", map->group ? map->group : - "(default)"); + seq_printf(s, "device %s\nstate %s\ntype %s (%d)\n", + map->dev_name, map->name, map_type(map->type), + map->type); + + if (map->type != PIN_MAP_TYPE_DUMMY_STATE) + seq_printf(s, "controlling device %s\n", + map->ctrl_dev_name); + + switch (map->type) { + case PIN_MAP_TYPE_MUX_GROUP: + pinmux_show_map(s, map); + break; + case PIN_MAP_TYPE_CONFIGS_PIN: + case PIN_MAP_TYPE_CONFIGS_GROUP: + pinconf_show_map(s, map); + break; + default: + break; + } + + seq_printf(s, "\n"); } mutex_unlock(&pinctrl_mutex); @@ -977,8 +1064,23 @@ static int pinctrl_show(struct seq_file *s, void *what) seq_printf(s, " state: %s\n", state->name); list_for_each_entry(setting, &state->settings, node) { - seq_printf(s, " "); - pinmux_dbg_show(s, setting); + struct pinctrl_dev *pctldev = setting->pctldev; + + seq_printf(s, " type: %s controller %s ", + map_type(setting->type), + pinctrl_dev_get_name(pctldev)); + + switch (setting->type) { + case PIN_MAP_TYPE_MUX_GROUP: + pinmux_show_setting(s, setting); + break; + case PIN_MAP_TYPE_CONFIGS_PIN: + case PIN_MAP_TYPE_CONFIGS_GROUP: + pinconf_show_setting(s, setting); + break; + default: + break; + } } } } diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 5691d31..1cae372 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -72,17 +72,44 @@ struct pinctrl_state { }; /** + * 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 setting * @node: list node for struct pinctrl_settings's @settings field + * @type: the type of setting * @pctldev: pin control device handling to be programmed - * @group_selector: the group selector to program - * @func_selector: the function selector to program + * @data: Data specific to the setting type */ struct pinctrl_setting { struct list_head node; + enum pinctrl_map_type type; struct pinctrl_dev *pctldev; - unsigned group_selector; - unsigned func_selector; + union { + struct pinctrl_setting_mux mux; + struct pinctrl_setting_configs configs; + } data; }; /** diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index e0a4537..84869f2 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -36,6 +36,24 @@ int pinconf_check_ops(struct pinctrl_dev *pctldev) return 0; } +int pinconf_validate_map(struct pinctrl_map const *map, int i) +{ + if (!map->data.configs.group_or_pin) { + pr_err("failed to register map %s (%d): no group/pin given\n", + map->name, i); + return -EINVAL; + } + + if (map->data.configs.num_configs && + !map->data.configs.configs) { + pr_err("failed to register map %s (%d): no configs ptr given\n", + map->name, i); + return -EINVAL; + } + + return 0; +} + static int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, unsigned long *config) { @@ -260,8 +278,155 @@ unlock: } 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; + + switch (setting->type) { + case PIN_MAP_TYPE_CONFIGS_PIN: + setting->data.configs.group_or_pin = + pin_get_from_name(pctldev, + map->data.configs.group_or_pin); + if (setting->data.configs.group_or_pin < 0) + return setting->data.configs.group_or_pin; + break; + case PIN_MAP_TYPE_CONFIGS_GROUP: + setting->data.configs.group_or_pin = + pinctrl_get_group_selector(pctldev, + map->data.configs.group_or_pin); + if (setting->data.configs.group_or_pin < 0) + return setting->data.configs.group_or_pin; + break; + default: + return -EINVAL; + } + + setting->data.configs.num_configs = map->data.configs.num_configs; + setting->data.configs.configs = map->data.configs.configs; + + return 0; +} + +void pinconf_free_setting(struct pinctrl_setting const *setting) +{ +} + +int pinconf_apply_setting(struct pinctrl_setting const *setting) +{ + struct pinctrl_dev *pctldev = setting->pctldev; + const struct pinconf_ops *ops = pctldev->desc->confops; + int i, ret; + + 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; +} + #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) { diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h index 1d6ea9d..0ded227 100644 --- a/drivers/pinctrl/pinconf.h +++ b/drivers/pinctrl/pinconf.h @@ -15,6 +15,16 @@ 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); @@ -25,6 +35,36 @@ static inline int pinconf_check_ops(struct pinctrl_dev *pctldev) return 0; } +static inline int pinconf_validate_map(struct pinctrl_map const *map, int i) +{ + return 0; +} + +static inline int pinconf_map_to_setting(struct pinctrl_map const *map, + struct pinctrl_setting *setting) +{ + return 0; +} + +static inline void pinconf_free_setting(struct pinctrl_setting const *setting) +{ +} + +static inline int pinconf_apply_setting(struct pinctrl_setting const *setting) +{ + return 0; +} + +static inline void pinconf_show_map(struct seq_file *s, + struct pinctrl_map const *map) +{ +} + +static inline void pinconf_show_setting(struct seq_file *s, + struct pinctrl_setting const *setting) +{ +} + static inline void pinconf_init_device_debugfs(struct dentry *devroot, struct pinctrl_dev *pctldev) { diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 56ca42e..4852ebe 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -58,6 +58,17 @@ int pinmux_check_ops(struct pinctrl_dev *pctldev) return 0; } +int pinmux_validate_map(struct pinctrl_map const *map, int i) +{ + if (!map->data.mux.function) { + pr_err("failed to register map %s (%d): no function given\n", + map->name, i); + return -EINVAL; + } + + return 0; +} + /** * pin_request() - request a single pin to be muxed in, typically for GPIO * @pin: the pin number in the global pin space @@ -284,21 +295,21 @@ int pinmux_map_to_setting(struct pinctrl_map const *map, const unsigned *pins; unsigned num_pins; - setting->func_selector = - pinmux_func_name_to_selector(pctldev, map->function); - if (setting->func_selector < 0) - return setting->func_selector; + setting->data.mux.func = + pinmux_func_name_to_selector(pctldev, map->data.mux.function); + if (setting->data.mux.func < 0) + return setting->data.mux.func; - ret = pmxops->get_function_groups(pctldev, setting->func_selector, + ret = pmxops->get_function_groups(pctldev, setting->data.mux.func, &groups, &num_groups); if (ret < 0) return ret; if (!num_groups) return -EINVAL; - if (map->group) { + if (map->data.mux.group) { bool found = false; - group = map->group; + group = map->data.mux.group; for (i = 0; i < num_groups; i++) { if (!strcmp(group, groups[i])) { found = true; @@ -311,17 +322,16 @@ int pinmux_map_to_setting(struct pinctrl_map const *map, group = groups[0]; } - setting->group_selector = - pinctrl_get_group_selector(pctldev, group); - if (setting->group_selector < 0) - return setting->group_selector; + setting->data.mux.group = pinctrl_get_group_selector(pctldev, group); + if (setting->data.mux.group < 0) + return setting->data.mux.group; - ret = pctlops->get_group_pins(pctldev, setting->group_selector, - &pins, &num_pins); + ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, &pins, + &num_pins); if (ret) { dev_err(pctldev->dev, "could not get pins for device %s group selector %d\n", - pinctrl_dev_get_name(pctldev), setting->group_selector); + pinctrl_dev_get_name(pctldev), setting->data.mux.group); return -ENODEV; } @@ -352,12 +362,12 @@ void pinmux_free_setting(struct pinctrl_setting const *setting) int ret; int i; - ret = pctlops->get_group_pins(pctldev, setting->group_selector, + ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, &pins, &num_pins); if (ret) { dev_err(pctldev->dev, "could not get pins for device %s group selector %d\n", - pinctrl_dev_get_name(pctldev), setting->group_selector); + pinctrl_dev_get_name(pctldev), setting->data.mux.group); return; } @@ -370,8 +380,8 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting) struct pinctrl_dev *pctldev = setting->pctldev; const struct pinmux_ops *ops = pctldev->desc->pmxops; - return ops->enable(pctldev, setting->func_selector, - setting->group_selector); + return ops->enable(pctldev, setting->data.mux.func, + setting->data.mux.group); } void pinmux_disable_setting(struct pinctrl_setting const *setting) @@ -379,7 +389,7 @@ void pinmux_disable_setting(struct pinctrl_setting const *setting) struct pinctrl_dev *pctldev = setting->pctldev; const struct pinmux_ops *ops = pctldev->desc->pmxops; - ops->disable(pctldev, setting->func_selector, setting->group_selector); + ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group); } #ifdef CONFIG_DEBUG_FS @@ -456,18 +466,25 @@ static int pinmux_pins_show(struct seq_file *s, void *what) return 0; } -void pinmux_dbg_show(struct seq_file *s, struct pinctrl_setting const *setting) +void pinmux_show_map(struct seq_file *s, struct pinctrl_map const *map) +{ + seq_printf(s, "group %s\nfunction %s\n", + map->data.mux.group ? map->data.mux.group : "(default)", + map->data.mux.function); +} + +void pinmux_show_setting(struct seq_file *s, + struct pinctrl_setting const *setting) { struct pinctrl_dev *pctldev = setting->pctldev; const struct pinmux_ops *pmxops = pctldev->desc->pmxops; const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; - seq_printf(s, "controller: %s group: %s (%u) function: %s (%u)\n", - pinctrl_dev_get_name(pctldev), - pctlops->get_group_name(pctldev, setting->group_selector), - setting->group_selector, - pmxops->get_function_name(pctldev, setting->func_selector), - setting->func_selector); + seq_printf(s, "group: %s (%u) function: %s (%u)\n", + pctlops->get_group_name(pctldev, setting->data.mux.group), + setting->data.mux.group, + pmxops->get_function_name(pctldev, setting->data.mux.func), + setting->data.mux.func); } static int pinmux_functions_open(struct inode *inode, struct file *file) diff --git a/drivers/pinctrl/pinmux.h b/drivers/pinctrl/pinmux.h index 1500ae8..6fc4700 100644 --- a/drivers/pinctrl/pinmux.h +++ b/drivers/pinctrl/pinmux.h @@ -14,6 +14,8 @@ 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); @@ -29,7 +31,9 @@ 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_dbg_show(struct seq_file *s, 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); @@ -40,6 +44,11 @@ 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) @@ -80,12 +89,18 @@ static inline void pinmux_disable_setting( { } -static inline void pinmux_init_device_debugfs(struct dentry *devroot, - struct pinctrl_dev *pctldev) +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_dbg_show(struct seq_file *s, struct pinctrl *p) +static inline void pinmux_init_device_debugfs(struct dentry *devroot, + struct pinctrl_dev *pctldev) { } diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index 05d25c8..3fd2f9d 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -14,6 +14,41 @@ #include "pinctrl.h" +enum pinctrl_map_type { + PIN_MAP_TYPE_INVALID, + PIN_MAP_TYPE_DUMMY_STATE, + PIN_MAP_TYPE_MUX_GROUP, + PIN_MAP_TYPE_CONFIGS_PIN, + PIN_MAP_TYPE_CONFIGS_GROUP, +}; + +/** + * struct pinctrl_map_mux - mapping table content for MAP_TYPE_MUX_GROUP + * @group: the name of the group whose mux function is to be configured. This + * field may be left NULL, and the first applicable group for the function + * will be used. + * @function: the mux function to select for the group + */ +struct pinctrl_map_mux { + const char *group; + const char *function; +}; + +/** + * struct pinctrl_map_configs - mapping table content for MAP_TYPE_CONFIGS_* + * @group_or_pin: the name of the pin or group whose configuration parameters + * are to be configured. + * @configs: a pointer to an array of config parameters/values to program into + * hardware. Each individual pin controller defines the format and meaning + * of config parameters. + * @num_configs: the number of entries in array @configs + */ +struct pinctrl_map_configs { + const char *group_or_pin; + unsigned long *configs; + unsigned num_configs; +}; + /** * struct pinctrl_map - boards/machines shall provide this map for devices * @dev_name: the name of the device using this specific mapping, the name @@ -22,46 +57,96 @@ * 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* - * @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 - * @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 + * the name must be the same as in your struct device*. This field is not + * used for PIN_MAP_TYPE_DUMMY_STATE + * @data: Data specific to the mapping type */ struct pinctrl_map { const char *dev_name; const char *name; + enum pinctrl_map_type type; const char *ctrl_dev_name; - const char *group; - const char *function; + union { + struct pinctrl_map_mux mux; + struct pinctrl_map_configs configs; + } data; }; -/* - * Convenience macro to set a simple map from a certain pin controller and a - * certain function to a named device - */ -#define PIN_MAP(a, b, c, d) \ - { .name = a, .ctrl_dev_name = b, .function = c, .dev_name = d } +/* Convenience macros to create mapping table entries */ -/* - * Convenience macro to map a system function onto a certain pinctrl device, - * to be hogged by the pin control core until the system shuts down. - */ -#define PIN_MAP_SYS_HOG(a, b) \ - { .name = PINCTRL_STATE_DEFAULT, .ctrl_dev_name = a, .dev_name = a, \ - .function = b, } +#define PIN_MAP_DUMMY_STATE(dev, state) \ + { \ + .dev_name = dev, \ + .name = state, \ + .type = PIN_MAP_TYPE_DUMMY_STATE, \ + } -/* - * Convenience macro to map a system function onto a certain pinctrl device - * using a specified group, to be hogged by the pin control core until the - * system shuts down. - */ -#define PIN_MAP_SYS_HOG_GROUP(a, b, c) \ - { .name = PINCTRL_STATE_DEFAULT, .ctrl_dev_name = a, .dev_name = a, \ - .function = b, .group = c, } +#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 -- cgit v0.10.2 From ba110d90c08d9676370db9a62792f57ade5b3bbf Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 2 Mar 2012 13:05:49 -0700 Subject: pinctrl: Show selected function and group in pinmux-pins debugfs Until recently, the pinctrl pinmux-pins debugfs file displayed the selected function for each owned pin. This feature was removed during restructing in support of recent API rework. This change restoreds this feature, and also displays the group that the function was selected on, in case a pin is a member of multiple groups. Based on work by: Linus Walleij Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 1cae372..5b3ff13 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -126,6 +126,7 @@ struct pinctrl_setting { * @owner: The name of the entity owning the pin. Typically, this is the name * of the device that called pinctrl_get(). Alternatively, it may be the * name of the GPIO passed to pinctrl_request_gpio(). + * @mux_setting: The most recent selected mux setting for this pin, if any. */ struct pin_desc { struct pinctrl_dev *pctldev; @@ -135,6 +136,7 @@ struct pin_desc { #ifdef CONFIG_PINMUX unsigned usecount; const char *owner; + const struct pinctrl_setting_mux *mux_setting; #endif }; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 4852ebe..86e4017 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -187,6 +187,7 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, owner = desc->owner; desc->owner = NULL; + desc->mux_setting = NULL; module_put(pctldev->owner); return owner; @@ -378,7 +379,34 @@ void pinmux_free_setting(struct pinctrl_setting const *setting) int pinmux_enable_setting(struct pinctrl_setting const *setting) { struct pinctrl_dev *pctldev = setting->pctldev; + const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; const struct pinmux_ops *ops = pctldev->desc->pmxops; + int ret; + const unsigned *pins; + unsigned num_pins; + int i; + struct pin_desc *desc; + + ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, + &pins, &num_pins); + if (ret) { + /* errors only affect debug data, so just warn */ + dev_warn(pctldev->dev, + "could not get pins for group selector %d\n", + setting->data.mux.group); + num_pins = 0; + } + + for (i = 0; i < num_pins; i++) { + desc = pin_desc_get(pctldev, pins[i]); + if (desc == NULL) { + dev_warn(pctldev->dev, + "could not get pin desc for pin %d\n", + pins[i]); + continue; + } + desc->mux_setting = &(setting->data.mux); + } return ops->enable(pctldev, setting->data.mux.func, setting->data.mux.group); @@ -387,7 +415,34 @@ int pinmux_enable_setting(struct pinctrl_setting const *setting) void pinmux_disable_setting(struct pinctrl_setting const *setting) { struct pinctrl_dev *pctldev = setting->pctldev; + const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; const struct pinmux_ops *ops = pctldev->desc->pmxops; + int ret; + const unsigned *pins; + unsigned num_pins; + int i; + struct pin_desc *desc; + + ret = pctlops->get_group_pins(pctldev, setting->data.mux.group, + &pins, &num_pins); + if (ret) { + /* errors only affect debug data, so just warn */ + dev_warn(pctldev->dev, + "could not get pins for group selector %d\n", + setting->data.mux.group); + num_pins = 0; + } + + for (i = 0; i < num_pins; i++) { + desc = pin_desc_get(pctldev, pins[i]); + if (desc == NULL) { + dev_warn(pctldev->dev, + "could not get pin desc for pin %d\n", + pins[i]); + continue; + } + desc->mux_setting = NULL; + } ops->disable(pctldev, setting->data.mux.func, setting->data.mux.group); } @@ -433,6 +488,8 @@ static int pinmux_functions_show(struct seq_file *s, void *what) static int pinmux_pins_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev = s->private; + const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; + const struct pinmux_ops *pmxops = pctldev->desc->pmxops; unsigned i, pin; seq_puts(s, "Pinmux settings per pin\n"); @@ -455,10 +512,19 @@ static int pinmux_pins_show(struct seq_file *s, void *what) !strcmp(desc->owner, pinctrl_dev_get_name(pctldev))) is_hog = true; - seq_printf(s, "pin %d (%s): %s%s\n", pin, + seq_printf(s, "pin %d (%s): %s%s", pin, desc->name ? desc->name : "unnamed", desc->owner ? desc->owner : "UNCLAIMED", is_hog ? " (HOG)" : ""); + + if (desc->mux_setting) + seq_printf(s, " function %s group %s\n", + pmxops->get_function_name(pctldev, + desc->mux_setting->func), + pctlops->get_group_name(pctldev, + desc->mux_setting->group)); + else + seq_printf(s, "\n"); } mutex_unlock(&pinctrl_mutex); -- cgit v0.10.2 From 971dac7123c785fdb0d09276b5d459b67585e242 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 1 Feb 2012 14:04:47 -0700 Subject: pinctrl: add a driver for NVIDIA Tegra This adds a driver for the Tegra pinmux, and required parameterization data for Tegra20 and Tegra30. The driver is initially added with driver name and device tree compatible value that won't cause this driver to be used. A later change will switch the pinctrl driver to use the correct values, switch the old pinmux driver to be disabled, and update all code that uses the old pinmux APIs to use the new pinctrl APIs. Signed-off-by: Stephen Warren Acked-by: Olof Johansson [squashed "fix case of Tegra30's foo_groups[] arrays"] Signed-off-by: Linus Walleij diff --git a/arch/arm/mach-tegra/include/mach/pinconf-tegra.h b/arch/arm/mach-tegra/include/mach/pinconf-tegra.h new file mode 100644 index 0000000..1f24d30 --- /dev/null +++ b/arch/arm/mach-tegra/include/mach/pinconf-tegra.h @@ -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 diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index afaf885..4beb5f6 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -28,6 +28,21 @@ config PINCTRL_SIRF 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 diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 827601c..be38455 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -6,5 +6,8 @@ obj-$(CONFIG_PINCTRL) += core.o obj-$(CONFIG_PINMUX) += pinmux.o obj-$(CONFIG_PINCONF) += pinconf.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 diff --git a/drivers/pinctrl/pinctrl-tegra.c b/drivers/pinctrl/pinctrl-tegra.c new file mode 100644 index 0000000..9b32968 --- /dev/null +++ b/drivers/pinctrl/pinctrl-tegra.c @@ -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 +#include +#include +#include +#include +#include +#include +#include + +#include + +#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, ®, &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, ®, &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 "); +MODULE_DESCRIPTION("NVIDIA Tegra pinctrl driver"); +MODULE_LICENSE("GPL v2"); +MODULE_DEVICE_TABLE(of, tegra_pinctrl_of_match); diff --git a/drivers/pinctrl/pinctrl-tegra.h b/drivers/pinctrl/pinctrl-tegra.h new file mode 100644 index 0000000..782c795 --- /dev/null +++ b/drivers/pinctrl/pinctrl-tegra.h @@ -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 diff --git a/drivers/pinctrl/pinctrl-tegra20.c b/drivers/pinctrl/pinctrl-tegra20.c new file mode 100644 index 0000000..f69ff96 --- /dev/null +++ b/drivers/pinctrl/pinctrl-tegra20.c @@ -0,0 +1,2860 @@ +/* + * Pinctrl data for the NVIDIA Tegra20 pinmux + * + * Copyright (c) 2011, NVIDIA CORPORATION. All rights reserved. + * + * Derived from code: + * Copyright (C) 2010 Google, Inc. + * Copyright (C) 2010 NVIDIA Corporation + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include +#include +#include + +#include "pinctrl-tegra.h" + +/* + * Most pins affected by the pinmux can also be GPIOs. Define these first. + * These must match how the GPIO driver names/numbers its pins. + */ +#define _GPIO(offset) (offset) + +#define TEGRA_PIN_VI_GP6_PA0 _GPIO(0) +#define TEGRA_PIN_UART3_CTS_N_PA1 _GPIO(1) +#define TEGRA_PIN_DAP2_FS_PA2 _GPIO(2) +#define TEGRA_PIN_DAP2_SCLK_PA3 _GPIO(3) +#define TEGRA_PIN_DAP2_DIN_PA4 _GPIO(4) +#define TEGRA_PIN_DAP2_DOUT_PA5 _GPIO(5) +#define TEGRA_PIN_SDIO3_CLK_PA6 _GPIO(6) +#define TEGRA_PIN_SDIO3_CMD_PA7 _GPIO(7) +#define TEGRA_PIN_GMI_AD17_PB0 _GPIO(8) +#define TEGRA_PIN_GMI_AD18_PB1 _GPIO(9) +#define TEGRA_PIN_LCD_PWR0_PB2 _GPIO(10) +#define TEGRA_PIN_LCD_PCLK_PB3 _GPIO(11) +#define TEGRA_PIN_SDIO3_DAT3_PB4 _GPIO(12) +#define TEGRA_PIN_SDIO3_DAT2_PB5 _GPIO(13) +#define TEGRA_PIN_SDIO3_DAT1_PB6 _GPIO(14) +#define TEGRA_PIN_SDIO3_DAT0_PB7 _GPIO(15) +#define TEGRA_PIN_UART3_RTS_N_PC0 _GPIO(16) +#define TEGRA_PIN_LCD_PWR1_PC1 _GPIO(17) +#define TEGRA_PIN_UART2_TXD_PC2 _GPIO(18) +#define TEGRA_PIN_UART2_RXD_PC3 _GPIO(19) +#define TEGRA_PIN_GEN1_I2C_SCL_PC4 _GPIO(20) +#define TEGRA_PIN_GEN1_I2C_SDA_PC5 _GPIO(21) +#define TEGRA_PIN_LCD_PWR2_PC6 _GPIO(22) +#define TEGRA_PIN_GMI_WP_N_PC7 _GPIO(23) +#define TEGRA_PIN_SDIO3_DAT5_PD0 _GPIO(24) +#define TEGRA_PIN_SDIO3_DAT4_PD1 _GPIO(25) +#define TEGRA_PIN_VI_GP5_PD2 _GPIO(26) +#define TEGRA_PIN_SDIO3_DAT6_PD3 _GPIO(27) +#define TEGRA_PIN_SDIO3_DAT7_PD4 _GPIO(28) +#define TEGRA_PIN_VI_D1_PD5 _GPIO(29) +#define TEGRA_PIN_VI_VSYNC_PD6 _GPIO(30) +#define TEGRA_PIN_VI_HSYNC_PD7 _GPIO(31) +#define TEGRA_PIN_LCD_D0_PE0 _GPIO(32) +#define TEGRA_PIN_LCD_D1_PE1 _GPIO(33) +#define TEGRA_PIN_LCD_D2_PE2 _GPIO(34) +#define TEGRA_PIN_LCD_D3_PE3 _GPIO(35) +#define TEGRA_PIN_LCD_D4_PE4 _GPIO(36) +#define TEGRA_PIN_LCD_D5_PE5 _GPIO(37) +#define TEGRA_PIN_LCD_D6_PE6 _GPIO(38) +#define TEGRA_PIN_LCD_D7_PE7 _GPIO(39) +#define TEGRA_PIN_LCD_D8_PF0 _GPIO(40) +#define TEGRA_PIN_LCD_D9_PF1 _GPIO(41) +#define TEGRA_PIN_LCD_D10_PF2 _GPIO(42) +#define TEGRA_PIN_LCD_D11_PF3 _GPIO(43) +#define TEGRA_PIN_LCD_D12_PF4 _GPIO(44) +#define TEGRA_PIN_LCD_D13_PF5 _GPIO(45) +#define TEGRA_PIN_LCD_D14_PF6 _GPIO(46) +#define TEGRA_PIN_LCD_D15_PF7 _GPIO(47) +#define TEGRA_PIN_GMI_AD0_PG0 _GPIO(48) +#define TEGRA_PIN_GMI_AD1_PG1 _GPIO(49) +#define TEGRA_PIN_GMI_AD2_PG2 _GPIO(50) +#define TEGRA_PIN_GMI_AD3_PG3 _GPIO(51) +#define TEGRA_PIN_GMI_AD4_PG4 _GPIO(52) +#define TEGRA_PIN_GMI_AD5_PG5 _GPIO(53) +#define TEGRA_PIN_GMI_AD6_PG6 _GPIO(54) +#define TEGRA_PIN_GMI_AD7_PG7 _GPIO(55) +#define TEGRA_PIN_GMI_AD8_PH0 _GPIO(56) +#define TEGRA_PIN_GMI_AD9_PH1 _GPIO(57) +#define TEGRA_PIN_GMI_AD10_PH2 _GPIO(58) +#define TEGRA_PIN_GMI_AD11_PH3 _GPIO(59) +#define TEGRA_PIN_GMI_AD12_PH4 _GPIO(60) +#define TEGRA_PIN_GMI_AD13_PH5 _GPIO(61) +#define TEGRA_PIN_GMI_AD14_PH6 _GPIO(62) +#define TEGRA_PIN_GMI_AD15_PH7 _GPIO(63) +#define TEGRA_PIN_GMI_HIOW_N_PI0 _GPIO(64) +#define TEGRA_PIN_GMI_HIOR_N_PI1 _GPIO(65) +#define TEGRA_PIN_GMI_CS5_N_PI2 _GPIO(66) +#define TEGRA_PIN_GMI_CS6_N_PI3 _GPIO(67) +#define TEGRA_PIN_GMI_RST_N_PI4 _GPIO(68) +#define TEGRA_PIN_GMI_IORDY_PI5 _GPIO(69) +#define TEGRA_PIN_GMI_CS7_N_PI6 _GPIO(70) +#define TEGRA_PIN_GMI_WAIT_PI7 _GPIO(71) +#define TEGRA_PIN_GMI_CS0_N_PJ0 _GPIO(72) +#define TEGRA_PIN_LCD_DE_PJ1 _GPIO(73) +#define TEGRA_PIN_GMI_CS1_N_PJ2 _GPIO(74) +#define TEGRA_PIN_LCD_HSYNC_PJ3 _GPIO(75) +#define TEGRA_PIN_LCD_VSYNC_PJ4 _GPIO(76) +#define TEGRA_PIN_UART2_CTS_N_PJ5 _GPIO(77) +#define TEGRA_PIN_UART2_RTS_N_PJ6 _GPIO(78) +#define TEGRA_PIN_GMI_AD16_PJ7 _GPIO(79) +#define TEGRA_PIN_GMI_ADV_N_PK0 _GPIO(80) +#define TEGRA_PIN_GMI_CLK_PK1 _GPIO(81) +#define TEGRA_PIN_GMI_CS4_N_PK2 _GPIO(82) +#define TEGRA_PIN_GMI_CS2_N_PK3 _GPIO(83) +#define TEGRA_PIN_GMI_CS3_N_PK4 _GPIO(84) +#define TEGRA_PIN_SPDIF_OUT_PK5 _GPIO(85) +#define TEGRA_PIN_SPDIF_IN_PK6 _GPIO(86) +#define TEGRA_PIN_GMI_AD19_PK7 _GPIO(87) +#define TEGRA_PIN_VI_D2_PL0 _GPIO(88) +#define TEGRA_PIN_VI_D3_PL1 _GPIO(89) +#define TEGRA_PIN_VI_D4_PL2 _GPIO(90) +#define TEGRA_PIN_VI_D5_PL3 _GPIO(91) +#define TEGRA_PIN_VI_D6_PL4 _GPIO(92) +#define TEGRA_PIN_VI_D7_PL5 _GPIO(93) +#define TEGRA_PIN_VI_D8_PL6 _GPIO(94) +#define TEGRA_PIN_VI_D9_PL7 _GPIO(95) +#define TEGRA_PIN_LCD_D16_PM0 _GPIO(96) +#define TEGRA_PIN_LCD_D17_PM1 _GPIO(97) +#define TEGRA_PIN_LCD_D18_PM2 _GPIO(98) +#define TEGRA_PIN_LCD_D19_PM3 _GPIO(99) +#define TEGRA_PIN_LCD_D20_PM4 _GPIO(100) +#define TEGRA_PIN_LCD_D21_PM5 _GPIO(101) +#define TEGRA_PIN_LCD_D22_PM6 _GPIO(102) +#define TEGRA_PIN_LCD_D23_PM7 _GPIO(103) +#define TEGRA_PIN_DAP1_FS_PN0 _GPIO(104) +#define TEGRA_PIN_DAP1_DIN_PN1 _GPIO(105) +#define TEGRA_PIN_DAP1_DOUT_PN2 _GPIO(106) +#define TEGRA_PIN_DAP1_SCLK_PN3 _GPIO(107) +#define TEGRA_PIN_LCD_CS0_N_PN4 _GPIO(108) +#define TEGRA_PIN_LCD_SDOUT_PN5 _GPIO(109) +#define TEGRA_PIN_LCD_DC0_PN6 _GPIO(110) +#define TEGRA_PIN_HDMI_INT_N_PN7 _GPIO(111) +#define TEGRA_PIN_ULPI_DATA7_PO0 _GPIO(112) +#define TEGRA_PIN_ULPI_DATA0_PO1 _GPIO(113) +#define TEGRA_PIN_ULPI_DATA1_PO2 _GPIO(114) +#define TEGRA_PIN_ULPI_DATA2_PO3 _GPIO(115) +#define TEGRA_PIN_ULPI_DATA3_PO4 _GPIO(116) +#define TEGRA_PIN_ULPI_DATA4_PO5 _GPIO(117) +#define TEGRA_PIN_ULPI_DATA5_PO6 _GPIO(118) +#define TEGRA_PIN_ULPI_DATA6_PO7 _GPIO(119) +#define TEGRA_PIN_DAP3_FS_PP0 _GPIO(120) +#define TEGRA_PIN_DAP3_DIN_PP1 _GPIO(121) +#define TEGRA_PIN_DAP3_DOUT_PP2 _GPIO(122) +#define TEGRA_PIN_DAP3_SCLK_PP3 _GPIO(123) +#define TEGRA_PIN_DAP4_FS_PP4 _GPIO(124) +#define TEGRA_PIN_DAP4_DIN_PP5 _GPIO(125) +#define TEGRA_PIN_DAP4_DOUT_PP6 _GPIO(126) +#define TEGRA_PIN_DAP4_SCLK_PP7 _GPIO(127) +#define TEGRA_PIN_KB_COL0_PQ0 _GPIO(128) +#define TEGRA_PIN_KB_COL1_PQ1 _GPIO(129) +#define TEGRA_PIN_KB_COL2_PQ2 _GPIO(130) +#define TEGRA_PIN_KB_COL3_PQ3 _GPIO(131) +#define TEGRA_PIN_KB_COL4_PQ4 _GPIO(132) +#define TEGRA_PIN_KB_COL5_PQ5 _GPIO(133) +#define TEGRA_PIN_KB_COL6_PQ6 _GPIO(134) +#define TEGRA_PIN_KB_COL7_PQ7 _GPIO(135) +#define TEGRA_PIN_KB_ROW0_PR0 _GPIO(136) +#define TEGRA_PIN_KB_ROW1_PR1 _GPIO(137) +#define TEGRA_PIN_KB_ROW2_PR2 _GPIO(138) +#define TEGRA_PIN_KB_ROW3_PR3 _GPIO(139) +#define TEGRA_PIN_KB_ROW4_PR4 _GPIO(140) +#define TEGRA_PIN_KB_ROW5_PR5 _GPIO(141) +#define TEGRA_PIN_KB_ROW6_PR6 _GPIO(142) +#define TEGRA_PIN_KB_ROW7_PR7 _GPIO(143) +#define TEGRA_PIN_KB_ROW8_PS0 _GPIO(144) +#define TEGRA_PIN_KB_ROW9_PS1 _GPIO(145) +#define TEGRA_PIN_KB_ROW10_PS2 _GPIO(146) +#define TEGRA_PIN_KB_ROW11_PS3 _GPIO(147) +#define TEGRA_PIN_KB_ROW12_PS4 _GPIO(148) +#define TEGRA_PIN_KB_ROW13_PS5 _GPIO(149) +#define TEGRA_PIN_KB_ROW14_PS6 _GPIO(150) +#define TEGRA_PIN_KB_ROW15_PS7 _GPIO(151) +#define TEGRA_PIN_VI_PCLK_PT0 _GPIO(152) +#define TEGRA_PIN_VI_MCLK_PT1 _GPIO(153) +#define TEGRA_PIN_VI_D10_PT2 _GPIO(154) +#define TEGRA_PIN_VI_D11_PT3 _GPIO(155) +#define TEGRA_PIN_VI_D0_PT4 _GPIO(156) +#define TEGRA_PIN_GEN2_I2C_SCL_PT5 _GPIO(157) +#define TEGRA_PIN_GEN2_I2C_SDA_PT6 _GPIO(158) +#define TEGRA_PIN_GMI_DPD_PT7 _GPIO(159) +#define TEGRA_PIN_PU0 _GPIO(160) +#define TEGRA_PIN_PU1 _GPIO(161) +#define TEGRA_PIN_PU2 _GPIO(162) +#define TEGRA_PIN_PU3 _GPIO(163) +#define TEGRA_PIN_PU4 _GPIO(164) +#define TEGRA_PIN_PU5 _GPIO(165) +#define TEGRA_PIN_PU6 _GPIO(166) +#define TEGRA_PIN_JTAG_RTCK_PU7 _GPIO(167) +#define TEGRA_PIN_PV0 _GPIO(168) +#define TEGRA_PIN_PV1 _GPIO(169) +#define TEGRA_PIN_PV2 _GPIO(170) +#define TEGRA_PIN_PV3 _GPIO(171) +#define TEGRA_PIN_PV4 _GPIO(172) +#define TEGRA_PIN_PV5 _GPIO(173) +#define TEGRA_PIN_PV6 _GPIO(174) +#define TEGRA_PIN_LCD_DC1_PV7 _GPIO(175) +#define TEGRA_PIN_LCD_CS1_N_PW0 _GPIO(176) +#define TEGRA_PIN_LCD_M1_PW1 _GPIO(177) +#define TEGRA_PIN_SPI2_CS1_N_PW2 _GPIO(178) +#define TEGRA_PIN_SPI2_CS2_N_PW3 _GPIO(179) +#define TEGRA_PIN_DAP_MCLK1_PW4 _GPIO(180) +#define TEGRA_PIN_DAP_MCLK2_PW5 _GPIO(181) +#define TEGRA_PIN_UART3_TXD_PW6 _GPIO(182) +#define TEGRA_PIN_UART3_RXD_PW7 _GPIO(183) +#define TEGRA_PIN_SPI2_MOSI_PX0 _GPIO(184) +#define TEGRA_PIN_SPI2_MISO_PX1 _GPIO(185) +#define TEGRA_PIN_SPI2_SCK_PX2 _GPIO(186) +#define TEGRA_PIN_SPI2_CS0_N_PX3 _GPIO(187) +#define TEGRA_PIN_SPI1_MOSI_PX4 _GPIO(188) +#define TEGRA_PIN_SPI1_SCK_PX5 _GPIO(189) +#define TEGRA_PIN_SPI1_CS0_N_PX6 _GPIO(190) +#define TEGRA_PIN_SPI1_MISO_PX7 _GPIO(191) +#define TEGRA_PIN_ULPI_CLK_PY0 _GPIO(192) +#define TEGRA_PIN_ULPI_DIR_PY1 _GPIO(193) +#define TEGRA_PIN_ULPI_NXT_PY2 _GPIO(194) +#define TEGRA_PIN_ULPI_STP_PY3 _GPIO(195) +#define TEGRA_PIN_SDIO1_DAT3_PY4 _GPIO(196) +#define TEGRA_PIN_SDIO1_DAT2_PY5 _GPIO(197) +#define TEGRA_PIN_SDIO1_DAT1_PY6 _GPIO(198) +#define TEGRA_PIN_SDIO1_DAT0_PY7 _GPIO(199) +#define TEGRA_PIN_SDIO1_CLK_PZ0 _GPIO(200) +#define TEGRA_PIN_SDIO1_CMD_PZ1 _GPIO(201) +#define TEGRA_PIN_LCD_SDIN_PZ2 _GPIO(202) +#define TEGRA_PIN_LCD_WR_N_PZ3 _GPIO(203) +#define TEGRA_PIN_LCD_SCK_PZ4 _GPIO(204) +#define TEGRA_PIN_SYS_CLK_REQ_PZ5 _GPIO(205) +#define TEGRA_PIN_PWR_I2C_SCL_PZ6 _GPIO(206) +#define TEGRA_PIN_PWR_I2C_SDA_PZ7 _GPIO(207) +#define TEGRA_PIN_GMI_AD20_PAA0 _GPIO(208) +#define TEGRA_PIN_GMI_AD21_PAA1 _GPIO(209) +#define TEGRA_PIN_GMI_AD22_PAA2 _GPIO(210) +#define TEGRA_PIN_GMI_AD23_PAA3 _GPIO(211) +#define TEGRA_PIN_GMI_AD24_PAA4 _GPIO(212) +#define TEGRA_PIN_GMI_AD25_PAA5 _GPIO(213) +#define TEGRA_PIN_GMI_AD26_PAA6 _GPIO(214) +#define TEGRA_PIN_GMI_AD27_PAA7 _GPIO(215) +#define TEGRA_PIN_LED_BLINK_PBB0 _GPIO(216) +#define TEGRA_PIN_VI_GP0_PBB1 _GPIO(217) +#define TEGRA_PIN_CAM_I2C_SCL_PBB2 _GPIO(218) +#define TEGRA_PIN_CAM_I2C_SDA_PBB3 _GPIO(219) +#define TEGRA_PIN_VI_GP3_PBB4 _GPIO(220) +#define TEGRA_PIN_VI_GP4_PBB5 _GPIO(221) +#define TEGRA_PIN_PBB6 _GPIO(222) +#define TEGRA_PIN_PBB7 _GPIO(223) + +/* All non-GPIO pins follow */ +#define NUM_GPIOS (TEGRA_PIN_PBB7 + 1) +#define _PIN(offset) (NUM_GPIOS + (offset)) + +#define TEGRA_PIN_CRT_HSYNC _PIN(30) +#define TEGRA_PIN_CRT_VSYNC _PIN(31) +#define TEGRA_PIN_DDC_SCL _PIN(32) +#define TEGRA_PIN_DDC_SDA _PIN(33) +#define TEGRA_PIN_OWC _PIN(34) +#define TEGRA_PIN_CORE_PWR_REQ _PIN(35) +#define TEGRA_PIN_CPU_PWR_REQ _PIN(36) +#define TEGRA_PIN_PWR_INT_N _PIN(37) +#define TEGRA_PIN_CLK_32_K_IN _PIN(38) +#define TEGRA_PIN_DDR_COMP_PD _PIN(39) +#define TEGRA_PIN_DDR_COMP_PU _PIN(40) +#define TEGRA_PIN_DDR_A0 _PIN(41) +#define TEGRA_PIN_DDR_A1 _PIN(42) +#define TEGRA_PIN_DDR_A2 _PIN(43) +#define TEGRA_PIN_DDR_A3 _PIN(44) +#define TEGRA_PIN_DDR_A4 _PIN(45) +#define TEGRA_PIN_DDR_A5 _PIN(46) +#define TEGRA_PIN_DDR_A6 _PIN(47) +#define TEGRA_PIN_DDR_A7 _PIN(48) +#define TEGRA_PIN_DDR_A8 _PIN(49) +#define TEGRA_PIN_DDR_A9 _PIN(50) +#define TEGRA_PIN_DDR_A10 _PIN(51) +#define TEGRA_PIN_DDR_A11 _PIN(52) +#define TEGRA_PIN_DDR_A12 _PIN(53) +#define TEGRA_PIN_DDR_A13 _PIN(54) +#define TEGRA_PIN_DDR_A14 _PIN(55) +#define TEGRA_PIN_DDR_CAS_N _PIN(56) +#define TEGRA_PIN_DDR_BA0 _PIN(57) +#define TEGRA_PIN_DDR_BA1 _PIN(58) +#define TEGRA_PIN_DDR_BA2 _PIN(59) +#define TEGRA_PIN_DDR_DQS0P _PIN(60) +#define TEGRA_PIN_DDR_DQS0N _PIN(61) +#define TEGRA_PIN_DDR_DQS1P _PIN(62) +#define TEGRA_PIN_DDR_DQS1N _PIN(63) +#define TEGRA_PIN_DDR_DQS2P _PIN(64) +#define TEGRA_PIN_DDR_DQS2N _PIN(65) +#define TEGRA_PIN_DDR_DQS3P _PIN(66) +#define TEGRA_PIN_DDR_DQS3N _PIN(67) +#define TEGRA_PIN_DDR_CKE0 _PIN(68) +#define TEGRA_PIN_DDR_CKE1 _PIN(69) +#define TEGRA_PIN_DDR_CLK _PIN(70) +#define TEGRA_PIN_DDR_CLK_N _PIN(71) +#define TEGRA_PIN_DDR_DM0 _PIN(72) +#define TEGRA_PIN_DDR_DM1 _PIN(73) +#define TEGRA_PIN_DDR_DM2 _PIN(74) +#define TEGRA_PIN_DDR_DM3 _PIN(75) +#define TEGRA_PIN_DDR_ODT _PIN(76) +#define TEGRA_PIN_DDR_QUSE0 _PIN(77) +#define TEGRA_PIN_DDR_QUSE1 _PIN(78) +#define TEGRA_PIN_DDR_QUSE2 _PIN(79) +#define TEGRA_PIN_DDR_QUSE3 _PIN(80) +#define TEGRA_PIN_DDR_RAS_N _PIN(81) +#define TEGRA_PIN_DDR_WE_N _PIN(82) +#define TEGRA_PIN_DDR_DQ0 _PIN(83) +#define TEGRA_PIN_DDR_DQ1 _PIN(84) +#define TEGRA_PIN_DDR_DQ2 _PIN(85) +#define TEGRA_PIN_DDR_DQ3 _PIN(86) +#define TEGRA_PIN_DDR_DQ4 _PIN(87) +#define TEGRA_PIN_DDR_DQ5 _PIN(88) +#define TEGRA_PIN_DDR_DQ6 _PIN(89) +#define TEGRA_PIN_DDR_DQ7 _PIN(90) +#define TEGRA_PIN_DDR_DQ8 _PIN(91) +#define TEGRA_PIN_DDR_DQ9 _PIN(92) +#define TEGRA_PIN_DDR_DQ10 _PIN(93) +#define TEGRA_PIN_DDR_DQ11 _PIN(94) +#define TEGRA_PIN_DDR_DQ12 _PIN(95) +#define TEGRA_PIN_DDR_DQ13 _PIN(96) +#define TEGRA_PIN_DDR_DQ14 _PIN(97) +#define TEGRA_PIN_DDR_DQ15 _PIN(98) +#define TEGRA_PIN_DDR_DQ16 _PIN(99) +#define TEGRA_PIN_DDR_DQ17 _PIN(100) +#define TEGRA_PIN_DDR_DQ18 _PIN(101) +#define TEGRA_PIN_DDR_DQ19 _PIN(102) +#define TEGRA_PIN_DDR_DQ20 _PIN(103) +#define TEGRA_PIN_DDR_DQ21 _PIN(104) +#define TEGRA_PIN_DDR_DQ22 _PIN(105) +#define TEGRA_PIN_DDR_DQ23 _PIN(106) +#define TEGRA_PIN_DDR_DQ24 _PIN(107) +#define TEGRA_PIN_DDR_DQ25 _PIN(108) +#define TEGRA_PIN_DDR_DQ26 _PIN(109) +#define TEGRA_PIN_DDR_DQ27 _PIN(110) +#define TEGRA_PIN_DDR_DQ28 _PIN(111) +#define TEGRA_PIN_DDR_DQ29 _PIN(112) +#define TEGRA_PIN_DDR_DQ30 _PIN(113) +#define TEGRA_PIN_DDR_DQ31 _PIN(114) +#define TEGRA_PIN_DDR_CS0_N _PIN(115) +#define TEGRA_PIN_DDR_CS1_N _PIN(116) +#define TEGRA_PIN_SYS_RESET _PIN(117) +#define TEGRA_PIN_JTAG_TRST_N _PIN(118) +#define TEGRA_PIN_JTAG_TDO _PIN(119) +#define TEGRA_PIN_JTAG_TMS _PIN(120) +#define TEGRA_PIN_JTAG_TCK _PIN(121) +#define TEGRA_PIN_JTAG_TDI _PIN(122) +#define TEGRA_PIN_TEST_MODE_EN _PIN(123) + +static const struct pinctrl_pin_desc tegra20_pins[] = { + PINCTRL_PIN(TEGRA_PIN_VI_GP6_PA0, "VI_GP6 PA0"), + PINCTRL_PIN(TEGRA_PIN_UART3_CTS_N_PA1, "UART3_CTS_N PA1"), + PINCTRL_PIN(TEGRA_PIN_DAP2_FS_PA2, "DAP2_FS PA2"), + PINCTRL_PIN(TEGRA_PIN_DAP2_SCLK_PA3, "DAP2_SCLK PA3"), + PINCTRL_PIN(TEGRA_PIN_DAP2_DIN_PA4, "DAP2_DIN PA4"), + PINCTRL_PIN(TEGRA_PIN_DAP2_DOUT_PA5, "DAP2_DOUT PA5"), + PINCTRL_PIN(TEGRA_PIN_SDIO3_CLK_PA6, "SDIO3_CLK PA6"), + PINCTRL_PIN(TEGRA_PIN_SDIO3_CMD_PA7, "SDIO3_CMD PA7"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD17_PB0, "GMI_AD17 PB0"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD18_PB1, "GMI_AD18 PB1"), + PINCTRL_PIN(TEGRA_PIN_LCD_PWR0_PB2, "LCD_PWR0 PB2"), + PINCTRL_PIN(TEGRA_PIN_LCD_PCLK_PB3, "LCD_PCLK PB3"), + PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT3_PB4, "SDIO3_DAT3 PB4"), + PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT2_PB5, "SDIO3_DAT2 PB5"), + PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT1_PB6, "SDIO3_DAT1 PB6"), + PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT0_PB7, "SDIO3_DAT0 PB7"), + PINCTRL_PIN(TEGRA_PIN_UART3_RTS_N_PC0, "UART3_RTS_N PC0"), + PINCTRL_PIN(TEGRA_PIN_LCD_PWR1_PC1, "LCD_PWR1 PC1"), + PINCTRL_PIN(TEGRA_PIN_UART2_TXD_PC2, "UART2_TXD PC2"), + PINCTRL_PIN(TEGRA_PIN_UART2_RXD_PC3, "UART2_RXD PC3"), + PINCTRL_PIN(TEGRA_PIN_GEN1_I2C_SCL_PC4, "GEN1_I2C_SCL PC4"), + PINCTRL_PIN(TEGRA_PIN_GEN1_I2C_SDA_PC5, "GEN1_I2C_SDA PC5"), + PINCTRL_PIN(TEGRA_PIN_LCD_PWR2_PC6, "LCD_PWR2 PC6"), + PINCTRL_PIN(TEGRA_PIN_GMI_WP_N_PC7, "GMI_WP_N PC7"), + PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT5_PD0, "SDIO3_DAT5 PD0"), + PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT4_PD1, "SDIO3_DAT4 PD1"), + PINCTRL_PIN(TEGRA_PIN_VI_GP5_PD2, "VI_GP5 PD2"), + PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT6_PD3, "SDIO3_DAT6 PD3"), + PINCTRL_PIN(TEGRA_PIN_SDIO3_DAT7_PD4, "SDIO3_DAT7 PD4"), + PINCTRL_PIN(TEGRA_PIN_VI_D1_PD5, "VI_D1 PD5"), + PINCTRL_PIN(TEGRA_PIN_VI_VSYNC_PD6, "VI_VSYNC PD6"), + PINCTRL_PIN(TEGRA_PIN_VI_HSYNC_PD7, "VI_HSYNC PD7"), + PINCTRL_PIN(TEGRA_PIN_LCD_D0_PE0, "LCD_D0 PE0"), + PINCTRL_PIN(TEGRA_PIN_LCD_D1_PE1, "LCD_D1 PE1"), + PINCTRL_PIN(TEGRA_PIN_LCD_D2_PE2, "LCD_D2 PE2"), + PINCTRL_PIN(TEGRA_PIN_LCD_D3_PE3, "LCD_D3 PE3"), + PINCTRL_PIN(TEGRA_PIN_LCD_D4_PE4, "LCD_D4 PE4"), + PINCTRL_PIN(TEGRA_PIN_LCD_D5_PE5, "LCD_D5 PE5"), + PINCTRL_PIN(TEGRA_PIN_LCD_D6_PE6, "LCD_D6 PE6"), + PINCTRL_PIN(TEGRA_PIN_LCD_D7_PE7, "LCD_D7 PE7"), + PINCTRL_PIN(TEGRA_PIN_LCD_D8_PF0, "LCD_D8 PF0"), + PINCTRL_PIN(TEGRA_PIN_LCD_D9_PF1, "LCD_D9 PF1"), + PINCTRL_PIN(TEGRA_PIN_LCD_D10_PF2, "LCD_D10 PF2"), + PINCTRL_PIN(TEGRA_PIN_LCD_D11_PF3, "LCD_D11 PF3"), + PINCTRL_PIN(TEGRA_PIN_LCD_D12_PF4, "LCD_D12 PF4"), + PINCTRL_PIN(TEGRA_PIN_LCD_D13_PF5, "LCD_D13 PF5"), + PINCTRL_PIN(TEGRA_PIN_LCD_D14_PF6, "LCD_D14 PF6"), + PINCTRL_PIN(TEGRA_PIN_LCD_D15_PF7, "LCD_D15 PF7"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD0_PG0, "GMI_AD0 PG0"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD1_PG1, "GMI_AD1 PG1"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD2_PG2, "GMI_AD2 PG2"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD3_PG3, "GMI_AD3 PG3"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD4_PG4, "GMI_AD4 PG4"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD5_PG5, "GMI_AD5 PG5"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD6_PG6, "GMI_AD6 PG6"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD7_PG7, "GMI_AD7 PG7"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD8_PH0, "GMI_AD8 PH0"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD9_PH1, "GMI_AD9 PH1"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD10_PH2, "GMI_AD10 PH2"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD11_PH3, "GMI_AD11 PH3"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD12_PH4, "GMI_AD12 PH4"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD13_PH5, "GMI_AD13 PH5"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD14_PH6, "GMI_AD14 PH6"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD15_PH7, "GMI_AD15 PH7"), + PINCTRL_PIN(TEGRA_PIN_GMI_HIOW_N_PI0, "GMI_HIOW_N PI0"), + PINCTRL_PIN(TEGRA_PIN_GMI_HIOR_N_PI1, "GMI_HIOR_N PI1"), + PINCTRL_PIN(TEGRA_PIN_GMI_CS5_N_PI2, "GMI_CS5_N PI2"), + PINCTRL_PIN(TEGRA_PIN_GMI_CS6_N_PI3, "GMI_CS6_N PI3"), + PINCTRL_PIN(TEGRA_PIN_GMI_RST_N_PI4, "GMI_RST_N PI4"), + PINCTRL_PIN(TEGRA_PIN_GMI_IORDY_PI5, "GMI_IORDY PI5"), + PINCTRL_PIN(TEGRA_PIN_GMI_CS7_N_PI6, "GMI_CS7_N PI6"), + PINCTRL_PIN(TEGRA_PIN_GMI_WAIT_PI7, "GMI_WAIT PI7"), + PINCTRL_PIN(TEGRA_PIN_GMI_CS0_N_PJ0, "GMI_CS0_N PJ0"), + PINCTRL_PIN(TEGRA_PIN_LCD_DE_PJ1, "LCD_DE PJ1"), + PINCTRL_PIN(TEGRA_PIN_GMI_CS1_N_PJ2, "GMI_CS1_N PJ2"), + PINCTRL_PIN(TEGRA_PIN_LCD_HSYNC_PJ3, "LCD_HSYNC PJ3"), + PINCTRL_PIN(TEGRA_PIN_LCD_VSYNC_PJ4, "LCD_VSYNC PJ4"), + PINCTRL_PIN(TEGRA_PIN_UART2_CTS_N_PJ5, "UART2_CTS_N PJ5"), + PINCTRL_PIN(TEGRA_PIN_UART2_RTS_N_PJ6, "UART2_RTS_N PJ6"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD16_PJ7, "GMI_AD16 PJ7"), + PINCTRL_PIN(TEGRA_PIN_GMI_ADV_N_PK0, "GMI_ADV_N PK0"), + PINCTRL_PIN(TEGRA_PIN_GMI_CLK_PK1, "GMI_CLK PK1"), + PINCTRL_PIN(TEGRA_PIN_GMI_CS4_N_PK2, "GMI_CS4_N PK2"), + PINCTRL_PIN(TEGRA_PIN_GMI_CS2_N_PK3, "GMI_CS2_N PK3"), + PINCTRL_PIN(TEGRA_PIN_GMI_CS3_N_PK4, "GMI_CS3_N PK4"), + PINCTRL_PIN(TEGRA_PIN_SPDIF_OUT_PK5, "SPDIF_OUT PK5"), + PINCTRL_PIN(TEGRA_PIN_SPDIF_IN_PK6, "SPDIF_IN PK6"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD19_PK7, "GMI_AD19 PK7"), + PINCTRL_PIN(TEGRA_PIN_VI_D2_PL0, "VI_D2 PL0"), + PINCTRL_PIN(TEGRA_PIN_VI_D3_PL1, "VI_D3 PL1"), + PINCTRL_PIN(TEGRA_PIN_VI_D4_PL2, "VI_D4 PL2"), + PINCTRL_PIN(TEGRA_PIN_VI_D5_PL3, "VI_D5 PL3"), + PINCTRL_PIN(TEGRA_PIN_VI_D6_PL4, "VI_D6 PL4"), + PINCTRL_PIN(TEGRA_PIN_VI_D7_PL5, "VI_D7 PL5"), + PINCTRL_PIN(TEGRA_PIN_VI_D8_PL6, "VI_D8 PL6"), + PINCTRL_PIN(TEGRA_PIN_VI_D9_PL7, "VI_D9 PL7"), + PINCTRL_PIN(TEGRA_PIN_LCD_D16_PM0, "LCD_D16 PM0"), + PINCTRL_PIN(TEGRA_PIN_LCD_D17_PM1, "LCD_D17 PM1"), + PINCTRL_PIN(TEGRA_PIN_LCD_D18_PM2, "LCD_D18 PM2"), + PINCTRL_PIN(TEGRA_PIN_LCD_D19_PM3, "LCD_D19 PM3"), + PINCTRL_PIN(TEGRA_PIN_LCD_D20_PM4, "LCD_D20 PM4"), + PINCTRL_PIN(TEGRA_PIN_LCD_D21_PM5, "LCD_D21 PM5"), + PINCTRL_PIN(TEGRA_PIN_LCD_D22_PM6, "LCD_D22 PM6"), + PINCTRL_PIN(TEGRA_PIN_LCD_D23_PM7, "LCD_D23 PM7"), + PINCTRL_PIN(TEGRA_PIN_DAP1_FS_PN0, "DAP1_FS PN0"), + PINCTRL_PIN(TEGRA_PIN_DAP1_DIN_PN1, "DAP1_DIN PN1"), + PINCTRL_PIN(TEGRA_PIN_DAP1_DOUT_PN2, "DAP1_DOUT PN2"), + PINCTRL_PIN(TEGRA_PIN_DAP1_SCLK_PN3, "DAP1_SCLK PN3"), + PINCTRL_PIN(TEGRA_PIN_LCD_CS0_N_PN4, "LCD_CS0_N PN4"), + PINCTRL_PIN(TEGRA_PIN_LCD_SDOUT_PN5, "LCD_SDOUT PN5"), + PINCTRL_PIN(TEGRA_PIN_LCD_DC0_PN6, "LCD_DC0 PN6"), + PINCTRL_PIN(TEGRA_PIN_HDMI_INT_N_PN7, "HDMI_INT_N PN7"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA7_PO0, "ULPI_DATA7 PO0"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA0_PO1, "ULPI_DATA0 PO1"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA1_PO2, "ULPI_DATA1 PO2"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA2_PO3, "ULPI_DATA2 PO3"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA3_PO4, "ULPI_DATA3 PO4"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA4_PO5, "ULPI_DATA4 PO5"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA5_PO6, "ULPI_DATA5 PO6"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA6_PO7, "ULPI_DATA6 PO7"), + PINCTRL_PIN(TEGRA_PIN_DAP3_FS_PP0, "DAP3_FS PP0"), + PINCTRL_PIN(TEGRA_PIN_DAP3_DIN_PP1, "DAP3_DIN PP1"), + PINCTRL_PIN(TEGRA_PIN_DAP3_DOUT_PP2, "DAP3_DOUT PP2"), + PINCTRL_PIN(TEGRA_PIN_DAP3_SCLK_PP3, "DAP3_SCLK PP3"), + PINCTRL_PIN(TEGRA_PIN_DAP4_FS_PP4, "DAP4_FS PP4"), + PINCTRL_PIN(TEGRA_PIN_DAP4_DIN_PP5, "DAP4_DIN PP5"), + PINCTRL_PIN(TEGRA_PIN_DAP4_DOUT_PP6, "DAP4_DOUT PP6"), + PINCTRL_PIN(TEGRA_PIN_DAP4_SCLK_PP7, "DAP4_SCLK PP7"), + PINCTRL_PIN(TEGRA_PIN_KB_COL0_PQ0, "KB_COL0 PQ0"), + PINCTRL_PIN(TEGRA_PIN_KB_COL1_PQ1, "KB_COL1 PQ1"), + PINCTRL_PIN(TEGRA_PIN_KB_COL2_PQ2, "KB_COL2 PQ2"), + PINCTRL_PIN(TEGRA_PIN_KB_COL3_PQ3, "KB_COL3 PQ3"), + PINCTRL_PIN(TEGRA_PIN_KB_COL4_PQ4, "KB_COL4 PQ4"), + PINCTRL_PIN(TEGRA_PIN_KB_COL5_PQ5, "KB_COL5 PQ5"), + PINCTRL_PIN(TEGRA_PIN_KB_COL6_PQ6, "KB_COL6 PQ6"), + PINCTRL_PIN(TEGRA_PIN_KB_COL7_PQ7, "KB_COL7 PQ7"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW0_PR0, "KB_ROW0 PR0"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW1_PR1, "KB_ROW1 PR1"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW2_PR2, "KB_ROW2 PR2"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW3_PR3, "KB_ROW3 PR3"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW4_PR4, "KB_ROW4 PR4"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW5_PR5, "KB_ROW5 PR5"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW6_PR6, "KB_ROW6 PR6"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW7_PR7, "KB_ROW7 PR7"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW8_PS0, "KB_ROW8 PS0"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW9_PS1, "KB_ROW9 PS1"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW10_PS2, "KB_ROW10 PS2"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW11_PS3, "KB_ROW11 PS3"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW12_PS4, "KB_ROW12 PS4"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW13_PS5, "KB_ROW13 PS5"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW14_PS6, "KB_ROW14 PS6"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW15_PS7, "KB_ROW15 PS7"), + PINCTRL_PIN(TEGRA_PIN_VI_PCLK_PT0, "VI_PCLK PT0"), + PINCTRL_PIN(TEGRA_PIN_VI_MCLK_PT1, "VI_MCLK PT1"), + PINCTRL_PIN(TEGRA_PIN_VI_D10_PT2, "VD_D10 PT2"), + PINCTRL_PIN(TEGRA_PIN_VI_D11_PT3, "VI_D11 PT3"), + PINCTRL_PIN(TEGRA_PIN_VI_D0_PT4, "VI_D0 PT4"), + PINCTRL_PIN(TEGRA_PIN_GEN2_I2C_SCL_PT5, "GEN2_I2C_SCL PT5"), + PINCTRL_PIN(TEGRA_PIN_GEN2_I2C_SDA_PT6, "GEN2_I2C_SDA PT6"), + PINCTRL_PIN(TEGRA_PIN_GMI_DPD_PT7, "GMI_DPD PT7"), + /* PU0..6: GPIO only */ + PINCTRL_PIN(TEGRA_PIN_PU0, "PU0"), + PINCTRL_PIN(TEGRA_PIN_PU1, "PU1"), + PINCTRL_PIN(TEGRA_PIN_PU2, "PU2"), + PINCTRL_PIN(TEGRA_PIN_PU3, "PU3"), + PINCTRL_PIN(TEGRA_PIN_PU4, "PU4"), + PINCTRL_PIN(TEGRA_PIN_PU5, "PU5"), + PINCTRL_PIN(TEGRA_PIN_PU6, "PU6"), + PINCTRL_PIN(TEGRA_PIN_JTAG_RTCK_PU7, "JTAG_RTCK PU7"), + /* PV0..1: GPIO only */ + PINCTRL_PIN(TEGRA_PIN_PV0, "PV0"), + PINCTRL_PIN(TEGRA_PIN_PV1, "PV1"), + /* PV2..3: Balls are named after GPIO not function */ + PINCTRL_PIN(TEGRA_PIN_PV2, "PV2"), + PINCTRL_PIN(TEGRA_PIN_PV3, "PV3"), + /* PV4..6: GPIO only */ + PINCTRL_PIN(TEGRA_PIN_PV4, "PV4"), + PINCTRL_PIN(TEGRA_PIN_PV5, "PV5"), + PINCTRL_PIN(TEGRA_PIN_PV6, "PV6"), + PINCTRL_PIN(TEGRA_PIN_LCD_DC1_PV7, "LCD_DC1 PV7"), + PINCTRL_PIN(TEGRA_PIN_LCD_CS1_N_PW0, "LCD_CS1_N PW0"), + PINCTRL_PIN(TEGRA_PIN_LCD_M1_PW1, "LCD_M1 PW1"), + PINCTRL_PIN(TEGRA_PIN_SPI2_CS1_N_PW2, "SPI2_CS1_N PW2"), + PINCTRL_PIN(TEGRA_PIN_SPI2_CS2_N_PW3, "SPI2_CS2_N PW3"), + PINCTRL_PIN(TEGRA_PIN_DAP_MCLK1_PW4, "DAP_MCLK1 PW4"), + PINCTRL_PIN(TEGRA_PIN_DAP_MCLK2_PW5, "DAP_MCLK2 PW5"), + PINCTRL_PIN(TEGRA_PIN_UART3_TXD_PW6, "UART3_TXD PW6"), + PINCTRL_PIN(TEGRA_PIN_UART3_RXD_PW7, "UART3_RXD PW7"), + PINCTRL_PIN(TEGRA_PIN_SPI2_MOSI_PX0, "SPI2_MOSI PX0"), + PINCTRL_PIN(TEGRA_PIN_SPI2_MISO_PX1, "SPI2_MISO PX1"), + PINCTRL_PIN(TEGRA_PIN_SPI2_SCK_PX2, "SPI2_SCK PX2"), + PINCTRL_PIN(TEGRA_PIN_SPI2_CS0_N_PX3, "SPI2_CS0_N PX3"), + PINCTRL_PIN(TEGRA_PIN_SPI1_MOSI_PX4, "SPI1_MOSI PX4"), + PINCTRL_PIN(TEGRA_PIN_SPI1_SCK_PX5, "SPI1_SCK PX5"), + PINCTRL_PIN(TEGRA_PIN_SPI1_CS0_N_PX6, "SPI1_CS0_N PX6"), + PINCTRL_PIN(TEGRA_PIN_SPI1_MISO_PX7, "SPI1_MISO PX7"), + PINCTRL_PIN(TEGRA_PIN_ULPI_CLK_PY0, "ULPI_CLK PY0"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DIR_PY1, "ULPI_DIR PY1"), + PINCTRL_PIN(TEGRA_PIN_ULPI_NXT_PY2, "ULPI_NXT PY2"), + PINCTRL_PIN(TEGRA_PIN_ULPI_STP_PY3, "ULPI_STP PY3"), + PINCTRL_PIN(TEGRA_PIN_SDIO1_DAT3_PY4, "SDIO1_DAT3 PY4"), + PINCTRL_PIN(TEGRA_PIN_SDIO1_DAT2_PY5, "SDIO1_DAT2 PY5"), + PINCTRL_PIN(TEGRA_PIN_SDIO1_DAT1_PY6, "SDIO1_DAT1 PY6"), + PINCTRL_PIN(TEGRA_PIN_SDIO1_DAT0_PY7, "SDIO1_DAT0 PY7"), + PINCTRL_PIN(TEGRA_PIN_SDIO1_CLK_PZ0, "SDIO1_CLK PZ0"), + PINCTRL_PIN(TEGRA_PIN_SDIO1_CMD_PZ1, "SDIO1_CMD PZ1"), + PINCTRL_PIN(TEGRA_PIN_LCD_SDIN_PZ2, "LCD_SDIN PZ2"), + PINCTRL_PIN(TEGRA_PIN_LCD_WR_N_PZ3, "LCD_WR_N PZ3"), + PINCTRL_PIN(TEGRA_PIN_LCD_SCK_PZ4, "LCD_SCK PZ4"), + PINCTRL_PIN(TEGRA_PIN_SYS_CLK_REQ_PZ5, "SYS_CLK_REQ PZ5"), + PINCTRL_PIN(TEGRA_PIN_PWR_I2C_SCL_PZ6, "PWR_I2C_SCL PZ6"), + PINCTRL_PIN(TEGRA_PIN_PWR_I2C_SDA_PZ7, "PWR_I2C_SDA PZ7"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD20_PAA0, "GMI_AD20 PAA0"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD21_PAA1, "GMI_AD21 PAA1"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD22_PAA2, "GMI_AD22 PAA2"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD23_PAA3, "GMI_AD23 PAA3"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD24_PAA4, "GMI_AD24 PAA4"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD25_PAA5, "GMI_AD25 PAA5"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD26_PAA6, "GMI_AD26 PAA6"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD27_PAA7, "GMI_AD27 PAA7"), + PINCTRL_PIN(TEGRA_PIN_LED_BLINK_PBB0, "LED_BLINK PBB0"), + PINCTRL_PIN(TEGRA_PIN_VI_GP0_PBB1, "VI_GP0 PBB1"), + PINCTRL_PIN(TEGRA_PIN_CAM_I2C_SCL_PBB2, "CAM_I2C_SCL PBB2"), + PINCTRL_PIN(TEGRA_PIN_CAM_I2C_SDA_PBB3, "CAM_I2C_SDA PBB3"), + PINCTRL_PIN(TEGRA_PIN_VI_GP3_PBB4, "VI_GP3 PBB4"), + PINCTRL_PIN(TEGRA_PIN_VI_GP4_PBB5, "VI_GP4 PBB5"), + PINCTRL_PIN(TEGRA_PIN_PBB6, "PBB6"), + PINCTRL_PIN(TEGRA_PIN_PBB7, "PBB7"), + PINCTRL_PIN(TEGRA_PIN_CRT_HSYNC, "CRT_HSYNC"), + PINCTRL_PIN(TEGRA_PIN_CRT_VSYNC, "CRT_VSYNC"), + PINCTRL_PIN(TEGRA_PIN_DDC_SCL, "DDC_SCL"), + PINCTRL_PIN(TEGRA_PIN_DDC_SDA, "DDC_SDA"), + PINCTRL_PIN(TEGRA_PIN_OWC, "OWC"), + PINCTRL_PIN(TEGRA_PIN_CORE_PWR_REQ, "CORE_PWR_REQ"), + PINCTRL_PIN(TEGRA_PIN_CPU_PWR_REQ, "CPU_PWR_REQ"), + PINCTRL_PIN(TEGRA_PIN_PWR_INT_N, "PWR_INT_N"), + PINCTRL_PIN(TEGRA_PIN_CLK_32_K_IN, "CLK_32_K_IN"), + PINCTRL_PIN(TEGRA_PIN_DDR_COMP_PD, "DDR_COMP_PD"), + PINCTRL_PIN(TEGRA_PIN_DDR_COMP_PU, "DDR_COMP_PU"), + PINCTRL_PIN(TEGRA_PIN_DDR_A0, "DDR_A0"), + PINCTRL_PIN(TEGRA_PIN_DDR_A1, "DDR_A1"), + PINCTRL_PIN(TEGRA_PIN_DDR_A2, "DDR_A2"), + PINCTRL_PIN(TEGRA_PIN_DDR_A3, "DDR_A3"), + PINCTRL_PIN(TEGRA_PIN_DDR_A4, "DDR_A4"), + PINCTRL_PIN(TEGRA_PIN_DDR_A5, "DDR_A5"), + PINCTRL_PIN(TEGRA_PIN_DDR_A6, "DDR_A6"), + PINCTRL_PIN(TEGRA_PIN_DDR_A7, "DDR_A7"), + PINCTRL_PIN(TEGRA_PIN_DDR_A8, "DDR_A8"), + PINCTRL_PIN(TEGRA_PIN_DDR_A9, "DDR_A9"), + PINCTRL_PIN(TEGRA_PIN_DDR_A10, "DDR_A10"), + PINCTRL_PIN(TEGRA_PIN_DDR_A11, "DDR_A11"), + PINCTRL_PIN(TEGRA_PIN_DDR_A12, "DDR_A12"), + PINCTRL_PIN(TEGRA_PIN_DDR_A13, "DDR_A13"), + PINCTRL_PIN(TEGRA_PIN_DDR_A14, "DDR_A14"), + PINCTRL_PIN(TEGRA_PIN_DDR_CAS_N, "DDR_CAS_N"), + PINCTRL_PIN(TEGRA_PIN_DDR_BA0, "DDR_BA0"), + PINCTRL_PIN(TEGRA_PIN_DDR_BA1, "DDR_BA1"), + PINCTRL_PIN(TEGRA_PIN_DDR_BA2, "DDR_BA2"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQS0P, "DDR_DQS0P"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQS0N, "DDR_DQS0N"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQS1P, "DDR_DQS1P"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQS1N, "DDR_DQS1N"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQS2P, "DDR_DQS2P"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQS2N, "DDR_DQS2N"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQS3P, "DDR_DQS3P"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQS3N, "DDR_DQS3N"), + PINCTRL_PIN(TEGRA_PIN_DDR_CKE0, "DDR_CKE0"), + PINCTRL_PIN(TEGRA_PIN_DDR_CKE1, "DDR_CKE1"), + PINCTRL_PIN(TEGRA_PIN_DDR_CLK, "DDR_CLK"), + PINCTRL_PIN(TEGRA_PIN_DDR_CLK_N, "DDR_CLK_N"), + PINCTRL_PIN(TEGRA_PIN_DDR_DM0, "DDR_DM0"), + PINCTRL_PIN(TEGRA_PIN_DDR_DM1, "DDR_DM1"), + PINCTRL_PIN(TEGRA_PIN_DDR_DM2, "DDR_DM2"), + PINCTRL_PIN(TEGRA_PIN_DDR_DM3, "DDR_DM3"), + PINCTRL_PIN(TEGRA_PIN_DDR_ODT, "DDR_ODT"), + PINCTRL_PIN(TEGRA_PIN_DDR_QUSE0, "DDR_QUSE0"), + PINCTRL_PIN(TEGRA_PIN_DDR_QUSE1, "DDR_QUSE1"), + PINCTRL_PIN(TEGRA_PIN_DDR_QUSE2, "DDR_QUSE2"), + PINCTRL_PIN(TEGRA_PIN_DDR_QUSE3, "DDR_QUSE3"), + PINCTRL_PIN(TEGRA_PIN_DDR_RAS_N, "DDR_RAS_N"), + PINCTRL_PIN(TEGRA_PIN_DDR_WE_N, "DDR_WE_N"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ0, "DDR_DQ0"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ1, "DDR_DQ1"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ2, "DDR_DQ2"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ3, "DDR_DQ3"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ4, "DDR_DQ4"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ5, "DDR_DQ5"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ6, "DDR_DQ6"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ7, "DDR_DQ7"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ8, "DDR_DQ8"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ9, "DDR_DQ9"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ10, "DDR_DQ10"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ11, "DDR_DQ11"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ12, "DDR_DQ12"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ13, "DDR_DQ13"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ14, "DDR_DQ14"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ15, "DDR_DQ15"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ16, "DDR_DQ16"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ17, "DDR_DQ17"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ18, "DDR_DQ18"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ19, "DDR_DQ19"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ20, "DDR_DQ20"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ21, "DDR_DQ21"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ22, "DDR_DQ22"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ23, "DDR_DQ23"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ24, "DDR_DQ24"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ25, "DDR_DQ25"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ26, "DDR_DQ26"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ27, "DDR_DQ27"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ28, "DDR_DQ28"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ29, "DDR_DQ29"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ30, "DDR_DQ30"), + PINCTRL_PIN(TEGRA_PIN_DDR_DQ31, "DDR_DQ31"), + PINCTRL_PIN(TEGRA_PIN_DDR_CS0_N, "DDR_CS0_N"), + PINCTRL_PIN(TEGRA_PIN_DDR_CS1_N, "DDR_CS1_N"), + PINCTRL_PIN(TEGRA_PIN_SYS_RESET, "SYS_RESET"), + PINCTRL_PIN(TEGRA_PIN_JTAG_TRST_N, "JTAG_TRST_N"), + PINCTRL_PIN(TEGRA_PIN_JTAG_TDO, "JTAG_TDO"), + PINCTRL_PIN(TEGRA_PIN_JTAG_TMS, "JTAG_TMS"), + PINCTRL_PIN(TEGRA_PIN_JTAG_TCK, "JTAG_TCK"), + PINCTRL_PIN(TEGRA_PIN_JTAG_TDI, "JTAG_TDI"), + PINCTRL_PIN(TEGRA_PIN_TEST_MODE_EN, "TEST_MODE_EN"), +}; + +static const unsigned ata_pins[] = { + TEGRA_PIN_GMI_CS6_N_PI3, + TEGRA_PIN_GMI_CS7_N_PI6, + TEGRA_PIN_GMI_RST_N_PI4, +}; + +static const unsigned atb_pins[] = { + TEGRA_PIN_GMI_CS5_N_PI2, + TEGRA_PIN_GMI_DPD_PT7, +}; + +static const unsigned atc_pins[] = { + TEGRA_PIN_GMI_IORDY_PI5, + TEGRA_PIN_GMI_WAIT_PI7, + TEGRA_PIN_GMI_ADV_N_PK0, + TEGRA_PIN_GMI_CLK_PK1, + TEGRA_PIN_GMI_CS2_N_PK3, + TEGRA_PIN_GMI_CS3_N_PK4, + TEGRA_PIN_GMI_CS4_N_PK2, + TEGRA_PIN_GMI_AD0_PG0, + TEGRA_PIN_GMI_AD1_PG1, + TEGRA_PIN_GMI_AD2_PG2, + TEGRA_PIN_GMI_AD3_PG3, + TEGRA_PIN_GMI_AD4_PG4, + TEGRA_PIN_GMI_AD5_PG5, + TEGRA_PIN_GMI_AD6_PG6, + TEGRA_PIN_GMI_AD7_PG7, + TEGRA_PIN_GMI_HIOW_N_PI0, + TEGRA_PIN_GMI_HIOR_N_PI1, +}; + +static const unsigned atd_pins[] = { + TEGRA_PIN_GMI_AD8_PH0, + TEGRA_PIN_GMI_AD9_PH1, + TEGRA_PIN_GMI_AD10_PH2, + TEGRA_PIN_GMI_AD11_PH3, +}; + +static const unsigned ate_pins[] = { + TEGRA_PIN_GMI_AD12_PH4, + TEGRA_PIN_GMI_AD13_PH5, + TEGRA_PIN_GMI_AD14_PH6, + TEGRA_PIN_GMI_AD15_PH7, +}; + +static const unsigned cdev1_pins[] = { + TEGRA_PIN_DAP_MCLK1_PW4, +}; + +static const unsigned cdev2_pins[] = { + TEGRA_PIN_DAP_MCLK2_PW5, +}; + +static const unsigned crtp_pins[] = { + TEGRA_PIN_CRT_HSYNC, + TEGRA_PIN_CRT_VSYNC, +}; + +static const unsigned csus_pins[] = { + TEGRA_PIN_VI_MCLK_PT1, +}; + +static const unsigned dap1_pins[] = { + TEGRA_PIN_DAP1_FS_PN0, + TEGRA_PIN_DAP1_DIN_PN1, + TEGRA_PIN_DAP1_DOUT_PN2, + TEGRA_PIN_DAP1_SCLK_PN3, +}; + +static const unsigned dap2_pins[] = { + TEGRA_PIN_DAP2_FS_PA2, + TEGRA_PIN_DAP2_SCLK_PA3, + TEGRA_PIN_DAP2_DIN_PA4, + TEGRA_PIN_DAP2_DOUT_PA5, +}; + +static const unsigned dap3_pins[] = { + TEGRA_PIN_DAP3_FS_PP0, + TEGRA_PIN_DAP3_DIN_PP1, + TEGRA_PIN_DAP3_DOUT_PP2, + TEGRA_PIN_DAP3_SCLK_PP3, +}; + +static const unsigned dap4_pins[] = { + TEGRA_PIN_DAP4_FS_PP4, + TEGRA_PIN_DAP4_DIN_PP5, + TEGRA_PIN_DAP4_DOUT_PP6, + TEGRA_PIN_DAP4_SCLK_PP7, +}; + +static const unsigned ddc_pins[] = { + TEGRA_PIN_DDC_SCL, + TEGRA_PIN_DDC_SDA, +}; + +static const unsigned dta_pins[] = { + TEGRA_PIN_VI_D0_PT4, + TEGRA_PIN_VI_D1_PD5, +}; + +static const unsigned dtb_pins[] = { + TEGRA_PIN_VI_D10_PT2, + TEGRA_PIN_VI_D11_PT3, +}; + +static const unsigned dtc_pins[] = { + TEGRA_PIN_VI_HSYNC_PD7, + TEGRA_PIN_VI_VSYNC_PD6, +}; + +static const unsigned dtd_pins[] = { + TEGRA_PIN_VI_PCLK_PT0, + TEGRA_PIN_VI_D2_PL0, + TEGRA_PIN_VI_D3_PL1, + TEGRA_PIN_VI_D4_PL2, + TEGRA_PIN_VI_D5_PL3, + TEGRA_PIN_VI_D6_PL4, + TEGRA_PIN_VI_D7_PL5, + TEGRA_PIN_VI_D8_PL6, + TEGRA_PIN_VI_D9_PL7, +}; + +static const unsigned dte_pins[] = { + TEGRA_PIN_VI_GP0_PBB1, + TEGRA_PIN_VI_GP3_PBB4, + TEGRA_PIN_VI_GP4_PBB5, + TEGRA_PIN_VI_GP5_PD2, + TEGRA_PIN_VI_GP6_PA0, +}; + +static const unsigned dtf_pins[] = { + TEGRA_PIN_CAM_I2C_SCL_PBB2, + TEGRA_PIN_CAM_I2C_SDA_PBB3, +}; + +static const unsigned gma_pins[] = { + TEGRA_PIN_GMI_AD20_PAA0, + TEGRA_PIN_GMI_AD21_PAA1, + TEGRA_PIN_GMI_AD22_PAA2, + TEGRA_PIN_GMI_AD23_PAA3, +}; + +static const unsigned gmb_pins[] = { + TEGRA_PIN_GMI_WP_N_PC7, +}; + +static const unsigned gmc_pins[] = { + TEGRA_PIN_GMI_AD16_PJ7, + TEGRA_PIN_GMI_AD17_PB0, + TEGRA_PIN_GMI_AD18_PB1, + TEGRA_PIN_GMI_AD19_PK7, +}; + +static const unsigned gmd_pins[] = { + TEGRA_PIN_GMI_CS0_N_PJ0, + TEGRA_PIN_GMI_CS1_N_PJ2, +}; + +static const unsigned gme_pins[] = { + TEGRA_PIN_GMI_AD24_PAA4, + TEGRA_PIN_GMI_AD25_PAA5, + TEGRA_PIN_GMI_AD26_PAA6, + TEGRA_PIN_GMI_AD27_PAA7, +}; + +static const unsigned gpu_pins[] = { + TEGRA_PIN_PU0, + TEGRA_PIN_PU1, + TEGRA_PIN_PU2, + TEGRA_PIN_PU3, + TEGRA_PIN_PU4, + TEGRA_PIN_PU5, + TEGRA_PIN_PU6, +}; + +static const unsigned gpu7_pins[] = { + TEGRA_PIN_JTAG_RTCK_PU7, +}; + +static const unsigned gpv_pins[] = { + TEGRA_PIN_PV4, + TEGRA_PIN_PV5, + TEGRA_PIN_PV6, +}; + +static const unsigned hdint_pins[] = { + TEGRA_PIN_HDMI_INT_N_PN7, +}; + +static const unsigned i2cp_pins[] = { + TEGRA_PIN_PWR_I2C_SCL_PZ6, + TEGRA_PIN_PWR_I2C_SDA_PZ7, +}; + +static const unsigned irrx_pins[] = { + TEGRA_PIN_UART2_RTS_N_PJ6, +}; + +static const unsigned irtx_pins[] = { + TEGRA_PIN_UART2_CTS_N_PJ5, +}; + +static const unsigned kbca_pins[] = { + TEGRA_PIN_KB_ROW0_PR0, + TEGRA_PIN_KB_ROW1_PR1, + TEGRA_PIN_KB_ROW2_PR2, +}; + +static const unsigned kbcb_pins[] = { + TEGRA_PIN_KB_ROW7_PR7, + TEGRA_PIN_KB_ROW8_PS0, + TEGRA_PIN_KB_ROW9_PS1, + TEGRA_PIN_KB_ROW10_PS2, + TEGRA_PIN_KB_ROW11_PS3, + TEGRA_PIN_KB_ROW12_PS4, + TEGRA_PIN_KB_ROW13_PS5, + TEGRA_PIN_KB_ROW14_PS6, + TEGRA_PIN_KB_ROW15_PS7, +}; + +static const unsigned kbcc_pins[] = { + TEGRA_PIN_KB_COL0_PQ0, + TEGRA_PIN_KB_COL1_PQ1, +}; + +static const unsigned kbcd_pins[] = { + TEGRA_PIN_KB_ROW3_PR3, + TEGRA_PIN_KB_ROW4_PR4, + TEGRA_PIN_KB_ROW5_PR5, + TEGRA_PIN_KB_ROW6_PR6, +}; + +static const unsigned kbce_pins[] = { + TEGRA_PIN_KB_COL7_PQ7, +}; + +static const unsigned kbcf_pins[] = { + TEGRA_PIN_KB_COL2_PQ2, + TEGRA_PIN_KB_COL3_PQ3, + TEGRA_PIN_KB_COL4_PQ4, + TEGRA_PIN_KB_COL5_PQ5, + TEGRA_PIN_KB_COL6_PQ6, +}; + +static const unsigned lcsn_pins[] = { + TEGRA_PIN_LCD_CS0_N_PN4, +}; + +static const unsigned ld0_pins[] = { + TEGRA_PIN_LCD_D0_PE0, +}; + +static const unsigned ld1_pins[] = { + TEGRA_PIN_LCD_D1_PE1, +}; + +static const unsigned ld2_pins[] = { + TEGRA_PIN_LCD_D2_PE2, +}; + +static const unsigned ld3_pins[] = { + TEGRA_PIN_LCD_D3_PE3, +}; + +static const unsigned ld4_pins[] = { + TEGRA_PIN_LCD_D4_PE4, +}; + +static const unsigned ld5_pins[] = { + TEGRA_PIN_LCD_D5_PE5, +}; + +static const unsigned ld6_pins[] = { + TEGRA_PIN_LCD_D6_PE6, +}; + +static const unsigned ld7_pins[] = { + TEGRA_PIN_LCD_D7_PE7, +}; + +static const unsigned ld8_pins[] = { + TEGRA_PIN_LCD_D8_PF0, +}; + +static const unsigned ld9_pins[] = { + TEGRA_PIN_LCD_D9_PF1, +}; + +static const unsigned ld10_pins[] = { + TEGRA_PIN_LCD_D10_PF2, +}; + +static const unsigned ld11_pins[] = { + TEGRA_PIN_LCD_D11_PF3, +}; + +static const unsigned ld12_pins[] = { + TEGRA_PIN_LCD_D12_PF4, +}; + +static const unsigned ld13_pins[] = { + TEGRA_PIN_LCD_D13_PF5, +}; + +static const unsigned ld14_pins[] = { + TEGRA_PIN_LCD_D14_PF6, +}; + +static const unsigned ld15_pins[] = { + TEGRA_PIN_LCD_D15_PF7, +}; + +static const unsigned ld16_pins[] = { + TEGRA_PIN_LCD_D16_PM0, +}; + +static const unsigned ld17_pins[] = { + TEGRA_PIN_LCD_D17_PM1, +}; + +static const unsigned ldc_pins[] = { + TEGRA_PIN_LCD_DC0_PN6, +}; + +static const unsigned ldi_pins[] = { + TEGRA_PIN_LCD_D22_PM6, +}; + +static const unsigned lhp0_pins[] = { + TEGRA_PIN_LCD_D21_PM5, +}; + +static const unsigned lhp1_pins[] = { + TEGRA_PIN_LCD_D18_PM2, +}; + +static const unsigned lhp2_pins[] = { + TEGRA_PIN_LCD_D19_PM3, +}; + +static const unsigned lhs_pins[] = { + TEGRA_PIN_LCD_HSYNC_PJ3, +}; + +static const unsigned lm0_pins[] = { + TEGRA_PIN_LCD_CS1_N_PW0, +}; + +static const unsigned lm1_pins[] = { + TEGRA_PIN_LCD_M1_PW1, +}; + +static const unsigned lpp_pins[] = { + TEGRA_PIN_LCD_D23_PM7, +}; + +static const unsigned lpw0_pins[] = { + TEGRA_PIN_LCD_PWR0_PB2, +}; + +static const unsigned lpw1_pins[] = { + TEGRA_PIN_LCD_PWR1_PC1, +}; + +static const unsigned lpw2_pins[] = { + TEGRA_PIN_LCD_PWR2_PC6, +}; + +static const unsigned lsc0_pins[] = { + TEGRA_PIN_LCD_PCLK_PB3, +}; + +static const unsigned lsc1_pins[] = { + TEGRA_PIN_LCD_WR_N_PZ3, +}; + +static const unsigned lsck_pins[] = { + TEGRA_PIN_LCD_SCK_PZ4, +}; + +static const unsigned lsda_pins[] = { + TEGRA_PIN_LCD_SDOUT_PN5, +}; + +static const unsigned lsdi_pins[] = { + TEGRA_PIN_LCD_SDIN_PZ2, +}; + +static const unsigned lspi_pins[] = { + TEGRA_PIN_LCD_DE_PJ1, +}; + +static const unsigned lvp0_pins[] = { + TEGRA_PIN_LCD_DC1_PV7, +}; + +static const unsigned lvp1_pins[] = { + TEGRA_PIN_LCD_D20_PM4, +}; + +static const unsigned lvs_pins[] = { + TEGRA_PIN_LCD_VSYNC_PJ4, +}; + +static const unsigned ls_pins[] = { + TEGRA_PIN_LCD_PWR0_PB2, + TEGRA_PIN_LCD_PWR1_PC1, + TEGRA_PIN_LCD_PWR2_PC6, + TEGRA_PIN_LCD_SDIN_PZ2, + TEGRA_PIN_LCD_SDOUT_PN5, + TEGRA_PIN_LCD_WR_N_PZ3, + TEGRA_PIN_LCD_CS0_N_PN4, + TEGRA_PIN_LCD_DC0_PN6, + TEGRA_PIN_LCD_SCK_PZ4, +}; + +static const unsigned lc_pins[] = { + TEGRA_PIN_LCD_PCLK_PB3, + TEGRA_PIN_LCD_DE_PJ1, + TEGRA_PIN_LCD_HSYNC_PJ3, + TEGRA_PIN_LCD_VSYNC_PJ4, + TEGRA_PIN_LCD_CS1_N_PW0, + TEGRA_PIN_LCD_M1_PW1, + TEGRA_PIN_LCD_DC1_PV7, + TEGRA_PIN_HDMI_INT_N_PN7, +}; + +static const unsigned ld17_0_pins[] = { + TEGRA_PIN_LCD_D0_PE0, + TEGRA_PIN_LCD_D1_PE1, + TEGRA_PIN_LCD_D2_PE2, + TEGRA_PIN_LCD_D3_PE3, + TEGRA_PIN_LCD_D4_PE4, + TEGRA_PIN_LCD_D5_PE5, + TEGRA_PIN_LCD_D6_PE6, + TEGRA_PIN_LCD_D7_PE7, + TEGRA_PIN_LCD_D8_PF0, + TEGRA_PIN_LCD_D9_PF1, + TEGRA_PIN_LCD_D10_PF2, + TEGRA_PIN_LCD_D11_PF3, + TEGRA_PIN_LCD_D12_PF4, + TEGRA_PIN_LCD_D13_PF5, + TEGRA_PIN_LCD_D14_PF6, + TEGRA_PIN_LCD_D15_PF7, + TEGRA_PIN_LCD_D16_PM0, + TEGRA_PIN_LCD_D17_PM1, +}; + +static const unsigned ld19_18_pins[] = { + TEGRA_PIN_LCD_D18_PM2, + TEGRA_PIN_LCD_D19_PM3, +}; + +static const unsigned ld21_20_pins[] = { + TEGRA_PIN_LCD_D20_PM4, + TEGRA_PIN_LCD_D21_PM5, +}; + +static const unsigned ld23_22_pins[] = { + TEGRA_PIN_LCD_D22_PM6, + TEGRA_PIN_LCD_D23_PM7, +}; + +static const unsigned owc_pins[] = { + TEGRA_PIN_OWC, +}; + +static const unsigned pmc_pins[] = { + TEGRA_PIN_LED_BLINK_PBB0, + TEGRA_PIN_SYS_CLK_REQ_PZ5, + TEGRA_PIN_CORE_PWR_REQ, + TEGRA_PIN_CPU_PWR_REQ, + TEGRA_PIN_PWR_INT_N, +}; + +static const unsigned pta_pins[] = { + TEGRA_PIN_GEN2_I2C_SCL_PT5, + TEGRA_PIN_GEN2_I2C_SDA_PT6, +}; + +static const unsigned rm_pins[] = { + TEGRA_PIN_GEN1_I2C_SCL_PC4, + TEGRA_PIN_GEN1_I2C_SDA_PC5, +}; + +static const unsigned sdb_pins[] = { + TEGRA_PIN_SDIO3_CMD_PA7, +}; + +static const unsigned sdc_pins[] = { + TEGRA_PIN_SDIO3_DAT0_PB7, + TEGRA_PIN_SDIO3_DAT1_PB6, + TEGRA_PIN_SDIO3_DAT2_PB5, + TEGRA_PIN_SDIO3_DAT3_PB4, +}; + +static const unsigned sdd_pins[] = { + TEGRA_PIN_SDIO3_CLK_PA6, +}; + +static const unsigned sdio1_pins[] = { + TEGRA_PIN_SDIO1_CLK_PZ0, + TEGRA_PIN_SDIO1_CMD_PZ1, + TEGRA_PIN_SDIO1_DAT0_PY7, + TEGRA_PIN_SDIO1_DAT1_PY6, + TEGRA_PIN_SDIO1_DAT2_PY5, + TEGRA_PIN_SDIO1_DAT3_PY4, +}; + +static const unsigned slxa_pins[] = { + TEGRA_PIN_SDIO3_DAT4_PD1, +}; + +static const unsigned slxc_pins[] = { + TEGRA_PIN_SDIO3_DAT6_PD3, +}; + +static const unsigned slxd_pins[] = { + TEGRA_PIN_SDIO3_DAT7_PD4, +}; + +static const unsigned slxk_pins[] = { + TEGRA_PIN_SDIO3_DAT5_PD0, +}; + +static const unsigned spdi_pins[] = { + TEGRA_PIN_SPDIF_IN_PK6, +}; + +static const unsigned spdo_pins[] = { + TEGRA_PIN_SPDIF_OUT_PK5, +}; + +static const unsigned spia_pins[] = { + TEGRA_PIN_SPI2_MOSI_PX0, +}; + +static const unsigned spib_pins[] = { + TEGRA_PIN_SPI2_MISO_PX1, +}; + +static const unsigned spic_pins[] = { + TEGRA_PIN_SPI2_CS0_N_PX3, + TEGRA_PIN_SPI2_SCK_PX2, +}; + +static const unsigned spid_pins[] = { + TEGRA_PIN_SPI1_MOSI_PX4, +}; + +static const unsigned spie_pins[] = { + TEGRA_PIN_SPI1_CS0_N_PX6, + TEGRA_PIN_SPI1_SCK_PX5, +}; + +static const unsigned spif_pins[] = { + TEGRA_PIN_SPI1_MISO_PX7, +}; + +static const unsigned spig_pins[] = { + TEGRA_PIN_SPI2_CS1_N_PW2, +}; + +static const unsigned spih_pins[] = { + TEGRA_PIN_SPI2_CS2_N_PW3, +}; + +static const unsigned uaa_pins[] = { + TEGRA_PIN_ULPI_DATA0_PO1, + TEGRA_PIN_ULPI_DATA1_PO2, + TEGRA_PIN_ULPI_DATA2_PO3, + TEGRA_PIN_ULPI_DATA3_PO4, +}; + +static const unsigned uab_pins[] = { + TEGRA_PIN_ULPI_DATA4_PO5, + TEGRA_PIN_ULPI_DATA5_PO6, + TEGRA_PIN_ULPI_DATA6_PO7, + TEGRA_PIN_ULPI_DATA7_PO0, +}; + +static const unsigned uac_pins[] = { + TEGRA_PIN_PV0, + TEGRA_PIN_PV1, + TEGRA_PIN_PV2, + TEGRA_PIN_PV3, +}; + +static const unsigned ck32_pins[] = { + TEGRA_PIN_CLK_32_K_IN, +}; + +static const unsigned uad_pins[] = { + TEGRA_PIN_UART2_RXD_PC3, + TEGRA_PIN_UART2_TXD_PC2, +}; + +static const unsigned uca_pins[] = { + TEGRA_PIN_UART3_RXD_PW7, + TEGRA_PIN_UART3_TXD_PW6, +}; + +static const unsigned ucb_pins[] = { + TEGRA_PIN_UART3_CTS_N_PA1, + TEGRA_PIN_UART3_RTS_N_PC0, +}; + +static const unsigned uda_pins[] = { + TEGRA_PIN_ULPI_CLK_PY0, + TEGRA_PIN_ULPI_DIR_PY1, + TEGRA_PIN_ULPI_NXT_PY2, + TEGRA_PIN_ULPI_STP_PY3, +}; + +static const unsigned ddrc_pins[] = { + TEGRA_PIN_DDR_COMP_PD, + TEGRA_PIN_DDR_COMP_PU, +}; + +static const unsigned pmca_pins[] = { + TEGRA_PIN_LED_BLINK_PBB0, +}; + +static const unsigned pmcb_pins[] = { + TEGRA_PIN_SYS_CLK_REQ_PZ5, +}; + +static const unsigned pmcc_pins[] = { + TEGRA_PIN_CORE_PWR_REQ, +}; + +static const unsigned pmcd_pins[] = { + TEGRA_PIN_CPU_PWR_REQ, +}; + +static const unsigned pmce_pins[] = { + TEGRA_PIN_PWR_INT_N, +}; + +static const unsigned xm2c_pins[] = { + TEGRA_PIN_DDR_A0, + TEGRA_PIN_DDR_A1, + TEGRA_PIN_DDR_A2, + TEGRA_PIN_DDR_A3, + TEGRA_PIN_DDR_A4, + TEGRA_PIN_DDR_A5, + TEGRA_PIN_DDR_A6, + TEGRA_PIN_DDR_A7, + TEGRA_PIN_DDR_A8, + TEGRA_PIN_DDR_A9, + TEGRA_PIN_DDR_A10, + TEGRA_PIN_DDR_A11, + TEGRA_PIN_DDR_A12, + TEGRA_PIN_DDR_A13, + TEGRA_PIN_DDR_A14, + TEGRA_PIN_DDR_CAS_N, + TEGRA_PIN_DDR_BA0, + TEGRA_PIN_DDR_BA1, + TEGRA_PIN_DDR_BA2, + TEGRA_PIN_DDR_DQS0P, + TEGRA_PIN_DDR_DQS0N, + TEGRA_PIN_DDR_DQS1P, + TEGRA_PIN_DDR_DQS1N, + TEGRA_PIN_DDR_DQS2P, + TEGRA_PIN_DDR_DQS2N, + TEGRA_PIN_DDR_DQS3P, + TEGRA_PIN_DDR_DQS3N, + TEGRA_PIN_DDR_CS0_N, + TEGRA_PIN_DDR_CS1_N, + TEGRA_PIN_DDR_CKE0, + TEGRA_PIN_DDR_CKE1, + TEGRA_PIN_DDR_CLK, + TEGRA_PIN_DDR_CLK_N, + TEGRA_PIN_DDR_DM0, + TEGRA_PIN_DDR_DM1, + TEGRA_PIN_DDR_DM2, + TEGRA_PIN_DDR_DM3, + TEGRA_PIN_DDR_ODT, + TEGRA_PIN_DDR_RAS_N, + TEGRA_PIN_DDR_WE_N, + TEGRA_PIN_DDR_QUSE0, + TEGRA_PIN_DDR_QUSE1, + TEGRA_PIN_DDR_QUSE2, + TEGRA_PIN_DDR_QUSE3, +}; + +static const unsigned xm2d_pins[] = { + TEGRA_PIN_DDR_DQ0, + TEGRA_PIN_DDR_DQ1, + TEGRA_PIN_DDR_DQ2, + TEGRA_PIN_DDR_DQ3, + TEGRA_PIN_DDR_DQ4, + TEGRA_PIN_DDR_DQ5, + TEGRA_PIN_DDR_DQ6, + TEGRA_PIN_DDR_DQ7, + TEGRA_PIN_DDR_DQ8, + TEGRA_PIN_DDR_DQ9, + TEGRA_PIN_DDR_DQ10, + TEGRA_PIN_DDR_DQ11, + TEGRA_PIN_DDR_DQ12, + TEGRA_PIN_DDR_DQ13, + TEGRA_PIN_DDR_DQ14, + TEGRA_PIN_DDR_DQ15, + TEGRA_PIN_DDR_DQ16, + TEGRA_PIN_DDR_DQ17, + TEGRA_PIN_DDR_DQ18, + TEGRA_PIN_DDR_DQ19, + TEGRA_PIN_DDR_DQ20, + TEGRA_PIN_DDR_DQ21, + TEGRA_PIN_DDR_DQ22, + TEGRA_PIN_DDR_DQ23, + TEGRA_PIN_DDR_DQ24, + TEGRA_PIN_DDR_DQ25, + TEGRA_PIN_DDR_DQ26, + TEGRA_PIN_DDR_DQ27, + TEGRA_PIN_DDR_DQ28, + TEGRA_PIN_DDR_DQ29, + TEGRA_PIN_DDR_DQ30, + TEGRA_PIN_DDR_DQ31, +}; + +static const unsigned drive_ao1_pins[] = { + TEGRA_PIN_SYS_RESET, + TEGRA_PIN_PWR_I2C_SCL_PZ6, + TEGRA_PIN_PWR_I2C_SDA_PZ7, + TEGRA_PIN_KB_ROW0_PR0, + TEGRA_PIN_KB_ROW1_PR1, + TEGRA_PIN_KB_ROW2_PR2, + TEGRA_PIN_KB_ROW3_PR3, + TEGRA_PIN_KB_ROW4_PR4, + TEGRA_PIN_KB_ROW5_PR5, + TEGRA_PIN_KB_ROW6_PR6, + TEGRA_PIN_KB_ROW7_PR7, +}; + +static const unsigned drive_ao2_pins[] = { + TEGRA_PIN_KB_ROW8_PS0, + TEGRA_PIN_KB_ROW9_PS1, + TEGRA_PIN_KB_ROW10_PS2, + TEGRA_PIN_KB_ROW11_PS3, + TEGRA_PIN_KB_ROW12_PS4, + TEGRA_PIN_KB_ROW13_PS5, + TEGRA_PIN_KB_ROW14_PS6, + TEGRA_PIN_KB_ROW15_PS7, + TEGRA_PIN_KB_COL0_PQ0, + TEGRA_PIN_KB_COL1_PQ1, + TEGRA_PIN_KB_COL2_PQ2, + TEGRA_PIN_KB_COL3_PQ3, + TEGRA_PIN_KB_COL4_PQ4, + TEGRA_PIN_KB_COL5_PQ5, + TEGRA_PIN_KB_COL6_PQ6, + TEGRA_PIN_KB_COL7_PQ7, + TEGRA_PIN_LED_BLINK_PBB0, + TEGRA_PIN_SYS_CLK_REQ_PZ5, + TEGRA_PIN_CORE_PWR_REQ, + TEGRA_PIN_CPU_PWR_REQ, + TEGRA_PIN_PWR_INT_N, + TEGRA_PIN_CLK_32_K_IN, +}; + +static const unsigned drive_at1_pins[] = { + TEGRA_PIN_GMI_IORDY_PI5, + TEGRA_PIN_GMI_AD8_PH0, + TEGRA_PIN_GMI_AD9_PH1, + TEGRA_PIN_GMI_AD10_PH2, + TEGRA_PIN_GMI_AD11_PH3, + TEGRA_PIN_GMI_AD12_PH4, + TEGRA_PIN_GMI_AD13_PH5, + TEGRA_PIN_GMI_AD14_PH6, + TEGRA_PIN_GMI_AD15_PH7, + TEGRA_PIN_GMI_CS7_N_PI6, + TEGRA_PIN_GMI_DPD_PT7, + TEGRA_PIN_GEN2_I2C_SCL_PT5, + TEGRA_PIN_GEN2_I2C_SDA_PT6, +}; + +static const unsigned drive_at2_pins[] = { + TEGRA_PIN_GMI_WAIT_PI7, + TEGRA_PIN_GMI_ADV_N_PK0, + TEGRA_PIN_GMI_CLK_PK1, + TEGRA_PIN_GMI_CS6_N_PI3, + TEGRA_PIN_GMI_CS5_N_PI2, + TEGRA_PIN_GMI_CS4_N_PK2, + TEGRA_PIN_GMI_CS3_N_PK4, + TEGRA_PIN_GMI_CS2_N_PK3, + TEGRA_PIN_GMI_AD0_PG0, + TEGRA_PIN_GMI_AD1_PG1, + TEGRA_PIN_GMI_AD2_PG2, + TEGRA_PIN_GMI_AD3_PG3, + TEGRA_PIN_GMI_AD4_PG4, + TEGRA_PIN_GMI_AD5_PG5, + TEGRA_PIN_GMI_AD6_PG6, + TEGRA_PIN_GMI_AD7_PG7, + TEGRA_PIN_GMI_HIOW_N_PI0, + TEGRA_PIN_GMI_HIOR_N_PI1, + TEGRA_PIN_GMI_RST_N_PI4, +}; + +static const unsigned drive_cdev1_pins[] = { + TEGRA_PIN_DAP_MCLK1_PW4, +}; + +static const unsigned drive_cdev2_pins[] = { + TEGRA_PIN_DAP_MCLK2_PW5, +}; + +static const unsigned drive_csus_pins[] = { + TEGRA_PIN_VI_MCLK_PT1, +}; + +static const unsigned drive_dap1_pins[] = { + TEGRA_PIN_DAP1_FS_PN0, + TEGRA_PIN_DAP1_DIN_PN1, + TEGRA_PIN_DAP1_DOUT_PN2, + TEGRA_PIN_DAP1_SCLK_PN3, + TEGRA_PIN_SPDIF_OUT_PK5, + TEGRA_PIN_SPDIF_IN_PK6, +}; + +static const unsigned drive_dap2_pins[] = { + TEGRA_PIN_DAP2_FS_PA2, + TEGRA_PIN_DAP2_SCLK_PA3, + TEGRA_PIN_DAP2_DIN_PA4, + TEGRA_PIN_DAP2_DOUT_PA5, +}; + +static const unsigned drive_dap3_pins[] = { + TEGRA_PIN_DAP3_FS_PP0, + TEGRA_PIN_DAP3_DIN_PP1, + TEGRA_PIN_DAP3_DOUT_PP2, + TEGRA_PIN_DAP3_SCLK_PP3, +}; + +static const unsigned drive_dap4_pins[] = { + TEGRA_PIN_DAP4_FS_PP4, + TEGRA_PIN_DAP4_DIN_PP5, + TEGRA_PIN_DAP4_DOUT_PP6, + TEGRA_PIN_DAP4_SCLK_PP7, +}; + +static const unsigned drive_dbg_pins[] = { + TEGRA_PIN_PU0, + TEGRA_PIN_PU1, + TEGRA_PIN_PU2, + TEGRA_PIN_PU3, + TEGRA_PIN_PU4, + TEGRA_PIN_PU5, + TEGRA_PIN_PU6, + TEGRA_PIN_JTAG_RTCK_PU7, + TEGRA_PIN_GEN1_I2C_SDA_PC5, + TEGRA_PIN_GEN1_I2C_SCL_PC4, + TEGRA_PIN_JTAG_TRST_N, + TEGRA_PIN_JTAG_TDO, + TEGRA_PIN_JTAG_TMS, + TEGRA_PIN_JTAG_TCK, + TEGRA_PIN_JTAG_TDI, + TEGRA_PIN_TEST_MODE_EN, +}; + +static const unsigned drive_lcd1_pins[] = { + TEGRA_PIN_LCD_PWR1_PC1, + TEGRA_PIN_LCD_PWR2_PC6, + TEGRA_PIN_LCD_SDIN_PZ2, + TEGRA_PIN_LCD_SDOUT_PN5, + TEGRA_PIN_LCD_WR_N_PZ3, + TEGRA_PIN_LCD_CS0_N_PN4, + TEGRA_PIN_LCD_DC0_PN6, + TEGRA_PIN_LCD_SCK_PZ4, +}; + +static const unsigned drive_lcd2_pins[] = { + TEGRA_PIN_LCD_PWR0_PB2, + TEGRA_PIN_LCD_PCLK_PB3, + TEGRA_PIN_LCD_DE_PJ1, + TEGRA_PIN_LCD_HSYNC_PJ3, + TEGRA_PIN_LCD_VSYNC_PJ4, + TEGRA_PIN_LCD_D0_PE0, + TEGRA_PIN_LCD_D1_PE1, + TEGRA_PIN_LCD_D2_PE2, + TEGRA_PIN_LCD_D3_PE3, + TEGRA_PIN_LCD_D4_PE4, + TEGRA_PIN_LCD_D5_PE5, + TEGRA_PIN_LCD_D6_PE6, + TEGRA_PIN_LCD_D7_PE7, + TEGRA_PIN_LCD_D8_PF0, + TEGRA_PIN_LCD_D9_PF1, + TEGRA_PIN_LCD_D10_PF2, + TEGRA_PIN_LCD_D11_PF3, + TEGRA_PIN_LCD_D12_PF4, + TEGRA_PIN_LCD_D13_PF5, + TEGRA_PIN_LCD_D14_PF6, + TEGRA_PIN_LCD_D15_PF7, + TEGRA_PIN_LCD_D16_PM0, + TEGRA_PIN_LCD_D17_PM1, + TEGRA_PIN_LCD_D18_PM2, + TEGRA_PIN_LCD_D19_PM3, + TEGRA_PIN_LCD_D20_PM4, + TEGRA_PIN_LCD_D21_PM5, + TEGRA_PIN_LCD_D22_PM6, + TEGRA_PIN_LCD_D23_PM7, + TEGRA_PIN_LCD_CS1_N_PW0, + TEGRA_PIN_LCD_M1_PW1, + TEGRA_PIN_LCD_DC1_PV7, + TEGRA_PIN_HDMI_INT_N_PN7, +}; + +static const unsigned drive_sdmmc2_pins[] = { + TEGRA_PIN_SDIO3_DAT4_PD1, + TEGRA_PIN_SDIO3_DAT5_PD0, + TEGRA_PIN_SDIO3_DAT6_PD3, + TEGRA_PIN_SDIO3_DAT7_PD4, +}; + +static const unsigned drive_sdmmc3_pins[] = { + TEGRA_PIN_SDIO3_CLK_PA6, + TEGRA_PIN_SDIO3_CMD_PA7, + TEGRA_PIN_SDIO3_DAT0_PB7, + TEGRA_PIN_SDIO3_DAT1_PB6, + TEGRA_PIN_SDIO3_DAT2_PB5, + TEGRA_PIN_SDIO3_DAT3_PB4, + TEGRA_PIN_PV4, + TEGRA_PIN_PV5, + TEGRA_PIN_PV6, +}; + +static const unsigned drive_spi_pins[] = { + TEGRA_PIN_SPI2_MOSI_PX0, + TEGRA_PIN_SPI2_MISO_PX1, + TEGRA_PIN_SPI2_SCK_PX2, + TEGRA_PIN_SPI2_CS0_N_PX3, + TEGRA_PIN_SPI1_MOSI_PX4, + TEGRA_PIN_SPI1_SCK_PX5, + TEGRA_PIN_SPI1_CS0_N_PX6, + TEGRA_PIN_SPI1_MISO_PX7, + TEGRA_PIN_SPI2_CS1_N_PW2, + TEGRA_PIN_SPI2_CS2_N_PW3, +}; + +static const unsigned drive_uaa_pins[] = { + TEGRA_PIN_ULPI_DATA0_PO1, + TEGRA_PIN_ULPI_DATA1_PO2, + TEGRA_PIN_ULPI_DATA2_PO3, + TEGRA_PIN_ULPI_DATA3_PO4, +}; + +static const unsigned drive_uab_pins[] = { + TEGRA_PIN_ULPI_DATA4_PO5, + TEGRA_PIN_ULPI_DATA5_PO6, + TEGRA_PIN_ULPI_DATA6_PO7, + TEGRA_PIN_ULPI_DATA7_PO0, + TEGRA_PIN_PV0, + TEGRA_PIN_PV1, + TEGRA_PIN_PV2, + TEGRA_PIN_PV3, +}; + +static const unsigned drive_uart2_pins[] = { + TEGRA_PIN_UART2_TXD_PC2, + TEGRA_PIN_UART2_RXD_PC3, + TEGRA_PIN_UART2_RTS_N_PJ6, + TEGRA_PIN_UART2_CTS_N_PJ5, +}; + +static const unsigned drive_uart3_pins[] = { + TEGRA_PIN_UART3_TXD_PW6, + TEGRA_PIN_UART3_RXD_PW7, + TEGRA_PIN_UART3_RTS_N_PC0, + TEGRA_PIN_UART3_CTS_N_PA1, +}; + +static const unsigned drive_vi1_pins[] = { + TEGRA_PIN_VI_D0_PT4, + TEGRA_PIN_VI_D1_PD5, + TEGRA_PIN_VI_D2_PL0, + TEGRA_PIN_VI_D3_PL1, + TEGRA_PIN_VI_D4_PL2, + TEGRA_PIN_VI_D5_PL3, + TEGRA_PIN_VI_D6_PL4, + TEGRA_PIN_VI_D7_PL5, + TEGRA_PIN_VI_D8_PL6, + TEGRA_PIN_VI_D9_PL7, + TEGRA_PIN_VI_D10_PT2, + TEGRA_PIN_VI_D11_PT3, + TEGRA_PIN_VI_PCLK_PT0, + TEGRA_PIN_VI_VSYNC_PD6, + TEGRA_PIN_VI_HSYNC_PD7, +}; + +static const unsigned drive_vi2_pins[] = { + TEGRA_PIN_VI_GP0_PBB1, + TEGRA_PIN_CAM_I2C_SCL_PBB2, + TEGRA_PIN_CAM_I2C_SDA_PBB3, + TEGRA_PIN_VI_GP3_PBB4, + TEGRA_PIN_VI_GP4_PBB5, + TEGRA_PIN_VI_GP5_PD2, + TEGRA_PIN_VI_GP6_PA0, +}; + +static const unsigned drive_xm2a_pins[] = { + TEGRA_PIN_DDR_A0, + TEGRA_PIN_DDR_A1, + TEGRA_PIN_DDR_A2, + TEGRA_PIN_DDR_A3, + TEGRA_PIN_DDR_A4, + TEGRA_PIN_DDR_A5, + TEGRA_PIN_DDR_A6, + TEGRA_PIN_DDR_A7, + TEGRA_PIN_DDR_A8, + TEGRA_PIN_DDR_A9, + TEGRA_PIN_DDR_A10, + TEGRA_PIN_DDR_A11, + TEGRA_PIN_DDR_A12, + TEGRA_PIN_DDR_A13, + TEGRA_PIN_DDR_A14, + TEGRA_PIN_DDR_BA0, + TEGRA_PIN_DDR_BA1, + TEGRA_PIN_DDR_BA2, + TEGRA_PIN_DDR_CS0_N, + TEGRA_PIN_DDR_CS1_N, + TEGRA_PIN_DDR_ODT, + TEGRA_PIN_DDR_RAS_N, + TEGRA_PIN_DDR_CAS_N, + TEGRA_PIN_DDR_WE_N, + TEGRA_PIN_DDR_CKE0, + TEGRA_PIN_DDR_CKE1, +}; + +static const unsigned drive_xm2c_pins[] = { + TEGRA_PIN_DDR_DQS0P, + TEGRA_PIN_DDR_DQS0N, + TEGRA_PIN_DDR_DQS1P, + TEGRA_PIN_DDR_DQS1N, + TEGRA_PIN_DDR_DQS2P, + TEGRA_PIN_DDR_DQS2N, + TEGRA_PIN_DDR_DQS3P, + TEGRA_PIN_DDR_DQS3N, + TEGRA_PIN_DDR_QUSE0, + TEGRA_PIN_DDR_QUSE1, + TEGRA_PIN_DDR_QUSE2, + TEGRA_PIN_DDR_QUSE3, +}; + +static const unsigned drive_xm2d_pins[] = { + TEGRA_PIN_DDR_DQ0, + TEGRA_PIN_DDR_DQ1, + TEGRA_PIN_DDR_DQ2, + TEGRA_PIN_DDR_DQ3, + TEGRA_PIN_DDR_DQ4, + TEGRA_PIN_DDR_DQ5, + TEGRA_PIN_DDR_DQ6, + TEGRA_PIN_DDR_DQ7, + TEGRA_PIN_DDR_DQ8, + TEGRA_PIN_DDR_DQ9, + TEGRA_PIN_DDR_DQ10, + TEGRA_PIN_DDR_DQ11, + TEGRA_PIN_DDR_DQ12, + TEGRA_PIN_DDR_DQ13, + TEGRA_PIN_DDR_DQ14, + TEGRA_PIN_DDR_DQ15, + TEGRA_PIN_DDR_DQ16, + TEGRA_PIN_DDR_DQ17, + TEGRA_PIN_DDR_DQ18, + TEGRA_PIN_DDR_DQ19, + TEGRA_PIN_DDR_DQ20, + TEGRA_PIN_DDR_DQ21, + TEGRA_PIN_DDR_DQ22, + TEGRA_PIN_DDR_DQ23, + TEGRA_PIN_DDR_DQ24, + TEGRA_PIN_DDR_DQ25, + TEGRA_PIN_DDR_DQ26, + TEGRA_PIN_DDR_DQ27, + TEGRA_PIN_DDR_DQ28, + TEGRA_PIN_DDR_DQ29, + TEGRA_PIN_DDR_DQ30, + TEGRA_PIN_DDR_DQ31, + TEGRA_PIN_DDR_DM0, + TEGRA_PIN_DDR_DM1, + TEGRA_PIN_DDR_DM2, + TEGRA_PIN_DDR_DM3, +}; + +static const unsigned drive_xm2clk_pins[] = { + TEGRA_PIN_DDR_CLK, + TEGRA_PIN_DDR_CLK_N, +}; + +static const unsigned drive_sdio1_pins[] = { + TEGRA_PIN_SDIO1_CLK_PZ0, + TEGRA_PIN_SDIO1_CMD_PZ1, + TEGRA_PIN_SDIO1_DAT0_PY7, + TEGRA_PIN_SDIO1_DAT1_PY6, + TEGRA_PIN_SDIO1_DAT2_PY5, + TEGRA_PIN_SDIO1_DAT3_PY4, +}; + +static const unsigned drive_crt_pins[] = { + TEGRA_PIN_CRT_HSYNC, + TEGRA_PIN_CRT_VSYNC, +}; + +static const unsigned drive_ddc_pins[] = { + TEGRA_PIN_DDC_SCL, + TEGRA_PIN_DDC_SDA, +}; + +static const unsigned drive_gma_pins[] = { + TEGRA_PIN_GMI_AD20_PAA0, + TEGRA_PIN_GMI_AD21_PAA1, + TEGRA_PIN_GMI_AD22_PAA2, + TEGRA_PIN_GMI_AD23_PAA3, +}; + +static const unsigned drive_gmb_pins[] = { + TEGRA_PIN_GMI_WP_N_PC7, +}; + +static const unsigned drive_gmc_pins[] = { + TEGRA_PIN_GMI_AD16_PJ7, + TEGRA_PIN_GMI_AD17_PB0, + TEGRA_PIN_GMI_AD18_PB1, + TEGRA_PIN_GMI_AD19_PK7, +}; + +static const unsigned drive_gmd_pins[] = { + TEGRA_PIN_GMI_CS0_N_PJ0, + TEGRA_PIN_GMI_CS1_N_PJ2, +}; + +static const unsigned drive_gme_pins[] = { + TEGRA_PIN_GMI_AD24_PAA4, + TEGRA_PIN_GMI_AD25_PAA5, + TEGRA_PIN_GMI_AD26_PAA6, + TEGRA_PIN_GMI_AD27_PAA7, +}; + +static const unsigned drive_owr_pins[] = { + TEGRA_PIN_OWC, +}; + +static const unsigned drive_uda_pins[] = { + TEGRA_PIN_ULPI_CLK_PY0, + TEGRA_PIN_ULPI_DIR_PY1, + TEGRA_PIN_ULPI_NXT_PY2, + TEGRA_PIN_ULPI_STP_PY3, +}; + +enum tegra_mux { + TEGRA_MUX_AHB_CLK, + TEGRA_MUX_APB_CLK, + TEGRA_MUX_AUDIO_SYNC, + TEGRA_MUX_CRT, + TEGRA_MUX_DAP1, + TEGRA_MUX_DAP2, + TEGRA_MUX_DAP3, + TEGRA_MUX_DAP4, + TEGRA_MUX_DAP5, + TEGRA_MUX_DISPLAYA, + TEGRA_MUX_DISPLAYB, + TEGRA_MUX_EMC_TEST0_DLL, + TEGRA_MUX_EMC_TEST1_DLL, + TEGRA_MUX_GMI, + TEGRA_MUX_GMI_INT, + TEGRA_MUX_HDMI, + TEGRA_MUX_I2CP, + TEGRA_MUX_I2C1, + TEGRA_MUX_I2C2, + TEGRA_MUX_I2C3, + TEGRA_MUX_IDE, + TEGRA_MUX_IRDA, + TEGRA_MUX_KBC, + TEGRA_MUX_MIO, + TEGRA_MUX_MIPI_HS, + TEGRA_MUX_NAND, + TEGRA_MUX_OSC, + TEGRA_MUX_OWR, + TEGRA_MUX_PCIE, + TEGRA_MUX_PLLA_OUT, + TEGRA_MUX_PLLC_OUT1, + TEGRA_MUX_PLLM_OUT1, + TEGRA_MUX_PLLP_OUT2, + TEGRA_MUX_PLLP_OUT3, + TEGRA_MUX_PLLP_OUT4, + TEGRA_MUX_PWM, + TEGRA_MUX_PWR_INTR, + TEGRA_MUX_PWR_ON, + TEGRA_MUX_RSVD1, + TEGRA_MUX_RSVD2, + TEGRA_MUX_RSVD3, + TEGRA_MUX_RSVD4, + TEGRA_MUX_RTCK, + TEGRA_MUX_SDIO1, + TEGRA_MUX_SDIO2, + TEGRA_MUX_SDIO3, + TEGRA_MUX_SDIO4, + TEGRA_MUX_SFLASH, + TEGRA_MUX_SPDIF, + TEGRA_MUX_SPI1, + TEGRA_MUX_SPI2, + TEGRA_MUX_SPI2_ALT, + TEGRA_MUX_SPI3, + TEGRA_MUX_SPI4, + TEGRA_MUX_TRACE, + TEGRA_MUX_TWC, + TEGRA_MUX_UARTA, + TEGRA_MUX_UARTB, + TEGRA_MUX_UARTC, + TEGRA_MUX_UARTD, + TEGRA_MUX_UARTE, + TEGRA_MUX_ULPI, + TEGRA_MUX_VI, + TEGRA_MUX_VI_SENSOR_CLK, + TEGRA_MUX_XIO, +}; + +static const char * const ahb_clk_groups[] = { + "cdev2", +}; + +static const char * const apb_clk_groups[] = { + "cdev2", +}; + +static const char * const audio_sync_groups[] = { + "cdev1", +}; + +static const char * const crt_groups[] = { + "crtp", + "lm1", +}; + +static const char * const dap1_groups[] = { + "dap1", +}; + +static const char * const dap2_groups[] = { + "dap2", +}; + +static const char * const dap3_groups[] = { + "dap3", +}; + +static const char * const dap4_groups[] = { + "dap4", +}; + +static const char * const dap5_groups[] = { + "gme", +}; + +static const char * const displaya_groups[] = { + "lcsn", + "ld0", + "ld1", + "ld10", + "ld11", + "ld12", + "ld13", + "ld14", + "ld15", + "ld16", + "ld17", + "ld2", + "ld3", + "ld4", + "ld5", + "ld6", + "ld7", + "ld8", + "ld9", + "ldc", + "ldi", + "lhp0", + "lhp1", + "lhp2", + "lhs", + "lm0", + "lm1", + "lpp", + "lpw0", + "lpw1", + "lpw2", + "lsc0", + "lsc1", + "lsck", + "lsda", + "lsdi", + "lspi", + "lvp0", + "lvp1", + "lvs", +}; + +static const char * const displayb_groups[] = { + "lcsn", + "ld0", + "ld1", + "ld10", + "ld11", + "ld12", + "ld13", + "ld14", + "ld15", + "ld16", + "ld17", + "ld2", + "ld3", + "ld4", + "ld5", + "ld6", + "ld7", + "ld8", + "ld9", + "ldc", + "ldi", + "lhp0", + "lhp1", + "lhp2", + "lhs", + "lm0", + "lm1", + "lpp", + "lpw0", + "lpw1", + "lpw2", + "lsc0", + "lsc1", + "lsck", + "lsda", + "lsdi", + "lspi", + "lvp0", + "lvp1", + "lvs", +}; + +static const char * const emc_test0_dll_groups[] = { + "kbca", +}; + +static const char * const emc_test1_dll_groups[] = { + "kbcc", +}; + +static const char * const gmi_groups[] = { + "ata", + "atb", + "atc", + "atd", + "ate", + "dap1", + "dap2", + "dap4", + "gma", + "gmb", + "gmc", + "gmd", + "gme", + "gpu", + "irrx", + "irtx", + "pta", + "spia", + "spib", + "spic", + "spid", + "spie", + "uca", + "ucb", +}; + +static const char * const gmi_int_groups[] = { + "gmb", +}; + +static const char * const hdmi_groups[] = { + "hdint", + "lpw0", + "lpw2", + "lsc1", + "lsck", + "lsda", + "lspi", + "pta", +}; + +static const char * const i2cp_groups[] = { + "i2cp", +}; + +static const char * const i2c1_groups[] = { + "rm", + "spdi", + "spdo", + "spig", + "spih", +}; + +static const char * const i2c2_groups[] = { + "ddc", + "pta", +}; + +static const char * const i2c3_groups[] = { + "dtf", +}; + +static const char * const ide_groups[] = { + "ata", + "atb", + "atc", + "atd", + "ate", + "gmb", +}; + +static const char * const irda_groups[] = { + "uad", +}; + +static const char * const kbc_groups[] = { + "kbca", + "kbcb", + "kbcc", + "kbcd", + "kbce", + "kbcf", +}; + +static const char * const mio_groups[] = { + "kbcb", + "kbcd", + "kbcf", +}; + +static const char * const mipi_hs_groups[] = { + "uaa", + "uab", +}; + +static const char * const nand_groups[] = { + "ata", + "atb", + "atc", + "atd", + "ate", + "gmb", + "gmd", + "kbca", + "kbcb", + "kbcc", + "kbcd", + "kbce", + "kbcf", +}; + +static const char * const osc_groups[] = { + "cdev1", + "cdev2", +}; + +static const char * const owr_groups[] = { + "kbce", + "owc", + "uac", +}; + +static const char * const pcie_groups[] = { + "gpv", + "slxa", + "slxk", +}; + +static const char * const plla_out_groups[] = { + "cdev1", +}; + +static const char * const pllc_out1_groups[] = { + "csus", +}; + +static const char * const pllm_out1_groups[] = { + "cdev1", +}; + +static const char * const pllp_out2_groups[] = { + "csus", +}; + +static const char * const pllp_out3_groups[] = { + "csus", +}; + +static const char * const pllp_out4_groups[] = { + "cdev2", +}; + +static const char * const pwm_groups[] = { + "gpu", + "sdb", + "sdc", + "sdd", + "ucb", +}; + +static const char * const pwr_intr_groups[] = { + "pmc", +}; + +static const char * const pwr_on_groups[] = { + "pmc", +}; + +static const char * const rsvd1_groups[] = { + "dta", + "dtb", + "dtc", + "dtd", + "dte", + "gmd", + "gme", +}; + +static const char * const rsvd2_groups[] = { + "crtp", + "dap1", + "dap3", + "dap4", + "ddc", + "dtb", + "dtc", + "dte", + "dtf", + "gpu7", + "gpv", + "hdint", + "i2cp", + "owc", + "rm", + "sdio1", + "spdi", + "spdo", + "uac", + "uca", + "uda", +}; + +static const char * const rsvd3_groups[] = { + "crtp", + "dap2", + "dap3", + "ddc", + "gpu7", + "gpv", + "hdint", + "i2cp", + "ld17", + "ldc", + "ldi", + "lhp0", + "lhp1", + "lhp2", + "lm1", + "lpp", + "lpw1", + "lvp0", + "lvp1", + "owc", + "pmc", + "rm", + "uac", +}; + +static const char * const rsvd4_groups[] = { + "ata", + "ate", + "crtp", + "dap3", + "dap4", + "ddc", + "dta", + "dtc", + "dtd", + "dtf", + "gpu", + "gpu7", + "gpv", + "hdint", + "i2cp", + "kbce", + "lcsn", + "ld0", + "ld1", + "ld2", + "ld3", + "ld4", + "ld5", + "ld6", + "ld7", + "ld8", + "ld9", + "ld10", + "ld11", + "ld12", + "ld13", + "ld14", + "ld15", + "ld16", + "ld17", + "ldc", + "ldi", + "lhp0", + "lhp1", + "lhp2", + "lhs", + "lm0", + "lpp", + "lpw1", + "lsc0", + "lsdi", + "lvp0", + "lvp1", + "lvs", + "owc", + "pmc", + "pta", + "rm", + "spif", + "uac", + "uca", + "ucb", +}; + +static const char * const rtck_groups[] = { + "gpu7", +}; + +static const char * const sdio1_groups[] = { + "sdio1", +}; + +static const char * const sdio2_groups[] = { + "dap1", + "dta", + "dtd", + "kbca", + "kbcb", + "kbcd", + "spdi", + "spdo", +}; + +static const char * const sdio3_groups[] = { + "sdb", + "sdc", + "sdd", + "slxa", + "slxc", + "slxd", + "slxk", +}; + +static const char * const sdio4_groups[] = { + "atb", + "atc", + "atd", + "gma", + "gme", +}; + +static const char * const sflash_groups[] = { + "gmc", + "gmd", +}; + +static const char * const spdif_groups[] = { + "slxc", + "slxd", + "spdi", + "spdo", + "uad", +}; + +static const char * const spi1_groups[] = { + "dtb", + "dte", + "spia", + "spib", + "spic", + "spid", + "spie", + "spif", + "uda", +}; + +static const char * const spi2_groups[] = { + "sdb", + "slxa", + "slxc", + "slxd", + "slxk", + "spia", + "spib", + "spic", + "spid", + "spie", + "spif", + "spig", + "spih", + "uab", +}; + +static const char * const spi2_alt_groups[] = { + "spid", + "spie", + "spig", + "spih", +}; + +static const char * const spi3_groups[] = { + "gma", + "lcsn", + "lm0", + "lpw0", + "lpw2", + "lsc1", + "lsck", + "lsda", + "lsdi", + "sdc", + "sdd", + "spia", + "spib", + "spic", + "spif", + "spig", + "spih", + "uaa", +}; + +static const char * const spi4_groups[] = { + "gmc", + "irrx", + "irtx", + "slxa", + "slxc", + "slxd", + "slxk", + "uad", +}; + +static const char * const trace_groups[] = { + "kbcc", + "kbcf", +}; + +static const char * const twc_groups[] = { + "dap2", + "sdc", +}; + +static const char * const uarta_groups[] = { + "gpu", + "irrx", + "irtx", + "sdb", + "sdd", + "sdio1", + "uaa", + "uab", + "uad", +}; + +static const char * const uartb_groups[] = { + "irrx", + "irtx", +}; + +static const char * const uartc_groups[] = { + "uca", + "ucb", +}; + +static const char * const uartd_groups[] = { + "gmc", + "uda", +}; + +static const char * const uarte_groups[] = { + "gma", + "sdio1", +}; + +static const char * const ulpi_groups[] = { + "uaa", + "uab", + "uda", +}; + +static const char * const vi_groups[] = { + "dta", + "dtb", + "dtc", + "dtd", + "dte", + "dtf", +}; + +static const char * const vi_sensor_clk_groups[] = { + "csus", +}; + +static const char * const xio_groups[] = { + "ld0", + "ld1", + "ld10", + "ld11", + "ld12", + "ld13", + "ld14", + "ld15", + "ld16", + "ld2", + "ld3", + "ld4", + "ld5", + "ld6", + "ld7", + "ld8", + "ld9", + "lhs", + "lsc0", + "lspi", + "lvs", +}; + +#define FUNCTION(fname) \ + { \ + .name = #fname, \ + .groups = fname##_groups, \ + .ngroups = ARRAY_SIZE(fname##_groups), \ + } + +static const struct tegra_function tegra20_functions[] = { + FUNCTION(ahb_clk), + FUNCTION(apb_clk), + FUNCTION(audio_sync), + FUNCTION(crt), + FUNCTION(dap1), + FUNCTION(dap2), + FUNCTION(dap3), + FUNCTION(dap4), + FUNCTION(dap5), + FUNCTION(displaya), + FUNCTION(displayb), + FUNCTION(emc_test0_dll), + FUNCTION(emc_test1_dll), + FUNCTION(gmi), + FUNCTION(gmi_int), + FUNCTION(hdmi), + FUNCTION(i2cp), + FUNCTION(i2c1), + FUNCTION(i2c2), + FUNCTION(i2c3), + FUNCTION(ide), + FUNCTION(irda), + FUNCTION(kbc), + FUNCTION(mio), + FUNCTION(mipi_hs), + FUNCTION(nand), + FUNCTION(osc), + FUNCTION(owr), + FUNCTION(pcie), + FUNCTION(plla_out), + FUNCTION(pllc_out1), + FUNCTION(pllm_out1), + FUNCTION(pllp_out2), + FUNCTION(pllp_out3), + FUNCTION(pllp_out4), + FUNCTION(pwm), + FUNCTION(pwr_intr), + FUNCTION(pwr_on), + FUNCTION(rsvd1), + FUNCTION(rsvd2), + FUNCTION(rsvd3), + FUNCTION(rsvd4), + FUNCTION(rtck), + FUNCTION(sdio1), + FUNCTION(sdio2), + FUNCTION(sdio3), + FUNCTION(sdio4), + FUNCTION(sflash), + FUNCTION(spdif), + FUNCTION(spi1), + FUNCTION(spi2), + FUNCTION(spi2_alt), + FUNCTION(spi3), + FUNCTION(spi4), + FUNCTION(trace), + FUNCTION(twc), + FUNCTION(uarta), + FUNCTION(uartb), + FUNCTION(uartc), + FUNCTION(uartd), + FUNCTION(uarte), + FUNCTION(ulpi), + FUNCTION(vi), + FUNCTION(vi_sensor_clk), + FUNCTION(xio), +}; + +#define TRISTATE_REG_A 0x14 +#define PIN_MUX_CTL_REG_A 0x80 +#define PULLUPDOWN_REG_A 0xa0 +#define PINGROUP_REG_A 0x868 + +/* Pin group with mux control, and typically tri-state and pull-up/down too */ +#define MUX_PG(pg_name, f0, f1, f2, f3, f_safe, \ + tri_r, tri_b, mux_r, mux_b, pupd_r, pupd_b) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = ARRAY_SIZE(pg_name##_pins), \ + .funcs = { \ + TEGRA_MUX_ ## f0, \ + TEGRA_MUX_ ## f1, \ + TEGRA_MUX_ ## f2, \ + TEGRA_MUX_ ## f3, \ + }, \ + .func_safe = TEGRA_MUX_ ## f_safe, \ + .mux_reg = ((mux_r) - PIN_MUX_CTL_REG_A), \ + .mux_bank = 1, \ + .mux_bit = mux_b, \ + .pupd_reg = ((pupd_r) - PULLUPDOWN_REG_A), \ + .pupd_bank = 2, \ + .pupd_bit = pupd_b, \ + .tri_reg = ((tri_r) - TRISTATE_REG_A), \ + .tri_bank = 0, \ + .tri_bit = tri_b, \ + .einput_reg = -1, \ + .odrain_reg = -1, \ + .lock_reg = -1, \ + .ioreset_reg = -1, \ + .drv_reg = -1, \ + } + +/* Pin groups with only pull up and pull down control */ +#define PULL_PG(pg_name, pupd_r, pupd_b) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = ARRAY_SIZE(pg_name##_pins), \ + .mux_reg = -1, \ + .pupd_reg = ((pupd_r) - PULLUPDOWN_REG_A), \ + .pupd_bank = 2, \ + .pupd_bit = pupd_b, \ + .tri_reg = -1, \ + .einput_reg = -1, \ + .odrain_reg = -1, \ + .lock_reg = -1, \ + .ioreset_reg = -1, \ + .drv_reg = -1, \ + } + +/* Pin groups for drive strength registers (configurable version) */ +#define DRV_PG_EXT(pg_name, r, hsm_b, schmitt_b, lpmd_b, \ + drvdn_b, drvup_b, \ + slwr_b, slwr_w, slwf_b, slwf_w) \ + { \ + .name = "drive_" #pg_name, \ + .pins = drive_##pg_name##_pins, \ + .npins = ARRAY_SIZE(drive_##pg_name##_pins), \ + .mux_reg = -1, \ + .pupd_reg = -1, \ + .tri_reg = -1, \ + .einput_reg = -1, \ + .odrain_reg = -1, \ + .lock_reg = -1, \ + .ioreset_reg = -1, \ + .drv_reg = ((r) - PINGROUP_REG_A), \ + .drv_bank = 3, \ + .hsm_bit = hsm_b, \ + .schmitt_bit = schmitt_b, \ + .lpmd_bit = lpmd_b, \ + .drvdn_bit = drvdn_b, \ + .drvdn_width = 5, \ + .drvup_bit = drvup_b, \ + .drvup_width = 5, \ + .slwr_bit = slwr_b, \ + .slwr_width = slwr_w, \ + .slwf_bit = slwf_b, \ + .slwf_width = slwf_w, \ + } + +/* Pin groups for drive strength registers (simple version) */ +#define DRV_PG(pg_name, r) \ + DRV_PG_EXT(pg_name, r, 2, 3, 4, 12, 20, 28, 2, 30, 2) + +static const struct tegra_pingroup tegra20_groups[] = { + /* name, f0, f1, f2, f3, f_safe, tri r/b, mux r/b, pupd r/b */ + MUX_PG(ata, IDE, NAND, GMI, RSVD4, IDE, 0x14, 0, 0x80, 24, 0xa0, 0), + MUX_PG(atb, IDE, NAND, GMI, SDIO4, IDE, 0x14, 1, 0x80, 16, 0xa0, 2), + MUX_PG(atc, IDE, NAND, GMI, SDIO4, IDE, 0x14, 2, 0x80, 22, 0xa0, 4), + MUX_PG(atd, IDE, NAND, GMI, SDIO4, IDE, 0x14, 3, 0x80, 20, 0xa0, 6), + MUX_PG(ate, IDE, NAND, GMI, RSVD4, IDE, 0x18, 25, 0x80, 12, 0xa0, 8), + MUX_PG(cdev1, OSC, PLLA_OUT, PLLM_OUT1, AUDIO_SYNC, OSC, 0x14, 4, 0x88, 2, 0xa8, 0), + MUX_PG(cdev2, OSC, AHB_CLK, APB_CLK, PLLP_OUT4, OSC, 0x14, 5, 0x88, 4, 0xa8, 2), + MUX_PG(crtp, CRT, RSVD2, RSVD3, RSVD4, RSVD2, 0x20, 14, 0x98, 20, 0xa4, 24), + MUX_PG(csus, PLLC_OUT1, PLLP_OUT2, PLLP_OUT3, VI_SENSOR_CLK, PLLC_OUT1, 0x14, 6, 0x88, 6, 0xac, 24), + MUX_PG(dap1, DAP1, RSVD2, GMI, SDIO2, DAP1, 0x14, 7, 0x88, 20, 0xa0, 10), + MUX_PG(dap2, DAP2, TWC, RSVD3, GMI, DAP2, 0x14, 8, 0x88, 22, 0xa0, 12), + MUX_PG(dap3, DAP3, RSVD2, RSVD3, RSVD4, DAP3, 0x14, 9, 0x88, 24, 0xa0, 14), + MUX_PG(dap4, DAP4, RSVD2, GMI, RSVD4, DAP4, 0x14, 10, 0x88, 26, 0xa0, 16), + MUX_PG(ddc, I2C2, RSVD2, RSVD3, RSVD4, RSVD4, 0x18, 31, 0x88, 0, 0xb0, 28), + MUX_PG(dta, RSVD1, SDIO2, VI, RSVD4, RSVD4, 0x14, 11, 0x84, 20, 0xa0, 18), + MUX_PG(dtb, RSVD1, RSVD2, VI, SPI1, RSVD1, 0x14, 12, 0x84, 22, 0xa0, 20), + MUX_PG(dtc, RSVD1, RSVD2, VI, RSVD4, RSVD1, 0x14, 13, 0x84, 26, 0xa0, 22), + MUX_PG(dtd, RSVD1, SDIO2, VI, RSVD4, RSVD1, 0x14, 14, 0x84, 28, 0xa0, 24), + MUX_PG(dte, RSVD1, RSVD2, VI, SPI1, RSVD1, 0x14, 15, 0x84, 30, 0xa0, 26), + MUX_PG(dtf, I2C3, RSVD2, VI, RSVD4, RSVD4, 0x20, 12, 0x98, 30, 0xa0, 28), + MUX_PG(gma, UARTE, SPI3, GMI, SDIO4, SPI3, 0x14, 28, 0x84, 0, 0xb0, 20), + MUX_PG(gmb, IDE, NAND, GMI, GMI_INT, GMI, 0x18, 29, 0x88, 28, 0xb0, 22), + MUX_PG(gmc, UARTD, SPI4, GMI, SFLASH, SPI4, 0x14, 29, 0x84, 2, 0xb0, 24), + MUX_PG(gmd, RSVD1, NAND, GMI, SFLASH, GMI, 0x18, 30, 0x88, 30, 0xb0, 26), + MUX_PG(gme, RSVD1, DAP5, GMI, SDIO4, GMI, 0x18, 0, 0x8c, 0, 0xa8, 24), + MUX_PG(gpu, PWM, UARTA, GMI, RSVD4, RSVD4, 0x14, 16, 0x8c, 4, 0xa4, 20), + MUX_PG(gpu7, RTCK, RSVD2, RSVD3, RSVD4, RTCK, 0x20, 11, 0x98, 28, 0xa4, 6), + MUX_PG(gpv, PCIE, RSVD2, RSVD3, RSVD4, PCIE, 0x14, 17, 0x8c, 2, 0xa0, 30), + MUX_PG(hdint, HDMI, RSVD2, RSVD3, RSVD4, HDMI, 0x1c, 23, 0x84, 4, -1, -1), + MUX_PG(i2cp, I2CP, RSVD2, RSVD3, RSVD4, RSVD4, 0x14, 18, 0x88, 8, 0xa4, 2), + MUX_PG(irrx, UARTA, UARTB, GMI, SPI4, UARTB, 0x14, 20, 0x88, 18, 0xa8, 22), + MUX_PG(irtx, UARTA, UARTB, GMI, SPI4, UARTB, 0x14, 19, 0x88, 16, 0xa8, 20), + MUX_PG(kbca, KBC, NAND, SDIO2, EMC_TEST0_DLL, KBC, 0x14, 22, 0x88, 10, 0xa4, 8), + MUX_PG(kbcb, KBC, NAND, SDIO2, MIO, KBC, 0x14, 21, 0x88, 12, 0xa4, 10), + MUX_PG(kbcc, KBC, NAND, TRACE, EMC_TEST1_DLL, KBC, 0x18, 26, 0x88, 14, 0xa4, 12), + MUX_PG(kbcd, KBC, NAND, SDIO2, MIO, KBC, 0x20, 10, 0x98, 26, 0xa4, 14), + MUX_PG(kbce, KBC, NAND, OWR, RSVD4, KBC, 0x14, 26, 0x80, 28, 0xb0, 2), + MUX_PG(kbcf, KBC, NAND, TRACE, MIO, KBC, 0x14, 27, 0x80, 26, 0xb0, 0), + MUX_PG(lcsn, DISPLAYA, DISPLAYB, SPI3, RSVD4, RSVD4, 0x1c, 31, 0x90, 12, -1, -1), + MUX_PG(ld0, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 0, 0x94, 0, -1, -1), + MUX_PG(ld1, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 1, 0x94, 2, -1, -1), + MUX_PG(ld2, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 2, 0x94, 4, -1, -1), + MUX_PG(ld3, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 3, 0x94, 6, -1, -1), + MUX_PG(ld4, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 4, 0x94, 8, -1, -1), + MUX_PG(ld5, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 5, 0x94, 10, -1, -1), + MUX_PG(ld6, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 6, 0x94, 12, -1, -1), + MUX_PG(ld7, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 7, 0x94, 14, -1, -1), + MUX_PG(ld8, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 8, 0x94, 16, -1, -1), + MUX_PG(ld9, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 9, 0x94, 18, -1, -1), + MUX_PG(ld10, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 10, 0x94, 20, -1, -1), + MUX_PG(ld11, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 11, 0x94, 22, -1, -1), + MUX_PG(ld12, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 12, 0x94, 24, -1, -1), + MUX_PG(ld13, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 13, 0x94, 26, -1, -1), + MUX_PG(ld14, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 14, 0x94, 28, -1, -1), + MUX_PG(ld15, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 15, 0x94, 30, -1, -1), + MUX_PG(ld16, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 16, 0x98, 0, -1, -1), + MUX_PG(ld17, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x1c, 17, 0x98, 2, -1, -1), + MUX_PG(ldc, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x1c, 30, 0x90, 14, -1, -1), + MUX_PG(ldi, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x20, 6, 0x98, 16, -1, -1), + MUX_PG(lhp0, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x1c, 18, 0x98, 10, -1, -1), + MUX_PG(lhp1, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x1c, 19, 0x98, 4, -1, -1), + MUX_PG(lhp2, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x1c, 20, 0x98, 6, -1, -1), + MUX_PG(lhs, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x20, 7, 0x90, 22, -1, -1), + MUX_PG(lm0, DISPLAYA, DISPLAYB, SPI3, RSVD4, RSVD4, 0x1c, 24, 0x90, 26, -1, -1), + MUX_PG(lm1, DISPLAYA, DISPLAYB, RSVD3, CRT, RSVD3, 0x1c, 25, 0x90, 28, -1, -1), + MUX_PG(lpp, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x20, 8, 0x98, 14, -1, -1), + MUX_PG(lpw0, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 3, 0x90, 0, -1, -1), + MUX_PG(lpw1, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x20, 4, 0x90, 2, -1, -1), + MUX_PG(lpw2, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 5, 0x90, 4, -1, -1), + MUX_PG(lsc0, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 27, 0x90, 18, -1, -1), + MUX_PG(lsc1, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x1c, 28, 0x90, 20, -1, -1), + MUX_PG(lsck, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x1c, 29, 0x90, 16, -1, -1), + MUX_PG(lsda, DISPLAYA, DISPLAYB, SPI3, HDMI, DISPLAYA, 0x20, 1, 0x90, 8, -1, -1), + MUX_PG(lsdi, DISPLAYA, DISPLAYB, SPI3, RSVD4, DISPLAYA, 0x20, 2, 0x90, 6, -1, -1), + MUX_PG(lspi, DISPLAYA, DISPLAYB, XIO, HDMI, DISPLAYA, 0x20, 0, 0x90, 10, -1, -1), + MUX_PG(lvp0, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x1c, 21, 0x90, 30, -1, -1), + MUX_PG(lvp1, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x1c, 22, 0x98, 8, -1, -1), + MUX_PG(lvs, DISPLAYA, DISPLAYB, XIO, RSVD4, RSVD4, 0x1c, 26, 0x90, 24, -1, -1), + MUX_PG(owc, OWR, RSVD2, RSVD3, RSVD4, OWR, 0x14, 31, 0x84, 8, 0xb0, 30), + MUX_PG(pmc, PWR_ON, PWR_INTR, RSVD3, RSVD4, PWR_ON, 0x14, 23, 0x98, 18, -1, -1), + MUX_PG(pta, I2C2, HDMI, GMI, RSVD4, RSVD4, 0x14, 24, 0x98, 22, 0xa4, 4), + MUX_PG(rm, I2C1, RSVD2, RSVD3, RSVD4, RSVD4, 0x14, 25, 0x80, 14, 0xa4, 0), + MUX_PG(sdb, UARTA, PWM, SDIO3, SPI2, PWM, 0x20, 15, 0x8c, 10, -1, -1), + MUX_PG(sdc, PWM, TWC, SDIO3, SPI3, TWC, 0x18, 1, 0x8c, 12, 0xac, 28), + MUX_PG(sdd, UARTA, PWM, SDIO3, SPI3, PWM, 0x18, 2, 0x8c, 14, 0xac, 30), + MUX_PG(sdio1, SDIO1, RSVD2, UARTE, UARTA, RSVD2, 0x14, 30, 0x80, 30, 0xb0, 18), + MUX_PG(slxa, PCIE, SPI4, SDIO3, SPI2, PCIE, 0x18, 3, 0x84, 6, 0xa4, 22), + MUX_PG(slxc, SPDIF, SPI4, SDIO3, SPI2, SPI4, 0x18, 5, 0x84, 10, 0xa4, 26), + MUX_PG(slxd, SPDIF, SPI4, SDIO3, SPI2, SPI4, 0x18, 6, 0x84, 12, 0xa4, 28), + MUX_PG(slxk, PCIE, SPI4, SDIO3, SPI2, PCIE, 0x18, 7, 0x84, 14, 0xa4, 30), + MUX_PG(spdi, SPDIF, RSVD2, I2C1, SDIO2, RSVD2, 0x18, 8, 0x8c, 8, 0xa4, 16), + MUX_PG(spdo, SPDIF, RSVD2, I2C1, SDIO2, RSVD2, 0x18, 9, 0x8c, 6, 0xa4, 18), + MUX_PG(spia, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 10, 0x8c, 30, 0xa8, 4), + MUX_PG(spib, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 11, 0x8c, 28, 0xa8, 6), + MUX_PG(spic, SPI1, SPI2, SPI3, GMI, GMI, 0x18, 12, 0x8c, 26, 0xa8, 8), + MUX_PG(spid, SPI2, SPI1, SPI2_ALT, GMI, GMI, 0x18, 13, 0x8c, 24, 0xa8, 10), + MUX_PG(spie, SPI2, SPI1, SPI2_ALT, GMI, GMI, 0x18, 14, 0x8c, 22, 0xa8, 12), + MUX_PG(spif, SPI3, SPI1, SPI2, RSVD4, RSVD4, 0x18, 15, 0x8c, 20, 0xa8, 14), + MUX_PG(spig, SPI3, SPI2, SPI2_ALT, I2C1, SPI2_ALT, 0x18, 16, 0x8c, 18, 0xa8, 16), + MUX_PG(spih, SPI3, SPI2, SPI2_ALT, I2C1, SPI2_ALT, 0x18, 17, 0x8c, 16, 0xa8, 18), + MUX_PG(uaa, SPI3, MIPI_HS, UARTA, ULPI, MIPI_HS, 0x18, 18, 0x80, 0, 0xac, 0), + MUX_PG(uab, SPI2, MIPI_HS, UARTA, ULPI, MIPI_HS, 0x18, 19, 0x80, 2, 0xac, 2), + MUX_PG(uac, OWR, RSVD2, RSVD3, RSVD4, RSVD4, 0x18, 20, 0x80, 4, 0xac, 4), + MUX_PG(uad, IRDA, SPDIF, UARTA, SPI4, SPDIF, 0x18, 21, 0x80, 6, 0xac, 6), + MUX_PG(uca, UARTC, RSVD2, GMI, RSVD4, RSVD4, 0x18, 22, 0x84, 16, 0xac, 8), + MUX_PG(ucb, UARTC, PWM, GMI, RSVD4, RSVD4, 0x18, 23, 0x84, 18, 0xac, 10), + MUX_PG(uda, SPI1, RSVD2, UARTD, ULPI, RSVD2, 0x20, 13, 0x80, 8, 0xb0, 16), + /* pg_name, pupd_r/b */ + PULL_PG(ck32, 0xb0, 14), + PULL_PG(ddrc, 0xac, 26), + PULL_PG(pmca, 0xb0, 4), + PULL_PG(pmcb, 0xb0, 6), + PULL_PG(pmcc, 0xb0, 8), + PULL_PG(pmcd, 0xb0, 10), + PULL_PG(pmce, 0xb0, 12), + PULL_PG(xm2c, 0xa8, 30), + PULL_PG(xm2d, 0xa8, 28), + PULL_PG(ls, 0xac, 20), + PULL_PG(lc, 0xac, 22), + PULL_PG(ld17_0, 0xac, 12), + PULL_PG(ld19_18, 0xac, 14), + PULL_PG(ld21_20, 0xac, 16), + PULL_PG(ld23_22, 0xac, 18), + /* pg_name, r */ + DRV_PG(ao1, 0x868), + DRV_PG(ao2, 0x86c), + DRV_PG(at1, 0x870), + DRV_PG(at2, 0x874), + DRV_PG(cdev1, 0x878), + DRV_PG(cdev2, 0x87c), + DRV_PG(csus, 0x880), + DRV_PG(dap1, 0x884), + DRV_PG(dap2, 0x888), + DRV_PG(dap3, 0x88c), + DRV_PG(dap4, 0x890), + DRV_PG(dbg, 0x894), + DRV_PG(lcd1, 0x898), + DRV_PG(lcd2, 0x89c), + DRV_PG(sdmmc2, 0x8a0), + DRV_PG(sdmmc3, 0x8a4), + DRV_PG(spi, 0x8a8), + DRV_PG(uaa, 0x8ac), + DRV_PG(uab, 0x8b0), + DRV_PG(uart2, 0x8b4), + DRV_PG(uart3, 0x8b8), + DRV_PG(vi1, 0x8bc), + DRV_PG(vi2, 0x8c0), + /* pg_name, r, hsm_b, schmitt_b, lpmd_b, drvdn_b, drvup_b, slwr_b, slwr_w, slwf_b, slwf_w */ + DRV_PG_EXT(xm2a, 0x8c4, -1, -1, 4, 14, 19, 24, 4, 28, 4), + DRV_PG_EXT(xm2c, 0x8c8, -1, 3, -1, 14, 19, 24, 4, 28, 4), + DRV_PG_EXT(xm2d, 0x8cc, -1, 3, -1, 14, 19, 24, 4, 28, 4), + DRV_PG_EXT(xm2clk, 0x8d0, -1, -1, -1, 14, 19, 24, 4, 28, 4), + /* pg_name, r */ + DRV_PG(sdio1, 0x8e0), + DRV_PG(crt, 0x8ec), + DRV_PG(ddc, 0x8f0), + DRV_PG(gma, 0x8f4), + DRV_PG(gmb, 0x8f8), + DRV_PG(gmc, 0x8fc), + DRV_PG(gmd, 0x900), + DRV_PG(gme, 0x904), + DRV_PG(owr, 0x908), + DRV_PG(uda, 0x90c), +}; + +static const struct tegra_pinctrl_soc_data tegra20_pinctrl = { + .ngpios = NUM_GPIOS, + .pins = tegra20_pins, + .npins = ARRAY_SIZE(tegra20_pins), + .functions = tegra20_functions, + .nfunctions = ARRAY_SIZE(tegra20_functions), + .groups = tegra20_groups, + .ngroups = ARRAY_SIZE(tegra20_groups), +}; + +void __devinit tegra20_pinctrl_init(const struct tegra_pinctrl_soc_data **soc) +{ + *soc = &tegra20_pinctrl; +} diff --git a/drivers/pinctrl/pinctrl-tegra30.c b/drivers/pinctrl/pinctrl-tegra30.c new file mode 100644 index 0000000..4d7571d --- /dev/null +++ b/drivers/pinctrl/pinctrl-tegra30.c @@ -0,0 +1,3726 @@ +/* + * Pinctrl data for the NVIDIA Tegra30 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. + */ + +#include +#include +#include + +#include "pinctrl-tegra.h" + +/* + * Most pins affected by the pinmux can also be GPIOs. Define these first. + * These must match how the GPIO driver names/numbers its pins. + */ +#define _GPIO(offset) (offset) + +#define TEGRA_PIN_CLK_32K_OUT_PA0 _GPIO(0) +#define TEGRA_PIN_UART3_CTS_N_PA1 _GPIO(1) +#define TEGRA_PIN_DAP2_FS_PA2 _GPIO(2) +#define TEGRA_PIN_DAP2_SCLK_PA3 _GPIO(3) +#define TEGRA_PIN_DAP2_DIN_PA4 _GPIO(4) +#define TEGRA_PIN_DAP2_DOUT_PA5 _GPIO(5) +#define TEGRA_PIN_SDMMC3_CLK_PA6 _GPIO(6) +#define TEGRA_PIN_SDMMC3_CMD_PA7 _GPIO(7) +#define TEGRA_PIN_GMI_A17_PB0 _GPIO(8) +#define TEGRA_PIN_GMI_A18_PB1 _GPIO(9) +#define TEGRA_PIN_LCD_PWR0_PB2 _GPIO(10) +#define TEGRA_PIN_LCD_PCLK_PB3 _GPIO(11) +#define TEGRA_PIN_SDMMC3_DAT3_PB4 _GPIO(12) +#define TEGRA_PIN_SDMMC3_DAT2_PB5 _GPIO(13) +#define TEGRA_PIN_SDMMC3_DAT1_PB6 _GPIO(14) +#define TEGRA_PIN_SDMMC3_DAT0_PB7 _GPIO(15) +#define TEGRA_PIN_UART3_RTS_N_PC0 _GPIO(16) +#define TEGRA_PIN_LCD_PWR1_PC1 _GPIO(17) +#define TEGRA_PIN_UART2_TXD_PC2 _GPIO(18) +#define TEGRA_PIN_UART2_RXD_PC3 _GPIO(19) +#define TEGRA_PIN_GEN1_I2C_SCL_PC4 _GPIO(20) +#define TEGRA_PIN_GEN1_I2C_SDA_PC5 _GPIO(21) +#define TEGRA_PIN_LCD_PWR2_PC6 _GPIO(22) +#define TEGRA_PIN_GMI_WP_N_PC7 _GPIO(23) +#define TEGRA_PIN_SDMMC3_DAT5_PD0 _GPIO(24) +#define TEGRA_PIN_SDMMC3_DAT4_PD1 _GPIO(25) +#define TEGRA_PIN_LCD_DC1_PD2 _GPIO(26) +#define TEGRA_PIN_SDMMC3_DAT6_PD3 _GPIO(27) +#define TEGRA_PIN_SDMMC3_DAT7_PD4 _GPIO(28) +#define TEGRA_PIN_VI_D1_PD5 _GPIO(29) +#define TEGRA_PIN_VI_VSYNC_PD6 _GPIO(30) +#define TEGRA_PIN_VI_HSYNC_PD7 _GPIO(31) +#define TEGRA_PIN_LCD_D0_PE0 _GPIO(32) +#define TEGRA_PIN_LCD_D1_PE1 _GPIO(33) +#define TEGRA_PIN_LCD_D2_PE2 _GPIO(34) +#define TEGRA_PIN_LCD_D3_PE3 _GPIO(35) +#define TEGRA_PIN_LCD_D4_PE4 _GPIO(36) +#define TEGRA_PIN_LCD_D5_PE5 _GPIO(37) +#define TEGRA_PIN_LCD_D6_PE6 _GPIO(38) +#define TEGRA_PIN_LCD_D7_PE7 _GPIO(39) +#define TEGRA_PIN_LCD_D8_PF0 _GPIO(40) +#define TEGRA_PIN_LCD_D9_PF1 _GPIO(41) +#define TEGRA_PIN_LCD_D10_PF2 _GPIO(42) +#define TEGRA_PIN_LCD_D11_PF3 _GPIO(43) +#define TEGRA_PIN_LCD_D12_PF4 _GPIO(44) +#define TEGRA_PIN_LCD_D13_PF5 _GPIO(45) +#define TEGRA_PIN_LCD_D14_PF6 _GPIO(46) +#define TEGRA_PIN_LCD_D15_PF7 _GPIO(47) +#define TEGRA_PIN_GMI_AD0_PG0 _GPIO(48) +#define TEGRA_PIN_GMI_AD1_PG1 _GPIO(49) +#define TEGRA_PIN_GMI_AD2_PG2 _GPIO(50) +#define TEGRA_PIN_GMI_AD3_PG3 _GPIO(51) +#define TEGRA_PIN_GMI_AD4_PG4 _GPIO(52) +#define TEGRA_PIN_GMI_AD5_PG5 _GPIO(53) +#define TEGRA_PIN_GMI_AD6_PG6 _GPIO(54) +#define TEGRA_PIN_GMI_AD7_PG7 _GPIO(55) +#define TEGRA_PIN_GMI_AD8_PH0 _GPIO(56) +#define TEGRA_PIN_GMI_AD9_PH1 _GPIO(57) +#define TEGRA_PIN_GMI_AD10_PH2 _GPIO(58) +#define TEGRA_PIN_GMI_AD11_PH3 _GPIO(59) +#define TEGRA_PIN_GMI_AD12_PH4 _GPIO(60) +#define TEGRA_PIN_GMI_AD13_PH5 _GPIO(61) +#define TEGRA_PIN_GMI_AD14_PH6 _GPIO(62) +#define TEGRA_PIN_GMI_AD15_PH7 _GPIO(63) +#define TEGRA_PIN_GMI_WR_N_PI0 _GPIO(64) +#define TEGRA_PIN_GMI_OE_N_PI1 _GPIO(65) +#define TEGRA_PIN_GMI_DQS_PI2 _GPIO(66) +#define TEGRA_PIN_GMI_CS6_N_PI3 _GPIO(67) +#define TEGRA_PIN_GMI_RST_N_PI4 _GPIO(68) +#define TEGRA_PIN_GMI_IORDY_PI5 _GPIO(69) +#define TEGRA_PIN_GMI_CS7_N_PI6 _GPIO(70) +#define TEGRA_PIN_GMI_WAIT_PI7 _GPIO(71) +#define TEGRA_PIN_GMI_CS0_N_PJ0 _GPIO(72) +#define TEGRA_PIN_LCD_DE_PJ1 _GPIO(73) +#define TEGRA_PIN_GMI_CS1_N_PJ2 _GPIO(74) +#define TEGRA_PIN_LCD_HSYNC_PJ3 _GPIO(75) +#define TEGRA_PIN_LCD_VSYNC_PJ4 _GPIO(76) +#define TEGRA_PIN_UART2_CTS_N_PJ5 _GPIO(77) +#define TEGRA_PIN_UART2_RTS_N_PJ6 _GPIO(78) +#define TEGRA_PIN_GMI_A16_PJ7 _GPIO(79) +#define TEGRA_PIN_GMI_ADV_N_PK0 _GPIO(80) +#define TEGRA_PIN_GMI_CLK_PK1 _GPIO(81) +#define TEGRA_PIN_GMI_CS4_N_PK2 _GPIO(82) +#define TEGRA_PIN_GMI_CS2_N_PK3 _GPIO(83) +#define TEGRA_PIN_GMI_CS3_N_PK4 _GPIO(84) +#define TEGRA_PIN_SPDIF_OUT_PK5 _GPIO(85) +#define TEGRA_PIN_SPDIF_IN_PK6 _GPIO(86) +#define TEGRA_PIN_GMI_A19_PK7 _GPIO(87) +#define TEGRA_PIN_VI_D2_PL0 _GPIO(88) +#define TEGRA_PIN_VI_D3_PL1 _GPIO(89) +#define TEGRA_PIN_VI_D4_PL2 _GPIO(90) +#define TEGRA_PIN_VI_D5_PL3 _GPIO(91) +#define TEGRA_PIN_VI_D6_PL4 _GPIO(92) +#define TEGRA_PIN_VI_D7_PL5 _GPIO(93) +#define TEGRA_PIN_VI_D8_PL6 _GPIO(94) +#define TEGRA_PIN_VI_D9_PL7 _GPIO(95) +#define TEGRA_PIN_LCD_D16_PM0 _GPIO(96) +#define TEGRA_PIN_LCD_D17_PM1 _GPIO(97) +#define TEGRA_PIN_LCD_D18_PM2 _GPIO(98) +#define TEGRA_PIN_LCD_D19_PM3 _GPIO(99) +#define TEGRA_PIN_LCD_D20_PM4 _GPIO(100) +#define TEGRA_PIN_LCD_D21_PM5 _GPIO(101) +#define TEGRA_PIN_LCD_D22_PM6 _GPIO(102) +#define TEGRA_PIN_LCD_D23_PM7 _GPIO(103) +#define TEGRA_PIN_DAP1_FS_PN0 _GPIO(104) +#define TEGRA_PIN_DAP1_DIN_PN1 _GPIO(105) +#define TEGRA_PIN_DAP1_DOUT_PN2 _GPIO(106) +#define TEGRA_PIN_DAP1_SCLK_PN3 _GPIO(107) +#define TEGRA_PIN_LCD_CS0_N_PN4 _GPIO(108) +#define TEGRA_PIN_LCD_SDOUT_PN5 _GPIO(109) +#define TEGRA_PIN_LCD_DC0_PN6 _GPIO(110) +#define TEGRA_PIN_HDMI_INT_PN7 _GPIO(111) +#define TEGRA_PIN_ULPI_DATA7_PO0 _GPIO(112) +#define TEGRA_PIN_ULPI_DATA0_PO1 _GPIO(113) +#define TEGRA_PIN_ULPI_DATA1_PO2 _GPIO(114) +#define TEGRA_PIN_ULPI_DATA2_PO3 _GPIO(115) +#define TEGRA_PIN_ULPI_DATA3_PO4 _GPIO(116) +#define TEGRA_PIN_ULPI_DATA4_PO5 _GPIO(117) +#define TEGRA_PIN_ULPI_DATA5_PO6 _GPIO(118) +#define TEGRA_PIN_ULPI_DATA6_PO7 _GPIO(119) +#define TEGRA_PIN_DAP3_FS_PP0 _GPIO(120) +#define TEGRA_PIN_DAP3_DIN_PP1 _GPIO(121) +#define TEGRA_PIN_DAP3_DOUT_PP2 _GPIO(122) +#define TEGRA_PIN_DAP3_SCLK_PP3 _GPIO(123) +#define TEGRA_PIN_DAP4_FS_PP4 _GPIO(124) +#define TEGRA_PIN_DAP4_DIN_PP5 _GPIO(125) +#define TEGRA_PIN_DAP4_DOUT_PP6 _GPIO(126) +#define TEGRA_PIN_DAP4_SCLK_PP7 _GPIO(127) +#define TEGRA_PIN_KB_COL0_PQ0 _GPIO(128) +#define TEGRA_PIN_KB_COL1_PQ1 _GPIO(129) +#define TEGRA_PIN_KB_COL2_PQ2 _GPIO(130) +#define TEGRA_PIN_KB_COL3_PQ3 _GPIO(131) +#define TEGRA_PIN_KB_COL4_PQ4 _GPIO(132) +#define TEGRA_PIN_KB_COL5_PQ5 _GPIO(133) +#define TEGRA_PIN_KB_COL6_PQ6 _GPIO(134) +#define TEGRA_PIN_KB_COL7_PQ7 _GPIO(135) +#define TEGRA_PIN_KB_ROW0_PR0 _GPIO(136) +#define TEGRA_PIN_KB_ROW1_PR1 _GPIO(137) +#define TEGRA_PIN_KB_ROW2_PR2 _GPIO(138) +#define TEGRA_PIN_KB_ROW3_PR3 _GPIO(139) +#define TEGRA_PIN_KB_ROW4_PR4 _GPIO(140) +#define TEGRA_PIN_KB_ROW5_PR5 _GPIO(141) +#define TEGRA_PIN_KB_ROW6_PR6 _GPIO(142) +#define TEGRA_PIN_KB_ROW7_PR7 _GPIO(143) +#define TEGRA_PIN_KB_ROW8_PS0 _GPIO(144) +#define TEGRA_PIN_KB_ROW9_PS1 _GPIO(145) +#define TEGRA_PIN_KB_ROW10_PS2 _GPIO(146) +#define TEGRA_PIN_KB_ROW11_PS3 _GPIO(147) +#define TEGRA_PIN_KB_ROW12_PS4 _GPIO(148) +#define TEGRA_PIN_KB_ROW13_PS5 _GPIO(149) +#define TEGRA_PIN_KB_ROW14_PS6 _GPIO(150) +#define TEGRA_PIN_KB_ROW15_PS7 _GPIO(151) +#define TEGRA_PIN_VI_PCLK_PT0 _GPIO(152) +#define TEGRA_PIN_VI_MCLK_PT1 _GPIO(153) +#define TEGRA_PIN_VI_D10_PT2 _GPIO(154) +#define TEGRA_PIN_VI_D11_PT3 _GPIO(155) +#define TEGRA_PIN_VI_D0_PT4 _GPIO(156) +#define TEGRA_PIN_GEN2_I2C_SCL_PT5 _GPIO(157) +#define TEGRA_PIN_GEN2_I2C_SDA_PT6 _GPIO(158) +#define TEGRA_PIN_SDMMC4_CMD_PT7 _GPIO(159) +#define TEGRA_PIN_PU0 _GPIO(160) +#define TEGRA_PIN_PU1 _GPIO(161) +#define TEGRA_PIN_PU2 _GPIO(162) +#define TEGRA_PIN_PU3 _GPIO(163) +#define TEGRA_PIN_PU4 _GPIO(164) +#define TEGRA_PIN_PU5 _GPIO(165) +#define TEGRA_PIN_PU6 _GPIO(166) +#define TEGRA_PIN_JTAG_RTCK_PU7 _GPIO(167) +#define TEGRA_PIN_PV0 _GPIO(168) +#define TEGRA_PIN_PV1 _GPIO(169) +#define TEGRA_PIN_PV2 _GPIO(170) +#define TEGRA_PIN_PV3 _GPIO(171) +#define TEGRA_PIN_DDC_SCL_PV4 _GPIO(172) +#define TEGRA_PIN_DDC_SDA_PV5 _GPIO(173) +#define TEGRA_PIN_CRT_HSYNC_PV6 _GPIO(174) +#define TEGRA_PIN_CRT_VSYNC_PV7 _GPIO(175) +#define TEGRA_PIN_LCD_CS1_N_PW0 _GPIO(176) +#define TEGRA_PIN_LCD_M1_PW1 _GPIO(177) +#define TEGRA_PIN_SPI2_CS1_N_PW2 _GPIO(178) +#define TEGRA_PIN_SPI2_CS2_N_PW3 _GPIO(179) +#define TEGRA_PIN_CLK1_OUT_PW4 _GPIO(180) +#define TEGRA_PIN_CLK2_OUT_PW5 _GPIO(181) +#define TEGRA_PIN_UART3_TXD_PW6 _GPIO(182) +#define TEGRA_PIN_UART3_RXD_PW7 _GPIO(183) +#define TEGRA_PIN_SPI2_MOSI_PX0 _GPIO(184) +#define TEGRA_PIN_SPI2_MISO_PX1 _GPIO(185) +#define TEGRA_PIN_SPI2_SCK_PX2 _GPIO(186) +#define TEGRA_PIN_SPI2_CS0_N_PX3 _GPIO(187) +#define TEGRA_PIN_SPI1_MOSI_PX4 _GPIO(188) +#define TEGRA_PIN_SPI1_SCK_PX5 _GPIO(189) +#define TEGRA_PIN_SPI1_CS0_N_PX6 _GPIO(190) +#define TEGRA_PIN_SPI1_MISO_PX7 _GPIO(191) +#define TEGRA_PIN_ULPI_CLK_PY0 _GPIO(192) +#define TEGRA_PIN_ULPI_DIR_PY1 _GPIO(193) +#define TEGRA_PIN_ULPI_NXT_PY2 _GPIO(194) +#define TEGRA_PIN_ULPI_STP_PY3 _GPIO(195) +#define TEGRA_PIN_SDMMC1_DAT3_PY4 _GPIO(196) +#define TEGRA_PIN_SDMMC1_DAT2_PY5 _GPIO(197) +#define TEGRA_PIN_SDMMC1_DAT1_PY6 _GPIO(198) +#define TEGRA_PIN_SDMMC1_DAT0_PY7 _GPIO(199) +#define TEGRA_PIN_SDMMC1_CLK_PZ0 _GPIO(200) +#define TEGRA_PIN_SDMMC1_CMD_PZ1 _GPIO(201) +#define TEGRA_PIN_LCD_SDIN_PZ2 _GPIO(202) +#define TEGRA_PIN_LCD_WR_N_PZ3 _GPIO(203) +#define TEGRA_PIN_LCD_SCK_PZ4 _GPIO(204) +#define TEGRA_PIN_SYS_CLK_REQ_PZ5 _GPIO(205) +#define TEGRA_PIN_PWR_I2C_SCL_PZ6 _GPIO(206) +#define TEGRA_PIN_PWR_I2C_SDA_PZ7 _GPIO(207) +#define TEGRA_PIN_SDMMC4_DAT0_PAA0 _GPIO(208) +#define TEGRA_PIN_SDMMC4_DAT1_PAA1 _GPIO(209) +#define TEGRA_PIN_SDMMC4_DAT2_PAA2 _GPIO(210) +#define TEGRA_PIN_SDMMC4_DAT3_PAA3 _GPIO(211) +#define TEGRA_PIN_SDMMC4_DAT4_PAA4 _GPIO(212) +#define TEGRA_PIN_SDMMC4_DAT5_PAA5 _GPIO(213) +#define TEGRA_PIN_SDMMC4_DAT6_PAA6 _GPIO(214) +#define TEGRA_PIN_SDMMC4_DAT7_PAA7 _GPIO(215) +#define TEGRA_PIN_PBB0 _GPIO(216) +#define TEGRA_PIN_CAM_I2C_SCL_PBB1 _GPIO(217) +#define TEGRA_PIN_CAM_I2C_SDA_PBB2 _GPIO(218) +#define TEGRA_PIN_PBB3 _GPIO(219) +#define TEGRA_PIN_PBB4 _GPIO(220) +#define TEGRA_PIN_PBB5 _GPIO(221) +#define TEGRA_PIN_PBB6 _GPIO(222) +#define TEGRA_PIN_PBB7 _GPIO(223) +#define TEGRA_PIN_CAM_MCLK_PCC0 _GPIO(224) +#define TEGRA_PIN_PCC1 _GPIO(225) +#define TEGRA_PIN_PCC2 _GPIO(226) +#define TEGRA_PIN_SDMMC4_RST_N_PCC3 _GPIO(227) +#define TEGRA_PIN_SDMMC4_CLK_PCC4 _GPIO(228) +#define TEGRA_PIN_CLK2_REQ_PCC5 _GPIO(229) +#define TEGRA_PIN_PEX_L2_RST_N_PCC6 _GPIO(230) +#define TEGRA_PIN_PEX_L2_CLKREQ_N_PCC7 _GPIO(231) +#define TEGRA_PIN_PEX_L0_PRSNT_N_PDD0 _GPIO(232) +#define TEGRA_PIN_PEX_L0_RST_N_PDD1 _GPIO(233) +#define TEGRA_PIN_PEX_L0_CLKREQ_N_PDD2 _GPIO(234) +#define TEGRA_PIN_PEX_WAKE_N_PDD3 _GPIO(235) +#define TEGRA_PIN_PEX_L1_PRSNT_N_PDD4 _GPIO(236) +#define TEGRA_PIN_PEX_L1_RST_N_PDD5 _GPIO(237) +#define TEGRA_PIN_PEX_L1_CLKREQ_N_PDD6 _GPIO(238) +#define TEGRA_PIN_PEX_L2_PRSNT_N_PDD7 _GPIO(239) +#define TEGRA_PIN_CLK3_OUT_PEE0 _GPIO(240) +#define TEGRA_PIN_CLK3_REQ_PEE1 _GPIO(241) +#define TEGRA_PIN_CLK1_REQ_PEE2 _GPIO(242) +#define TEGRA_PIN_HDMI_CEC_PEE3 _GPIO(243) +#define TEGRA_PIN_PEE4 _GPIO(244) +#define TEGRA_PIN_PEE5 _GPIO(245) +#define TEGRA_PIN_PEE6 _GPIO(246) +#define TEGRA_PIN_PEE7 _GPIO(247) + +/* All non-GPIO pins follow */ +#define NUM_GPIOS (TEGRA_PIN_PEE7 + 1) +#define _PIN(offset) (NUM_GPIOS + (offset)) + +/* Non-GPIO pins */ +#define TEGRA_PIN_CLK_32K_IN _PIN(0) +#define TEGRA_PIN_CORE_PWR_REQ _PIN(1) +#define TEGRA_PIN_CPU_PWR_REQ _PIN(2) +#define TEGRA_PIN_JTAG_TCK _PIN(3) +#define TEGRA_PIN_JTAG_TDI _PIN(4) +#define TEGRA_PIN_JTAG_TDO _PIN(5) +#define TEGRA_PIN_JTAG_TMS _PIN(6) +#define TEGRA_PIN_JTAG_TRST_N _PIN(7) +#define TEGRA_PIN_OWR _PIN(8) +#define TEGRA_PIN_PWR_INT_N _PIN(9) +#define TEGRA_PIN_SYS_RESET_N _PIN(10) +#define TEGRA_PIN_TEST_MODE_EN _PIN(11) + +static const struct pinctrl_pin_desc tegra30_pins[] = { + PINCTRL_PIN(TEGRA_PIN_CLK_32K_OUT_PA0, "CLK_32K_OUT PA0"), + PINCTRL_PIN(TEGRA_PIN_UART3_CTS_N_PA1, "UART3_CTS_N PA1"), + PINCTRL_PIN(TEGRA_PIN_DAP2_FS_PA2, "DAP2_FS PA2"), + PINCTRL_PIN(TEGRA_PIN_DAP2_SCLK_PA3, "DAP2_SCLK PA3"), + PINCTRL_PIN(TEGRA_PIN_DAP2_DIN_PA4, "DAP2_DIN PA4"), + PINCTRL_PIN(TEGRA_PIN_DAP2_DOUT_PA5, "DAP2_DOUT PA5"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_CLK_PA6, "SDMMC3_CLK PA6"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_CMD_PA7, "SDMMC3_CMD PA7"), + PINCTRL_PIN(TEGRA_PIN_GMI_A17_PB0, "GMI_A17 PB0"), + PINCTRL_PIN(TEGRA_PIN_GMI_A18_PB1, "GMI_A18 PB1"), + PINCTRL_PIN(TEGRA_PIN_LCD_PWR0_PB2, "LCD_PWR0 PB2"), + PINCTRL_PIN(TEGRA_PIN_LCD_PCLK_PB3, "LCD_PCLK PB3"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT3_PB4, "SDMMC3_DAT3 PB4"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT2_PB5, "SDMMC3_DAT2 PB5"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT1_PB6, "SDMMC3_DAT1 PB6"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT0_PB7, "SDMMC3_DAT0 PB7"), + PINCTRL_PIN(TEGRA_PIN_UART3_RTS_N_PC0, "UART3_RTS_N PC0"), + PINCTRL_PIN(TEGRA_PIN_LCD_PWR1_PC1, "LCD_PWR1 PC1"), + PINCTRL_PIN(TEGRA_PIN_UART2_TXD_PC2, "UART2_TXD PC2"), + PINCTRL_PIN(TEGRA_PIN_UART2_RXD_PC3, "UART2_RXD PC3"), + PINCTRL_PIN(TEGRA_PIN_GEN1_I2C_SCL_PC4, "GEN1_I2C_SCL PC4"), + PINCTRL_PIN(TEGRA_PIN_GEN1_I2C_SDA_PC5, "GEN1_I2C_SDA PC5"), + PINCTRL_PIN(TEGRA_PIN_LCD_PWR2_PC6, "LCD_PWR2 PC6"), + PINCTRL_PIN(TEGRA_PIN_GMI_WP_N_PC7, "GMI_WP_N PC7"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT5_PD0, "SDMMC3_DAT5 PD0"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT4_PD1, "SDMMC3_DAT4 PD1"), + PINCTRL_PIN(TEGRA_PIN_LCD_DC1_PD2, "LCD_DC1 PD2"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT6_PD3, "SDMMC3_DAT6 PD3"), + PINCTRL_PIN(TEGRA_PIN_SDMMC3_DAT7_PD4, "SDMMC3_DAT7 PD4"), + PINCTRL_PIN(TEGRA_PIN_VI_D1_PD5, "VI_D1 PD5"), + PINCTRL_PIN(TEGRA_PIN_VI_VSYNC_PD6, "VI_VSYNC PD6"), + PINCTRL_PIN(TEGRA_PIN_VI_HSYNC_PD7, "VI_HSYNC PD7"), + PINCTRL_PIN(TEGRA_PIN_LCD_D0_PE0, "LCD_D0 PE0"), + PINCTRL_PIN(TEGRA_PIN_LCD_D1_PE1, "LCD_D1 PE1"), + PINCTRL_PIN(TEGRA_PIN_LCD_D2_PE2, "LCD_D2 PE2"), + PINCTRL_PIN(TEGRA_PIN_LCD_D3_PE3, "LCD_D3 PE3"), + PINCTRL_PIN(TEGRA_PIN_LCD_D4_PE4, "LCD_D4 PE4"), + PINCTRL_PIN(TEGRA_PIN_LCD_D5_PE5, "LCD_D5 PE5"), + PINCTRL_PIN(TEGRA_PIN_LCD_D6_PE6, "LCD_D6 PE6"), + PINCTRL_PIN(TEGRA_PIN_LCD_D7_PE7, "LCD_D7 PE7"), + PINCTRL_PIN(TEGRA_PIN_LCD_D8_PF0, "LCD_D8 PF0"), + PINCTRL_PIN(TEGRA_PIN_LCD_D9_PF1, "LCD_D9 PF1"), + PINCTRL_PIN(TEGRA_PIN_LCD_D10_PF2, "LCD_D10 PF2"), + PINCTRL_PIN(TEGRA_PIN_LCD_D11_PF3, "LCD_D11 PF3"), + PINCTRL_PIN(TEGRA_PIN_LCD_D12_PF4, "LCD_D12 PF4"), + PINCTRL_PIN(TEGRA_PIN_LCD_D13_PF5, "LCD_D13 PF5"), + PINCTRL_PIN(TEGRA_PIN_LCD_D14_PF6, "LCD_D14 PF6"), + PINCTRL_PIN(TEGRA_PIN_LCD_D15_PF7, "LCD_D15 PF7"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD0_PG0, "GMI_AD0 PG0"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD1_PG1, "GMI_AD1 PG1"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD2_PG2, "GMI_AD2 PG2"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD3_PG3, "GMI_AD3 PG3"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD4_PG4, "GMI_AD4 PG4"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD5_PG5, "GMI_AD5 PG5"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD6_PG6, "GMI_AD6 PG6"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD7_PG7, "GMI_AD7 PG7"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD8_PH0, "GMI_AD8 PH0"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD9_PH1, "GMI_AD9 PH1"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD10_PH2, "GMI_AD10 PH2"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD11_PH3, "GMI_AD11 PH3"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD12_PH4, "GMI_AD12 PH4"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD13_PH5, "GMI_AD13 PH5"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD14_PH6, "GMI_AD14 PH6"), + PINCTRL_PIN(TEGRA_PIN_GMI_AD15_PH7, "GMI_AD15 PH7"), + PINCTRL_PIN(TEGRA_PIN_GMI_WR_N_PI0, "GMI_WR_N PI0"), + PINCTRL_PIN(TEGRA_PIN_GMI_OE_N_PI1, "GMI_OE_N PI1"), + PINCTRL_PIN(TEGRA_PIN_GMI_DQS_PI2, "GMI_DQS PI2"), + PINCTRL_PIN(TEGRA_PIN_GMI_CS6_N_PI3, "GMI_CS6_N PI3"), + PINCTRL_PIN(TEGRA_PIN_GMI_RST_N_PI4, "GMI_RST_N PI4"), + PINCTRL_PIN(TEGRA_PIN_GMI_IORDY_PI5, "GMI_IORDY PI5"), + PINCTRL_PIN(TEGRA_PIN_GMI_CS7_N_PI6, "GMI_CS7_N PI6"), + PINCTRL_PIN(TEGRA_PIN_GMI_WAIT_PI7, "GMI_WAIT PI7"), + PINCTRL_PIN(TEGRA_PIN_GMI_CS0_N_PJ0, "GMI_CS0_N PJ0"), + PINCTRL_PIN(TEGRA_PIN_LCD_DE_PJ1, "LCD_DE PJ1"), + PINCTRL_PIN(TEGRA_PIN_GMI_CS1_N_PJ2, "GMI_CS1_N PJ2"), + PINCTRL_PIN(TEGRA_PIN_LCD_HSYNC_PJ3, "LCD_HSYNC PJ3"), + PINCTRL_PIN(TEGRA_PIN_LCD_VSYNC_PJ4, "LCD_VSYNC PJ4"), + PINCTRL_PIN(TEGRA_PIN_UART2_CTS_N_PJ5, "UART2_CTS_N PJ5"), + PINCTRL_PIN(TEGRA_PIN_UART2_RTS_N_PJ6, "UART2_RTS_N PJ6"), + PINCTRL_PIN(TEGRA_PIN_GMI_A16_PJ7, "GMI_A16 PJ7"), + PINCTRL_PIN(TEGRA_PIN_GMI_ADV_N_PK0, "GMI_ADV_N PK0"), + PINCTRL_PIN(TEGRA_PIN_GMI_CLK_PK1, "GMI_CLK PK1"), + PINCTRL_PIN(TEGRA_PIN_GMI_CS4_N_PK2, "GMI_CS4_N PK2"), + PINCTRL_PIN(TEGRA_PIN_GMI_CS2_N_PK3, "GMI_CS2_N PK3"), + PINCTRL_PIN(TEGRA_PIN_GMI_CS3_N_PK4, "GMI_CS3_N PK4"), + PINCTRL_PIN(TEGRA_PIN_SPDIF_OUT_PK5, "SPDIF_OUT PK5"), + PINCTRL_PIN(TEGRA_PIN_SPDIF_IN_PK6, "SPDIF_IN PK6"), + PINCTRL_PIN(TEGRA_PIN_GMI_A19_PK7, "GMI_A19 PK7"), + PINCTRL_PIN(TEGRA_PIN_VI_D2_PL0, "VI_D2 PL0"), + PINCTRL_PIN(TEGRA_PIN_VI_D3_PL1, "VI_D3 PL1"), + PINCTRL_PIN(TEGRA_PIN_VI_D4_PL2, "VI_D4 PL2"), + PINCTRL_PIN(TEGRA_PIN_VI_D5_PL3, "VI_D5 PL3"), + PINCTRL_PIN(TEGRA_PIN_VI_D6_PL4, "VI_D6 PL4"), + PINCTRL_PIN(TEGRA_PIN_VI_D7_PL5, "VI_D7 PL5"), + PINCTRL_PIN(TEGRA_PIN_VI_D8_PL6, "VI_D8 PL6"), + PINCTRL_PIN(TEGRA_PIN_VI_D9_PL7, "VI_D9 PL7"), + PINCTRL_PIN(TEGRA_PIN_LCD_D16_PM0, "LCD_D16 PM0"), + PINCTRL_PIN(TEGRA_PIN_LCD_D17_PM1, "LCD_D17 PM1"), + PINCTRL_PIN(TEGRA_PIN_LCD_D18_PM2, "LCD_D18 PM2"), + PINCTRL_PIN(TEGRA_PIN_LCD_D19_PM3, "LCD_D19 PM3"), + PINCTRL_PIN(TEGRA_PIN_LCD_D20_PM4, "LCD_D20 PM4"), + PINCTRL_PIN(TEGRA_PIN_LCD_D21_PM5, "LCD_D21 PM5"), + PINCTRL_PIN(TEGRA_PIN_LCD_D22_PM6, "LCD_D22 PM6"), + PINCTRL_PIN(TEGRA_PIN_LCD_D23_PM7, "LCD_D23 PM7"), + PINCTRL_PIN(TEGRA_PIN_DAP1_FS_PN0, "DAP1_FS PN0"), + PINCTRL_PIN(TEGRA_PIN_DAP1_DIN_PN1, "DAP1_DIN PN1"), + PINCTRL_PIN(TEGRA_PIN_DAP1_DOUT_PN2, "DAP1_DOUT PN2"), + PINCTRL_PIN(TEGRA_PIN_DAP1_SCLK_PN3, "DAP1_SCLK PN3"), + PINCTRL_PIN(TEGRA_PIN_LCD_CS0_N_PN4, "LCD_CS0_N PN4"), + PINCTRL_PIN(TEGRA_PIN_LCD_SDOUT_PN5, "LCD_SDOUT PN5"), + PINCTRL_PIN(TEGRA_PIN_LCD_DC0_PN6, "LCD_DC0 PN6"), + PINCTRL_PIN(TEGRA_PIN_HDMI_INT_PN7, "HDMI_INT PN7"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA7_PO0, "ULPI_DATA7 PO0"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA0_PO1, "ULPI_DATA0 PO1"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA1_PO2, "ULPI_DATA1 PO2"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA2_PO3, "ULPI_DATA2 PO3"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA3_PO4, "ULPI_DATA3 PO4"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA4_PO5, "ULPI_DATA4 PO5"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA5_PO6, "ULPI_DATA5 PO6"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DATA6_PO7, "ULPI_DATA6 PO7"), + PINCTRL_PIN(TEGRA_PIN_DAP3_FS_PP0, "DAP3_FS PP0"), + PINCTRL_PIN(TEGRA_PIN_DAP3_DIN_PP1, "DAP3_DIN PP1"), + PINCTRL_PIN(TEGRA_PIN_DAP3_DOUT_PP2, "DAP3_DOUT PP2"), + PINCTRL_PIN(TEGRA_PIN_DAP3_SCLK_PP3, "DAP3_SCLK PP3"), + PINCTRL_PIN(TEGRA_PIN_DAP4_FS_PP4, "DAP4_FS PP4"), + PINCTRL_PIN(TEGRA_PIN_DAP4_DIN_PP5, "DAP4_DIN PP5"), + PINCTRL_PIN(TEGRA_PIN_DAP4_DOUT_PP6, "DAP4_DOUT PP6"), + PINCTRL_PIN(TEGRA_PIN_DAP4_SCLK_PP7, "DAP4_SCLK PP7"), + PINCTRL_PIN(TEGRA_PIN_KB_COL0_PQ0, "KB_COL0 PQ0"), + PINCTRL_PIN(TEGRA_PIN_KB_COL1_PQ1, "KB_COL1 PQ1"), + PINCTRL_PIN(TEGRA_PIN_KB_COL2_PQ2, "KB_COL2 PQ2"), + PINCTRL_PIN(TEGRA_PIN_KB_COL3_PQ3, "KB_COL3 PQ3"), + PINCTRL_PIN(TEGRA_PIN_KB_COL4_PQ4, "KB_COL4 PQ4"), + PINCTRL_PIN(TEGRA_PIN_KB_COL5_PQ5, "KB_COL5 PQ5"), + PINCTRL_PIN(TEGRA_PIN_KB_COL6_PQ6, "KB_COL6 PQ6"), + PINCTRL_PIN(TEGRA_PIN_KB_COL7_PQ7, "KB_COL7 PQ7"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW0_PR0, "KB_ROW0 PR0"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW1_PR1, "KB_ROW1 PR1"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW2_PR2, "KB_ROW2 PR2"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW3_PR3, "KB_ROW3 PR3"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW4_PR4, "KB_ROW4 PR4"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW5_PR5, "KB_ROW5 PR5"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW6_PR6, "KB_ROW6 PR6"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW7_PR7, "KB_ROW7 PR7"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW8_PS0, "KB_ROW8 PS0"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW9_PS1, "KB_ROW9 PS1"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW10_PS2, "KB_ROW10 PS2"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW11_PS3, "KB_ROW11 PS3"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW12_PS4, "KB_ROW12 PS4"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW13_PS5, "KB_ROW13 PS5"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW14_PS6, "KB_ROW14 PS6"), + PINCTRL_PIN(TEGRA_PIN_KB_ROW15_PS7, "KB_ROW15 PS7"), + PINCTRL_PIN(TEGRA_PIN_VI_PCLK_PT0, "VI_PCLK PT0"), + PINCTRL_PIN(TEGRA_PIN_VI_MCLK_PT1, "VI_MCLK PT1"), + PINCTRL_PIN(TEGRA_PIN_VI_D10_PT2, "VI_D10 PT2"), + PINCTRL_PIN(TEGRA_PIN_VI_D11_PT3, "VI_D11 PT3"), + PINCTRL_PIN(TEGRA_PIN_VI_D0_PT4, "VI_D0 PT4"), + PINCTRL_PIN(TEGRA_PIN_GEN2_I2C_SCL_PT5, "GEN2_I2C_SCL PT5"), + PINCTRL_PIN(TEGRA_PIN_GEN2_I2C_SDA_PT6, "GEN2_I2C_SDA PT6"), + PINCTRL_PIN(TEGRA_PIN_SDMMC4_CMD_PT7, "SDMMC4_CMD PT7"), + PINCTRL_PIN(TEGRA_PIN_PU0, "PU0"), + PINCTRL_PIN(TEGRA_PIN_PU1, "PU1"), + PINCTRL_PIN(TEGRA_PIN_PU2, "PU2"), + PINCTRL_PIN(TEGRA_PIN_PU3, "PU3"), + PINCTRL_PIN(TEGRA_PIN_PU4, "PU4"), + PINCTRL_PIN(TEGRA_PIN_PU5, "PU5"), + PINCTRL_PIN(TEGRA_PIN_PU6, "PU6"), + PINCTRL_PIN(TEGRA_PIN_JTAG_RTCK_PU7, "JTAG_RTCK PU7"), + PINCTRL_PIN(TEGRA_PIN_PV0, "PV0"), + PINCTRL_PIN(TEGRA_PIN_PV1, "PV1"), + PINCTRL_PIN(TEGRA_PIN_PV2, "PV2"), + PINCTRL_PIN(TEGRA_PIN_PV3, "PV3"), + PINCTRL_PIN(TEGRA_PIN_DDC_SCL_PV4, "DDC_SCL PV4"), + PINCTRL_PIN(TEGRA_PIN_DDC_SDA_PV5, "DDC_SDA PV5"), + PINCTRL_PIN(TEGRA_PIN_CRT_HSYNC_PV6, "CRT_HSYNC PV6"), + PINCTRL_PIN(TEGRA_PIN_CRT_VSYNC_PV7, "CRT_VSYNC PV7"), + PINCTRL_PIN(TEGRA_PIN_LCD_CS1_N_PW0, "LCD_CS1_N PW0"), + PINCTRL_PIN(TEGRA_PIN_LCD_M1_PW1, "LCD_M1 PW1"), + PINCTRL_PIN(TEGRA_PIN_SPI2_CS1_N_PW2, "SPI2_CS1_N PW2"), + PINCTRL_PIN(TEGRA_PIN_SPI2_CS2_N_PW3, "SPI2_CS2_N PW3"), + PINCTRL_PIN(TEGRA_PIN_CLK1_OUT_PW4, "CLK1_OUT PW4"), + PINCTRL_PIN(TEGRA_PIN_CLK2_OUT_PW5, "CLK2_OUT PW5"), + PINCTRL_PIN(TEGRA_PIN_UART3_TXD_PW6, "UART3_TXD PW6"), + PINCTRL_PIN(TEGRA_PIN_UART3_RXD_PW7, "UART3_RXD PW7"), + PINCTRL_PIN(TEGRA_PIN_SPI2_MOSI_PX0, "SPI2_MOSI PX0"), + PINCTRL_PIN(TEGRA_PIN_SPI2_MISO_PX1, "SPI2_MISO PX1"), + PINCTRL_PIN(TEGRA_PIN_SPI2_SCK_PX2, "SPI2_SCK PX2"), + PINCTRL_PIN(TEGRA_PIN_SPI2_CS0_N_PX3, "SPI2_CS0_N PX3"), + PINCTRL_PIN(TEGRA_PIN_SPI1_MOSI_PX4, "SPI1_MOSI PX4"), + PINCTRL_PIN(TEGRA_PIN_SPI1_SCK_PX5, "SPI1_SCK PX5"), + PINCTRL_PIN(TEGRA_PIN_SPI1_CS0_N_PX6, "SPI1_CS0_N PX6"), + PINCTRL_PIN(TEGRA_PIN_SPI1_MISO_PX7, "SPI1_MISO PX7"), + PINCTRL_PIN(TEGRA_PIN_ULPI_CLK_PY0, "ULPI_CLK PY0"), + PINCTRL_PIN(TEGRA_PIN_ULPI_DIR_PY1, "ULPI_DIR PY1"), + PINCTRL_PIN(TEGRA_PIN_ULPI_NXT_PY2, "ULPI_NXT PY2"), + PINCTRL_PIN(TEGRA_PIN_ULPI_STP_PY3, "ULPI_STP PY3"), + PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT3_PY4, "SDMMC1_DAT3 PY4"), + PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT2_PY5, "SDMMC1_DAT2 PY5"), + PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT1_PY6, "SDMMC1_DAT1 PY6"), + PINCTRL_PIN(TEGRA_PIN_SDMMC1_DAT0_PY7, "SDMMC1_DAT0 PY7"), + PINCTRL_PIN(TEGRA_PIN_SDMMC1_CLK_PZ0, "SDMMC1_CLK PZ0"), + PINCTRL_PIN(TEGRA_PIN_SDMMC1_CMD_PZ1, "SDMMC1_CMD PZ1"), + PINCTRL_PIN(TEGRA_PIN_LCD_SDIN_PZ2, "LCD_SDIN PZ2"), + PINCTRL_PIN(TEGRA_PIN_LCD_WR_N_PZ3, "LCD_WR_N PZ3"), + PINCTRL_PIN(TEGRA_PIN_LCD_SCK_PZ4, "LCD_SCK PZ4"), + PINCTRL_PIN(TEGRA_PIN_SYS_CLK_REQ_PZ5, "SYS_CLK_REQ PZ5"), + PINCTRL_PIN(TEGRA_PIN_PWR_I2C_SCL_PZ6, "PWR_I2C_SCL PZ6"), + PINCTRL_PIN(TEGRA_PIN_PWR_I2C_SDA_PZ7, "PWR_I2C_SDA PZ7"), + PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT0_PAA0, "SDMMC4_DAT0 PAA0"), + PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT1_PAA1, "SDMMC4_DAT1 PAA1"), + PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT2_PAA2, "SDMMC4_DAT2 PAA2"), + PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT3_PAA3, "SDMMC4_DAT3 PAA3"), + PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT4_PAA4, "SDMMC4_DAT4 PAA4"), + PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT5_PAA5, "SDMMC4_DAT5 PAA5"), + PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT6_PAA6, "SDMMC4_DAT6 PAA6"), + PINCTRL_PIN(TEGRA_PIN_SDMMC4_DAT7_PAA7, "SDMMC4_DAT7 PAA7"), + PINCTRL_PIN(TEGRA_PIN_PBB0, "PBB0"), + PINCTRL_PIN(TEGRA_PIN_CAM_I2C_SCL_PBB1, "CAM_I2C_SCL PBB1"), + PINCTRL_PIN(TEGRA_PIN_CAM_I2C_SDA_PBB2, "CAM_I2C_SDA PBB2"), + PINCTRL_PIN(TEGRA_PIN_PBB3, "PBB3"), + PINCTRL_PIN(TEGRA_PIN_PBB4, "PBB4"), + PINCTRL_PIN(TEGRA_PIN_PBB5, "PBB5"), + PINCTRL_PIN(TEGRA_PIN_PBB6, "PBB6"), + PINCTRL_PIN(TEGRA_PIN_PBB7, "PBB7"), + PINCTRL_PIN(TEGRA_PIN_CAM_MCLK_PCC0, "CAM_MCLK PCC0"), + PINCTRL_PIN(TEGRA_PIN_PCC1, "PCC1"), + PINCTRL_PIN(TEGRA_PIN_PCC2, "PCC2"), + PINCTRL_PIN(TEGRA_PIN_SDMMC4_RST_N_PCC3, "SDMMC4_RST_N PCC3"), + PINCTRL_PIN(TEGRA_PIN_SDMMC4_CLK_PCC4, "SDMMC4_CLK PCC4"), + PINCTRL_PIN(TEGRA_PIN_CLK2_REQ_PCC5, "CLK2_REQ PCC5"), + PINCTRL_PIN(TEGRA_PIN_PEX_L2_RST_N_PCC6, "PEX_L2_RST_N PCC6"), + PINCTRL_PIN(TEGRA_PIN_PEX_L2_CLKREQ_N_PCC7, "PEX_L2_CLKREQ_N PCC7"), + PINCTRL_PIN(TEGRA_PIN_PEX_L0_PRSNT_N_PDD0, "PEX_L0_PRSNT_N PDD0"), + PINCTRL_PIN(TEGRA_PIN_PEX_L0_RST_N_PDD1, "PEX_L0_RST_N PDD1"), + PINCTRL_PIN(TEGRA_PIN_PEX_L0_CLKREQ_N_PDD2, "PEX_L0_CLKREQ_N PDD2"), + PINCTRL_PIN(TEGRA_PIN_PEX_WAKE_N_PDD3, "PEX_WAKE_N PDD3"), + PINCTRL_PIN(TEGRA_PIN_PEX_L1_PRSNT_N_PDD4, "PEX_L1_PRSNT_N PDD4"), + PINCTRL_PIN(TEGRA_PIN_PEX_L1_RST_N_PDD5, "PEX_L1_RST_N PDD5"), + PINCTRL_PIN(TEGRA_PIN_PEX_L1_CLKREQ_N_PDD6, "PEX_L1_CLKREQ_N PDD6"), + PINCTRL_PIN(TEGRA_PIN_PEX_L2_PRSNT_N_PDD7, "PEX_L2_PRSNT_N PDD7"), + PINCTRL_PIN(TEGRA_PIN_CLK3_OUT_PEE0, "CLK3_OUT PEE0"), + PINCTRL_PIN(TEGRA_PIN_CLK3_REQ_PEE1, "CLK3_REQ PEE1"), + PINCTRL_PIN(TEGRA_PIN_CLK1_REQ_PEE2, "CLK1_REQ PEE2"), + PINCTRL_PIN(TEGRA_PIN_HDMI_CEC_PEE3, "HDMI_CEC PEE3"), + PINCTRL_PIN(TEGRA_PIN_PEE4, "PEE4"), + PINCTRL_PIN(TEGRA_PIN_PEE5, "PEE5"), + PINCTRL_PIN(TEGRA_PIN_PEE6, "PEE6"), + PINCTRL_PIN(TEGRA_PIN_PEE7, "PEE7"), + PINCTRL_PIN(TEGRA_PIN_CLK_32K_IN, "CLK_32K_IN"), + PINCTRL_PIN(TEGRA_PIN_CORE_PWR_REQ, "CORE_PWR_REQ"), + PINCTRL_PIN(TEGRA_PIN_CPU_PWR_REQ, "CPU_PWR_REQ"), + PINCTRL_PIN(TEGRA_PIN_JTAG_TCK, "JTAG_TCK"), + PINCTRL_PIN(TEGRA_PIN_JTAG_TDI, "JTAG_TDI"), + PINCTRL_PIN(TEGRA_PIN_JTAG_TDO, "JTAG_TDO"), + PINCTRL_PIN(TEGRA_PIN_JTAG_TMS, "JTAG_TMS"), + PINCTRL_PIN(TEGRA_PIN_JTAG_TRST_N, "JTAG_TRST_N"), + PINCTRL_PIN(TEGRA_PIN_OWR, "OWR"), + PINCTRL_PIN(TEGRA_PIN_PWR_INT_N, "PWR_INT_N"), + PINCTRL_PIN(TEGRA_PIN_SYS_RESET_N, "SYS_RESET_N"), + PINCTRL_PIN(TEGRA_PIN_TEST_MODE_EN, "TEST_MODE_EN"), +}; + +static const unsigned clk_32k_out_pa0_pins[] = { + TEGRA_PIN_CLK_32K_OUT_PA0, +}; + +static const unsigned uart3_cts_n_pa1_pins[] = { + TEGRA_PIN_UART3_CTS_N_PA1, +}; + +static const unsigned dap2_fs_pa2_pins[] = { + TEGRA_PIN_DAP2_FS_PA2, +}; + +static const unsigned dap2_sclk_pa3_pins[] = { + TEGRA_PIN_DAP2_SCLK_PA3, +}; + +static const unsigned dap2_din_pa4_pins[] = { + TEGRA_PIN_DAP2_DIN_PA4, +}; + +static const unsigned dap2_dout_pa5_pins[] = { + TEGRA_PIN_DAP2_DOUT_PA5, +}; + +static const unsigned sdmmc3_clk_pa6_pins[] = { + TEGRA_PIN_SDMMC3_CLK_PA6, +}; + +static const unsigned sdmmc3_cmd_pa7_pins[] = { + TEGRA_PIN_SDMMC3_CMD_PA7, +}; + +static const unsigned gmi_a17_pb0_pins[] = { + TEGRA_PIN_GMI_A17_PB0, +}; + +static const unsigned gmi_a18_pb1_pins[] = { + TEGRA_PIN_GMI_A18_PB1, +}; + +static const unsigned lcd_pwr0_pb2_pins[] = { + TEGRA_PIN_LCD_PWR0_PB2, +}; + +static const unsigned lcd_pclk_pb3_pins[] = { + TEGRA_PIN_LCD_PCLK_PB3, +}; + +static const unsigned sdmmc3_dat3_pb4_pins[] = { + TEGRA_PIN_SDMMC3_DAT3_PB4, +}; + +static const unsigned sdmmc3_dat2_pb5_pins[] = { + TEGRA_PIN_SDMMC3_DAT2_PB5, +}; + +static const unsigned sdmmc3_dat1_pb6_pins[] = { + TEGRA_PIN_SDMMC3_DAT1_PB6, +}; + +static const unsigned sdmmc3_dat0_pb7_pins[] = { + TEGRA_PIN_SDMMC3_DAT0_PB7, +}; + +static const unsigned uart3_rts_n_pc0_pins[] = { + TEGRA_PIN_UART3_RTS_N_PC0, +}; + +static const unsigned lcd_pwr1_pc1_pins[] = { + TEGRA_PIN_LCD_PWR1_PC1, +}; + +static const unsigned uart2_txd_pc2_pins[] = { + TEGRA_PIN_UART2_TXD_PC2, +}; + +static const unsigned uart2_rxd_pc3_pins[] = { + TEGRA_PIN_UART2_RXD_PC3, +}; + +static const unsigned gen1_i2c_scl_pc4_pins[] = { + TEGRA_PIN_GEN1_I2C_SCL_PC4, +}; + +static const unsigned gen1_i2c_sda_pc5_pins[] = { + TEGRA_PIN_GEN1_I2C_SDA_PC5, +}; + +static const unsigned lcd_pwr2_pc6_pins[] = { + TEGRA_PIN_LCD_PWR2_PC6, +}; + +static const unsigned gmi_wp_n_pc7_pins[] = { + TEGRA_PIN_GMI_WP_N_PC7, +}; + +static const unsigned sdmmc3_dat5_pd0_pins[] = { + TEGRA_PIN_SDMMC3_DAT5_PD0, +}; + +static const unsigned sdmmc3_dat4_pd1_pins[] = { + TEGRA_PIN_SDMMC3_DAT4_PD1, +}; + +static const unsigned lcd_dc1_pd2_pins[] = { + TEGRA_PIN_LCD_DC1_PD2, +}; + +static const unsigned sdmmc3_dat6_pd3_pins[] = { + TEGRA_PIN_SDMMC3_DAT6_PD3, +}; + +static const unsigned sdmmc3_dat7_pd4_pins[] = { + TEGRA_PIN_SDMMC3_DAT7_PD4, +}; + +static const unsigned vi_d1_pd5_pins[] = { + TEGRA_PIN_VI_D1_PD5, +}; + +static const unsigned vi_vsync_pd6_pins[] = { + TEGRA_PIN_VI_VSYNC_PD6, +}; + +static const unsigned vi_hsync_pd7_pins[] = { + TEGRA_PIN_VI_HSYNC_PD7, +}; + +static const unsigned lcd_d0_pe0_pins[] = { + TEGRA_PIN_LCD_D0_PE0, +}; + +static const unsigned lcd_d1_pe1_pins[] = { + TEGRA_PIN_LCD_D1_PE1, +}; + +static const unsigned lcd_d2_pe2_pins[] = { + TEGRA_PIN_LCD_D2_PE2, +}; + +static const unsigned lcd_d3_pe3_pins[] = { + TEGRA_PIN_LCD_D3_PE3, +}; + +static const unsigned lcd_d4_pe4_pins[] = { + TEGRA_PIN_LCD_D4_PE4, +}; + +static const unsigned lcd_d5_pe5_pins[] = { + TEGRA_PIN_LCD_D5_PE5, +}; + +static const unsigned lcd_d6_pe6_pins[] = { + TEGRA_PIN_LCD_D6_PE6, +}; + +static const unsigned lcd_d7_pe7_pins[] = { + TEGRA_PIN_LCD_D7_PE7, +}; + +static const unsigned lcd_d8_pf0_pins[] = { + TEGRA_PIN_LCD_D8_PF0, +}; + +static const unsigned lcd_d9_pf1_pins[] = { + TEGRA_PIN_LCD_D9_PF1, +}; + +static const unsigned lcd_d10_pf2_pins[] = { + TEGRA_PIN_LCD_D10_PF2, +}; + +static const unsigned lcd_d11_pf3_pins[] = { + TEGRA_PIN_LCD_D11_PF3, +}; + +static const unsigned lcd_d12_pf4_pins[] = { + TEGRA_PIN_LCD_D12_PF4, +}; + +static const unsigned lcd_d13_pf5_pins[] = { + TEGRA_PIN_LCD_D13_PF5, +}; + +static const unsigned lcd_d14_pf6_pins[] = { + TEGRA_PIN_LCD_D14_PF6, +}; + +static const unsigned lcd_d15_pf7_pins[] = { + TEGRA_PIN_LCD_D15_PF7, +}; + +static const unsigned gmi_ad0_pg0_pins[] = { + TEGRA_PIN_GMI_AD0_PG0, +}; + +static const unsigned gmi_ad1_pg1_pins[] = { + TEGRA_PIN_GMI_AD1_PG1, +}; + +static const unsigned gmi_ad2_pg2_pins[] = { + TEGRA_PIN_GMI_AD2_PG2, +}; + +static const unsigned gmi_ad3_pg3_pins[] = { + TEGRA_PIN_GMI_AD3_PG3, +}; + +static const unsigned gmi_ad4_pg4_pins[] = { + TEGRA_PIN_GMI_AD4_PG4, +}; + +static const unsigned gmi_ad5_pg5_pins[] = { + TEGRA_PIN_GMI_AD5_PG5, +}; + +static const unsigned gmi_ad6_pg6_pins[] = { + TEGRA_PIN_GMI_AD6_PG6, +}; + +static const unsigned gmi_ad7_pg7_pins[] = { + TEGRA_PIN_GMI_AD7_PG7, +}; + +static const unsigned gmi_ad8_ph0_pins[] = { + TEGRA_PIN_GMI_AD8_PH0, +}; + +static const unsigned gmi_ad9_ph1_pins[] = { + TEGRA_PIN_GMI_AD9_PH1, +}; + +static const unsigned gmi_ad10_ph2_pins[] = { + TEGRA_PIN_GMI_AD10_PH2, +}; + +static const unsigned gmi_ad11_ph3_pins[] = { + TEGRA_PIN_GMI_AD11_PH3, +}; + +static const unsigned gmi_ad12_ph4_pins[] = { + TEGRA_PIN_GMI_AD12_PH4, +}; + +static const unsigned gmi_ad13_ph5_pins[] = { + TEGRA_PIN_GMI_AD13_PH5, +}; + +static const unsigned gmi_ad14_ph6_pins[] = { + TEGRA_PIN_GMI_AD14_PH6, +}; + +static const unsigned gmi_ad15_ph7_pins[] = { + TEGRA_PIN_GMI_AD15_PH7, +}; + +static const unsigned gmi_wr_n_pi0_pins[] = { + TEGRA_PIN_GMI_WR_N_PI0, +}; + +static const unsigned gmi_oe_n_pi1_pins[] = { + TEGRA_PIN_GMI_OE_N_PI1, +}; + +static const unsigned gmi_dqs_pi2_pins[] = { + TEGRA_PIN_GMI_DQS_PI2, +}; + +static const unsigned gmi_cs6_n_pi3_pins[] = { + TEGRA_PIN_GMI_CS6_N_PI3, +}; + +static const unsigned gmi_rst_n_pi4_pins[] = { + TEGRA_PIN_GMI_RST_N_PI4, +}; + +static const unsigned gmi_iordy_pi5_pins[] = { + TEGRA_PIN_GMI_IORDY_PI5, +}; + +static const unsigned gmi_cs7_n_pi6_pins[] = { + TEGRA_PIN_GMI_CS7_N_PI6, +}; + +static const unsigned gmi_wait_pi7_pins[] = { + TEGRA_PIN_GMI_WAIT_PI7, +}; + +static const unsigned gmi_cs0_n_pj0_pins[] = { + TEGRA_PIN_GMI_CS0_N_PJ0, +}; + +static const unsigned lcd_de_pj1_pins[] = { + TEGRA_PIN_LCD_DE_PJ1, +}; + +static const unsigned gmi_cs1_n_pj2_pins[] = { + TEGRA_PIN_GMI_CS1_N_PJ2, +}; + +static const unsigned lcd_hsync_pj3_pins[] = { + TEGRA_PIN_LCD_HSYNC_PJ3, +}; + +static const unsigned lcd_vsync_pj4_pins[] = { + TEGRA_PIN_LCD_VSYNC_PJ4, +}; + +static const unsigned uart2_cts_n_pj5_pins[] = { + TEGRA_PIN_UART2_CTS_N_PJ5, +}; + +static const unsigned uart2_rts_n_pj6_pins[] = { + TEGRA_PIN_UART2_RTS_N_PJ6, +}; + +static const unsigned gmi_a16_pj7_pins[] = { + TEGRA_PIN_GMI_A16_PJ7, +}; + +static const unsigned gmi_adv_n_pk0_pins[] = { + TEGRA_PIN_GMI_ADV_N_PK0, +}; + +static const unsigned gmi_clk_pk1_pins[] = { + TEGRA_PIN_GMI_CLK_PK1, +}; + +static const unsigned gmi_cs4_n_pk2_pins[] = { + TEGRA_PIN_GMI_CS4_N_PK2, +}; + +static const unsigned gmi_cs2_n_pk3_pins[] = { + TEGRA_PIN_GMI_CS2_N_PK3, +}; + +static const unsigned gmi_cs3_n_pk4_pins[] = { + TEGRA_PIN_GMI_CS3_N_PK4, +}; + +static const unsigned spdif_out_pk5_pins[] = { + TEGRA_PIN_SPDIF_OUT_PK5, +}; + +static const unsigned spdif_in_pk6_pins[] = { + TEGRA_PIN_SPDIF_IN_PK6, +}; + +static const unsigned gmi_a19_pk7_pins[] = { + TEGRA_PIN_GMI_A19_PK7, +}; + +static const unsigned vi_d2_pl0_pins[] = { + TEGRA_PIN_VI_D2_PL0, +}; + +static const unsigned vi_d3_pl1_pins[] = { + TEGRA_PIN_VI_D3_PL1, +}; + +static const unsigned vi_d4_pl2_pins[] = { + TEGRA_PIN_VI_D4_PL2, +}; + +static const unsigned vi_d5_pl3_pins[] = { + TEGRA_PIN_VI_D5_PL3, +}; + +static const unsigned vi_d6_pl4_pins[] = { + TEGRA_PIN_VI_D6_PL4, +}; + +static const unsigned vi_d7_pl5_pins[] = { + TEGRA_PIN_VI_D7_PL5, +}; + +static const unsigned vi_d8_pl6_pins[] = { + TEGRA_PIN_VI_D8_PL6, +}; + +static const unsigned vi_d9_pl7_pins[] = { + TEGRA_PIN_VI_D9_PL7, +}; + +static const unsigned lcd_d16_pm0_pins[] = { + TEGRA_PIN_LCD_D16_PM0, +}; + +static const unsigned lcd_d17_pm1_pins[] = { + TEGRA_PIN_LCD_D17_PM1, +}; + +static const unsigned lcd_d18_pm2_pins[] = { + TEGRA_PIN_LCD_D18_PM2, +}; + +static const unsigned lcd_d19_pm3_pins[] = { + TEGRA_PIN_LCD_D19_PM3, +}; + +static const unsigned lcd_d20_pm4_pins[] = { + TEGRA_PIN_LCD_D20_PM4, +}; + +static const unsigned lcd_d21_pm5_pins[] = { + TEGRA_PIN_LCD_D21_PM5, +}; + +static const unsigned lcd_d22_pm6_pins[] = { + TEGRA_PIN_LCD_D22_PM6, +}; + +static const unsigned lcd_d23_pm7_pins[] = { + TEGRA_PIN_LCD_D23_PM7, +}; + +static const unsigned dap1_fs_pn0_pins[] = { + TEGRA_PIN_DAP1_FS_PN0, +}; + +static const unsigned dap1_din_pn1_pins[] = { + TEGRA_PIN_DAP1_DIN_PN1, +}; + +static const unsigned dap1_dout_pn2_pins[] = { + TEGRA_PIN_DAP1_DOUT_PN2, +}; + +static const unsigned dap1_sclk_pn3_pins[] = { + TEGRA_PIN_DAP1_SCLK_PN3, +}; + +static const unsigned lcd_cs0_n_pn4_pins[] = { + TEGRA_PIN_LCD_CS0_N_PN4, +}; + +static const unsigned lcd_sdout_pn5_pins[] = { + TEGRA_PIN_LCD_SDOUT_PN5, +}; + +static const unsigned lcd_dc0_pn6_pins[] = { + TEGRA_PIN_LCD_DC0_PN6, +}; + +static const unsigned hdmi_int_pn7_pins[] = { + TEGRA_PIN_HDMI_INT_PN7, +}; + +static const unsigned ulpi_data7_po0_pins[] = { + TEGRA_PIN_ULPI_DATA7_PO0, +}; + +static const unsigned ulpi_data0_po1_pins[] = { + TEGRA_PIN_ULPI_DATA0_PO1, +}; + +static const unsigned ulpi_data1_po2_pins[] = { + TEGRA_PIN_ULPI_DATA1_PO2, +}; + +static const unsigned ulpi_data2_po3_pins[] = { + TEGRA_PIN_ULPI_DATA2_PO3, +}; + +static const unsigned ulpi_data3_po4_pins[] = { + TEGRA_PIN_ULPI_DATA3_PO4, +}; + +static const unsigned ulpi_data4_po5_pins[] = { + TEGRA_PIN_ULPI_DATA4_PO5, +}; + +static const unsigned ulpi_data5_po6_pins[] = { + TEGRA_PIN_ULPI_DATA5_PO6, +}; + +static const unsigned ulpi_data6_po7_pins[] = { + TEGRA_PIN_ULPI_DATA6_PO7, +}; + +static const unsigned dap3_fs_pp0_pins[] = { + TEGRA_PIN_DAP3_FS_PP0, +}; + +static const unsigned dap3_din_pp1_pins[] = { + TEGRA_PIN_DAP3_DIN_PP1, +}; + +static const unsigned dap3_dout_pp2_pins[] = { + TEGRA_PIN_DAP3_DOUT_PP2, +}; + +static const unsigned dap3_sclk_pp3_pins[] = { + TEGRA_PIN_DAP3_SCLK_PP3, +}; + +static const unsigned dap4_fs_pp4_pins[] = { + TEGRA_PIN_DAP4_FS_PP4, +}; + +static const unsigned dap4_din_pp5_pins[] = { + TEGRA_PIN_DAP4_DIN_PP5, +}; + +static const unsigned dap4_dout_pp6_pins[] = { + TEGRA_PIN_DAP4_DOUT_PP6, +}; + +static const unsigned dap4_sclk_pp7_pins[] = { + TEGRA_PIN_DAP4_SCLK_PP7, +}; + +static const unsigned kb_col0_pq0_pins[] = { + TEGRA_PIN_KB_COL0_PQ0, +}; + +static const unsigned kb_col1_pq1_pins[] = { + TEGRA_PIN_KB_COL1_PQ1, +}; + +static const unsigned kb_col2_pq2_pins[] = { + TEGRA_PIN_KB_COL2_PQ2, +}; + +static const unsigned kb_col3_pq3_pins[] = { + TEGRA_PIN_KB_COL3_PQ3, +}; + +static const unsigned kb_col4_pq4_pins[] = { + TEGRA_PIN_KB_COL4_PQ4, +}; + +static const unsigned kb_col5_pq5_pins[] = { + TEGRA_PIN_KB_COL5_PQ5, +}; + +static const unsigned kb_col6_pq6_pins[] = { + TEGRA_PIN_KB_COL6_PQ6, +}; + +static const unsigned kb_col7_pq7_pins[] = { + TEGRA_PIN_KB_COL7_PQ7, +}; + +static const unsigned kb_row0_pr0_pins[] = { + TEGRA_PIN_KB_ROW0_PR0, +}; + +static const unsigned kb_row1_pr1_pins[] = { + TEGRA_PIN_KB_ROW1_PR1, +}; + +static const unsigned kb_row2_pr2_pins[] = { + TEGRA_PIN_KB_ROW2_PR2, +}; + +static const unsigned kb_row3_pr3_pins[] = { + TEGRA_PIN_KB_ROW3_PR3, +}; + +static const unsigned kb_row4_pr4_pins[] = { + TEGRA_PIN_KB_ROW4_PR4, +}; + +static const unsigned kb_row5_pr5_pins[] = { + TEGRA_PIN_KB_ROW5_PR5, +}; + +static const unsigned kb_row6_pr6_pins[] = { + TEGRA_PIN_KB_ROW6_PR6, +}; + +static const unsigned kb_row7_pr7_pins[] = { + TEGRA_PIN_KB_ROW7_PR7, +}; + +static const unsigned kb_row8_ps0_pins[] = { + TEGRA_PIN_KB_ROW8_PS0, +}; + +static const unsigned kb_row9_ps1_pins[] = { + TEGRA_PIN_KB_ROW9_PS1, +}; + +static const unsigned kb_row10_ps2_pins[] = { + TEGRA_PIN_KB_ROW10_PS2, +}; + +static const unsigned kb_row11_ps3_pins[] = { + TEGRA_PIN_KB_ROW11_PS3, +}; + +static const unsigned kb_row12_ps4_pins[] = { + TEGRA_PIN_KB_ROW12_PS4, +}; + +static const unsigned kb_row13_ps5_pins[] = { + TEGRA_PIN_KB_ROW13_PS5, +}; + +static const unsigned kb_row14_ps6_pins[] = { + TEGRA_PIN_KB_ROW14_PS6, +}; + +static const unsigned kb_row15_ps7_pins[] = { + TEGRA_PIN_KB_ROW15_PS7, +}; + +static const unsigned vi_pclk_pt0_pins[] = { + TEGRA_PIN_VI_PCLK_PT0, +}; + +static const unsigned vi_mclk_pt1_pins[] = { + TEGRA_PIN_VI_MCLK_PT1, +}; + +static const unsigned vi_d10_pt2_pins[] = { + TEGRA_PIN_VI_D10_PT2, +}; + +static const unsigned vi_d11_pt3_pins[] = { + TEGRA_PIN_VI_D11_PT3, +}; + +static const unsigned vi_d0_pt4_pins[] = { + TEGRA_PIN_VI_D0_PT4, +}; + +static const unsigned gen2_i2c_scl_pt5_pins[] = { + TEGRA_PIN_GEN2_I2C_SCL_PT5, +}; + +static const unsigned gen2_i2c_sda_pt6_pins[] = { + TEGRA_PIN_GEN2_I2C_SDA_PT6, +}; + +static const unsigned sdmmc4_cmd_pt7_pins[] = { + TEGRA_PIN_SDMMC4_CMD_PT7, +}; + +static const unsigned pu0_pins[] = { + TEGRA_PIN_PU0, +}; + +static const unsigned pu1_pins[] = { + TEGRA_PIN_PU1, +}; + +static const unsigned pu2_pins[] = { + TEGRA_PIN_PU2, +}; + +static const unsigned pu3_pins[] = { + TEGRA_PIN_PU3, +}; + +static const unsigned pu4_pins[] = { + TEGRA_PIN_PU4, +}; + +static const unsigned pu5_pins[] = { + TEGRA_PIN_PU5, +}; + +static const unsigned pu6_pins[] = { + TEGRA_PIN_PU6, +}; + +static const unsigned jtag_rtck_pu7_pins[] = { + TEGRA_PIN_JTAG_RTCK_PU7, +}; + +static const unsigned pv0_pins[] = { + TEGRA_PIN_PV0, +}; + +static const unsigned pv1_pins[] = { + TEGRA_PIN_PV1, +}; + +static const unsigned pv2_pins[] = { + TEGRA_PIN_PV2, +}; + +static const unsigned pv3_pins[] = { + TEGRA_PIN_PV3, +}; + +static const unsigned ddc_scl_pv4_pins[] = { + TEGRA_PIN_DDC_SCL_PV4, +}; + +static const unsigned ddc_sda_pv5_pins[] = { + TEGRA_PIN_DDC_SDA_PV5, +}; + +static const unsigned crt_hsync_pv6_pins[] = { + TEGRA_PIN_CRT_HSYNC_PV6, +}; + +static const unsigned crt_vsync_pv7_pins[] = { + TEGRA_PIN_CRT_VSYNC_PV7, +}; + +static const unsigned lcd_cs1_n_pw0_pins[] = { + TEGRA_PIN_LCD_CS1_N_PW0, +}; + +static const unsigned lcd_m1_pw1_pins[] = { + TEGRA_PIN_LCD_M1_PW1, +}; + +static const unsigned spi2_cs1_n_pw2_pins[] = { + TEGRA_PIN_SPI2_CS1_N_PW2, +}; + +static const unsigned spi2_cs2_n_pw3_pins[] = { + TEGRA_PIN_SPI2_CS2_N_PW3, +}; + +static const unsigned clk1_out_pw4_pins[] = { + TEGRA_PIN_CLK1_OUT_PW4, +}; + +static const unsigned clk2_out_pw5_pins[] = { + TEGRA_PIN_CLK2_OUT_PW5, +}; + +static const unsigned uart3_txd_pw6_pins[] = { + TEGRA_PIN_UART3_TXD_PW6, +}; + +static const unsigned uart3_rxd_pw7_pins[] = { + TEGRA_PIN_UART3_RXD_PW7, +}; + +static const unsigned spi2_mosi_px0_pins[] = { + TEGRA_PIN_SPI2_MOSI_PX0, +}; + +static const unsigned spi2_miso_px1_pins[] = { + TEGRA_PIN_SPI2_MISO_PX1, +}; + +static const unsigned spi2_sck_px2_pins[] = { + TEGRA_PIN_SPI2_SCK_PX2, +}; + +static const unsigned spi2_cs0_n_px3_pins[] = { + TEGRA_PIN_SPI2_CS0_N_PX3, +}; + +static const unsigned spi1_mosi_px4_pins[] = { + TEGRA_PIN_SPI1_MOSI_PX4, +}; + +static const unsigned spi1_sck_px5_pins[] = { + TEGRA_PIN_SPI1_SCK_PX5, +}; + +static const unsigned spi1_cs0_n_px6_pins[] = { + TEGRA_PIN_SPI1_CS0_N_PX6, +}; + +static const unsigned spi1_miso_px7_pins[] = { + TEGRA_PIN_SPI1_MISO_PX7, +}; + +static const unsigned ulpi_clk_py0_pins[] = { + TEGRA_PIN_ULPI_CLK_PY0, +}; + +static const unsigned ulpi_dir_py1_pins[] = { + TEGRA_PIN_ULPI_DIR_PY1, +}; + +static const unsigned ulpi_nxt_py2_pins[] = { + TEGRA_PIN_ULPI_NXT_PY2, +}; + +static const unsigned ulpi_stp_py3_pins[] = { + TEGRA_PIN_ULPI_STP_PY3, +}; + +static const unsigned sdmmc1_dat3_py4_pins[] = { + TEGRA_PIN_SDMMC1_DAT3_PY4, +}; + +static const unsigned sdmmc1_dat2_py5_pins[] = { + TEGRA_PIN_SDMMC1_DAT2_PY5, +}; + +static const unsigned sdmmc1_dat1_py6_pins[] = { + TEGRA_PIN_SDMMC1_DAT1_PY6, +}; + +static const unsigned sdmmc1_dat0_py7_pins[] = { + TEGRA_PIN_SDMMC1_DAT0_PY7, +}; + +static const unsigned sdmmc1_clk_pz0_pins[] = { + TEGRA_PIN_SDMMC1_CLK_PZ0, +}; + +static const unsigned sdmmc1_cmd_pz1_pins[] = { + TEGRA_PIN_SDMMC1_CMD_PZ1, +}; + +static const unsigned lcd_sdin_pz2_pins[] = { + TEGRA_PIN_LCD_SDIN_PZ2, +}; + +static const unsigned lcd_wr_n_pz3_pins[] = { + TEGRA_PIN_LCD_WR_N_PZ3, +}; + +static const unsigned lcd_sck_pz4_pins[] = { + TEGRA_PIN_LCD_SCK_PZ4, +}; + +static const unsigned sys_clk_req_pz5_pins[] = { + TEGRA_PIN_SYS_CLK_REQ_PZ5, +}; + +static const unsigned pwr_i2c_scl_pz6_pins[] = { + TEGRA_PIN_PWR_I2C_SCL_PZ6, +}; + +static const unsigned pwr_i2c_sda_pz7_pins[] = { + TEGRA_PIN_PWR_I2C_SDA_PZ7, +}; + +static const unsigned sdmmc4_dat0_paa0_pins[] = { + TEGRA_PIN_SDMMC4_DAT0_PAA0, +}; + +static const unsigned sdmmc4_dat1_paa1_pins[] = { + TEGRA_PIN_SDMMC4_DAT1_PAA1, +}; + +static const unsigned sdmmc4_dat2_paa2_pins[] = { + TEGRA_PIN_SDMMC4_DAT2_PAA2, +}; + +static const unsigned sdmmc4_dat3_paa3_pins[] = { + TEGRA_PIN_SDMMC4_DAT3_PAA3, +}; + +static const unsigned sdmmc4_dat4_paa4_pins[] = { + TEGRA_PIN_SDMMC4_DAT4_PAA4, +}; + +static const unsigned sdmmc4_dat5_paa5_pins[] = { + TEGRA_PIN_SDMMC4_DAT5_PAA5, +}; + +static const unsigned sdmmc4_dat6_paa6_pins[] = { + TEGRA_PIN_SDMMC4_DAT6_PAA6, +}; + +static const unsigned sdmmc4_dat7_paa7_pins[] = { + TEGRA_PIN_SDMMC4_DAT7_PAA7, +}; + +static const unsigned pbb0_pins[] = { + TEGRA_PIN_PBB0, +}; + +static const unsigned cam_i2c_scl_pbb1_pins[] = { + TEGRA_PIN_CAM_I2C_SCL_PBB1, +}; + +static const unsigned cam_i2c_sda_pbb2_pins[] = { + TEGRA_PIN_CAM_I2C_SDA_PBB2, +}; + +static const unsigned pbb3_pins[] = { + TEGRA_PIN_PBB3, +}; + +static const unsigned pbb4_pins[] = { + TEGRA_PIN_PBB4, +}; + +static const unsigned pbb5_pins[] = { + TEGRA_PIN_PBB5, +}; + +static const unsigned pbb6_pins[] = { + TEGRA_PIN_PBB6, +}; + +static const unsigned pbb7_pins[] = { + TEGRA_PIN_PBB7, +}; + +static const unsigned cam_mclk_pcc0_pins[] = { + TEGRA_PIN_CAM_MCLK_PCC0, +}; + +static const unsigned pcc1_pins[] = { + TEGRA_PIN_PCC1, +}; + +static const unsigned pcc2_pins[] = { + TEGRA_PIN_PCC2, +}; + +static const unsigned sdmmc4_rst_n_pcc3_pins[] = { + TEGRA_PIN_SDMMC4_RST_N_PCC3, +}; + +static const unsigned sdmmc4_clk_pcc4_pins[] = { + TEGRA_PIN_SDMMC4_CLK_PCC4, +}; + +static const unsigned clk2_req_pcc5_pins[] = { + TEGRA_PIN_CLK2_REQ_PCC5, +}; + +static const unsigned pex_l2_rst_n_pcc6_pins[] = { + TEGRA_PIN_PEX_L2_RST_N_PCC6, +}; + +static const unsigned pex_l2_clkreq_n_pcc7_pins[] = { + TEGRA_PIN_PEX_L2_CLKREQ_N_PCC7, +}; + +static const unsigned pex_l0_prsnt_n_pdd0_pins[] = { + TEGRA_PIN_PEX_L0_PRSNT_N_PDD0, +}; + +static const unsigned pex_l0_rst_n_pdd1_pins[] = { + TEGRA_PIN_PEX_L0_RST_N_PDD1, +}; + +static const unsigned pex_l0_clkreq_n_pdd2_pins[] = { + TEGRA_PIN_PEX_L0_CLKREQ_N_PDD2, +}; + +static const unsigned pex_wake_n_pdd3_pins[] = { + TEGRA_PIN_PEX_WAKE_N_PDD3, +}; + +static const unsigned pex_l1_prsnt_n_pdd4_pins[] = { + TEGRA_PIN_PEX_L1_PRSNT_N_PDD4, +}; + +static const unsigned pex_l1_rst_n_pdd5_pins[] = { + TEGRA_PIN_PEX_L1_RST_N_PDD5, +}; + +static const unsigned pex_l1_clkreq_n_pdd6_pins[] = { + TEGRA_PIN_PEX_L1_CLKREQ_N_PDD6, +}; + +static const unsigned pex_l2_prsnt_n_pdd7_pins[] = { + TEGRA_PIN_PEX_L2_PRSNT_N_PDD7, +}; + +static const unsigned clk3_out_pee0_pins[] = { + TEGRA_PIN_CLK3_OUT_PEE0, +}; + +static const unsigned clk3_req_pee1_pins[] = { + TEGRA_PIN_CLK3_REQ_PEE1, +}; + +static const unsigned clk1_req_pee2_pins[] = { + TEGRA_PIN_CLK1_REQ_PEE2, +}; + +static const unsigned hdmi_cec_pee3_pins[] = { + TEGRA_PIN_HDMI_CEC_PEE3, +}; + +static const unsigned clk_32k_in_pins[] = { + TEGRA_PIN_CLK_32K_IN, +}; + +static const unsigned core_pwr_req_pins[] = { + TEGRA_PIN_CORE_PWR_REQ, +}; + +static const unsigned cpu_pwr_req_pins[] = { + TEGRA_PIN_CPU_PWR_REQ, +}; + +static const unsigned owr_pins[] = { + TEGRA_PIN_OWR, +}; + +static const unsigned pwr_int_n_pins[] = { + TEGRA_PIN_PWR_INT_N, +}; + +static const unsigned drive_ao1_pins[] = { + TEGRA_PIN_KB_ROW0_PR0, + TEGRA_PIN_KB_ROW1_PR1, + TEGRA_PIN_KB_ROW2_PR2, + TEGRA_PIN_KB_ROW3_PR3, + TEGRA_PIN_KB_ROW4_PR4, + TEGRA_PIN_KB_ROW5_PR5, + TEGRA_PIN_KB_ROW6_PR6, + TEGRA_PIN_KB_ROW7_PR7, + TEGRA_PIN_PWR_I2C_SCL_PZ6, + TEGRA_PIN_PWR_I2C_SDA_PZ7, + TEGRA_PIN_SYS_RESET_N, +}; + +static const unsigned drive_ao2_pins[] = { + TEGRA_PIN_CLK_32K_OUT_PA0, + TEGRA_PIN_KB_COL0_PQ0, + TEGRA_PIN_KB_COL1_PQ1, + TEGRA_PIN_KB_COL2_PQ2, + TEGRA_PIN_KB_COL3_PQ3, + TEGRA_PIN_KB_COL4_PQ4, + TEGRA_PIN_KB_COL5_PQ5, + TEGRA_PIN_KB_COL6_PQ6, + TEGRA_PIN_KB_COL7_PQ7, + TEGRA_PIN_KB_ROW8_PS0, + TEGRA_PIN_KB_ROW9_PS1, + TEGRA_PIN_KB_ROW10_PS2, + TEGRA_PIN_KB_ROW11_PS3, + TEGRA_PIN_KB_ROW12_PS4, + TEGRA_PIN_KB_ROW13_PS5, + TEGRA_PIN_KB_ROW14_PS6, + TEGRA_PIN_KB_ROW15_PS7, + TEGRA_PIN_SYS_CLK_REQ_PZ5, + TEGRA_PIN_CLK_32K_IN, + TEGRA_PIN_CORE_PWR_REQ, + TEGRA_PIN_CPU_PWR_REQ, + TEGRA_PIN_PWR_INT_N, +}; + +static const unsigned drive_at1_pins[] = { + TEGRA_PIN_GMI_AD8_PH0, + TEGRA_PIN_GMI_AD9_PH1, + TEGRA_PIN_GMI_AD10_PH2, + TEGRA_PIN_GMI_AD11_PH3, + TEGRA_PIN_GMI_AD12_PH4, + TEGRA_PIN_GMI_AD13_PH5, + TEGRA_PIN_GMI_AD14_PH6, + TEGRA_PIN_GMI_AD15_PH7, + TEGRA_PIN_GMI_IORDY_PI5, + TEGRA_PIN_GMI_CS7_N_PI6, +}; + +static const unsigned drive_at2_pins[] = { + TEGRA_PIN_GMI_AD0_PG0, + TEGRA_PIN_GMI_AD1_PG1, + TEGRA_PIN_GMI_AD2_PG2, + TEGRA_PIN_GMI_AD3_PG3, + TEGRA_PIN_GMI_AD4_PG4, + TEGRA_PIN_GMI_AD5_PG5, + TEGRA_PIN_GMI_AD6_PG6, + TEGRA_PIN_GMI_AD7_PG7, + TEGRA_PIN_GMI_WR_N_PI0, + TEGRA_PIN_GMI_OE_N_PI1, + TEGRA_PIN_GMI_DQS_PI2, + TEGRA_PIN_GMI_CS6_N_PI3, + TEGRA_PIN_GMI_RST_N_PI4, + TEGRA_PIN_GMI_WAIT_PI7, + TEGRA_PIN_GMI_ADV_N_PK0, + TEGRA_PIN_GMI_CLK_PK1, + TEGRA_PIN_GMI_CS4_N_PK2, + TEGRA_PIN_GMI_CS2_N_PK3, + TEGRA_PIN_GMI_CS3_N_PK4, +}; + +static const unsigned drive_at3_pins[] = { + TEGRA_PIN_GMI_WP_N_PC7, + TEGRA_PIN_GMI_CS0_N_PJ0, +}; + +static const unsigned drive_at4_pins[] = { + TEGRA_PIN_GMI_A17_PB0, + TEGRA_PIN_GMI_A18_PB1, + TEGRA_PIN_GMI_CS1_N_PJ2, + TEGRA_PIN_GMI_A16_PJ7, + TEGRA_PIN_GMI_A19_PK7, +}; + +static const unsigned drive_at5_pins[] = { + TEGRA_PIN_GEN2_I2C_SCL_PT5, + TEGRA_PIN_GEN2_I2C_SDA_PT6, +}; + +static const unsigned drive_cdev1_pins[] = { + TEGRA_PIN_CLK1_OUT_PW4, + TEGRA_PIN_CLK1_REQ_PEE2, +}; + +static const unsigned drive_cdev2_pins[] = { + TEGRA_PIN_CLK2_OUT_PW5, + TEGRA_PIN_CLK2_REQ_PCC5, +}; + +static const unsigned drive_cec_pins[] = { + TEGRA_PIN_HDMI_CEC_PEE3, +}; + +static const unsigned drive_crt_pins[] = { + TEGRA_PIN_CRT_HSYNC_PV6, + TEGRA_PIN_CRT_VSYNC_PV7, +}; + +static const unsigned drive_csus_pins[] = { + TEGRA_PIN_VI_MCLK_PT1, +}; + +static const unsigned drive_dap1_pins[] = { + TEGRA_PIN_SPDIF_OUT_PK5, + TEGRA_PIN_SPDIF_IN_PK6, + TEGRA_PIN_DAP1_FS_PN0, + TEGRA_PIN_DAP1_DIN_PN1, + TEGRA_PIN_DAP1_DOUT_PN2, + TEGRA_PIN_DAP1_SCLK_PN3, +}; + +static const unsigned drive_dap2_pins[] = { + TEGRA_PIN_DAP2_FS_PA2, + TEGRA_PIN_DAP2_SCLK_PA3, + TEGRA_PIN_DAP2_DIN_PA4, + TEGRA_PIN_DAP2_DOUT_PA5, +}; + +static const unsigned drive_dap3_pins[] = { + TEGRA_PIN_DAP3_FS_PP0, + TEGRA_PIN_DAP3_DIN_PP1, + TEGRA_PIN_DAP3_DOUT_PP2, + TEGRA_PIN_DAP3_SCLK_PP3, +}; + +static const unsigned drive_dap4_pins[] = { + TEGRA_PIN_DAP4_FS_PP4, + TEGRA_PIN_DAP4_DIN_PP5, + TEGRA_PIN_DAP4_DOUT_PP6, + TEGRA_PIN_DAP4_SCLK_PP7, +}; + +static const unsigned drive_dbg_pins[] = { + TEGRA_PIN_GEN1_I2C_SCL_PC4, + TEGRA_PIN_GEN1_I2C_SDA_PC5, + TEGRA_PIN_PU0, + TEGRA_PIN_PU1, + TEGRA_PIN_PU2, + TEGRA_PIN_PU3, + TEGRA_PIN_PU4, + TEGRA_PIN_PU5, + TEGRA_PIN_PU6, + TEGRA_PIN_JTAG_RTCK_PU7, + TEGRA_PIN_JTAG_TCK, + TEGRA_PIN_JTAG_TDI, + TEGRA_PIN_JTAG_TDO, + TEGRA_PIN_JTAG_TMS, + TEGRA_PIN_JTAG_TRST_N, + TEGRA_PIN_TEST_MODE_EN, +}; + +static const unsigned drive_ddc_pins[] = { + TEGRA_PIN_DDC_SCL_PV4, + TEGRA_PIN_DDC_SDA_PV5, +}; + +static const unsigned drive_dev3_pins[] = { + TEGRA_PIN_CLK3_OUT_PEE0, + TEGRA_PIN_CLK3_REQ_PEE1, +}; + +static const unsigned drive_gma_pins[] = { + TEGRA_PIN_SDMMC4_DAT0_PAA0, + TEGRA_PIN_SDMMC4_DAT1_PAA1, + TEGRA_PIN_SDMMC4_DAT2_PAA2, + TEGRA_PIN_SDMMC4_DAT3_PAA3, + TEGRA_PIN_SDMMC4_RST_N_PCC3, +}; + +static const unsigned drive_gmb_pins[] = { + TEGRA_PIN_SDMMC4_DAT4_PAA4, + TEGRA_PIN_SDMMC4_DAT5_PAA5, + TEGRA_PIN_SDMMC4_DAT6_PAA6, + TEGRA_PIN_SDMMC4_DAT7_PAA7, +}; + +static const unsigned drive_gmc_pins[] = { + TEGRA_PIN_SDMMC4_CLK_PCC4, +}; + +static const unsigned drive_gmd_pins[] = { + TEGRA_PIN_SDMMC4_CMD_PT7, +}; + +static const unsigned drive_gme_pins[] = { + TEGRA_PIN_PBB0, + TEGRA_PIN_CAM_I2C_SCL_PBB1, + TEGRA_PIN_CAM_I2C_SDA_PBB2, + TEGRA_PIN_PBB3, + TEGRA_PIN_PCC2, +}; + +static const unsigned drive_gmf_pins[] = { + TEGRA_PIN_PBB4, + TEGRA_PIN_PBB5, + TEGRA_PIN_PBB6, + TEGRA_PIN_PBB7, +}; + +static const unsigned drive_gmg_pins[] = { + TEGRA_PIN_CAM_MCLK_PCC0, +}; + +static const unsigned drive_gmh_pins[] = { + TEGRA_PIN_PCC1, +}; + +static const unsigned drive_gpv_pins[] = { + TEGRA_PIN_PEX_L2_RST_N_PCC6, + TEGRA_PIN_PEX_L2_CLKREQ_N_PCC7, + TEGRA_PIN_PEX_L0_PRSNT_N_PDD0, + TEGRA_PIN_PEX_L0_RST_N_PDD1, + TEGRA_PIN_PEX_L0_CLKREQ_N_PDD2, + TEGRA_PIN_PEX_WAKE_N_PDD3, + TEGRA_PIN_PEX_L1_PRSNT_N_PDD4, + TEGRA_PIN_PEX_L1_RST_N_PDD5, + TEGRA_PIN_PEX_L1_CLKREQ_N_PDD6, + TEGRA_PIN_PEX_L2_PRSNT_N_PDD7, +}; + +static const unsigned drive_lcd1_pins[] = { + TEGRA_PIN_LCD_PWR1_PC1, + TEGRA_PIN_LCD_PWR2_PC6, + TEGRA_PIN_LCD_CS0_N_PN4, + TEGRA_PIN_LCD_SDOUT_PN5, + TEGRA_PIN_LCD_DC0_PN6, + TEGRA_PIN_LCD_SDIN_PZ2, + TEGRA_PIN_LCD_WR_N_PZ3, + TEGRA_PIN_LCD_SCK_PZ4, +}; + +static const unsigned drive_lcd2_pins[] = { + TEGRA_PIN_LCD_PWR0_PB2, + TEGRA_PIN_LCD_PCLK_PB3, + TEGRA_PIN_LCD_DC1_PD2, + TEGRA_PIN_LCD_D0_PE0, + TEGRA_PIN_LCD_D1_PE1, + TEGRA_PIN_LCD_D2_PE2, + TEGRA_PIN_LCD_D3_PE3, + TEGRA_PIN_LCD_D4_PE4, + TEGRA_PIN_LCD_D5_PE5, + TEGRA_PIN_LCD_D6_PE6, + TEGRA_PIN_LCD_D7_PE7, + TEGRA_PIN_LCD_D8_PF0, + TEGRA_PIN_LCD_D9_PF1, + TEGRA_PIN_LCD_D10_PF2, + TEGRA_PIN_LCD_D11_PF3, + TEGRA_PIN_LCD_D12_PF4, + TEGRA_PIN_LCD_D13_PF5, + TEGRA_PIN_LCD_D14_PF6, + TEGRA_PIN_LCD_D15_PF7, + TEGRA_PIN_LCD_DE_PJ1, + TEGRA_PIN_LCD_HSYNC_PJ3, + TEGRA_PIN_LCD_VSYNC_PJ4, + TEGRA_PIN_LCD_D16_PM0, + TEGRA_PIN_LCD_D17_PM1, + TEGRA_PIN_LCD_D18_PM2, + TEGRA_PIN_LCD_D19_PM3, + TEGRA_PIN_LCD_D20_PM4, + TEGRA_PIN_LCD_D21_PM5, + TEGRA_PIN_LCD_D22_PM6, + TEGRA_PIN_LCD_D23_PM7, + TEGRA_PIN_HDMI_INT_PN7, + TEGRA_PIN_LCD_CS1_N_PW0, + TEGRA_PIN_LCD_M1_PW1, +}; + +static const unsigned drive_owr_pins[] = { + TEGRA_PIN_OWR, +}; + +static const unsigned drive_sdio1_pins[] = { + TEGRA_PIN_SDMMC1_DAT3_PY4, + TEGRA_PIN_SDMMC1_DAT2_PY5, + TEGRA_PIN_SDMMC1_DAT1_PY6, + TEGRA_PIN_SDMMC1_DAT0_PY7, + TEGRA_PIN_SDMMC1_CLK_PZ0, + TEGRA_PIN_SDMMC1_CMD_PZ1, +}; + +static const unsigned drive_sdio2_pins[] = { + TEGRA_PIN_SDMMC3_DAT5_PD0, + TEGRA_PIN_SDMMC3_DAT4_PD1, + TEGRA_PIN_SDMMC3_DAT6_PD3, + TEGRA_PIN_SDMMC3_DAT7_PD4, +}; + +static const unsigned drive_sdio3_pins[] = { + TEGRA_PIN_SDMMC3_CLK_PA6, + TEGRA_PIN_SDMMC3_CMD_PA7, + TEGRA_PIN_SDMMC3_DAT3_PB4, + TEGRA_PIN_SDMMC3_DAT2_PB5, + TEGRA_PIN_SDMMC3_DAT1_PB6, + TEGRA_PIN_SDMMC3_DAT0_PB7, +}; + +static const unsigned drive_spi_pins[] = { + TEGRA_PIN_SPI2_CS1_N_PW2, + TEGRA_PIN_SPI2_CS2_N_PW3, + TEGRA_PIN_SPI2_MOSI_PX0, + TEGRA_PIN_SPI2_MISO_PX1, + TEGRA_PIN_SPI2_SCK_PX2, + TEGRA_PIN_SPI2_CS0_N_PX3, + TEGRA_PIN_SPI1_MOSI_PX4, + TEGRA_PIN_SPI1_SCK_PX5, + TEGRA_PIN_SPI1_CS0_N_PX6, + TEGRA_PIN_SPI1_MISO_PX7, +}; + +static const unsigned drive_uaa_pins[] = { + TEGRA_PIN_ULPI_DATA0_PO1, + TEGRA_PIN_ULPI_DATA1_PO2, + TEGRA_PIN_ULPI_DATA2_PO3, + TEGRA_PIN_ULPI_DATA3_PO4, +}; + +static const unsigned drive_uab_pins[] = { + TEGRA_PIN_ULPI_DATA7_PO0, + TEGRA_PIN_ULPI_DATA4_PO5, + TEGRA_PIN_ULPI_DATA5_PO6, + TEGRA_PIN_ULPI_DATA6_PO7, + TEGRA_PIN_PV0, + TEGRA_PIN_PV1, + TEGRA_PIN_PV2, + TEGRA_PIN_PV3, +}; + +static const unsigned drive_uart2_pins[] = { + TEGRA_PIN_UART2_TXD_PC2, + TEGRA_PIN_UART2_RXD_PC3, + TEGRA_PIN_UART2_CTS_N_PJ5, + TEGRA_PIN_UART2_RTS_N_PJ6, +}; + +static const unsigned drive_uart3_pins[] = { + TEGRA_PIN_UART3_CTS_N_PA1, + TEGRA_PIN_UART3_RTS_N_PC0, + TEGRA_PIN_UART3_TXD_PW6, + TEGRA_PIN_UART3_RXD_PW7, +}; + +static const unsigned drive_uda_pins[] = { + TEGRA_PIN_ULPI_CLK_PY0, + TEGRA_PIN_ULPI_DIR_PY1, + TEGRA_PIN_ULPI_NXT_PY2, + TEGRA_PIN_ULPI_STP_PY3, +}; + +static const unsigned drive_vi1_pins[] = { + TEGRA_PIN_VI_D1_PD5, + TEGRA_PIN_VI_VSYNC_PD6, + TEGRA_PIN_VI_HSYNC_PD7, + TEGRA_PIN_VI_D2_PL0, + TEGRA_PIN_VI_D3_PL1, + TEGRA_PIN_VI_D4_PL2, + TEGRA_PIN_VI_D5_PL3, + TEGRA_PIN_VI_D6_PL4, + TEGRA_PIN_VI_D7_PL5, + TEGRA_PIN_VI_D8_PL6, + TEGRA_PIN_VI_D9_PL7, + TEGRA_PIN_VI_PCLK_PT0, + TEGRA_PIN_VI_D10_PT2, + TEGRA_PIN_VI_D11_PT3, + TEGRA_PIN_VI_D0_PT4, +}; + +enum tegra_mux { + TEGRA_MUX_BLINK, + TEGRA_MUX_CEC, + TEGRA_MUX_CLK_12M_OUT, + TEGRA_MUX_CLK_32K_IN, + TEGRA_MUX_CORE_PWR_REQ, + TEGRA_MUX_CPU_PWR_REQ, + TEGRA_MUX_CRT, + TEGRA_MUX_DAP, + TEGRA_MUX_DDR, + TEGRA_MUX_DEV3, + TEGRA_MUX_DISPLAYA, + TEGRA_MUX_DISPLAYB, + TEGRA_MUX_DTV, + TEGRA_MUX_EXTPERIPH1, + TEGRA_MUX_EXTPERIPH2, + TEGRA_MUX_EXTPERIPH3, + TEGRA_MUX_GMI, + TEGRA_MUX_GMI_ALT, + TEGRA_MUX_HDA, + TEGRA_MUX_HDCP, + TEGRA_MUX_HDMI, + TEGRA_MUX_HSI, + TEGRA_MUX_I2C1, + TEGRA_MUX_I2C2, + TEGRA_MUX_I2C3, + TEGRA_MUX_I2C4, + TEGRA_MUX_I2CPWR, + TEGRA_MUX_I2S0, + TEGRA_MUX_I2S1, + TEGRA_MUX_I2S2, + TEGRA_MUX_I2S3, + TEGRA_MUX_I2S4, + TEGRA_MUX_INVALID, + TEGRA_MUX_KBC, + TEGRA_MUX_MIO, + TEGRA_MUX_NAND, + TEGRA_MUX_NAND_ALT, + TEGRA_MUX_OWR, + TEGRA_MUX_PCIE, + TEGRA_MUX_PWM0, + TEGRA_MUX_PWM1, + TEGRA_MUX_PWM2, + TEGRA_MUX_PWM3, + TEGRA_MUX_PWR_INT_N, + TEGRA_MUX_RSVD1, + TEGRA_MUX_RSVD2, + TEGRA_MUX_RSVD3, + TEGRA_MUX_RSVD4, + TEGRA_MUX_RTCK, + TEGRA_MUX_SATA, + TEGRA_MUX_SDMMC1, + TEGRA_MUX_SDMMC2, + TEGRA_MUX_SDMMC3, + TEGRA_MUX_SDMMC4, + TEGRA_MUX_SPDIF, + TEGRA_MUX_SPI1, + TEGRA_MUX_SPI2, + TEGRA_MUX_SPI2_ALT, + TEGRA_MUX_SPI3, + TEGRA_MUX_SPI4, + TEGRA_MUX_SPI5, + TEGRA_MUX_SPI6, + TEGRA_MUX_SYSCLK, + TEGRA_MUX_TEST, + TEGRA_MUX_TRACE, + TEGRA_MUX_UARTA, + TEGRA_MUX_UARTB, + TEGRA_MUX_UARTC, + TEGRA_MUX_UARTD, + TEGRA_MUX_UARTE, + TEGRA_MUX_ULPI, + TEGRA_MUX_VGP1, + TEGRA_MUX_VGP2, + TEGRA_MUX_VGP3, + TEGRA_MUX_VGP4, + TEGRA_MUX_VGP5, + TEGRA_MUX_VGP6, + TEGRA_MUX_VI, + TEGRA_MUX_VI_ALT1, + TEGRA_MUX_VI_ALT2, + TEGRA_MUX_VI_ALT3, +}; +static const char * const blink_groups[] = { + "clk_32k_out_pa0", +}; + +static const char * const cec_groups[] = { + "hdmi_cec_pee3", + "owr", +}; + +static const char * const clk_12m_out_groups[] = { + "pv3", +}; + +static const char * const clk_32k_in_groups[] = { + "clk_32k_in", +}; + +static const char * const core_pwr_req_groups[] = { + "core_pwr_req", +}; + +static const char * const cpu_pwr_req_groups[] = { + "cpu_pwr_req", +}; + +static const char * const crt_groups[] = { + "crt_hsync_pv6", + "crt_vsync_pv7", +}; + +static const char * const dap_groups[] = { + "clk1_req_pee2", + "clk2_req_pcc5", +}; + +static const char * const ddr_groups[] = { + "vi_d0_pt4", + "vi_d1_pd5", + "vi_d10_pt2", + "vi_d11_pt3", + "vi_d2_pl0", + "vi_d3_pl1", + "vi_d4_pl2", + "vi_d5_pl3", + "vi_d6_pl4", + "vi_d7_pl5", + "vi_d8_pl6", + "vi_d9_pl7", + "vi_hsync_pd7", + "vi_vsync_pd6", +}; + +static const char * const dev3_groups[] = { + "clk3_req_pee1", +}; + +static const char * const displaya_groups[] = { + "dap3_din_pp1", + "dap3_dout_pp2", + "dap3_fs_pp0", + "dap3_sclk_pp3", + "pbb3", + "pbb4", + "pbb5", + "pbb6", + "lcd_cs0_n_pn4", + "lcd_cs1_n_pw0", + "lcd_d0_pe0", + "lcd_d1_pe1", + "lcd_d10_pf2", + "lcd_d11_pf3", + "lcd_d12_pf4", + "lcd_d13_pf5", + "lcd_d14_pf6", + "lcd_d15_pf7", + "lcd_d16_pm0", + "lcd_d17_pm1", + "lcd_d18_pm2", + "lcd_d19_pm3", + "lcd_d2_pe2", + "lcd_d20_pm4", + "lcd_d21_pm5", + "lcd_d22_pm6", + "lcd_d23_pm7", + "lcd_d3_pe3", + "lcd_d4_pe4", + "lcd_d5_pe5", + "lcd_d6_pe6", + "lcd_d7_pe7", + "lcd_d8_pf0", + "lcd_d9_pf1", + "lcd_dc0_pn6", + "lcd_dc1_pd2", + "lcd_de_pj1", + "lcd_hsync_pj3", + "lcd_m1_pw1", + "lcd_pclk_pb3", + "lcd_pwr0_pb2", + "lcd_pwr1_pc1", + "lcd_pwr2_pc6", + "lcd_sck_pz4", + "lcd_sdin_pz2", + "lcd_sdout_pn5", + "lcd_vsync_pj4", + "lcd_wr_n_pz3", +}; + +static const char * const displayb_groups[] = { + "dap3_din_pp1", + "dap3_dout_pp2", + "dap3_fs_pp0", + "dap3_sclk_pp3", + "pbb3", + "pbb4", + "pbb5", + "pbb6", + "lcd_cs0_n_pn4", + "lcd_cs1_n_pw0", + "lcd_d0_pe0", + "lcd_d1_pe1", + "lcd_d10_pf2", + "lcd_d11_pf3", + "lcd_d12_pf4", + "lcd_d13_pf5", + "lcd_d14_pf6", + "lcd_d15_pf7", + "lcd_d16_pm0", + "lcd_d17_pm1", + "lcd_d18_pm2", + "lcd_d19_pm3", + "lcd_d2_pe2", + "lcd_d20_pm4", + "lcd_d21_pm5", + "lcd_d22_pm6", + "lcd_d23_pm7", + "lcd_d3_pe3", + "lcd_d4_pe4", + "lcd_d5_pe5", + "lcd_d6_pe6", + "lcd_d7_pe7", + "lcd_d8_pf0", + "lcd_d9_pf1", + "lcd_dc0_pn6", + "lcd_dc1_pd2", + "lcd_de_pj1", + "lcd_hsync_pj3", + "lcd_m1_pw1", + "lcd_pclk_pb3", + "lcd_pwr0_pb2", + "lcd_pwr1_pc1", + "lcd_pwr2_pc6", + "lcd_sck_pz4", + "lcd_sdin_pz2", + "lcd_sdout_pn5", + "lcd_vsync_pj4", + "lcd_wr_n_pz3", +}; + +static const char * const dtv_groups[] = { + "gmi_a17_pb0", + "gmi_a18_pb1", + "gmi_cs0_n_pj0", + "gmi_cs1_n_pj2", +}; + +static const char * const extperiph1_groups[] = { + "clk1_out_pw4", +}; + +static const char * const extperiph2_groups[] = { + "clk2_out_pw5", +}; + +static const char * const extperiph3_groups[] = { + "clk3_out_pee0", +}; + +static const char * const gmi_groups[] = { + "dap1_din_pn1", + "dap1_dout_pn2", + "dap1_fs_pn0", + "dap1_sclk_pn3", + "dap2_din_pa4", + "dap2_dout_pa5", + "dap2_fs_pa2", + "dap2_sclk_pa3", + "dap4_din_pp5", + "dap4_dout_pp6", + "dap4_fs_pp4", + "dap4_sclk_pp7", + "gen2_i2c_scl_pt5", + "gen2_i2c_sda_pt6", + "gmi_a16_pj7", + "gmi_a17_pb0", + "gmi_a18_pb1", + "gmi_a19_pk7", + "gmi_ad0_pg0", + "gmi_ad1_pg1", + "gmi_ad10_ph2", + "gmi_ad11_ph3", + "gmi_ad12_ph4", + "gmi_ad13_ph5", + "gmi_ad14_ph6", + "gmi_ad15_ph7", + "gmi_ad2_pg2", + "gmi_ad3_pg3", + "gmi_ad4_pg4", + "gmi_ad5_pg5", + "gmi_ad6_pg6", + "gmi_ad7_pg7", + "gmi_ad8_ph0", + "gmi_ad9_ph1", + "gmi_adv_n_pk0", + "gmi_clk_pk1", + "gmi_cs0_n_pj0", + "gmi_cs1_n_pj2", + "gmi_cs2_n_pk3", + "gmi_cs3_n_pk4", + "gmi_cs4_n_pk2", + "gmi_cs6_n_pi3", + "gmi_cs7_n_pi6", + "gmi_dqs_pi2", + "gmi_iordy_pi5", + "gmi_oe_n_pi1", + "gmi_rst_n_pi4", + "gmi_wait_pi7", + "gmi_wp_n_pc7", + "gmi_wr_n_pi0", + "pu0", + "pu1", + "pu2", + "pu3", + "pu4", + "pu5", + "pu6", + "sdmmc4_clk_pcc4", + "sdmmc4_cmd_pt7", + "sdmmc4_dat0_paa0", + "sdmmc4_dat1_paa1", + "sdmmc4_dat2_paa2", + "sdmmc4_dat3_paa3", + "sdmmc4_dat4_paa4", + "sdmmc4_dat5_paa5", + "sdmmc4_dat6_paa6", + "sdmmc4_dat7_paa7", + "spi1_cs0_n_px6", + "spi1_mosi_px4", + "spi1_sck_px5", + "spi2_cs0_n_px3", + "spi2_miso_px1", + "spi2_mosi_px0", + "spi2_sck_px2", + "uart2_cts_n_pj5", + "uart2_rts_n_pj6", + "uart3_cts_n_pa1", + "uart3_rts_n_pc0", + "uart3_rxd_pw7", + "uart3_txd_pw6", +}; + +static const char * const gmi_alt_groups[] = { + "gmi_a16_pj7", + "gmi_cs3_n_pk4", + "gmi_cs7_n_pi6", + "gmi_wp_n_pc7", +}; + +static const char * const hda_groups[] = { + "clk1_req_pee2", + "dap1_din_pn1", + "dap1_dout_pn2", + "dap1_fs_pn0", + "dap1_sclk_pn3", + "dap2_din_pa4", + "dap2_dout_pa5", + "dap2_fs_pa2", + "dap2_sclk_pa3", + "pex_l0_clkreq_n_pdd2", + "pex_l0_prsnt_n_pdd0", + "pex_l0_rst_n_pdd1", + "pex_l1_clkreq_n_pdd6", + "pex_l1_prsnt_n_pdd4", + "pex_l1_rst_n_pdd5", + "pex_l2_clkreq_n_pcc7", + "pex_l2_prsnt_n_pdd7", + "pex_l2_rst_n_pcc6", + "pex_wake_n_pdd3", + "spdif_in_pk6", +}; + +static const char * const hdcp_groups[] = { + "gen2_i2c_scl_pt5", + "gen2_i2c_sda_pt6", + "lcd_pwr0_pb2", + "lcd_pwr2_pc6", + "lcd_sck_pz4", + "lcd_sdout_pn5", + "lcd_wr_n_pz3", +}; + +static const char * const hdmi_groups[] = { + "hdmi_int_pn7", +}; + +static const char * const hsi_groups[] = { + "ulpi_data0_po1", + "ulpi_data1_po2", + "ulpi_data2_po3", + "ulpi_data3_po4", + "ulpi_data4_po5", + "ulpi_data5_po6", + "ulpi_data6_po7", + "ulpi_data7_po0", +}; + +static const char * const i2c1_groups[] = { + "gen1_i2c_scl_pc4", + "gen1_i2c_sda_pc5", + "spdif_in_pk6", + "spdif_out_pk5", + "spi2_cs1_n_pw2", + "spi2_cs2_n_pw3", +}; + +static const char * const i2c2_groups[] = { + "gen2_i2c_scl_pt5", + "gen2_i2c_sda_pt6", +}; + +static const char * const i2c3_groups[] = { + "cam_i2c_scl_pbb1", + "cam_i2c_sda_pbb2", + "sdmmc4_cmd_pt7", + "sdmmc4_dat4_paa4", +}; + +static const char * const i2c4_groups[] = { + "ddc_scl_pv4", + "ddc_sda_pv5", +}; + +static const char * const i2cpwr_groups[] = { + "pwr_i2c_scl_pz6", + "pwr_i2c_sda_pz7", +}; + +static const char * const i2s0_groups[] = { + "dap1_din_pn1", + "dap1_dout_pn2", + "dap1_fs_pn0", + "dap1_sclk_pn3", +}; + +static const char * const i2s1_groups[] = { + "dap2_din_pa4", + "dap2_dout_pa5", + "dap2_fs_pa2", + "dap2_sclk_pa3", +}; + +static const char * const i2s2_groups[] = { + "dap3_din_pp1", + "dap3_dout_pp2", + "dap3_fs_pp0", + "dap3_sclk_pp3", +}; + +static const char * const i2s3_groups[] = { + "dap4_din_pp5", + "dap4_dout_pp6", + "dap4_fs_pp4", + "dap4_sclk_pp7", +}; + +static const char * const i2s4_groups[] = { + "pbb0", + "pbb7", + "pcc1", + "pcc2", + "sdmmc4_dat4_paa4", + "sdmmc4_dat5_paa5", + "sdmmc4_dat6_paa6", + "sdmmc4_dat7_paa7", +}; + +static const char * const invalid_groups[] = { + "kb_row3_pr3", + "sdmmc4_clk_pcc4", +}; + +static const char * const kbc_groups[] = { + "kb_col0_pq0", + "kb_col1_pq1", + "kb_col2_pq2", + "kb_col3_pq3", + "kb_col4_pq4", + "kb_col5_pq5", + "kb_col6_pq6", + "kb_col7_pq7", + "kb_row0_pr0", + "kb_row1_pr1", + "kb_row10_ps2", + "kb_row11_ps3", + "kb_row12_ps4", + "kb_row13_ps5", + "kb_row14_ps6", + "kb_row15_ps7", + "kb_row2_pr2", + "kb_row3_pr3", + "kb_row4_pr4", + "kb_row5_pr5", + "kb_row6_pr6", + "kb_row7_pr7", + "kb_row8_ps0", + "kb_row9_ps1", +}; + +static const char * const mio_groups[] = { + "kb_col6_pq6", + "kb_col7_pq7", + "kb_row10_ps2", + "kb_row11_ps3", + "kb_row12_ps4", + "kb_row13_ps5", + "kb_row14_ps6", + "kb_row15_ps7", + "kb_row6_pr6", + "kb_row7_pr7", + "kb_row8_ps0", + "kb_row9_ps1", +}; + +static const char * const nand_groups[] = { + "gmi_ad0_pg0", + "gmi_ad1_pg1", + "gmi_ad10_ph2", + "gmi_ad11_ph3", + "gmi_ad12_ph4", + "gmi_ad13_ph5", + "gmi_ad14_ph6", + "gmi_ad15_ph7", + "gmi_ad2_pg2", + "gmi_ad3_pg3", + "gmi_ad4_pg4", + "gmi_ad5_pg5", + "gmi_ad6_pg6", + "gmi_ad7_pg7", + "gmi_ad8_ph0", + "gmi_ad9_ph1", + "gmi_adv_n_pk0", + "gmi_clk_pk1", + "gmi_cs0_n_pj0", + "gmi_cs1_n_pj2", + "gmi_cs2_n_pk3", + "gmi_cs3_n_pk4", + "gmi_cs4_n_pk2", + "gmi_cs6_n_pi3", + "gmi_cs7_n_pi6", + "gmi_dqs_pi2", + "gmi_iordy_pi5", + "gmi_oe_n_pi1", + "gmi_rst_n_pi4", + "gmi_wait_pi7", + "gmi_wp_n_pc7", + "gmi_wr_n_pi0", + "kb_col0_pq0", + "kb_col1_pq1", + "kb_col2_pq2", + "kb_col3_pq3", + "kb_col4_pq4", + "kb_col5_pq5", + "kb_col6_pq6", + "kb_col7_pq7", + "kb_row0_pr0", + "kb_row1_pr1", + "kb_row10_ps2", + "kb_row11_ps3", + "kb_row12_ps4", + "kb_row13_ps5", + "kb_row14_ps6", + "kb_row15_ps7", + "kb_row2_pr2", + "kb_row3_pr3", + "kb_row4_pr4", + "kb_row5_pr5", + "kb_row6_pr6", + "kb_row7_pr7", + "kb_row8_ps0", + "kb_row9_ps1", + "sdmmc4_clk_pcc4", + "sdmmc4_cmd_pt7", +}; + +static const char * const nand_alt_groups[] = { + "gmi_cs6_n_pi3", + "gmi_cs7_n_pi6", + "gmi_rst_n_pi4", +}; + +static const char * const owr_groups[] = { + "pu0", + "pv2", + "kb_row5_pr5", + "owr", +}; + +static const char * const pcie_groups[] = { + "pex_l0_clkreq_n_pdd2", + "pex_l0_prsnt_n_pdd0", + "pex_l0_rst_n_pdd1", + "pex_l1_clkreq_n_pdd6", + "pex_l1_prsnt_n_pdd4", + "pex_l1_rst_n_pdd5", + "pex_l2_clkreq_n_pcc7", + "pex_l2_prsnt_n_pdd7", + "pex_l2_rst_n_pcc6", + "pex_wake_n_pdd3", +}; + +static const char * const pwm0_groups[] = { + "gmi_ad8_ph0", + "pu3", + "sdmmc3_dat3_pb4", + "sdmmc3_dat5_pd0", + "uart3_rts_n_pc0", +}; + +static const char * const pwm1_groups[] = { + "gmi_ad9_ph1", + "pu4", + "sdmmc3_dat2_pb5", + "sdmmc3_dat4_pd1", +}; + +static const char * const pwm2_groups[] = { + "gmi_ad10_ph2", + "pu5", + "sdmmc3_clk_pa6", +}; + +static const char * const pwm3_groups[] = { + "gmi_ad11_ph3", + "pu6", + "sdmmc3_cmd_pa7", +}; + +static const char * const pwr_int_n_groups[] = { + "pwr_int_n", +}; + +static const char * const rsvd1_groups[] = { + "gmi_ad0_pg0", + "gmi_ad1_pg1", + "gmi_ad12_ph4", + "gmi_ad13_ph5", + "gmi_ad14_ph6", + "gmi_ad15_ph7", + "gmi_ad2_pg2", + "gmi_ad3_pg3", + "gmi_ad4_pg4", + "gmi_ad5_pg5", + "gmi_ad6_pg6", + "gmi_ad7_pg7", + "gmi_adv_n_pk0", + "gmi_clk_pk1", + "gmi_cs0_n_pj0", + "gmi_cs1_n_pj2", + "gmi_cs2_n_pk3", + "gmi_cs3_n_pk4", + "gmi_cs4_n_pk2", + "gmi_dqs_pi2", + "gmi_iordy_pi5", + "gmi_oe_n_pi1", + "gmi_wait_pi7", + "gmi_wp_n_pc7", + "gmi_wr_n_pi0", + "pu1", + "pu2", + "pv0", + "pv1", + "sdmmc3_dat0_pb7", + "sdmmc3_dat1_pb6", + "sdmmc3_dat2_pb5", + "sdmmc3_dat3_pb4", + "vi_pclk_pt0", +}; + +static const char * const rsvd2_groups[] = { + "clk1_out_pw4", + "clk2_out_pw5", + "clk2_req_pcc5", + "clk3_out_pee0", + "clk3_req_pee1", + "clk_32k_in", + "clk_32k_out_pa0", + "core_pwr_req", + "cpu_pwr_req", + "crt_hsync_pv6", + "crt_vsync_pv7", + "dap3_din_pp1", + "dap3_dout_pp2", + "dap3_fs_pp0", + "dap3_sclk_pp3", + "dap4_din_pp5", + "dap4_dout_pp6", + "dap4_fs_pp4", + "dap4_sclk_pp7", + "ddc_scl_pv4", + "ddc_sda_pv5", + "gen1_i2c_scl_pc4", + "gen1_i2c_sda_pc5", + "pbb0", + "pbb7", + "pcc1", + "pcc2", + "pv0", + "pv1", + "pv2", + "pv3", + "hdmi_cec_pee3", + "hdmi_int_pn7", + "jtag_rtck_pu7", + "pwr_i2c_scl_pz6", + "pwr_i2c_sda_pz7", + "pwr_int_n", + "sdmmc1_clk_pz0", + "sdmmc1_cmd_pz1", + "sdmmc1_dat0_py7", + "sdmmc1_dat1_py6", + "sdmmc1_dat2_py5", + "sdmmc1_dat3_py4", + "sdmmc3_dat0_pb7", + "sdmmc3_dat1_pb6", + "sdmmc4_rst_n_pcc3", + "spdif_out_pk5", + "sys_clk_req_pz5", + "uart3_cts_n_pa1", + "uart3_rxd_pw7", + "uart3_txd_pw6", + "ulpi_clk_py0", + "ulpi_dir_py1", + "ulpi_nxt_py2", + "ulpi_stp_py3", + "vi_d0_pt4", + "vi_d10_pt2", + "vi_d11_pt3", + "vi_hsync_pd7", + "vi_vsync_pd6", +}; + +static const char * const rsvd3_groups[] = { + "cam_i2c_scl_pbb1", + "cam_i2c_sda_pbb2", + "clk1_out_pw4", + "clk1_req_pee2", + "clk2_out_pw5", + "clk2_req_pcc5", + "clk3_out_pee0", + "clk3_req_pee1", + "clk_32k_in", + "clk_32k_out_pa0", + "core_pwr_req", + "cpu_pwr_req", + "crt_hsync_pv6", + "crt_vsync_pv7", + "dap2_din_pa4", + "dap2_dout_pa5", + "dap2_fs_pa2", + "dap2_sclk_pa3", + "ddc_scl_pv4", + "ddc_sda_pv5", + "gen1_i2c_scl_pc4", + "gen1_i2c_sda_pc5", + "pbb0", + "pbb7", + "pcc1", + "pcc2", + "pv0", + "pv1", + "pv2", + "pv3", + "hdmi_cec_pee3", + "hdmi_int_pn7", + "jtag_rtck_pu7", + "kb_row0_pr0", + "kb_row1_pr1", + "kb_row2_pr2", + "kb_row3_pr3", + "lcd_d0_pe0", + "lcd_d1_pe1", + "lcd_d10_pf2", + "lcd_d11_pf3", + "lcd_d12_pf4", + "lcd_d13_pf5", + "lcd_d14_pf6", + "lcd_d15_pf7", + "lcd_d16_pm0", + "lcd_d17_pm1", + "lcd_d18_pm2", + "lcd_d19_pm3", + "lcd_d2_pe2", + "lcd_d20_pm4", + "lcd_d21_pm5", + "lcd_d22_pm6", + "lcd_d23_pm7", + "lcd_d3_pe3", + "lcd_d4_pe4", + "lcd_d5_pe5", + "lcd_d6_pe6", + "lcd_d7_pe7", + "lcd_d8_pf0", + "lcd_d9_pf1", + "lcd_dc0_pn6", + "lcd_dc1_pd2", + "lcd_de_pj1", + "lcd_hsync_pj3", + "lcd_m1_pw1", + "lcd_pclk_pb3", + "lcd_pwr1_pc1", + "lcd_vsync_pj4", + "owr", + "pex_l0_clkreq_n_pdd2", + "pex_l0_prsnt_n_pdd0", + "pex_l0_rst_n_pdd1", + "pex_l1_clkreq_n_pdd6", + "pex_l1_prsnt_n_pdd4", + "pex_l1_rst_n_pdd5", + "pex_l2_clkreq_n_pcc7", + "pex_l2_prsnt_n_pdd7", + "pex_l2_rst_n_pcc6", + "pex_wake_n_pdd3", + "pwr_i2c_scl_pz6", + "pwr_i2c_sda_pz7", + "pwr_int_n", + "sdmmc1_clk_pz0", + "sdmmc1_cmd_pz1", + "sdmmc4_rst_n_pcc3", + "sys_clk_req_pz5", +}; + +static const char * const rsvd4_groups[] = { + "clk1_out_pw4", + "clk1_req_pee2", + "clk2_out_pw5", + "clk2_req_pcc5", + "clk3_out_pee0", + "clk3_req_pee1", + "clk_32k_in", + "clk_32k_out_pa0", + "core_pwr_req", + "cpu_pwr_req", + "crt_hsync_pv6", + "crt_vsync_pv7", + "dap4_din_pp5", + "dap4_dout_pp6", + "dap4_fs_pp4", + "dap4_sclk_pp7", + "ddc_scl_pv4", + "ddc_sda_pv5", + "gen1_i2c_scl_pc4", + "gen1_i2c_sda_pc5", + "gen2_i2c_scl_pt5", + "gen2_i2c_sda_pt6", + "gmi_a19_pk7", + "gmi_ad0_pg0", + "gmi_ad1_pg1", + "gmi_ad10_ph2", + "gmi_ad11_ph3", + "gmi_ad12_ph4", + "gmi_ad13_ph5", + "gmi_ad14_ph6", + "gmi_ad15_ph7", + "gmi_ad2_pg2", + "gmi_ad3_pg3", + "gmi_ad4_pg4", + "gmi_ad5_pg5", + "gmi_ad6_pg6", + "gmi_ad7_pg7", + "gmi_ad8_ph0", + "gmi_ad9_ph1", + "gmi_adv_n_pk0", + "gmi_clk_pk1", + "gmi_cs2_n_pk3", + "gmi_cs4_n_pk2", + "gmi_dqs_pi2", + "gmi_iordy_pi5", + "gmi_oe_n_pi1", + "gmi_rst_n_pi4", + "gmi_wait_pi7", + "gmi_wr_n_pi0", + "pcc2", + "pu0", + "pu1", + "pu2", + "pu3", + "pu4", + "pu5", + "pu6", + "pv0", + "pv1", + "pv2", + "pv3", + "hdmi_cec_pee3", + "hdmi_int_pn7", + "jtag_rtck_pu7", + "kb_col2_pq2", + "kb_col3_pq3", + "kb_col4_pq4", + "kb_col5_pq5", + "kb_row0_pr0", + "kb_row1_pr1", + "kb_row2_pr2", + "kb_row4_pr4", + "lcd_cs0_n_pn4", + "lcd_cs1_n_pw0", + "lcd_d0_pe0", + "lcd_d1_pe1", + "lcd_d10_pf2", + "lcd_d11_pf3", + "lcd_d12_pf4", + "lcd_d13_pf5", + "lcd_d14_pf6", + "lcd_d15_pf7", + "lcd_d16_pm0", + "lcd_d17_pm1", + "lcd_d18_pm2", + "lcd_d19_pm3", + "lcd_d2_pe2", + "lcd_d20_pm4", + "lcd_d21_pm5", + "lcd_d22_pm6", + "lcd_d23_pm7", + "lcd_d3_pe3", + "lcd_d4_pe4", + "lcd_d5_pe5", + "lcd_d6_pe6", + "lcd_d7_pe7", + "lcd_d8_pf0", + "lcd_d9_pf1", + "lcd_dc0_pn6", + "lcd_dc1_pd2", + "lcd_de_pj1", + "lcd_hsync_pj3", + "lcd_m1_pw1", + "lcd_pclk_pb3", + "lcd_pwr1_pc1", + "lcd_sdin_pz2", + "lcd_vsync_pj4", + "owr", + "pex_l0_clkreq_n_pdd2", + "pex_l0_prsnt_n_pdd0", + "pex_l0_rst_n_pdd1", + "pex_l1_clkreq_n_pdd6", + "pex_l1_prsnt_n_pdd4", + "pex_l1_rst_n_pdd5", + "pex_l2_clkreq_n_pcc7", + "pex_l2_prsnt_n_pdd7", + "pex_l2_rst_n_pcc6", + "pex_wake_n_pdd3", + "pwr_i2c_scl_pz6", + "pwr_i2c_sda_pz7", + "pwr_int_n", + "spi1_miso_px7", + "sys_clk_req_pz5", + "uart3_cts_n_pa1", + "uart3_rts_n_pc0", + "uart3_rxd_pw7", + "uart3_txd_pw6", + "vi_d0_pt4", + "vi_d1_pd5", + "vi_d10_pt2", + "vi_d11_pt3", + "vi_d2_pl0", + "vi_d3_pl1", + "vi_d4_pl2", + "vi_d5_pl3", + "vi_d6_pl4", + "vi_d7_pl5", + "vi_d8_pl6", + "vi_d9_pl7", + "vi_hsync_pd7", + "vi_pclk_pt0", + "vi_vsync_pd6", +}; + +static const char * const rtck_groups[] = { + "jtag_rtck_pu7", +}; + +static const char * const sata_groups[] = { + "gmi_cs6_n_pi3", +}; + +static const char * const sdmmc1_groups[] = { + "sdmmc1_clk_pz0", + "sdmmc1_cmd_pz1", + "sdmmc1_dat0_py7", + "sdmmc1_dat1_py6", + "sdmmc1_dat2_py5", + "sdmmc1_dat3_py4", +}; + +static const char * const sdmmc2_groups[] = { + "dap1_din_pn1", + "dap1_dout_pn2", + "dap1_fs_pn0", + "dap1_sclk_pn3", + "kb_row10_ps2", + "kb_row11_ps3", + "kb_row12_ps4", + "kb_row13_ps5", + "kb_row14_ps6", + "kb_row15_ps7", + "kb_row6_pr6", + "kb_row7_pr7", + "kb_row8_ps0", + "kb_row9_ps1", + "spdif_in_pk6", + "spdif_out_pk5", + "vi_d1_pd5", + "vi_d2_pl0", + "vi_d3_pl1", + "vi_d4_pl2", + "vi_d5_pl3", + "vi_d6_pl4", + "vi_d7_pl5", + "vi_d8_pl6", + "vi_d9_pl7", + "vi_pclk_pt0", +}; + +static const char * const sdmmc3_groups[] = { + "sdmmc3_clk_pa6", + "sdmmc3_cmd_pa7", + "sdmmc3_dat0_pb7", + "sdmmc3_dat1_pb6", + "sdmmc3_dat2_pb5", + "sdmmc3_dat3_pb4", + "sdmmc3_dat4_pd1", + "sdmmc3_dat5_pd0", + "sdmmc3_dat6_pd3", + "sdmmc3_dat7_pd4", +}; + +static const char * const sdmmc4_groups[] = { + "cam_i2c_scl_pbb1", + "cam_i2c_sda_pbb2", + "cam_mclk_pcc0", + "pbb0", + "pbb3", + "pbb4", + "pbb5", + "pbb6", + "pbb7", + "pcc1", + "sdmmc4_clk_pcc4", + "sdmmc4_cmd_pt7", + "sdmmc4_dat0_paa0", + "sdmmc4_dat1_paa1", + "sdmmc4_dat2_paa2", + "sdmmc4_dat3_paa3", + "sdmmc4_dat4_paa4", + "sdmmc4_dat5_paa5", + "sdmmc4_dat6_paa6", + "sdmmc4_dat7_paa7", + "sdmmc4_rst_n_pcc3", +}; + +static const char * const spdif_groups[] = { + "sdmmc3_dat6_pd3", + "sdmmc3_dat7_pd4", + "spdif_in_pk6", + "spdif_out_pk5", + "uart2_rxd_pc3", + "uart2_txd_pc2", +}; + +static const char * const spi1_groups[] = { + "spi1_cs0_n_px6", + "spi1_miso_px7", + "spi1_mosi_px4", + "spi1_sck_px5", + "ulpi_clk_py0", + "ulpi_dir_py1", + "ulpi_nxt_py2", + "ulpi_stp_py3", +}; + +static const char * const spi2_groups[] = { + "sdmmc3_cmd_pa7", + "sdmmc3_dat4_pd1", + "sdmmc3_dat5_pd0", + "sdmmc3_dat6_pd3", + "sdmmc3_dat7_pd4", + "spi1_cs0_n_px6", + "spi1_mosi_px4", + "spi1_sck_px5", + "spi2_cs0_n_px3", + "spi2_cs1_n_pw2", + "spi2_cs2_n_pw3", + "spi2_miso_px1", + "spi2_mosi_px0", + "spi2_sck_px2", + "ulpi_data4_po5", + "ulpi_data5_po6", + "ulpi_data6_po7", + "ulpi_data7_po0", +}; + +static const char * const spi2_alt_groups[] = { + "spi1_cs0_n_px6", + "spi1_miso_px7", + "spi1_mosi_px4", + "spi1_sck_px5", + "spi2_cs1_n_pw2", + "spi2_cs2_n_pw3", +}; + +static const char * const spi3_groups[] = { + "sdmmc3_clk_pa6", + "sdmmc3_dat0_pb7", + "sdmmc3_dat1_pb6", + "sdmmc3_dat2_pb5", + "sdmmc3_dat3_pb4", + "sdmmc4_dat0_paa0", + "sdmmc4_dat1_paa1", + "sdmmc4_dat2_paa2", + "sdmmc4_dat3_paa3", + "spi1_miso_px7", + "spi2_cs0_n_px3", + "spi2_cs1_n_pw2", + "spi2_cs2_n_pw3", + "spi2_miso_px1", + "spi2_mosi_px0", + "spi2_sck_px2", + "ulpi_data0_po1", + "ulpi_data1_po2", + "ulpi_data2_po3", + "ulpi_data3_po4", +}; + +static const char * const spi4_groups[] = { + "gmi_a16_pj7", + "gmi_a17_pb0", + "gmi_a18_pb1", + "gmi_a19_pk7", + "sdmmc3_dat4_pd1", + "sdmmc3_dat5_pd0", + "sdmmc3_dat6_pd3", + "sdmmc3_dat7_pd4", + "uart2_cts_n_pj5", + "uart2_rts_n_pj6", + "uart2_rxd_pc3", + "uart2_txd_pc2", +}; + +static const char * const spi5_groups[] = { + "lcd_cs0_n_pn4", + "lcd_cs1_n_pw0", + "lcd_pwr0_pb2", + "lcd_pwr2_pc6", + "lcd_sck_pz4", + "lcd_sdin_pz2", + "lcd_sdout_pn5", + "lcd_wr_n_pz3", +}; + +static const char * const spi6_groups[] = { + "spi2_cs0_n_px3", + "spi2_miso_px1", + "spi2_mosi_px0", + "spi2_sck_px2", +}; + +static const char * const sysclk_groups[] = { + "sys_clk_req_pz5", +}; + +static const char * const test_groups[] = { + "kb_col0_pq0", + "kb_col1_pq1", +}; + +static const char * const trace_groups[] = { + "kb_col0_pq0", + "kb_col1_pq1", + "kb_col2_pq2", + "kb_col3_pq3", + "kb_col4_pq4", + "kb_col5_pq5", + "kb_col6_pq6", + "kb_col7_pq7", + "kb_row4_pr4", + "kb_row5_pr5", +}; + +static const char * const uarta_groups[] = { + "pu0", + "pu1", + "pu2", + "pu3", + "pu4", + "pu5", + "pu6", + "sdmmc1_clk_pz0", + "sdmmc1_cmd_pz1", + "sdmmc1_dat0_py7", + "sdmmc1_dat1_py6", + "sdmmc1_dat2_py5", + "sdmmc1_dat3_py4", + "sdmmc3_clk_pa6", + "sdmmc3_cmd_pa7", + "uart2_cts_n_pj5", + "uart2_rts_n_pj6", + "uart2_rxd_pc3", + "uart2_txd_pc2", + "ulpi_data0_po1", + "ulpi_data1_po2", + "ulpi_data2_po3", + "ulpi_data3_po4", + "ulpi_data4_po5", + "ulpi_data5_po6", + "ulpi_data6_po7", + "ulpi_data7_po0", +}; + +static const char * const uartb_groups[] = { + "uart2_cts_n_pj5", + "uart2_rts_n_pj6", + "uart2_rxd_pc3", + "uart2_txd_pc2", +}; + +static const char * const uartc_groups[] = { + "uart3_cts_n_pa1", + "uart3_rts_n_pc0", + "uart3_rxd_pw7", + "uart3_txd_pw6", +}; + +static const char * const uartd_groups[] = { + "gmi_a16_pj7", + "gmi_a17_pb0", + "gmi_a18_pb1", + "gmi_a19_pk7", + "ulpi_clk_py0", + "ulpi_dir_py1", + "ulpi_nxt_py2", + "ulpi_stp_py3", +}; + +static const char * const uarte_groups[] = { + "sdmmc1_dat0_py7", + "sdmmc1_dat1_py6", + "sdmmc1_dat2_py5", + "sdmmc1_dat3_py4", + "sdmmc4_dat0_paa0", + "sdmmc4_dat1_paa1", + "sdmmc4_dat2_paa2", + "sdmmc4_dat3_paa3", +}; + +static const char * const ulpi_groups[] = { + "ulpi_clk_py0", + "ulpi_data0_po1", + "ulpi_data1_po2", + "ulpi_data2_po3", + "ulpi_data3_po4", + "ulpi_data4_po5", + "ulpi_data5_po6", + "ulpi_data6_po7", + "ulpi_data7_po0", + "ulpi_dir_py1", + "ulpi_nxt_py2", + "ulpi_stp_py3", +}; + +static const char * const vgp1_groups[] = { + "cam_i2c_scl_pbb1", +}; + +static const char * const vgp2_groups[] = { + "cam_i2c_sda_pbb2", +}; + +static const char * const vgp3_groups[] = { + "pbb3", + "sdmmc4_dat5_paa5", +}; + +static const char * const vgp4_groups[] = { + "pbb4", + "sdmmc4_dat6_paa6", +}; + +static const char * const vgp5_groups[] = { + "pbb5", + "sdmmc4_dat7_paa7", +}; + +static const char * const vgp6_groups[] = { + "pbb6", + "sdmmc4_rst_n_pcc3", +}; + +static const char * const vi_groups[] = { + "cam_mclk_pcc0", + "vi_d0_pt4", + "vi_d1_pd5", + "vi_d10_pt2", + "vi_d11_pt3", + "vi_d2_pl0", + "vi_d3_pl1", + "vi_d4_pl2", + "vi_d5_pl3", + "vi_d6_pl4", + "vi_d7_pl5", + "vi_d8_pl6", + "vi_d9_pl7", + "vi_hsync_pd7", + "vi_mclk_pt1", + "vi_pclk_pt0", + "vi_vsync_pd6", +}; + +static const char * const vi_alt1_groups[] = { + "cam_mclk_pcc0", + "vi_mclk_pt1", +}; + +static const char * const vi_alt2_groups[] = { + "vi_mclk_pt1", +}; + +static const char * const vi_alt3_groups[] = { + "cam_mclk_pcc0", + "vi_mclk_pt1", +}; + +#define FUNCTION(fname) \ + { \ + .name = #fname, \ + .groups = fname##_groups, \ + .ngroups = ARRAY_SIZE(fname##_groups), \ + } + +static const struct tegra_function tegra30_functions[] = { + FUNCTION(blink), + FUNCTION(cec), + FUNCTION(clk_12m_out), + FUNCTION(clk_32k_in), + FUNCTION(core_pwr_req), + FUNCTION(cpu_pwr_req), + FUNCTION(crt), + FUNCTION(dap), + FUNCTION(ddr), + FUNCTION(dev3), + FUNCTION(displaya), + FUNCTION(displayb), + FUNCTION(dtv), + FUNCTION(extperiph1), + FUNCTION(extperiph2), + FUNCTION(extperiph3), + FUNCTION(gmi), + FUNCTION(gmi_alt), + FUNCTION(hda), + FUNCTION(hdcp), + FUNCTION(hdmi), + FUNCTION(hsi), + FUNCTION(i2c1), + FUNCTION(i2c2), + FUNCTION(i2c3), + FUNCTION(i2c4), + FUNCTION(i2cpwr), + FUNCTION(i2s0), + FUNCTION(i2s1), + FUNCTION(i2s2), + FUNCTION(i2s3), + FUNCTION(i2s4), + FUNCTION(invalid), + FUNCTION(kbc), + FUNCTION(mio), + FUNCTION(nand), + FUNCTION(nand_alt), + FUNCTION(owr), + FUNCTION(pcie), + FUNCTION(pwm0), + FUNCTION(pwm1), + FUNCTION(pwm2), + FUNCTION(pwm3), + FUNCTION(pwr_int_n), + FUNCTION(rsvd1), + FUNCTION(rsvd2), + FUNCTION(rsvd3), + FUNCTION(rsvd4), + FUNCTION(rtck), + FUNCTION(sata), + FUNCTION(sdmmc1), + FUNCTION(sdmmc2), + FUNCTION(sdmmc3), + FUNCTION(sdmmc4), + FUNCTION(spdif), + FUNCTION(spi1), + FUNCTION(spi2), + FUNCTION(spi2_alt), + FUNCTION(spi3), + FUNCTION(spi4), + FUNCTION(spi5), + FUNCTION(spi6), + FUNCTION(sysclk), + FUNCTION(test), + FUNCTION(trace), + FUNCTION(uarta), + FUNCTION(uartb), + FUNCTION(uartc), + FUNCTION(uartd), + FUNCTION(uarte), + FUNCTION(ulpi), + FUNCTION(vgp1), + FUNCTION(vgp2), + FUNCTION(vgp3), + FUNCTION(vgp4), + FUNCTION(vgp5), + FUNCTION(vgp6), + FUNCTION(vi), + FUNCTION(vi_alt1), + FUNCTION(vi_alt2), + FUNCTION(vi_alt3), +}; + +#define MUXCTL_REG_A 0x3000 +#define PINGROUP_REG_A 0x868 + +#define PINGROUP_REG_Y(r) ((r) - MUXCTL_REG_A) +#define PINGROUP_REG_N(r) -1 + +#define PINGROUP(pg_name, f0, f1, f2, f3, f_safe, r, od, ior) \ + { \ + .name = #pg_name, \ + .pins = pg_name##_pins, \ + .npins = ARRAY_SIZE(pg_name##_pins), \ + .funcs = { \ + TEGRA_MUX_ ## f0, \ + TEGRA_MUX_ ## f1, \ + TEGRA_MUX_ ## f2, \ + TEGRA_MUX_ ## f3, \ + }, \ + .func_safe = TEGRA_MUX_ ## f_safe, \ + .mux_reg = PINGROUP_REG_Y(r), \ + .mux_bank = 0, \ + .mux_bit = 0, \ + .pupd_reg = PINGROUP_REG_Y(r), \ + .pupd_bank = 0, \ + .pupd_bit = 2, \ + .tri_reg = PINGROUP_REG_Y(r), \ + .tri_bank = 0, \ + .tri_bit = 4, \ + .einput_reg = PINGROUP_REG_Y(r), \ + .einput_bank = 0, \ + .einput_bit = 5, \ + .odrain_reg = PINGROUP_REG_##od(r), \ + .odrain_bank = 0, \ + .odrain_bit = 6, \ + .lock_reg = PINGROUP_REG_Y(r), \ + .lock_bank = 0, \ + .lock_bit = 7, \ + .ioreset_reg = PINGROUP_REG_##ior(r), \ + .ioreset_bank = 0, \ + .ioreset_bit = 8, \ + .drv_reg = -1, \ + } + +#define DRV_PINGROUP(pg_name, r, hsm_b, schmitt_b, lpmd_b, \ + drvdn_b, drvdn_w, drvup_b, drvup_w, \ + slwr_b, slwr_w, slwf_b, slwf_w) \ + { \ + .name = "drive_" #pg_name, \ + .pins = drive_##pg_name##_pins, \ + .npins = ARRAY_SIZE(drive_##pg_name##_pins), \ + .mux_reg = -1, \ + .pupd_reg = -1, \ + .tri_reg = -1, \ + .einput_reg = -1, \ + .odrain_reg = -1, \ + .lock_reg = -1, \ + .ioreset_reg = -1, \ + .drv_reg = ((r) - PINGROUP_REG_A), \ + .drv_bank = 1, \ + .hsm_bit = hsm_b, \ + .schmitt_bit = schmitt_b, \ + .lpmd_bit = lpmd_b, \ + .drvdn_bit = drvdn_b, \ + .drvdn_width = drvdn_w, \ + .drvup_bit = drvup_b, \ + .drvup_width = drvup_w, \ + .slwr_bit = slwr_b, \ + .slwr_width = slwr_w, \ + .slwf_bit = slwf_b, \ + .slwf_width = slwf_w, \ + } + +static const struct tegra_pingroup tegra30_groups[] = { + /* pg_name, f0, f1, f2, f3, safe, r, od, ior */ + /* FIXME: Fill in correct data in safe column */ + PINGROUP(clk_32k_out_pa0, BLINK, RSVD2, RSVD3, RSVD4, RSVD4, 0x331c, N, N), + PINGROUP(uart3_cts_n_pa1, UARTC, RSVD2, GMI, RSVD4, RSVD4, 0x317c, N, N), + PINGROUP(dap2_fs_pa2, I2S1, HDA, RSVD3, GMI, RSVD3, 0x3358, N, N), + PINGROUP(dap2_sclk_pa3, I2S1, HDA, RSVD3, GMI, RSVD3, 0x3364, N, N), + PINGROUP(dap2_din_pa4, I2S1, HDA, RSVD3, GMI, RSVD3, 0x335c, N, N), + PINGROUP(dap2_dout_pa5, I2S1, HDA, RSVD3, GMI, RSVD3, 0x3360, N, N), + PINGROUP(sdmmc3_clk_pa6, UARTA, PWM2, SDMMC3, SPI3, SPI3, 0x3390, N, N), + PINGROUP(sdmmc3_cmd_pa7, UARTA, PWM3, SDMMC3, SPI2, SPI2, 0x3394, N, N), + PINGROUP(gmi_a17_pb0, UARTD, SPI4, GMI, DTV, DTV, 0x3234, N, N), + PINGROUP(gmi_a18_pb1, UARTD, SPI4, GMI, DTV, DTV, 0x3238, N, N), + PINGROUP(lcd_pwr0_pb2, DISPLAYA, DISPLAYB, SPI5, HDCP, HDCP, 0x3090, N, N), + PINGROUP(lcd_pclk_pb3, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x3094, N, N), + PINGROUP(sdmmc3_dat3_pb4, RSVD1, PWM0, SDMMC3, SPI3, RSVD1, 0x33a4, N, N), + PINGROUP(sdmmc3_dat2_pb5, RSVD1, PWM1, SDMMC3, SPI3, RSVD1, 0x33a0, N, N), + PINGROUP(sdmmc3_dat1_pb6, RSVD1, RSVD2, SDMMC3, SPI3, RSVD2, 0x339c, N, N), + PINGROUP(sdmmc3_dat0_pb7, RSVD1, RSVD2, SDMMC3, SPI3, RSVD2, 0x3398, N, N), + PINGROUP(uart3_rts_n_pc0, UARTC, PWM0, GMI, RSVD4, RSVD4, 0x3180, N, N), + PINGROUP(lcd_pwr1_pc1, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x3070, N, N), + PINGROUP(uart2_txd_pc2, UARTB, SPDIF, UARTA, SPI4, SPI4, 0x3168, N, N), + PINGROUP(uart2_rxd_pc3, UARTB, SPDIF, UARTA, SPI4, SPI4, 0x3164, N, N), + PINGROUP(gen1_i2c_scl_pc4, I2C1, RSVD2, RSVD3, RSVD4, RSVD4, 0x31a4, Y, N), + PINGROUP(gen1_i2c_sda_pc5, I2C1, RSVD2, RSVD3, RSVD4, RSVD4, 0x31a0, Y, N), + PINGROUP(lcd_pwr2_pc6, DISPLAYA, DISPLAYB, SPI5, HDCP, HDCP, 0x3074, N, N), + PINGROUP(gmi_wp_n_pc7, RSVD1, NAND, GMI, GMI_ALT, RSVD1, 0x31c0, N, N), + PINGROUP(sdmmc3_dat5_pd0, PWM0, SPI4, SDMMC3, SPI2, SPI2, 0x33ac, N, N), + PINGROUP(sdmmc3_dat4_pd1, PWM1, SPI4, SDMMC3, SPI2, SPI2, 0x33a8, N, N), + PINGROUP(lcd_dc1_pd2, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x310c, N, N), + PINGROUP(sdmmc3_dat6_pd3, SPDIF, SPI4, SDMMC3, SPI2, SPI2, 0x33b0, N, N), + PINGROUP(sdmmc3_dat7_pd4, SPDIF, SPI4, SDMMC3, SPI2, SPI2, 0x33b4, N, N), + PINGROUP(vi_d1_pd5, DDR, SDMMC2, VI, RSVD4, RSVD4, 0x3128, N, Y), + PINGROUP(vi_vsync_pd6, DDR, RSVD2, VI, RSVD4, RSVD4, 0x315c, N, Y), + PINGROUP(vi_hsync_pd7, DDR, RSVD2, VI, RSVD4, RSVD4, 0x3160, N, Y), + PINGROUP(lcd_d0_pe0, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30a4, N, N), + PINGROUP(lcd_d1_pe1, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30a8, N, N), + PINGROUP(lcd_d2_pe2, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30ac, N, N), + PINGROUP(lcd_d3_pe3, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30b0, N, N), + PINGROUP(lcd_d4_pe4, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30b4, N, N), + PINGROUP(lcd_d5_pe5, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30b8, N, N), + PINGROUP(lcd_d6_pe6, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30bc, N, N), + PINGROUP(lcd_d7_pe7, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30c0, N, N), + PINGROUP(lcd_d8_pf0, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30c4, N, N), + PINGROUP(lcd_d9_pf1, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30c8, N, N), + PINGROUP(lcd_d10_pf2, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30cc, N, N), + PINGROUP(lcd_d11_pf3, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30d0, N, N), + PINGROUP(lcd_d12_pf4, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30d4, N, N), + PINGROUP(lcd_d13_pf5, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30d8, N, N), + PINGROUP(lcd_d14_pf6, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30dc, N, N), + PINGROUP(lcd_d15_pf7, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30e0, N, N), + PINGROUP(gmi_ad0_pg0, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x31f0, N, N), + PINGROUP(gmi_ad1_pg1, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x31f4, N, N), + PINGROUP(gmi_ad2_pg2, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x31f8, N, N), + PINGROUP(gmi_ad3_pg3, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x31fc, N, N), + PINGROUP(gmi_ad4_pg4, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x3200, N, N), + PINGROUP(gmi_ad5_pg5, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x3204, N, N), + PINGROUP(gmi_ad6_pg6, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x3208, N, N), + PINGROUP(gmi_ad7_pg7, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x320c, N, N), + PINGROUP(gmi_ad8_ph0, PWM0, NAND, GMI, RSVD4, RSVD4, 0x3210, N, N), + PINGROUP(gmi_ad9_ph1, PWM1, NAND, GMI, RSVD4, RSVD4, 0x3214, N, N), + PINGROUP(gmi_ad10_ph2, PWM2, NAND, GMI, RSVD4, RSVD4, 0x3218, N, N), + PINGROUP(gmi_ad11_ph3, PWM3, NAND, GMI, RSVD4, RSVD4, 0x321c, N, N), + PINGROUP(gmi_ad12_ph4, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x3220, N, N), + PINGROUP(gmi_ad13_ph5, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x3224, N, N), + PINGROUP(gmi_ad14_ph6, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x3228, N, N), + PINGROUP(gmi_ad15_ph7, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x322c, N, N), + PINGROUP(gmi_wr_n_pi0, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x3240, N, N), + PINGROUP(gmi_oe_n_pi1, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x3244, N, N), + PINGROUP(gmi_dqs_pi2, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x3248, N, N), + PINGROUP(gmi_cs6_n_pi3, NAND, NAND_ALT, GMI, SATA, SATA, 0x31e8, N, N), + PINGROUP(gmi_rst_n_pi4, NAND, NAND_ALT, GMI, RSVD4, RSVD4, 0x324c, N, N), + PINGROUP(gmi_iordy_pi5, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x31c4, N, N), + PINGROUP(gmi_cs7_n_pi6, NAND, NAND_ALT, GMI, GMI_ALT, GMI_ALT, 0x31ec, N, N), + PINGROUP(gmi_wait_pi7, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x31c8, N, N), + PINGROUP(gmi_cs0_n_pj0, RSVD1, NAND, GMI, DTV, RSVD1, 0x31d4, N, N), + PINGROUP(lcd_de_pj1, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x3098, N, N), + PINGROUP(gmi_cs1_n_pj2, RSVD1, NAND, GMI, DTV, RSVD1, 0x31d8, N, N), + PINGROUP(lcd_hsync_pj3, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x309c, N, N), + PINGROUP(lcd_vsync_pj4, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30a0, N, N), + PINGROUP(uart2_cts_n_pj5, UARTA, UARTB, GMI, SPI4, SPI4, 0x3170, N, N), + PINGROUP(uart2_rts_n_pj6, UARTA, UARTB, GMI, SPI4, SPI4, 0x316c, N, N), + PINGROUP(gmi_a16_pj7, UARTD, SPI4, GMI, GMI_ALT, GMI_ALT, 0x3230, N, N), + PINGROUP(gmi_adv_n_pk0, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x31cc, N, N), + PINGROUP(gmi_clk_pk1, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x31d0, N, N), + PINGROUP(gmi_cs4_n_pk2, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x31e4, N, N), + PINGROUP(gmi_cs2_n_pk3, RSVD1, NAND, GMI, RSVD4, RSVD4, 0x31dc, N, N), + PINGROUP(gmi_cs3_n_pk4, RSVD1, NAND, GMI, GMI_ALT, RSVD1, 0x31e0, N, N), + PINGROUP(spdif_out_pk5, SPDIF, RSVD2, I2C1, SDMMC2, RSVD2, 0x3354, N, N), + PINGROUP(spdif_in_pk6, SPDIF, HDA, I2C1, SDMMC2, SDMMC2, 0x3350, N, N), + PINGROUP(gmi_a19_pk7, UARTD, SPI4, GMI, RSVD4, RSVD4, 0x323c, N, N), + PINGROUP(vi_d2_pl0, DDR, SDMMC2, VI, RSVD4, RSVD4, 0x312c, N, Y), + PINGROUP(vi_d3_pl1, DDR, SDMMC2, VI, RSVD4, RSVD4, 0x3130, N, Y), + PINGROUP(vi_d4_pl2, DDR, SDMMC2, VI, RSVD4, RSVD4, 0x3134, N, Y), + PINGROUP(vi_d5_pl3, DDR, SDMMC2, VI, RSVD4, RSVD4, 0x3138, N, Y), + PINGROUP(vi_d6_pl4, DDR, SDMMC2, VI, RSVD4, RSVD4, 0x313c, N, Y), + PINGROUP(vi_d7_pl5, DDR, SDMMC2, VI, RSVD4, RSVD4, 0x3140, N, Y), + PINGROUP(vi_d8_pl6, DDR, SDMMC2, VI, RSVD4, RSVD4, 0x3144, N, Y), + PINGROUP(vi_d9_pl7, DDR, SDMMC2, VI, RSVD4, RSVD4, 0x3148, N, Y), + PINGROUP(lcd_d16_pm0, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30e4, N, N), + PINGROUP(lcd_d17_pm1, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30e8, N, N), + PINGROUP(lcd_d18_pm2, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30ec, N, N), + PINGROUP(lcd_d19_pm3, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30f0, N, N), + PINGROUP(lcd_d20_pm4, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30f4, N, N), + PINGROUP(lcd_d21_pm5, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30f8, N, N), + PINGROUP(lcd_d22_pm6, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x30fc, N, N), + PINGROUP(lcd_d23_pm7, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x3100, N, N), + PINGROUP(dap1_fs_pn0, I2S0, HDA, GMI, SDMMC2, SDMMC2, 0x3338, N, N), + PINGROUP(dap1_din_pn1, I2S0, HDA, GMI, SDMMC2, SDMMC2, 0x333c, N, N), + PINGROUP(dap1_dout_pn2, I2S0, HDA, GMI, SDMMC2, SDMMC2, 0x3340, N, N), + PINGROUP(dap1_sclk_pn3, I2S0, HDA, GMI, SDMMC2, SDMMC2, 0x3344, N, N), + PINGROUP(lcd_cs0_n_pn4, DISPLAYA, DISPLAYB, SPI5, RSVD4, RSVD4, 0x3084, N, N), + PINGROUP(lcd_sdout_pn5, DISPLAYA, DISPLAYB, SPI5, HDCP, HDCP, 0x307c, N, N), + PINGROUP(lcd_dc0_pn6, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x3088, N, N), + PINGROUP(hdmi_int_pn7, HDMI, RSVD2, RSVD3, RSVD4, RSVD4, 0x3110, N, N), + PINGROUP(ulpi_data7_po0, SPI2, HSI, UARTA, ULPI, ULPI, 0x301c, N, N), + PINGROUP(ulpi_data0_po1, SPI3, HSI, UARTA, ULPI, ULPI, 0x3000, N, N), + PINGROUP(ulpi_data1_po2, SPI3, HSI, UARTA, ULPI, ULPI, 0x3004, N, N), + PINGROUP(ulpi_data2_po3, SPI3, HSI, UARTA, ULPI, ULPI, 0x3008, N, N), + PINGROUP(ulpi_data3_po4, SPI3, HSI, UARTA, ULPI, ULPI, 0x300c, N, N), + PINGROUP(ulpi_data4_po5, SPI2, HSI, UARTA, ULPI, ULPI, 0x3010, N, N), + PINGROUP(ulpi_data5_po6, SPI2, HSI, UARTA, ULPI, ULPI, 0x3014, N, N), + PINGROUP(ulpi_data6_po7, SPI2, HSI, UARTA, ULPI, ULPI, 0x3018, N, N), + PINGROUP(dap3_fs_pp0, I2S2, RSVD2, DISPLAYA, DISPLAYB, RSVD2, 0x3030, N, N), + PINGROUP(dap3_din_pp1, I2S2, RSVD2, DISPLAYA, DISPLAYB, RSVD2, 0x3034, N, N), + PINGROUP(dap3_dout_pp2, I2S2, RSVD2, DISPLAYA, DISPLAYB, RSVD2, 0x3038, N, N), + PINGROUP(dap3_sclk_pp3, I2S2, RSVD2, DISPLAYA, DISPLAYB, RSVD2, 0x303c, N, N), + PINGROUP(dap4_fs_pp4, I2S3, RSVD2, GMI, RSVD4, RSVD4, 0x31a8, N, N), + PINGROUP(dap4_din_pp5, I2S3, RSVD2, GMI, RSVD4, RSVD4, 0x31ac, N, N), + PINGROUP(dap4_dout_pp6, I2S3, RSVD2, GMI, RSVD4, RSVD4, 0x31b0, N, N), + PINGROUP(dap4_sclk_pp7, I2S3, RSVD2, GMI, RSVD4, RSVD4, 0x31b4, N, N), + PINGROUP(kb_col0_pq0, KBC, NAND, TRACE, TEST, TEST, 0x32fc, N, N), + PINGROUP(kb_col1_pq1, KBC, NAND, TRACE, TEST, TEST, 0x3300, N, N), + PINGROUP(kb_col2_pq2, KBC, NAND, TRACE, RSVD4, RSVD4, 0x3304, N, N), + PINGROUP(kb_col3_pq3, KBC, NAND, TRACE, RSVD4, RSVD4, 0x3308, N, N), + PINGROUP(kb_col4_pq4, KBC, NAND, TRACE, RSVD4, RSVD4, 0x330c, N, N), + PINGROUP(kb_col5_pq5, KBC, NAND, TRACE, RSVD4, RSVD4, 0x3310, N, N), + PINGROUP(kb_col6_pq6, KBC, NAND, TRACE, MIO, MIO, 0x3314, N, N), + PINGROUP(kb_col7_pq7, KBC, NAND, TRACE, MIO, MIO, 0x3318, N, N), + PINGROUP(kb_row0_pr0, KBC, NAND, RSVD3, RSVD4, RSVD4, 0x32bc, N, N), + PINGROUP(kb_row1_pr1, KBC, NAND, RSVD3, RSVD4, RSVD4, 0x32c0, N, N), + PINGROUP(kb_row2_pr2, KBC, NAND, RSVD3, RSVD4, RSVD4, 0x32c4, N, N), + PINGROUP(kb_row3_pr3, KBC, NAND, RSVD3, INVALID, RSVD3, 0x32c8, N, N), + PINGROUP(kb_row4_pr4, KBC, NAND, TRACE, RSVD4, RSVD4, 0x32cc, N, N), + PINGROUP(kb_row5_pr5, KBC, NAND, TRACE, OWR, OWR, 0x32d0, N, N), + PINGROUP(kb_row6_pr6, KBC, NAND, SDMMC2, MIO, MIO, 0x32d4, N, N), + PINGROUP(kb_row7_pr7, KBC, NAND, SDMMC2, MIO, MIO, 0x32d8, N, N), + PINGROUP(kb_row8_ps0, KBC, NAND, SDMMC2, MIO, MIO, 0x32dc, N, N), + PINGROUP(kb_row9_ps1, KBC, NAND, SDMMC2, MIO, MIO, 0x32e0, N, N), + PINGROUP(kb_row10_ps2, KBC, NAND, SDMMC2, MIO, MIO, 0x32e4, N, N), + PINGROUP(kb_row11_ps3, KBC, NAND, SDMMC2, MIO, MIO, 0x32e8, N, N), + PINGROUP(kb_row12_ps4, KBC, NAND, SDMMC2, MIO, MIO, 0x32ec, N, N), + PINGROUP(kb_row13_ps5, KBC, NAND, SDMMC2, MIO, MIO, 0x32f0, N, N), + PINGROUP(kb_row14_ps6, KBC, NAND, SDMMC2, MIO, MIO, 0x32f4, N, N), + PINGROUP(kb_row15_ps7, KBC, NAND, SDMMC2, MIO, MIO, 0x32f8, N, N), + PINGROUP(vi_pclk_pt0, RSVD1, SDMMC2, VI, RSVD4, RSVD4, 0x3154, N, Y), + PINGROUP(vi_mclk_pt1, VI, VI_ALT1, VI_ALT2, VI_ALT3, VI_ALT3, 0x3158, N, Y), + PINGROUP(vi_d10_pt2, DDR, RSVD2, VI, RSVD4, RSVD4, 0x314c, N, Y), + PINGROUP(vi_d11_pt3, DDR, RSVD2, VI, RSVD4, RSVD4, 0x3150, N, Y), + PINGROUP(vi_d0_pt4, DDR, RSVD2, VI, RSVD4, RSVD4, 0x3124, N, Y), + PINGROUP(gen2_i2c_scl_pt5, I2C2, HDCP, GMI, RSVD4, RSVD4, 0x3250, Y, N), + PINGROUP(gen2_i2c_sda_pt6, I2C2, HDCP, GMI, RSVD4, RSVD4, 0x3254, Y, N), + PINGROUP(sdmmc4_cmd_pt7, I2C3, NAND, GMI, SDMMC4, SDMMC4, 0x325c, N, Y), + PINGROUP(pu0, OWR, UARTA, GMI, RSVD4, RSVD4, 0x3184, N, N), + PINGROUP(pu1, RSVD1, UARTA, GMI, RSVD4, RSVD4, 0x3188, N, N), + PINGROUP(pu2, RSVD1, UARTA, GMI, RSVD4, RSVD4, 0x318c, N, N), + PINGROUP(pu3, PWM0, UARTA, GMI, RSVD4, RSVD4, 0x3190, N, N), + PINGROUP(pu4, PWM1, UARTA, GMI, RSVD4, RSVD4, 0x3194, N, N), + PINGROUP(pu5, PWM2, UARTA, GMI, RSVD4, RSVD4, 0x3198, N, N), + PINGROUP(pu6, PWM3, UARTA, GMI, RSVD4, RSVD4, 0x319c, N, N), + PINGROUP(jtag_rtck_pu7, RTCK, RSVD2, RSVD3, RSVD4, RSVD4, 0x32b0, N, N), + PINGROUP(pv0, RSVD1, RSVD2, RSVD3, RSVD4, RSVD4, 0x3040, N, N), + PINGROUP(pv1, RSVD1, RSVD2, RSVD3, RSVD4, RSVD4, 0x3044, N, N), + PINGROUP(pv2, OWR, RSVD2, RSVD3, RSVD4, RSVD4, 0x3060, N, N), + PINGROUP(pv3, CLK_12M_OUT, RSVD2, RSVD3, RSVD4, RSVD4, 0x3064, N, N), + PINGROUP(ddc_scl_pv4, I2C4, RSVD2, RSVD3, RSVD4, RSVD4, 0x3114, N, N), + PINGROUP(ddc_sda_pv5, I2C4, RSVD2, RSVD3, RSVD4, RSVD4, 0x3118, N, N), + PINGROUP(crt_hsync_pv6, CRT, RSVD2, RSVD3, RSVD4, RSVD4, 0x311c, N, N), + PINGROUP(crt_vsync_pv7, CRT, RSVD2, RSVD3, RSVD4, RSVD4, 0x3120, N, N), + PINGROUP(lcd_cs1_n_pw0, DISPLAYA, DISPLAYB, SPI5, RSVD4, RSVD4, 0x3104, N, N), + PINGROUP(lcd_m1_pw1, DISPLAYA, DISPLAYB, RSVD3, RSVD4, RSVD4, 0x3108, N, N), + PINGROUP(spi2_cs1_n_pw2, SPI3, SPI2, SPI2_ALT, I2C1, I2C1, 0x3388, N, N), + PINGROUP(spi2_cs2_n_pw3, SPI3, SPI2, SPI2_ALT, I2C1, I2C1, 0x338c, N, N), + PINGROUP(clk1_out_pw4, EXTPERIPH1, RSVD2, RSVD3, RSVD4, RSVD4, 0x334c, N, N), + PINGROUP(clk2_out_pw5, EXTPERIPH2, RSVD2, RSVD3, RSVD4, RSVD4, 0x3068, N, N), + PINGROUP(uart3_txd_pw6, UARTC, RSVD2, GMI, RSVD4, RSVD4, 0x3174, N, N), + PINGROUP(uart3_rxd_pw7, UARTC, RSVD2, GMI, RSVD4, RSVD4, 0x3178, N, N), + PINGROUP(spi2_mosi_px0, SPI6, SPI2, SPI3, GMI, GMI, 0x3368, N, N), + PINGROUP(spi2_miso_px1, SPI6, SPI2, SPI3, GMI, GMI, 0x336c, N, N), + PINGROUP(spi2_sck_px2, SPI6, SPI2, SPI3, GMI, GMI, 0x3374, N, N), + PINGROUP(spi2_cs0_n_px3, SPI6, SPI2, SPI3, GMI, GMI, 0x3370, N, N), + PINGROUP(spi1_mosi_px4, SPI2, SPI1, SPI2_ALT, GMI, GMI, 0x3378, N, N), + PINGROUP(spi1_sck_px5, SPI2, SPI1, SPI2_ALT, GMI, GMI, 0x337c, N, N), + PINGROUP(spi1_cs0_n_px6, SPI2, SPI1, SPI2_ALT, GMI, GMI, 0x3380, N, N), + PINGROUP(spi1_miso_px7, SPI3, SPI1, SPI2_ALT, RSVD4, RSVD4, 0x3384, N, N), + PINGROUP(ulpi_clk_py0, SPI1, RSVD2, UARTD, ULPI, RSVD2, 0x3020, N, N), + PINGROUP(ulpi_dir_py1, SPI1, RSVD2, UARTD, ULPI, RSVD2, 0x3024, N, N), + PINGROUP(ulpi_nxt_py2, SPI1, RSVD2, UARTD, ULPI, RSVD2, 0x3028, N, N), + PINGROUP(ulpi_stp_py3, SPI1, RSVD2, UARTD, ULPI, RSVD2, 0x302c, N, N), + PINGROUP(sdmmc1_dat3_py4, SDMMC1, RSVD2, UARTE, UARTA, RSVD2, 0x3050, N, N), + PINGROUP(sdmmc1_dat2_py5, SDMMC1, RSVD2, UARTE, UARTA, RSVD2, 0x3054, N, N), + PINGROUP(sdmmc1_dat1_py6, SDMMC1, RSVD2, UARTE, UARTA, RSVD2, 0x3058, N, N), + PINGROUP(sdmmc1_dat0_py7, SDMMC1, RSVD2, UARTE, UARTA, RSVD2, 0x305c, N, N), + PINGROUP(sdmmc1_clk_pz0, SDMMC1, RSVD2, RSVD3, UARTA, RSVD3, 0x3048, N, N), + PINGROUP(sdmmc1_cmd_pz1, SDMMC1, RSVD2, RSVD3, UARTA, RSVD3, 0x304c, N, N), + PINGROUP(lcd_sdin_pz2, DISPLAYA, DISPLAYB, SPI5, RSVD4, RSVD4, 0x3078, N, N), + PINGROUP(lcd_wr_n_pz3, DISPLAYA, DISPLAYB, SPI5, HDCP, HDCP, 0x3080, N, N), + PINGROUP(lcd_sck_pz4, DISPLAYA, DISPLAYB, SPI5, HDCP, HDCP, 0x308c, N, N), + PINGROUP(sys_clk_req_pz5, SYSCLK, RSVD2, RSVD3, RSVD4, RSVD4, 0x3320, N, N), + PINGROUP(pwr_i2c_scl_pz6, I2CPWR, RSVD2, RSVD3, RSVD4, RSVD4, 0x32b4, Y, N), + PINGROUP(pwr_i2c_sda_pz7, I2CPWR, RSVD2, RSVD3, RSVD4, RSVD4, 0x32b8, Y, N), + PINGROUP(sdmmc4_dat0_paa0, UARTE, SPI3, GMI, SDMMC4, SDMMC4, 0x3260, N, Y), + PINGROUP(sdmmc4_dat1_paa1, UARTE, SPI3, GMI, SDMMC4, SDMMC4, 0x3264, N, Y), + PINGROUP(sdmmc4_dat2_paa2, UARTE, SPI3, GMI, SDMMC4, SDMMC4, 0x3268, N, Y), + PINGROUP(sdmmc4_dat3_paa3, UARTE, SPI3, GMI, SDMMC4, SDMMC4, 0x326c, N, Y), + PINGROUP(sdmmc4_dat4_paa4, I2C3, I2S4, GMI, SDMMC4, SDMMC4, 0x3270, N, Y), + PINGROUP(sdmmc4_dat5_paa5, VGP3, I2S4, GMI, SDMMC4, SDMMC4, 0x3274, N, Y), + PINGROUP(sdmmc4_dat6_paa6, VGP4, I2S4, GMI, SDMMC4, SDMMC4, 0x3278, N, Y), + PINGROUP(sdmmc4_dat7_paa7, VGP5, I2S4, GMI, SDMMC4, SDMMC4, 0x327c, N, Y), + PINGROUP(pbb0, I2S4, RSVD2, RSVD3, SDMMC4, RSVD3, 0x328c, N, N), + PINGROUP(cam_i2c_scl_pbb1, VGP1, I2C3, RSVD3, SDMMC4, RSVD3, 0x3290, Y, N), + PINGROUP(cam_i2c_sda_pbb2, VGP2, I2C3, RSVD3, SDMMC4, RSVD3, 0x3294, Y, N), + PINGROUP(pbb3, VGP3, DISPLAYA, DISPLAYB, SDMMC4, SDMMC4, 0x3298, N, N), + PINGROUP(pbb4, VGP4, DISPLAYA, DISPLAYB, SDMMC4, SDMMC4, 0x329c, N, N), + PINGROUP(pbb5, VGP5, DISPLAYA, DISPLAYB, SDMMC4, SDMMC4, 0x32a0, N, N), + PINGROUP(pbb6, VGP6, DISPLAYA, DISPLAYB, SDMMC4, SDMMC4, 0x32a4, N, N), + PINGROUP(pbb7, I2S4, RSVD2, RSVD3, SDMMC4, RSVD3, 0x32a8, N, N), + PINGROUP(cam_mclk_pcc0, VI, VI_ALT1, VI_ALT3, SDMMC4, SDMMC4, 0x3284, N, N), + PINGROUP(pcc1, I2S4, RSVD2, RSVD3, SDMMC4, RSVD3, 0x3288, N, N), + PINGROUP(pcc2, I2S4, RSVD2, RSVD3, RSVD4, RSVD4, 0x32ac, N, N), + PINGROUP(sdmmc4_rst_n_pcc3, VGP6, RSVD2, RSVD3, SDMMC4, RSVD3, 0x3280, N, Y), + PINGROUP(sdmmc4_clk_pcc4, INVALID, NAND, GMI, SDMMC4, SDMMC4, 0x3258, N, Y), + PINGROUP(clk2_req_pcc5, DAP, RSVD2, RSVD3, RSVD4, RSVD4, 0x306c, N, N), + PINGROUP(pex_l2_rst_n_pcc6, PCIE, HDA, RSVD3, RSVD4, RSVD4, 0x33d8, N, N), + PINGROUP(pex_l2_clkreq_n_pcc7, PCIE, HDA, RSVD3, RSVD4, RSVD4, 0x33dc, N, N), + PINGROUP(pex_l0_prsnt_n_pdd0, PCIE, HDA, RSVD3, RSVD4, RSVD4, 0x33b8, N, N), + PINGROUP(pex_l0_rst_n_pdd1, PCIE, HDA, RSVD3, RSVD4, RSVD4, 0x33bc, N, N), + PINGROUP(pex_l0_clkreq_n_pdd2, PCIE, HDA, RSVD3, RSVD4, RSVD4, 0x33c0, N, N), + PINGROUP(pex_wake_n_pdd3, PCIE, HDA, RSVD3, RSVD4, RSVD4, 0x33c4, N, N), + PINGROUP(pex_l1_prsnt_n_pdd4, PCIE, HDA, RSVD3, RSVD4, RSVD4, 0x33c8, N, N), + PINGROUP(pex_l1_rst_n_pdd5, PCIE, HDA, RSVD3, RSVD4, RSVD4, 0x33cc, N, N), + PINGROUP(pex_l1_clkreq_n_pdd6, PCIE, HDA, RSVD3, RSVD4, RSVD4, 0x33d0, N, N), + PINGROUP(pex_l2_prsnt_n_pdd7, PCIE, HDA, RSVD3, RSVD4, RSVD4, 0x33d4, N, N), + PINGROUP(clk3_out_pee0, EXTPERIPH3, RSVD2, RSVD3, RSVD4, RSVD4, 0x31b8, N, N), + PINGROUP(clk3_req_pee1, DEV3, RSVD2, RSVD3, RSVD4, RSVD4, 0x31bc, N, N), + PINGROUP(clk1_req_pee2, DAP, HDA, RSVD3, RSVD4, RSVD4, 0x3348, N, N), + PINGROUP(hdmi_cec_pee3, CEC, RSVD2, RSVD3, RSVD4, RSVD4, 0x33e0, Y, N), + PINGROUP(clk_32k_in, CLK_32K_IN, RSVD2, RSVD3, RSVD4, RSVD4, 0x3330, N, N), + PINGROUP(core_pwr_req, CORE_PWR_REQ, RSVD2, RSVD3, RSVD4, RSVD4, 0x3324, N, N), + PINGROUP(cpu_pwr_req, CPU_PWR_REQ, RSVD2, RSVD3, RSVD4, RSVD4, 0x3328, N, N), + PINGROUP(owr, OWR, CEC, RSVD3, RSVD4, RSVD4, 0x3334, N, N), + PINGROUP(pwr_int_n, PWR_INT_N, RSVD2, RSVD3, RSVD4, RSVD4, 0x332c, N, N), + /* pg_name, r, hsm_b, schmitt_b, lpmd_b, drvdn_b, drvdn_w, drvup_b, drvup_w, slwr_b, slwr_w, slwf_b, slwf_w */ + DRV_PINGROUP(ao1, 0x868, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(ao2, 0x86c, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(at1, 0x870, 2, 3, 4, 14, 5, 19, 5, 24, 2, 28, 2), + DRV_PINGROUP(at2, 0x874, 2, 3, 4, 14, 5, 19, 5, 24, 2, 28, 2), + DRV_PINGROUP(at3, 0x878, 2, 3, 4, 14, 5, 19, 5, 28, 2, 30, 2), + DRV_PINGROUP(at4, 0x87c, 2, 3, 4, 14, 5, 19, 5, 28, 2, 30, 2), + DRV_PINGROUP(at5, 0x880, 2, 3, 4, 14, 5, 19, 5, 28, 2, 30, 2), + DRV_PINGROUP(cdev1, 0x884, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(cdev2, 0x888, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(cec, 0x938, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(crt, 0x8f8, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(csus, 0x88c, -1, -1, -1, 12, 5, 19, 5, 24, 4, 28, 4), + DRV_PINGROUP(dap1, 0x890, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(dap2, 0x894, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(dap3, 0x898, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(dap4, 0x89c, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(dbg, 0x8a0, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(ddc, 0x8fc, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(dev3, 0x92c, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(gma, 0x900, -1, -1, -1, 14, 5, 19, 5, 24, 4, 28, 4), + DRV_PINGROUP(gmb, 0x904, -1, -1, -1, 14, 5, 19, 5, 24, 4, 28, 4), + DRV_PINGROUP(gmc, 0x908, -1, -1, -1, 14, 5, 19, 5, 24, 4, 28, 4), + DRV_PINGROUP(gmd, 0x90c, -1, -1, -1, 14, 5, 19, 5, 24, 4, 28, 4), + DRV_PINGROUP(gme, 0x910, 2, 3, 4, 14, 5, 19, 5, 28, 2, 30, 2), + DRV_PINGROUP(gmf, 0x914, 2, 3, 4, 14, 5, 19, 5, 28, 2, 30, 2), + DRV_PINGROUP(gmg, 0x918, 2, 3, 4, 14, 5, 19, 5, 28, 2, 30, 2), + DRV_PINGROUP(gmh, 0x91c, 2, 3, 4, 14, 5, 19, 5, 28, 2, 30, 2), + DRV_PINGROUP(gpv, 0x928, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(lcd1, 0x8a4, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(lcd2, 0x8a8, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(owr, 0x920, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(sdio1, 0x8ec, 2, 3, -1, 12, 7, 20, 7, 28, 2, 30, 2), + DRV_PINGROUP(sdio2, 0x8ac, 2, 3, -1, 12, 7, 20, 7, 28, 2, 30, 2), + DRV_PINGROUP(sdio3, 0x8b0, 2, 3, -1, 12, 7, 20, 7, 28, 2, 30, 2), + DRV_PINGROUP(spi, 0x8b4, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(uaa, 0x8b8, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(uab, 0x8bc, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(uart2, 0x8c0, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(uart3, 0x8c4, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(uda, 0x924, 2, 3, 4, 12, 5, 20, 5, 28, 2, 30, 2), + DRV_PINGROUP(vi1, 0x8c8, -1, -1, -1, 14, 5, 19, 5, 24, 4, 28, 4), +}; + +static const struct tegra_pinctrl_soc_data tegra30_pinctrl = { + .ngpios = NUM_GPIOS, + .pins = tegra30_pins, + .npins = ARRAY_SIZE(tegra30_pins), + .functions = tegra30_functions, + .nfunctions = ARRAY_SIZE(tegra30_functions), + .groups = tegra30_groups, + .ngroups = ARRAY_SIZE(tegra30_groups), +}; + +void __devinit tegra30_pinctrl_init(const struct tegra_pinctrl_soc_data **soc) +{ + *soc = &tegra30_pinctrl; +} -- cgit v0.10.2 From f1f1ffa0d2fd562b610940c7374b8217597af47f Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Wed, 1 Feb 2012 14:04:48 -0700 Subject: ARM: tegra: Select PINCTRL Kconfig variables This causes the Tegra pinctrl driver to be built whenever core Tegra support is enabled. Signed-off-by: Stephen Warren Acked-by: Linus Walleij Acked-by: Olof Johansson Signed-off-by: Linus Walleij diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig index 373652d..32b420a 100644 --- a/arch/arm/mach-tegra/Kconfig +++ b/arch/arm/mach-tegra/Kconfig @@ -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 -- cgit v0.10.2 From 872acc322c74bb06b7ceb61fe93314e2da32362c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 6 Mar 2012 13:52:22 +0100 Subject: pinctrl: include machine header to core.h struct pinctrl_setting contains an enum pinctrl_map_type field, so we need to include machine.h. Also fix kerneldoc to indicate that the pinctrl_setting is about both muxing and other config. Acked-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 5b3ff13..efbfb62 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -12,6 +12,7 @@ #include #include #include +#include struct pinctrl_gpio_range; @@ -96,7 +97,7 @@ struct pinctrl_setting_configs { }; /** - * struct pinctrl_setting - an individual mux setting + * 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 -- cgit v0.10.2 From 9a01be1715b6a027765701ca09ba0401ff066fc5 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 6 Mar 2012 21:15:51 +0100 Subject: pinctrl: split pincontrol states into its own header Move the pin control state defines into its own header file, since it is used both by machine.h which is facing the platform and by consumer.h which is facing the drivers, and pinctrl.h which is pinctrl-driver internal, let's not have each and every .h file include all others, then isolation is moot. Acked-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/include/linux/pinctrl/consumer.h b/include/linux/pinctrl/consumer.h index 9ad5896..191e726 100644 --- a/include/linux/pinctrl/consumer.h +++ b/include/linux/pinctrl/consumer.h @@ -15,7 +15,7 @@ #include #include #include -#include "pinctrl.h" +#include "pinctrl-state.h" /* This struct is private to the core and should be regarded as a cookie */ struct pinctrl; diff --git a/include/linux/pinctrl/machine.h b/include/linux/pinctrl/machine.h index 3fd2f9d..fee4349 100644 --- a/include/linux/pinctrl/machine.h +++ b/include/linux/pinctrl/machine.h @@ -12,7 +12,7 @@ #ifndef __LINUX_PINCTRL_MACHINE_H #define __LINUX_PINCTRL_MACHINE_H -#include "pinctrl.h" +#include "pinctrl-state.h" enum pinctrl_map_type { PIN_MAP_TYPE_INVALID, diff --git a/include/linux/pinctrl/pinctrl-state.h b/include/linux/pinctrl/pinctrl-state.h new file mode 100644 index 0000000..3920e28 --- /dev/null +++ b/include/linux/pinctrl/pinctrl-state.h @@ -0,0 +1,6 @@ +/* + * Standard pin control state definitions + */ + +#define PINCTRL_STATE_DEFAULT "default" +#define PINCTRL_STATE_IDLE "idle" diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index bbdd7e1..e9e94eb 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -17,8 +17,7 @@ #include #include #include - -#define PINCTRL_STATE_DEFAULT "default" +#include "pinctrl-state.h" struct pinctrl_dev; struct pinmux_ops; -- cgit v0.10.2 From 0acfb076f7987bd4bb5cd5de879ba3e3e71724e9 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Tue, 6 Mar 2012 12:12:12 -0700 Subject: pinctrl: forward-declare struct device Add a dummy declaration of struct device to avoid the following warning: In file included from include/linux/pinctrl/machine.h:15:0, from arch/arm/mach-tegra/board-pinmux.h:18, from arch/arm/mach-tegra/board-trimslice-pinmux.c:20: include/linux/pinctrl/pinctrl.h:115:12: warning: 'struct device' declared inside parameter list [enabled by default] include/linux/pinctrl/pinctrl.h:115:12: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default] Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/include/linux/pinctrl/pinctrl.h b/include/linux/pinctrl/pinctrl.h index e9e94eb..4e9f078 100644 --- a/include/linux/pinctrl/pinctrl.h +++ b/include/linux/pinctrl/pinctrl.h @@ -19,6 +19,7 @@ #include #include "pinctrl-state.h" +struct device; struct pinctrl_dev; struct pinmux_ops; struct pinconf_ops; -- cgit v0.10.2 From 652162d469a73450a66b6c8049b16c2b7828fa24 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Mon, 5 Mar 2012 17:22:15 -0700 Subject: pinctrl: allow concurrent gpio and mux function ownership of pins Per recent updates to Documentation/gpio.txt, gpiolib drivers should inform pinctrl when a GPIO is requested. pinctrl then marks that pin as in-use for that GPIO function. When an SoC muxes pins in a group, it's quite possible for the group to contain e.g. 6 pins, but only 4 of them actually be needed by the HW module that's mux'd to them. In this case, the other 2 pins could be used as GPIOs. However, pinctrl marks all the pins within the group as in-use by the selected mux function. To allow the expected gpiolib interaction, separate the concepts of pin ownership into two parts: One for the mux function and one for GPIO usage. Finally, allow those two ownerships to exist in parallel. Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index efbfb62..17ecf65 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -119,15 +119,15 @@ struct pinctrl_setting { * @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 - * @usecount: If zero, the pin is not claimed, and @owner should be NULL. + * @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. - * @owner: The name of the entity owning the pin. Typically, this is the name - * of the device that called pinctrl_get(). Alternatively, it may be the - * name of the GPIO passed to pinctrl_request_gpio(). + * @mux_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; @@ -135,9 +135,10 @@ struct pin_desc { bool dynamic_name; /* These fields only added when supporting pinmux drivers */ #ifdef CONFIG_PINMUX - unsigned usecount; - const char *owner; + unsigned mux_usecount; + const char *mux_owner; const struct pinctrl_setting_mux *mux_setting; + const char *gpio_owner; #endif }; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 86e4017..4e62783 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -94,17 +94,28 @@ static int pin_request(struct pinctrl_dev *pctldev, goto out; } - if (desc->usecount && strcmp(desc->owner, owner)) { - dev_err(pctldev->dev, - "pin already requested\n"); - goto out; - } + if (gpio_range) { + /* There's no need to support multiple GPIO requests */ + if (desc->gpio_owner) { + dev_err(pctldev->dev, + "pin already requested\n"); + goto out; + } - desc->usecount++; - if (desc->usecount > 1) - return 0; + desc->gpio_owner = owner; + } else { + if (desc->mux_usecount && strcmp(desc->mux_owner, owner)) { + dev_err(pctldev->dev, + "pin already requested\n"); + goto out; + } - desc->owner = owner; + desc->mux_usecount++; + if (desc->mux_usecount > 1) + return 0; + + desc->mux_owner = owner; + } /* Let each pin increase references to this module */ if (!try_module_get(pctldev->owner)) { @@ -135,9 +146,13 @@ static int pin_request(struct pinctrl_dev *pctldev, out_free_pin: if (status) { - desc->usecount--; - if (!desc->usecount) - desc->owner = NULL; + if (gpio_range) { + desc->gpio_owner = NULL; + } else { + desc->mux_usecount--; + if (!desc->mux_usecount) + desc->mux_owner = NULL; + } } out: if (status) @@ -172,9 +187,11 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, return NULL; } - desc->usecount--; - if (desc->usecount) - return NULL; + if (!gpio_range) { + desc->mux_usecount--; + if (desc->mux_usecount) + return NULL; + } /* * If there is no kind of request function for the pin we just assume @@ -185,9 +202,15 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, else if (ops->free) ops->free(pctldev, pin); - owner = desc->owner; - desc->owner = NULL; - desc->mux_setting = NULL; + if (gpio_range) { + owner = desc->gpio_owner; + desc->gpio_owner = NULL; + } else { + owner = desc->mux_owner; + desc->mux_owner = NULL; + desc->mux_setting = NULL; + } + module_put(pctldev->owner); return owner; @@ -493,7 +516,7 @@ static int pinmux_pins_show(struct seq_file *s, void *what) unsigned i, pin; seq_puts(s, "Pinmux settings per pin\n"); - seq_puts(s, "Format: pin (name): owner\n"); + seq_puts(s, "Format: pin (name): mux_owner gpio_owner hog?\n"); mutex_lock(&pinctrl_mutex); @@ -508,13 +531,16 @@ static int pinmux_pins_show(struct seq_file *s, void *what) if (desc == NULL) continue; - if (desc->owner && - !strcmp(desc->owner, pinctrl_dev_get_name(pctldev))) + if (desc->mux_owner && + !strcmp(desc->mux_owner, pinctrl_dev_get_name(pctldev))) is_hog = true; - seq_printf(s, "pin %d (%s): %s%s", pin, + seq_printf(s, "pin %d (%s): %s %s%s", pin, desc->name ? desc->name : "unnamed", - desc->owner ? desc->owner : "UNCLAIMED", + desc->mux_owner ? desc->mux_owner + : "(MUX UNCLAIMED)", + desc->gpio_owner ? desc->gpio_owner + : "(GPIO UNCLAIMED)", is_hog ? " (HOG)" : ""); if (desc->mux_setting) -- cgit v0.10.2 From 70b36378d44d7f5e62458a830b1a9bb1c570f28a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 12 Mar 2012 21:38:29 +0100 Subject: pinctrl: fix error path in pinconf_map_to_setting() The code was using the union member setting->data.configs.group_or_pin to store a potential error code, but since that member is unsigned the < 0 comparison was not true, letting errors pass through, ending up as mapped to pin "-22". Fix this up and print the error. Acked-by: Stephen Warren Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 84869f2..b40ac1b 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -282,21 +282,28 @@ 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: - setting->data.configs.group_or_pin = - pin_get_from_name(pctldev, - map->data.configs.group_or_pin); - if (setting->data.configs.group_or_pin < 0) - return setting->data.configs.group_or_pin; + 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: - setting->data.configs.group_or_pin = - pinctrl_get_group_selector(pctldev, - map->data.configs.group_or_pin); - if (setting->data.configs.group_or_pin < 0) - return setting->data.configs.group_or_pin; + 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; -- cgit v0.10.2 From 394349f7789fdfcdc74b61afcac84046535c40b7 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 24 Nov 2011 18:27:15 +0100 Subject: pinctrl: introduce generic pin config This is a split-off from the earlier patch set which adds generic pin configuration for the pin controllers that want it. Since we may have a system with mixed generic and custom pin controllers, we pass a boolean in the pin controller ops vtable to indicate if it is generic. ChangeLog v1->v5: - Follow parent patch versioning number system. - Document the semantic meaning of return values from pin config get functions, so we can iterate over pins and check their properties from debugfs as part of the generic config code. - Use proper cast functions in the generic debugfs pin config file. - Expand generic config to optionally cover groups too. ChangeLog v5->v6: - Update to match underlying changes. ChangeLog v6->v7: - Drop DRIVE_OFF parameter, use bias high impedance for this - Delete argument for drive modes push-pull, od and os. These are now just state transitions. - Delete slew rate rising/falling due to discussions on on proper semantics - Drop config wakeup, struct irq_chip does this for now, add back if need be. - Set PIN_CONFIG_END to 0x7fff making room for custom config parameters from 0x8000 and up. - Prefix accessor functions with pinconf_ diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index c6d29ff..07f3d8d 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -17,6 +17,10 @@ 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 diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 754329b..6d4150b 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -5,6 +5,7 @@ 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 diff --git a/drivers/pinctrl/pinconf-generic.c b/drivers/pinctrl/pinconf-generic.c new file mode 100644 index 0000000..33fbaea --- /dev/null +++ b/drivers/pinctrl/pinconf-generic.c @@ -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 + * + * License terms: GNU General Public License (GPL) version 2 + */ + +#define pr_fmt(fmt) "generic pinconfig core: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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 diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index b40ac1b..7321e86 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -54,7 +54,7 @@ int pinconf_validate_map(struct pinctrl_map const *map, int i) return 0; } -static int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, +int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, unsigned long *config) { const struct pinconf_ops *ops = pctldev->desc->confops; @@ -439,6 +439,8 @@ static void pinconf_dump_pin(struct pinctrl_dev *pctldev, { 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); } @@ -482,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); } diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h index 0ded227..54510de 100644 --- a/drivers/pinctrl/pinconf.h +++ b/drivers/pinctrl/pinconf.h @@ -14,20 +14,26 @@ #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_group_get(const char *dev_name, const char *pin_group, + unsigned long *config); + #else static inline int pinconf_check_ops(struct pinctrl_dev *pctldev) @@ -71,3 +77,34 @@ static inline void pinconf_init_device_debugfs(struct dentry *devroot, } #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 diff --git a/include/linux/pinctrl/pinconf-generic.h b/include/linux/pinctrl/pinconf-generic.h new file mode 100644 index 0000000..4f0abb9 --- /dev/null +++ b/include/linux/pinctrl/pinconf-generic.h @@ -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 + * + * 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 */ diff --git a/include/linux/pinctrl/pinconf.h b/include/linux/pinctrl/pinconf.h index f8cf156..ec431f0 100644 --- a/include/linux/pinctrl/pinconf.h +++ b/include/linux/pinctrl/pinconf.h @@ -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); -- cgit v0.10.2 From a050b3eee61666421df786c8d898ec22c129f4af Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 16 Nov 2011 20:10:09 +0100 Subject: pinctrl/coh901: use generic pinconf enums and parameters Adjust the COH 901 driver to use the standard enums for biasing and driving pins, alter signature of config function to suit the framework. Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index b90c011..724234c 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -26,36 +26,6 @@ #include /* - * Bias modes for U300 GPIOs - * - * GPIO_U300_CONFIG_BIAS_UNKNOWN: this bias mode is not known to us - * GPIO_U300_CONFIG_BIAS_FLOAT: no specific bias, the GPIO will float or state - * is not controlled by software - * GPIO_U300_CONFIG_BIAS_PULL_UP: the GPIO will be pulled up (usually with high - * impedance to VDD) - */ -#define GPIO_U300_CONFIG_BIAS_UNKNOWN 0x1000 -#define GPIO_U300_CONFIG_BIAS_FLOAT 0x1001 -#define GPIO_U300_CONFIG_BIAS_PULL_UP 0x1002 - -/* - * Drive modes for U300 GPIOs (output) - * - * GPIO_U300_CONFIG_DRIVE_PUSH_PULL: the GPIO will be driven actively high and - * low, this is the most typical case and is typically achieved with two - * active transistors on the output - * GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN: the GPIO will be driven with open drain - * (open collector) which means it is usually wired with other output - * ports which are then pulled up with an external resistor - * GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE: the GPIO will be driven with open drain - * (open emitter) which is the same as open drain mutatis mutandis but - * pulled to ground - */ -#define GPIO_U300_CONFIG_DRIVE_PUSH_PULL 0x2000 -#define GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN 0x2001 -#define GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE 0x2002 - -/* * Register definitions for COH 901 335 variant */ #define U300_335_PORT_STRIDE (0x1C) @@ -181,12 +151,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, \ } @@ -449,7 +419,7 @@ static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset) } static int u300_gpio_config(struct gpio_chip *chip, unsigned offset, - u16 param, unsigned long *data) + enum pin_config_param param, unsigned long data) { struct u300_gpio *gpio = to_u300_gpio(chip); unsigned long flags; @@ -457,16 +427,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 +444,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 +452,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)); @@ -651,12 +621,12 @@ static void __init u300_gpio_init_pin(struct u300_gpio *gpio, /* Deactivate bias mode for output */ u300_gpio_config(&gpio->chip, offset, - GPIO_U300_CONFIG_BIAS_FLOAT, - NULL); + PIN_CONFIG_BIAS_HIGH_IMPEDANCE, + 0); /* Set drive mode for output */ u300_gpio_config(&gpio->chip, offset, - GPIO_U300_CONFIG_DRIVE_PUSH_PULL, NULL); + PIN_CONFIG_DRIVE_PUSH_PULL, 0); dev_dbg(gpio->dev, "set up pin %d as output, value: %d\n", offset, conf->outval); @@ -667,7 +637,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(&gpio->chip, offset, conf->bias_mode, 0); dev_dbg(gpio->dev, "set up pin %d as input, bias: %04x\n", offset, conf->bias_mode); -- cgit v0.10.2 From dc0b1aa3e2fefa6372f38d7f6d5d33581567a1b5 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 16 Nov 2011 21:58:10 +0100 Subject: pinctrl: support pinconfig on the U300 This adds pin configuration support for the U300 driver pair, we can now read out the biasing and drive mode in debugfs and configure it using the new configuration API. ChangeLog v1->v2: - Migrate to pin config and generic pin config changes. ChangeLog v2->v3: - Adjust to generic pin config changes in v7 patch set. Signed-off-by: Linus Walleij diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 07f3d8d..abfb964 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -73,6 +73,7 @@ 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" diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index 724234c..0797eba 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -23,7 +23,9 @@ #include #include #include +#include #include +#include "pinctrl-coh901.h" /* * Register definitions for COH 901 335 variant @@ -418,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, - enum pin_config_param 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; @@ -620,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, - PIN_CONFIG_BIAS_HIGH_IMPEDANCE, - 0); + u300_gpio_config_set(&gpio->chip, offset, + PIN_CONFIG_BIAS_HIGH_IMPEDANCE); /* Set drive mode for output */ - u300_gpio_config(&gpio->chip, offset, - PIN_CONFIG_DRIVE_PUSH_PULL, 0); + 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); @@ -637,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, 0); + 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); diff --git a/drivers/pinctrl/pinctrl-coh901.h b/drivers/pinctrl/pinctrl-coh901.h new file mode 100644 index 0000000..8729422 --- /dev/null +++ b/drivers/pinctrl/pinctrl-coh901.h @@ -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); diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index fc4a281..26eb8cc 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c @@ -19,6 +19,9 @@ #include #include #include +#include +#include +#include "pinctrl-coh901.h" /* * Register definitions for the U300 Padmux control registers in the @@ -1044,12 +1047,69 @@ 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, }; -- cgit v0.10.2 From 51dddfe839a0ebcb5ff61a779e3f2768714f9957 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Fri, 20 Jan 2012 17:53:15 +0100 Subject: ARM: u300: configure some pins as an example To show how the pin configuration is used on the U300, let's include some configs for two GPIO pins. ChangeLog v1->v2: - Provide a better example, set the clock return pin to pull-up and set the card detect pin to high impedance. Signed-off-by: Linus Walleij diff --git a/arch/arm/mach-u300/core.c b/arch/arm/mach-u300/core.c index f326d31..a7b3f36 100644 --- a/arch/arm/mach-u300/core.c +++ b/arch/arm/mach-u300/core.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include @@ -1605,7 +1606,15 @@ static struct platform_device dma_device = { }, }; -/* Pinmux settings */ +static unsigned long pin_pullup_conf[] = { + PIN_CONF_PACKED(PIN_CONFIG_BIAS_PULL_UP, 1), +}; + +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 */ PIN_MAP_MUX_GROUP_HOG_DEFAULT("pinctrl-u300", NULL, "power"), @@ -1615,6 +1624,12 @@ static struct pinctrl_map __initdata u300_pinmux_map[] = { 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 { @@ -1640,7 +1655,6 @@ static int __init u300_pinctrl_fetch(void) for (i = 0; i < ARRAY_SIZE(u300_mux_hogs); i++) { struct pinctrl *p; - int ret; p = pinctrl_get_select_default(u300_mux_hogs[i].dev); if (IS_ERR(p)) { -- cgit v0.10.2