]> git.karo-electronics.de Git - mv-sheeva.git/blob - arch/arm/plat-s3c/gpio-config.c
Merge branch 'x86-fpu-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git...
[mv-sheeva.git] / arch / arm / plat-s3c / gpio-config.c
1 /* linux/arch/arm/plat-s3c/gpio-config.c
2  *
3  * Copyright 2008 Openmoko, Inc.
4  * Copyright 2008 Simtec Electronics
5  *      Ben Dooks <ben@simtec.co.uk>
6  *      http://armlinux.simtec.co.uk/
7  *
8  * S3C series GPIO configuration core
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License version 2 as
12  * published by the Free Software Foundation.
13 */
14
15 #include <linux/kernel.h>
16 #include <linux/module.h>
17 #include <linux/gpio.h>
18 #include <linux/io.h>
19
20 #include <mach/gpio-core.h>
21 #include <plat/gpio-cfg.h>
22 #include <plat/gpio-cfg-helpers.h>
23
24 int s3c_gpio_cfgpin(unsigned int pin, unsigned int config)
25 {
26         struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
27         unsigned long flags;
28         int offset;
29         int ret;
30
31         if (!chip)
32                 return -EINVAL;
33
34         offset = pin - chip->chip.base;
35
36         local_irq_save(flags);
37         ret = s3c_gpio_do_setcfg(chip, offset, config);
38         local_irq_restore(flags);
39
40         return ret;
41 }
42 EXPORT_SYMBOL(s3c_gpio_cfgpin);
43
44 int s3c_gpio_setpull(unsigned int pin, s3c_gpio_pull_t pull)
45 {
46         struct s3c_gpio_chip *chip = s3c_gpiolib_getchip(pin);
47         unsigned long flags;
48         int offset, ret;
49
50         if (!chip)
51                 return -EINVAL;
52
53         offset = pin - chip->chip.base;
54
55         local_irq_save(flags);
56         ret = s3c_gpio_do_setpull(chip, offset, pull);
57         local_irq_restore(flags);
58
59         return ret;
60 }
61 EXPORT_SYMBOL(s3c_gpio_setpull);
62
63 #ifdef CONFIG_S3C_GPIO_CFG_S3C24XX
64 int s3c_gpio_setcfg_s3c24xx_banka(struct s3c_gpio_chip *chip,
65                                   unsigned int off, unsigned int cfg)
66 {
67         void __iomem *reg = chip->base;
68         unsigned int shift = off;
69         u32 con;
70
71         if (s3c_gpio_is_cfg_special(cfg)) {
72                 cfg &= 0xf;
73
74                 /* Map output to 0, and SFN2 to 1 */
75                 cfg -= 1;
76                 if (cfg > 1)
77                         return -EINVAL;
78
79                 cfg <<= shift;
80         }
81
82         con = __raw_readl(reg);
83         con &= ~(0x1 << shift);
84         con |= cfg;
85         __raw_writel(con, reg);
86
87         return 0;
88 }
89
90 int s3c_gpio_setcfg_s3c24xx(struct s3c_gpio_chip *chip,
91                             unsigned int off, unsigned int cfg)
92 {
93         void __iomem *reg = chip->base;
94         unsigned int shift = off * 2;
95         u32 con;
96
97         if (s3c_gpio_is_cfg_special(cfg)) {
98                 cfg &= 0xf;
99                 if (cfg > 3)
100                         return -EINVAL;
101
102                 cfg <<= shift;
103         }
104
105         con = __raw_readl(reg);
106         con &= ~(0x3 << shift);
107         con |= cfg;
108         __raw_writel(con, reg);
109
110         return 0;
111 }
112 #endif
113
114 #ifdef CONFIG_S3C_GPIO_CFG_S3C64XX
115 int s3c_gpio_setcfg_s3c64xx_4bit(struct s3c_gpio_chip *chip,
116                                  unsigned int off, unsigned int cfg)
117 {
118         void __iomem *reg = chip->base;
119         unsigned int shift = (off & 7) * 4;
120         u32 con;
121
122         if (off < 8 && chip->chip.ngpio >= 8)
123                 reg -= 4;
124
125         if (s3c_gpio_is_cfg_special(cfg)) {
126                 cfg &= 0xf;
127                 cfg <<= shift;
128         }
129
130         con = __raw_readl(reg);
131         con &= ~(0xf << shift);
132         con |= cfg;
133         __raw_writel(con, reg);
134
135         return 0;
136 }
137 #endif /* CONFIG_S3C_GPIO_CFG_S3C64XX */
138
139 #ifdef CONFIG_S3C_GPIO_PULL_UPDOWN
140 int s3c_gpio_setpull_updown(struct s3c_gpio_chip *chip,
141                             unsigned int off, s3c_gpio_pull_t pull)
142 {
143         void __iomem *reg = chip->base + 0x08;
144         int shift = off * 2;
145         u32 pup;
146
147         pup = __raw_readl(reg);
148         pup &= ~(3 << shift);
149         pup |= pull << shift;
150         __raw_writel(pup, reg);
151
152         return 0;
153 }
154
155 s3c_gpio_pull_t s3c_gpio_getpull_updown(struct s3c_gpio_chip *chip,
156                                         unsigned int off)
157 {
158         void __iomem *reg = chip->base + 0x08;
159         int shift = off * 2;
160         u32 pup = __raw_readl(reg);
161
162         pup >>= shift;
163         pup &= 0x3;
164         return (__force s3c_gpio_pull_t)pup;
165 }
166 #endif