From f59d28dc00ae3f1a76b442dcd0a52d8708c577cc Mon Sep 17 00:00:00 2001 From: Barry Song Date: Fri, 2 Dec 2011 10:32:15 +0800 Subject: pinctrl/sirf: fix pin number typo for SPI1 Signed-off-by: Barry Song Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux-sirf.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinmux-sirf.c b/drivers/pinctrl/pinmux-sirf.c index d76cae6..d848d97 100644 --- a/drivers/pinctrl/pinmux-sirf.c +++ b/drivers/pinctrl/pinmux-sirf.c @@ -463,7 +463,7 @@ static const struct sirfsoc_padmux spi1_padmux = { .funcval = BIT(8), }; -static const unsigned spi1_pins[] = { 33, 34, 35, 36 }; +static const unsigned spi1_pins[] = { 43, 44, 45, 46 }; static const struct sirfsoc_muxmask sdmmc1_muxmask[] = { { -- cgit v1.1 From 3838d3275923d0e0df706d2d32e633839166ccea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 8 Dec 2011 15:42:45 +0100 Subject: pinctrl: make the "Debug PINCTRL calls" entry actually do something MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit DEBUG_PINCTRL wasn't used at all and DEBUG_PINMUX doesn't exist. Signed-off-by: Uwe Kleine-König Signed-off-by: Linus Walleij --- drivers/pinctrl/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index bdc548a..50a2e2f 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -1,6 +1,6 @@ # generic pinmux support -ccflags-$(CONFIG_DEBUG_PINMUX) += -DDEBUG +ccflags-$(CONFIG_DEBUG_PINCTRL) += -DDEBUG obj-$(CONFIG_PINCTRL) += core.o obj-$(CONFIG_PINMUX) += pinmux.o -- cgit v1.1 From cc96ffbb744bff2826aa9e62b14bb599b1f15fc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Uwe=20Kleine-K=C3=B6nig?= Date: Thu, 8 Dec 2011 15:52:15 +0100 Subject: pinctrl: remove two unused global variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Uwe Kleine-König Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux.c | 4 ---- 1 file changed, 4 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index a5467f8..f2c84a9 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -32,10 +32,6 @@ static DEFINE_MUTEX(pinmux_list_mutex); static LIST_HEAD(pinmux_list); -/* List of pinmux hogs */ -static DEFINE_MUTEX(pinmux_hoglist_mutex); -static LIST_HEAD(pinmux_hoglist); - /* Global pinmux maps, we allow one set only */ static struct pinmux_map const *pinmux_maps; static unsigned pinmux_maps_num; -- cgit v1.1 From b84e673f51799a2d0bad7a7c1e7a74021c4eba4b Mon Sep 17 00:00:00 2001 From: Rajendra Nayak Date: Tue, 15 Nov 2011 12:10:26 +0530 Subject: pinctrl: iterate over u300_pmx_mask's in u300_pmx_endisable Fix u300_pmx_endisable() to iterate over the list of 'bits' and 'mask' populated as part of u300_pmx_functions.mask[] Signed-off-by: Rajendra Nayak Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux-u300.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinmux-u300.c b/drivers/pinctrl/pinmux-u300.c index 4858a64..145a84d 100644 --- a/drivers/pinctrl/pinmux-u300.c +++ b/drivers/pinctrl/pinmux-u300.c @@ -940,20 +940,23 @@ static void u300_pmx_endisable(struct u300_pmx *upmx, unsigned selector, { u16 regval, val, mask; int i; + const struct u300_pmx_mask *upmx_mask; + upmx_mask = u300_pmx_functions[selector].mask; for (i = 0; i < ARRAY_SIZE(u300_pmx_registers); i++) { if (enable) - val = u300_pmx_functions[selector].mask->bits; + val = upmx_mask->bits; else val = 0; - mask = u300_pmx_functions[selector].mask->mask; + mask = upmx_mask->mask; if (mask != 0) { regval = readw(upmx->virtbase + u300_pmx_registers[i]); regval &= ~mask; regval |= val; writew(regval, upmx->virtbase + u300_pmx_registers[i]); } + upmx_mask++; } } -- cgit v1.1 From 7afde8baa83b9ac409a6db86f27a41878aa6b33f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 19 Oct 2011 17:07:16 +0200 Subject: pinctrl: move group lookup to core Now also the core needs to look up pin groups so move the lookup function there and expose it in the internal header. Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 31 +++++++++++++++++++++++++++++++ drivers/pinctrl/core.h | 2 ++ drivers/pinctrl/pinmux.c | 35 ++--------------------------------- 3 files changed, 35 insertions(+), 33 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index eadef9e..9970590 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -284,6 +284,37 @@ void pinctrl_remove_gpio_range(struct pinctrl_dev *pctldev, mutex_unlock(&pctldev->gpio_ranges_lock); } +/** + * pinctrl_get_group_selector() - returns the group selector for a group + * @pctldev: the pin controller handling the group + * @pin_group: the pin group to look up + */ +int pinctrl_get_group_selector(struct pinctrl_dev *pctldev, + const char *pin_group) +{ + const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; + unsigned group_selector = 0; + + while (pctlops->list_groups(pctldev, group_selector) >= 0) { + const char *gname = pctlops->get_group_name(pctldev, + group_selector); + if (!strcmp(gname, pin_group)) { + dev_dbg(&pctldev->dev, + "found group selector %u for %s\n", + group_selector, + pin_group); + return group_selector; + } + + group_selector++; + } + + dev_err(&pctldev->dev, "does not have pin group %s\n", + pin_group); + + return -EINVAL; +} + #ifdef CONFIG_DEBUG_FS static int pinctrl_pins_show(struct seq_file *s, void *what) diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 472fa13..dcc6d68 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -69,3 +69,5 @@ struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, int pin); 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); diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index f2c84a9..72b760b 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -390,37 +390,6 @@ static void release_pins(struct pinctrl_dev *pctldev, } /** - * pinmux_get_group_selector() - returns the group selector for a group - * @pctldev: the pin controller handling the group - * @pin_group: the pin group to look up - */ -static int pinmux_get_group_selector(struct pinctrl_dev *pctldev, - const char *pin_group) -{ - const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; - unsigned group_selector = 0; - - while (pctlops->list_groups(pctldev, group_selector) >= 0) { - const char *gname = pctlops->get_group_name(pctldev, - group_selector); - if (!strcmp(gname, pin_group)) { - dev_dbg(&pctldev->dev, - "found group selector %u for %s\n", - group_selector, - pin_group); - return group_selector; - } - - group_selector++; - } - - dev_err(&pctldev->dev, "does not have pin group %s\n", - pin_group); - - return -EINVAL; -} - -/** * 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 @@ -461,7 +430,7 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, return ret; if (num_groups < 1) return -EINVAL; - ret = pinmux_get_group_selector(pctldev, groups[0]); + ret = pinctrl_get_group_selector(pctldev, groups[0]); if (ret < 0) { dev_err(&pctldev->dev, "function %s wants group %s but the pin " @@ -486,7 +455,7 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, "check if we have pin group %s on controller %s\n", pin_group, pinctrl_dev_get_name(pctldev)); - ret = pinmux_get_group_selector(pctldev, pin_group); + 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", -- cgit v1.1 From d2f6a1c6fb0e510a24ccac066eefbcfd0c932858 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Wed, 26 Oct 2011 22:57:20 +0200 Subject: pinctrl: remove double pin validity check. Function pin_is_valid just call pin_desc_get which is in pin_request call some line below. Remove pin_is_valid() check. Acked-by: Stephen Warren Signed-off-by: Marek Belisko Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 72b760b..17c3931 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -108,16 +108,6 @@ static int pin_request(struct pinctrl_dev *pctldev, dev_dbg(&pctldev->dev, "request pin %d for %s\n", pin, function); - if (!pin_is_valid(pctldev, pin)) { - dev_err(&pctldev->dev, "pin is invalid\n"); - return -EINVAL; - } - - if (!function) { - dev_err(&pctldev->dev, "no function name given\n"); - return -EINVAL; - } - desc = pin_desc_get(pctldev, pin); if (desc == NULL) { dev_err(&pctldev->dev, @@ -125,6 +115,11 @@ static int pin_request(struct pinctrl_dev *pctldev, goto out; } + if (!function) { + dev_err(&pctldev->dev, "no function name given\n"); + return -EINVAL; + } + spin_lock(&desc->lock); if (desc->mux_function) { spin_unlock(&desc->lock); -- cgit v1.1 From 3712a3c488987849613a4ad74129e67e40b12b38 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 21 Oct 2011 12:25:53 -0600 Subject: pinctrl: add explicit gpio_disable_free pinmux_op Some pinctrl drivers (Tegra at least) program a pin to be a GPIO in a completely different manner than they select which function to mux out of that pin. In order to support a single "free" pinmux_op, the driver would need to maintain a per-pin state of requested-for-gpio vs. requested-for- function. However, that's a lot of work when the core already has explicit separate paths for gpio request/free and function request/free. So, add a gpio_disable_free op to struct pinmux_ops, and make pin_free() call it when appropriate. When doing this, I noticed that when calling pin_request(): !!gpio == (gpio_range != NULL) ... and so I collapsed those two parameters in both pin_request(), and when adding writing the new code in pin_free(). Also, for pin_free(): !!free_func == (gpio_range != NULL) However, I didn't want pin_free() to know about the GPIO function naming special case, so instead, I reworked pin_free() to always return the pin's previously requested function, and now pinmux_free_gpio() calls kfree(function). This is much more balanced with the allocation having been performed in pinmux_request_gpio(). Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux.c | 39 +++++++++++++++++++++++++-------------- 1 file changed, 25 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 17c3931..c77aee5 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -94,12 +94,11 @@ struct pinmux_hog { * @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 - * @gpio: if this request concerns a single GPIO pin * @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, bool gpio, + int pin, const char *function, struct pinctrl_gpio_range *gpio_range) { struct pin_desc *desc; @@ -143,7 +142,7 @@ static int pin_request(struct pinctrl_dev *pctldev, * If there is no kind of request function for the pin we just assume * we got it by default and proceed. */ - if (gpio && ops->gpio_request_enable) + if (gpio_range && ops->gpio_request_enable) /* This requests and enables a single GPIO pin */ status = ops->gpio_request_enable(pctldev, gpio_range, pin); else if (ops->request) @@ -173,29 +172,39 @@ out: * pin_free() - release a single muxed in pin so something else can be muxed * @pctldev: pin controller device handling this pin * @pin: the pin to free - * @free_func: whether to free the pin's assigned function name string + * @gpio_range: the range matching the GPIO pin if this is a request for a + * single GPIO pin */ -static void pin_free(struct pinctrl_dev *pctldev, int pin, int free_func) +static const char *pin_free(struct pinctrl_dev *pctldev, int pin, + struct pinctrl_gpio_range *gpio_range) { const struct pinmux_ops *ops = pctldev->desc->pmxops; struct pin_desc *desc; + const char *func; desc = pin_desc_get(pctldev, pin); if (desc == NULL) { dev_err(&pctldev->dev, "pin is not registered so it cannot be freed\n"); - return; + return NULL; } - if (ops->free) + /* + * If there is no kind of request function for the pin we just assume + * we got it by default and proceed. + */ + if (gpio_range && ops->gpio_disable_free) + ops->gpio_disable_free(pctldev, gpio_range, pin); + else if (ops->free) ops->free(pctldev, pin); spin_lock(&desc->lock); - if (free_func) - kfree(desc->mux_function); + func = desc->mux_function; desc->mux_function = NULL; spin_unlock(&desc->lock); module_put(pctldev->owner); + + return func; } /** @@ -225,7 +234,7 @@ int pinmux_request_gpio(unsigned gpio) if (!function) return -EINVAL; - ret = pin_request(pctldev, pin, function, true, range); + ret = pin_request(pctldev, pin, function, range); if (ret < 0) kfree(function); @@ -243,6 +252,7 @@ void pinmux_free_gpio(unsigned gpio) struct pinctrl_gpio_range *range; int ret; int pin; + const char *func; ret = pinctrl_get_device_gpio_range(gpio, &pctldev, &range); if (ret) @@ -251,7 +261,8 @@ void pinmux_free_gpio(unsigned gpio) /* Convert to the pin controllers number space */ pin = gpio - range->base; - pin_free(pctldev, pin, true); + func = pin_free(pctldev, pin, range); + kfree(func); } EXPORT_SYMBOL_GPL(pinmux_free_gpio); @@ -341,7 +352,7 @@ 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, false, NULL); + ret = pin_request(pctldev, pins[i], func, NULL); if (ret) { dev_err(&pctldev->dev, "could not get pin %d for function %s " @@ -351,7 +362,7 @@ static int acquire_pins(struct pinctrl_dev *pctldev, /* On error release all taken pins */ i--; /* this pin just failed */ for (; i >= 0; i--) - pin_free(pctldev, pins[i], false); + pin_free(pctldev, pins[i], NULL); return -ENODEV; } } @@ -381,7 +392,7 @@ static void release_pins(struct pinctrl_dev *pctldev, return; } for (i = 0; i < num_pins; i++) - pin_free(pctldev, pins[i], false); + pin_free(pctldev, pins[i], NULL); } /** -- cgit v1.1 From 336cdba09a5df706402628fb20b7660d186aff6c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 10 Nov 2011 09:27:41 +0100 Subject: pinctrl: documentation update MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update the docs removing an obsolete __refdata tag and document the mysterious return value of pin_free(). And fixes up some various confusions in the pinctrl documentation. Reported-by: Rajendra Nayak Reported-by: Randy Dunlap Reported-by: Thomas Abraham Reported-by: Uwe Kleine-König Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index c77aee5..ee3aba7 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -174,6 +174,10 @@ out: * @pin: the pin to free * @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 + * once the pin is free. This is done for GPIO request functions. */ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, struct pinctrl_gpio_range *gpio_range) @@ -919,7 +923,7 @@ int pinmux_hog_maps(struct pinctrl_dev *pctldev) } /** - * pinmux_hog_maps() - unhog specific map entries on controller device + * pinmux_unhog_maps() - unhog specific map entries on controller device * @pctldev: the pin control device to unhog entries on */ void pinmux_unhog_maps(struct pinctrl_dev *pctldev) -- cgit v1.1 From 33d58949adee5086478e140751e4a7263bd7e207 Mon Sep 17 00:00:00 2001 From: Marek Belisko Date: Mon, 31 Oct 2011 21:27:52 +0100 Subject: pinctrl: unify pin type from signed to unsigned We want singned pins to mean "invalid" only on the outside of the subsystem. Signed-off-by: Marek Belisko Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 2 +- drivers/pinctrl/core.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 9970590..6782166 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -88,7 +88,7 @@ struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, return found ? pctldev : NULL; } -struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, int pin) +struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin) { struct pin_desc *pindesc; unsigned long flags; diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index dcc6d68..74dee43 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -65,7 +65,7 @@ struct pin_desc { struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, const char *dev_name); -struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, int pin); +struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin); int pinctrl_get_device_gpio_range(unsigned gpio, struct pinctrl_dev **outdev, struct pinctrl_gpio_range **outrange); -- cgit v1.1 From 3c739ad0df5eb41cd7adad879eda6aa09879eb76 Mon Sep 17 00:00:00 2001 From: Chanho Park Date: Fri, 11 Nov 2011 18:47:58 +0900 Subject: pinctrl: add a pin_base for sparse gpio-ranges This patch enables mapping a base offset of gpio ranges with a pin offset even if does'nt matched. A base of pinctrl_gpio_range means a base offset of gpio. However, we cannot convert gpio to pin number for sparse gpio ranges just only using a gpio base offset. We can convert a gpio to real pin number(even if not matched) using a new pin_base which means a base pin offset of requested gpio range. Now, the pin control subsystem passes the pin base offset to the pinmux driver. For example, let's assume below two gpio ranges in the system. static struct pinctrl_gpio_range gpio_range_a = { .name = "chip a", .id = 0, .base = 32, .pin_base = 32, .npins = 16, .gc = &chip_a; }; static struct pinctrl_gpio_range gpio_range_b = { .name = "chip b", .id = 0, .base = 48, .pin_base = 64, .npins = 8, .gc = &chip_b; }; We can calucalate a exact pin ranges even if doesn't matched with gpio ranges. chip a: gpio-range : [32 .. 47] pin-range : [32 .. 47] chip b: gpio-range : [48 .. 55] pin-range : [64 .. 71] Signed-off-by: Chanho Park Signed-off-by: Kyungmin Park Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux-sirf.c | 6 +++++- drivers/pinctrl/pinmux-u300.c | 1 + drivers/pinctrl/pinmux.c | 4 ++-- 3 files changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinmux-sirf.c b/drivers/pinctrl/pinmux-sirf.c index d848d97..99e688e 100644 --- a/drivers/pinctrl/pinmux-sirf.c +++ b/drivers/pinctrl/pinmux-sirf.c @@ -1067,7 +1067,7 @@ static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, spmx = pinctrl_dev_get_drvdata(pmxdev); muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); - muxval = muxval | (1 << offset); + muxval = muxval | (1 << (offset - range->pin_base)); writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); return 0; @@ -1100,21 +1100,25 @@ static struct pinctrl_gpio_range sirfsoc_gpio_ranges[] = { .name = "sirfsoc-gpio*", .id = 0, .base = 0, + .pin_base = 0, .npins = 32, }, { .name = "sirfsoc-gpio*", .id = 1, .base = 32, + .pin_base = 32, .npins = 32, }, { .name = "sirfsoc-gpio*", .id = 2, .base = 64, + .pin_base = 64, .npins = 32, }, { .name = "sirfsoc-gpio*", .id = 3, .base = 96, + .pin_base = 96, .npins = 19, }, }; diff --git a/drivers/pinctrl/pinmux-u300.c b/drivers/pinctrl/pinmux-u300.c index 145a84d..bcf61be 100644 --- a/drivers/pinctrl/pinmux-u300.c +++ b/drivers/pinctrl/pinmux-u300.c @@ -1026,6 +1026,7 @@ static struct pinctrl_gpio_range u300_gpio_range = { .name = "COH901*", .id = 0, .base = 0, + .pin_base = 0, .npins = 64, }; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index ee3aba7..92aa13e 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -229,7 +229,7 @@ int pinmux_request_gpio(unsigned gpio) return -EINVAL; /* Convert to the pin controllers number space */ - pin = gpio - range->base; + 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); @@ -263,7 +263,7 @@ void pinmux_free_gpio(unsigned gpio) return; /* Convert to the pin controllers number space */ - pin = gpio - range->base; + pin = gpio - range->base + range->pin_base; func = pin_free(pctldev, pin, range); kfree(func); -- cgit v1.1 From 75d6642a3ee1dfe2552028997cdcc2c4207bec8f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 16 Nov 2011 09:58:51 +0100 Subject: pinctrl: print pin range in GPIO range debugs Show the mapped pin range corresponding to the GPIO range in debugfs for pin controllers. Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 6782166..4955a68 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -394,8 +394,11 @@ static int pinctrl_gpioranges_show(struct seq_file *s, void *what) /* Loop over the ranges */ mutex_lock(&pctldev->gpio_ranges_lock); list_for_each_entry(range, &pctldev->gpio_ranges, node) { - seq_printf(s, "%u: %s [%u - %u]\n", range->id, range->name, - range->base, (range->base + range->npins - 1)); + seq_printf(s, "%u: %s GPIOS [%u - %u] PINS [%u - %u]\n", + range->id, range->name, + range->base, (range->base + range->npins - 1), + range->pin_base, + (range->pin_base + range->npins - 1)); } mutex_unlock(&pctldev->gpio_ranges_lock); -- cgit v1.1 From 542e704f3ffee1dc4539c9e8191e4dc215220f5e Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Mon, 14 Nov 2011 10:06:22 +0100 Subject: pinctrl: GPIO direction support for muxing When requesting a single GPIO pin to be muxed in, some controllers will need to poke a different value into the control register depending on whether the pin will be used for GPIO output or GPIO input. So create pinmux counterparts to gpio_direction_[input|output] in the pinctrl framework. ChangeLog v1->v2: - This also amends the documentation to make it clear the this function and associated machinery is *ONLY* intended as a backend to gpiolib machinery, not for everyone and his dog to start playing around with pins. ChangeLog v2->v3: - Don't pass an argument to the common request function, instead provide pinmux_* counterparts to the gpio_direction_[input|output] calls, simpler and anyone can understand it. ChangeLog v3->v4: - Fix numerous spelling mistakes and dangling text in documentation. Add Ack and Rewewed-by. Cc: Igor Grinberg Acked-by: Stephen Warren Reviewed-by: Thomas Abraham Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'drivers') diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 92aa13e..f3e4f03 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -214,6 +214,10 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, /** * pinmux_request_gpio() - request a single pin to be muxed in as GPIO * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_request() semantics, platforms and individual drivers + * shall *NOT* request GPIO pins to be muxed in. */ int pinmux_request_gpio(unsigned gpio) { @@ -249,6 +253,10 @@ EXPORT_SYMBOL_GPL(pinmux_request_gpio); /** * pinmux_free_gpio() - free a single pin, currently used as GPIO * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_free() semantics, platforms and individual drivers + * shall *NOT* request GPIO pins to be muxed out. */ void pinmux_free_gpio(unsigned gpio) { @@ -270,6 +278,59 @@ void pinmux_free_gpio(unsigned gpio) } EXPORT_SYMBOL_GPL(pinmux_free_gpio); +static int pinmux_gpio_direction(unsigned gpio, 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 + ret = 0; + + return ret; +} + +/** + * pinmux_gpio_direction_input() - request a GPIO pin to go into input mode + * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_direction_input() semantics, platforms and individual + * drivers shall *NOT* touch pinmux GPIO calls. + */ +int pinmux_gpio_direction_input(unsigned gpio) +{ + return pinmux_gpio_direction(gpio, true); +} +EXPORT_SYMBOL_GPL(pinmux_gpio_direction_input); + +/** + * pinmux_gpio_direction_output() - request a GPIO pin to go into output mode + * @gpio: the GPIO pin number from the GPIO subsystem number space + * + * This function should *ONLY* be used from gpiolib-based GPIO drivers, + * as part of their gpio_direction_output() semantics, platforms and individual + * drivers shall *NOT* touch pinmux GPIO calls. + */ +int pinmux_gpio_direction_output(unsigned gpio) +{ + return pinmux_gpio_direction(gpio, false); +} +EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output); + /** * pinmux_register_mappings() - register a set of pinmux mappings * @maps: the pinmux mappings table to register -- cgit v1.1 From 97607d157c133ab18dfcd77fa836e37fa950a44a Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Tue, 29 Nov 2011 12:52:39 +0100 Subject: pinctrl: make a copy of pinmux map This makes a deep copy of the pinmux function map instead of keeping the copy supplied from the platform around. This makes it possible to tag the platforms map with __initdata as is also done as part of this patch. Rationale: a certain target platform (PXA) has numerous pinmux maps, many of which will be lying around unused after boot in a multi-platform binary. Instead, deep-copy the one we're going to use and tag them all __initdata so they go away after boot. ChangeLog v1->v2: - Fixup the deep copy, missed a few items on the struct, plus mark bool member non-const since we're making runtime copies if this stuff now. ChangeLog v2->v3: - Make a shallow copy (just copy the array of map structs) as Arnd noticed, string constants never get discarded by the kernel anyway, so these pointers may be safely copied over. Reviewed-by: Arnd Bergmann Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux.c | 44 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 34 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index f3e4f03..f6e7d58 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -21,6 +21,7 @@ #include #include #include +#include #include #include #include @@ -33,7 +34,7 @@ static DEFINE_MUTEX(pinmux_list_mutex); static LIST_HEAD(pinmux_list); /* Global pinmux maps, we allow one set only */ -static struct pinmux_map const *pinmux_maps; +static struct pinmux_map *pinmux_maps; static unsigned pinmux_maps_num; /** @@ -333,7 +334,9 @@ EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output); /** * pinmux_register_mappings() - register a set of pinmux mappings - * @maps: the pinmux mappings table to register + * @maps: the pinmux mappings table to register, this should be marked with + * __initdata so it can be discarded after boot, this function will + * perform a shallow copy for the mapping entries. * @num_maps: the number of maps in the mapping table * * Only call this once during initialization of your machine, the function is @@ -344,32 +347,48 @@ EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output); int __init pinmux_register_mappings(struct pinmux_map const *maps, unsigned num_maps) { + int ret = 0; int i; - if (pinmux_maps != NULL) { + if (pinmux_maps_num != 0) { pr_err("pinmux mappings already registered, you can only " "register one set of maps\n"); return -EINVAL; } pr_debug("add %d pinmux maps\n", num_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. + */ + pinmux_maps = kmemdup(maps, sizeof(struct pinmux_map) * num_maps, + GFP_KERNEL); + if (!pinmux_maps) + return -ENOMEM; + for (i = 0; i < num_maps; i++) { - /* Sanity check the mapping */ + /* Sanity check the mapping while copying it */ if (!maps[i].name) { pr_err("failed to register map %d: " "no map name given\n", i); - return -EINVAL; + ret = -EINVAL; + goto err_out_free; } + if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) { pr_err("failed to register map %s (%d): " "no pin control device given\n", maps[i].name, i); - return -EINVAL; + ret = -EINVAL; + goto err_out_free; } + if (!maps[i].function) { pr_err("failed to register map %s (%d): " "no function ID given\n", maps[i].name, i); - return -EINVAL; + ret = -EINVAL; + goto err_out_free; } if (!maps[i].dev && !maps[i].dev_name) @@ -380,12 +399,17 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps, pr_debug("register map %s, function %s\n", maps[i].name, maps[i].function); - } - pinmux_maps = maps; - pinmux_maps_num = num_maps; + pinmux_maps_num++; + } return 0; + +err_out_free: + kfree(pinmux_maps); + pinmux_maps = NULL; + pinmux_maps_num = 0; + return ret; } /** -- cgit v1.1 From 59b099b04981917ee7fbd88b6f50eeaffc9f33cd Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 30 Nov 2011 13:28:14 +0100 Subject: pinctrl: make it possible to add multiple maps Since we now anyway make a copy of the platform-supplied pinmux map, we can just as well make it possible to call the function adding maps several times, so as to simplify cases (as PXA) where several sets of disparate mappings need to be added depending on target platform. Acked-by: Haojian Zhuang Acked-by: Arnd Bergmann Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux.c | 60 +++++++++++++++++++++++------------------------- 1 file changed, 29 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index f6e7d58..a11681b 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -33,7 +33,7 @@ static DEFINE_MUTEX(pinmux_list_mutex); static LIST_HEAD(pinmux_list); -/* Global pinmux maps, we allow one set only */ +/* Global pinmux maps */ static struct pinmux_map *pinmux_maps; static unsigned pinmux_maps_num; @@ -347,48 +347,30 @@ EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output); int __init pinmux_register_mappings(struct pinmux_map const *maps, unsigned num_maps) { - int ret = 0; + void *tmp_maps; int i; - if (pinmux_maps_num != 0) { - pr_err("pinmux mappings already registered, you can only " - "register one set of maps\n"); - return -EINVAL; - } - pr_debug("add %d pinmux maps\n", num_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. - */ - pinmux_maps = kmemdup(maps, sizeof(struct pinmux_map) * num_maps, - GFP_KERNEL); - if (!pinmux_maps) - return -ENOMEM; - + /* First sanity check the new mapping */ for (i = 0; i < num_maps; i++) { - /* Sanity check the mapping while copying it */ if (!maps[i].name) { pr_err("failed to register map %d: " "no map name given\n", i); - ret = -EINVAL; - goto err_out_free; + return -EINVAL; } if (!maps[i].ctrl_dev && !maps[i].ctrl_dev_name) { pr_err("failed to register map %s (%d): " "no pin control device given\n", maps[i].name, i); - ret = -EINVAL; - goto err_out_free; + return -EINVAL; } if (!maps[i].function) { pr_err("failed to register map %s (%d): " "no function ID given\n", maps[i].name, i); - ret = -EINVAL; - goto err_out_free; + return -EINVAL; } if (!maps[i].dev && !maps[i].dev_name) @@ -399,17 +381,33 @@ int __init pinmux_register_mappings(struct pinmux_map const *maps, pr_debug("register map %s, function %s\n", maps[i].name, maps[i].function); + } - pinmux_maps_num++; + /* + * Make a copy of the map array - string pointers will end up in the + * kernel const section anyway so these do not need to be deep copied. + */ + if (!pinmux_maps_num) { + /* On first call, just copy them */ + tmp_maps = kmemdup(maps, + sizeof(struct pinmux_map) * num_maps, + GFP_KERNEL); + if (!tmp_maps) + return -ENOMEM; + } else { + /* Subsequent calls, reallocate array to new size */ + size_t oldsize = sizeof(struct pinmux_map) * pinmux_maps_num; + size_t newsize = sizeof(struct pinmux_map) * num_maps; + + tmp_maps = krealloc(pinmux_maps, oldsize + newsize, GFP_KERNEL); + if (!tmp_maps) + return -ENOMEM; + memcpy((tmp_maps + oldsize), maps, newsize); } + pinmux_maps = tmp_maps; + pinmux_maps_num += num_maps; return 0; - -err_out_free: - kfree(pinmux_maps); - pinmux_maps = NULL; - pinmux_maps_num = 0; - return ret; } /** -- cgit v1.1 From ca402d37dccf2b797440c5f03bd0db16f977acc9 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 16 Nov 2011 09:22:59 +0100 Subject: pinctrl: move the U300 GPIO driver to pinctrl This driver will be converted to a dual GPIO + pinctrl driver since it supports biasing and driving control options. Hopefully it can serve as an example. Signed-off-by: Linus Walleij --- drivers/gpio/Kconfig | 9 - drivers/gpio/Makefile | 1 - drivers/gpio/gpio-u300.c | 917 --------------------------------------- drivers/pinctrl/Kconfig | 9 + drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-coh901.c | 917 +++++++++++++++++++++++++++++++++++++++ 6 files changed, 927 insertions(+), 927 deletions(-) delete mode 100644 drivers/gpio/gpio-u300.c create mode 100644 drivers/pinctrl/pinctrl-coh901.c (limited to 'drivers') diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 8482a23..0f82aa8f 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -170,15 +170,6 @@ config GPIO_SCH The Intel Tunnel Creek processor has 5 GPIOs powered by the core power rail and 9 from suspend power supply. -config GPIO_U300 - bool "ST-Ericsson U300 COH 901 335/571 GPIO" - depends on GPIOLIB && ARCH_U300 - help - Say yes here to support GPIO interface on ST-Ericsson U300. - The names of the two IP block variants supported are - COH 901 335 and COH 901 571/3. They contain 3, 5 or 7 - ports of 8 GPIO pins each. - config GPIO_VX855 tristate "VIA VX855/VX875 GPIO" depends on PCI diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index dbcb0bc..7f20316 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -54,7 +54,6 @@ obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o obj-$(CONFIG_GPIO_TPS65910) += gpio-tps65910.o obj-$(CONFIG_GPIO_TPS65912) += gpio-tps65912.o obj-$(CONFIG_GPIO_TWL4030) += gpio-twl4030.o -obj-$(CONFIG_MACH_U300) += gpio-u300.o obj-$(CONFIG_GPIO_UCB1400) += gpio-ucb1400.o obj-$(CONFIG_GPIO_VR41XX) += gpio-vr41xx.o obj-$(CONFIG_GPIO_VX855) += gpio-vx855.o diff --git a/drivers/gpio/gpio-u300.c b/drivers/gpio/gpio-u300.c deleted file mode 100644 index 4035778..0000000 --- a/drivers/gpio/gpio-u300.c +++ /dev/null @@ -1,917 +0,0 @@ -/* - * U300 GPIO module. - * - * Copyright (C) 2007-2011 ST-Ericsson AB - * License terms: GNU General Public License (GPL) version 2 - * This can driver either of the two basic GPIO cores - * available in the U300 platforms: - * COH 901 335 - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0) - * COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0) - * Author: Linus Walleij - * Author: Jonas Aaberg - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#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) -/* Port X Pin Data Register 32bit, this is both input and output (R/W) */ -#define U300_335_PXPDIR (0x00) -#define U300_335_PXPDOR (0x00) -/* Port X Pin Config Register 32bit (R/W) */ -#define U300_335_PXPCR (0x04) -/* This register layout is the same in both blocks */ -#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL) -#define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL) -#define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL) -#define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL) -#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL) -#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL) -#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL) -/* Port X Interrupt Event Register 32bit (R/W) */ -#define U300_335_PXIEV (0x08) -/* Port X Interrupt Enable Register 32bit (R/W) */ -#define U300_335_PXIEN (0x0C) -/* Port X Interrupt Force Register 32bit (R/W) */ -#define U300_335_PXIFR (0x10) -/* Port X Interrupt Config Register 32bit (R/W) */ -#define U300_335_PXICR (0x14) -/* This register layout is the same in both blocks */ -#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL) -#define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL) -#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL) -#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL) -/* Port X Pull-up Enable Register 32bit (R/W) */ -#define U300_335_PXPER (0x18) -/* This register layout is the same in both blocks */ -#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL) -#define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL) -/* Control Register 32bit (R/W) */ -#define U300_335_CR (0x54) -#define U300_335_CR_BLOCK_CLOCK_ENABLE (0x00000001UL) - -/* - * Register definitions for COH 901 571 / 3 variant - */ -#define U300_571_PORT_STRIDE (0x30) -/* - * Control Register 32bit (R/W) - * bit 15-9 (mask 0x0000FE00) contains the number of cores. 8*cores - * gives the number of GPIO pins. - * bit 8-2 (mask 0x000001FC) contains the core version ID. - */ -#define U300_571_CR (0x00) -#define U300_571_CR_SYNC_SEL_ENABLE (0x00000002UL) -#define U300_571_CR_BLOCK_CLKRQ_ENABLE (0x00000001UL) -/* - * These registers have the same layout and function as the corresponding - * COH 901 335 registers, just at different offset. - */ -#define U300_571_PXPDIR (0x04) -#define U300_571_PXPDOR (0x08) -#define U300_571_PXPCR (0x0C) -#define U300_571_PXPER (0x10) -#define U300_571_PXIEV (0x14) -#define U300_571_PXIEN (0x18) -#define U300_571_PXIFR (0x1C) -#define U300_571_PXICR (0x20) - -/* 8 bits per port, no version has more than 7 ports */ -#define U300_GPIO_PINS_PER_PORT 8 -#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * 7) - -struct u300_gpio { - struct gpio_chip chip; - struct list_head port_list; - struct clk *clk; - struct resource *memres; - void __iomem *base; - struct device *dev; - int irq_base; - u32 stride; - /* Register offsets */ - u32 pcr; - u32 dor; - u32 dir; - u32 per; - u32 icr; - u32 ien; - u32 iev; -}; - -struct u300_gpio_port { - struct list_head node; - struct u300_gpio *gpio; - char name[8]; - int irq; - int number; - u8 toggle_edge_mode; -}; - -/* - * Macro to expand to read a specific register found in the "gpio" - * struct. It requires the struct u300_gpio *gpio variable to exist in - * its context. It calculates the port offset from the given pin - * offset, muliplies by the port stride and adds the register offset - * so it provides a pointer to the desired register. - */ -#define U300_PIN_REG(pin, reg) \ - (gpio->base + (pin >> 3) * gpio->stride + gpio->reg) - -/* - * Provides a bitmask for a specific gpio pin inside an 8-bit GPIO - * register. - */ -#define U300_PIN_BIT(pin) \ - (1 << (pin & 0x07)) - -struct u300_gpio_confdata { - u16 bias_mode; - bool output; - int outval; -}; - -/* BS335 has seven ports of 8 bits each = GPIO pins 0..55 */ -#define BS335_GPIO_NUM_PORTS 7 -/* BS365 has five ports of 8 bits each = GPIO pins 0..39 */ -#define BS365_GPIO_NUM_PORTS 5 - -#define U300_FLOATING_INPUT { \ - .bias_mode = GPIO_U300_CONFIG_BIAS_FLOAT, \ - .output = false, \ -} - -#define U300_PULL_UP_INPUT { \ - .bias_mode = GPIO_U300_CONFIG_BIAS_PULL_UP, \ - .output = false, \ -} - -#define U300_OUTPUT_LOW { \ - .output = true, \ - .outval = 0, \ -} - -#define U300_OUTPUT_HIGH { \ - .output = true, \ - .outval = 1, \ -} - - -/* Initial configuration */ -static const struct __initdata u300_gpio_confdata -bs335_gpio_config[BS335_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { - /* Port 0, pins 0-7 */ - { - U300_FLOATING_INPUT, - U300_OUTPUT_HIGH, - U300_FLOATING_INPUT, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - }, - /* Port 1, pins 0-7 */ - { - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_PULL_UP_INPUT, - U300_FLOATING_INPUT, - U300_OUTPUT_HIGH, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - }, - /* Port 2, pins 0-7 */ - { - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_OUTPUT_LOW, - U300_PULL_UP_INPUT, - U300_OUTPUT_LOW, - U300_PULL_UP_INPUT, - }, - /* Port 3, pins 0-7 */ - { - U300_PULL_UP_INPUT, - U300_OUTPUT_LOW, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - }, - /* Port 4, pins 0-7 */ - { - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - }, - /* Port 5, pins 0-7 */ - { - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - }, - /* Port 6, pind 0-7 */ - { - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - } -}; - -static const struct __initdata u300_gpio_confdata -bs365_gpio_config[BS365_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { - /* Port 0, pins 0-7 */ - { - U300_FLOATING_INPUT, - U300_OUTPUT_LOW, - U300_FLOATING_INPUT, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_PULL_UP_INPUT, - U300_FLOATING_INPUT, - }, - /* Port 1, pins 0-7 */ - { - U300_OUTPUT_LOW, - U300_FLOATING_INPUT, - U300_OUTPUT_LOW, - U300_FLOATING_INPUT, - U300_FLOATING_INPUT, - U300_OUTPUT_HIGH, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - }, - /* Port 2, pins 0-7 */ - { - U300_FLOATING_INPUT, - U300_PULL_UP_INPUT, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_PULL_UP_INPUT, - U300_PULL_UP_INPUT, - U300_PULL_UP_INPUT, - U300_PULL_UP_INPUT, - }, - /* Port 3, pins 0-7 */ - { - U300_PULL_UP_INPUT, - U300_PULL_UP_INPUT, - U300_PULL_UP_INPUT, - U300_PULL_UP_INPUT, - U300_PULL_UP_INPUT, - U300_PULL_UP_INPUT, - U300_PULL_UP_INPUT, - U300_PULL_UP_INPUT, - }, - /* Port 4, pins 0-7 */ - { - U300_PULL_UP_INPUT, - U300_PULL_UP_INPUT, - U300_PULL_UP_INPUT, - U300_PULL_UP_INPUT, - /* These 4 pins doesn't exist on DB3210 */ - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - U300_OUTPUT_LOW, - } -}; - -/** - * to_u300_gpio() - get the pointer to u300_gpio - * @chip: the gpio chip member of the structure u300_gpio - */ -static inline struct u300_gpio *to_u300_gpio(struct gpio_chip *chip) -{ - return container_of(chip, struct u300_gpio, chip); -} - -static int u300_gpio_get(struct gpio_chip *chip, unsigned offset) -{ - struct u300_gpio *gpio = to_u300_gpio(chip); - - return readl(U300_PIN_REG(offset, dir)) & U300_PIN_BIT(offset); -} - -static void u300_gpio_set(struct gpio_chip *chip, unsigned offset, int value) -{ - struct u300_gpio *gpio = to_u300_gpio(chip); - unsigned long flags; - u32 val; - - local_irq_save(flags); - - val = readl(U300_PIN_REG(offset, dor)); - if (value) - writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, dor)); - else - writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, dor)); - - local_irq_restore(flags); -} - -static int u300_gpio_direction_input(struct gpio_chip *chip, unsigned offset) -{ - struct u300_gpio *gpio = to_u300_gpio(chip); - unsigned long flags; - u32 val; - - local_irq_save(flags); - val = readl(U300_PIN_REG(offset, pcr)); - /* Mask out this pin, note 2 bits per setting */ - val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((offset & 0x07) << 1)); - writel(val, U300_PIN_REG(offset, pcr)); - local_irq_restore(flags); - return 0; -} - -static int u300_gpio_direction_output(struct gpio_chip *chip, unsigned offset, - int value) -{ - struct u300_gpio *gpio = to_u300_gpio(chip); - unsigned long flags; - u32 oldmode; - u32 val; - - local_irq_save(flags); - val = readl(U300_PIN_REG(offset, pcr)); - /* - * Drive mode must be set by the special mode set function, set - * push/pull mode by default if no mode has been selected. - */ - oldmode = val & (U300_GPIO_PXPCR_PIN_MODE_MASK << - ((offset & 0x07) << 1)); - /* mode = 0 means input, else some mode is already set */ - if (oldmode == 0) { - val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << - ((offset & 0x07) << 1)); - val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL - << ((offset & 0x07) << 1)); - writel(val, U300_PIN_REG(offset, pcr)); - } - u300_gpio_set(chip, offset, value); - local_irq_restore(flags); - return 0; -} - -static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset) -{ - struct u300_gpio *gpio = to_u300_gpio(chip); - int retirq = gpio->irq_base + offset; - - dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d\n", offset, - retirq); - return retirq; -} - -static int u300_gpio_config(struct gpio_chip *chip, unsigned offset, - u16 param, unsigned long *data) -{ - struct u300_gpio *gpio = to_u300_gpio(chip); - unsigned long flags; - u32 val; - - local_irq_save(flags); - switch (param) { - case GPIO_U300_CONFIG_BIAS_UNKNOWN: - case GPIO_U300_CONFIG_BIAS_FLOAT: - 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: - 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: - val = readl(U300_PIN_REG(offset, pcr)); - val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK - << ((offset & 0x07) << 1)); - val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL - << ((offset & 0x07) << 1)); - writel(val, U300_PIN_REG(offset, pcr)); - break; - case GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN: - val = readl(U300_PIN_REG(offset, pcr)); - val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK - << ((offset & 0x07) << 1)); - val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN - << ((offset & 0x07) << 1)); - writel(val, U300_PIN_REG(offset, pcr)); - break; - case GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE: - val = readl(U300_PIN_REG(offset, pcr)); - val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK - << ((offset & 0x07) << 1)); - val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE - << ((offset & 0x07) << 1)); - writel(val, U300_PIN_REG(offset, pcr)); - break; - default: - local_irq_restore(flags); - dev_err(gpio->dev, "illegal configuration requested\n"); - return -EINVAL; - } - local_irq_restore(flags); - return 0; -} - -static struct gpio_chip u300_gpio_chip = { - .label = "u300-gpio-chip", - .owner = THIS_MODULE, - .get = u300_gpio_get, - .set = u300_gpio_set, - .direction_input = u300_gpio_direction_input, - .direction_output = u300_gpio_direction_output, - .to_irq = u300_gpio_to_irq, -}; - -static void u300_toggle_trigger(struct u300_gpio *gpio, unsigned offset) -{ - u32 val; - - val = readl(U300_PIN_REG(offset, icr)); - /* Set mode depending on state */ - if (u300_gpio_get(&gpio->chip, offset)) { - /* High now, let's trigger on falling edge next then */ - writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); - dev_dbg(gpio->dev, "next IRQ on falling edge on pin %d\n", - offset); - } else { - /* Low now, let's trigger on rising edge next then */ - writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); - dev_dbg(gpio->dev, "next IRQ on rising edge on pin %d\n", - offset); - } -} - -static int u300_gpio_irq_type(struct irq_data *d, unsigned trigger) -{ - struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); - struct u300_gpio *gpio = port->gpio; - int offset = d->irq - gpio->irq_base; - u32 val; - - if ((trigger & IRQF_TRIGGER_RISING) && - (trigger & IRQF_TRIGGER_FALLING)) { - /* - * The GPIO block can only trigger on falling OR rising edges, - * not both. So we need to toggle the mode whenever the pin - * goes from one state to the other with a special state flag - */ - dev_dbg(gpio->dev, - "trigger on both rising and falling edge on pin %d\n", - offset); - port->toggle_edge_mode |= U300_PIN_BIT(offset); - u300_toggle_trigger(gpio, offset); - } else if (trigger & IRQF_TRIGGER_RISING) { - dev_dbg(gpio->dev, "trigger on rising edge on pin %d\n", - offset); - val = readl(U300_PIN_REG(offset, icr)); - writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); - port->toggle_edge_mode &= ~U300_PIN_BIT(offset); - } else if (trigger & IRQF_TRIGGER_FALLING) { - dev_dbg(gpio->dev, "trigger on falling edge on pin %d\n", - offset); - val = readl(U300_PIN_REG(offset, icr)); - writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); - port->toggle_edge_mode &= ~U300_PIN_BIT(offset); - } - - return 0; -} - -static void u300_gpio_irq_enable(struct irq_data *d) -{ - struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); - struct u300_gpio *gpio = port->gpio; - int offset = d->irq - gpio->irq_base; - u32 val; - unsigned long flags; - - local_irq_save(flags); - val = readl(U300_PIN_REG(offset, ien)); - writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); - local_irq_restore(flags); -} - -static void u300_gpio_irq_disable(struct irq_data *d) -{ - struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); - struct u300_gpio *gpio = port->gpio; - int offset = d->irq - gpio->irq_base; - u32 val; - unsigned long flags; - - local_irq_save(flags); - val = readl(U300_PIN_REG(offset, ien)); - writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); - local_irq_restore(flags); -} - -static struct irq_chip u300_gpio_irqchip = { - .name = "u300-gpio-irqchip", - .irq_enable = u300_gpio_irq_enable, - .irq_disable = u300_gpio_irq_disable, - .irq_set_type = u300_gpio_irq_type, - -}; - -static void u300_gpio_irq_handler(unsigned irq, struct irq_desc *desc) -{ - struct u300_gpio_port *port = irq_get_handler_data(irq); - struct u300_gpio *gpio = port->gpio; - int pinoffset = port->number << 3; /* get the right stride */ - unsigned long val; - - desc->irq_data.chip->irq_ack(&desc->irq_data); - /* Read event register */ - val = readl(U300_PIN_REG(pinoffset, iev)); - /* Mask relevant bits */ - val &= 0xFFU; /* 8 bits per port */ - /* ACK IRQ (clear event) */ - writel(val, U300_PIN_REG(pinoffset, iev)); - - /* Call IRQ handler */ - if (val != 0) { - int irqoffset; - - for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) { - int pin_irq = gpio->irq_base + (port->number << 3) - + irqoffset; - int offset = pinoffset + irqoffset; - - dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n", - pin_irq, offset); - generic_handle_irq(pin_irq); - /* - * Triggering IRQ on both rising and falling edge - * needs mockery - */ - if (port->toggle_edge_mode & U300_PIN_BIT(offset)) - u300_toggle_trigger(gpio, offset); - } - } - - desc->irq_data.chip->irq_unmask(&desc->irq_data); -} - -static void __init u300_gpio_init_pin(struct u300_gpio *gpio, - int offset, - const struct u300_gpio_confdata *conf) -{ - /* Set mode: input or output */ - if (conf->output) { - u300_gpio_direction_output(&gpio->chip, offset, conf->outval); - - /* Deactivate bias mode for output */ - u300_gpio_config(&gpio->chip, offset, - GPIO_U300_CONFIG_BIAS_FLOAT, - NULL); - - /* Set drive mode for output */ - u300_gpio_config(&gpio->chip, offset, - GPIO_U300_CONFIG_DRIVE_PUSH_PULL, NULL); - - dev_dbg(gpio->dev, "set up pin %d as output, value: %d\n", - offset, conf->outval); - } else { - u300_gpio_direction_input(&gpio->chip, offset); - - /* Always set output low on input pins */ - u300_gpio_set(&gpio->chip, offset, 0); - - /* Set bias mode for input */ - u300_gpio_config(&gpio->chip, offset, conf->bias_mode, NULL); - - dev_dbg(gpio->dev, "set up pin %d as input, bias: %04x\n", - offset, conf->bias_mode); - } -} - -static void __init u300_gpio_init_coh901571(struct u300_gpio *gpio, - struct u300_gpio_platform *plat) -{ - int i, j; - - /* Write default config and values to all pins */ - for (i = 0; i < plat->ports; i++) { - for (j = 0; j < 8; j++) { - const struct u300_gpio_confdata *conf; - int offset = (i*8) + j; - - if (plat->variant == U300_GPIO_COH901571_3_BS335) - conf = &bs335_gpio_config[i][j]; - else if (plat->variant == U300_GPIO_COH901571_3_BS365) - conf = &bs365_gpio_config[i][j]; - else - break; - - u300_gpio_init_pin(gpio, offset, conf); - } - } -} - -static inline void u300_gpio_free_ports(struct u300_gpio *gpio) -{ - struct u300_gpio_port *port; - struct list_head *p, *n; - - 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); - } -} - -static int __init u300_gpio_probe(struct platform_device *pdev) -{ - struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); - struct u300_gpio *gpio; - int err = 0; - int portno; - u32 val; - u32 ifr; - int i; - - gpio = kzalloc(sizeof(struct u300_gpio), GFP_KERNEL); - if (gpio == NULL) { - dev_err(&pdev->dev, "failed to allocate memory\n"); - return -ENOMEM; - } - - gpio->chip = u300_gpio_chip; - gpio->chip.ngpio = plat->ports * U300_GPIO_PINS_PER_PORT; - gpio->irq_base = plat->gpio_irq_base; - gpio->chip.dev = &pdev->dev; - gpio->chip.base = plat->gpio_base; - gpio->dev = &pdev->dev; - - /* Get GPIO clock */ - gpio->clk = clk_get(gpio->dev, NULL); - if (IS_ERR(gpio->clk)) { - err = PTR_ERR(gpio->clk); - dev_err(gpio->dev, "could not get GPIO clock\n"); - goto err_no_clk; - } - err = clk_enable(gpio->clk); - if (err) { - dev_err(gpio->dev, "could not enable GPIO clock\n"); - goto err_no_clk_enable; - } - - gpio->memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!gpio->memres) { - dev_err(gpio->dev, "could not get GPIO memory resource\n"); - err = -ENODEV; - goto err_no_resource; - } - - if (!request_mem_region(gpio->memres->start, - resource_size(gpio->memres), - "GPIO Controller")) { - err = -ENODEV; - goto err_no_ioregion; - } - - gpio->base = ioremap(gpio->memres->start, resource_size(gpio->memres)); - if (!gpio->base) { - err = -ENOMEM; - goto err_no_ioremap; - } - - if (plat->variant == U300_GPIO_COH901335) { - dev_info(gpio->dev, - "initializing GPIO Controller COH 901 335\n"); - gpio->stride = U300_335_PORT_STRIDE; - gpio->pcr = U300_335_PXPCR; - gpio->dor = U300_335_PXPDOR; - gpio->dir = U300_335_PXPDIR; - gpio->per = U300_335_PXPER; - gpio->icr = U300_335_PXICR; - gpio->ien = U300_335_PXIEN; - gpio->iev = U300_335_PXIEV; - ifr = U300_335_PXIFR; - - /* Turn on the GPIO block */ - writel(U300_335_CR_BLOCK_CLOCK_ENABLE, - gpio->base + U300_335_CR); - } else if (plat->variant == U300_GPIO_COH901571_3_BS335 || - plat->variant == U300_GPIO_COH901571_3_BS365) { - dev_info(gpio->dev, - "initializing GPIO Controller COH 901 571/3\n"); - gpio->stride = U300_571_PORT_STRIDE; - gpio->pcr = U300_571_PXPCR; - gpio->dor = U300_571_PXPDOR; - gpio->dir = U300_571_PXPDIR; - gpio->per = U300_571_PXPER; - gpio->icr = U300_571_PXICR; - gpio->ien = U300_571_PXIEN; - gpio->iev = U300_571_PXIEV; - ifr = U300_571_PXIFR; - - val = readl(gpio->base + U300_571_CR); - dev_info(gpio->dev, "COH901571/3 block version: %d, " \ - "number of cores: %d totalling %d pins\n", - ((val & 0x000001FC) >> 2), - ((val & 0x0000FE00) >> 9), - ((val & 0x0000FE00) >> 9) * 8); - writel(U300_571_CR_BLOCK_CLKRQ_ENABLE, - gpio->base + U300_571_CR); - u300_gpio_init_coh901571(gpio, plat); - } else { - dev_err(gpio->dev, "unknown block variant\n"); - err = -ENODEV; - goto err_unknown_variant; - } - - /* Add each port with its IRQ separately */ - INIT_LIST_HEAD(&gpio->port_list); - for (portno = 0 ; portno < plat->ports; portno++) { - struct u300_gpio_port *port = - kmalloc(sizeof(struct u300_gpio_port), GFP_KERNEL); - - if (!port) { - dev_err(gpio->dev, "out of memory\n"); - err = -ENOMEM; - goto err_no_port; - } - - snprintf(port->name, 8, "gpio%d", portno); - port->number = portno; - port->gpio = gpio; - - port->irq = platform_get_irq_byname(pdev, - port->name); - - dev_dbg(gpio->dev, "register IRQ %d for %s\n", port->irq, - port->name); - - irq_set_chained_handler(port->irq, u300_gpio_irq_handler); - irq_set_handler_data(port->irq, port); - - /* For each GPIO pin set the unique IRQ handler */ - for (i = 0; i < U300_GPIO_PINS_PER_PORT; i++) { - int irqno = gpio->irq_base + (portno << 3) + i; - - dev_dbg(gpio->dev, "handler for IRQ %d on %s\n", - irqno, port->name); - irq_set_chip_and_handler(irqno, &u300_gpio_irqchip, - handle_simple_irq); - set_irq_flags(irqno, IRQF_VALID); - irq_set_chip_data(irqno, port); - } - - /* Turns off irq force (test register) for this port */ - writel(0x0, gpio->base + portno * gpio->stride + ifr); - - list_add_tail(&port->node, &gpio->port_list); - } - dev_dbg(gpio->dev, "initialized %d GPIO ports\n", portno); - - err = gpiochip_add(&gpio->chip); - if (err) { - dev_err(gpio->dev, "unable to add gpiochip: %d\n", err); - goto err_no_chip; - } - - platform_set_drvdata(pdev, gpio); - - return 0; - -err_no_chip: -err_no_port: - u300_gpio_free_ports(gpio); -err_unknown_variant: - iounmap(gpio->base); -err_no_ioremap: - release_mem_region(gpio->memres->start, resource_size(gpio->memres)); -err_no_ioregion: -err_no_resource: - clk_disable(gpio->clk); -err_no_clk_enable: - clk_put(gpio->clk); -err_no_clk: - kfree(gpio); - dev_info(&pdev->dev, "module ERROR:%d\n", err); - return err; -} - -static int __exit u300_gpio_remove(struct platform_device *pdev) -{ - struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); - struct u300_gpio *gpio = platform_get_drvdata(pdev); - int err; - - /* Turn off the GPIO block */ - if (plat->variant == U300_GPIO_COH901335) - writel(0x00000000U, gpio->base + U300_335_CR); - if (plat->variant == U300_GPIO_COH901571_3_BS335 || - plat->variant == U300_GPIO_COH901571_3_BS365) - writel(0x00000000U, gpio->base + U300_571_CR); - - err = gpiochip_remove(&gpio->chip); - if (err < 0) { - dev_err(gpio->dev, "unable to remove gpiochip: %d\n", err); - return err; - } - u300_gpio_free_ports(gpio); - iounmap(gpio->base); - release_mem_region(gpio->memres->start, - resource_size(gpio->memres)); - clk_disable(gpio->clk); - clk_put(gpio->clk); - platform_set_drvdata(pdev, NULL); - kfree(gpio); - return 0; -} - -static struct platform_driver u300_gpio_driver = { - .driver = { - .name = "u300-gpio", - }, - .remove = __exit_p(u300_gpio_remove), -}; - - -static int __init u300_gpio_init(void) -{ - return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe); -} - -static void __exit u300_gpio_exit(void) -{ - platform_driver_unregister(&u300_gpio_driver); -} - -arch_initcall(u300_gpio_init); -module_exit(u300_gpio_exit); - -MODULE_AUTHOR("Linus Walleij "); -MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335/COH 901 571/3 GPIO driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index e17e2f8..e087f02 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -30,6 +30,15 @@ config PINMUX_U300 depends on ARCH_U300 select PINMUX +config PINCTRL_COH901 + bool "ST-Ericsson U300 COH 901 335/571 GPIO" + depends on GPIOLIB && ARCH_U300 + help + Say yes here to support GPIO interface on ST-Ericsson U300. + The names of the two IP block variants supported are + COH 901 335 and COH 901 571/3. They contain 3, 5 or 7 + ports of 8 GPIO pins each. + endmenu endif diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 50a2e2f..5f3e4d6 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -6,3 +6,4 @@ obj-$(CONFIG_PINCTRL) += core.o obj-$(CONFIG_PINMUX) += pinmux.o obj-$(CONFIG_PINMUX_SIRF) += pinmux-sirf.o obj-$(CONFIG_PINMUX_U300) += pinmux-u300.o +obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c new file mode 100644 index 0000000..4035778 --- /dev/null +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -0,0 +1,917 @@ +/* + * U300 GPIO module. + * + * Copyright (C) 2007-2011 ST-Ericsson AB + * License terms: GNU General Public License (GPL) version 2 + * This can driver either of the two basic GPIO cores + * available in the U300 platforms: + * COH 901 335 - Used in DB3150 (U300 1.0) and DB3200 (U330 1.0) + * COH 901 571/3 - Used in DB3210 (U365 2.0) and DB3350 (U335 1.0) + * Author: Linus Walleij + * Author: Jonas Aaberg + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#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) +/* Port X Pin Data Register 32bit, this is both input and output (R/W) */ +#define U300_335_PXPDIR (0x00) +#define U300_335_PXPDOR (0x00) +/* Port X Pin Config Register 32bit (R/W) */ +#define U300_335_PXPCR (0x04) +/* This register layout is the same in both blocks */ +#define U300_GPIO_PXPCR_ALL_PINS_MODE_MASK (0x0000FFFFUL) +#define U300_GPIO_PXPCR_PIN_MODE_MASK (0x00000003UL) +#define U300_GPIO_PXPCR_PIN_MODE_SHIFT (0x00000002UL) +#define U300_GPIO_PXPCR_PIN_MODE_INPUT (0x00000000UL) +#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL (0x00000001UL) +#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN (0x00000002UL) +#define U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE (0x00000003UL) +/* Port X Interrupt Event Register 32bit (R/W) */ +#define U300_335_PXIEV (0x08) +/* Port X Interrupt Enable Register 32bit (R/W) */ +#define U300_335_PXIEN (0x0C) +/* Port X Interrupt Force Register 32bit (R/W) */ +#define U300_335_PXIFR (0x10) +/* Port X Interrupt Config Register 32bit (R/W) */ +#define U300_335_PXICR (0x14) +/* This register layout is the same in both blocks */ +#define U300_GPIO_PXICR_ALL_IRQ_CONFIG_MASK (0x000000FFUL) +#define U300_GPIO_PXICR_IRQ_CONFIG_MASK (0x00000001UL) +#define U300_GPIO_PXICR_IRQ_CONFIG_FALLING_EDGE (0x00000000UL) +#define U300_GPIO_PXICR_IRQ_CONFIG_RISING_EDGE (0x00000001UL) +/* Port X Pull-up Enable Register 32bit (R/W) */ +#define U300_335_PXPER (0x18) +/* This register layout is the same in both blocks */ +#define U300_GPIO_PXPER_ALL_PULL_UP_DISABLE_MASK (0x000000FFUL) +#define U300_GPIO_PXPER_PULL_UP_DISABLE (0x00000001UL) +/* Control Register 32bit (R/W) */ +#define U300_335_CR (0x54) +#define U300_335_CR_BLOCK_CLOCK_ENABLE (0x00000001UL) + +/* + * Register definitions for COH 901 571 / 3 variant + */ +#define U300_571_PORT_STRIDE (0x30) +/* + * Control Register 32bit (R/W) + * bit 15-9 (mask 0x0000FE00) contains the number of cores. 8*cores + * gives the number of GPIO pins. + * bit 8-2 (mask 0x000001FC) contains the core version ID. + */ +#define U300_571_CR (0x00) +#define U300_571_CR_SYNC_SEL_ENABLE (0x00000002UL) +#define U300_571_CR_BLOCK_CLKRQ_ENABLE (0x00000001UL) +/* + * These registers have the same layout and function as the corresponding + * COH 901 335 registers, just at different offset. + */ +#define U300_571_PXPDIR (0x04) +#define U300_571_PXPDOR (0x08) +#define U300_571_PXPCR (0x0C) +#define U300_571_PXPER (0x10) +#define U300_571_PXIEV (0x14) +#define U300_571_PXIEN (0x18) +#define U300_571_PXIFR (0x1C) +#define U300_571_PXICR (0x20) + +/* 8 bits per port, no version has more than 7 ports */ +#define U300_GPIO_PINS_PER_PORT 8 +#define U300_GPIO_MAX (U300_GPIO_PINS_PER_PORT * 7) + +struct u300_gpio { + struct gpio_chip chip; + struct list_head port_list; + struct clk *clk; + struct resource *memres; + void __iomem *base; + struct device *dev; + int irq_base; + u32 stride; + /* Register offsets */ + u32 pcr; + u32 dor; + u32 dir; + u32 per; + u32 icr; + u32 ien; + u32 iev; +}; + +struct u300_gpio_port { + struct list_head node; + struct u300_gpio *gpio; + char name[8]; + int irq; + int number; + u8 toggle_edge_mode; +}; + +/* + * Macro to expand to read a specific register found in the "gpio" + * struct. It requires the struct u300_gpio *gpio variable to exist in + * its context. It calculates the port offset from the given pin + * offset, muliplies by the port stride and adds the register offset + * so it provides a pointer to the desired register. + */ +#define U300_PIN_REG(pin, reg) \ + (gpio->base + (pin >> 3) * gpio->stride + gpio->reg) + +/* + * Provides a bitmask for a specific gpio pin inside an 8-bit GPIO + * register. + */ +#define U300_PIN_BIT(pin) \ + (1 << (pin & 0x07)) + +struct u300_gpio_confdata { + u16 bias_mode; + bool output; + int outval; +}; + +/* BS335 has seven ports of 8 bits each = GPIO pins 0..55 */ +#define BS335_GPIO_NUM_PORTS 7 +/* BS365 has five ports of 8 bits each = GPIO pins 0..39 */ +#define BS365_GPIO_NUM_PORTS 5 + +#define U300_FLOATING_INPUT { \ + .bias_mode = GPIO_U300_CONFIG_BIAS_FLOAT, \ + .output = false, \ +} + +#define U300_PULL_UP_INPUT { \ + .bias_mode = GPIO_U300_CONFIG_BIAS_PULL_UP, \ + .output = false, \ +} + +#define U300_OUTPUT_LOW { \ + .output = true, \ + .outval = 0, \ +} + +#define U300_OUTPUT_HIGH { \ + .output = true, \ + .outval = 1, \ +} + + +/* Initial configuration */ +static const struct __initdata u300_gpio_confdata +bs335_gpio_config[BS335_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { + /* Port 0, pins 0-7 */ + { + U300_FLOATING_INPUT, + U300_OUTPUT_HIGH, + U300_FLOATING_INPUT, + U300_OUTPUT_LOW, + U300_OUTPUT_LOW, + U300_OUTPUT_LOW, + U300_OUTPUT_LOW, + U300_OUTPUT_LOW, + }, + /* Port 1, pins 0-7 */ + { + U300_OUTPUT_LOW, + U300_OUTPUT_LOW, + U300_OUTPUT_LOW, + U300_PULL_UP_INPUT, + U300_FLOATING_INPUT, + U300_OUTPUT_HIGH, + U300_OUTPUT_LOW, + U300_OUTPUT_LOW, + }, + /* Port 2, pins 0-7 */ + { + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_OUTPUT_LOW, + U300_PULL_UP_INPUT, + U300_OUTPUT_LOW, + U300_PULL_UP_INPUT, + }, + /* Port 3, pins 0-7 */ + { + U300_PULL_UP_INPUT, + U300_OUTPUT_LOW, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + }, + /* Port 4, pins 0-7 */ + { + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + }, + /* Port 5, pins 0-7 */ + { + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + }, + /* Port 6, pind 0-7 */ + { + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + } +}; + +static const struct __initdata u300_gpio_confdata +bs365_gpio_config[BS365_GPIO_NUM_PORTS][U300_GPIO_PINS_PER_PORT] = { + /* Port 0, pins 0-7 */ + { + U300_FLOATING_INPUT, + U300_OUTPUT_LOW, + U300_FLOATING_INPUT, + U300_OUTPUT_LOW, + U300_OUTPUT_LOW, + U300_OUTPUT_LOW, + U300_PULL_UP_INPUT, + U300_FLOATING_INPUT, + }, + /* Port 1, pins 0-7 */ + { + U300_OUTPUT_LOW, + U300_FLOATING_INPUT, + U300_OUTPUT_LOW, + U300_FLOATING_INPUT, + U300_FLOATING_INPUT, + U300_OUTPUT_HIGH, + U300_OUTPUT_LOW, + U300_OUTPUT_LOW, + }, + /* Port 2, pins 0-7 */ + { + U300_FLOATING_INPUT, + U300_PULL_UP_INPUT, + U300_OUTPUT_LOW, + U300_OUTPUT_LOW, + U300_PULL_UP_INPUT, + U300_PULL_UP_INPUT, + U300_PULL_UP_INPUT, + U300_PULL_UP_INPUT, + }, + /* Port 3, pins 0-7 */ + { + U300_PULL_UP_INPUT, + U300_PULL_UP_INPUT, + U300_PULL_UP_INPUT, + U300_PULL_UP_INPUT, + U300_PULL_UP_INPUT, + U300_PULL_UP_INPUT, + U300_PULL_UP_INPUT, + U300_PULL_UP_INPUT, + }, + /* Port 4, pins 0-7 */ + { + U300_PULL_UP_INPUT, + U300_PULL_UP_INPUT, + U300_PULL_UP_INPUT, + U300_PULL_UP_INPUT, + /* These 4 pins doesn't exist on DB3210 */ + U300_OUTPUT_LOW, + U300_OUTPUT_LOW, + U300_OUTPUT_LOW, + U300_OUTPUT_LOW, + } +}; + +/** + * to_u300_gpio() - get the pointer to u300_gpio + * @chip: the gpio chip member of the structure u300_gpio + */ +static inline struct u300_gpio *to_u300_gpio(struct gpio_chip *chip) +{ + return container_of(chip, struct u300_gpio, chip); +} + +static int u300_gpio_get(struct gpio_chip *chip, unsigned offset) +{ + struct u300_gpio *gpio = to_u300_gpio(chip); + + return readl(U300_PIN_REG(offset, dir)) & U300_PIN_BIT(offset); +} + +static void u300_gpio_set(struct gpio_chip *chip, unsigned offset, int value) +{ + struct u300_gpio *gpio = to_u300_gpio(chip); + unsigned long flags; + u32 val; + + local_irq_save(flags); + + val = readl(U300_PIN_REG(offset, dor)); + if (value) + writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, dor)); + else + writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, dor)); + + local_irq_restore(flags); +} + +static int u300_gpio_direction_input(struct gpio_chip *chip, unsigned offset) +{ + struct u300_gpio *gpio = to_u300_gpio(chip); + unsigned long flags; + u32 val; + + local_irq_save(flags); + val = readl(U300_PIN_REG(offset, pcr)); + /* Mask out this pin, note 2 bits per setting */ + val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << ((offset & 0x07) << 1)); + writel(val, U300_PIN_REG(offset, pcr)); + local_irq_restore(flags); + return 0; +} + +static int u300_gpio_direction_output(struct gpio_chip *chip, unsigned offset, + int value) +{ + struct u300_gpio *gpio = to_u300_gpio(chip); + unsigned long flags; + u32 oldmode; + u32 val; + + local_irq_save(flags); + val = readl(U300_PIN_REG(offset, pcr)); + /* + * Drive mode must be set by the special mode set function, set + * push/pull mode by default if no mode has been selected. + */ + oldmode = val & (U300_GPIO_PXPCR_PIN_MODE_MASK << + ((offset & 0x07) << 1)); + /* mode = 0 means input, else some mode is already set */ + if (oldmode == 0) { + val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK << + ((offset & 0x07) << 1)); + val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL + << ((offset & 0x07) << 1)); + writel(val, U300_PIN_REG(offset, pcr)); + } + u300_gpio_set(chip, offset, value); + local_irq_restore(flags); + return 0; +} + +static int u300_gpio_to_irq(struct gpio_chip *chip, unsigned offset) +{ + struct u300_gpio *gpio = to_u300_gpio(chip); + int retirq = gpio->irq_base + offset; + + dev_dbg(gpio->dev, "request IRQ for GPIO %d, return %d\n", offset, + retirq); + return retirq; +} + +static int u300_gpio_config(struct gpio_chip *chip, unsigned offset, + u16 param, unsigned long *data) +{ + struct u300_gpio *gpio = to_u300_gpio(chip); + unsigned long flags; + u32 val; + + local_irq_save(flags); + switch (param) { + case GPIO_U300_CONFIG_BIAS_UNKNOWN: + case GPIO_U300_CONFIG_BIAS_FLOAT: + 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: + 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: + val = readl(U300_PIN_REG(offset, pcr)); + val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK + << ((offset & 0x07) << 1)); + val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_PUSH_PULL + << ((offset & 0x07) << 1)); + writel(val, U300_PIN_REG(offset, pcr)); + break; + case GPIO_U300_CONFIG_DRIVE_OPEN_DRAIN: + val = readl(U300_PIN_REG(offset, pcr)); + val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK + << ((offset & 0x07) << 1)); + val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_DRAIN + << ((offset & 0x07) << 1)); + writel(val, U300_PIN_REG(offset, pcr)); + break; + case GPIO_U300_CONFIG_DRIVE_OPEN_SOURCE: + val = readl(U300_PIN_REG(offset, pcr)); + val &= ~(U300_GPIO_PXPCR_PIN_MODE_MASK + << ((offset & 0x07) << 1)); + val |= (U300_GPIO_PXPCR_PIN_MODE_OUTPUT_OPEN_SOURCE + << ((offset & 0x07) << 1)); + writel(val, U300_PIN_REG(offset, pcr)); + break; + default: + local_irq_restore(flags); + dev_err(gpio->dev, "illegal configuration requested\n"); + return -EINVAL; + } + local_irq_restore(flags); + return 0; +} + +static struct gpio_chip u300_gpio_chip = { + .label = "u300-gpio-chip", + .owner = THIS_MODULE, + .get = u300_gpio_get, + .set = u300_gpio_set, + .direction_input = u300_gpio_direction_input, + .direction_output = u300_gpio_direction_output, + .to_irq = u300_gpio_to_irq, +}; + +static void u300_toggle_trigger(struct u300_gpio *gpio, unsigned offset) +{ + u32 val; + + val = readl(U300_PIN_REG(offset, icr)); + /* Set mode depending on state */ + if (u300_gpio_get(&gpio->chip, offset)) { + /* High now, let's trigger on falling edge next then */ + writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); + dev_dbg(gpio->dev, "next IRQ on falling edge on pin %d\n", + offset); + } else { + /* Low now, let's trigger on rising edge next then */ + writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); + dev_dbg(gpio->dev, "next IRQ on rising edge on pin %d\n", + offset); + } +} + +static int u300_gpio_irq_type(struct irq_data *d, unsigned trigger) +{ + struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); + struct u300_gpio *gpio = port->gpio; + int offset = d->irq - gpio->irq_base; + u32 val; + + if ((trigger & IRQF_TRIGGER_RISING) && + (trigger & IRQF_TRIGGER_FALLING)) { + /* + * The GPIO block can only trigger on falling OR rising edges, + * not both. So we need to toggle the mode whenever the pin + * goes from one state to the other with a special state flag + */ + dev_dbg(gpio->dev, + "trigger on both rising and falling edge on pin %d\n", + offset); + port->toggle_edge_mode |= U300_PIN_BIT(offset); + u300_toggle_trigger(gpio, offset); + } else if (trigger & IRQF_TRIGGER_RISING) { + dev_dbg(gpio->dev, "trigger on rising edge on pin %d\n", + offset); + val = readl(U300_PIN_REG(offset, icr)); + writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); + port->toggle_edge_mode &= ~U300_PIN_BIT(offset); + } else if (trigger & IRQF_TRIGGER_FALLING) { + dev_dbg(gpio->dev, "trigger on falling edge on pin %d\n", + offset); + val = readl(U300_PIN_REG(offset, icr)); + writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, icr)); + port->toggle_edge_mode &= ~U300_PIN_BIT(offset); + } + + return 0; +} + +static void u300_gpio_irq_enable(struct irq_data *d) +{ + struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); + struct u300_gpio *gpio = port->gpio; + int offset = d->irq - gpio->irq_base; + u32 val; + unsigned long flags; + + local_irq_save(flags); + val = readl(U300_PIN_REG(offset, ien)); + writel(val | U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); + local_irq_restore(flags); +} + +static void u300_gpio_irq_disable(struct irq_data *d) +{ + struct u300_gpio_port *port = irq_data_get_irq_chip_data(d); + struct u300_gpio *gpio = port->gpio; + int offset = d->irq - gpio->irq_base; + u32 val; + unsigned long flags; + + local_irq_save(flags); + val = readl(U300_PIN_REG(offset, ien)); + writel(val & ~U300_PIN_BIT(offset), U300_PIN_REG(offset, ien)); + local_irq_restore(flags); +} + +static struct irq_chip u300_gpio_irqchip = { + .name = "u300-gpio-irqchip", + .irq_enable = u300_gpio_irq_enable, + .irq_disable = u300_gpio_irq_disable, + .irq_set_type = u300_gpio_irq_type, + +}; + +static void u300_gpio_irq_handler(unsigned irq, struct irq_desc *desc) +{ + struct u300_gpio_port *port = irq_get_handler_data(irq); + struct u300_gpio *gpio = port->gpio; + int pinoffset = port->number << 3; /* get the right stride */ + unsigned long val; + + desc->irq_data.chip->irq_ack(&desc->irq_data); + /* Read event register */ + val = readl(U300_PIN_REG(pinoffset, iev)); + /* Mask relevant bits */ + val &= 0xFFU; /* 8 bits per port */ + /* ACK IRQ (clear event) */ + writel(val, U300_PIN_REG(pinoffset, iev)); + + /* Call IRQ handler */ + if (val != 0) { + int irqoffset; + + for_each_set_bit(irqoffset, &val, U300_GPIO_PINS_PER_PORT) { + int pin_irq = gpio->irq_base + (port->number << 3) + + irqoffset; + int offset = pinoffset + irqoffset; + + dev_dbg(gpio->dev, "GPIO IRQ %d on pin %d\n", + pin_irq, offset); + generic_handle_irq(pin_irq); + /* + * Triggering IRQ on both rising and falling edge + * needs mockery + */ + if (port->toggle_edge_mode & U300_PIN_BIT(offset)) + u300_toggle_trigger(gpio, offset); + } + } + + desc->irq_data.chip->irq_unmask(&desc->irq_data); +} + +static void __init u300_gpio_init_pin(struct u300_gpio *gpio, + int offset, + const struct u300_gpio_confdata *conf) +{ + /* Set mode: input or output */ + if (conf->output) { + u300_gpio_direction_output(&gpio->chip, offset, conf->outval); + + /* Deactivate bias mode for output */ + u300_gpio_config(&gpio->chip, offset, + GPIO_U300_CONFIG_BIAS_FLOAT, + NULL); + + /* Set drive mode for output */ + u300_gpio_config(&gpio->chip, offset, + GPIO_U300_CONFIG_DRIVE_PUSH_PULL, NULL); + + dev_dbg(gpio->dev, "set up pin %d as output, value: %d\n", + offset, conf->outval); + } else { + u300_gpio_direction_input(&gpio->chip, offset); + + /* Always set output low on input pins */ + u300_gpio_set(&gpio->chip, offset, 0); + + /* Set bias mode for input */ + u300_gpio_config(&gpio->chip, offset, conf->bias_mode, NULL); + + dev_dbg(gpio->dev, "set up pin %d as input, bias: %04x\n", + offset, conf->bias_mode); + } +} + +static void __init u300_gpio_init_coh901571(struct u300_gpio *gpio, + struct u300_gpio_platform *plat) +{ + int i, j; + + /* Write default config and values to all pins */ + for (i = 0; i < plat->ports; i++) { + for (j = 0; j < 8; j++) { + const struct u300_gpio_confdata *conf; + int offset = (i*8) + j; + + if (plat->variant == U300_GPIO_COH901571_3_BS335) + conf = &bs335_gpio_config[i][j]; + else if (plat->variant == U300_GPIO_COH901571_3_BS365) + conf = &bs365_gpio_config[i][j]; + else + break; + + u300_gpio_init_pin(gpio, offset, conf); + } + } +} + +static inline void u300_gpio_free_ports(struct u300_gpio *gpio) +{ + struct u300_gpio_port *port; + struct list_head *p, *n; + + 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); + } +} + +static int __init u300_gpio_probe(struct platform_device *pdev) +{ + struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); + struct u300_gpio *gpio; + int err = 0; + int portno; + u32 val; + u32 ifr; + int i; + + gpio = kzalloc(sizeof(struct u300_gpio), GFP_KERNEL); + if (gpio == NULL) { + dev_err(&pdev->dev, "failed to allocate memory\n"); + return -ENOMEM; + } + + gpio->chip = u300_gpio_chip; + gpio->chip.ngpio = plat->ports * U300_GPIO_PINS_PER_PORT; + gpio->irq_base = plat->gpio_irq_base; + gpio->chip.dev = &pdev->dev; + gpio->chip.base = plat->gpio_base; + gpio->dev = &pdev->dev; + + /* Get GPIO clock */ + gpio->clk = clk_get(gpio->dev, NULL); + if (IS_ERR(gpio->clk)) { + err = PTR_ERR(gpio->clk); + dev_err(gpio->dev, "could not get GPIO clock\n"); + goto err_no_clk; + } + err = clk_enable(gpio->clk); + if (err) { + dev_err(gpio->dev, "could not enable GPIO clock\n"); + goto err_no_clk_enable; + } + + gpio->memres = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!gpio->memres) { + dev_err(gpio->dev, "could not get GPIO memory resource\n"); + err = -ENODEV; + goto err_no_resource; + } + + if (!request_mem_region(gpio->memres->start, + resource_size(gpio->memres), + "GPIO Controller")) { + err = -ENODEV; + goto err_no_ioregion; + } + + gpio->base = ioremap(gpio->memres->start, resource_size(gpio->memres)); + if (!gpio->base) { + err = -ENOMEM; + goto err_no_ioremap; + } + + if (plat->variant == U300_GPIO_COH901335) { + dev_info(gpio->dev, + "initializing GPIO Controller COH 901 335\n"); + gpio->stride = U300_335_PORT_STRIDE; + gpio->pcr = U300_335_PXPCR; + gpio->dor = U300_335_PXPDOR; + gpio->dir = U300_335_PXPDIR; + gpio->per = U300_335_PXPER; + gpio->icr = U300_335_PXICR; + gpio->ien = U300_335_PXIEN; + gpio->iev = U300_335_PXIEV; + ifr = U300_335_PXIFR; + + /* Turn on the GPIO block */ + writel(U300_335_CR_BLOCK_CLOCK_ENABLE, + gpio->base + U300_335_CR); + } else if (plat->variant == U300_GPIO_COH901571_3_BS335 || + plat->variant == U300_GPIO_COH901571_3_BS365) { + dev_info(gpio->dev, + "initializing GPIO Controller COH 901 571/3\n"); + gpio->stride = U300_571_PORT_STRIDE; + gpio->pcr = U300_571_PXPCR; + gpio->dor = U300_571_PXPDOR; + gpio->dir = U300_571_PXPDIR; + gpio->per = U300_571_PXPER; + gpio->icr = U300_571_PXICR; + gpio->ien = U300_571_PXIEN; + gpio->iev = U300_571_PXIEV; + ifr = U300_571_PXIFR; + + val = readl(gpio->base + U300_571_CR); + dev_info(gpio->dev, "COH901571/3 block version: %d, " \ + "number of cores: %d totalling %d pins\n", + ((val & 0x000001FC) >> 2), + ((val & 0x0000FE00) >> 9), + ((val & 0x0000FE00) >> 9) * 8); + writel(U300_571_CR_BLOCK_CLKRQ_ENABLE, + gpio->base + U300_571_CR); + u300_gpio_init_coh901571(gpio, plat); + } else { + dev_err(gpio->dev, "unknown block variant\n"); + err = -ENODEV; + goto err_unknown_variant; + } + + /* Add each port with its IRQ separately */ + INIT_LIST_HEAD(&gpio->port_list); + for (portno = 0 ; portno < plat->ports; portno++) { + struct u300_gpio_port *port = + kmalloc(sizeof(struct u300_gpio_port), GFP_KERNEL); + + if (!port) { + dev_err(gpio->dev, "out of memory\n"); + err = -ENOMEM; + goto err_no_port; + } + + snprintf(port->name, 8, "gpio%d", portno); + port->number = portno; + port->gpio = gpio; + + port->irq = platform_get_irq_byname(pdev, + port->name); + + dev_dbg(gpio->dev, "register IRQ %d for %s\n", port->irq, + port->name); + + irq_set_chained_handler(port->irq, u300_gpio_irq_handler); + irq_set_handler_data(port->irq, port); + + /* For each GPIO pin set the unique IRQ handler */ + for (i = 0; i < U300_GPIO_PINS_PER_PORT; i++) { + int irqno = gpio->irq_base + (portno << 3) + i; + + dev_dbg(gpio->dev, "handler for IRQ %d on %s\n", + irqno, port->name); + irq_set_chip_and_handler(irqno, &u300_gpio_irqchip, + handle_simple_irq); + set_irq_flags(irqno, IRQF_VALID); + irq_set_chip_data(irqno, port); + } + + /* Turns off irq force (test register) for this port */ + writel(0x0, gpio->base + portno * gpio->stride + ifr); + + list_add_tail(&port->node, &gpio->port_list); + } + dev_dbg(gpio->dev, "initialized %d GPIO ports\n", portno); + + err = gpiochip_add(&gpio->chip); + if (err) { + dev_err(gpio->dev, "unable to add gpiochip: %d\n", err); + goto err_no_chip; + } + + platform_set_drvdata(pdev, gpio); + + return 0; + +err_no_chip: +err_no_port: + u300_gpio_free_ports(gpio); +err_unknown_variant: + iounmap(gpio->base); +err_no_ioremap: + release_mem_region(gpio->memres->start, resource_size(gpio->memres)); +err_no_ioregion: +err_no_resource: + clk_disable(gpio->clk); +err_no_clk_enable: + clk_put(gpio->clk); +err_no_clk: + kfree(gpio); + dev_info(&pdev->dev, "module ERROR:%d\n", err); + return err; +} + +static int __exit u300_gpio_remove(struct platform_device *pdev) +{ + struct u300_gpio_platform *plat = dev_get_platdata(&pdev->dev); + struct u300_gpio *gpio = platform_get_drvdata(pdev); + int err; + + /* Turn off the GPIO block */ + if (plat->variant == U300_GPIO_COH901335) + writel(0x00000000U, gpio->base + U300_335_CR); + if (plat->variant == U300_GPIO_COH901571_3_BS335 || + plat->variant == U300_GPIO_COH901571_3_BS365) + writel(0x00000000U, gpio->base + U300_571_CR); + + err = gpiochip_remove(&gpio->chip); + if (err < 0) { + dev_err(gpio->dev, "unable to remove gpiochip: %d\n", err); + return err; + } + u300_gpio_free_ports(gpio); + iounmap(gpio->base); + release_mem_region(gpio->memres->start, + resource_size(gpio->memres)); + clk_disable(gpio->clk); + clk_put(gpio->clk); + platform_set_drvdata(pdev, NULL); + kfree(gpio); + return 0; +} + +static struct platform_driver u300_gpio_driver = { + .driver = { + .name = "u300-gpio", + }, + .remove = __exit_p(u300_gpio_remove), +}; + + +static int __init u300_gpio_init(void) +{ + return platform_driver_probe(&u300_gpio_driver, u300_gpio_probe); +} + +static void __exit u300_gpio_exit(void) +{ + platform_driver_unregister(&u300_gpio_driver); +} + +arch_initcall(u300_gpio_init); +module_exit(u300_gpio_exit); + +MODULE_AUTHOR("Linus Walleij "); +MODULE_DESCRIPTION("ST-Ericsson AB COH 901 335/COH 901 571/3 GPIO driver"); +MODULE_LICENSE("GPL"); -- cgit v1.1 From f812f0f53e5643c06b929ce3299cbaffb307c488 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 16 Nov 2011 10:23:05 +0100 Subject: pinctrl: u300-pinmux: register proper GPIO ranges This register the actual GPIO ranges used by the COH901XXX GPIO driver. Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux-u300.c | 40 +++++++++++++++++++++++++++++----------- 1 file changed, 29 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinmux-u300.c b/drivers/pinctrl/pinmux-u300.c index bcf61be..7e89b36 100644 --- a/drivers/pinctrl/pinmux-u300.c +++ b/drivers/pinctrl/pinmux-u300.c @@ -1019,15 +1019,29 @@ static struct pinmux_ops u300_pmx_ops = { }; /* - * FIXME: this will be set to sane values as this driver engulfs - * drivers/gpio/gpio-u300.c and we really know this stuff. + * GPIO ranges handled by the application-side COH901XXX GPIO controller + * Very many pins can be converted into GPIO pins, but we only list those + * that are useful in practice to cut down on tables. */ -static struct pinctrl_gpio_range u300_gpio_range = { - .name = "COH901*", - .id = 0, - .base = 0, - .pin_base = 0, - .npins = 64, +#define U300_GPIO_RANGE(a, b, c) { .name = "COH901XXX", .id = a, .base= a, \ + .pin_base = b, .npins = c } + +static struct pinctrl_gpio_range u300_gpio_ranges[] = { + U300_GPIO_RANGE(10, 426, 1), + U300_GPIO_RANGE(11, 180, 1), + U300_GPIO_RANGE(12, 165, 1), /* MS/MMC card insertion */ + U300_GPIO_RANGE(13, 179, 1), + U300_GPIO_RANGE(14, 178, 1), + U300_GPIO_RANGE(16, 194, 1), + U300_GPIO_RANGE(17, 193, 1), + U300_GPIO_RANGE(18, 192, 1), + U300_GPIO_RANGE(19, 191, 1), + U300_GPIO_RANGE(20, 186, 1), + U300_GPIO_RANGE(21, 185, 1), + U300_GPIO_RANGE(22, 184, 1), + U300_GPIO_RANGE(23, 183, 1), + U300_GPIO_RANGE(24, 182, 1), + U300_GPIO_RANGE(25, 181, 1), }; static struct pinctrl_desc u300_pmx_desc = { @@ -1042,9 +1056,10 @@ static struct pinctrl_desc u300_pmx_desc = { static int __init u300_pmx_probe(struct platform_device *pdev) { - int ret; struct u300_pmx *upmx; struct resource *res; + int ret; + int i; /* Create state holders etc for this driver */ upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL); @@ -1081,7 +1096,8 @@ static int __init u300_pmx_probe(struct platform_device *pdev) } /* We will handle a range of GPIO pins */ - pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_range); + for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) + pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]); platform_set_drvdata(pdev, upmx); @@ -1103,8 +1119,10 @@ out_no_resource: static int __exit u300_pmx_remove(struct platform_device *pdev) { struct u300_pmx *upmx = platform_get_drvdata(pdev); + int i; - pinctrl_remove_gpio_range(upmx->pctl, &u300_gpio_range); + for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) + pinctrl_remove_gpio_range(upmx->pctl, &u300_gpio_ranges[i]); pinctrl_unregister(upmx->pctl); iounmap(upmx->virtbase); release_mem_region(upmx->phybase, upmx->physize); -- cgit v1.1 From b4e3ac74d5cd4152f2ec6b3280b1ff3428952f7f Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 16 Nov 2011 10:24:39 +0100 Subject: pinctrl/coh901: driver to request its pins This makes the COH 901 driver request muxing of its GPIO pins from the pinmux-u300 driver using the standard API calls. Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 2 +- drivers/pinctrl/pinctrl-coh901.c | 21 +++++++++++++++++++++ 2 files changed, 22 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index e087f02..e963da4 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -32,7 +32,7 @@ config PINMUX_U300 config PINCTRL_COH901 bool "ST-Ericsson U300 COH 901 335/571 GPIO" - depends on GPIOLIB && ARCH_U300 + depends on GPIOLIB && ARCH_U300 && PINMUX_U300 help Say yes here to support GPIO interface on ST-Ericsson U300. The names of the two IP block variants supported are diff --git a/drivers/pinctrl/pinctrl-coh901.c b/drivers/pinctrl/pinctrl-coh901.c index 4035778..69fb707 100644 --- a/drivers/pinctrl/pinctrl-coh901.c +++ b/drivers/pinctrl/pinctrl-coh901.c @@ -22,6 +22,7 @@ #include #include #include +#include #include /* @@ -351,6 +352,24 @@ static inline struct u300_gpio *to_u300_gpio(struct gpio_chip *chip) return container_of(chip, struct u300_gpio, chip); } +static int u300_gpio_request(struct gpio_chip *chip, unsigned offset) +{ + /* + * Map back to global GPIO space and request muxing, the direction + * parameter does not matter for this controller. + */ + int gpio = chip->base + offset; + + return pinmux_request_gpio(gpio); +} + +static void u300_gpio_free(struct gpio_chip *chip, unsigned offset) +{ + int gpio = chip->base + offset; + + pinmux_free_gpio(gpio); +} + static int u300_gpio_get(struct gpio_chip *chip, unsigned offset) { struct u300_gpio *gpio = to_u300_gpio(chip); @@ -483,6 +502,8 @@ static int u300_gpio_config(struct gpio_chip *chip, unsigned offset, static struct gpio_chip u300_gpio_chip = { .label = "u300-gpio-chip", .owner = THIS_MODULE, + .request = u300_gpio_request, + .free = u300_gpio_free, .get = u300_gpio_get, .set = u300_gpio_set, .direction_input = u300_gpio_direction_input, -- cgit v1.1 From ae6b4d8588f4fc95520b0e62c4b1f474c82191a9 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 19 Oct 2011 18:14:33 +0200 Subject: pinctrl: add a pin config interface This add per-pin and per-group pin config interfaces for biasing, driving and other such electronic properties. The details of passed configurations are passed in an opaque unsigned long which may be dereferences to integer types, structs or lists on either side of the configuration interface. ChangeLog v1->v2: - Clear split of terminology: we now have pin controllers, and those may support two interfaces using vtables: pin multiplexing and pin configuration. - Break out pin configuration to its own C file, controllers may implement only config without mux, and vice versa, so keep each sub-functionality of pin controllers separate. Introduce CONFIG_PINCONF in Kconfig. - Implement some core logic around pin configuration in the pinconf.c file. - Remove UNKNOWN config states, these were just surplus baggage. - Remove FLOAT config state - HIGH_IMPEDANCE should be enough for everyone. - PIN_CONFIG_POWER_SOURCE added to handle switching the power supply for the pin logic between different sources - Explicit DISABLE config enums to turn schmitt-trigger, wakeup etc OFF. - Update documentation to reflect all the recent reasoning. ChangeLog v2->v3: - Twist API around to pass around arrays of config tuples instead of (param, value) pairs everywhere. - Explicit drive strength semantics for push/pull and similar drive modes, this shall be the number of drive stages vs nominal load impedance, which should match the actual electronics used in push/pull CMOS or TTY totempoles. - Drop load capacitance configuration - I probably don't know what I'm doing here so leave it out. - Drop PIN_CONFIG_INPUT_SCHMITT_OFF, instead the argument zero to PIN_CONFIG_INPUT_SCHMITT turns schmitt trigger off. - Drop PIN_CONFIG_NORMAL_POWER_MODE and have a well defined argument to PIN_CONFIG_LOW_POWER_MODE to get out of it instead. - Drop PIN_CONFIG_WAKEUP_ENABLE/DISABLE and just use PIN_CONFIG_WAKEUP with defined value zero to turn wakeup off. - Add PIN_CONFIG_INPUT_DEBOUNCE for configuring debounce time on input lines. - Fix a bug when we tried to configure pins for pin controllers without pinconf support. - Initialized debugfs properly so it works. - Initialize the mutex properly and lock around config tampering sections. - Check the return value from get_initial_config() properly. ChangeLog v3->v4: - Export the pin_config_get(), pin_config_set() and pin_config_group() functions. - Drop the entire concept of just getting initial config and keeping track of pin states internally, instead ask the pins what state they are in. Previous idea was plain wrong, if the device cannot keep track of its state, the driver should do it. - Drop the generic configuration layout, it seems this impose too much restriction on some pin controllers, so let them do things the way they want and split off support for generic config as an optional add-on. ChangeLog v4->v5: - Introduce two symmetric driver calls for group configuration, .pin_config_group_[get|set] and corresponding external calls. - Remove generic semantic meanings of return values from config calls, these belong in the generic config patch. Just pass the return value through instead. - Add a debugfs entry "pinconf-groups" to read status from group configuration only, also slam in a per-group debug callback in the pinconf_ops so custom drivers can display something meaningful for their pins. - Fix some dangling newline. - Drop dangling #else clause. - Update documentation to match the above. ChangeLog v5->v6: - Change to using a pin name as parameter for the [get|set]_config() functions, as suggested by Stephen Warren. This is more natural as names will be what a developer has access to in written documentation etc. ChangeLog v6->v7: - Refactor out by-pin and by-name get/set functions, only expose the by-name functions externally, expose the by-pin functions internally. - Show supported pin control functionality in the debugfs pinctrl-devices file. Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 5 +- drivers/pinctrl/Makefile | 1 + drivers/pinctrl/core.c | 43 ++++++- drivers/pinctrl/core.h | 5 + drivers/pinctrl/pinconf.c | 302 ++++++++++++++++++++++++++++++++++++++++++++++ drivers/pinctrl/pinconf.h | 36 ++++++ 6 files changed, 390 insertions(+), 2 deletions(-) create mode 100644 drivers/pinctrl/pinconf.c create mode 100644 drivers/pinctrl/pinconf.h (limited to 'drivers') diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index e963da4..c63c721 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -12,7 +12,10 @@ menu "Pin controllers" depends on PINCTRL config PINMUX - bool "Support pinmux controllers" + bool "Support pin multiplexing controllers" + +config PINCONF + bool "Support pin configuration controllers" config DEBUG_PINCTRL bool "Debug PINCTRL calls" diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 5f3e4d6..c046f78 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -4,6 +4,7 @@ ccflags-$(CONFIG_DEBUG_PINCTRL) += -DDEBUG obj-$(CONFIG_PINCTRL) += core.o obj-$(CONFIG_PINMUX) += pinmux.o +obj-$(CONFIG_PINCONF) += pinconf.o obj-$(CONFIG_PINMUX_SIRF) += pinmux-sirf.o obj-$(CONFIG_PINMUX_U300) += pinmux-u300.o obj-$(CONFIG_PINCTRL_COH901) += pinctrl-coh901.o diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 4955a68..034b1ad 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -28,6 +28,7 @@ #include #include "core.h" #include "pinmux.h" +#include "pinconf.h" /* Global list of pin control devices */ static DEFINE_MUTEX(pinctrldev_list_mutex); @@ -101,6 +102,30 @@ struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin) } /** + * pin_get_from_name() - look up a pin number from a name + * @pctldev: the pin control device to lookup the pin on + * @name: the name of the pin to look up + */ +int pin_get_from_name(struct pinctrl_dev *pctldev, const char *name) +{ + unsigned pin; + + /* The highest pin number need to be included in the loop, thus <= */ + for (pin = 0; pin <= pctldev->desc->maxpin; pin++) { + struct pin_desc *desc; + + desc = pin_desc_get(pctldev, pin); + /* Pin space may be sparse */ + if (desc == NULL) + continue; + if (desc->name && !strcmp(name, desc->name)) + return pin; + } + + return -EINVAL; +} + +/** * pin_is_valid() - check if pin exists on controller * @pctldev: the pin control device to check the pin on * @pin: pin to check, use the local pin controller index number @@ -160,6 +185,7 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, pindesc = kzalloc(sizeof(*pindesc), GFP_KERNEL); if (pindesc == NULL) return -ENOMEM; + spin_lock_init(&pindesc->lock); /* Set owner */ @@ -409,11 +435,15 @@ static int pinctrl_devices_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev; - seq_puts(s, "name [pinmux]\n"); + seq_puts(s, "name [pinmux] [pinconf]\n"); mutex_lock(&pinctrldev_list_mutex); list_for_each_entry(pctldev, &pinctrldev_list, node) { seq_printf(s, "%s ", pctldev->desc->name); if (pctldev->desc->pmxops) + seq_puts(s, "yes "); + else + seq_puts(s, "no "); + if (pctldev->desc->confops) seq_puts(s, "yes"); else seq_puts(s, "no"); @@ -492,6 +522,7 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) debugfs_create_file("gpio-ranges", S_IFREG | S_IRUGO, device_root, pctldev, &pinctrl_gpioranges_ops); pinmux_init_device_debugfs(device_root, pctldev); + pinconf_init_device_debugfs(device_root, pctldev); } static void pinctrl_init_debugfs(void) @@ -548,6 +579,16 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, } } + /* If we're implementing pinconfig, check the ops for sanity */ + if (pctldesc->confops) { + ret = pinconf_check_ops(pctldesc->confops); + if (ret) { + pr_err("%s pin config ops lacks necessary functions\n", + pctldesc->name); + return NULL; + } + } + pctldev = kzalloc(sizeof(struct pinctrl_dev), GFP_KERNEL); if (pctldev == NULL) return NULL; diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 74dee43..3f5b911 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -9,6 +9,10 @@ * License terms: GNU General Public License (GPL) version 2 */ +#include + +struct pinctrl_gpio_range; + /** * struct pinctrl_dev - pin control class device * @node: node to include this pin controller in the global pin controller list @@ -66,6 +70,7 @@ struct pin_desc { struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, const char *dev_name); struct pin_desc *pin_desc_get(struct pinctrl_dev *pctldev, unsigned int pin); +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); diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c new file mode 100644 index 0000000..9195eef --- /dev/null +++ b/drivers/pinctrl/pinconf.c @@ -0,0 +1,302 @@ +/* + * Core driver for the 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) "pinconfig core: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "core.h" +#include "pinconf.h" + +int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, + unsigned long *config) +{ + const struct pinconf_ops *ops = pctldev->desc->confops; + + if (!ops || !ops->pin_config_get) { + dev_err(&pctldev->dev, "cannot get pin configuration, missing " + "pin_config_get() function in driver\n"); + return -EINVAL; + } + + return ops->pin_config_get(pctldev, pin, config); +} + +/** + * pin_config_get() - get the configuration of a single pin parameter + * @pctldev: pin controller device for this pin + * @name: name of the pin to get the config for + * @config: the config pointed to by this argument will be filled in with the + * current pin state, it can be used directly by drivers as a numeral, or + * it can be dereferenced to any struct. + */ +int pin_config_get(struct pinctrl_dev *pctldev, const char *name, + unsigned long *config) +{ + int pin; + + pin = pin_get_from_name(pctldev, name); + if (pin < 0) + return pin; + + return pin_config_get_for_pin(pctldev, pin, config); +} +EXPORT_SYMBOL(pin_config_get); + +int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin, + unsigned long config) +{ + const struct pinconf_ops *ops = pctldev->desc->confops; + int ret; + + if (!ops || !ops->pin_config_set) { + dev_err(&pctldev->dev, "cannot configure pin, missing " + "config function in driver\n"); + return -EINVAL; + } + + ret = ops->pin_config_set(pctldev, pin, config); + if (ret) { + dev_err(&pctldev->dev, + "unable to set pin configuration on pin %d\n", pin); + return ret; + } + + return 0; +} + +/** + * pin_config_set() - set the configuration of a single pin parameter + * @pctldev: pin controller device for this pin + * @name: name of the pin to set the config for + * @config: the config in this argument will contain the desired pin state, it + * can be used directly by drivers as a numeral, or it can be dereferenced + * to any struct. + */ +int pin_config_set(struct pinctrl_dev *pctldev, const char *name, + unsigned long config) +{ + int pin; + + pin = pin_get_from_name(pctldev, name); + if (pin < 0) + return pin; + + return pin_config_set_for_pin(pctldev, pin, config); +} +EXPORT_SYMBOL(pin_config_set); + +int pin_config_group_get(struct pinctrl_dev *pctldev, const char *pin_group, + unsigned long *config) +{ + const struct pinconf_ops *ops = pctldev->desc->confops; + int selector; + + 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; + } + + selector = pinctrl_get_group_selector(pctldev, pin_group); + if (selector < 0) + return selector; + + return ops->pin_config_group_get(pctldev, selector, config); +} +EXPORT_SYMBOL(pin_config_group_get); + + +int pin_config_group_set(struct pinctrl_dev *pctldev, const char *pin_group, + unsigned long config) +{ + const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; + const struct pinconf_ops *ops = pctldev->desc->confops; + int selector; + const unsigned *pins; + unsigned num_pins; + int ret; + int i; + + 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; + } + + selector = pinctrl_get_group_selector(pctldev, pin_group); + if (selector < 0) + return selector; + + 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; + } + + /* + * If the pin controller supports handling entire groups we use that + * capability. + */ + if (ops->pin_config_group_set) { + ret = ops->pin_config_group_set(pctldev, selector, config); + /* + * If the pin controller prefer that a certain group be handled + * pin-by-pin as well, it returns -EAGAIN. + */ + if (ret != -EAGAIN) + return ret; + } + + /* + * If the controller cannot handle entire groups, we configure each pin + * individually. + */ + if (!ops->pin_config_set) + return 0; + + for (i = 0; i < num_pins; i++) { + ret = ops->pin_config_set(pctldev, pins[i], config); + if (ret < 0) + return ret; + } + + return 0; +} +EXPORT_SYMBOL(pin_config_group_set); + +int pinconf_check_ops(const struct pinconf_ops *ops) +{ + /* 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, + struct seq_file *s, int pin) +{ + const struct pinconf_ops *ops = pctldev->desc->confops; + + if (ops && ops->pin_config_dbg_show) + ops->pin_config_dbg_show(pctldev, s, pin); +} + +static int pinconf_pins_show(struct seq_file *s, void *what) +{ + struct pinctrl_dev *pctldev = s->private; + unsigned pin; + + seq_puts(s, "Pin config settings per pin\n"); + seq_puts(s, "Format: pin (name): pinmux setting array\n"); + + /* The highest pin number need to be included in the loop, thus <= */ + for (pin = 0; pin <= pctldev->desc->maxpin; pin++) { + struct pin_desc *desc; + + desc = pin_desc_get(pctldev, pin); + /* Pin space may be sparse */ + if (desc == NULL) + continue; + + seq_printf(s, "pin %d (%s):", pin, + desc->name ? desc->name : "unnamed"); + + pinconf_dump_pin(pctldev, s, pin); + + seq_printf(s, "\n"); + } + + return 0; +} + +static void pinconf_dump_group(struct pinctrl_dev *pctldev, + struct seq_file *s, unsigned selector, + const char *gname) +{ + const struct pinconf_ops *ops = pctldev->desc->confops; + + if (ops && ops->pin_config_group_dbg_show) + ops->pin_config_group_dbg_show(pctldev, s, selector); +} + +static int pinconf_groups_show(struct seq_file *s, void *what) +{ + struct pinctrl_dev *pctldev = s->private; + const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; + const struct pinconf_ops *ops = pctldev->desc->confops; + unsigned selector = 0; + + if (!ops || !ops->pin_config_group_get) + return 0; + + seq_puts(s, "Pin config settings per pin group\n"); + seq_puts(s, "Format: group (name): pinmux setting array\n"); + + while (pctlops->list_groups(pctldev, selector) >= 0) { + const char *gname = pctlops->get_group_name(pctldev, selector); + + seq_printf(s, "%u (%s):", selector, gname); + pinconf_dump_group(pctldev, s, selector, gname); + selector++; + } + + return 0; +} + +static int pinconf_pins_open(struct inode *inode, struct file *file) +{ + return single_open(file, pinconf_pins_show, inode->i_private); +} + +static int pinconf_groups_open(struct inode *inode, struct file *file) +{ + return single_open(file, pinconf_groups_show, inode->i_private); +} + +static const struct file_operations pinconf_pins_ops = { + .open = pinconf_pins_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +static const struct file_operations pinconf_groups_ops = { + .open = pinconf_groups_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + +void pinconf_init_device_debugfs(struct dentry *devroot, + struct pinctrl_dev *pctldev) +{ + debugfs_create_file("pinconf-pins", S_IFREG | S_IRUGO, + devroot, pctldev, &pinconf_pins_ops); + debugfs_create_file("pinconf-groups", S_IFREG | S_IRUGO, + devroot, pctldev, &pinconf_groups_ops); +} + +#endif diff --git a/drivers/pinctrl/pinconf.h b/drivers/pinctrl/pinconf.h new file mode 100644 index 0000000..e7dc616 --- /dev/null +++ b/drivers/pinctrl/pinconf.h @@ -0,0 +1,36 @@ +/* + * Internal interface between the core pin control system and the + * pin config portions + * + * Copyright (C) 2011 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 + */ + +#ifdef CONFIG_PINCONF + +int pinconf_check_ops(const struct pinconf_ops *ops); +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 + +static inline int pinconf_check_ops(const struct pinconf_ops *ops) +{ + return 0; +} + +static inline void pinconf_init_device_debugfs(struct dentry *devroot, + struct pinctrl_dev *pctldev) +{ +} + +#endif -- cgit v1.1 From 51cd24ee625c348654114032499914d0311e5832 Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Fri, 9 Dec 2011 16:59:05 -0700 Subject: pinctrl: don't create a device for each pin controller Pin controllers should already be instantiated as a device, so there's no need for the pinctrl core to create a new struct device for each controller. This allows the controller's real name to be used in the mux mapping table, rather than e.g. "pinctrl.0", "pinctrl.1", etc. This necessitates removal of the PINMUX_MAP_PRIMARY*() macros, since their sole purpose was to hard-code the .ctrl_dev_name field to be "pinctrl.0". Signed-off-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 42 +++++++++++------------------------------- drivers/pinctrl/core.h | 2 +- drivers/pinctrl/pinconf.c | 12 ++++++------ drivers/pinctrl/pinmux.c | 46 +++++++++++++++++++++++----------------------- 4 files changed, 41 insertions(+), 61 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 034b1ad..160fb5a 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -34,12 +34,6 @@ static DEFINE_MUTEX(pinctrldev_list_mutex); static LIST_HEAD(pinctrldev_list); -static void pinctrl_dev_release(struct device *dev) -{ - struct pinctrl_dev *pctldev = dev_get_drvdata(dev); - kfree(pctldev); -} - const char *pinctrl_dev_get_name(struct pinctrl_dev *pctldev) { /* We're not allowed to register devices without name */ @@ -71,14 +65,14 @@ struct pinctrl_dev *get_pinctrl_dev_from_dev(struct device *dev, mutex_lock(&pinctrldev_list_mutex); list_for_each_entry(pctldev, &pinctrldev_list, node) { - if (dev && &pctldev->dev == dev) { + if (dev && pctldev->dev == dev) { /* Matched on device pointer */ found = true; break; } if (devname && - !strcmp(dev_name(&pctldev->dev), devname)) { + !strcmp(dev_name(pctldev->dev), devname)) { /* Matched on device name */ found = true; break; @@ -325,7 +319,7 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev, const char *gname = pctlops->get_group_name(pctldev, group_selector); if (!strcmp(gname, pin_group)) { - dev_dbg(&pctldev->dev, + dev_dbg(pctldev->dev, "found group selector %u for %s\n", group_selector, pin_group); @@ -335,7 +329,7 @@ int pinctrl_get_group_selector(struct pinctrl_dev *pctldev, group_selector++; } - dev_err(&pctldev->dev, "does not have pin group %s\n", + dev_err(pctldev->dev, "does not have pin group %s\n", pin_group); return -EINVAL; @@ -508,11 +502,11 @@ static void pinctrl_init_device_debugfs(struct pinctrl_dev *pctldev) { static struct dentry *device_root; - device_root = debugfs_create_dir(dev_name(&pctldev->dev), + device_root = debugfs_create_dir(dev_name(pctldev->dev), debugfs_root); if (IS_ERR(device_root) || !device_root) { pr_warn("failed to create debugfs directory for %s\n", - dev_name(&pctldev->dev)); + dev_name(pctldev->dev)); return; } debugfs_create_file("pins", S_IFREG | S_IRUGO, @@ -560,7 +554,6 @@ static void pinctrl_init_debugfs(void) struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, struct device *dev, void *driver_data) { - static atomic_t pinmux_no = ATOMIC_INIT(0); struct pinctrl_dev *pctldev; int ret; @@ -601,18 +594,7 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, spin_lock_init(&pctldev->pin_desc_tree_lock); INIT_LIST_HEAD(&pctldev->gpio_ranges); mutex_init(&pctldev->gpio_ranges_lock); - - /* Register device */ - pctldev->dev.parent = dev; - dev_set_name(&pctldev->dev, "pinctrl.%d", - atomic_inc_return(&pinmux_no) - 1); - pctldev->dev.release = pinctrl_dev_release; - ret = device_register(&pctldev->dev); - if (ret != 0) { - pr_err("error in device registration\n"); - goto out_reg_dev_err; - } - dev_set_drvdata(&pctldev->dev, pctldev); + pctldev->dev = dev; /* Register all the pins */ pr_debug("try to register %d pins on %s...\n", @@ -622,7 +604,7 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, pr_err("error during pin registration\n"); pinctrl_free_pindescs(pctldev, pctldesc->pins, pctldesc->npins); - goto out_reg_pins_err; + goto out_err; } pinctrl_init_device_debugfs(pctldev); @@ -632,10 +614,8 @@ struct pinctrl_dev *pinctrl_register(struct pinctrl_desc *pctldesc, pinmux_hog_maps(pctldev); return pctldev; -out_reg_pins_err: - device_del(&pctldev->dev); -out_reg_dev_err: - put_device(&pctldev->dev); +out_err: + kfree(pctldev); return NULL; } EXPORT_SYMBOL_GPL(pinctrl_register); @@ -659,7 +639,7 @@ void pinctrl_unregister(struct pinctrl_dev *pctldev) /* Destroy descriptor tree */ pinctrl_free_pindescs(pctldev, pctldev->desc->pins, pctldev->desc->npins); - device_unregister(&pctldev->dev); + kfree(pctldev); } EXPORT_SYMBOL_GPL(pinctrl_unregister); diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 3f5b911..53755825 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -38,7 +38,7 @@ struct pinctrl_dev { spinlock_t pin_desc_tree_lock; struct list_head gpio_ranges; struct mutex gpio_ranges_lock; - struct device dev; + struct device *dev; struct module *owner; void *driver_data; #ifdef CONFIG_PINMUX diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 9195eef..124762b 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -29,7 +29,7 @@ int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, const struct pinconf_ops *ops = pctldev->desc->confops; if (!ops || !ops->pin_config_get) { - dev_err(&pctldev->dev, "cannot get pin configuration, missing " + dev_err(pctldev->dev, "cannot get pin configuration, missing " "pin_config_get() function in driver\n"); return -EINVAL; } @@ -65,14 +65,14 @@ int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin, int ret; if (!ops || !ops->pin_config_set) { - dev_err(&pctldev->dev, "cannot configure pin, missing " + dev_err(pctldev->dev, "cannot configure pin, missing " "config function in driver\n"); return -EINVAL; } ret = ops->pin_config_set(pctldev, pin, config); if (ret) { - dev_err(&pctldev->dev, + dev_err(pctldev->dev, "unable to set pin configuration on pin %d\n", pin); return ret; } @@ -108,7 +108,7 @@ int pin_config_group_get(struct pinctrl_dev *pctldev, const char *pin_group, int selector; if (!ops || !ops->pin_config_group_get) { - dev_err(&pctldev->dev, "cannot get configuration for pin " + dev_err(pctldev->dev, "cannot get configuration for pin " "group, missing group config get function in " "driver\n"); return -EINVAL; @@ -135,7 +135,7 @@ int pin_config_group_set(struct pinctrl_dev *pctldev, const char *pin_group, int i; if (!ops || (!ops->pin_config_group_set && !ops->pin_config_set)) { - dev_err(&pctldev->dev, "cannot configure pin group, missing " + dev_err(pctldev->dev, "cannot configure pin group, missing " "config function in driver\n"); return -EINVAL; } @@ -146,7 +146,7 @@ int pin_config_group_set(struct pinctrl_dev *pctldev, const char *pin_group, ret = pctlops->get_group_pins(pctldev, selector, &pins, &num_pins); if (ret) { - dev_err(&pctldev->dev, "cannot configure pin group, error " + dev_err(pctldev->dev, "cannot configure pin group, error " "getting pins\n"); return ret; } diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index a11681b..3bcc641 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -106,24 +106,24 @@ static int pin_request(struct pinctrl_dev *pctldev, 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, function); desc = pin_desc_get(pctldev, pin); if (desc == NULL) { - dev_err(&pctldev->dev, + dev_err(pctldev->dev, "pin is not registered so it cannot be requested\n"); goto out; } if (!function) { - dev_err(&pctldev->dev, "no function name given\n"); + dev_err(pctldev->dev, "no function name given\n"); return -EINVAL; } spin_lock(&desc->lock); if (desc->mux_function) { spin_unlock(&desc->lock); - dev_err(&pctldev->dev, + dev_err(pctldev->dev, "pin already requested\n"); goto out; } @@ -132,7 +132,7 @@ static int pin_request(struct pinctrl_dev *pctldev, /* Let each pin increase references to this module */ if (!try_module_get(pctldev->owner)) { - dev_err(&pctldev->dev, + dev_err(pctldev->dev, "could not increase module refcount for pin %d\n", pin); status = -EINVAL; @@ -152,7 +152,7 @@ static int pin_request(struct pinctrl_dev *pctldev, status = 0; if (status) - dev_err(&pctldev->dev, "->request on device %s failed " + dev_err(pctldev->dev, "->request on device %s failed " "for pin %d\n", pctldev->desc->name, pin); out_free_pin: @@ -163,7 +163,7 @@ out_free_pin: } out: if (status) - dev_err(&pctldev->dev, "pin-%d (%s) status %d\n", + dev_err(pctldev->dev, "pin-%d (%s) status %d\n", pin, function ? : "?", status); return status; @@ -189,7 +189,7 @@ static const char *pin_free(struct pinctrl_dev *pctldev, int pin, desc = pin_desc_get(pctldev, pin); if (desc == NULL) { - dev_err(&pctldev->dev, + dev_err(pctldev->dev, "pin is not registered so it cannot be freed\n"); return NULL; } @@ -434,14 +434,14 @@ static int acquire_pins(struct pinctrl_dev *pctldev, if (ret) return ret; - dev_dbg(&pctldev->dev, "requesting the %u pins from group %u\n", + 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], func, NULL); if (ret) { - dev_err(&pctldev->dev, + dev_err(pctldev->dev, "could not get pin %d for function %s " "on device %s - conflicting mux mappings?\n", pins[i], func ? : "(undefined)", @@ -473,7 +473,7 @@ static void release_pins(struct pinctrl_dev *pctldev, ret = pctlops->get_group_pins(pctldev, group_selector, &pins, &num_pins); if (ret) { - dev_err(&pctldev->dev, "could not get pins to release for " + dev_err(pctldev->dev, "could not get pins to release for " "group selector %d\n", group_selector); return; @@ -525,7 +525,7 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, return -EINVAL; ret = pinctrl_get_group_selector(pctldev, groups[0]); if (ret < 0) { - dev_err(&pctldev->dev, + 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), @@ -534,7 +534,7 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, } if (num_groups > 1) - dev_dbg(&pctldev->dev, + 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), @@ -544,13 +544,13 @@ static int pinmux_check_pin_group(struct pinctrl_dev *pctldev, return ret; } - dev_dbg(&pctldev->dev, + 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, + dev_dbg(pctldev->dev, "%s does not support pin group %s with function %s\n", pinctrl_dev_get_name(pctldev), pin_group, @@ -627,7 +627,7 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, */ if (pmx->pctldev && pmx->pctldev != pctldev) { - dev_err(&pctldev->dev, + dev_err(pctldev->dev, "different pin control devices given for device %s, " "function %s\n", devname, @@ -650,7 +650,7 @@ static int pinmux_enable_muxmap(struct pinctrl_dev *pctldev, */ if (pmx->func_selector != UINT_MAX && pmx->func_selector != func_selector) { - dev_err(&pctldev->dev, + dev_err(pctldev->dev, "dual function defines in the map for device %s\n", devname); return -EINVAL; @@ -756,7 +756,7 @@ struct pinmux *pinmux_get(struct device *dev, const char *name) } pr_debug("in map, found pctldev %s to handle function %s", - dev_name(&pctldev->dev), map->function); + dev_name(pctldev->dev), map->function); /* @@ -932,7 +932,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, * 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 " + dev_err(pctldev->dev, "map %s wants to hog a non-system " "pinmux, this is not going to work\n", map->name); return -EINVAL; } @@ -944,7 +944,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, pmx = pinmux_get(NULL, map->name); if (IS_ERR(pmx)) { kfree(hog); - dev_err(&pctldev->dev, + dev_err(pctldev->dev, "could not get the %s pinmux mapping for hogging\n", map->name); return PTR_ERR(pmx); @@ -954,7 +954,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, if (ret) { pinmux_put(pmx); kfree(hog); - dev_err(&pctldev->dev, + dev_err(pctldev->dev, "could not enable the %s pinmux mapping for hogging\n", map->name); return ret; @@ -963,7 +963,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, hog->map = map; hog->pmx = pmx; - dev_info(&pctldev->dev, "hogged map %s, function %s\n", map->name, + 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); @@ -982,7 +982,7 @@ static int pinmux_hog_map(struct pinctrl_dev *pctldev, */ int pinmux_hog_maps(struct pinctrl_dev *pctldev) { - struct device *dev = &pctldev->dev; + struct device *dev = pctldev->dev; const char *devname = dev_name(dev); int ret; int i; -- cgit v1.1 From ca53c5f1ca5c936777caca46b7c716a40682ce83 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 14 Dec 2011 20:33:37 +0100 Subject: pinctrl: conjure names for unnamed pins If pins with blank names are registered, we assign them names on-the-fly on the form "PINn" where n is the pin number for that pin on the specific controller. Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 13 +++++++++++-- drivers/pinctrl/core.h | 2 ++ 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 160fb5a..9e32ea3 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -158,6 +158,8 @@ static void pinctrl_free_pindescs(struct pinctrl_dev *pctldev, if (pindesc != NULL) { radix_tree_delete(&pctldev->pin_desc_tree, pins[i].number); + if (pindesc->dynamic_name) + kfree(pindesc->name); } kfree(pindesc); } @@ -186,13 +188,20 @@ static int pinctrl_register_one_pin(struct pinctrl_dev *pctldev, pindesc->pctldev = pctldev; /* Copy basic pin info */ - pindesc->name = name; + if (pindesc->name) { + pindesc->name = name; + } else { + pindesc->name = kasprintf(GFP_KERNEL, "PIN%u", number); + if (pindesc->name == NULL) + return -ENOMEM; + 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, name ? name : "(unnamed)", pctldev->desc->name); + number, pindesc->name, pctldev->desc->name); return 0; } diff --git a/drivers/pinctrl/core.h b/drivers/pinctrl/core.h index 53755825..177a331 100644 --- a/drivers/pinctrl/core.h +++ b/drivers/pinctrl/core.h @@ -52,6 +52,7 @@ struct pinctrl_dev { * @pctldev: corresponding pin control device * @name: a name for the pin, e.g. the name of the pin/pad/finger on a * datasheet or such + * @dynamic_name: if the name of this pin was dynamically allocated * @lock: a lock to protect the descriptor structure * @mux_requested: whether the pin is already requested by pinmux or not * @mux_function: a named muxing function for the pin that will be passed to @@ -60,6 +61,7 @@ struct pinctrl_dev { 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 -- cgit v1.1 From 43699dea1ea21a0d5786317a794cb2ba27a6f4fe Mon Sep 17 00:00:00 2001 From: Stephen Warren Date: Thu, 15 Dec 2011 16:57:17 -0700 Subject: pinctrl: pass name instead of device to pin_config_* Obtaining a "struct pinctrl_dev *" is difficult for code not directly related to the pinctrl subsystem. However, the device name of the pinctrl device is fairly well known. So, modify pin_config_*() to take the device name instead of the "struct pinctrl_dev *". Signed-off-by: Stephen Warren [rebased on top of refactoring code] Signed-off-by: Linus Walleij --- drivers/pinctrl/pinconf.c | 41 ++++++++++++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 9 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 124762b..57dbb4b 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -39,17 +39,22 @@ int pin_config_get_for_pin(struct pinctrl_dev *pctldev, unsigned pin, /** * pin_config_get() - get the configuration of a single pin parameter - * @pctldev: pin controller device for this pin + * @dev_name: name of the pin controller device for this pin * @name: name of the pin to get the config for * @config: the config pointed to by this argument will be filled in with the * current pin state, it can be used directly by drivers as a numeral, or * it can be dereferenced to any struct. */ -int pin_config_get(struct pinctrl_dev *pctldev, const char *name, +int pin_config_get(const char *dev_name, const char *name, unsigned long *config) { + struct pinctrl_dev *pctldev; int pin; + pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); + if (!pctldev) + return -EINVAL; + pin = pin_get_from_name(pctldev, name); if (pin < 0) return pin; @@ -82,17 +87,22 @@ int pin_config_set_for_pin(struct pinctrl_dev *pctldev, unsigned pin, /** * pin_config_set() - set the configuration of a single pin parameter - * @pctldev: pin controller device for this pin + * @dev_name: name of pin controller device for this pin * @name: name of the pin to set the config for * @config: the config in this argument will contain the desired pin state, it * can be used directly by drivers as a numeral, or it can be dereferenced * to any struct. */ -int pin_config_set(struct pinctrl_dev *pctldev, const char *name, +int pin_config_set(const char *dev_name, const char *name, unsigned long config) { + struct pinctrl_dev *pctldev; int pin; + pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); + if (!pctldev) + return -EINVAL; + pin = pin_get_from_name(pctldev, name); if (pin < 0) return pin; @@ -101,12 +111,18 @@ int pin_config_set(struct pinctrl_dev *pctldev, const char *name, } EXPORT_SYMBOL(pin_config_set); -int pin_config_group_get(struct pinctrl_dev *pctldev, const char *pin_group, +int pin_config_group_get(const char *dev_name, const char *pin_group, unsigned long *config) { - const struct pinconf_ops *ops = pctldev->desc->confops; + struct pinctrl_dev *pctldev; + const struct pinconf_ops *ops; int selector; + pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); + if (!pctldev) + return -EINVAL; + 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 " @@ -123,17 +139,24 @@ int pin_config_group_get(struct pinctrl_dev *pctldev, const char *pin_group, EXPORT_SYMBOL(pin_config_group_get); -int pin_config_group_set(struct pinctrl_dev *pctldev, const char *pin_group, +int pin_config_group_set(const char *dev_name, const char *pin_group, unsigned long config) { - const struct pinctrl_ops *pctlops = pctldev->desc->pctlops; - const struct pinconf_ops *ops = pctldev->desc->confops; + struct pinctrl_dev *pctldev; + const struct pinconf_ops *ops; + const struct pinctrl_ops *pctlops; int selector; const unsigned *pins; unsigned num_pins; int ret; int i; + pctldev = get_pinctrl_dev_from_dev(NULL, dev_name); + if (!pctldev) + return -EINVAL; + 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"); -- cgit v1.1 From 3bece55aa5356af0171aaa64fd9c4f7601c47f1c Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Sun, 18 Dec 2011 23:44:26 +0100 Subject: pinctrl: rename U300 and SIRF pin controllers For stringent order, rename the pinmux-* pin controllers to pinctrl-* and also rename the Kconfig symbols and in-kernel users. Cc: Rongjun Ying Cc: Jean-Christophe PLAGNIOL-VILLARD Acked-by: Stephen Warren Signed-off-by: Linus Walleij --- drivers/pinctrl/Kconfig | 8 +- drivers/pinctrl/Makefile | 4 +- drivers/pinctrl/pinctrl-sirf.c | 1219 ++++++++++++++++++++++++++++++++++++++++ drivers/pinctrl/pinctrl-u300.c | 1157 ++++++++++++++++++++++++++++++++++++++ drivers/pinctrl/pinmux-sirf.c | 1219 ---------------------------------------- drivers/pinctrl/pinmux-u300.c | 1157 -------------------------------------- 6 files changed, 2382 insertions(+), 2382 deletions(-) create mode 100644 drivers/pinctrl/pinctrl-sirf.c create mode 100644 drivers/pinctrl/pinctrl-u300.c delete mode 100644 drivers/pinctrl/pinmux-sirf.c delete mode 100644 drivers/pinctrl/pinmux-u300.c (limited to 'drivers') diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index c63c721..afaf885 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -23,13 +23,13 @@ config DEBUG_PINCTRL help Say Y here to add some extra checks and diagnostics to PINCTRL calls. -config PINMUX_SIRF - bool "CSR SiRFprimaII pinmux driver" +config PINCTRL_SIRF + bool "CSR SiRFprimaII pin controller driver" depends on ARCH_PRIMA2 select PINMUX -config PINMUX_U300 - bool "U300 pinmux driver" +config PINCTRL_U300 + bool "U300 pin controller driver" depends on ARCH_U300 select PINMUX diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index c046f78..827601c 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -5,6 +5,6 @@ ccflags-$(CONFIG_DEBUG_PINCTRL) += -DDEBUG obj-$(CONFIG_PINCTRL) += core.o obj-$(CONFIG_PINMUX) += pinmux.o obj-$(CONFIG_PINCONF) += pinconf.o -obj-$(CONFIG_PINMUX_SIRF) += pinmux-sirf.o -obj-$(CONFIG_PINMUX_U300) += pinmux-u300.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-sirf.c b/drivers/pinctrl/pinctrl-sirf.c new file mode 100644 index 0000000..99e688e --- /dev/null +++ b/drivers/pinctrl/pinctrl-sirf.c @@ -0,0 +1,1219 @@ +/* + * pinmux driver for CSR SiRFprimaII + * + * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. + * + * Licensed under GPLv2 or later. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRIVER_NAME "pinmux-sirf" + +#define SIRFSOC_NUM_PADS 622 +#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) +#define SIRFSOC_RSC_PIN_MUX 0x4 + +/* + * pad list for the pinmux subsystem + * refer to CS-131858-DC-6A.xls + */ +static const struct pinctrl_pin_desc sirfsoc_pads[] = { + PINCTRL_PIN(4, "pwm0"), + PINCTRL_PIN(5, "pwm1"), + PINCTRL_PIN(6, "pwm2"), + PINCTRL_PIN(7, "pwm3"), + PINCTRL_PIN(8, "warm_rst_b"), + PINCTRL_PIN(9, "odo_0"), + PINCTRL_PIN(10, "odo_1"), + PINCTRL_PIN(11, "dr_dir"), + PINCTRL_PIN(13, "scl_1"), + PINCTRL_PIN(15, "sda_1"), + PINCTRL_PIN(16, "x_ldd[16]"), + PINCTRL_PIN(17, "x_ldd[17]"), + PINCTRL_PIN(18, "x_ldd[18]"), + PINCTRL_PIN(19, "x_ldd[19]"), + PINCTRL_PIN(20, "x_ldd[20]"), + PINCTRL_PIN(21, "x_ldd[21]"), + PINCTRL_PIN(22, "x_ldd[22]"), + PINCTRL_PIN(23, "x_ldd[23], lcdrom_frdy"), + PINCTRL_PIN(24, "gps_sgn"), + PINCTRL_PIN(25, "gps_mag"), + PINCTRL_PIN(26, "gps_clk"), + PINCTRL_PIN(27, "sd_cd_b_1"), + PINCTRL_PIN(28, "sd_vcc_on_1"), + PINCTRL_PIN(29, "sd_wp_b_1"), + PINCTRL_PIN(30, "sd_clk_3"), + PINCTRL_PIN(31, "sd_cmd_3"), + + PINCTRL_PIN(32, "x_sd_dat_3[0]"), + PINCTRL_PIN(33, "x_sd_dat_3[1]"), + PINCTRL_PIN(34, "x_sd_dat_3[2]"), + PINCTRL_PIN(35, "x_sd_dat_3[3]"), + PINCTRL_PIN(36, "x_sd_clk_4"), + PINCTRL_PIN(37, "x_sd_cmd_4"), + PINCTRL_PIN(38, "x_sd_dat_4[0]"), + PINCTRL_PIN(39, "x_sd_dat_4[1]"), + PINCTRL_PIN(40, "x_sd_dat_4[2]"), + PINCTRL_PIN(41, "x_sd_dat_4[3]"), + PINCTRL_PIN(42, "x_cko_1"), + PINCTRL_PIN(43, "x_ac97_bit_clk"), + PINCTRL_PIN(44, "x_ac97_dout"), + PINCTRL_PIN(45, "x_ac97_din"), + PINCTRL_PIN(46, "x_ac97_sync"), + PINCTRL_PIN(47, "x_txd_1"), + PINCTRL_PIN(48, "x_txd_2"), + PINCTRL_PIN(49, "x_rxd_1"), + PINCTRL_PIN(50, "x_rxd_2"), + PINCTRL_PIN(51, "x_usclk_0"), + PINCTRL_PIN(52, "x_utxd_0"), + PINCTRL_PIN(53, "x_urxd_0"), + PINCTRL_PIN(54, "x_utfs_0"), + PINCTRL_PIN(55, "x_urfs_0"), + PINCTRL_PIN(56, "x_usclk_1"), + PINCTRL_PIN(57, "x_utxd_1"), + PINCTRL_PIN(58, "x_urxd_1"), + PINCTRL_PIN(59, "x_utfs_1"), + PINCTRL_PIN(60, "x_urfs_1"), + PINCTRL_PIN(61, "x_usclk_2"), + PINCTRL_PIN(62, "x_utxd_2"), + PINCTRL_PIN(63, "x_urxd_2"), + + PINCTRL_PIN(64, "x_utfs_2"), + PINCTRL_PIN(65, "x_urfs_2"), + PINCTRL_PIN(66, "x_df_we_b"), + PINCTRL_PIN(67, "x_df_re_b"), + PINCTRL_PIN(68, "x_txd_0"), + PINCTRL_PIN(69, "x_rxd_0"), + PINCTRL_PIN(78, "x_cko_0"), + PINCTRL_PIN(79, "x_vip_pxd[7]"), + PINCTRL_PIN(80, "x_vip_pxd[6]"), + PINCTRL_PIN(81, "x_vip_pxd[5]"), + PINCTRL_PIN(82, "x_vip_pxd[4]"), + PINCTRL_PIN(83, "x_vip_pxd[3]"), + PINCTRL_PIN(84, "x_vip_pxd[2]"), + PINCTRL_PIN(85, "x_vip_pxd[1]"), + PINCTRL_PIN(86, "x_vip_pxd[0]"), + PINCTRL_PIN(87, "x_vip_vsync"), + PINCTRL_PIN(88, "x_vip_hsync"), + PINCTRL_PIN(89, "x_vip_pxclk"), + PINCTRL_PIN(90, "x_sda_0"), + PINCTRL_PIN(91, "x_scl_0"), + PINCTRL_PIN(92, "x_df_ry_by"), + PINCTRL_PIN(93, "x_df_cs_b[1]"), + PINCTRL_PIN(94, "x_df_cs_b[0]"), + PINCTRL_PIN(95, "x_l_pclk"), + + PINCTRL_PIN(96, "x_l_lck"), + PINCTRL_PIN(97, "x_l_fck"), + PINCTRL_PIN(98, "x_l_de"), + PINCTRL_PIN(99, "x_ldd[0]"), + PINCTRL_PIN(100, "x_ldd[1]"), + PINCTRL_PIN(101, "x_ldd[2]"), + PINCTRL_PIN(102, "x_ldd[3]"), + PINCTRL_PIN(103, "x_ldd[4]"), + PINCTRL_PIN(104, "x_ldd[5]"), + PINCTRL_PIN(105, "x_ldd[6]"), + PINCTRL_PIN(106, "x_ldd[7]"), + PINCTRL_PIN(107, "x_ldd[8]"), + PINCTRL_PIN(108, "x_ldd[9]"), + PINCTRL_PIN(109, "x_ldd[10]"), + PINCTRL_PIN(110, "x_ldd[11]"), + PINCTRL_PIN(111, "x_ldd[12]"), + PINCTRL_PIN(112, "x_ldd[13]"), + PINCTRL_PIN(113, "x_ldd[14]"), + PINCTRL_PIN(114, "x_ldd[15]"), +}; + +/** + * @dev: a pointer back to containing device + * @virtbase: the offset to the controller in virtual memory + */ +struct sirfsoc_pmx { + struct device *dev; + struct pinctrl_dev *pmx; + void __iomem *gpio_virtbase; + void __iomem *rsc_virtbase; +}; + +/* SIRFSOC_GPIO_PAD_EN set */ +struct sirfsoc_muxmask { + unsigned long group; + unsigned long mask; +}; + +struct sirfsoc_padmux { + unsigned long muxmask_counts; + const struct sirfsoc_muxmask *muxmask; + /* RSC_PIN_MUX set */ + unsigned long funcmask; + unsigned long funcval; +}; + + /** + * struct sirfsoc_pin_group - describes a SiRFprimaII pin group + * @name: the name of this specific pin group + * @pins: an array of discrete physical pins used in this group, taken + * from the driver-local pin enumeration space + * @num_pins: the number of pins in this group array, i.e. the number of + * elements in .pins so we can iterate over that array + */ +struct sirfsoc_pin_group { + const char *name; + const unsigned int *pins; + const unsigned num_pins; +}; + +static const struct sirfsoc_muxmask lcd_16bits_sirfsoc_muxmask[] = { + { + .group = 3, + .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | + BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | + BIT(17) | BIT(18), + }, { + .group = 2, + .mask = BIT(31), + }, +}; + +static const struct sirfsoc_padmux lcd_16bits_padmux = { + .muxmask_counts = ARRAY_SIZE(lcd_16bits_sirfsoc_muxmask), + .muxmask = lcd_16bits_sirfsoc_muxmask, + .funcmask = BIT(4), + .funcval = 0, +}; + +static const unsigned lcd_16bits_pins[] = { 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114 }; + +static const struct sirfsoc_muxmask lcd_18bits_muxmask[] = { + { + .group = 3, + .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | + BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | + BIT(17) | BIT(18), + }, { + .group = 2, + .mask = BIT(31), + }, { + .group = 0, + .mask = BIT(16) | BIT(17), + }, +}; + +static const struct sirfsoc_padmux lcd_18bits_padmux = { + .muxmask_counts = ARRAY_SIZE(lcd_18bits_muxmask), + .muxmask = lcd_18bits_muxmask, + .funcmask = BIT(4), + .funcval = 0, +}; + +static const unsigned lcd_18bits_pins[] = { 16, 17, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114}; + +static const struct sirfsoc_muxmask lcd_24bits_muxmask[] = { + { + .group = 3, + .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | + BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | + BIT(17) | BIT(18), + }, { + .group = 2, + .mask = BIT(31), + }, { + .group = 0, + .mask = BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23), + }, +}; + +static const struct sirfsoc_padmux lcd_24bits_padmux = { + .muxmask_counts = ARRAY_SIZE(lcd_24bits_muxmask), + .muxmask = lcd_24bits_muxmask, + .funcmask = BIT(4), + .funcval = 0, +}; + +static const unsigned lcd_24bits_pins[] = { 16, 17, 18, 19, 20, 21, 22, 23, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114 }; + +static const struct sirfsoc_muxmask lcdrom_muxmask[] = { + { + .group = 3, + .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | + BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | + BIT(17) | BIT(18), + }, { + .group = 2, + .mask = BIT(31), + }, { + .group = 0, + .mask = BIT(23), + }, +}; + +static const struct sirfsoc_padmux lcdrom_padmux = { + .muxmask_counts = ARRAY_SIZE(lcdrom_muxmask), + .muxmask = lcdrom_muxmask, + .funcmask = BIT(4), + .funcval = BIT(4), +}; + +static const unsigned lcdrom_pins[] = { 23, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114 }; + +static const struct sirfsoc_muxmask uart0_muxmask[] = { + { + .group = 2, + .mask = BIT(4) | BIT(5), + }, { + .group = 1, + .mask = BIT(23) | BIT(28), + }, +}; + +static const struct sirfsoc_padmux uart0_padmux = { + .muxmask_counts = ARRAY_SIZE(uart0_muxmask), + .muxmask = uart0_muxmask, + .funcmask = BIT(9), + .funcval = BIT(9), +}; + +static const unsigned uart0_pins[] = { 55, 60, 68, 69 }; + +static const struct sirfsoc_muxmask uart0_nostreamctrl_muxmask[] = { + { + .group = 2, + .mask = BIT(4) | BIT(5), + }, +}; + +static const struct sirfsoc_padmux uart0_nostreamctrl_padmux = { + .muxmask_counts = ARRAY_SIZE(uart0_nostreamctrl_muxmask), + .muxmask = uart0_nostreamctrl_muxmask, +}; + +static const unsigned uart0_nostreamctrl_pins[] = { 68, 39 }; + +static const struct sirfsoc_muxmask uart1_muxmask[] = { + { + .group = 1, + .mask = BIT(15) | BIT(17), + }, +}; + +static const struct sirfsoc_padmux uart1_padmux = { + .muxmask_counts = ARRAY_SIZE(uart1_muxmask), + .muxmask = uart1_muxmask, +}; + +static const unsigned uart1_pins[] = { 47, 49 }; + +static const struct sirfsoc_muxmask uart2_muxmask[] = { + { + .group = 1, + .mask = BIT(16) | BIT(18) | BIT(24) | BIT(27), + }, +}; + +static const struct sirfsoc_padmux uart2_padmux = { + .muxmask_counts = ARRAY_SIZE(uart2_muxmask), + .muxmask = uart2_muxmask, + .funcmask = BIT(10), + .funcval = BIT(10), +}; + +static const unsigned uart2_pins[] = { 48, 50, 56, 59 }; + +static const struct sirfsoc_muxmask uart2_nostreamctrl_muxmask[] = { + { + .group = 1, + .mask = BIT(16) | BIT(18), + }, +}; + +static const struct sirfsoc_padmux uart2_nostreamctrl_padmux = { + .muxmask_counts = ARRAY_SIZE(uart2_nostreamctrl_muxmask), + .muxmask = uart2_nostreamctrl_muxmask, +}; + +static const unsigned uart2_nostreamctrl_pins[] = { 48, 50 }; + +static const struct sirfsoc_muxmask sdmmc3_muxmask[] = { + { + .group = 0, + .mask = BIT(30) | BIT(31), + }, { + .group = 1, + .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), + }, +}; + +static const struct sirfsoc_padmux sdmmc3_padmux = { + .muxmask_counts = ARRAY_SIZE(sdmmc3_muxmask), + .muxmask = sdmmc3_muxmask, + .funcmask = BIT(7), + .funcval = 0, +}; + +static const unsigned sdmmc3_pins[] = { 30, 31, 32, 33, 34, 35 }; + +static const struct sirfsoc_muxmask spi0_muxmask[] = { + { + .group = 1, + .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), + }, +}; + +static const struct sirfsoc_padmux spi0_padmux = { + .muxmask_counts = ARRAY_SIZE(spi0_muxmask), + .muxmask = spi0_muxmask, + .funcmask = BIT(7), + .funcval = BIT(7), +}; + +static const unsigned spi0_pins[] = { 32, 33, 34, 35 }; + +static const struct sirfsoc_muxmask sdmmc4_muxmask[] = { + { + .group = 1, + .mask = BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9), + }, +}; + +static const struct sirfsoc_padmux sdmmc4_padmux = { + .muxmask_counts = ARRAY_SIZE(sdmmc4_muxmask), + .muxmask = sdmmc4_muxmask, +}; + +static const unsigned sdmmc4_pins[] = { 36, 37, 38, 39, 40, 41 }; + +static const struct sirfsoc_muxmask cko1_muxmask[] = { + { + .group = 1, + .mask = BIT(10), + }, +}; + +static const struct sirfsoc_padmux cko1_padmux = { + .muxmask_counts = ARRAY_SIZE(cko1_muxmask), + .muxmask = cko1_muxmask, + .funcmask = BIT(3), + .funcval = 0, +}; + +static const unsigned cko1_pins[] = { 42 }; + +static const struct sirfsoc_muxmask i2s_muxmask[] = { + { + .group = 1, + .mask = + BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(19) + | BIT(23) | BIT(28), + }, +}; + +static const struct sirfsoc_padmux i2s_padmux = { + .muxmask_counts = ARRAY_SIZE(i2s_muxmask), + .muxmask = i2s_muxmask, + .funcmask = BIT(3) | BIT(9), + .funcval = BIT(3), +}; + +static const unsigned i2s_pins[] = { 42, 43, 44, 45, 46, 51, 55, 60 }; + +static const struct sirfsoc_muxmask ac97_muxmask[] = { + { + .group = 1, + .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), + }, +}; + +static const struct sirfsoc_padmux ac97_padmux = { + .muxmask_counts = ARRAY_SIZE(ac97_muxmask), + .muxmask = ac97_muxmask, + .funcmask = BIT(8), + .funcval = 0, +}; + +static const unsigned ac97_pins[] = { 33, 34, 35, 36 }; + +static const struct sirfsoc_muxmask spi1_muxmask[] = { + { + .group = 1, + .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), + }, +}; + +static const struct sirfsoc_padmux spi1_padmux = { + .muxmask_counts = ARRAY_SIZE(spi1_muxmask), + .muxmask = spi1_muxmask, + .funcmask = BIT(8), + .funcval = BIT(8), +}; + +static const unsigned spi1_pins[] = { 43, 44, 45, 46 }; + +static const struct sirfsoc_muxmask sdmmc1_muxmask[] = { + { + .group = 0, + .mask = BIT(27) | BIT(28) | BIT(29), + }, +}; + +static const struct sirfsoc_padmux sdmmc1_padmux = { + .muxmask_counts = ARRAY_SIZE(sdmmc1_muxmask), + .muxmask = sdmmc1_muxmask, +}; + +static const unsigned sdmmc1_pins[] = { 27, 28, 29 }; + +static const struct sirfsoc_muxmask gps_muxmask[] = { + { + .group = 0, + .mask = BIT(24) | BIT(25) | BIT(26), + }, +}; + +static const struct sirfsoc_padmux gps_padmux = { + .muxmask_counts = ARRAY_SIZE(gps_muxmask), + .muxmask = gps_muxmask, + .funcmask = BIT(12) | BIT(13) | BIT(14), + .funcval = BIT(12), +}; + +static const unsigned gps_pins[] = { 24, 25, 26 }; + +static const struct sirfsoc_muxmask sdmmc5_muxmask[] = { + { + .group = 0, + .mask = BIT(24) | BIT(25) | BIT(26), + }, { + .group = 1, + .mask = BIT(29), + }, { + .group = 2, + .mask = BIT(0) | BIT(1), + }, +}; + +static const struct sirfsoc_padmux sdmmc5_padmux = { + .muxmask_counts = ARRAY_SIZE(sdmmc5_muxmask), + .muxmask = sdmmc5_muxmask, + .funcmask = BIT(13) | BIT(14), + .funcval = BIT(13) | BIT(14), +}; + +static const unsigned sdmmc5_pins[] = { 24, 25, 26, 61, 64, 65 }; + +static const struct sirfsoc_muxmask usp0_muxmask[] = { + { + .group = 1, + .mask = BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23), + }, +}; + +static const struct sirfsoc_padmux usp0_padmux = { + .muxmask_counts = ARRAY_SIZE(usp0_muxmask), + .muxmask = usp0_muxmask, + .funcmask = BIT(1) | BIT(2) | BIT(6) | BIT(9), + .funcval = 0, +}; + +static const unsigned usp0_pins[] = { 51, 52, 53, 54, 55 }; + +static const struct sirfsoc_muxmask usp1_muxmask[] = { + { + .group = 1, + .mask = BIT(24) | BIT(25) | BIT(26) | BIT(27) | BIT(28), + }, +}; + +static const struct sirfsoc_padmux usp1_padmux = { + .muxmask_counts = ARRAY_SIZE(usp1_muxmask), + .muxmask = usp1_muxmask, + .funcmask = BIT(1) | BIT(9) | BIT(10) | BIT(11), + .funcval = 0, +}; + +static const unsigned usp1_pins[] = { 56, 57, 58, 59, 60 }; + +static const struct sirfsoc_muxmask usp2_muxmask[] = { + { + .group = 1, + .mask = BIT(29) | BIT(30) | BIT(31), + }, { + .group = 2, + .mask = BIT(0) | BIT(1), + }, +}; + +static const struct sirfsoc_padmux usp2_padmux = { + .muxmask_counts = ARRAY_SIZE(usp2_muxmask), + .muxmask = usp2_muxmask, + .funcmask = BIT(13) | BIT(14), + .funcval = 0, +}; + +static const unsigned usp2_pins[] = { 61, 62, 63, 64, 65 }; + +static const struct sirfsoc_muxmask nand_muxmask[] = { + { + .group = 2, + .mask = BIT(2) | BIT(3) | BIT(28) | BIT(29) | BIT(30), + }, +}; + +static const struct sirfsoc_padmux nand_padmux = { + .muxmask_counts = ARRAY_SIZE(nand_muxmask), + .muxmask = nand_muxmask, + .funcmask = BIT(5), + .funcval = 0, +}; + +static const unsigned nand_pins[] = { 64, 65, 92, 93, 94 }; + +static const struct sirfsoc_padmux sdmmc0_padmux = { + .muxmask_counts = 0, + .funcmask = BIT(5), + .funcval = 0, +}; + +static const unsigned sdmmc0_pins[] = { }; + +static const struct sirfsoc_muxmask sdmmc2_muxmask[] = { + { + .group = 2, + .mask = BIT(2) | BIT(3), + }, +}; + +static const struct sirfsoc_padmux sdmmc2_padmux = { + .muxmask_counts = ARRAY_SIZE(sdmmc2_muxmask), + .muxmask = sdmmc2_muxmask, + .funcmask = BIT(5), + .funcval = BIT(5), +}; + +static const unsigned sdmmc2_pins[] = { 66, 67 }; + +static const struct sirfsoc_muxmask cko0_muxmask[] = { + { + .group = 2, + .mask = BIT(14), + }, +}; + +static const struct sirfsoc_padmux cko0_padmux = { + .muxmask_counts = ARRAY_SIZE(cko0_muxmask), + .muxmask = cko0_muxmask, +}; + +static const unsigned cko0_pins[] = { 78 }; + +static const struct sirfsoc_muxmask vip_muxmask[] = { + { + .group = 2, + .mask = BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) + | BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) | + BIT(25), + }, +}; + +static const struct sirfsoc_padmux vip_padmux = { + .muxmask_counts = ARRAY_SIZE(vip_muxmask), + .muxmask = vip_muxmask, + .funcmask = BIT(0), + .funcval = 0, +}; + +static const unsigned vip_pins[] = { 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89 }; + +static const struct sirfsoc_muxmask i2c0_muxmask[] = { + { + .group = 2, + .mask = BIT(26) | BIT(27), + }, +}; + +static const struct sirfsoc_padmux i2c0_padmux = { + .muxmask_counts = ARRAY_SIZE(i2c0_muxmask), + .muxmask = i2c0_muxmask, +}; + +static const unsigned i2c0_pins[] = { 90, 91 }; + +static const struct sirfsoc_muxmask i2c1_muxmask[] = { + { + .group = 0, + .mask = BIT(13) | BIT(15), + }, +}; + +static const struct sirfsoc_padmux i2c1_padmux = { + .muxmask_counts = ARRAY_SIZE(i2c1_muxmask), + .muxmask = i2c1_muxmask, +}; + +static const unsigned i2c1_pins[] = { 13, 15 }; + +static const struct sirfsoc_muxmask viprom_muxmask[] = { + { + .group = 2, + .mask = BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) + | BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) | + BIT(25), + }, { + .group = 0, + .mask = BIT(12), + }, +}; + +static const struct sirfsoc_padmux viprom_padmux = { + .muxmask_counts = ARRAY_SIZE(viprom_muxmask), + .muxmask = viprom_muxmask, + .funcmask = BIT(0), + .funcval = BIT(0), +}; + +static const unsigned viprom_pins[] = { 12, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89 }; + +static const struct sirfsoc_muxmask pwm0_muxmask[] = { + { + .group = 0, + .mask = BIT(4), + }, +}; + +static const struct sirfsoc_padmux pwm0_padmux = { + .muxmask_counts = ARRAY_SIZE(pwm0_muxmask), + .muxmask = pwm0_muxmask, + .funcmask = BIT(12), + .funcval = 0, +}; + +static const unsigned pwm0_pins[] = { 4 }; + +static const struct sirfsoc_muxmask pwm1_muxmask[] = { + { + .group = 0, + .mask = BIT(5), + }, +}; + +static const struct sirfsoc_padmux pwm1_padmux = { + .muxmask_counts = ARRAY_SIZE(pwm1_muxmask), + .muxmask = pwm1_muxmask, +}; + +static const unsigned pwm1_pins[] = { 5 }; + +static const struct sirfsoc_muxmask pwm2_muxmask[] = { + { + .group = 0, + .mask = BIT(6), + }, +}; + +static const struct sirfsoc_padmux pwm2_padmux = { + .muxmask_counts = ARRAY_SIZE(pwm2_muxmask), + .muxmask = pwm2_muxmask, +}; + +static const unsigned pwm2_pins[] = { 6 }; + +static const struct sirfsoc_muxmask pwm3_muxmask[] = { + { + .group = 0, + .mask = BIT(7), + }, +}; + +static const struct sirfsoc_padmux pwm3_padmux = { + .muxmask_counts = ARRAY_SIZE(pwm3_muxmask), + .muxmask = pwm3_muxmask, +}; + +static const unsigned pwm3_pins[] = { 7 }; + +static const struct sirfsoc_muxmask warm_rst_muxmask[] = { + { + .group = 0, + .mask = BIT(8), + }, +}; + +static const struct sirfsoc_padmux warm_rst_padmux = { + .muxmask_counts = ARRAY_SIZE(warm_rst_muxmask), + .muxmask = warm_rst_muxmask, +}; + +static const unsigned warm_rst_pins[] = { 8 }; + +static const struct sirfsoc_muxmask usb0_utmi_drvbus_muxmask[] = { + { + .group = 1, + .mask = BIT(22), + }, +}; +static const struct sirfsoc_padmux usb0_utmi_drvbus_padmux = { + .muxmask_counts = ARRAY_SIZE(usb0_utmi_drvbus_muxmask), + .muxmask = usb0_utmi_drvbus_muxmask, + .funcmask = BIT(6), + .funcval = BIT(6), /* refer to PAD_UTMI_DRVVBUS0_ENABLE */ +}; + +static const unsigned usb0_utmi_drvbus_pins[] = { 54 }; + +static const struct sirfsoc_muxmask usb1_utmi_drvbus_muxmask[] = { + { + .group = 1, + .mask = BIT(27), + }, +}; + +static const struct sirfsoc_padmux usb1_utmi_drvbus_padmux = { + .muxmask_counts = ARRAY_SIZE(usb1_utmi_drvbus_muxmask), + .muxmask = usb1_utmi_drvbus_muxmask, + .funcmask = BIT(11), + .funcval = BIT(11), /* refer to PAD_UTMI_DRVVBUS1_ENABLE */ +}; + +static const unsigned usb1_utmi_drvbus_pins[] = { 59 }; + +static const struct sirfsoc_muxmask pulse_count_muxmask[] = { + { + .group = 0, + .mask = BIT(9) | BIT(10) | BIT(11), + }, +}; + +static const struct sirfsoc_padmux pulse_count_padmux = { + .muxmask_counts = ARRAY_SIZE(pulse_count_muxmask), + .muxmask = pulse_count_muxmask, +}; + +static const unsigned pulse_count_pins[] = { 9, 10, 11 }; + +#define SIRFSOC_PIN_GROUP(n, p) \ + { \ + .name = n, \ + .pins = p, \ + .num_pins = ARRAY_SIZE(p), \ + } + +static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = { + SIRFSOC_PIN_GROUP("lcd_16bitsgrp", lcd_16bits_pins), + SIRFSOC_PIN_GROUP("lcd_18bitsgrp", lcd_18bits_pins), + SIRFSOC_PIN_GROUP("lcd_24bitsgrp", lcd_24bits_pins), + SIRFSOC_PIN_GROUP("lcdrom_grp", lcdrom_pins), + SIRFSOC_PIN_GROUP("uart0grp", uart0_pins), + SIRFSOC_PIN_GROUP("uart1grp", uart1_pins), + SIRFSOC_PIN_GROUP("uart2grp", uart2_pins), + SIRFSOC_PIN_GROUP("uart2_nostreamctrlgrp", uart2_nostreamctrl_pins), + SIRFSOC_PIN_GROUP("usp0grp", usp0_pins), + SIRFSOC_PIN_GROUP("usp1grp", usp1_pins), + SIRFSOC_PIN_GROUP("usp2grp", usp2_pins), + SIRFSOC_PIN_GROUP("i2c0grp", i2c0_pins), + SIRFSOC_PIN_GROUP("i2c1grp", i2c1_pins), + SIRFSOC_PIN_GROUP("pwm0grp", pwm0_pins), + SIRFSOC_PIN_GROUP("pwm1grp", pwm1_pins), + SIRFSOC_PIN_GROUP("pwm2grp", pwm2_pins), + SIRFSOC_PIN_GROUP("pwm3grp", pwm3_pins), + SIRFSOC_PIN_GROUP("vipgrp", vip_pins), + SIRFSOC_PIN_GROUP("vipromgrp", viprom_pins), + SIRFSOC_PIN_GROUP("warm_rstgrp", warm_rst_pins), + SIRFSOC_PIN_GROUP("cko0_rstgrp", cko0_pins), + SIRFSOC_PIN_GROUP("cko1_rstgrp", cko1_pins), + SIRFSOC_PIN_GROUP("sdmmc0grp", sdmmc0_pins), + SIRFSOC_PIN_GROUP("sdmmc1grp", sdmmc1_pins), + SIRFSOC_PIN_GROUP("sdmmc2grp", sdmmc2_pins), + SIRFSOC_PIN_GROUP("sdmmc3grp", sdmmc3_pins), + SIRFSOC_PIN_GROUP("sdmmc4grp", sdmmc4_pins), + SIRFSOC_PIN_GROUP("sdmmc5grp", sdmmc5_pins), + SIRFSOC_PIN_GROUP("usb0_utmi_drvbusgrp", usb0_utmi_drvbus_pins), + SIRFSOC_PIN_GROUP("usb1_utmi_drvbusgrp", usb1_utmi_drvbus_pins), + SIRFSOC_PIN_GROUP("pulse_countgrp", pulse_count_pins), + SIRFSOC_PIN_GROUP("i2sgrp", i2s_pins), + SIRFSOC_PIN_GROUP("ac97grp", ac97_pins), + SIRFSOC_PIN_GROUP("nandgrp", nand_pins), + SIRFSOC_PIN_GROUP("spi0grp", spi0_pins), + SIRFSOC_PIN_GROUP("spi1grp", spi1_pins), + SIRFSOC_PIN_GROUP("gpsgrp", gps_pins), +}; + +static int sirfsoc_list_groups(struct pinctrl_dev *pctldev, unsigned selector) +{ + if (selector >= ARRAY_SIZE(sirfsoc_pin_groups)) + return -EINVAL; + return 0; +} + +static const char *sirfsoc_get_group_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + if (selector >= ARRAY_SIZE(sirfsoc_pin_groups)) + return NULL; + return sirfsoc_pin_groups[selector].name; +} + +static int sirfsoc_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, + const unsigned **pins, + unsigned *num_pins) +{ + if (selector >= ARRAY_SIZE(sirfsoc_pin_groups)) + return -EINVAL; + *pins = sirfsoc_pin_groups[selector].pins; + *num_pins = sirfsoc_pin_groups[selector].num_pins; + return 0; +} + +static void sirfsoc_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, + unsigned offset) +{ + seq_printf(s, " " DRIVER_NAME); +} + +static struct pinctrl_ops sirfsoc_pctrl_ops = { + .list_groups = sirfsoc_list_groups, + .get_group_name = sirfsoc_get_group_name, + .get_group_pins = sirfsoc_get_group_pins, + .pin_dbg_show = sirfsoc_pin_dbg_show, +}; + +struct sirfsoc_pmx_func { + const char *name; + const char * const *groups; + const unsigned num_groups; + const struct sirfsoc_padmux *padmux; +}; + +static const char * const lcd_16bitsgrp[] = { "lcd_16bitsgrp" }; +static const char * const lcd_18bitsgrp[] = { "lcd_18bitsgrp" }; +static const char * const lcd_24bitsgrp[] = { "lcd_24bitsgrp" }; +static const char * const lcdromgrp[] = { "lcdromgrp" }; +static const char * const uart0grp[] = { "uart0grp" }; +static const char * const uart1grp[] = { "uart1grp" }; +static const char * const uart2grp[] = { "uart2grp" }; +static const char * const uart2_nostreamctrlgrp[] = { "uart2_nostreamctrlgrp" }; +static const char * const usp0grp[] = { "usp0grp" }; +static const char * const usp1grp[] = { "usp1grp" }; +static const char * const usp2grp[] = { "usp2grp" }; +static const char * const i2c0grp[] = { "i2c0grp" }; +static const char * const i2c1grp[] = { "i2c1grp" }; +static const char * const pwm0grp[] = { "pwm0grp" }; +static const char * const pwm1grp[] = { "pwm1grp" }; +static const char * const pwm2grp[] = { "pwm2grp" }; +static const char * const pwm3grp[] = { "pwm3grp" }; +static const char * const vipgrp[] = { "vipgrp" }; +static const char * const vipromgrp[] = { "vipromgrp" }; +static const char * const warm_rstgrp[] = { "warm_rstgrp" }; +static const char * const cko0grp[] = { "cko0grp" }; +static const char * const cko1grp[] = { "cko1grp" }; +static const char * const sdmmc0grp[] = { "sdmmc0grp" }; +static const char * const sdmmc1grp[] = { "sdmmc1grp" }; +static const char * const sdmmc2grp[] = { "sdmmc2grp" }; +static const char * const sdmmc3grp[] = { "sdmmc3grp" }; +static const char * const sdmmc4grp[] = { "sdmmc4grp" }; +static const char * const sdmmc5grp[] = { "sdmmc5grp" }; +static const char * const usb0_utmi_drvbusgrp[] = { "usb0_utmi_drvbusgrp" }; +static const char * const usb1_utmi_drvbusgrp[] = { "usb1_utmi_drvbusgrp" }; +static const char * const pulse_countgrp[] = { "pulse_countgrp" }; +static const char * const i2sgrp[] = { "i2sgrp" }; +static const char * const ac97grp[] = { "ac97grp" }; +static const char * const nandgrp[] = { "nandgrp" }; +static const char * const spi0grp[] = { "spi0grp" }; +static const char * const spi1grp[] = { "spi1grp" }; +static const char * const gpsgrp[] = { "gpsgrp" }; + +#define SIRFSOC_PMX_FUNCTION(n, g, m) \ + { \ + .name = n, \ + .groups = g, \ + .num_groups = ARRAY_SIZE(g), \ + .padmux = &m, \ + } + +static const struct sirfsoc_pmx_func sirfsoc_pmx_functions[] = { + SIRFSOC_PMX_FUNCTION("lcd_16bits", lcd_16bitsgrp, lcd_16bits_padmux), + SIRFSOC_PMX_FUNCTION("lcd_18bits", lcd_18bitsgrp, lcd_18bits_padmux), + SIRFSOC_PMX_FUNCTION("lcd_24bits", lcd_24bitsgrp, lcd_24bits_padmux), + SIRFSOC_PMX_FUNCTION("lcdrom", lcdromgrp, lcdrom_padmux), + SIRFSOC_PMX_FUNCTION("uart0", uart0grp, uart0_padmux), + SIRFSOC_PMX_FUNCTION("uart1", uart1grp, uart1_padmux), + SIRFSOC_PMX_FUNCTION("uart2", uart2grp, uart2_padmux), + SIRFSOC_PMX_FUNCTION("uart2_nostreamctrl", uart2_nostreamctrlgrp, uart2_nostreamctrl_padmux), + SIRFSOC_PMX_FUNCTION("usp0", usp0grp, usp0_padmux), + SIRFSOC_PMX_FUNCTION("usp1", usp1grp, usp1_padmux), + SIRFSOC_PMX_FUNCTION("usp2", usp2grp, usp2_padmux), + SIRFSOC_PMX_FUNCTION("i2c0", i2c0grp, i2c0_padmux), + SIRFSOC_PMX_FUNCTION("i2c1", i2c1grp, i2c1_padmux), + SIRFSOC_PMX_FUNCTION("pwm0", pwm0grp, pwm0_padmux), + SIRFSOC_PMX_FUNCTION("pwm1", pwm1grp, pwm1_padmux), + SIRFSOC_PMX_FUNCTION("pwm2", pwm2grp, pwm2_padmux), + SIRFSOC_PMX_FUNCTION("pwm3", pwm3grp, pwm3_padmux), + SIRFSOC_PMX_FUNCTION("vip", vipgrp, vip_padmux), + SIRFSOC_PMX_FUNCTION("viprom", vipromgrp, viprom_padmux), + SIRFSOC_PMX_FUNCTION("warm_rst", warm_rstgrp, warm_rst_padmux), + SIRFSOC_PMX_FUNCTION("cko0", cko0grp, cko0_padmux), + SIRFSOC_PMX_FUNCTION("cko1", cko1grp, cko1_padmux), + SIRFSOC_PMX_FUNCTION("sdmmc0", sdmmc0grp, sdmmc0_padmux), + SIRFSOC_PMX_FUNCTION("sdmmc1", sdmmc1grp, sdmmc1_padmux), + SIRFSOC_PMX_FUNCTION("sdmmc2", sdmmc2grp, sdmmc2_padmux), + SIRFSOC_PMX_FUNCTION("sdmmc3", sdmmc3grp, sdmmc3_padmux), + SIRFSOC_PMX_FUNCTION("sdmmc4", sdmmc4grp, sdmmc4_padmux), + SIRFSOC_PMX_FUNCTION("sdmmc5", sdmmc5grp, sdmmc5_padmux), + SIRFSOC_PMX_FUNCTION("usb0_utmi_drvbus", usb0_utmi_drvbusgrp, usb0_utmi_drvbus_padmux), + SIRFSOC_PMX_FUNCTION("usb1_utmi_drvbus", usb1_utmi_drvbusgrp, usb1_utmi_drvbus_padmux), + SIRFSOC_PMX_FUNCTION("pulse_count", pulse_countgrp, pulse_count_padmux), + SIRFSOC_PMX_FUNCTION("i2s", i2sgrp, i2s_padmux), + SIRFSOC_PMX_FUNCTION("ac97", ac97grp, ac97_padmux), + SIRFSOC_PMX_FUNCTION("nand", nandgrp, nand_padmux), + SIRFSOC_PMX_FUNCTION("spi0", spi0grp, spi0_padmux), + SIRFSOC_PMX_FUNCTION("spi1", spi1grp, spi1_padmux), + SIRFSOC_PMX_FUNCTION("gps", gpsgrp, gps_padmux), +}; + +static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, unsigned selector, + bool enable) +{ + int i; + const struct sirfsoc_padmux *mux = sirfsoc_pmx_functions[selector].padmux; + const struct sirfsoc_muxmask *mask = mux->muxmask; + + for (i = 0; i < mux->muxmask_counts; i++) { + u32 muxval; + muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); + if (enable) + muxval = muxval & ~mask[i].mask; + else + muxval = muxval | mask[i].mask; + writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); + } + + if (mux->funcmask && enable) { + u32 func_en_val; + func_en_val = + readl(spmx->rsc_virtbase + SIRFSOC_RSC_PIN_MUX); + func_en_val = + (func_en_val & ~mux->funcmask) | (mux-> + funcval); + writel(func_en_val, spmx->rsc_virtbase + SIRFSOC_RSC_PIN_MUX); + } +} + +static int sirfsoc_pinmux_enable(struct pinctrl_dev *pmxdev, unsigned selector, + unsigned group) +{ + struct sirfsoc_pmx *spmx; + + spmx = pinctrl_dev_get_drvdata(pmxdev); + sirfsoc_pinmux_endisable(spmx, selector, true); + + return 0; +} + +static void sirfsoc_pinmux_disable(struct pinctrl_dev *pmxdev, unsigned selector, + unsigned group) +{ + struct sirfsoc_pmx *spmx; + + spmx = pinctrl_dev_get_drvdata(pmxdev); + sirfsoc_pinmux_endisable(spmx, selector, false); +} + +static int sirfsoc_pinmux_list_funcs(struct pinctrl_dev *pmxdev, unsigned selector) +{ + if (selector >= ARRAY_SIZE(sirfsoc_pmx_functions)) + return -EINVAL; + return 0; +} + +static const char *sirfsoc_pinmux_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return sirfsoc_pmx_functions[selector].name; +} + +static int sirfsoc_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = sirfsoc_pmx_functions[selector].groups; + *num_groups = sirfsoc_pmx_functions[selector].num_groups; + return 0; +} + +static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, + struct pinctrl_gpio_range *range, unsigned offset) +{ + struct sirfsoc_pmx *spmx; + + int group = range->id; + + u32 muxval; + + spmx = pinctrl_dev_get_drvdata(pmxdev); + + muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); + muxval = muxval | (1 << (offset - range->pin_base)); + writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); + + return 0; +} + +static struct pinmux_ops sirfsoc_pinmux_ops = { + .list_functions = sirfsoc_pinmux_list_funcs, + .enable = sirfsoc_pinmux_enable, + .disable = sirfsoc_pinmux_disable, + .get_function_name = sirfsoc_pinmux_get_func_name, + .get_function_groups = sirfsoc_pinmux_get_groups, + .gpio_request_enable = sirfsoc_pinmux_request_gpio, +}; + +static struct pinctrl_desc sirfsoc_pinmux_desc = { + .name = DRIVER_NAME, + .pins = sirfsoc_pads, + .npins = ARRAY_SIZE(sirfsoc_pads), + .maxpin = SIRFSOC_NUM_PADS - 1, + .pctlops = &sirfsoc_pctrl_ops, + .pmxops = &sirfsoc_pinmux_ops, + .owner = THIS_MODULE, +}; + +/* + * Todo: bind irq_chip to every pinctrl_gpio_range + */ +static struct pinctrl_gpio_range sirfsoc_gpio_ranges[] = { + { + .name = "sirfsoc-gpio*", + .id = 0, + .base = 0, + .pin_base = 0, + .npins = 32, + }, { + .name = "sirfsoc-gpio*", + .id = 1, + .base = 32, + .pin_base = 32, + .npins = 32, + }, { + .name = "sirfsoc-gpio*", + .id = 2, + .base = 64, + .pin_base = 64, + .npins = 32, + }, { + .name = "sirfsoc-gpio*", + .id = 3, + .base = 96, + .pin_base = 96, + .npins = 19, + }, +}; + +static void __iomem *sirfsoc_rsc_of_iomap(void) +{ + const struct of_device_id rsc_ids[] = { + { .compatible = "sirf,prima2-rsc" }, + {} + }; + struct device_node *np; + + np = of_find_matching_node(NULL, rsc_ids); + if (!np) + panic("unable to find compatible rsc node in dtb\n"); + + return of_iomap(np, 0); +} + +static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev) +{ + int ret; + struct sirfsoc_pmx *spmx; + struct device_node *np = pdev->dev.of_node; + int i; + + /* Create state holders etc for this driver */ + spmx = devm_kzalloc(&pdev->dev, sizeof(*spmx), GFP_KERNEL); + if (!spmx) + return -ENOMEM; + + spmx->dev = &pdev->dev; + + platform_set_drvdata(pdev, spmx); + + spmx->gpio_virtbase = of_iomap(np, 0); + if (!spmx->gpio_virtbase) { + ret = -ENOMEM; + dev_err(&pdev->dev, "can't map gpio registers\n"); + goto out_no_gpio_remap; + } + + spmx->rsc_virtbase = sirfsoc_rsc_of_iomap(); + if (!spmx->rsc_virtbase) { + ret = -ENOMEM; + dev_err(&pdev->dev, "can't map rsc registers\n"); + goto out_no_rsc_remap; + } + + /* Now register the pin controller and all pins it handles */ + spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx); + if (!spmx->pmx) { + dev_err(&pdev->dev, "could not register SIRFSOC pinmux driver\n"); + ret = -EINVAL; + goto out_no_pmx; + } + + for (i = 0; i < ARRAY_SIZE(sirfsoc_gpio_ranges); i++) + pinctrl_add_gpio_range(spmx->pmx, &sirfsoc_gpio_ranges[i]); + + dev_info(&pdev->dev, "initialized SIRFSOC pinmux driver\n"); + + return 0; + +out_no_pmx: + iounmap(spmx->rsc_virtbase); +out_no_rsc_remap: + iounmap(spmx->gpio_virtbase); +out_no_gpio_remap: + platform_set_drvdata(pdev, NULL); + devm_kfree(&pdev->dev, spmx); + return ret; +} + +static const struct of_device_id pinmux_ids[] = { + { .compatible = "sirf,prima2-gpio-pinmux" }, + {} +}; + +static struct platform_driver sirfsoc_pinmux_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + .of_match_table = pinmux_ids, + }, + .probe = sirfsoc_pinmux_probe, +}; + +static int __init sirfsoc_pinmux_init(void) +{ + return platform_driver_register(&sirfsoc_pinmux_driver); +} +arch_initcall(sirfsoc_pinmux_init); + +MODULE_AUTHOR("Rongjun Ying , " + "Barry Song "); +MODULE_DESCRIPTION("SIRFSOC pin control driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c new file mode 100644 index 0000000..7e89b36 --- /dev/null +++ b/drivers/pinctrl/pinctrl-u300.c @@ -0,0 +1,1157 @@ +/* + * Driver for the U300 pin controller + * + * Based on the original U300 padmux functions + * Copyright (C) 2009-2011 ST-Ericsson AB + * Author: Martin Persson + * Author: Linus Walleij + * + * The DB3350 design and control registers are oriented around pads rather than + * pins, so we enumerate the pads we can mux rather than actual pins. The pads + * are connected to different pins in different packaging types, so it would + * be confusing. + */ +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * Register definitions for the U300 Padmux control registers in the + * system controller + */ + +/* PAD MUX Control register 1 (LOW) 16bit (R/W) */ +#define U300_SYSCON_PMC1LR 0x007C +#define U300_SYSCON_PMC1LR_MASK 0xFFFF +#define U300_SYSCON_PMC1LR_CDI_MASK 0xC000 +#define U300_SYSCON_PMC1LR_CDI_CDI 0x0000 +#define U300_SYSCON_PMC1LR_CDI_EMIF 0x4000 +/* For BS335 */ +#define U300_SYSCON_PMC1LR_CDI_CDI2 0x8000 +#define U300_SYSCON_PMC1LR_CDI_WCDMA_APP_GPIO 0xC000 +/* For BS365 */ +#define U300_SYSCON_PMC1LR_CDI_GPIO 0x8000 +#define U300_SYSCON_PMC1LR_CDI_WCDMA 0xC000 +/* Common defs */ +#define U300_SYSCON_PMC1LR_PDI_MASK 0x3000 +#define U300_SYSCON_PMC1LR_PDI_PDI 0x0000 +#define U300_SYSCON_PMC1LR_PDI_EGG 0x1000 +#define U300_SYSCON_PMC1LR_PDI_WCDMA 0x3000 +#define U300_SYSCON_PMC1LR_MMCSD_MASK 0x0C00 +#define U300_SYSCON_PMC1LR_MMCSD_MMCSD 0x0000 +#define U300_SYSCON_PMC1LR_MMCSD_MSPRO 0x0400 +#define U300_SYSCON_PMC1LR_MMCSD_DSP 0x0800 +#define U300_SYSCON_PMC1LR_MMCSD_WCDMA 0x0C00 +#define U300_SYSCON_PMC1LR_ETM_MASK 0x0300 +#define U300_SYSCON_PMC1LR_ETM_ACC 0x0000 +#define U300_SYSCON_PMC1LR_ETM_APP 0x0100 +#define U300_SYSCON_PMC1LR_EMIF_1_CS2_MASK 0x00C0 +#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC 0x0000 +#define U300_SYSCON_PMC1LR_EMIF_1_CS2_NFIF 0x0040 +#define U300_SYSCON_PMC1LR_EMIF_1_CS2_SDRAM 0x0080 +#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC_2GB 0x00C0 +#define U300_SYSCON_PMC1LR_EMIF_1_CS1_MASK 0x0030 +#define U300_SYSCON_PMC1LR_EMIF_1_CS1_STATIC 0x0000 +#define U300_SYSCON_PMC1LR_EMIF_1_CS1_NFIF 0x0010 +#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SDRAM 0x0020 +#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SEMI 0x0030 +#define U300_SYSCON_PMC1LR_EMIF_1_CS0_MASK 0x000C +#define U300_SYSCON_PMC1LR_EMIF_1_CS0_STATIC 0x0000 +#define U300_SYSCON_PMC1LR_EMIF_1_CS0_NFIF 0x0004 +#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SDRAM 0x0008 +#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SEMI 0x000C +#define U300_SYSCON_PMC1LR_EMIF_1_MASK 0x0003 +#define U300_SYSCON_PMC1LR_EMIF_1_STATIC 0x0000 +#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM0 0x0001 +#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM1 0x0002 +#define U300_SYSCON_PMC1LR_EMIF_1 0x0003 +/* PAD MUX Control register 2 (HIGH) 16bit (R/W) */ +#define U300_SYSCON_PMC1HR 0x007E +#define U300_SYSCON_PMC1HR_MASK 0xFFFF +#define U300_SYSCON_PMC1HR_MISC_2_MASK 0xC000 +#define U300_SYSCON_PMC1HR_MISC_2_APP_GPIO 0x0000 +#define U300_SYSCON_PMC1HR_MISC_2_MSPRO 0x4000 +#define U300_SYSCON_PMC1HR_MISC_2_DSP 0x8000 +#define U300_SYSCON_PMC1HR_MISC_2_AAIF 0xC000 +#define U300_SYSCON_PMC1HR_APP_GPIO_2_MASK 0x3000 +#define U300_SYSCON_PMC1HR_APP_GPIO_2_APP_GPIO 0x0000 +#define U300_SYSCON_PMC1HR_APP_GPIO_2_NFIF 0x1000 +#define U300_SYSCON_PMC1HR_APP_GPIO_2_DSP 0x2000 +#define U300_SYSCON_PMC1HR_APP_GPIO_2_AAIF 0x3000 +#define U300_SYSCON_PMC1HR_APP_GPIO_1_MASK 0x0C00 +#define U300_SYSCON_PMC1HR_APP_GPIO_1_APP_GPIO 0x0000 +#define U300_SYSCON_PMC1HR_APP_GPIO_1_MMC 0x0400 +#define U300_SYSCON_PMC1HR_APP_GPIO_1_DSP 0x0800 +#define U300_SYSCON_PMC1HR_APP_GPIO_1_AAIF 0x0C00 +#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK 0x0300 +#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_APP_GPIO 0x0000 +#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI 0x0100 +#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_AAIF 0x0300 +#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK 0x00C0 +#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_APP_GPIO 0x0000 +#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI 0x0040 +#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_AAIF 0x00C0 +#define U300_SYSCON_PMC1HR_APP_SPI_2_MASK 0x0030 +#define U300_SYSCON_PMC1HR_APP_SPI_2_APP_GPIO 0x0000 +#define U300_SYSCON_PMC1HR_APP_SPI_2_SPI 0x0010 +#define U300_SYSCON_PMC1HR_APP_SPI_2_DSP 0x0020 +#define U300_SYSCON_PMC1HR_APP_SPI_2_AAIF 0x0030 +#define U300_SYSCON_PMC1HR_APP_UART0_2_MASK 0x000C +#define U300_SYSCON_PMC1HR_APP_UART0_2_APP_GPIO 0x0000 +#define U300_SYSCON_PMC1HR_APP_UART0_2_UART0 0x0004 +#define U300_SYSCON_PMC1HR_APP_UART0_2_NFIF_CS 0x0008 +#define U300_SYSCON_PMC1HR_APP_UART0_2_AAIF 0x000C +#define U300_SYSCON_PMC1HR_APP_UART0_1_MASK 0x0003 +#define U300_SYSCON_PMC1HR_APP_UART0_1_APP_GPIO 0x0000 +#define U300_SYSCON_PMC1HR_APP_UART0_1_UART0 0x0001 +#define U300_SYSCON_PMC1HR_APP_UART0_1_AAIF 0x0003 +/* Padmux 2 control */ +#define U300_SYSCON_PMC2R 0x100 +#define U300_SYSCON_PMC2R_APP_MISC_0_MASK 0x00C0 +#define U300_SYSCON_PMC2R_APP_MISC_0_APP_GPIO 0x0000 +#define U300_SYSCON_PMC2R_APP_MISC_0_EMIF_SDRAM 0x0040 +#define U300_SYSCON_PMC2R_APP_MISC_0_MMC 0x0080 +#define U300_SYSCON_PMC2R_APP_MISC_0_CDI2 0x00C0 +#define U300_SYSCON_PMC2R_APP_MISC_1_MASK 0x0300 +#define U300_SYSCON_PMC2R_APP_MISC_1_APP_GPIO 0x0000 +#define U300_SYSCON_PMC2R_APP_MISC_1_EMIF_SDRAM 0x0100 +#define U300_SYSCON_PMC2R_APP_MISC_1_MMC 0x0200 +#define U300_SYSCON_PMC2R_APP_MISC_1_CDI2 0x0300 +#define U300_SYSCON_PMC2R_APP_MISC_2_MASK 0x0C00 +#define U300_SYSCON_PMC2R_APP_MISC_2_APP_GPIO 0x0000 +#define U300_SYSCON_PMC2R_APP_MISC_2_EMIF_SDRAM 0x0400 +#define U300_SYSCON_PMC2R_APP_MISC_2_MMC 0x0800 +#define U300_SYSCON_PMC2R_APP_MISC_2_CDI2 0x0C00 +#define U300_SYSCON_PMC2R_APP_MISC_3_MASK 0x3000 +#define U300_SYSCON_PMC2R_APP_MISC_3_APP_GPIO 0x0000 +#define U300_SYSCON_PMC2R_APP_MISC_3_EMIF_SDRAM 0x1000 +#define U300_SYSCON_PMC2R_APP_MISC_3_MMC 0x2000 +#define U300_SYSCON_PMC2R_APP_MISC_3_CDI2 0x3000 +#define U300_SYSCON_PMC2R_APP_MISC_4_MASK 0xC000 +#define U300_SYSCON_PMC2R_APP_MISC_4_APP_GPIO 0x0000 +#define U300_SYSCON_PMC2R_APP_MISC_4_EMIF_SDRAM 0x4000 +#define U300_SYSCON_PMC2R_APP_MISC_4_MMC 0x8000 +#define U300_SYSCON_PMC2R_APP_MISC_4_ACC_GPIO 0xC000 +/* TODO: More SYSCON registers missing */ +#define U300_SYSCON_PMC3R 0x10C +#define U300_SYSCON_PMC3R_APP_MISC_11_MASK 0xC000 +#define U300_SYSCON_PMC3R_APP_MISC_11_SPI 0x4000 +#define U300_SYSCON_PMC3R_APP_MISC_10_MASK 0x3000 +#define U300_SYSCON_PMC3R_APP_MISC_10_SPI 0x1000 +/* TODO: Missing other configs */ +#define U300_SYSCON_PMC4R 0x168 +#define U300_SYSCON_PMC4R_APP_MISC_12_MASK 0x0003 +#define U300_SYSCON_PMC4R_APP_MISC_12_APP_GPIO 0x0000 +#define U300_SYSCON_PMC4R_APP_MISC_13_MASK 0x000C +#define U300_SYSCON_PMC4R_APP_MISC_13_CDI 0x0000 +#define U300_SYSCON_PMC4R_APP_MISC_13_SMIA 0x0004 +#define U300_SYSCON_PMC4R_APP_MISC_13_SMIA2 0x0008 +#define U300_SYSCON_PMC4R_APP_MISC_13_APP_GPIO 0x000C +#define U300_SYSCON_PMC4R_APP_MISC_14_MASK 0x0030 +#define U300_SYSCON_PMC4R_APP_MISC_14_CDI 0x0000 +#define U300_SYSCON_PMC4R_APP_MISC_14_SMIA 0x0010 +#define U300_SYSCON_PMC4R_APP_MISC_14_CDI2 0x0020 +#define U300_SYSCON_PMC4R_APP_MISC_14_APP_GPIO 0x0030 +#define U300_SYSCON_PMC4R_APP_MISC_16_MASK 0x0300 +#define U300_SYSCON_PMC4R_APP_MISC_16_APP_GPIO_13 0x0000 +#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" + +/* + * The DB3350 has 467 pads, I have enumerated the pads clockwise around the + * edges of the silicon, finger by finger. LTCORNER upper left is pad 0. + * Data taken from the PadRing chart, arranged like this: + * + * 0 ..... 104 + * 466 105 + * . . + * . . + * 358 224 + * 357 .... 225 + */ +#define U300_NUM_PADS 467 + +/* Pad names for the pinmux subsystem */ +static const struct pinctrl_pin_desc u300_pads[] = { + /* Pads along the top edge of the chip */ + PINCTRL_PIN(0, "P PAD VDD 28"), + PINCTRL_PIN(1, "P PAD GND 28"), + PINCTRL_PIN(2, "PO SIM RST N"), + PINCTRL_PIN(3, "VSSIO 25"), + PINCTRL_PIN(4, "VSSA ADDA ESDSUB"), + PINCTRL_PIN(5, "PWR VSSCOMMON"), + PINCTRL_PIN(6, "PI ADC I1 POS"), + PINCTRL_PIN(7, "PI ADC I1 NEG"), + PINCTRL_PIN(8, "PWR VSSAD0"), + PINCTRL_PIN(9, "PWR VCCAD0"), + PINCTRL_PIN(10, "PI ADC Q1 NEG"), + PINCTRL_PIN(11, "PI ADC Q1 POS"), + PINCTRL_PIN(12, "PWR VDDAD"), + PINCTRL_PIN(13, "PWR GNDAD"), + PINCTRL_PIN(14, "PI ADC I2 POS"), + PINCTRL_PIN(15, "PI ADC I2 NEG"), + PINCTRL_PIN(16, "PWR VSSAD1"), + PINCTRL_PIN(17, "PWR VCCAD1"), + PINCTRL_PIN(18, "PI ADC Q2 NEG"), + PINCTRL_PIN(19, "PI ADC Q2 POS"), + PINCTRL_PIN(20, "VSSA ADDA ESDSUB"), + PINCTRL_PIN(21, "PWR VCCGPAD"), + PINCTRL_PIN(22, "PI TX POW"), + PINCTRL_PIN(23, "PWR VSSGPAD"), + PINCTRL_PIN(24, "PO DAC I POS"), + PINCTRL_PIN(25, "PO DAC I NEG"), + PINCTRL_PIN(26, "PO DAC Q POS"), + PINCTRL_PIN(27, "PO DAC Q NEG"), + PINCTRL_PIN(28, "PWR VSSDA"), + PINCTRL_PIN(29, "PWR VCCDA"), + PINCTRL_PIN(30, "VSSA ADDA ESDSUB"), + PINCTRL_PIN(31, "P PAD VDDIO 11"), + PINCTRL_PIN(32, "PI PLL 26 FILTVDD"), + PINCTRL_PIN(33, "PI PLL 26 VCONT"), + PINCTRL_PIN(34, "PWR AGNDPLL2V5 32 13"), + PINCTRL_PIN(35, "PWR AVDDPLL2V5 32 13"), + PINCTRL_PIN(36, "VDDA PLL ESD"), + PINCTRL_PIN(37, "VSSA PLL ESD"), + PINCTRL_PIN(38, "VSS PLL"), + PINCTRL_PIN(39, "VDDC PLL"), + PINCTRL_PIN(40, "PWR AGNDPLL2V5 26 60"), + PINCTRL_PIN(41, "PWR AVDDPLL2V5 26 60"), + PINCTRL_PIN(42, "PWR AVDDPLL2V5 26 208"), + PINCTRL_PIN(43, "PWR AGNDPLL2V5 26 208"), + PINCTRL_PIN(44, "PWR AVDDPLL2V5 13 208"), + PINCTRL_PIN(45, "PWR AGNDPLL2V5 13 208"), + PINCTRL_PIN(46, "P PAD VSSIO 11"), + PINCTRL_PIN(47, "P PAD VSSIO 12"), + PINCTRL_PIN(48, "PI POW RST N"), + PINCTRL_PIN(49, "VDDC IO"), + PINCTRL_PIN(50, "P PAD VDDIO 16"), + PINCTRL_PIN(51, "PO RF WCDMA EN 4"), + PINCTRL_PIN(52, "PO RF WCDMA EN 3"), + PINCTRL_PIN(53, "PO RF WCDMA EN 2"), + PINCTRL_PIN(54, "PO RF WCDMA EN 1"), + PINCTRL_PIN(55, "PO RF WCDMA EN 0"), + PINCTRL_PIN(56, "PO GSM PA ENABLE"), + PINCTRL_PIN(57, "PO RF DATA STRB"), + PINCTRL_PIN(58, "PO RF DATA2"), + PINCTRL_PIN(59, "PIO RF DATA1"), + PINCTRL_PIN(60, "PIO RF DATA0"), + PINCTRL_PIN(61, "P PAD VDD 11"), + PINCTRL_PIN(62, "P PAD GND 11"), + PINCTRL_PIN(63, "P PAD VSSIO 16"), + PINCTRL_PIN(64, "P PAD VDDIO 18"), + PINCTRL_PIN(65, "PO RF CTRL STRB2"), + PINCTRL_PIN(66, "PO RF CTRL STRB1"), + PINCTRL_PIN(67, "PO RF CTRL STRB0"), + PINCTRL_PIN(68, "PIO RF CTRL DATA"), + PINCTRL_PIN(69, "PO RF CTRL CLK"), + PINCTRL_PIN(70, "PO TX ADC STRB"), + PINCTRL_PIN(71, "PO ANT SW 2"), + PINCTRL_PIN(72, "PO ANT SW 3"), + PINCTRL_PIN(73, "PO ANT SW 0"), + PINCTRL_PIN(74, "PO ANT SW 1"), + PINCTRL_PIN(75, "PO M CLKRQ"), + PINCTRL_PIN(76, "PI M CLK"), + PINCTRL_PIN(77, "PI RTC CLK"), + PINCTRL_PIN(78, "P PAD VDD 8"), + PINCTRL_PIN(79, "P PAD GND 8"), + PINCTRL_PIN(80, "P PAD VSSIO 13"), + PINCTRL_PIN(81, "P PAD VDDIO 13"), + PINCTRL_PIN(82, "PO SYS 1 CLK"), + PINCTRL_PIN(83, "PO SYS 2 CLK"), + PINCTRL_PIN(84, "PO SYS 0 CLK"), + PINCTRL_PIN(85, "PI SYS 0 CLKRQ"), + PINCTRL_PIN(86, "PO PWR MNGT CTRL 1"), + PINCTRL_PIN(87, "PO PWR MNGT CTRL 0"), + PINCTRL_PIN(88, "PO RESOUT2 RST N"), + PINCTRL_PIN(89, "PO RESOUT1 RST N"), + PINCTRL_PIN(90, "PO RESOUT0 RST N"), + PINCTRL_PIN(91, "PI SERVICE N"), + PINCTRL_PIN(92, "P PAD VDD 29"), + PINCTRL_PIN(93, "P PAD GND 29"), + PINCTRL_PIN(94, "P PAD VSSIO 8"), + PINCTRL_PIN(95, "P PAD VDDIO 8"), + PINCTRL_PIN(96, "PI EXT IRQ1 N"), + PINCTRL_PIN(97, "PI EXT IRQ0 N"), + PINCTRL_PIN(98, "PIO DC ON"), + PINCTRL_PIN(99, "PIO ACC APP I2C DATA"), + PINCTRL_PIN(100, "PIO ACC APP I2C CLK"), + PINCTRL_PIN(101, "P PAD VDD 12"), + PINCTRL_PIN(102, "P PAD GND 12"), + PINCTRL_PIN(103, "P PAD VSSIO 14"), + PINCTRL_PIN(104, "P PAD VDDIO 14"), + /* Pads along the right edge of the chip */ + PINCTRL_PIN(105, "PIO APP I2C1 DATA"), + PINCTRL_PIN(106, "PIO APP I2C1 CLK"), + PINCTRL_PIN(107, "PO KEY OUT0"), + PINCTRL_PIN(108, "PO KEY OUT1"), + PINCTRL_PIN(109, "PO KEY OUT2"), + PINCTRL_PIN(110, "PO KEY OUT3"), + PINCTRL_PIN(111, "PO KEY OUT4"), + PINCTRL_PIN(112, "PI KEY IN0"), + PINCTRL_PIN(113, "PI KEY IN1"), + PINCTRL_PIN(114, "PI KEY IN2"), + PINCTRL_PIN(115, "P PAD VDDIO 15"), + PINCTRL_PIN(116, "P PAD VSSIO 15"), + PINCTRL_PIN(117, "P PAD GND 13"), + PINCTRL_PIN(118, "P PAD VDD 13"), + PINCTRL_PIN(119, "PI KEY IN3"), + PINCTRL_PIN(120, "PI KEY IN4"), + PINCTRL_PIN(121, "PI KEY IN5"), + PINCTRL_PIN(122, "PIO APP PCM I2S1 DATA B"), + PINCTRL_PIN(123, "PIO APP PCM I2S1 DATA A"), + PINCTRL_PIN(124, "PIO APP PCM I2S1 WS"), + PINCTRL_PIN(125, "PIO APP PCM I2S1 CLK"), + PINCTRL_PIN(126, "PIO APP PCM I2S0 DATA B"), + PINCTRL_PIN(127, "PIO APP PCM I2S0 DATA A"), + PINCTRL_PIN(128, "PIO APP PCM I2S0 WS"), + PINCTRL_PIN(129, "PIO APP PCM I2S0 CLK"), + PINCTRL_PIN(130, "P PAD VDD 17"), + PINCTRL_PIN(131, "P PAD GND 17"), + PINCTRL_PIN(132, "P PAD VSSIO 19"), + PINCTRL_PIN(133, "P PAD VDDIO 19"), + PINCTRL_PIN(134, "UART0 RTS"), + PINCTRL_PIN(135, "UART0 CTS"), + PINCTRL_PIN(136, "UART0 TX"), + PINCTRL_PIN(137, "UART0 RX"), + PINCTRL_PIN(138, "PIO ACC SPI DO"), + PINCTRL_PIN(139, "PIO ACC SPI DI"), + PINCTRL_PIN(140, "PIO ACC SPI CS0 N"), + PINCTRL_PIN(141, "PIO ACC SPI CS1 N"), + PINCTRL_PIN(142, "PIO ACC SPI CS2 N"), + PINCTRL_PIN(143, "PIO ACC SPI CLK"), + PINCTRL_PIN(144, "PO PDI EXT RST N"), + PINCTRL_PIN(145, "P PAD VDDIO 22"), + PINCTRL_PIN(146, "P PAD VSSIO 22"), + PINCTRL_PIN(147, "P PAD GND 18"), + PINCTRL_PIN(148, "P PAD VDD 18"), + PINCTRL_PIN(149, "PIO PDI C0"), + PINCTRL_PIN(150, "PIO PDI C1"), + PINCTRL_PIN(151, "PIO PDI C2"), + PINCTRL_PIN(152, "PIO PDI C3"), + PINCTRL_PIN(153, "PIO PDI C4"), + PINCTRL_PIN(154, "PIO PDI C5"), + PINCTRL_PIN(155, "PIO PDI D0"), + PINCTRL_PIN(156, "PIO PDI D1"), + PINCTRL_PIN(157, "PIO PDI D2"), + PINCTRL_PIN(158, "PIO PDI D3"), + PINCTRL_PIN(159, "P PAD VDDIO 21"), + PINCTRL_PIN(160, "P PAD VSSIO 21"), + PINCTRL_PIN(161, "PIO PDI D4"), + PINCTRL_PIN(162, "PIO PDI D5"), + PINCTRL_PIN(163, "PIO PDI D6"), + PINCTRL_PIN(164, "PIO PDI D7"), + PINCTRL_PIN(165, "PIO MS INS"), + PINCTRL_PIN(166, "MMC DATA DIR LS"), + PINCTRL_PIN(167, "MMC DATA 3"), + PINCTRL_PIN(168, "MMC DATA 2"), + PINCTRL_PIN(169, "MMC DATA 1"), + PINCTRL_PIN(170, "MMC DATA 0"), + PINCTRL_PIN(171, "MMC CMD DIR LS"), + PINCTRL_PIN(172, "P PAD VDD 27"), + PINCTRL_PIN(173, "P PAD GND 27"), + PINCTRL_PIN(174, "P PAD VSSIO 20"), + PINCTRL_PIN(175, "P PAD VDDIO 20"), + PINCTRL_PIN(176, "MMC CMD"), + PINCTRL_PIN(177, "MMC CLK"), + PINCTRL_PIN(178, "PIO APP GPIO 14"), + PINCTRL_PIN(179, "PIO APP GPIO 13"), + PINCTRL_PIN(180, "PIO APP GPIO 11"), + PINCTRL_PIN(181, "PIO APP GPIO 25"), + PINCTRL_PIN(182, "PIO APP GPIO 24"), + PINCTRL_PIN(183, "PIO APP GPIO 23"), + PINCTRL_PIN(184, "PIO APP GPIO 22"), + PINCTRL_PIN(185, "PIO APP GPIO 21"), + PINCTRL_PIN(186, "PIO APP GPIO 20"), + PINCTRL_PIN(187, "P PAD VDD 19"), + PINCTRL_PIN(188, "P PAD GND 19"), + PINCTRL_PIN(189, "P PAD VSSIO 23"), + PINCTRL_PIN(190, "P PAD VDDIO 23"), + PINCTRL_PIN(191, "PIO APP GPIO 19"), + PINCTRL_PIN(192, "PIO APP GPIO 18"), + PINCTRL_PIN(193, "PIO APP GPIO 17"), + PINCTRL_PIN(194, "PIO APP GPIO 16"), + PINCTRL_PIN(195, "PI CI D1"), + PINCTRL_PIN(196, "PI CI D0"), + PINCTRL_PIN(197, "PI CI HSYNC"), + PINCTRL_PIN(198, "PI CI VSYNC"), + PINCTRL_PIN(199, "PI CI EXT CLK"), + PINCTRL_PIN(200, "PO CI EXT RST N"), + PINCTRL_PIN(201, "P PAD VSSIO 43"), + PINCTRL_PIN(202, "P PAD VDDIO 43"), + PINCTRL_PIN(203, "PI CI D6"), + PINCTRL_PIN(204, "PI CI D7"), + PINCTRL_PIN(205, "PI CI D2"), + PINCTRL_PIN(206, "PI CI D3"), + PINCTRL_PIN(207, "PI CI D4"), + PINCTRL_PIN(208, "PI CI D5"), + PINCTRL_PIN(209, "PI CI D8"), + PINCTRL_PIN(210, "PI CI D9"), + PINCTRL_PIN(211, "P PAD VDD 20"), + PINCTRL_PIN(212, "P PAD GND 20"), + PINCTRL_PIN(213, "P PAD VSSIO 24"), + PINCTRL_PIN(214, "P PAD VDDIO 24"), + PINCTRL_PIN(215, "P PAD VDDIO 26"), + PINCTRL_PIN(216, "PO EMIF 1 A26"), + PINCTRL_PIN(217, "PO EMIF 1 A25"), + PINCTRL_PIN(218, "P PAD VSSIO 26"), + PINCTRL_PIN(219, "PO EMIF 1 A24"), + PINCTRL_PIN(220, "PO EMIF 1 A23"), + /* Pads along the bottom edge of the chip */ + PINCTRL_PIN(221, "PO EMIF 1 A22"), + PINCTRL_PIN(222, "PO EMIF 1 A21"), + PINCTRL_PIN(223, "P PAD VDD 21"), + PINCTRL_PIN(224, "P PAD GND 21"), + PINCTRL_PIN(225, "P PAD VSSIO 27"), + PINCTRL_PIN(226, "P PAD VDDIO 27"), + PINCTRL_PIN(227, "PO EMIF 1 A20"), + PINCTRL_PIN(228, "PO EMIF 1 A19"), + PINCTRL_PIN(229, "PO EMIF 1 A18"), + PINCTRL_PIN(230, "PO EMIF 1 A17"), + PINCTRL_PIN(231, "P PAD VDDIO 28"), + PINCTRL_PIN(232, "P PAD VSSIO 28"), + PINCTRL_PIN(233, "PO EMIF 1 A16"), + PINCTRL_PIN(234, "PIO EMIF 1 D15"), + PINCTRL_PIN(235, "PO EMIF 1 A15"), + PINCTRL_PIN(236, "PIO EMIF 1 D14"), + PINCTRL_PIN(237, "P PAD VDD 22"), + PINCTRL_PIN(238, "P PAD GND 22"), + PINCTRL_PIN(239, "P PAD VSSIO 29"), + PINCTRL_PIN(240, "P PAD VDDIO 29"), + PINCTRL_PIN(241, "PO EMIF 1 A14"), + PINCTRL_PIN(242, "PIO EMIF 1 D13"), + PINCTRL_PIN(243, "PO EMIF 1 A13"), + PINCTRL_PIN(244, "PIO EMIF 1 D12"), + PINCTRL_PIN(245, "P PAD VSSIO 30"), + PINCTRL_PIN(246, "P PAD VDDIO 30"), + PINCTRL_PIN(247, "PO EMIF 1 A12"), + PINCTRL_PIN(248, "PIO EMIF 1 D11"), + PINCTRL_PIN(249, "PO EMIF 1 A11"), + PINCTRL_PIN(250, "PIO EMIF 1 D10"), + PINCTRL_PIN(251, "P PAD VSSIO 31"), + PINCTRL_PIN(252, "P PAD VDDIO 31"), + PINCTRL_PIN(253, "PO EMIF 1 A10"), + PINCTRL_PIN(254, "PIO EMIF 1 D09"), + PINCTRL_PIN(255, "PO EMIF 1 A09"), + PINCTRL_PIN(256, "P PAD VDDIO 32"), + PINCTRL_PIN(257, "P PAD VSSIO 32"), + PINCTRL_PIN(258, "P PAD GND 24"), + PINCTRL_PIN(259, "P PAD VDD 24"), + PINCTRL_PIN(260, "PIO EMIF 1 D08"), + PINCTRL_PIN(261, "PO EMIF 1 A08"), + PINCTRL_PIN(262, "PIO EMIF 1 D07"), + PINCTRL_PIN(263, "PO EMIF 1 A07"), + PINCTRL_PIN(264, "P PAD VDDIO 33"), + PINCTRL_PIN(265, "P PAD VSSIO 33"), + PINCTRL_PIN(266, "PIO EMIF 1 D06"), + PINCTRL_PIN(267, "PO EMIF 1 A06"), + PINCTRL_PIN(268, "PIO EMIF 1 D05"), + PINCTRL_PIN(269, "PO EMIF 1 A05"), + PINCTRL_PIN(270, "P PAD VDDIO 34"), + PINCTRL_PIN(271, "P PAD VSSIO 34"), + PINCTRL_PIN(272, "PIO EMIF 1 D04"), + PINCTRL_PIN(273, "PO EMIF 1 A04"), + PINCTRL_PIN(274, "PIO EMIF 1 D03"), + PINCTRL_PIN(275, "PO EMIF 1 A03"), + PINCTRL_PIN(276, "P PAD VDDIO 35"), + PINCTRL_PIN(277, "P PAD VSSIO 35"), + PINCTRL_PIN(278, "P PAD GND 23"), + PINCTRL_PIN(279, "P PAD VDD 23"), + PINCTRL_PIN(280, "PIO EMIF 1 D02"), + PINCTRL_PIN(281, "PO EMIF 1 A02"), + PINCTRL_PIN(282, "PIO EMIF 1 D01"), + PINCTRL_PIN(283, "PO EMIF 1 A01"), + PINCTRL_PIN(284, "P PAD VDDIO 36"), + PINCTRL_PIN(285, "P PAD VSSIO 36"), + PINCTRL_PIN(286, "PIO EMIF 1 D00"), + PINCTRL_PIN(287, "PO EMIF 1 BE1 N"), + PINCTRL_PIN(288, "PO EMIF 1 BE0 N"), + PINCTRL_PIN(289, "PO EMIF 1 ADV N"), + PINCTRL_PIN(290, "P PAD VDDIO 37"), + PINCTRL_PIN(291, "P PAD VSSIO 37"), + PINCTRL_PIN(292, "PO EMIF 1 SD CKE0"), + PINCTRL_PIN(293, "PO EMIF 1 OE N"), + PINCTRL_PIN(294, "PO EMIF 1 WE N"), + PINCTRL_PIN(295, "P PAD VDDIO 38"), + PINCTRL_PIN(296, "P PAD VSSIO 38"), + PINCTRL_PIN(297, "PO EMIF 1 CLK"), + PINCTRL_PIN(298, "PIO EMIF 1 SD CLK"), + PINCTRL_PIN(299, "P PAD VSSIO 45 (not bonded)"), + PINCTRL_PIN(300, "P PAD VDDIO 42"), + PINCTRL_PIN(301, "P PAD VSSIO 42"), + PINCTRL_PIN(302, "P PAD GND 31"), + PINCTRL_PIN(303, "P PAD VDD 31"), + PINCTRL_PIN(304, "PI EMIF 1 RET CLK"), + PINCTRL_PIN(305, "PI EMIF 1 WAIT N"), + PINCTRL_PIN(306, "PI EMIF 1 NFIF READY"), + PINCTRL_PIN(307, "PO EMIF 1 SD CKE1"), + PINCTRL_PIN(308, "PO EMIF 1 CS3 N"), + PINCTRL_PIN(309, "P PAD VDD 25"), + PINCTRL_PIN(310, "P PAD GND 25"), + PINCTRL_PIN(311, "P PAD VSSIO 39"), + PINCTRL_PIN(312, "P PAD VDDIO 39"), + PINCTRL_PIN(313, "PO EMIF 1 CS2 N"), + PINCTRL_PIN(314, "PO EMIF 1 CS1 N"), + PINCTRL_PIN(315, "PO EMIF 1 CS0 N"), + PINCTRL_PIN(316, "PO ETM TRACE PKT0"), + PINCTRL_PIN(317, "PO ETM TRACE PKT1"), + PINCTRL_PIN(318, "PO ETM TRACE PKT2"), + PINCTRL_PIN(319, "P PAD VDD 30"), + PINCTRL_PIN(320, "P PAD GND 30"), + PINCTRL_PIN(321, "P PAD VSSIO 44"), + PINCTRL_PIN(322, "P PAD VDDIO 44"), + PINCTRL_PIN(323, "PO ETM TRACE PKT3"), + PINCTRL_PIN(324, "PO ETM TRACE PKT4"), + PINCTRL_PIN(325, "PO ETM TRACE PKT5"), + PINCTRL_PIN(326, "PO ETM TRACE PKT6"), + PINCTRL_PIN(327, "PO ETM TRACE PKT7"), + PINCTRL_PIN(328, "PO ETM PIPE STAT0"), + PINCTRL_PIN(329, "P PAD VDD 26"), + PINCTRL_PIN(330, "P PAD GND 26"), + PINCTRL_PIN(331, "P PAD VSSIO 40"), + PINCTRL_PIN(332, "P PAD VDDIO 40"), + PINCTRL_PIN(333, "PO ETM PIPE STAT1"), + PINCTRL_PIN(334, "PO ETM PIPE STAT2"), + PINCTRL_PIN(335, "PO ETM TRACE CLK"), + PINCTRL_PIN(336, "PO ETM TRACE SYNC"), + PINCTRL_PIN(337, "PIO ACC GPIO 33"), + PINCTRL_PIN(338, "PIO ACC GPIO 32"), + PINCTRL_PIN(339, "PIO ACC GPIO 30"), + PINCTRL_PIN(340, "PIO ACC GPIO 29"), + PINCTRL_PIN(341, "P PAD VDDIO 17"), + PINCTRL_PIN(342, "P PAD VSSIO 17"), + PINCTRL_PIN(343, "P PAD GND 15"), + PINCTRL_PIN(344, "P PAD VDD 15"), + PINCTRL_PIN(345, "PIO ACC GPIO 28"), + PINCTRL_PIN(346, "PIO ACC GPIO 27"), + PINCTRL_PIN(347, "PIO ACC GPIO 16"), + PINCTRL_PIN(348, "PI TAP TMS"), + PINCTRL_PIN(349, "PI TAP TDI"), + PINCTRL_PIN(350, "PO TAP TDO"), + PINCTRL_PIN(351, "PI TAP RST N"), + /* Pads along the left edge of the chip */ + PINCTRL_PIN(352, "PI EMU MODE 0"), + PINCTRL_PIN(353, "PO TAP RET CLK"), + PINCTRL_PIN(354, "PI TAP CLK"), + PINCTRL_PIN(355, "PO EMIF 0 SD CS N"), + PINCTRL_PIN(356, "PO EMIF 0 SD CAS N"), + PINCTRL_PIN(357, "PO EMIF 0 SD WE N"), + PINCTRL_PIN(358, "P PAD VDDIO 1"), + PINCTRL_PIN(359, "P PAD VSSIO 1"), + PINCTRL_PIN(360, "P PAD GND 1"), + PINCTRL_PIN(361, "P PAD VDD 1"), + PINCTRL_PIN(362, "PO EMIF 0 SD CKE"), + PINCTRL_PIN(363, "PO EMIF 0 SD DQML"), + PINCTRL_PIN(364, "PO EMIF 0 SD DQMU"), + PINCTRL_PIN(365, "PO EMIF 0 SD RAS N"), + PINCTRL_PIN(366, "PIO EMIF 0 D15"), + PINCTRL_PIN(367, "PO EMIF 0 A15"), + PINCTRL_PIN(368, "PIO EMIF 0 D14"), + PINCTRL_PIN(369, "PO EMIF 0 A14"), + PINCTRL_PIN(370, "PIO EMIF 0 D13"), + PINCTRL_PIN(371, "PO EMIF 0 A13"), + PINCTRL_PIN(372, "P PAD VDDIO 2"), + PINCTRL_PIN(373, "P PAD VSSIO 2"), + PINCTRL_PIN(374, "P PAD GND 2"), + PINCTRL_PIN(375, "P PAD VDD 2"), + PINCTRL_PIN(376, "PIO EMIF 0 D12"), + PINCTRL_PIN(377, "PO EMIF 0 A12"), + PINCTRL_PIN(378, "PIO EMIF 0 D11"), + PINCTRL_PIN(379, "PO EMIF 0 A11"), + PINCTRL_PIN(380, "PIO EMIF 0 D10"), + PINCTRL_PIN(381, "PO EMIF 0 A10"), + PINCTRL_PIN(382, "PIO EMIF 0 D09"), + PINCTRL_PIN(383, "PO EMIF 0 A09"), + PINCTRL_PIN(384, "PIO EMIF 0 D08"), + PINCTRL_PIN(385, "PO EMIF 0 A08"), + PINCTRL_PIN(386, "PIO EMIF 0 D07"), + PINCTRL_PIN(387, "PO EMIF 0 A07"), + PINCTRL_PIN(388, "P PAD VDDIO 3"), + PINCTRL_PIN(389, "P PAD VSSIO 3"), + PINCTRL_PIN(390, "P PAD GND 3"), + PINCTRL_PIN(391, "P PAD VDD 3"), + PINCTRL_PIN(392, "PO EFUSE RDOUT1"), + PINCTRL_PIN(393, "PIO EMIF 0 D06"), + PINCTRL_PIN(394, "PO EMIF 0 A06"), + PINCTRL_PIN(395, "PIO EMIF 0 D05"), + PINCTRL_PIN(396, "PO EMIF 0 A05"), + PINCTRL_PIN(397, "PIO EMIF 0 D04"), + PINCTRL_PIN(398, "PO EMIF 0 A04"), + PINCTRL_PIN(399, "A PADS/A VDDCO1v82v5 GND 80U SF LIN VDDCO AF"), + PINCTRL_PIN(400, "PWR VDDCO AF"), + PINCTRL_PIN(401, "PWR EFUSE HV1"), + PINCTRL_PIN(402, "P PAD VSSIO 4"), + PINCTRL_PIN(403, "P PAD VDDIO 4"), + PINCTRL_PIN(404, "P PAD GND 4"), + PINCTRL_PIN(405, "P PAD VDD 4"), + PINCTRL_PIN(406, "PIO EMIF 0 D03"), + PINCTRL_PIN(407, "PO EMIF 0 A03"), + PINCTRL_PIN(408, "PWR EFUSE HV2"), + PINCTRL_PIN(409, "PWR EFUSE HV3"), + PINCTRL_PIN(410, "PIO EMIF 0 D02"), + PINCTRL_PIN(411, "PO EMIF 0 A02"), + PINCTRL_PIN(412, "PIO EMIF 0 D01"), + PINCTRL_PIN(413, "P PAD VDDIO 5"), + PINCTRL_PIN(414, "P PAD VSSIO 5"), + PINCTRL_PIN(415, "P PAD GND 5"), + PINCTRL_PIN(416, "P PAD VDD 5"), + PINCTRL_PIN(417, "PO EMIF 0 A01"), + PINCTRL_PIN(418, "PIO EMIF 0 D00"), + PINCTRL_PIN(419, "IF 0 SD CLK"), + PINCTRL_PIN(420, "APP SPI CLK"), + PINCTRL_PIN(421, "APP SPI DO"), + PINCTRL_PIN(422, "APP SPI DI"), + PINCTRL_PIN(423, "APP SPI CS0"), + PINCTRL_PIN(424, "APP SPI CS1"), + PINCTRL_PIN(425, "APP SPI CS2"), + PINCTRL_PIN(426, "PIO APP GPIO 10"), + PINCTRL_PIN(427, "P PAD VDDIO 41"), + PINCTRL_PIN(428, "P PAD VSSIO 41"), + PINCTRL_PIN(429, "P PAD GND 6"), + PINCTRL_PIN(430, "P PAD VDD 6"), + PINCTRL_PIN(431, "PIO ACC SDIO0 CMD"), + PINCTRL_PIN(432, "PIO ACC SDIO0 CK"), + PINCTRL_PIN(433, "PIO ACC SDIO0 D3"), + PINCTRL_PIN(434, "PIO ACC SDIO0 D2"), + PINCTRL_PIN(435, "PIO ACC SDIO0 D1"), + PINCTRL_PIN(436, "PIO ACC SDIO0 D0"), + PINCTRL_PIN(437, "PIO USB PU"), + PINCTRL_PIN(438, "PIO USB SP"), + PINCTRL_PIN(439, "PIO USB DAT VP"), + PINCTRL_PIN(440, "PIO USB SE0 VM"), + PINCTRL_PIN(441, "PIO USB OE"), + PINCTRL_PIN(442, "PIO USB SUSP"), + PINCTRL_PIN(443, "P PAD VSSIO 6"), + PINCTRL_PIN(444, "P PAD VDDIO 6"), + PINCTRL_PIN(445, "PIO USB PUEN"), + PINCTRL_PIN(446, "PIO ACC UART0 RX"), + PINCTRL_PIN(447, "PIO ACC UART0 TX"), + PINCTRL_PIN(448, "PIO ACC UART0 CTS"), + PINCTRL_PIN(449, "PIO ACC UART0 RTS"), + PINCTRL_PIN(450, "PIO ACC UART3 RX"), + PINCTRL_PIN(451, "PIO ACC UART3 TX"), + PINCTRL_PIN(452, "PIO ACC UART3 CTS"), + PINCTRL_PIN(453, "PIO ACC UART3 RTS"), + PINCTRL_PIN(454, "PIO ACC IRDA TX"), + PINCTRL_PIN(455, "P PAD VDDIO 7"), + PINCTRL_PIN(456, "P PAD VSSIO 7"), + PINCTRL_PIN(457, "P PAD GND 7"), + PINCTRL_PIN(458, "P PAD VDD 7"), + PINCTRL_PIN(459, "PIO ACC IRDA RX"), + PINCTRL_PIN(460, "PIO ACC PCM I2S CLK"), + PINCTRL_PIN(461, "PIO ACC PCM I2S WS"), + PINCTRL_PIN(462, "PIO ACC PCM I2S DATA A"), + PINCTRL_PIN(463, "PIO ACC PCM I2S DATA B"), + PINCTRL_PIN(464, "PO SIM CLK"), + PINCTRL_PIN(465, "PIO ACC IRDA SD"), + PINCTRL_PIN(466, "PIO SIM DATA"), +}; + +/** + * @dev: a pointer back to containing device + * @virtbase: the offset to the controller in virtual memory + */ +struct u300_pmx { + struct device *dev; + struct pinctrl_dev *pctl; + u32 phybase; + u32 physize; + void __iomem *virtbase; +}; + +/** + * u300_pmx_registers - the array of registers read/written for each pinmux + * shunt setting + */ +const u32 u300_pmx_registers[] = { + U300_SYSCON_PMC1LR, + U300_SYSCON_PMC1HR, + U300_SYSCON_PMC2R, + U300_SYSCON_PMC3R, + U300_SYSCON_PMC4R, +}; + +/** + * struct u300_pin_group - describes a U300 pin group + * @name: the name of this specific pin group + * @pins: an array of discrete physical pins used in this group, taken + * from the driver-local pin enumeration space + * @num_pins: the number of pins in this group array, i.e. the number of + * elements in .pins so we can iterate over that array + */ +struct u300_pin_group { + const char *name; + const unsigned int *pins; + const unsigned num_pins; +}; + +/** + * struct pmx_onmask - mask bits to enable/disable padmux + * @mask: mask bits to disable + * @val: mask bits to enable + * + * onmask lazy dog: + * onmask = { + * {"PMC1LR" mask, "PMC1LR" value}, + * {"PMC1HR" mask, "PMC1HR" value}, + * {"PMC2R" mask, "PMC2R" value}, + * {"PMC3R" mask, "PMC3R" value}, + * {"PMC4R" mask, "PMC4R" value} + * } + */ +struct u300_pmx_mask { + u16 mask; + u16 bits; +}; + +/* The chip power pins are VDD, GND, VDDIO and VSSIO */ +static const unsigned power_pins[] = { 0, 1, 3, 31, 46, 47, 49, 50, 61, 62, 63, + 64, 78, 79, 80, 81, 92, 93, 94, 95, 101, 102, 103, 104, 115, 116, 117, + 118, 130, 131, 132, 133, 145, 146, 147, 148, 159, 160, 172, 173, 174, + 175, 187, 188, 189, 190, 201, 202, 211, 212, 213, 214, 215, 218, 223, + 224, 225, 226, 231, 232, 237, 238, 239, 240, 245, 246, 251, 252, 256, + 257, 258, 259, 264, 265, 270, 271, 276, 277, 278, 279, 284, 285, 290, + 291, 295, 296, 299, 300, 301, 302, 303, 309, 310, 311, 312, 319, 320, + 321, 322, 329, 330, 331, 332, 341, 342, 343, 344, 358, 359, 360, 361, + 372, 373, 374, 375, 388, 389, 390, 391, 402, 403, 404, 405, 413, 414, + 415, 416, 427, 428, 429, 430, 443, 444, 455, 456, 457, 458 }; +static const unsigned emif0_pins[] = { 355, 356, 357, 362, 363, 364, 365, 366, + 367, 368, 369, 370, 371, 376, 377, 378, 379, 380, 381, 382, 383, 384, + 385, 386, 387, 393, 394, 395, 396, 397, 398, 406, 407, 410, 411, 412, + 417, 418 }; +static const unsigned emif1_pins[] = { 216, 217, 219, 220, 221, 222, 227, 228, + 229, 230, 233, 234, 235, 236, 241, 242, 243, 244, 247, 248, 249, 250, + 253, 254, 255, 260, 261, 262, 263, 266, 267, 268, 269, 272, 273, 274, + 275, 280, 281, 282, 283, 286, 287, 288, 289, 292, 293, 294, 297, 298, + 304, 305, 306, 307, 308, 313, 314, 315 }; +static const unsigned uart0_pins[] = { 134, 135, 136, 137 }; +static const unsigned mmc0_pins[] = { 166, 167, 168, 169, 170, 171, 176, 177 }; +static const unsigned spi0_pins[] = { 420, 421, 422, 423, 424, 425 }; + +static const struct u300_pmx_mask emif0_mask[] = { + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, +}; + +static const struct u300_pmx_mask emif1_mask[] = { + /* + * This connects the SDRAM to CS2 and a NAND flash to + * CS0 on the EMIF. + */ + { + U300_SYSCON_PMC1LR_EMIF_1_CS2_MASK | + U300_SYSCON_PMC1LR_EMIF_1_CS1_MASK | + U300_SYSCON_PMC1LR_EMIF_1_CS0_MASK | + U300_SYSCON_PMC1LR_EMIF_1_MASK, + U300_SYSCON_PMC1LR_EMIF_1_CS2_SDRAM | + U300_SYSCON_PMC1LR_EMIF_1_CS1_STATIC | + U300_SYSCON_PMC1LR_EMIF_1_CS0_NFIF | + U300_SYSCON_PMC1LR_EMIF_1_SDRAM0 + }, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, +}; + +static const struct u300_pmx_mask uart0_mask[] = { + {0, 0}, + { + U300_SYSCON_PMC1HR_APP_UART0_1_MASK | + U300_SYSCON_PMC1HR_APP_UART0_2_MASK, + U300_SYSCON_PMC1HR_APP_UART0_1_UART0 | + U300_SYSCON_PMC1HR_APP_UART0_2_UART0 + }, + {0, 0}, + {0, 0}, + {0, 0}, +}; + +static const struct u300_pmx_mask mmc0_mask[] = { + { U300_SYSCON_PMC1LR_MMCSD_MASK, U300_SYSCON_PMC1LR_MMCSD_MMCSD}, + {0, 0}, + {0, 0}, + {0, 0}, + { U300_SYSCON_PMC4R_APP_MISC_12_MASK, + U300_SYSCON_PMC4R_APP_MISC_12_APP_GPIO } +}; + +static const struct u300_pmx_mask spi0_mask[] = { + {0, 0}, + { + U300_SYSCON_PMC1HR_APP_SPI_2_MASK | + U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK | + U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK, + U300_SYSCON_PMC1HR_APP_SPI_2_SPI | + U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI | + U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI + }, + {0, 0}, + {0, 0}, + {0, 0} +}; + +static const struct u300_pin_group u300_pin_groups[] = { + { + .name = "powergrp", + .pins = power_pins, + .num_pins = ARRAY_SIZE(power_pins), + }, + { + .name = "emif0grp", + .pins = emif0_pins, + .num_pins = ARRAY_SIZE(emif0_pins), + }, + { + .name = "emif1grp", + .pins = emif1_pins, + .num_pins = ARRAY_SIZE(emif1_pins), + }, + { + .name = "uart0grp", + .pins = uart0_pins, + .num_pins = ARRAY_SIZE(uart0_pins), + }, + { + .name = "mmc0grp", + .pins = mmc0_pins, + .num_pins = ARRAY_SIZE(mmc0_pins), + }, + { + .name = "spi0grp", + .pins = spi0_pins, + .num_pins = ARRAY_SIZE(spi0_pins), + }, +}; + +static int u300_list_groups(struct pinctrl_dev *pctldev, unsigned selector) +{ + if (selector >= ARRAY_SIZE(u300_pin_groups)) + return -EINVAL; + return 0; +} + +static const char *u300_get_group_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + if (selector >= ARRAY_SIZE(u300_pin_groups)) + return NULL; + return u300_pin_groups[selector].name; +} + +static int u300_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, + const unsigned **pins, + unsigned *num_pins) +{ + if (selector >= ARRAY_SIZE(u300_pin_groups)) + return -EINVAL; + *pins = u300_pin_groups[selector].pins; + *num_pins = u300_pin_groups[selector].num_pins; + return 0; +} + +static void u300_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, + unsigned offset) +{ + seq_printf(s, " " DRIVER_NAME); +} + +static struct pinctrl_ops u300_pctrl_ops = { + .list_groups = u300_list_groups, + .get_group_name = u300_get_group_name, + .get_group_pins = u300_get_group_pins, + .pin_dbg_show = u300_pin_dbg_show, +}; + +/* + * Here we define the available functions and their corresponding pin groups + */ + +/** + * struct u300_pmx_func - describes U300 pinmux functions + * @name: the name of this specific function + * @groups: corresponding pin groups + * @onmask: bits to set to enable this when doing pin muxing + */ +struct u300_pmx_func { + const char *name; + const char * const *groups; + const unsigned num_groups; + const struct u300_pmx_mask *mask; +}; + +static const char * const powergrps[] = { "powergrp" }; +static const char * const emif0grps[] = { "emif0grp" }; +static const char * const emif1grps[] = { "emif1grp" }; +static const char * const uart0grps[] = { "uart0grp" }; +static const char * const mmc0grps[] = { "mmc0grp" }; +static const char * const spi0grps[] = { "spi0grp" }; + +static const struct u300_pmx_func u300_pmx_functions[] = { + { + .name = "power", + .groups = powergrps, + .num_groups = ARRAY_SIZE(powergrps), + /* Mask is N/A */ + }, + { + .name = "emif0", + .groups = emif0grps, + .num_groups = ARRAY_SIZE(emif0grps), + .mask = emif0_mask, + }, + { + .name = "emif1", + .groups = emif1grps, + .num_groups = ARRAY_SIZE(emif1grps), + .mask = emif1_mask, + }, + { + .name = "uart0", + .groups = uart0grps, + .num_groups = ARRAY_SIZE(uart0grps), + .mask = uart0_mask, + }, + { + .name = "mmc0", + .groups = mmc0grps, + .num_groups = ARRAY_SIZE(mmc0grps), + .mask = mmc0_mask, + }, + { + .name = "spi0", + .groups = spi0grps, + .num_groups = ARRAY_SIZE(spi0grps), + .mask = spi0_mask, + }, +}; + +static void u300_pmx_endisable(struct u300_pmx *upmx, unsigned selector, + bool enable) +{ + u16 regval, val, mask; + int i; + const struct u300_pmx_mask *upmx_mask; + + upmx_mask = u300_pmx_functions[selector].mask; + for (i = 0; i < ARRAY_SIZE(u300_pmx_registers); i++) { + if (enable) + val = upmx_mask->bits; + else + val = 0; + + mask = upmx_mask->mask; + if (mask != 0) { + regval = readw(upmx->virtbase + u300_pmx_registers[i]); + regval &= ~mask; + regval |= val; + writew(regval, upmx->virtbase + u300_pmx_registers[i]); + } + upmx_mask++; + } +} + +static int u300_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, + unsigned group) +{ + struct u300_pmx *upmx; + + /* There is nothing to do with the power pins */ + if (selector == 0) + return 0; + + upmx = pinctrl_dev_get_drvdata(pctldev); + u300_pmx_endisable(upmx, selector, true); + + return 0; +} + +static void u300_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector, + unsigned group) +{ + struct u300_pmx *upmx; + + /* There is nothing to do with the power pins */ + if (selector == 0) + return; + + upmx = pinctrl_dev_get_drvdata(pctldev); + u300_pmx_endisable(upmx, selector, false); +} + +static int u300_pmx_list_funcs(struct pinctrl_dev *pctldev, unsigned selector) +{ + if (selector >= ARRAY_SIZE(u300_pmx_functions)) + return -EINVAL; + return 0; +} + +static const char *u300_pmx_get_func_name(struct pinctrl_dev *pctldev, + unsigned selector) +{ + return u300_pmx_functions[selector].name; +} + +static int u300_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, + const char * const **groups, + unsigned * const num_groups) +{ + *groups = u300_pmx_functions[selector].groups; + *num_groups = u300_pmx_functions[selector].num_groups; + return 0; +} + +static struct pinmux_ops u300_pmx_ops = { + .list_functions = u300_pmx_list_funcs, + .get_function_name = u300_pmx_get_func_name, + .get_function_groups = u300_pmx_get_groups, + .enable = u300_pmx_enable, + .disable = u300_pmx_disable, +}; + +/* + * GPIO ranges handled by the application-side COH901XXX GPIO controller + * Very many pins can be converted into GPIO pins, but we only list those + * that are useful in practice to cut down on tables. + */ +#define U300_GPIO_RANGE(a, b, c) { .name = "COH901XXX", .id = a, .base= a, \ + .pin_base = b, .npins = c } + +static struct pinctrl_gpio_range u300_gpio_ranges[] = { + U300_GPIO_RANGE(10, 426, 1), + U300_GPIO_RANGE(11, 180, 1), + U300_GPIO_RANGE(12, 165, 1), /* MS/MMC card insertion */ + U300_GPIO_RANGE(13, 179, 1), + U300_GPIO_RANGE(14, 178, 1), + U300_GPIO_RANGE(16, 194, 1), + U300_GPIO_RANGE(17, 193, 1), + U300_GPIO_RANGE(18, 192, 1), + U300_GPIO_RANGE(19, 191, 1), + U300_GPIO_RANGE(20, 186, 1), + U300_GPIO_RANGE(21, 185, 1), + U300_GPIO_RANGE(22, 184, 1), + U300_GPIO_RANGE(23, 183, 1), + U300_GPIO_RANGE(24, 182, 1), + U300_GPIO_RANGE(25, 181, 1), +}; + +static struct pinctrl_desc u300_pmx_desc = { + .name = DRIVER_NAME, + .pins = u300_pads, + .npins = ARRAY_SIZE(u300_pads), + .maxpin = U300_NUM_PADS-1, + .pctlops = &u300_pctrl_ops, + .pmxops = &u300_pmx_ops, + .owner = THIS_MODULE, +}; + +static int __init u300_pmx_probe(struct platform_device *pdev) +{ + struct u300_pmx *upmx; + struct resource *res; + int ret; + int i; + + /* Create state holders etc for this driver */ + upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL); + if (!upmx) + return -ENOMEM; + + upmx->dev = &pdev->dev; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) { + ret = -ENOENT; + goto out_no_resource; + } + upmx->phybase = res->start; + upmx->physize = resource_size(res); + + if (request_mem_region(upmx->phybase, upmx->physize, + DRIVER_NAME) == NULL) { + ret = -ENOMEM; + goto out_no_memregion; + } + + upmx->virtbase = ioremap(upmx->phybase, upmx->physize); + if (!upmx->virtbase) { + ret = -ENOMEM; + goto out_no_remap; + } + + upmx->pctl = pinctrl_register(&u300_pmx_desc, &pdev->dev, upmx); + if (!upmx->pctl) { + dev_err(&pdev->dev, "could not register U300 pinmux driver\n"); + ret = -EINVAL; + goto out_no_pmx; + } + + /* We will handle a range of GPIO pins */ + for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) + pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]); + + platform_set_drvdata(pdev, upmx); + + dev_info(&pdev->dev, "initialized U300 pinmux driver\n"); + + return 0; + +out_no_pmx: + iounmap(upmx->virtbase); +out_no_remap: + platform_set_drvdata(pdev, NULL); +out_no_memregion: + release_mem_region(upmx->phybase, upmx->physize); +out_no_resource: + devm_kfree(&pdev->dev, upmx); + return ret; +} + +static int __exit u300_pmx_remove(struct platform_device *pdev) +{ + struct u300_pmx *upmx = platform_get_drvdata(pdev); + int i; + + for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) + pinctrl_remove_gpio_range(upmx->pctl, &u300_gpio_ranges[i]); + pinctrl_unregister(upmx->pctl); + iounmap(upmx->virtbase); + release_mem_region(upmx->phybase, upmx->physize); + platform_set_drvdata(pdev, NULL); + devm_kfree(&pdev->dev, upmx); + + return 0; +} + +static struct platform_driver u300_pmx_driver = { + .driver = { + .name = DRIVER_NAME, + .owner = THIS_MODULE, + }, + .remove = __exit_p(u300_pmx_remove), +}; + +static int __init u300_pmx_init(void) +{ + return platform_driver_probe(&u300_pmx_driver, u300_pmx_probe); +} +arch_initcall(u300_pmx_init); + +static void __exit u300_pmx_exit(void) +{ + platform_driver_unregister(&u300_pmx_driver); +} +module_exit(u300_pmx_exit); + +MODULE_AUTHOR("Linus Walleij "); +MODULE_DESCRIPTION("U300 pin control driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/pinctrl/pinmux-sirf.c b/drivers/pinctrl/pinmux-sirf.c deleted file mode 100644 index 99e688e..0000000 --- a/drivers/pinctrl/pinmux-sirf.c +++ /dev/null @@ -1,1219 +0,0 @@ -/* - * pinmux driver for CSR SiRFprimaII - * - * Copyright (c) 2011 Cambridge Silicon Radio Limited, a CSR plc group company. - * - * Licensed under GPLv2 or later. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRIVER_NAME "pinmux-sirf" - -#define SIRFSOC_NUM_PADS 622 -#define SIRFSOC_GPIO_PAD_EN(g) ((g)*0x100 + 0x84) -#define SIRFSOC_RSC_PIN_MUX 0x4 - -/* - * pad list for the pinmux subsystem - * refer to CS-131858-DC-6A.xls - */ -static const struct pinctrl_pin_desc sirfsoc_pads[] = { - PINCTRL_PIN(4, "pwm0"), - PINCTRL_PIN(5, "pwm1"), - PINCTRL_PIN(6, "pwm2"), - PINCTRL_PIN(7, "pwm3"), - PINCTRL_PIN(8, "warm_rst_b"), - PINCTRL_PIN(9, "odo_0"), - PINCTRL_PIN(10, "odo_1"), - PINCTRL_PIN(11, "dr_dir"), - PINCTRL_PIN(13, "scl_1"), - PINCTRL_PIN(15, "sda_1"), - PINCTRL_PIN(16, "x_ldd[16]"), - PINCTRL_PIN(17, "x_ldd[17]"), - PINCTRL_PIN(18, "x_ldd[18]"), - PINCTRL_PIN(19, "x_ldd[19]"), - PINCTRL_PIN(20, "x_ldd[20]"), - PINCTRL_PIN(21, "x_ldd[21]"), - PINCTRL_PIN(22, "x_ldd[22]"), - PINCTRL_PIN(23, "x_ldd[23], lcdrom_frdy"), - PINCTRL_PIN(24, "gps_sgn"), - PINCTRL_PIN(25, "gps_mag"), - PINCTRL_PIN(26, "gps_clk"), - PINCTRL_PIN(27, "sd_cd_b_1"), - PINCTRL_PIN(28, "sd_vcc_on_1"), - PINCTRL_PIN(29, "sd_wp_b_1"), - PINCTRL_PIN(30, "sd_clk_3"), - PINCTRL_PIN(31, "sd_cmd_3"), - - PINCTRL_PIN(32, "x_sd_dat_3[0]"), - PINCTRL_PIN(33, "x_sd_dat_3[1]"), - PINCTRL_PIN(34, "x_sd_dat_3[2]"), - PINCTRL_PIN(35, "x_sd_dat_3[3]"), - PINCTRL_PIN(36, "x_sd_clk_4"), - PINCTRL_PIN(37, "x_sd_cmd_4"), - PINCTRL_PIN(38, "x_sd_dat_4[0]"), - PINCTRL_PIN(39, "x_sd_dat_4[1]"), - PINCTRL_PIN(40, "x_sd_dat_4[2]"), - PINCTRL_PIN(41, "x_sd_dat_4[3]"), - PINCTRL_PIN(42, "x_cko_1"), - PINCTRL_PIN(43, "x_ac97_bit_clk"), - PINCTRL_PIN(44, "x_ac97_dout"), - PINCTRL_PIN(45, "x_ac97_din"), - PINCTRL_PIN(46, "x_ac97_sync"), - PINCTRL_PIN(47, "x_txd_1"), - PINCTRL_PIN(48, "x_txd_2"), - PINCTRL_PIN(49, "x_rxd_1"), - PINCTRL_PIN(50, "x_rxd_2"), - PINCTRL_PIN(51, "x_usclk_0"), - PINCTRL_PIN(52, "x_utxd_0"), - PINCTRL_PIN(53, "x_urxd_0"), - PINCTRL_PIN(54, "x_utfs_0"), - PINCTRL_PIN(55, "x_urfs_0"), - PINCTRL_PIN(56, "x_usclk_1"), - PINCTRL_PIN(57, "x_utxd_1"), - PINCTRL_PIN(58, "x_urxd_1"), - PINCTRL_PIN(59, "x_utfs_1"), - PINCTRL_PIN(60, "x_urfs_1"), - PINCTRL_PIN(61, "x_usclk_2"), - PINCTRL_PIN(62, "x_utxd_2"), - PINCTRL_PIN(63, "x_urxd_2"), - - PINCTRL_PIN(64, "x_utfs_2"), - PINCTRL_PIN(65, "x_urfs_2"), - PINCTRL_PIN(66, "x_df_we_b"), - PINCTRL_PIN(67, "x_df_re_b"), - PINCTRL_PIN(68, "x_txd_0"), - PINCTRL_PIN(69, "x_rxd_0"), - PINCTRL_PIN(78, "x_cko_0"), - PINCTRL_PIN(79, "x_vip_pxd[7]"), - PINCTRL_PIN(80, "x_vip_pxd[6]"), - PINCTRL_PIN(81, "x_vip_pxd[5]"), - PINCTRL_PIN(82, "x_vip_pxd[4]"), - PINCTRL_PIN(83, "x_vip_pxd[3]"), - PINCTRL_PIN(84, "x_vip_pxd[2]"), - PINCTRL_PIN(85, "x_vip_pxd[1]"), - PINCTRL_PIN(86, "x_vip_pxd[0]"), - PINCTRL_PIN(87, "x_vip_vsync"), - PINCTRL_PIN(88, "x_vip_hsync"), - PINCTRL_PIN(89, "x_vip_pxclk"), - PINCTRL_PIN(90, "x_sda_0"), - PINCTRL_PIN(91, "x_scl_0"), - PINCTRL_PIN(92, "x_df_ry_by"), - PINCTRL_PIN(93, "x_df_cs_b[1]"), - PINCTRL_PIN(94, "x_df_cs_b[0]"), - PINCTRL_PIN(95, "x_l_pclk"), - - PINCTRL_PIN(96, "x_l_lck"), - PINCTRL_PIN(97, "x_l_fck"), - PINCTRL_PIN(98, "x_l_de"), - PINCTRL_PIN(99, "x_ldd[0]"), - PINCTRL_PIN(100, "x_ldd[1]"), - PINCTRL_PIN(101, "x_ldd[2]"), - PINCTRL_PIN(102, "x_ldd[3]"), - PINCTRL_PIN(103, "x_ldd[4]"), - PINCTRL_PIN(104, "x_ldd[5]"), - PINCTRL_PIN(105, "x_ldd[6]"), - PINCTRL_PIN(106, "x_ldd[7]"), - PINCTRL_PIN(107, "x_ldd[8]"), - PINCTRL_PIN(108, "x_ldd[9]"), - PINCTRL_PIN(109, "x_ldd[10]"), - PINCTRL_PIN(110, "x_ldd[11]"), - PINCTRL_PIN(111, "x_ldd[12]"), - PINCTRL_PIN(112, "x_ldd[13]"), - PINCTRL_PIN(113, "x_ldd[14]"), - PINCTRL_PIN(114, "x_ldd[15]"), -}; - -/** - * @dev: a pointer back to containing device - * @virtbase: the offset to the controller in virtual memory - */ -struct sirfsoc_pmx { - struct device *dev; - struct pinctrl_dev *pmx; - void __iomem *gpio_virtbase; - void __iomem *rsc_virtbase; -}; - -/* SIRFSOC_GPIO_PAD_EN set */ -struct sirfsoc_muxmask { - unsigned long group; - unsigned long mask; -}; - -struct sirfsoc_padmux { - unsigned long muxmask_counts; - const struct sirfsoc_muxmask *muxmask; - /* RSC_PIN_MUX set */ - unsigned long funcmask; - unsigned long funcval; -}; - - /** - * struct sirfsoc_pin_group - describes a SiRFprimaII pin group - * @name: the name of this specific pin group - * @pins: an array of discrete physical pins used in this group, taken - * from the driver-local pin enumeration space - * @num_pins: the number of pins in this group array, i.e. the number of - * elements in .pins so we can iterate over that array - */ -struct sirfsoc_pin_group { - const char *name; - const unsigned int *pins; - const unsigned num_pins; -}; - -static const struct sirfsoc_muxmask lcd_16bits_sirfsoc_muxmask[] = { - { - .group = 3, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | - BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | - BIT(17) | BIT(18), - }, { - .group = 2, - .mask = BIT(31), - }, -}; - -static const struct sirfsoc_padmux lcd_16bits_padmux = { - .muxmask_counts = ARRAY_SIZE(lcd_16bits_sirfsoc_muxmask), - .muxmask = lcd_16bits_sirfsoc_muxmask, - .funcmask = BIT(4), - .funcval = 0, -}; - -static const unsigned lcd_16bits_pins[] = { 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114 }; - -static const struct sirfsoc_muxmask lcd_18bits_muxmask[] = { - { - .group = 3, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | - BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | - BIT(17) | BIT(18), - }, { - .group = 2, - .mask = BIT(31), - }, { - .group = 0, - .mask = BIT(16) | BIT(17), - }, -}; - -static const struct sirfsoc_padmux lcd_18bits_padmux = { - .muxmask_counts = ARRAY_SIZE(lcd_18bits_muxmask), - .muxmask = lcd_18bits_muxmask, - .funcmask = BIT(4), - .funcval = 0, -}; - -static const unsigned lcd_18bits_pins[] = { 16, 17, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114}; - -static const struct sirfsoc_muxmask lcd_24bits_muxmask[] = { - { - .group = 3, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | - BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | - BIT(17) | BIT(18), - }, { - .group = 2, - .mask = BIT(31), - }, { - .group = 0, - .mask = BIT(16) | BIT(17) | BIT(18) | BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23), - }, -}; - -static const struct sirfsoc_padmux lcd_24bits_padmux = { - .muxmask_counts = ARRAY_SIZE(lcd_24bits_muxmask), - .muxmask = lcd_24bits_muxmask, - .funcmask = BIT(4), - .funcval = 0, -}; - -static const unsigned lcd_24bits_pins[] = { 16, 17, 18, 19, 20, 21, 22, 23, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114 }; - -static const struct sirfsoc_muxmask lcdrom_muxmask[] = { - { - .group = 3, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3) | BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | - BIT(9) | BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(15) | BIT(16) | - BIT(17) | BIT(18), - }, { - .group = 2, - .mask = BIT(31), - }, { - .group = 0, - .mask = BIT(23), - }, -}; - -static const struct sirfsoc_padmux lcdrom_padmux = { - .muxmask_counts = ARRAY_SIZE(lcdrom_muxmask), - .muxmask = lcdrom_muxmask, - .funcmask = BIT(4), - .funcval = BIT(4), -}; - -static const unsigned lcdrom_pins[] = { 23, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 110, 111, 112, 113, 114 }; - -static const struct sirfsoc_muxmask uart0_muxmask[] = { - { - .group = 2, - .mask = BIT(4) | BIT(5), - }, { - .group = 1, - .mask = BIT(23) | BIT(28), - }, -}; - -static const struct sirfsoc_padmux uart0_padmux = { - .muxmask_counts = ARRAY_SIZE(uart0_muxmask), - .muxmask = uart0_muxmask, - .funcmask = BIT(9), - .funcval = BIT(9), -}; - -static const unsigned uart0_pins[] = { 55, 60, 68, 69 }; - -static const struct sirfsoc_muxmask uart0_nostreamctrl_muxmask[] = { - { - .group = 2, - .mask = BIT(4) | BIT(5), - }, -}; - -static const struct sirfsoc_padmux uart0_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(uart0_nostreamctrl_muxmask), - .muxmask = uart0_nostreamctrl_muxmask, -}; - -static const unsigned uart0_nostreamctrl_pins[] = { 68, 39 }; - -static const struct sirfsoc_muxmask uart1_muxmask[] = { - { - .group = 1, - .mask = BIT(15) | BIT(17), - }, -}; - -static const struct sirfsoc_padmux uart1_padmux = { - .muxmask_counts = ARRAY_SIZE(uart1_muxmask), - .muxmask = uart1_muxmask, -}; - -static const unsigned uart1_pins[] = { 47, 49 }; - -static const struct sirfsoc_muxmask uart2_muxmask[] = { - { - .group = 1, - .mask = BIT(16) | BIT(18) | BIT(24) | BIT(27), - }, -}; - -static const struct sirfsoc_padmux uart2_padmux = { - .muxmask_counts = ARRAY_SIZE(uart2_muxmask), - .muxmask = uart2_muxmask, - .funcmask = BIT(10), - .funcval = BIT(10), -}; - -static const unsigned uart2_pins[] = { 48, 50, 56, 59 }; - -static const struct sirfsoc_muxmask uart2_nostreamctrl_muxmask[] = { - { - .group = 1, - .mask = BIT(16) | BIT(18), - }, -}; - -static const struct sirfsoc_padmux uart2_nostreamctrl_padmux = { - .muxmask_counts = ARRAY_SIZE(uart2_nostreamctrl_muxmask), - .muxmask = uart2_nostreamctrl_muxmask, -}; - -static const unsigned uart2_nostreamctrl_pins[] = { 48, 50 }; - -static const struct sirfsoc_muxmask sdmmc3_muxmask[] = { - { - .group = 0, - .mask = BIT(30) | BIT(31), - }, { - .group = 1, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), - }, -}; - -static const struct sirfsoc_padmux sdmmc3_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc3_muxmask), - .muxmask = sdmmc3_muxmask, - .funcmask = BIT(7), - .funcval = 0, -}; - -static const unsigned sdmmc3_pins[] = { 30, 31, 32, 33, 34, 35 }; - -static const struct sirfsoc_muxmask spi0_muxmask[] = { - { - .group = 1, - .mask = BIT(0) | BIT(1) | BIT(2) | BIT(3), - }, -}; - -static const struct sirfsoc_padmux spi0_padmux = { - .muxmask_counts = ARRAY_SIZE(spi0_muxmask), - .muxmask = spi0_muxmask, - .funcmask = BIT(7), - .funcval = BIT(7), -}; - -static const unsigned spi0_pins[] = { 32, 33, 34, 35 }; - -static const struct sirfsoc_muxmask sdmmc4_muxmask[] = { - { - .group = 1, - .mask = BIT(4) | BIT(5) | BIT(6) | BIT(7) | BIT(8) | BIT(9), - }, -}; - -static const struct sirfsoc_padmux sdmmc4_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc4_muxmask), - .muxmask = sdmmc4_muxmask, -}; - -static const unsigned sdmmc4_pins[] = { 36, 37, 38, 39, 40, 41 }; - -static const struct sirfsoc_muxmask cko1_muxmask[] = { - { - .group = 1, - .mask = BIT(10), - }, -}; - -static const struct sirfsoc_padmux cko1_padmux = { - .muxmask_counts = ARRAY_SIZE(cko1_muxmask), - .muxmask = cko1_muxmask, - .funcmask = BIT(3), - .funcval = 0, -}; - -static const unsigned cko1_pins[] = { 42 }; - -static const struct sirfsoc_muxmask i2s_muxmask[] = { - { - .group = 1, - .mask = - BIT(10) | BIT(11) | BIT(12) | BIT(13) | BIT(14) | BIT(19) - | BIT(23) | BIT(28), - }, -}; - -static const struct sirfsoc_padmux i2s_padmux = { - .muxmask_counts = ARRAY_SIZE(i2s_muxmask), - .muxmask = i2s_muxmask, - .funcmask = BIT(3) | BIT(9), - .funcval = BIT(3), -}; - -static const unsigned i2s_pins[] = { 42, 43, 44, 45, 46, 51, 55, 60 }; - -static const struct sirfsoc_muxmask ac97_muxmask[] = { - { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), - }, -}; - -static const struct sirfsoc_padmux ac97_padmux = { - .muxmask_counts = ARRAY_SIZE(ac97_muxmask), - .muxmask = ac97_muxmask, - .funcmask = BIT(8), - .funcval = 0, -}; - -static const unsigned ac97_pins[] = { 33, 34, 35, 36 }; - -static const struct sirfsoc_muxmask spi1_muxmask[] = { - { - .group = 1, - .mask = BIT(11) | BIT(12) | BIT(13) | BIT(14), - }, -}; - -static const struct sirfsoc_padmux spi1_padmux = { - .muxmask_counts = ARRAY_SIZE(spi1_muxmask), - .muxmask = spi1_muxmask, - .funcmask = BIT(8), - .funcval = BIT(8), -}; - -static const unsigned spi1_pins[] = { 43, 44, 45, 46 }; - -static const struct sirfsoc_muxmask sdmmc1_muxmask[] = { - { - .group = 0, - .mask = BIT(27) | BIT(28) | BIT(29), - }, -}; - -static const struct sirfsoc_padmux sdmmc1_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc1_muxmask), - .muxmask = sdmmc1_muxmask, -}; - -static const unsigned sdmmc1_pins[] = { 27, 28, 29 }; - -static const struct sirfsoc_muxmask gps_muxmask[] = { - { - .group = 0, - .mask = BIT(24) | BIT(25) | BIT(26), - }, -}; - -static const struct sirfsoc_padmux gps_padmux = { - .muxmask_counts = ARRAY_SIZE(gps_muxmask), - .muxmask = gps_muxmask, - .funcmask = BIT(12) | BIT(13) | BIT(14), - .funcval = BIT(12), -}; - -static const unsigned gps_pins[] = { 24, 25, 26 }; - -static const struct sirfsoc_muxmask sdmmc5_muxmask[] = { - { - .group = 0, - .mask = BIT(24) | BIT(25) | BIT(26), - }, { - .group = 1, - .mask = BIT(29), - }, { - .group = 2, - .mask = BIT(0) | BIT(1), - }, -}; - -static const struct sirfsoc_padmux sdmmc5_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc5_muxmask), - .muxmask = sdmmc5_muxmask, - .funcmask = BIT(13) | BIT(14), - .funcval = BIT(13) | BIT(14), -}; - -static const unsigned sdmmc5_pins[] = { 24, 25, 26, 61, 64, 65 }; - -static const struct sirfsoc_muxmask usp0_muxmask[] = { - { - .group = 1, - .mask = BIT(19) | BIT(20) | BIT(21) | BIT(22) | BIT(23), - }, -}; - -static const struct sirfsoc_padmux usp0_padmux = { - .muxmask_counts = ARRAY_SIZE(usp0_muxmask), - .muxmask = usp0_muxmask, - .funcmask = BIT(1) | BIT(2) | BIT(6) | BIT(9), - .funcval = 0, -}; - -static const unsigned usp0_pins[] = { 51, 52, 53, 54, 55 }; - -static const struct sirfsoc_muxmask usp1_muxmask[] = { - { - .group = 1, - .mask = BIT(24) | BIT(25) | BIT(26) | BIT(27) | BIT(28), - }, -}; - -static const struct sirfsoc_padmux usp1_padmux = { - .muxmask_counts = ARRAY_SIZE(usp1_muxmask), - .muxmask = usp1_muxmask, - .funcmask = BIT(1) | BIT(9) | BIT(10) | BIT(11), - .funcval = 0, -}; - -static const unsigned usp1_pins[] = { 56, 57, 58, 59, 60 }; - -static const struct sirfsoc_muxmask usp2_muxmask[] = { - { - .group = 1, - .mask = BIT(29) | BIT(30) | BIT(31), - }, { - .group = 2, - .mask = BIT(0) | BIT(1), - }, -}; - -static const struct sirfsoc_padmux usp2_padmux = { - .muxmask_counts = ARRAY_SIZE(usp2_muxmask), - .muxmask = usp2_muxmask, - .funcmask = BIT(13) | BIT(14), - .funcval = 0, -}; - -static const unsigned usp2_pins[] = { 61, 62, 63, 64, 65 }; - -static const struct sirfsoc_muxmask nand_muxmask[] = { - { - .group = 2, - .mask = BIT(2) | BIT(3) | BIT(28) | BIT(29) | BIT(30), - }, -}; - -static const struct sirfsoc_padmux nand_padmux = { - .muxmask_counts = ARRAY_SIZE(nand_muxmask), - .muxmask = nand_muxmask, - .funcmask = BIT(5), - .funcval = 0, -}; - -static const unsigned nand_pins[] = { 64, 65, 92, 93, 94 }; - -static const struct sirfsoc_padmux sdmmc0_padmux = { - .muxmask_counts = 0, - .funcmask = BIT(5), - .funcval = 0, -}; - -static const unsigned sdmmc0_pins[] = { }; - -static const struct sirfsoc_muxmask sdmmc2_muxmask[] = { - { - .group = 2, - .mask = BIT(2) | BIT(3), - }, -}; - -static const struct sirfsoc_padmux sdmmc2_padmux = { - .muxmask_counts = ARRAY_SIZE(sdmmc2_muxmask), - .muxmask = sdmmc2_muxmask, - .funcmask = BIT(5), - .funcval = BIT(5), -}; - -static const unsigned sdmmc2_pins[] = { 66, 67 }; - -static const struct sirfsoc_muxmask cko0_muxmask[] = { - { - .group = 2, - .mask = BIT(14), - }, -}; - -static const struct sirfsoc_padmux cko0_padmux = { - .muxmask_counts = ARRAY_SIZE(cko0_muxmask), - .muxmask = cko0_muxmask, -}; - -static const unsigned cko0_pins[] = { 78 }; - -static const struct sirfsoc_muxmask vip_muxmask[] = { - { - .group = 2, - .mask = BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) - | BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) | - BIT(25), - }, -}; - -static const struct sirfsoc_padmux vip_padmux = { - .muxmask_counts = ARRAY_SIZE(vip_muxmask), - .muxmask = vip_muxmask, - .funcmask = BIT(0), - .funcval = 0, -}; - -static const unsigned vip_pins[] = { 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89 }; - -static const struct sirfsoc_muxmask i2c0_muxmask[] = { - { - .group = 2, - .mask = BIT(26) | BIT(27), - }, -}; - -static const struct sirfsoc_padmux i2c0_padmux = { - .muxmask_counts = ARRAY_SIZE(i2c0_muxmask), - .muxmask = i2c0_muxmask, -}; - -static const unsigned i2c0_pins[] = { 90, 91 }; - -static const struct sirfsoc_muxmask i2c1_muxmask[] = { - { - .group = 0, - .mask = BIT(13) | BIT(15), - }, -}; - -static const struct sirfsoc_padmux i2c1_padmux = { - .muxmask_counts = ARRAY_SIZE(i2c1_muxmask), - .muxmask = i2c1_muxmask, -}; - -static const unsigned i2c1_pins[] = { 13, 15 }; - -static const struct sirfsoc_muxmask viprom_muxmask[] = { - { - .group = 2, - .mask = BIT(15) | BIT(16) | BIT(17) | BIT(18) | BIT(19) - | BIT(20) | BIT(21) | BIT(22) | BIT(23) | BIT(24) | - BIT(25), - }, { - .group = 0, - .mask = BIT(12), - }, -}; - -static const struct sirfsoc_padmux viprom_padmux = { - .muxmask_counts = ARRAY_SIZE(viprom_muxmask), - .muxmask = viprom_muxmask, - .funcmask = BIT(0), - .funcval = BIT(0), -}; - -static const unsigned viprom_pins[] = { 12, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89 }; - -static const struct sirfsoc_muxmask pwm0_muxmask[] = { - { - .group = 0, - .mask = BIT(4), - }, -}; - -static const struct sirfsoc_padmux pwm0_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm0_muxmask), - .muxmask = pwm0_muxmask, - .funcmask = BIT(12), - .funcval = 0, -}; - -static const unsigned pwm0_pins[] = { 4 }; - -static const struct sirfsoc_muxmask pwm1_muxmask[] = { - { - .group = 0, - .mask = BIT(5), - }, -}; - -static const struct sirfsoc_padmux pwm1_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm1_muxmask), - .muxmask = pwm1_muxmask, -}; - -static const unsigned pwm1_pins[] = { 5 }; - -static const struct sirfsoc_muxmask pwm2_muxmask[] = { - { - .group = 0, - .mask = BIT(6), - }, -}; - -static const struct sirfsoc_padmux pwm2_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm2_muxmask), - .muxmask = pwm2_muxmask, -}; - -static const unsigned pwm2_pins[] = { 6 }; - -static const struct sirfsoc_muxmask pwm3_muxmask[] = { - { - .group = 0, - .mask = BIT(7), - }, -}; - -static const struct sirfsoc_padmux pwm3_padmux = { - .muxmask_counts = ARRAY_SIZE(pwm3_muxmask), - .muxmask = pwm3_muxmask, -}; - -static const unsigned pwm3_pins[] = { 7 }; - -static const struct sirfsoc_muxmask warm_rst_muxmask[] = { - { - .group = 0, - .mask = BIT(8), - }, -}; - -static const struct sirfsoc_padmux warm_rst_padmux = { - .muxmask_counts = ARRAY_SIZE(warm_rst_muxmask), - .muxmask = warm_rst_muxmask, -}; - -static const unsigned warm_rst_pins[] = { 8 }; - -static const struct sirfsoc_muxmask usb0_utmi_drvbus_muxmask[] = { - { - .group = 1, - .mask = BIT(22), - }, -}; -static const struct sirfsoc_padmux usb0_utmi_drvbus_padmux = { - .muxmask_counts = ARRAY_SIZE(usb0_utmi_drvbus_muxmask), - .muxmask = usb0_utmi_drvbus_muxmask, - .funcmask = BIT(6), - .funcval = BIT(6), /* refer to PAD_UTMI_DRVVBUS0_ENABLE */ -}; - -static const unsigned usb0_utmi_drvbus_pins[] = { 54 }; - -static const struct sirfsoc_muxmask usb1_utmi_drvbus_muxmask[] = { - { - .group = 1, - .mask = BIT(27), - }, -}; - -static const struct sirfsoc_padmux usb1_utmi_drvbus_padmux = { - .muxmask_counts = ARRAY_SIZE(usb1_utmi_drvbus_muxmask), - .muxmask = usb1_utmi_drvbus_muxmask, - .funcmask = BIT(11), - .funcval = BIT(11), /* refer to PAD_UTMI_DRVVBUS1_ENABLE */ -}; - -static const unsigned usb1_utmi_drvbus_pins[] = { 59 }; - -static const struct sirfsoc_muxmask pulse_count_muxmask[] = { - { - .group = 0, - .mask = BIT(9) | BIT(10) | BIT(11), - }, -}; - -static const struct sirfsoc_padmux pulse_count_padmux = { - .muxmask_counts = ARRAY_SIZE(pulse_count_muxmask), - .muxmask = pulse_count_muxmask, -}; - -static const unsigned pulse_count_pins[] = { 9, 10, 11 }; - -#define SIRFSOC_PIN_GROUP(n, p) \ - { \ - .name = n, \ - .pins = p, \ - .num_pins = ARRAY_SIZE(p), \ - } - -static const struct sirfsoc_pin_group sirfsoc_pin_groups[] = { - SIRFSOC_PIN_GROUP("lcd_16bitsgrp", lcd_16bits_pins), - SIRFSOC_PIN_GROUP("lcd_18bitsgrp", lcd_18bits_pins), - SIRFSOC_PIN_GROUP("lcd_24bitsgrp", lcd_24bits_pins), - SIRFSOC_PIN_GROUP("lcdrom_grp", lcdrom_pins), - SIRFSOC_PIN_GROUP("uart0grp", uart0_pins), - SIRFSOC_PIN_GROUP("uart1grp", uart1_pins), - SIRFSOC_PIN_GROUP("uart2grp", uart2_pins), - SIRFSOC_PIN_GROUP("uart2_nostreamctrlgrp", uart2_nostreamctrl_pins), - SIRFSOC_PIN_GROUP("usp0grp", usp0_pins), - SIRFSOC_PIN_GROUP("usp1grp", usp1_pins), - SIRFSOC_PIN_GROUP("usp2grp", usp2_pins), - SIRFSOC_PIN_GROUP("i2c0grp", i2c0_pins), - SIRFSOC_PIN_GROUP("i2c1grp", i2c1_pins), - SIRFSOC_PIN_GROUP("pwm0grp", pwm0_pins), - SIRFSOC_PIN_GROUP("pwm1grp", pwm1_pins), - SIRFSOC_PIN_GROUP("pwm2grp", pwm2_pins), - SIRFSOC_PIN_GROUP("pwm3grp", pwm3_pins), - SIRFSOC_PIN_GROUP("vipgrp", vip_pins), - SIRFSOC_PIN_GROUP("vipromgrp", viprom_pins), - SIRFSOC_PIN_GROUP("warm_rstgrp", warm_rst_pins), - SIRFSOC_PIN_GROUP("cko0_rstgrp", cko0_pins), - SIRFSOC_PIN_GROUP("cko1_rstgrp", cko1_pins), - SIRFSOC_PIN_GROUP("sdmmc0grp", sdmmc0_pins), - SIRFSOC_PIN_GROUP("sdmmc1grp", sdmmc1_pins), - SIRFSOC_PIN_GROUP("sdmmc2grp", sdmmc2_pins), - SIRFSOC_PIN_GROUP("sdmmc3grp", sdmmc3_pins), - SIRFSOC_PIN_GROUP("sdmmc4grp", sdmmc4_pins), - SIRFSOC_PIN_GROUP("sdmmc5grp", sdmmc5_pins), - SIRFSOC_PIN_GROUP("usb0_utmi_drvbusgrp", usb0_utmi_drvbus_pins), - SIRFSOC_PIN_GROUP("usb1_utmi_drvbusgrp", usb1_utmi_drvbus_pins), - SIRFSOC_PIN_GROUP("pulse_countgrp", pulse_count_pins), - SIRFSOC_PIN_GROUP("i2sgrp", i2s_pins), - SIRFSOC_PIN_GROUP("ac97grp", ac97_pins), - SIRFSOC_PIN_GROUP("nandgrp", nand_pins), - SIRFSOC_PIN_GROUP("spi0grp", spi0_pins), - SIRFSOC_PIN_GROUP("spi1grp", spi1_pins), - SIRFSOC_PIN_GROUP("gpsgrp", gps_pins), -}; - -static int sirfsoc_list_groups(struct pinctrl_dev *pctldev, unsigned selector) -{ - if (selector >= ARRAY_SIZE(sirfsoc_pin_groups)) - return -EINVAL; - return 0; -} - -static const char *sirfsoc_get_group_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - if (selector >= ARRAY_SIZE(sirfsoc_pin_groups)) - return NULL; - return sirfsoc_pin_groups[selector].name; -} - -static int sirfsoc_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, - const unsigned **pins, - unsigned *num_pins) -{ - if (selector >= ARRAY_SIZE(sirfsoc_pin_groups)) - return -EINVAL; - *pins = sirfsoc_pin_groups[selector].pins; - *num_pins = sirfsoc_pin_groups[selector].num_pins; - return 0; -} - -static void sirfsoc_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, - unsigned offset) -{ - seq_printf(s, " " DRIVER_NAME); -} - -static struct pinctrl_ops sirfsoc_pctrl_ops = { - .list_groups = sirfsoc_list_groups, - .get_group_name = sirfsoc_get_group_name, - .get_group_pins = sirfsoc_get_group_pins, - .pin_dbg_show = sirfsoc_pin_dbg_show, -}; - -struct sirfsoc_pmx_func { - const char *name; - const char * const *groups; - const unsigned num_groups; - const struct sirfsoc_padmux *padmux; -}; - -static const char * const lcd_16bitsgrp[] = { "lcd_16bitsgrp" }; -static const char * const lcd_18bitsgrp[] = { "lcd_18bitsgrp" }; -static const char * const lcd_24bitsgrp[] = { "lcd_24bitsgrp" }; -static const char * const lcdromgrp[] = { "lcdromgrp" }; -static const char * const uart0grp[] = { "uart0grp" }; -static const char * const uart1grp[] = { "uart1grp" }; -static const char * const uart2grp[] = { "uart2grp" }; -static const char * const uart2_nostreamctrlgrp[] = { "uart2_nostreamctrlgrp" }; -static const char * const usp0grp[] = { "usp0grp" }; -static const char * const usp1grp[] = { "usp1grp" }; -static const char * const usp2grp[] = { "usp2grp" }; -static const char * const i2c0grp[] = { "i2c0grp" }; -static const char * const i2c1grp[] = { "i2c1grp" }; -static const char * const pwm0grp[] = { "pwm0grp" }; -static const char * const pwm1grp[] = { "pwm1grp" }; -static const char * const pwm2grp[] = { "pwm2grp" }; -static const char * const pwm3grp[] = { "pwm3grp" }; -static const char * const vipgrp[] = { "vipgrp" }; -static const char * const vipromgrp[] = { "vipromgrp" }; -static const char * const warm_rstgrp[] = { "warm_rstgrp" }; -static const char * const cko0grp[] = { "cko0grp" }; -static const char * const cko1grp[] = { "cko1grp" }; -static const char * const sdmmc0grp[] = { "sdmmc0grp" }; -static const char * const sdmmc1grp[] = { "sdmmc1grp" }; -static const char * const sdmmc2grp[] = { "sdmmc2grp" }; -static const char * const sdmmc3grp[] = { "sdmmc3grp" }; -static const char * const sdmmc4grp[] = { "sdmmc4grp" }; -static const char * const sdmmc5grp[] = { "sdmmc5grp" }; -static const char * const usb0_utmi_drvbusgrp[] = { "usb0_utmi_drvbusgrp" }; -static const char * const usb1_utmi_drvbusgrp[] = { "usb1_utmi_drvbusgrp" }; -static const char * const pulse_countgrp[] = { "pulse_countgrp" }; -static const char * const i2sgrp[] = { "i2sgrp" }; -static const char * const ac97grp[] = { "ac97grp" }; -static const char * const nandgrp[] = { "nandgrp" }; -static const char * const spi0grp[] = { "spi0grp" }; -static const char * const spi1grp[] = { "spi1grp" }; -static const char * const gpsgrp[] = { "gpsgrp" }; - -#define SIRFSOC_PMX_FUNCTION(n, g, m) \ - { \ - .name = n, \ - .groups = g, \ - .num_groups = ARRAY_SIZE(g), \ - .padmux = &m, \ - } - -static const struct sirfsoc_pmx_func sirfsoc_pmx_functions[] = { - SIRFSOC_PMX_FUNCTION("lcd_16bits", lcd_16bitsgrp, lcd_16bits_padmux), - SIRFSOC_PMX_FUNCTION("lcd_18bits", lcd_18bitsgrp, lcd_18bits_padmux), - SIRFSOC_PMX_FUNCTION("lcd_24bits", lcd_24bitsgrp, lcd_24bits_padmux), - SIRFSOC_PMX_FUNCTION("lcdrom", lcdromgrp, lcdrom_padmux), - SIRFSOC_PMX_FUNCTION("uart0", uart0grp, uart0_padmux), - SIRFSOC_PMX_FUNCTION("uart1", uart1grp, uart1_padmux), - SIRFSOC_PMX_FUNCTION("uart2", uart2grp, uart2_padmux), - SIRFSOC_PMX_FUNCTION("uart2_nostreamctrl", uart2_nostreamctrlgrp, uart2_nostreamctrl_padmux), - SIRFSOC_PMX_FUNCTION("usp0", usp0grp, usp0_padmux), - SIRFSOC_PMX_FUNCTION("usp1", usp1grp, usp1_padmux), - SIRFSOC_PMX_FUNCTION("usp2", usp2grp, usp2_padmux), - SIRFSOC_PMX_FUNCTION("i2c0", i2c0grp, i2c0_padmux), - SIRFSOC_PMX_FUNCTION("i2c1", i2c1grp, i2c1_padmux), - SIRFSOC_PMX_FUNCTION("pwm0", pwm0grp, pwm0_padmux), - SIRFSOC_PMX_FUNCTION("pwm1", pwm1grp, pwm1_padmux), - SIRFSOC_PMX_FUNCTION("pwm2", pwm2grp, pwm2_padmux), - SIRFSOC_PMX_FUNCTION("pwm3", pwm3grp, pwm3_padmux), - SIRFSOC_PMX_FUNCTION("vip", vipgrp, vip_padmux), - SIRFSOC_PMX_FUNCTION("viprom", vipromgrp, viprom_padmux), - SIRFSOC_PMX_FUNCTION("warm_rst", warm_rstgrp, warm_rst_padmux), - SIRFSOC_PMX_FUNCTION("cko0", cko0grp, cko0_padmux), - SIRFSOC_PMX_FUNCTION("cko1", cko1grp, cko1_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc0", sdmmc0grp, sdmmc0_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc1", sdmmc1grp, sdmmc1_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc2", sdmmc2grp, sdmmc2_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc3", sdmmc3grp, sdmmc3_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc4", sdmmc4grp, sdmmc4_padmux), - SIRFSOC_PMX_FUNCTION("sdmmc5", sdmmc5grp, sdmmc5_padmux), - SIRFSOC_PMX_FUNCTION("usb0_utmi_drvbus", usb0_utmi_drvbusgrp, usb0_utmi_drvbus_padmux), - SIRFSOC_PMX_FUNCTION("usb1_utmi_drvbus", usb1_utmi_drvbusgrp, usb1_utmi_drvbus_padmux), - SIRFSOC_PMX_FUNCTION("pulse_count", pulse_countgrp, pulse_count_padmux), - SIRFSOC_PMX_FUNCTION("i2s", i2sgrp, i2s_padmux), - SIRFSOC_PMX_FUNCTION("ac97", ac97grp, ac97_padmux), - SIRFSOC_PMX_FUNCTION("nand", nandgrp, nand_padmux), - SIRFSOC_PMX_FUNCTION("spi0", spi0grp, spi0_padmux), - SIRFSOC_PMX_FUNCTION("spi1", spi1grp, spi1_padmux), - SIRFSOC_PMX_FUNCTION("gps", gpsgrp, gps_padmux), -}; - -static void sirfsoc_pinmux_endisable(struct sirfsoc_pmx *spmx, unsigned selector, - bool enable) -{ - int i; - const struct sirfsoc_padmux *mux = sirfsoc_pmx_functions[selector].padmux; - const struct sirfsoc_muxmask *mask = mux->muxmask; - - for (i = 0; i < mux->muxmask_counts; i++) { - u32 muxval; - muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); - if (enable) - muxval = muxval & ~mask[i].mask; - else - muxval = muxval | mask[i].mask; - writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(mask[i].group)); - } - - if (mux->funcmask && enable) { - u32 func_en_val; - func_en_val = - readl(spmx->rsc_virtbase + SIRFSOC_RSC_PIN_MUX); - func_en_val = - (func_en_val & ~mux->funcmask) | (mux-> - funcval); - writel(func_en_val, spmx->rsc_virtbase + SIRFSOC_RSC_PIN_MUX); - } -} - -static int sirfsoc_pinmux_enable(struct pinctrl_dev *pmxdev, unsigned selector, - unsigned group) -{ - struct sirfsoc_pmx *spmx; - - spmx = pinctrl_dev_get_drvdata(pmxdev); - sirfsoc_pinmux_endisable(spmx, selector, true); - - return 0; -} - -static void sirfsoc_pinmux_disable(struct pinctrl_dev *pmxdev, unsigned selector, - unsigned group) -{ - struct sirfsoc_pmx *spmx; - - spmx = pinctrl_dev_get_drvdata(pmxdev); - sirfsoc_pinmux_endisable(spmx, selector, false); -} - -static int sirfsoc_pinmux_list_funcs(struct pinctrl_dev *pmxdev, unsigned selector) -{ - if (selector >= ARRAY_SIZE(sirfsoc_pmx_functions)) - return -EINVAL; - return 0; -} - -static const char *sirfsoc_pinmux_get_func_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - return sirfsoc_pmx_functions[selector].name; -} - -static int sirfsoc_pinmux_get_groups(struct pinctrl_dev *pctldev, unsigned selector, - const char * const **groups, - unsigned * const num_groups) -{ - *groups = sirfsoc_pmx_functions[selector].groups; - *num_groups = sirfsoc_pmx_functions[selector].num_groups; - return 0; -} - -static int sirfsoc_pinmux_request_gpio(struct pinctrl_dev *pmxdev, - struct pinctrl_gpio_range *range, unsigned offset) -{ - struct sirfsoc_pmx *spmx; - - int group = range->id; - - u32 muxval; - - spmx = pinctrl_dev_get_drvdata(pmxdev); - - muxval = readl(spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); - muxval = muxval | (1 << (offset - range->pin_base)); - writel(muxval, spmx->gpio_virtbase + SIRFSOC_GPIO_PAD_EN(group)); - - return 0; -} - -static struct pinmux_ops sirfsoc_pinmux_ops = { - .list_functions = sirfsoc_pinmux_list_funcs, - .enable = sirfsoc_pinmux_enable, - .disable = sirfsoc_pinmux_disable, - .get_function_name = sirfsoc_pinmux_get_func_name, - .get_function_groups = sirfsoc_pinmux_get_groups, - .gpio_request_enable = sirfsoc_pinmux_request_gpio, -}; - -static struct pinctrl_desc sirfsoc_pinmux_desc = { - .name = DRIVER_NAME, - .pins = sirfsoc_pads, - .npins = ARRAY_SIZE(sirfsoc_pads), - .maxpin = SIRFSOC_NUM_PADS - 1, - .pctlops = &sirfsoc_pctrl_ops, - .pmxops = &sirfsoc_pinmux_ops, - .owner = THIS_MODULE, -}; - -/* - * Todo: bind irq_chip to every pinctrl_gpio_range - */ -static struct pinctrl_gpio_range sirfsoc_gpio_ranges[] = { - { - .name = "sirfsoc-gpio*", - .id = 0, - .base = 0, - .pin_base = 0, - .npins = 32, - }, { - .name = "sirfsoc-gpio*", - .id = 1, - .base = 32, - .pin_base = 32, - .npins = 32, - }, { - .name = "sirfsoc-gpio*", - .id = 2, - .base = 64, - .pin_base = 64, - .npins = 32, - }, { - .name = "sirfsoc-gpio*", - .id = 3, - .base = 96, - .pin_base = 96, - .npins = 19, - }, -}; - -static void __iomem *sirfsoc_rsc_of_iomap(void) -{ - const struct of_device_id rsc_ids[] = { - { .compatible = "sirf,prima2-rsc" }, - {} - }; - struct device_node *np; - - np = of_find_matching_node(NULL, rsc_ids); - if (!np) - panic("unable to find compatible rsc node in dtb\n"); - - return of_iomap(np, 0); -} - -static int __devinit sirfsoc_pinmux_probe(struct platform_device *pdev) -{ - int ret; - struct sirfsoc_pmx *spmx; - struct device_node *np = pdev->dev.of_node; - int i; - - /* Create state holders etc for this driver */ - spmx = devm_kzalloc(&pdev->dev, sizeof(*spmx), GFP_KERNEL); - if (!spmx) - return -ENOMEM; - - spmx->dev = &pdev->dev; - - platform_set_drvdata(pdev, spmx); - - spmx->gpio_virtbase = of_iomap(np, 0); - if (!spmx->gpio_virtbase) { - ret = -ENOMEM; - dev_err(&pdev->dev, "can't map gpio registers\n"); - goto out_no_gpio_remap; - } - - spmx->rsc_virtbase = sirfsoc_rsc_of_iomap(); - if (!spmx->rsc_virtbase) { - ret = -ENOMEM; - dev_err(&pdev->dev, "can't map rsc registers\n"); - goto out_no_rsc_remap; - } - - /* Now register the pin controller and all pins it handles */ - spmx->pmx = pinctrl_register(&sirfsoc_pinmux_desc, &pdev->dev, spmx); - if (!spmx->pmx) { - dev_err(&pdev->dev, "could not register SIRFSOC pinmux driver\n"); - ret = -EINVAL; - goto out_no_pmx; - } - - for (i = 0; i < ARRAY_SIZE(sirfsoc_gpio_ranges); i++) - pinctrl_add_gpio_range(spmx->pmx, &sirfsoc_gpio_ranges[i]); - - dev_info(&pdev->dev, "initialized SIRFSOC pinmux driver\n"); - - return 0; - -out_no_pmx: - iounmap(spmx->rsc_virtbase); -out_no_rsc_remap: - iounmap(spmx->gpio_virtbase); -out_no_gpio_remap: - platform_set_drvdata(pdev, NULL); - devm_kfree(&pdev->dev, spmx); - return ret; -} - -static const struct of_device_id pinmux_ids[] = { - { .compatible = "sirf,prima2-gpio-pinmux" }, - {} -}; - -static struct platform_driver sirfsoc_pinmux_driver = { - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - .of_match_table = pinmux_ids, - }, - .probe = sirfsoc_pinmux_probe, -}; - -static int __init sirfsoc_pinmux_init(void) -{ - return platform_driver_register(&sirfsoc_pinmux_driver); -} -arch_initcall(sirfsoc_pinmux_init); - -MODULE_AUTHOR("Rongjun Ying , " - "Barry Song "); -MODULE_DESCRIPTION("SIRFSOC pin control driver"); -MODULE_LICENSE("GPL"); diff --git a/drivers/pinctrl/pinmux-u300.c b/drivers/pinctrl/pinmux-u300.c deleted file mode 100644 index 7e89b36..0000000 --- a/drivers/pinctrl/pinmux-u300.c +++ /dev/null @@ -1,1157 +0,0 @@ -/* - * Driver for the U300 pin controller - * - * Based on the original U300 padmux functions - * Copyright (C) 2009-2011 ST-Ericsson AB - * Author: Martin Persson - * Author: Linus Walleij - * - * The DB3350 design and control registers are oriented around pads rather than - * pins, so we enumerate the pads we can mux rather than actual pins. The pads - * are connected to different pins in different packaging types, so it would - * be confusing. - */ -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Register definitions for the U300 Padmux control registers in the - * system controller - */ - -/* PAD MUX Control register 1 (LOW) 16bit (R/W) */ -#define U300_SYSCON_PMC1LR 0x007C -#define U300_SYSCON_PMC1LR_MASK 0xFFFF -#define U300_SYSCON_PMC1LR_CDI_MASK 0xC000 -#define U300_SYSCON_PMC1LR_CDI_CDI 0x0000 -#define U300_SYSCON_PMC1LR_CDI_EMIF 0x4000 -/* For BS335 */ -#define U300_SYSCON_PMC1LR_CDI_CDI2 0x8000 -#define U300_SYSCON_PMC1LR_CDI_WCDMA_APP_GPIO 0xC000 -/* For BS365 */ -#define U300_SYSCON_PMC1LR_CDI_GPIO 0x8000 -#define U300_SYSCON_PMC1LR_CDI_WCDMA 0xC000 -/* Common defs */ -#define U300_SYSCON_PMC1LR_PDI_MASK 0x3000 -#define U300_SYSCON_PMC1LR_PDI_PDI 0x0000 -#define U300_SYSCON_PMC1LR_PDI_EGG 0x1000 -#define U300_SYSCON_PMC1LR_PDI_WCDMA 0x3000 -#define U300_SYSCON_PMC1LR_MMCSD_MASK 0x0C00 -#define U300_SYSCON_PMC1LR_MMCSD_MMCSD 0x0000 -#define U300_SYSCON_PMC1LR_MMCSD_MSPRO 0x0400 -#define U300_SYSCON_PMC1LR_MMCSD_DSP 0x0800 -#define U300_SYSCON_PMC1LR_MMCSD_WCDMA 0x0C00 -#define U300_SYSCON_PMC1LR_ETM_MASK 0x0300 -#define U300_SYSCON_PMC1LR_ETM_ACC 0x0000 -#define U300_SYSCON_PMC1LR_ETM_APP 0x0100 -#define U300_SYSCON_PMC1LR_EMIF_1_CS2_MASK 0x00C0 -#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC 0x0000 -#define U300_SYSCON_PMC1LR_EMIF_1_CS2_NFIF 0x0040 -#define U300_SYSCON_PMC1LR_EMIF_1_CS2_SDRAM 0x0080 -#define U300_SYSCON_PMC1LR_EMIF_1_CS2_STATIC_2GB 0x00C0 -#define U300_SYSCON_PMC1LR_EMIF_1_CS1_MASK 0x0030 -#define U300_SYSCON_PMC1LR_EMIF_1_CS1_STATIC 0x0000 -#define U300_SYSCON_PMC1LR_EMIF_1_CS1_NFIF 0x0010 -#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SDRAM 0x0020 -#define U300_SYSCON_PMC1LR_EMIF_1_CS1_SEMI 0x0030 -#define U300_SYSCON_PMC1LR_EMIF_1_CS0_MASK 0x000C -#define U300_SYSCON_PMC1LR_EMIF_1_CS0_STATIC 0x0000 -#define U300_SYSCON_PMC1LR_EMIF_1_CS0_NFIF 0x0004 -#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SDRAM 0x0008 -#define U300_SYSCON_PMC1LR_EMIF_1_CS0_SEMI 0x000C -#define U300_SYSCON_PMC1LR_EMIF_1_MASK 0x0003 -#define U300_SYSCON_PMC1LR_EMIF_1_STATIC 0x0000 -#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM0 0x0001 -#define U300_SYSCON_PMC1LR_EMIF_1_SDRAM1 0x0002 -#define U300_SYSCON_PMC1LR_EMIF_1 0x0003 -/* PAD MUX Control register 2 (HIGH) 16bit (R/W) */ -#define U300_SYSCON_PMC1HR 0x007E -#define U300_SYSCON_PMC1HR_MASK 0xFFFF -#define U300_SYSCON_PMC1HR_MISC_2_MASK 0xC000 -#define U300_SYSCON_PMC1HR_MISC_2_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_MISC_2_MSPRO 0x4000 -#define U300_SYSCON_PMC1HR_MISC_2_DSP 0x8000 -#define U300_SYSCON_PMC1HR_MISC_2_AAIF 0xC000 -#define U300_SYSCON_PMC1HR_APP_GPIO_2_MASK 0x3000 -#define U300_SYSCON_PMC1HR_APP_GPIO_2_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_APP_GPIO_2_NFIF 0x1000 -#define U300_SYSCON_PMC1HR_APP_GPIO_2_DSP 0x2000 -#define U300_SYSCON_PMC1HR_APP_GPIO_2_AAIF 0x3000 -#define U300_SYSCON_PMC1HR_APP_GPIO_1_MASK 0x0C00 -#define U300_SYSCON_PMC1HR_APP_GPIO_1_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_APP_GPIO_1_MMC 0x0400 -#define U300_SYSCON_PMC1HR_APP_GPIO_1_DSP 0x0800 -#define U300_SYSCON_PMC1HR_APP_GPIO_1_AAIF 0x0C00 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK 0x0300 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI 0x0100 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_2_AAIF 0x0300 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK 0x00C0 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI 0x0040 -#define U300_SYSCON_PMC1HR_APP_SPI_CS_1_AAIF 0x00C0 -#define U300_SYSCON_PMC1HR_APP_SPI_2_MASK 0x0030 -#define U300_SYSCON_PMC1HR_APP_SPI_2_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_APP_SPI_2_SPI 0x0010 -#define U300_SYSCON_PMC1HR_APP_SPI_2_DSP 0x0020 -#define U300_SYSCON_PMC1HR_APP_SPI_2_AAIF 0x0030 -#define U300_SYSCON_PMC1HR_APP_UART0_2_MASK 0x000C -#define U300_SYSCON_PMC1HR_APP_UART0_2_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_APP_UART0_2_UART0 0x0004 -#define U300_SYSCON_PMC1HR_APP_UART0_2_NFIF_CS 0x0008 -#define U300_SYSCON_PMC1HR_APP_UART0_2_AAIF 0x000C -#define U300_SYSCON_PMC1HR_APP_UART0_1_MASK 0x0003 -#define U300_SYSCON_PMC1HR_APP_UART0_1_APP_GPIO 0x0000 -#define U300_SYSCON_PMC1HR_APP_UART0_1_UART0 0x0001 -#define U300_SYSCON_PMC1HR_APP_UART0_1_AAIF 0x0003 -/* Padmux 2 control */ -#define U300_SYSCON_PMC2R 0x100 -#define U300_SYSCON_PMC2R_APP_MISC_0_MASK 0x00C0 -#define U300_SYSCON_PMC2R_APP_MISC_0_APP_GPIO 0x0000 -#define U300_SYSCON_PMC2R_APP_MISC_0_EMIF_SDRAM 0x0040 -#define U300_SYSCON_PMC2R_APP_MISC_0_MMC 0x0080 -#define U300_SYSCON_PMC2R_APP_MISC_0_CDI2 0x00C0 -#define U300_SYSCON_PMC2R_APP_MISC_1_MASK 0x0300 -#define U300_SYSCON_PMC2R_APP_MISC_1_APP_GPIO 0x0000 -#define U300_SYSCON_PMC2R_APP_MISC_1_EMIF_SDRAM 0x0100 -#define U300_SYSCON_PMC2R_APP_MISC_1_MMC 0x0200 -#define U300_SYSCON_PMC2R_APP_MISC_1_CDI2 0x0300 -#define U300_SYSCON_PMC2R_APP_MISC_2_MASK 0x0C00 -#define U300_SYSCON_PMC2R_APP_MISC_2_APP_GPIO 0x0000 -#define U300_SYSCON_PMC2R_APP_MISC_2_EMIF_SDRAM 0x0400 -#define U300_SYSCON_PMC2R_APP_MISC_2_MMC 0x0800 -#define U300_SYSCON_PMC2R_APP_MISC_2_CDI2 0x0C00 -#define U300_SYSCON_PMC2R_APP_MISC_3_MASK 0x3000 -#define U300_SYSCON_PMC2R_APP_MISC_3_APP_GPIO 0x0000 -#define U300_SYSCON_PMC2R_APP_MISC_3_EMIF_SDRAM 0x1000 -#define U300_SYSCON_PMC2R_APP_MISC_3_MMC 0x2000 -#define U300_SYSCON_PMC2R_APP_MISC_3_CDI2 0x3000 -#define U300_SYSCON_PMC2R_APP_MISC_4_MASK 0xC000 -#define U300_SYSCON_PMC2R_APP_MISC_4_APP_GPIO 0x0000 -#define U300_SYSCON_PMC2R_APP_MISC_4_EMIF_SDRAM 0x4000 -#define U300_SYSCON_PMC2R_APP_MISC_4_MMC 0x8000 -#define U300_SYSCON_PMC2R_APP_MISC_4_ACC_GPIO 0xC000 -/* TODO: More SYSCON registers missing */ -#define U300_SYSCON_PMC3R 0x10C -#define U300_SYSCON_PMC3R_APP_MISC_11_MASK 0xC000 -#define U300_SYSCON_PMC3R_APP_MISC_11_SPI 0x4000 -#define U300_SYSCON_PMC3R_APP_MISC_10_MASK 0x3000 -#define U300_SYSCON_PMC3R_APP_MISC_10_SPI 0x1000 -/* TODO: Missing other configs */ -#define U300_SYSCON_PMC4R 0x168 -#define U300_SYSCON_PMC4R_APP_MISC_12_MASK 0x0003 -#define U300_SYSCON_PMC4R_APP_MISC_12_APP_GPIO 0x0000 -#define U300_SYSCON_PMC4R_APP_MISC_13_MASK 0x000C -#define U300_SYSCON_PMC4R_APP_MISC_13_CDI 0x0000 -#define U300_SYSCON_PMC4R_APP_MISC_13_SMIA 0x0004 -#define U300_SYSCON_PMC4R_APP_MISC_13_SMIA2 0x0008 -#define U300_SYSCON_PMC4R_APP_MISC_13_APP_GPIO 0x000C -#define U300_SYSCON_PMC4R_APP_MISC_14_MASK 0x0030 -#define U300_SYSCON_PMC4R_APP_MISC_14_CDI 0x0000 -#define U300_SYSCON_PMC4R_APP_MISC_14_SMIA 0x0010 -#define U300_SYSCON_PMC4R_APP_MISC_14_CDI2 0x0020 -#define U300_SYSCON_PMC4R_APP_MISC_14_APP_GPIO 0x0030 -#define U300_SYSCON_PMC4R_APP_MISC_16_MASK 0x0300 -#define U300_SYSCON_PMC4R_APP_MISC_16_APP_GPIO_13 0x0000 -#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" - -/* - * The DB3350 has 467 pads, I have enumerated the pads clockwise around the - * edges of the silicon, finger by finger. LTCORNER upper left is pad 0. - * Data taken from the PadRing chart, arranged like this: - * - * 0 ..... 104 - * 466 105 - * . . - * . . - * 358 224 - * 357 .... 225 - */ -#define U300_NUM_PADS 467 - -/* Pad names for the pinmux subsystem */ -static const struct pinctrl_pin_desc u300_pads[] = { - /* Pads along the top edge of the chip */ - PINCTRL_PIN(0, "P PAD VDD 28"), - PINCTRL_PIN(1, "P PAD GND 28"), - PINCTRL_PIN(2, "PO SIM RST N"), - PINCTRL_PIN(3, "VSSIO 25"), - PINCTRL_PIN(4, "VSSA ADDA ESDSUB"), - PINCTRL_PIN(5, "PWR VSSCOMMON"), - PINCTRL_PIN(6, "PI ADC I1 POS"), - PINCTRL_PIN(7, "PI ADC I1 NEG"), - PINCTRL_PIN(8, "PWR VSSAD0"), - PINCTRL_PIN(9, "PWR VCCAD0"), - PINCTRL_PIN(10, "PI ADC Q1 NEG"), - PINCTRL_PIN(11, "PI ADC Q1 POS"), - PINCTRL_PIN(12, "PWR VDDAD"), - PINCTRL_PIN(13, "PWR GNDAD"), - PINCTRL_PIN(14, "PI ADC I2 POS"), - PINCTRL_PIN(15, "PI ADC I2 NEG"), - PINCTRL_PIN(16, "PWR VSSAD1"), - PINCTRL_PIN(17, "PWR VCCAD1"), - PINCTRL_PIN(18, "PI ADC Q2 NEG"), - PINCTRL_PIN(19, "PI ADC Q2 POS"), - PINCTRL_PIN(20, "VSSA ADDA ESDSUB"), - PINCTRL_PIN(21, "PWR VCCGPAD"), - PINCTRL_PIN(22, "PI TX POW"), - PINCTRL_PIN(23, "PWR VSSGPAD"), - PINCTRL_PIN(24, "PO DAC I POS"), - PINCTRL_PIN(25, "PO DAC I NEG"), - PINCTRL_PIN(26, "PO DAC Q POS"), - PINCTRL_PIN(27, "PO DAC Q NEG"), - PINCTRL_PIN(28, "PWR VSSDA"), - PINCTRL_PIN(29, "PWR VCCDA"), - PINCTRL_PIN(30, "VSSA ADDA ESDSUB"), - PINCTRL_PIN(31, "P PAD VDDIO 11"), - PINCTRL_PIN(32, "PI PLL 26 FILTVDD"), - PINCTRL_PIN(33, "PI PLL 26 VCONT"), - PINCTRL_PIN(34, "PWR AGNDPLL2V5 32 13"), - PINCTRL_PIN(35, "PWR AVDDPLL2V5 32 13"), - PINCTRL_PIN(36, "VDDA PLL ESD"), - PINCTRL_PIN(37, "VSSA PLL ESD"), - PINCTRL_PIN(38, "VSS PLL"), - PINCTRL_PIN(39, "VDDC PLL"), - PINCTRL_PIN(40, "PWR AGNDPLL2V5 26 60"), - PINCTRL_PIN(41, "PWR AVDDPLL2V5 26 60"), - PINCTRL_PIN(42, "PWR AVDDPLL2V5 26 208"), - PINCTRL_PIN(43, "PWR AGNDPLL2V5 26 208"), - PINCTRL_PIN(44, "PWR AVDDPLL2V5 13 208"), - PINCTRL_PIN(45, "PWR AGNDPLL2V5 13 208"), - PINCTRL_PIN(46, "P PAD VSSIO 11"), - PINCTRL_PIN(47, "P PAD VSSIO 12"), - PINCTRL_PIN(48, "PI POW RST N"), - PINCTRL_PIN(49, "VDDC IO"), - PINCTRL_PIN(50, "P PAD VDDIO 16"), - PINCTRL_PIN(51, "PO RF WCDMA EN 4"), - PINCTRL_PIN(52, "PO RF WCDMA EN 3"), - PINCTRL_PIN(53, "PO RF WCDMA EN 2"), - PINCTRL_PIN(54, "PO RF WCDMA EN 1"), - PINCTRL_PIN(55, "PO RF WCDMA EN 0"), - PINCTRL_PIN(56, "PO GSM PA ENABLE"), - PINCTRL_PIN(57, "PO RF DATA STRB"), - PINCTRL_PIN(58, "PO RF DATA2"), - PINCTRL_PIN(59, "PIO RF DATA1"), - PINCTRL_PIN(60, "PIO RF DATA0"), - PINCTRL_PIN(61, "P PAD VDD 11"), - PINCTRL_PIN(62, "P PAD GND 11"), - PINCTRL_PIN(63, "P PAD VSSIO 16"), - PINCTRL_PIN(64, "P PAD VDDIO 18"), - PINCTRL_PIN(65, "PO RF CTRL STRB2"), - PINCTRL_PIN(66, "PO RF CTRL STRB1"), - PINCTRL_PIN(67, "PO RF CTRL STRB0"), - PINCTRL_PIN(68, "PIO RF CTRL DATA"), - PINCTRL_PIN(69, "PO RF CTRL CLK"), - PINCTRL_PIN(70, "PO TX ADC STRB"), - PINCTRL_PIN(71, "PO ANT SW 2"), - PINCTRL_PIN(72, "PO ANT SW 3"), - PINCTRL_PIN(73, "PO ANT SW 0"), - PINCTRL_PIN(74, "PO ANT SW 1"), - PINCTRL_PIN(75, "PO M CLKRQ"), - PINCTRL_PIN(76, "PI M CLK"), - PINCTRL_PIN(77, "PI RTC CLK"), - PINCTRL_PIN(78, "P PAD VDD 8"), - PINCTRL_PIN(79, "P PAD GND 8"), - PINCTRL_PIN(80, "P PAD VSSIO 13"), - PINCTRL_PIN(81, "P PAD VDDIO 13"), - PINCTRL_PIN(82, "PO SYS 1 CLK"), - PINCTRL_PIN(83, "PO SYS 2 CLK"), - PINCTRL_PIN(84, "PO SYS 0 CLK"), - PINCTRL_PIN(85, "PI SYS 0 CLKRQ"), - PINCTRL_PIN(86, "PO PWR MNGT CTRL 1"), - PINCTRL_PIN(87, "PO PWR MNGT CTRL 0"), - PINCTRL_PIN(88, "PO RESOUT2 RST N"), - PINCTRL_PIN(89, "PO RESOUT1 RST N"), - PINCTRL_PIN(90, "PO RESOUT0 RST N"), - PINCTRL_PIN(91, "PI SERVICE N"), - PINCTRL_PIN(92, "P PAD VDD 29"), - PINCTRL_PIN(93, "P PAD GND 29"), - PINCTRL_PIN(94, "P PAD VSSIO 8"), - PINCTRL_PIN(95, "P PAD VDDIO 8"), - PINCTRL_PIN(96, "PI EXT IRQ1 N"), - PINCTRL_PIN(97, "PI EXT IRQ0 N"), - PINCTRL_PIN(98, "PIO DC ON"), - PINCTRL_PIN(99, "PIO ACC APP I2C DATA"), - PINCTRL_PIN(100, "PIO ACC APP I2C CLK"), - PINCTRL_PIN(101, "P PAD VDD 12"), - PINCTRL_PIN(102, "P PAD GND 12"), - PINCTRL_PIN(103, "P PAD VSSIO 14"), - PINCTRL_PIN(104, "P PAD VDDIO 14"), - /* Pads along the right edge of the chip */ - PINCTRL_PIN(105, "PIO APP I2C1 DATA"), - PINCTRL_PIN(106, "PIO APP I2C1 CLK"), - PINCTRL_PIN(107, "PO KEY OUT0"), - PINCTRL_PIN(108, "PO KEY OUT1"), - PINCTRL_PIN(109, "PO KEY OUT2"), - PINCTRL_PIN(110, "PO KEY OUT3"), - PINCTRL_PIN(111, "PO KEY OUT4"), - PINCTRL_PIN(112, "PI KEY IN0"), - PINCTRL_PIN(113, "PI KEY IN1"), - PINCTRL_PIN(114, "PI KEY IN2"), - PINCTRL_PIN(115, "P PAD VDDIO 15"), - PINCTRL_PIN(116, "P PAD VSSIO 15"), - PINCTRL_PIN(117, "P PAD GND 13"), - PINCTRL_PIN(118, "P PAD VDD 13"), - PINCTRL_PIN(119, "PI KEY IN3"), - PINCTRL_PIN(120, "PI KEY IN4"), - PINCTRL_PIN(121, "PI KEY IN5"), - PINCTRL_PIN(122, "PIO APP PCM I2S1 DATA B"), - PINCTRL_PIN(123, "PIO APP PCM I2S1 DATA A"), - PINCTRL_PIN(124, "PIO APP PCM I2S1 WS"), - PINCTRL_PIN(125, "PIO APP PCM I2S1 CLK"), - PINCTRL_PIN(126, "PIO APP PCM I2S0 DATA B"), - PINCTRL_PIN(127, "PIO APP PCM I2S0 DATA A"), - PINCTRL_PIN(128, "PIO APP PCM I2S0 WS"), - PINCTRL_PIN(129, "PIO APP PCM I2S0 CLK"), - PINCTRL_PIN(130, "P PAD VDD 17"), - PINCTRL_PIN(131, "P PAD GND 17"), - PINCTRL_PIN(132, "P PAD VSSIO 19"), - PINCTRL_PIN(133, "P PAD VDDIO 19"), - PINCTRL_PIN(134, "UART0 RTS"), - PINCTRL_PIN(135, "UART0 CTS"), - PINCTRL_PIN(136, "UART0 TX"), - PINCTRL_PIN(137, "UART0 RX"), - PINCTRL_PIN(138, "PIO ACC SPI DO"), - PINCTRL_PIN(139, "PIO ACC SPI DI"), - PINCTRL_PIN(140, "PIO ACC SPI CS0 N"), - PINCTRL_PIN(141, "PIO ACC SPI CS1 N"), - PINCTRL_PIN(142, "PIO ACC SPI CS2 N"), - PINCTRL_PIN(143, "PIO ACC SPI CLK"), - PINCTRL_PIN(144, "PO PDI EXT RST N"), - PINCTRL_PIN(145, "P PAD VDDIO 22"), - PINCTRL_PIN(146, "P PAD VSSIO 22"), - PINCTRL_PIN(147, "P PAD GND 18"), - PINCTRL_PIN(148, "P PAD VDD 18"), - PINCTRL_PIN(149, "PIO PDI C0"), - PINCTRL_PIN(150, "PIO PDI C1"), - PINCTRL_PIN(151, "PIO PDI C2"), - PINCTRL_PIN(152, "PIO PDI C3"), - PINCTRL_PIN(153, "PIO PDI C4"), - PINCTRL_PIN(154, "PIO PDI C5"), - PINCTRL_PIN(155, "PIO PDI D0"), - PINCTRL_PIN(156, "PIO PDI D1"), - PINCTRL_PIN(157, "PIO PDI D2"), - PINCTRL_PIN(158, "PIO PDI D3"), - PINCTRL_PIN(159, "P PAD VDDIO 21"), - PINCTRL_PIN(160, "P PAD VSSIO 21"), - PINCTRL_PIN(161, "PIO PDI D4"), - PINCTRL_PIN(162, "PIO PDI D5"), - PINCTRL_PIN(163, "PIO PDI D6"), - PINCTRL_PIN(164, "PIO PDI D7"), - PINCTRL_PIN(165, "PIO MS INS"), - PINCTRL_PIN(166, "MMC DATA DIR LS"), - PINCTRL_PIN(167, "MMC DATA 3"), - PINCTRL_PIN(168, "MMC DATA 2"), - PINCTRL_PIN(169, "MMC DATA 1"), - PINCTRL_PIN(170, "MMC DATA 0"), - PINCTRL_PIN(171, "MMC CMD DIR LS"), - PINCTRL_PIN(172, "P PAD VDD 27"), - PINCTRL_PIN(173, "P PAD GND 27"), - PINCTRL_PIN(174, "P PAD VSSIO 20"), - PINCTRL_PIN(175, "P PAD VDDIO 20"), - PINCTRL_PIN(176, "MMC CMD"), - PINCTRL_PIN(177, "MMC CLK"), - PINCTRL_PIN(178, "PIO APP GPIO 14"), - PINCTRL_PIN(179, "PIO APP GPIO 13"), - PINCTRL_PIN(180, "PIO APP GPIO 11"), - PINCTRL_PIN(181, "PIO APP GPIO 25"), - PINCTRL_PIN(182, "PIO APP GPIO 24"), - PINCTRL_PIN(183, "PIO APP GPIO 23"), - PINCTRL_PIN(184, "PIO APP GPIO 22"), - PINCTRL_PIN(185, "PIO APP GPIO 21"), - PINCTRL_PIN(186, "PIO APP GPIO 20"), - PINCTRL_PIN(187, "P PAD VDD 19"), - PINCTRL_PIN(188, "P PAD GND 19"), - PINCTRL_PIN(189, "P PAD VSSIO 23"), - PINCTRL_PIN(190, "P PAD VDDIO 23"), - PINCTRL_PIN(191, "PIO APP GPIO 19"), - PINCTRL_PIN(192, "PIO APP GPIO 18"), - PINCTRL_PIN(193, "PIO APP GPIO 17"), - PINCTRL_PIN(194, "PIO APP GPIO 16"), - PINCTRL_PIN(195, "PI CI D1"), - PINCTRL_PIN(196, "PI CI D0"), - PINCTRL_PIN(197, "PI CI HSYNC"), - PINCTRL_PIN(198, "PI CI VSYNC"), - PINCTRL_PIN(199, "PI CI EXT CLK"), - PINCTRL_PIN(200, "PO CI EXT RST N"), - PINCTRL_PIN(201, "P PAD VSSIO 43"), - PINCTRL_PIN(202, "P PAD VDDIO 43"), - PINCTRL_PIN(203, "PI CI D6"), - PINCTRL_PIN(204, "PI CI D7"), - PINCTRL_PIN(205, "PI CI D2"), - PINCTRL_PIN(206, "PI CI D3"), - PINCTRL_PIN(207, "PI CI D4"), - PINCTRL_PIN(208, "PI CI D5"), - PINCTRL_PIN(209, "PI CI D8"), - PINCTRL_PIN(210, "PI CI D9"), - PINCTRL_PIN(211, "P PAD VDD 20"), - PINCTRL_PIN(212, "P PAD GND 20"), - PINCTRL_PIN(213, "P PAD VSSIO 24"), - PINCTRL_PIN(214, "P PAD VDDIO 24"), - PINCTRL_PIN(215, "P PAD VDDIO 26"), - PINCTRL_PIN(216, "PO EMIF 1 A26"), - PINCTRL_PIN(217, "PO EMIF 1 A25"), - PINCTRL_PIN(218, "P PAD VSSIO 26"), - PINCTRL_PIN(219, "PO EMIF 1 A24"), - PINCTRL_PIN(220, "PO EMIF 1 A23"), - /* Pads along the bottom edge of the chip */ - PINCTRL_PIN(221, "PO EMIF 1 A22"), - PINCTRL_PIN(222, "PO EMIF 1 A21"), - PINCTRL_PIN(223, "P PAD VDD 21"), - PINCTRL_PIN(224, "P PAD GND 21"), - PINCTRL_PIN(225, "P PAD VSSIO 27"), - PINCTRL_PIN(226, "P PAD VDDIO 27"), - PINCTRL_PIN(227, "PO EMIF 1 A20"), - PINCTRL_PIN(228, "PO EMIF 1 A19"), - PINCTRL_PIN(229, "PO EMIF 1 A18"), - PINCTRL_PIN(230, "PO EMIF 1 A17"), - PINCTRL_PIN(231, "P PAD VDDIO 28"), - PINCTRL_PIN(232, "P PAD VSSIO 28"), - PINCTRL_PIN(233, "PO EMIF 1 A16"), - PINCTRL_PIN(234, "PIO EMIF 1 D15"), - PINCTRL_PIN(235, "PO EMIF 1 A15"), - PINCTRL_PIN(236, "PIO EMIF 1 D14"), - PINCTRL_PIN(237, "P PAD VDD 22"), - PINCTRL_PIN(238, "P PAD GND 22"), - PINCTRL_PIN(239, "P PAD VSSIO 29"), - PINCTRL_PIN(240, "P PAD VDDIO 29"), - PINCTRL_PIN(241, "PO EMIF 1 A14"), - PINCTRL_PIN(242, "PIO EMIF 1 D13"), - PINCTRL_PIN(243, "PO EMIF 1 A13"), - PINCTRL_PIN(244, "PIO EMIF 1 D12"), - PINCTRL_PIN(245, "P PAD VSSIO 30"), - PINCTRL_PIN(246, "P PAD VDDIO 30"), - PINCTRL_PIN(247, "PO EMIF 1 A12"), - PINCTRL_PIN(248, "PIO EMIF 1 D11"), - PINCTRL_PIN(249, "PO EMIF 1 A11"), - PINCTRL_PIN(250, "PIO EMIF 1 D10"), - PINCTRL_PIN(251, "P PAD VSSIO 31"), - PINCTRL_PIN(252, "P PAD VDDIO 31"), - PINCTRL_PIN(253, "PO EMIF 1 A10"), - PINCTRL_PIN(254, "PIO EMIF 1 D09"), - PINCTRL_PIN(255, "PO EMIF 1 A09"), - PINCTRL_PIN(256, "P PAD VDDIO 32"), - PINCTRL_PIN(257, "P PAD VSSIO 32"), - PINCTRL_PIN(258, "P PAD GND 24"), - PINCTRL_PIN(259, "P PAD VDD 24"), - PINCTRL_PIN(260, "PIO EMIF 1 D08"), - PINCTRL_PIN(261, "PO EMIF 1 A08"), - PINCTRL_PIN(262, "PIO EMIF 1 D07"), - PINCTRL_PIN(263, "PO EMIF 1 A07"), - PINCTRL_PIN(264, "P PAD VDDIO 33"), - PINCTRL_PIN(265, "P PAD VSSIO 33"), - PINCTRL_PIN(266, "PIO EMIF 1 D06"), - PINCTRL_PIN(267, "PO EMIF 1 A06"), - PINCTRL_PIN(268, "PIO EMIF 1 D05"), - PINCTRL_PIN(269, "PO EMIF 1 A05"), - PINCTRL_PIN(270, "P PAD VDDIO 34"), - PINCTRL_PIN(271, "P PAD VSSIO 34"), - PINCTRL_PIN(272, "PIO EMIF 1 D04"), - PINCTRL_PIN(273, "PO EMIF 1 A04"), - PINCTRL_PIN(274, "PIO EMIF 1 D03"), - PINCTRL_PIN(275, "PO EMIF 1 A03"), - PINCTRL_PIN(276, "P PAD VDDIO 35"), - PINCTRL_PIN(277, "P PAD VSSIO 35"), - PINCTRL_PIN(278, "P PAD GND 23"), - PINCTRL_PIN(279, "P PAD VDD 23"), - PINCTRL_PIN(280, "PIO EMIF 1 D02"), - PINCTRL_PIN(281, "PO EMIF 1 A02"), - PINCTRL_PIN(282, "PIO EMIF 1 D01"), - PINCTRL_PIN(283, "PO EMIF 1 A01"), - PINCTRL_PIN(284, "P PAD VDDIO 36"), - PINCTRL_PIN(285, "P PAD VSSIO 36"), - PINCTRL_PIN(286, "PIO EMIF 1 D00"), - PINCTRL_PIN(287, "PO EMIF 1 BE1 N"), - PINCTRL_PIN(288, "PO EMIF 1 BE0 N"), - PINCTRL_PIN(289, "PO EMIF 1 ADV N"), - PINCTRL_PIN(290, "P PAD VDDIO 37"), - PINCTRL_PIN(291, "P PAD VSSIO 37"), - PINCTRL_PIN(292, "PO EMIF 1 SD CKE0"), - PINCTRL_PIN(293, "PO EMIF 1 OE N"), - PINCTRL_PIN(294, "PO EMIF 1 WE N"), - PINCTRL_PIN(295, "P PAD VDDIO 38"), - PINCTRL_PIN(296, "P PAD VSSIO 38"), - PINCTRL_PIN(297, "PO EMIF 1 CLK"), - PINCTRL_PIN(298, "PIO EMIF 1 SD CLK"), - PINCTRL_PIN(299, "P PAD VSSIO 45 (not bonded)"), - PINCTRL_PIN(300, "P PAD VDDIO 42"), - PINCTRL_PIN(301, "P PAD VSSIO 42"), - PINCTRL_PIN(302, "P PAD GND 31"), - PINCTRL_PIN(303, "P PAD VDD 31"), - PINCTRL_PIN(304, "PI EMIF 1 RET CLK"), - PINCTRL_PIN(305, "PI EMIF 1 WAIT N"), - PINCTRL_PIN(306, "PI EMIF 1 NFIF READY"), - PINCTRL_PIN(307, "PO EMIF 1 SD CKE1"), - PINCTRL_PIN(308, "PO EMIF 1 CS3 N"), - PINCTRL_PIN(309, "P PAD VDD 25"), - PINCTRL_PIN(310, "P PAD GND 25"), - PINCTRL_PIN(311, "P PAD VSSIO 39"), - PINCTRL_PIN(312, "P PAD VDDIO 39"), - PINCTRL_PIN(313, "PO EMIF 1 CS2 N"), - PINCTRL_PIN(314, "PO EMIF 1 CS1 N"), - PINCTRL_PIN(315, "PO EMIF 1 CS0 N"), - PINCTRL_PIN(316, "PO ETM TRACE PKT0"), - PINCTRL_PIN(317, "PO ETM TRACE PKT1"), - PINCTRL_PIN(318, "PO ETM TRACE PKT2"), - PINCTRL_PIN(319, "P PAD VDD 30"), - PINCTRL_PIN(320, "P PAD GND 30"), - PINCTRL_PIN(321, "P PAD VSSIO 44"), - PINCTRL_PIN(322, "P PAD VDDIO 44"), - PINCTRL_PIN(323, "PO ETM TRACE PKT3"), - PINCTRL_PIN(324, "PO ETM TRACE PKT4"), - PINCTRL_PIN(325, "PO ETM TRACE PKT5"), - PINCTRL_PIN(326, "PO ETM TRACE PKT6"), - PINCTRL_PIN(327, "PO ETM TRACE PKT7"), - PINCTRL_PIN(328, "PO ETM PIPE STAT0"), - PINCTRL_PIN(329, "P PAD VDD 26"), - PINCTRL_PIN(330, "P PAD GND 26"), - PINCTRL_PIN(331, "P PAD VSSIO 40"), - PINCTRL_PIN(332, "P PAD VDDIO 40"), - PINCTRL_PIN(333, "PO ETM PIPE STAT1"), - PINCTRL_PIN(334, "PO ETM PIPE STAT2"), - PINCTRL_PIN(335, "PO ETM TRACE CLK"), - PINCTRL_PIN(336, "PO ETM TRACE SYNC"), - PINCTRL_PIN(337, "PIO ACC GPIO 33"), - PINCTRL_PIN(338, "PIO ACC GPIO 32"), - PINCTRL_PIN(339, "PIO ACC GPIO 30"), - PINCTRL_PIN(340, "PIO ACC GPIO 29"), - PINCTRL_PIN(341, "P PAD VDDIO 17"), - PINCTRL_PIN(342, "P PAD VSSIO 17"), - PINCTRL_PIN(343, "P PAD GND 15"), - PINCTRL_PIN(344, "P PAD VDD 15"), - PINCTRL_PIN(345, "PIO ACC GPIO 28"), - PINCTRL_PIN(346, "PIO ACC GPIO 27"), - PINCTRL_PIN(347, "PIO ACC GPIO 16"), - PINCTRL_PIN(348, "PI TAP TMS"), - PINCTRL_PIN(349, "PI TAP TDI"), - PINCTRL_PIN(350, "PO TAP TDO"), - PINCTRL_PIN(351, "PI TAP RST N"), - /* Pads along the left edge of the chip */ - PINCTRL_PIN(352, "PI EMU MODE 0"), - PINCTRL_PIN(353, "PO TAP RET CLK"), - PINCTRL_PIN(354, "PI TAP CLK"), - PINCTRL_PIN(355, "PO EMIF 0 SD CS N"), - PINCTRL_PIN(356, "PO EMIF 0 SD CAS N"), - PINCTRL_PIN(357, "PO EMIF 0 SD WE N"), - PINCTRL_PIN(358, "P PAD VDDIO 1"), - PINCTRL_PIN(359, "P PAD VSSIO 1"), - PINCTRL_PIN(360, "P PAD GND 1"), - PINCTRL_PIN(361, "P PAD VDD 1"), - PINCTRL_PIN(362, "PO EMIF 0 SD CKE"), - PINCTRL_PIN(363, "PO EMIF 0 SD DQML"), - PINCTRL_PIN(364, "PO EMIF 0 SD DQMU"), - PINCTRL_PIN(365, "PO EMIF 0 SD RAS N"), - PINCTRL_PIN(366, "PIO EMIF 0 D15"), - PINCTRL_PIN(367, "PO EMIF 0 A15"), - PINCTRL_PIN(368, "PIO EMIF 0 D14"), - PINCTRL_PIN(369, "PO EMIF 0 A14"), - PINCTRL_PIN(370, "PIO EMIF 0 D13"), - PINCTRL_PIN(371, "PO EMIF 0 A13"), - PINCTRL_PIN(372, "P PAD VDDIO 2"), - PINCTRL_PIN(373, "P PAD VSSIO 2"), - PINCTRL_PIN(374, "P PAD GND 2"), - PINCTRL_PIN(375, "P PAD VDD 2"), - PINCTRL_PIN(376, "PIO EMIF 0 D12"), - PINCTRL_PIN(377, "PO EMIF 0 A12"), - PINCTRL_PIN(378, "PIO EMIF 0 D11"), - PINCTRL_PIN(379, "PO EMIF 0 A11"), - PINCTRL_PIN(380, "PIO EMIF 0 D10"), - PINCTRL_PIN(381, "PO EMIF 0 A10"), - PINCTRL_PIN(382, "PIO EMIF 0 D09"), - PINCTRL_PIN(383, "PO EMIF 0 A09"), - PINCTRL_PIN(384, "PIO EMIF 0 D08"), - PINCTRL_PIN(385, "PO EMIF 0 A08"), - PINCTRL_PIN(386, "PIO EMIF 0 D07"), - PINCTRL_PIN(387, "PO EMIF 0 A07"), - PINCTRL_PIN(388, "P PAD VDDIO 3"), - PINCTRL_PIN(389, "P PAD VSSIO 3"), - PINCTRL_PIN(390, "P PAD GND 3"), - PINCTRL_PIN(391, "P PAD VDD 3"), - PINCTRL_PIN(392, "PO EFUSE RDOUT1"), - PINCTRL_PIN(393, "PIO EMIF 0 D06"), - PINCTRL_PIN(394, "PO EMIF 0 A06"), - PINCTRL_PIN(395, "PIO EMIF 0 D05"), - PINCTRL_PIN(396, "PO EMIF 0 A05"), - PINCTRL_PIN(397, "PIO EMIF 0 D04"), - PINCTRL_PIN(398, "PO EMIF 0 A04"), - PINCTRL_PIN(399, "A PADS/A VDDCO1v82v5 GND 80U SF LIN VDDCO AF"), - PINCTRL_PIN(400, "PWR VDDCO AF"), - PINCTRL_PIN(401, "PWR EFUSE HV1"), - PINCTRL_PIN(402, "P PAD VSSIO 4"), - PINCTRL_PIN(403, "P PAD VDDIO 4"), - PINCTRL_PIN(404, "P PAD GND 4"), - PINCTRL_PIN(405, "P PAD VDD 4"), - PINCTRL_PIN(406, "PIO EMIF 0 D03"), - PINCTRL_PIN(407, "PO EMIF 0 A03"), - PINCTRL_PIN(408, "PWR EFUSE HV2"), - PINCTRL_PIN(409, "PWR EFUSE HV3"), - PINCTRL_PIN(410, "PIO EMIF 0 D02"), - PINCTRL_PIN(411, "PO EMIF 0 A02"), - PINCTRL_PIN(412, "PIO EMIF 0 D01"), - PINCTRL_PIN(413, "P PAD VDDIO 5"), - PINCTRL_PIN(414, "P PAD VSSIO 5"), - PINCTRL_PIN(415, "P PAD GND 5"), - PINCTRL_PIN(416, "P PAD VDD 5"), - PINCTRL_PIN(417, "PO EMIF 0 A01"), - PINCTRL_PIN(418, "PIO EMIF 0 D00"), - PINCTRL_PIN(419, "IF 0 SD CLK"), - PINCTRL_PIN(420, "APP SPI CLK"), - PINCTRL_PIN(421, "APP SPI DO"), - PINCTRL_PIN(422, "APP SPI DI"), - PINCTRL_PIN(423, "APP SPI CS0"), - PINCTRL_PIN(424, "APP SPI CS1"), - PINCTRL_PIN(425, "APP SPI CS2"), - PINCTRL_PIN(426, "PIO APP GPIO 10"), - PINCTRL_PIN(427, "P PAD VDDIO 41"), - PINCTRL_PIN(428, "P PAD VSSIO 41"), - PINCTRL_PIN(429, "P PAD GND 6"), - PINCTRL_PIN(430, "P PAD VDD 6"), - PINCTRL_PIN(431, "PIO ACC SDIO0 CMD"), - PINCTRL_PIN(432, "PIO ACC SDIO0 CK"), - PINCTRL_PIN(433, "PIO ACC SDIO0 D3"), - PINCTRL_PIN(434, "PIO ACC SDIO0 D2"), - PINCTRL_PIN(435, "PIO ACC SDIO0 D1"), - PINCTRL_PIN(436, "PIO ACC SDIO0 D0"), - PINCTRL_PIN(437, "PIO USB PU"), - PINCTRL_PIN(438, "PIO USB SP"), - PINCTRL_PIN(439, "PIO USB DAT VP"), - PINCTRL_PIN(440, "PIO USB SE0 VM"), - PINCTRL_PIN(441, "PIO USB OE"), - PINCTRL_PIN(442, "PIO USB SUSP"), - PINCTRL_PIN(443, "P PAD VSSIO 6"), - PINCTRL_PIN(444, "P PAD VDDIO 6"), - PINCTRL_PIN(445, "PIO USB PUEN"), - PINCTRL_PIN(446, "PIO ACC UART0 RX"), - PINCTRL_PIN(447, "PIO ACC UART0 TX"), - PINCTRL_PIN(448, "PIO ACC UART0 CTS"), - PINCTRL_PIN(449, "PIO ACC UART0 RTS"), - PINCTRL_PIN(450, "PIO ACC UART3 RX"), - PINCTRL_PIN(451, "PIO ACC UART3 TX"), - PINCTRL_PIN(452, "PIO ACC UART3 CTS"), - PINCTRL_PIN(453, "PIO ACC UART3 RTS"), - PINCTRL_PIN(454, "PIO ACC IRDA TX"), - PINCTRL_PIN(455, "P PAD VDDIO 7"), - PINCTRL_PIN(456, "P PAD VSSIO 7"), - PINCTRL_PIN(457, "P PAD GND 7"), - PINCTRL_PIN(458, "P PAD VDD 7"), - PINCTRL_PIN(459, "PIO ACC IRDA RX"), - PINCTRL_PIN(460, "PIO ACC PCM I2S CLK"), - PINCTRL_PIN(461, "PIO ACC PCM I2S WS"), - PINCTRL_PIN(462, "PIO ACC PCM I2S DATA A"), - PINCTRL_PIN(463, "PIO ACC PCM I2S DATA B"), - PINCTRL_PIN(464, "PO SIM CLK"), - PINCTRL_PIN(465, "PIO ACC IRDA SD"), - PINCTRL_PIN(466, "PIO SIM DATA"), -}; - -/** - * @dev: a pointer back to containing device - * @virtbase: the offset to the controller in virtual memory - */ -struct u300_pmx { - struct device *dev; - struct pinctrl_dev *pctl; - u32 phybase; - u32 physize; - void __iomem *virtbase; -}; - -/** - * u300_pmx_registers - the array of registers read/written for each pinmux - * shunt setting - */ -const u32 u300_pmx_registers[] = { - U300_SYSCON_PMC1LR, - U300_SYSCON_PMC1HR, - U300_SYSCON_PMC2R, - U300_SYSCON_PMC3R, - U300_SYSCON_PMC4R, -}; - -/** - * struct u300_pin_group - describes a U300 pin group - * @name: the name of this specific pin group - * @pins: an array of discrete physical pins used in this group, taken - * from the driver-local pin enumeration space - * @num_pins: the number of pins in this group array, i.e. the number of - * elements in .pins so we can iterate over that array - */ -struct u300_pin_group { - const char *name; - const unsigned int *pins; - const unsigned num_pins; -}; - -/** - * struct pmx_onmask - mask bits to enable/disable padmux - * @mask: mask bits to disable - * @val: mask bits to enable - * - * onmask lazy dog: - * onmask = { - * {"PMC1LR" mask, "PMC1LR" value}, - * {"PMC1HR" mask, "PMC1HR" value}, - * {"PMC2R" mask, "PMC2R" value}, - * {"PMC3R" mask, "PMC3R" value}, - * {"PMC4R" mask, "PMC4R" value} - * } - */ -struct u300_pmx_mask { - u16 mask; - u16 bits; -}; - -/* The chip power pins are VDD, GND, VDDIO and VSSIO */ -static const unsigned power_pins[] = { 0, 1, 3, 31, 46, 47, 49, 50, 61, 62, 63, - 64, 78, 79, 80, 81, 92, 93, 94, 95, 101, 102, 103, 104, 115, 116, 117, - 118, 130, 131, 132, 133, 145, 146, 147, 148, 159, 160, 172, 173, 174, - 175, 187, 188, 189, 190, 201, 202, 211, 212, 213, 214, 215, 218, 223, - 224, 225, 226, 231, 232, 237, 238, 239, 240, 245, 246, 251, 252, 256, - 257, 258, 259, 264, 265, 270, 271, 276, 277, 278, 279, 284, 285, 290, - 291, 295, 296, 299, 300, 301, 302, 303, 309, 310, 311, 312, 319, 320, - 321, 322, 329, 330, 331, 332, 341, 342, 343, 344, 358, 359, 360, 361, - 372, 373, 374, 375, 388, 389, 390, 391, 402, 403, 404, 405, 413, 414, - 415, 416, 427, 428, 429, 430, 443, 444, 455, 456, 457, 458 }; -static const unsigned emif0_pins[] = { 355, 356, 357, 362, 363, 364, 365, 366, - 367, 368, 369, 370, 371, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 393, 394, 395, 396, 397, 398, 406, 407, 410, 411, 412, - 417, 418 }; -static const unsigned emif1_pins[] = { 216, 217, 219, 220, 221, 222, 227, 228, - 229, 230, 233, 234, 235, 236, 241, 242, 243, 244, 247, 248, 249, 250, - 253, 254, 255, 260, 261, 262, 263, 266, 267, 268, 269, 272, 273, 274, - 275, 280, 281, 282, 283, 286, 287, 288, 289, 292, 293, 294, 297, 298, - 304, 305, 306, 307, 308, 313, 314, 315 }; -static const unsigned uart0_pins[] = { 134, 135, 136, 137 }; -static const unsigned mmc0_pins[] = { 166, 167, 168, 169, 170, 171, 176, 177 }; -static const unsigned spi0_pins[] = { 420, 421, 422, 423, 424, 425 }; - -static const struct u300_pmx_mask emif0_mask[] = { - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, -}; - -static const struct u300_pmx_mask emif1_mask[] = { - /* - * This connects the SDRAM to CS2 and a NAND flash to - * CS0 on the EMIF. - */ - { - U300_SYSCON_PMC1LR_EMIF_1_CS2_MASK | - U300_SYSCON_PMC1LR_EMIF_1_CS1_MASK | - U300_SYSCON_PMC1LR_EMIF_1_CS0_MASK | - U300_SYSCON_PMC1LR_EMIF_1_MASK, - U300_SYSCON_PMC1LR_EMIF_1_CS2_SDRAM | - U300_SYSCON_PMC1LR_EMIF_1_CS1_STATIC | - U300_SYSCON_PMC1LR_EMIF_1_CS0_NFIF | - U300_SYSCON_PMC1LR_EMIF_1_SDRAM0 - }, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, -}; - -static const struct u300_pmx_mask uart0_mask[] = { - {0, 0}, - { - U300_SYSCON_PMC1HR_APP_UART0_1_MASK | - U300_SYSCON_PMC1HR_APP_UART0_2_MASK, - U300_SYSCON_PMC1HR_APP_UART0_1_UART0 | - U300_SYSCON_PMC1HR_APP_UART0_2_UART0 - }, - {0, 0}, - {0, 0}, - {0, 0}, -}; - -static const struct u300_pmx_mask mmc0_mask[] = { - { U300_SYSCON_PMC1LR_MMCSD_MASK, U300_SYSCON_PMC1LR_MMCSD_MMCSD}, - {0, 0}, - {0, 0}, - {0, 0}, - { U300_SYSCON_PMC4R_APP_MISC_12_MASK, - U300_SYSCON_PMC4R_APP_MISC_12_APP_GPIO } -}; - -static const struct u300_pmx_mask spi0_mask[] = { - {0, 0}, - { - U300_SYSCON_PMC1HR_APP_SPI_2_MASK | - U300_SYSCON_PMC1HR_APP_SPI_CS_1_MASK | - U300_SYSCON_PMC1HR_APP_SPI_CS_2_MASK, - U300_SYSCON_PMC1HR_APP_SPI_2_SPI | - U300_SYSCON_PMC1HR_APP_SPI_CS_1_SPI | - U300_SYSCON_PMC1HR_APP_SPI_CS_2_SPI - }, - {0, 0}, - {0, 0}, - {0, 0} -}; - -static const struct u300_pin_group u300_pin_groups[] = { - { - .name = "powergrp", - .pins = power_pins, - .num_pins = ARRAY_SIZE(power_pins), - }, - { - .name = "emif0grp", - .pins = emif0_pins, - .num_pins = ARRAY_SIZE(emif0_pins), - }, - { - .name = "emif1grp", - .pins = emif1_pins, - .num_pins = ARRAY_SIZE(emif1_pins), - }, - { - .name = "uart0grp", - .pins = uart0_pins, - .num_pins = ARRAY_SIZE(uart0_pins), - }, - { - .name = "mmc0grp", - .pins = mmc0_pins, - .num_pins = ARRAY_SIZE(mmc0_pins), - }, - { - .name = "spi0grp", - .pins = spi0_pins, - .num_pins = ARRAY_SIZE(spi0_pins), - }, -}; - -static int u300_list_groups(struct pinctrl_dev *pctldev, unsigned selector) -{ - if (selector >= ARRAY_SIZE(u300_pin_groups)) - return -EINVAL; - return 0; -} - -static const char *u300_get_group_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - if (selector >= ARRAY_SIZE(u300_pin_groups)) - return NULL; - return u300_pin_groups[selector].name; -} - -static int u300_get_group_pins(struct pinctrl_dev *pctldev, unsigned selector, - const unsigned **pins, - unsigned *num_pins) -{ - if (selector >= ARRAY_SIZE(u300_pin_groups)) - return -EINVAL; - *pins = u300_pin_groups[selector].pins; - *num_pins = u300_pin_groups[selector].num_pins; - return 0; -} - -static void u300_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s, - unsigned offset) -{ - seq_printf(s, " " DRIVER_NAME); -} - -static struct pinctrl_ops u300_pctrl_ops = { - .list_groups = u300_list_groups, - .get_group_name = u300_get_group_name, - .get_group_pins = u300_get_group_pins, - .pin_dbg_show = u300_pin_dbg_show, -}; - -/* - * Here we define the available functions and their corresponding pin groups - */ - -/** - * struct u300_pmx_func - describes U300 pinmux functions - * @name: the name of this specific function - * @groups: corresponding pin groups - * @onmask: bits to set to enable this when doing pin muxing - */ -struct u300_pmx_func { - const char *name; - const char * const *groups; - const unsigned num_groups; - const struct u300_pmx_mask *mask; -}; - -static const char * const powergrps[] = { "powergrp" }; -static const char * const emif0grps[] = { "emif0grp" }; -static const char * const emif1grps[] = { "emif1grp" }; -static const char * const uart0grps[] = { "uart0grp" }; -static const char * const mmc0grps[] = { "mmc0grp" }; -static const char * const spi0grps[] = { "spi0grp" }; - -static const struct u300_pmx_func u300_pmx_functions[] = { - { - .name = "power", - .groups = powergrps, - .num_groups = ARRAY_SIZE(powergrps), - /* Mask is N/A */ - }, - { - .name = "emif0", - .groups = emif0grps, - .num_groups = ARRAY_SIZE(emif0grps), - .mask = emif0_mask, - }, - { - .name = "emif1", - .groups = emif1grps, - .num_groups = ARRAY_SIZE(emif1grps), - .mask = emif1_mask, - }, - { - .name = "uart0", - .groups = uart0grps, - .num_groups = ARRAY_SIZE(uart0grps), - .mask = uart0_mask, - }, - { - .name = "mmc0", - .groups = mmc0grps, - .num_groups = ARRAY_SIZE(mmc0grps), - .mask = mmc0_mask, - }, - { - .name = "spi0", - .groups = spi0grps, - .num_groups = ARRAY_SIZE(spi0grps), - .mask = spi0_mask, - }, -}; - -static void u300_pmx_endisable(struct u300_pmx *upmx, unsigned selector, - bool enable) -{ - u16 regval, val, mask; - int i; - const struct u300_pmx_mask *upmx_mask; - - upmx_mask = u300_pmx_functions[selector].mask; - for (i = 0; i < ARRAY_SIZE(u300_pmx_registers); i++) { - if (enable) - val = upmx_mask->bits; - else - val = 0; - - mask = upmx_mask->mask; - if (mask != 0) { - regval = readw(upmx->virtbase + u300_pmx_registers[i]); - regval &= ~mask; - regval |= val; - writew(regval, upmx->virtbase + u300_pmx_registers[i]); - } - upmx_mask++; - } -} - -static int u300_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector, - unsigned group) -{ - struct u300_pmx *upmx; - - /* There is nothing to do with the power pins */ - if (selector == 0) - return 0; - - upmx = pinctrl_dev_get_drvdata(pctldev); - u300_pmx_endisable(upmx, selector, true); - - return 0; -} - -static void u300_pmx_disable(struct pinctrl_dev *pctldev, unsigned selector, - unsigned group) -{ - struct u300_pmx *upmx; - - /* There is nothing to do with the power pins */ - if (selector == 0) - return; - - upmx = pinctrl_dev_get_drvdata(pctldev); - u300_pmx_endisable(upmx, selector, false); -} - -static int u300_pmx_list_funcs(struct pinctrl_dev *pctldev, unsigned selector) -{ - if (selector >= ARRAY_SIZE(u300_pmx_functions)) - return -EINVAL; - return 0; -} - -static const char *u300_pmx_get_func_name(struct pinctrl_dev *pctldev, - unsigned selector) -{ - return u300_pmx_functions[selector].name; -} - -static int u300_pmx_get_groups(struct pinctrl_dev *pctldev, unsigned selector, - const char * const **groups, - unsigned * const num_groups) -{ - *groups = u300_pmx_functions[selector].groups; - *num_groups = u300_pmx_functions[selector].num_groups; - return 0; -} - -static struct pinmux_ops u300_pmx_ops = { - .list_functions = u300_pmx_list_funcs, - .get_function_name = u300_pmx_get_func_name, - .get_function_groups = u300_pmx_get_groups, - .enable = u300_pmx_enable, - .disable = u300_pmx_disable, -}; - -/* - * GPIO ranges handled by the application-side COH901XXX GPIO controller - * Very many pins can be converted into GPIO pins, but we only list those - * that are useful in practice to cut down on tables. - */ -#define U300_GPIO_RANGE(a, b, c) { .name = "COH901XXX", .id = a, .base= a, \ - .pin_base = b, .npins = c } - -static struct pinctrl_gpio_range u300_gpio_ranges[] = { - U300_GPIO_RANGE(10, 426, 1), - U300_GPIO_RANGE(11, 180, 1), - U300_GPIO_RANGE(12, 165, 1), /* MS/MMC card insertion */ - U300_GPIO_RANGE(13, 179, 1), - U300_GPIO_RANGE(14, 178, 1), - U300_GPIO_RANGE(16, 194, 1), - U300_GPIO_RANGE(17, 193, 1), - U300_GPIO_RANGE(18, 192, 1), - U300_GPIO_RANGE(19, 191, 1), - U300_GPIO_RANGE(20, 186, 1), - U300_GPIO_RANGE(21, 185, 1), - U300_GPIO_RANGE(22, 184, 1), - U300_GPIO_RANGE(23, 183, 1), - U300_GPIO_RANGE(24, 182, 1), - U300_GPIO_RANGE(25, 181, 1), -}; - -static struct pinctrl_desc u300_pmx_desc = { - .name = DRIVER_NAME, - .pins = u300_pads, - .npins = ARRAY_SIZE(u300_pads), - .maxpin = U300_NUM_PADS-1, - .pctlops = &u300_pctrl_ops, - .pmxops = &u300_pmx_ops, - .owner = THIS_MODULE, -}; - -static int __init u300_pmx_probe(struct platform_device *pdev) -{ - struct u300_pmx *upmx; - struct resource *res; - int ret; - int i; - - /* Create state holders etc for this driver */ - upmx = devm_kzalloc(&pdev->dev, sizeof(*upmx), GFP_KERNEL); - if (!upmx) - return -ENOMEM; - - upmx->dev = &pdev->dev; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - ret = -ENOENT; - goto out_no_resource; - } - upmx->phybase = res->start; - upmx->physize = resource_size(res); - - if (request_mem_region(upmx->phybase, upmx->physize, - DRIVER_NAME) == NULL) { - ret = -ENOMEM; - goto out_no_memregion; - } - - upmx->virtbase = ioremap(upmx->phybase, upmx->physize); - if (!upmx->virtbase) { - ret = -ENOMEM; - goto out_no_remap; - } - - upmx->pctl = pinctrl_register(&u300_pmx_desc, &pdev->dev, upmx); - if (!upmx->pctl) { - dev_err(&pdev->dev, "could not register U300 pinmux driver\n"); - ret = -EINVAL; - goto out_no_pmx; - } - - /* We will handle a range of GPIO pins */ - for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) - pinctrl_add_gpio_range(upmx->pctl, &u300_gpio_ranges[i]); - - platform_set_drvdata(pdev, upmx); - - dev_info(&pdev->dev, "initialized U300 pinmux driver\n"); - - return 0; - -out_no_pmx: - iounmap(upmx->virtbase); -out_no_remap: - platform_set_drvdata(pdev, NULL); -out_no_memregion: - release_mem_region(upmx->phybase, upmx->physize); -out_no_resource: - devm_kfree(&pdev->dev, upmx); - return ret; -} - -static int __exit u300_pmx_remove(struct platform_device *pdev) -{ - struct u300_pmx *upmx = platform_get_drvdata(pdev); - int i; - - for (i = 0; i < ARRAY_SIZE(u300_gpio_ranges); i++) - pinctrl_remove_gpio_range(upmx->pctl, &u300_gpio_ranges[i]); - pinctrl_unregister(upmx->pctl); - iounmap(upmx->virtbase); - release_mem_region(upmx->phybase, upmx->physize); - platform_set_drvdata(pdev, NULL); - devm_kfree(&pdev->dev, upmx); - - return 0; -} - -static struct platform_driver u300_pmx_driver = { - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - }, - .remove = __exit_p(u300_pmx_remove), -}; - -static int __init u300_pmx_init(void) -{ - return platform_driver_probe(&u300_pmx_driver, u300_pmx_probe); -} -arch_initcall(u300_pmx_init); - -static void __exit u300_pmx_exit(void) -{ - platform_driver_unregister(&u300_pmx_driver); -} -module_exit(u300_pmx_exit); - -MODULE_AUTHOR("Linus Walleij "); -MODULE_DESCRIPTION("U300 pin control driver"); -MODULE_LICENSE("GPL v2"); -- cgit v1.1 From e6337c3c96a7ee5cfd5e7afed825f894d4576f58 Mon Sep 17 00:00:00 2001 From: Dong Aisheng Date: Tue, 20 Dec 2011 17:51:59 +0800 Subject: pinctrl: some typo fixes Minor copyedits. Signed-off-by: Dong Aisheng Signed-off-by: Linus Walleij --- drivers/pinctrl/pinmux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 3bcc641..0916222 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -342,7 +342,7 @@ EXPORT_SYMBOL_GPL(pinmux_gpio_direction_output); * 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 - * free:d. + * freed. */ int __init pinmux_register_mappings(struct pinmux_map const *maps, unsigned num_maps) -- cgit v1.1 From 706e8520e8450a631ca6f798f8c811faf56f0a59 Mon Sep 17 00:00:00 2001 From: Chanho Park Date: Tue, 3 Jan 2012 16:47:50 +0900 Subject: pinctrl: correct a offset while enumerating pins This patch modifies a offset while enumerating pins to support a partial pin space. If we use a pin number for enumerating pins, the pin space always starts with zero base. Indeed, we always check the pin is in the pin space. An extreme example, there is only two pins. One is 0. Another is 1000. We always enumerate whole offsets until 1000. For solving this problem, we use the offset of the pin array instead of the zero-based pin number. Signed-off-by: Chanho Park Signed-off-by: Kyungmin Park [Restored sparse pin space comment] Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 14 ++++++++------ drivers/pinctrl/pinconf.c | 9 +++++---- drivers/pinctrl/pinmux.c | 9 +++++---- 3 files changed, 18 insertions(+), 14 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 9e32ea3..79c56d90 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -102,12 +102,13 @@ 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) { - unsigned pin; + unsigned i, pin; - /* The highest pin number need to be included in the loop, thus <= */ - for (pin = 0; pin <= pctldev->desc->maxpin; pin++) { + /* The pin number can be retrived from the pin controller descriptor */ + for (i = 0; i < pctldev->desc->npins; i++) { struct pin_desc *desc; + pin = pctldev->desc->pins[i].number; desc = pin_desc_get(pctldev, pin); /* Pin space may be sparse */ if (desc == NULL) @@ -350,15 +351,16 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev = s->private; const struct pinctrl_ops *ops = pctldev->desc->pctlops; - unsigned pin; + unsigned i, pin; seq_printf(s, "registered pins: %d\n", pctldev->desc->npins); seq_printf(s, "max pin number: %d\n", pctldev->desc->maxpin); - /* The highest pin number need to be included in the loop, thus <= */ - for (pin = 0; pin <= pctldev->desc->maxpin; pin++) { + /* The pin number can be retrived from the pin controller descriptor */ + for (i = 0; i < pctldev->desc->npins; i++) { struct pin_desc *desc; + pin = pctldev->desc->pins[i].number; desc = pin_desc_get(pctldev, pin); /* Pin space may be sparse */ if (desc == NULL) diff --git a/drivers/pinctrl/pinconf.c b/drivers/pinctrl/pinconf.c index 57dbb4b..1259872 100644 --- a/drivers/pinctrl/pinconf.c +++ b/drivers/pinctrl/pinconf.c @@ -230,17 +230,18 @@ static void pinconf_dump_pin(struct pinctrl_dev *pctldev, static int pinconf_pins_show(struct seq_file *s, void *what) { struct pinctrl_dev *pctldev = s->private; - unsigned pin; + unsigned i, pin; seq_puts(s, "Pin config settings per pin\n"); seq_puts(s, "Format: pin (name): pinmux setting array\n"); - /* The highest pin number need to be included in the loop, thus <= */ - for (pin = 0; pin <= pctldev->desc->maxpin; pin++) { + /* The pin number can be retrived from the pin controller descriptor */ + for (i = 0; pin < pctldev->desc->npins; i++) { struct pin_desc *desc; + pin = pctldev->desc->pins[i].number; desc = pin_desc_get(pctldev, pin); - /* Pin space may be sparse */ + /* Skip if we cannot search the pin */ if (desc == NULL) continue; diff --git a/drivers/pinctrl/pinmux.c b/drivers/pinctrl/pinmux.c index 0916222..a76a348 100644 --- a/drivers/pinctrl/pinmux.c +++ b/drivers/pinctrl/pinmux.c @@ -1063,18 +1063,19 @@ 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; - unsigned pin; + unsigned i, pin; seq_puts(s, "Pinmux settings per pin\n"); seq_puts(s, "Format: pin (name): pinmuxfunction\n"); - /* The highest pin number need to be included in the loop, thus <= */ - for (pin = 0; pin <= pctldev->desc->maxpin; pin++) { + /* The pin number can be retrived from the pin controller descriptor */ + for (i = 0; i < pctldev->desc->npins; i++) { struct pin_desc *desc; + pin = pctldev->desc->pins[i].number; desc = pin_desc_get(pctldev, pin); - /* Pin space may be sparse */ + /* Skip if we cannot search the pin */ if (desc == NULL) continue; -- cgit v1.1 From 0d2006bbf09e817f125ba1e42b2549bc2c5d7351 Mon Sep 17 00:00:00 2001 From: Chanho Park Date: Tue, 3 Jan 2012 16:47:51 +0900 Subject: pinctrl: remove unnecessary max pin number This patch removes maxpin member in the pin control descriptor because we don't need this value as we enumerate a pin space using offset. Signed-off-by: Chanho Park Signed-off-by: Kyungmin Park Signed-off-by: Linus Walleij --- drivers/pinctrl/core.c | 1 - drivers/pinctrl/pinctrl-sirf.c | 1 - drivers/pinctrl/pinctrl-u300.c | 1 - 3 files changed, 3 deletions(-) (limited to 'drivers') diff --git a/drivers/pinctrl/core.c b/drivers/pinctrl/core.c index 79c56d90..569bdb3 100644 --- a/drivers/pinctrl/core.c +++ b/drivers/pinctrl/core.c @@ -354,7 +354,6 @@ static int pinctrl_pins_show(struct seq_file *s, void *what) unsigned i, pin; seq_printf(s, "registered pins: %d\n", pctldev->desc->npins); - seq_printf(s, "max pin number: %d\n", pctldev->desc->maxpin); /* The pin number can be retrived from the pin controller descriptor */ for (i = 0; i < pctldev->desc->npins; i++) { diff --git a/drivers/pinctrl/pinctrl-sirf.c b/drivers/pinctrl/pinctrl-sirf.c index 99e688e..6b3534c 100644 --- a/drivers/pinctrl/pinctrl-sirf.c +++ b/drivers/pinctrl/pinctrl-sirf.c @@ -1086,7 +1086,6 @@ static struct pinctrl_desc sirfsoc_pinmux_desc = { .name = DRIVER_NAME, .pins = sirfsoc_pads, .npins = ARRAY_SIZE(sirfsoc_pads), - .maxpin = SIRFSOC_NUM_PADS - 1, .pctlops = &sirfsoc_pctrl_ops, .pmxops = &sirfsoc_pinmux_ops, .owner = THIS_MODULE, diff --git a/drivers/pinctrl/pinctrl-u300.c b/drivers/pinctrl/pinctrl-u300.c index 7e89b36..c8d02f1 100644 --- a/drivers/pinctrl/pinctrl-u300.c +++ b/drivers/pinctrl/pinctrl-u300.c @@ -1048,7 +1048,6 @@ static struct pinctrl_desc u300_pmx_desc = { .name = DRIVER_NAME, .pins = u300_pads, .npins = ARRAY_SIZE(u300_pads), - .maxpin = U300_NUM_PADS-1, .pctlops = &u300_pctrl_ops, .pmxops = &u300_pmx_ops, .owner = THIS_MODULE, -- cgit v1.1