]> git.ipfire.org Git - people/ms/u-boot.git/blob - drivers/gpio/s5p_gpio.c
Merge branch 'master' of git://git.denx.de/u-boot-ppc4xx
[people/ms/u-boot.git] / drivers / gpio / s5p_gpio.c
1 /*
2 * (C) Copyright 2009 Samsung Electronics
3 * Minkyu Kang <mk7.kang@samsung.com>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA
19 */
20
21 #include <common.h>
22 #include <asm/io.h>
23 #include <asm/gpio.h>
24
25 #define CON_MASK(x) (0xf << ((x) << 2))
26 #define CON_SFR(x, v) ((v) << ((x) << 2))
27
28 #define DAT_MASK(x) (0x1 << (x))
29 #define DAT_SET(x) (0x1 << (x))
30
31 #define PULL_MASK(x) (0x3 << ((x) << 1))
32 #define PULL_MODE(x, v) ((v) << ((x) << 1))
33
34 #define DRV_MASK(x) (0x3 << ((x) << 1))
35 #define DRV_SET(x, m) ((m) << ((x) << 1))
36 #define RATE_MASK(x) (0x1 << (x + 16))
37 #define RATE_SET(x) (0x1 << (x + 16))
38
39 void s5p_gpio_cfg_pin(struct s5p_gpio_bank *bank, int gpio, int cfg)
40 {
41 unsigned int value;
42
43 value = readl(&bank->con);
44 value &= ~CON_MASK(gpio);
45 value |= CON_SFR(gpio, cfg);
46 writel(value, &bank->con);
47 }
48
49 void s5p_gpio_direction_output(struct s5p_gpio_bank *bank, int gpio, int en)
50 {
51 unsigned int value;
52
53 s5p_gpio_cfg_pin(bank, gpio, GPIO_OUTPUT);
54
55 value = readl(&bank->dat);
56 value &= ~DAT_MASK(gpio);
57 if (en)
58 value |= DAT_SET(gpio);
59 writel(value, &bank->dat);
60 }
61
62 void s5p_gpio_direction_input(struct s5p_gpio_bank *bank, int gpio)
63 {
64 s5p_gpio_cfg_pin(bank, gpio, GPIO_INPUT);
65 }
66
67 void s5p_gpio_set_value(struct s5p_gpio_bank *bank, int gpio, int en)
68 {
69 unsigned int value;
70
71 value = readl(&bank->dat);
72 value &= ~DAT_MASK(gpio);
73 if (en)
74 value |= DAT_SET(gpio);
75 writel(value, &bank->dat);
76 }
77
78 unsigned int s5p_gpio_get_value(struct s5p_gpio_bank *bank, int gpio)
79 {
80 unsigned int value;
81
82 value = readl(&bank->dat);
83 return !!(value & DAT_MASK(gpio));
84 }
85
86 void s5p_gpio_set_pull(struct s5p_gpio_bank *bank, int gpio, int mode)
87 {
88 unsigned int value;
89
90 value = readl(&bank->pull);
91 value &= ~PULL_MASK(gpio);
92
93 switch (mode) {
94 case GPIO_PULL_DOWN:
95 case GPIO_PULL_UP:
96 value |= PULL_MODE(gpio, mode);
97 break;
98 default:
99 break;
100 }
101
102 writel(value, &bank->pull);
103 }
104
105 void s5p_gpio_set_drv(struct s5p_gpio_bank *bank, int gpio, int mode)
106 {
107 unsigned int value;
108
109 value = readl(&bank->drv);
110 value &= ~DRV_MASK(gpio);
111
112 switch (mode) {
113 case GPIO_DRV_1X:
114 case GPIO_DRV_2X:
115 case GPIO_DRV_3X:
116 case GPIO_DRV_4X:
117 value |= DRV_SET(gpio, mode);
118 break;
119 default:
120 return;
121 }
122
123 writel(value, &bank->drv);
124 }
125
126 void s5p_gpio_set_rate(struct s5p_gpio_bank *bank, int gpio, int mode)
127 {
128 unsigned int value;
129
130 value = readl(&bank->drv);
131 value &= ~RATE_MASK(gpio);
132
133 switch (mode) {
134 case GPIO_DRV_FAST:
135 case GPIO_DRV_SLOW:
136 value |= RATE_SET(gpio);
137 break;
138 default:
139 return;
140 }
141
142 writel(value, &bank->drv);
143 }
144
145 struct s5p_gpio_bank *s5p_gpio_get_bank(unsigned gpio)
146 {
147 int bank = gpio / GPIO_PER_BANK;
148 bank *= sizeof(struct s5p_gpio_bank);
149
150 return (struct s5p_gpio_bank *) (s5p_gpio_base(gpio) + bank);
151 }
152
153 int s5p_gpio_get_pin(unsigned gpio)
154 {
155 return gpio % GPIO_PER_BANK;
156 }
157
158 /* Common GPIO API */
159
160 int gpio_request(unsigned gpio, const char *label)
161 {
162 return 0;
163 }
164
165 int gpio_free(unsigned gpio)
166 {
167 return 0;
168 }
169
170 int gpio_direction_input(unsigned gpio)
171 {
172 s5p_gpio_direction_input(s5p_gpio_get_bank(gpio),
173 s5p_gpio_get_pin(gpio));
174 return 0;
175 }
176
177 int gpio_direction_output(unsigned gpio, int value)
178 {
179 s5p_gpio_direction_output(s5p_gpio_get_bank(gpio),
180 s5p_gpio_get_pin(gpio), value);
181 return 0;
182 }
183
184 int gpio_get_value(unsigned gpio)
185 {
186 return (int) s5p_gpio_get_value(s5p_gpio_get_bank(gpio),
187 s5p_gpio_get_pin(gpio));
188 }
189
190 int gpio_set_value(unsigned gpio, int value)
191 {
192 s5p_gpio_set_value(s5p_gpio_get_bank(gpio),
193 s5p_gpio_get_pin(gpio), value);
194
195 return 0;
196 }