aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/pinctrl/spear
diff options
context:
space:
mode:
authorShiraz Hashim <shiraz.hashim@st.com>2012-11-07 09:37:25 -0500
committerLinus Walleij <linus.walleij@linaro.org>2012-11-11 13:36:04 -0500
commit826d6ca8f955c7a902e775acef3bdbfc93695b04 (patch)
treeacfea21f3a3d52e0cfc706028394a4283fa6eb1b /drivers/pinctrl/spear
parent6bb0700bfe124f3ee245da24b5bb35152d2e6bfc (diff)
pinctrl: SPEAr: Add SoC specific gpio configuration routines
Different SPEAr SoCs have different approach to configure pins as gpios. Some configure a group of gpios with single register bit and others have one bit per gpio pin. Only earlier one is implemented till now, this patch adds support for later one. Here we add callbacks to SoC specific code to configure gpios in gpio_request_enable(). That will do additional SoC specific configuration to enable gpio pins. We also implement this callback for SPEAr1340 in this patch. Signed-off-by: Shiraz Hashim <shiraz.hashim@st.com> Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org> Signed-off-by: Linus Walleij <linus.walleij@linaro.org>
Diffstat (limited to 'drivers/pinctrl/spear')
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear.c26
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear.h14
-rw-r--r--drivers/pinctrl/spear/pinctrl-spear1340.c27
3 files changed, 53 insertions, 14 deletions
diff --git a/drivers/pinctrl/spear/pinctrl-spear.c b/drivers/pinctrl/spear/pinctrl-spear.c
index cbca6dc66eb7..f9483ae42726 100644
--- a/drivers/pinctrl/spear/pinctrl-spear.c
+++ b/drivers/pinctrl/spear/pinctrl-spear.c
@@ -14,7 +14,6 @@
14 */ 14 */
15 15
16#include <linux/err.h> 16#include <linux/err.h>
17#include <linux/io.h>
18#include <linux/module.h> 17#include <linux/module.h>
19#include <linux/of.h> 18#include <linux/of.h>
20#include <linux/of_address.h> 19#include <linux/of_address.h>
@@ -29,16 +28,6 @@
29 28
30#define DRIVER_NAME "spear-pinmux" 29#define DRIVER_NAME "spear-pinmux"
31 30
32static inline u32 pmx_readl(struct spear_pmx *pmx, u32 reg)
33{
34 return readl_relaxed(pmx->vbase + reg);
35}
36
37static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg)
38{
39 writel_relaxed(val, pmx->vbase + reg);
40}
41
42static void muxregs_endisable(struct spear_pmx *pmx, 31static void muxregs_endisable(struct spear_pmx *pmx,
43 struct spear_muxreg *muxregs, u8 count, bool enable) 32 struct spear_muxreg *muxregs, u8 count, bool enable)
44{ 33{
@@ -316,16 +305,25 @@ static int gpio_request_endisable(struct pinctrl_dev *pctldev,
316 struct pinctrl_gpio_range *range, unsigned offset, bool enable) 305 struct pinctrl_gpio_range *range, unsigned offset, bool enable)
317{ 306{
318 struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev); 307 struct spear_pmx *pmx = pinctrl_dev_get_drvdata(pctldev);
308 struct spear_pinctrl_machdata *machdata = pmx->machdata;
319 struct spear_gpio_pingroup *gpio_pingroup; 309 struct spear_gpio_pingroup *gpio_pingroup;
320 310
311 /*
312 * Some SoC have configuration options applicable to group of pins,
313 * rather than a single pin.
314 */
321 gpio_pingroup = get_gpio_pingroup(pmx, offset); 315 gpio_pingroup = get_gpio_pingroup(pmx, offset);
322 if (IS_ERR(gpio_pingroup))
323 return PTR_ERR(gpio_pingroup);
324
325 if (gpio_pingroup) 316 if (gpio_pingroup)
326 muxregs_endisable(pmx, gpio_pingroup->muxregs, 317 muxregs_endisable(pmx, gpio_pingroup->muxregs,
327 gpio_pingroup->nmuxregs, enable); 318 gpio_pingroup->nmuxregs, enable);
328 319
320 /*
321 * SoC may need some extra configurations, or configurations for single
322 * pin
323 */
324 if (machdata->gpio_request_endisable)
325 machdata->gpio_request_endisable(pmx, offset, enable);
326
329 return 0; 327 return 0;
330} 328}
331 329
diff --git a/drivers/pinctrl/spear/pinctrl-spear.h b/drivers/pinctrl/spear/pinctrl-spear.h
index 94f142c10c19..b06332719b2c 100644
--- a/drivers/pinctrl/spear/pinctrl-spear.h
+++ b/drivers/pinctrl/spear/pinctrl-spear.h
@@ -13,11 +13,13 @@
13#define __PINMUX_SPEAR_H__ 13#define __PINMUX_SPEAR_H__
14 14
15#include <linux/gpio.h> 15#include <linux/gpio.h>
16#include <linux/io.h>
16#include <linux/pinctrl/pinctrl.h> 17#include <linux/pinctrl/pinctrl.h>
17#include <linux/types.h> 18#include <linux/types.h>
18 19
19struct platform_device; 20struct platform_device;
20struct device; 21struct device;
22struct spear_pmx;
21 23
22/** 24/**
23 * struct spear_pmx_mode - SPEAr pmx mode 25 * struct spear_pmx_mode - SPEAr pmx mode
@@ -155,6 +157,8 @@ struct spear_pinctrl_machdata {
155 struct spear_pingroup **groups; 157 struct spear_pingroup **groups;
156 unsigned ngroups; 158 unsigned ngroups;
157 struct spear_gpio_pingroup *gpio_pingroups; 159 struct spear_gpio_pingroup *gpio_pingroups;
160 void (*gpio_request_endisable)(struct spear_pmx *pmx, int offset,
161 bool enable);
158 unsigned ngpio_pingroups; 162 unsigned ngpio_pingroups;
159 163
160 bool modes_supported; 164 bool modes_supported;
@@ -178,6 +182,16 @@ struct spear_pmx {
178}; 182};
179 183
180/* exported routines */ 184/* exported routines */
185static inline u32 pmx_readl(struct spear_pmx *pmx, u32 reg)
186{
187 return readl_relaxed(pmx->vbase + reg);
188}
189
190static inline void pmx_writel(struct spear_pmx *pmx, u32 val, u32 reg)
191{
192 writel_relaxed(val, pmx->vbase + reg);
193}
194
181void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg); 195void __devinit pmx_init_addr(struct spear_pinctrl_machdata *machdata, u16 reg);
182void __devinit 196void __devinit
183pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup, 197pmx_init_gpio_pingroup_addr(struct spear_gpio_pingroup *gpio_pingroup,
diff --git a/drivers/pinctrl/spear/pinctrl-spear1340.c b/drivers/pinctrl/spear/pinctrl-spear1340.c
index 0606b8cf3f2c..0b4af0e5cdc1 100644
--- a/drivers/pinctrl/spear/pinctrl-spear1340.c
+++ b/drivers/pinctrl/spear/pinctrl-spear1340.c
@@ -1971,6 +1971,32 @@ static struct spear_function *spear1340_functions[] = {
1971 &sata_function, 1971 &sata_function,
1972}; 1972};
1973 1973
1974static void gpio_request_endisable(struct spear_pmx *pmx, int pin,
1975 bool enable)
1976{
1977 unsigned int regoffset, regindex, bitoffset;
1978 unsigned int val;
1979
1980 /* pin++ as gpio configuration starts from 2nd bit of base register */
1981 pin++;
1982
1983 regindex = pin / 32;
1984 bitoffset = pin % 32;
1985
1986 if (regindex <= 3)
1987 regoffset = PAD_FUNCTION_EN_1 + regindex * sizeof(int *);
1988 else
1989 regoffset = PAD_FUNCTION_EN_5 + (regindex - 4) * sizeof(int *);
1990
1991 val = pmx_readl(pmx, regoffset);
1992 if (enable)
1993 val &= ~(0x1 << bitoffset);
1994 else
1995 val |= 0x1 << bitoffset;
1996
1997 pmx_writel(pmx, val, regoffset);
1998}
1999
1974static struct spear_pinctrl_machdata spear1340_machdata = { 2000static struct spear_pinctrl_machdata spear1340_machdata = {
1975 .pins = spear1340_pins, 2001 .pins = spear1340_pins,
1976 .npins = ARRAY_SIZE(spear1340_pins), 2002 .npins = ARRAY_SIZE(spear1340_pins),
@@ -1978,6 +2004,7 @@ static struct spear_pinctrl_machdata spear1340_machdata = {
1978 .ngroups = ARRAY_SIZE(spear1340_pingroups), 2004 .ngroups = ARRAY_SIZE(spear1340_pingroups),
1979 .functions = spear1340_functions, 2005 .functions = spear1340_functions,
1980 .nfunctions = ARRAY_SIZE(spear1340_functions), 2006 .nfunctions = ARRAY_SIZE(spear1340_functions),
2007 .gpio_request_endisable = gpio_request_endisable,
1981 .modes_supported = false, 2008 .modes_supported = false,
1982}; 2009};
1983 2010