blob: 9487ca4357bf657db8cae562ab67025a883c4236 [file] [log] [blame]
Shashank Mittal246f8d02011-01-21 17:12:27 -08001/*
2 * Copyright (c) 2008, Google Inc.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
18 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
19 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
21 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
22 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
23 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
24 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
25 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
26 * SUCH DAMAGE.
27 */
28
29#include <debug.h>
30#include <reg.h>
31#include <platform/iomap.h>
32#include <dev/gpio.h>
33
34#define GPIO1_REG(off) (MSM_GPIO1_BASE + 0x800 + (off))
35#define GPIO2_REG(off) (MSM_GPIO2_BASE + 0xC00 + (off))
36
37/* output value */
Ajay Dudanib01e5062011-12-03 23:23:42 -080038#define GPIO_OUT_0 GPIO1_REG(0x00) /* gpio 15-0 */
39#define GPIO_OUT_1 GPIO2_REG(0x00) /* gpio 42-16 */
40#define GPIO_OUT_2 GPIO1_REG(0x04) /* gpio 67-43 */
41#define GPIO_OUT_3 GPIO1_REG(0x08) /* gpio 94-68 */
42#define GPIO_OUT_4 GPIO1_REG(0x0C) /* gpio 106-95 */
43#define GPIO_OUT_5 GPIO1_REG(0x50) /* gpio 132-107 */
Shashank Mittal246f8d02011-01-21 17:12:27 -080044
45/* same pin map as above, output enable */
46#define GPIO_OE_0 GPIO1_REG(0x10)
47#define GPIO_OE_1 GPIO2_REG(0x08)
48#define GPIO_OE_2 GPIO1_REG(0x14)
49#define GPIO_OE_3 GPIO1_REG(0x18)
50#define GPIO_OE_4 GPIO1_REG(0x1C)
Shashank Mittal39763072011-04-08 17:45:50 -070051#define GPIO_OE_5 GPIO1_REG(0x54)
Shashank Mittal246f8d02011-01-21 17:12:27 -080052
53/* same pin map as above, input read */
54#define GPIO_IN_0 GPIO1_REG(0x34)
55#define GPIO_IN_1 GPIO2_REG(0x20)
56#define GPIO_IN_2 GPIO1_REG(0x38)
57#define GPIO_IN_3 GPIO1_REG(0x3C)
58#define GPIO_IN_4 GPIO1_REG(0x40)
Shashank Mittal39763072011-04-08 17:45:50 -070059#define GPIO_IN_5 GPIO1_REG(0x44)
Shashank Mittal246f8d02011-01-21 17:12:27 -080060
61/* same pin map as above, 1=edge 0=level interrup */
62#define GPIO_INT_EDGE_0 GPIO1_REG(0x60)
63#define GPIO_INT_EDGE_1 GPIO2_REG(0x50)
64#define GPIO_INT_EDGE_2 GPIO1_REG(0x64)
65#define GPIO_INT_EDGE_3 GPIO1_REG(0x68)
66#define GPIO_INT_EDGE_4 GPIO1_REG(0x6C)
Shashank Mittal39763072011-04-08 17:45:50 -070067#define GPIO_INT_EDGE_5 GPIO1_REG(0xC0)
Shashank Mittal246f8d02011-01-21 17:12:27 -080068
69/* same pin map as above, 1=positive 0=negative */
70#define GPIO_INT_POS_0 GPIO1_REG(0x70)
71#define GPIO_INT_POS_1 GPIO2_REG(0x58)
72#define GPIO_INT_POS_2 GPIO1_REG(0x74)
73#define GPIO_INT_POS_3 GPIO1_REG(0x78)
74#define GPIO_INT_POS_4 GPIO1_REG(0x7C)
Shashank Mittal39763072011-04-08 17:45:50 -070075#define GPIO_INT_POS_5 GPIO1_REG(0xBC)
Shashank Mittal246f8d02011-01-21 17:12:27 -080076
77/* same pin map as above, interrupt enable */
78#define GPIO_INT_EN_0 GPIO1_REG(0x80)
79#define GPIO_INT_EN_1 GPIO2_REG(0x60)
80#define GPIO_INT_EN_2 GPIO1_REG(0x84)
81#define GPIO_INT_EN_3 GPIO1_REG(0x88)
82#define GPIO_INT_EN_4 GPIO1_REG(0x8C)
Shashank Mittal39763072011-04-08 17:45:50 -070083#define GPIO_INT_EN_5 GPIO1_REG(0xB8)
Shashank Mittal246f8d02011-01-21 17:12:27 -080084
85/* same pin map as above, write 1 to clear interrupt */
86#define GPIO_INT_CLEAR_0 GPIO1_REG(0x90)
87#define GPIO_INT_CLEAR_1 GPIO2_REG(0x68)
88#define GPIO_INT_CLEAR_2 GPIO1_REG(0x94)
89#define GPIO_INT_CLEAR_3 GPIO1_REG(0x98)
90#define GPIO_INT_CLEAR_4 GPIO1_REG(0x9C)
Shashank Mittal39763072011-04-08 17:45:50 -070091#define GPIO_INT_CLEAR_5 GPIO1_REG(0xB4)
Shashank Mittal246f8d02011-01-21 17:12:27 -080092
93/* same pin map as above, 1=interrupt pending */
94#define GPIO_INT_STATUS_0 GPIO1_REG(0xA0)
95#define GPIO_INT_STATUS_1 GPIO2_REG(0x70)
96#define GPIO_INT_STATUS_2 GPIO1_REG(0xA4)
97#define GPIO_INT_STATUS_3 GPIO1_REG(0xA8)
98#define GPIO_INT_STATUS_4 GPIO1_REG(0xAC)
Shashank Mittal39763072011-04-08 17:45:50 -070099#define GPIO_INT_STATUS_5 GPIO1_REG(0xB0)
Shashank Mittal246f8d02011-01-21 17:12:27 -0800100
101typedef struct gpioregs gpioregs;
102
Ajay Dudanib01e5062011-12-03 23:23:42 -0800103struct gpioregs {
Shashank Mittal246f8d02011-01-21 17:12:27 -0800104 unsigned out;
105 unsigned in;
106 unsigned int_status;
107 unsigned int_clear;
108 unsigned int_en;
109 unsigned int_edge;
110 unsigned int_pos;
111 unsigned oe;
112};
113
114static gpioregs GPIO_REGS[] = {
115 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800116 .out = GPIO_OUT_0,
117 .in = GPIO_IN_0,
118 .int_status = GPIO_INT_STATUS_0,
119 .int_clear = GPIO_INT_CLEAR_0,
120 .int_en = GPIO_INT_EN_0,
121 .int_edge = GPIO_INT_EDGE_0,
122 .int_pos = GPIO_INT_POS_0,
123 .oe = GPIO_OE_0,
124 },
Shashank Mittal246f8d02011-01-21 17:12:27 -0800125 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800126 .out = GPIO_OUT_1,
127 .in = GPIO_IN_1,
128 .int_status = GPIO_INT_STATUS_1,
129 .int_clear = GPIO_INT_CLEAR_1,
130 .int_en = GPIO_INT_EN_1,
131 .int_edge = GPIO_INT_EDGE_1,
132 .int_pos = GPIO_INT_POS_1,
133 .oe = GPIO_OE_1,
134 },
Shashank Mittal246f8d02011-01-21 17:12:27 -0800135 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800136 .out = GPIO_OUT_2,
137 .in = GPIO_IN_2,
138 .int_status = GPIO_INT_STATUS_2,
139 .int_clear = GPIO_INT_CLEAR_2,
140 .int_en = GPIO_INT_EN_2,
141 .int_edge = GPIO_INT_EDGE_2,
142 .int_pos = GPIO_INT_POS_2,
143 .oe = GPIO_OE_2,
144 },
Shashank Mittal246f8d02011-01-21 17:12:27 -0800145 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800146 .out = GPIO_OUT_3,
147 .in = GPIO_IN_3,
148 .int_status = GPIO_INT_STATUS_3,
149 .int_clear = GPIO_INT_CLEAR_3,
150 .int_en = GPIO_INT_EN_3,
151 .int_edge = GPIO_INT_EDGE_3,
152 .int_pos = GPIO_INT_POS_3,
153 .oe = GPIO_OE_3,
154 },
Shashank Mittal246f8d02011-01-21 17:12:27 -0800155 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800156 .out = GPIO_OUT_4,
157 .in = GPIO_IN_4,
158 .int_status = GPIO_INT_STATUS_4,
159 .int_clear = GPIO_INT_CLEAR_4,
160 .int_en = GPIO_INT_EN_4,
161 .int_edge = GPIO_INT_EDGE_4,
162 .int_pos = GPIO_INT_POS_4,
163 .oe = GPIO_OE_4,
164 },
Shashank Mittal39763072011-04-08 17:45:50 -0700165 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800166 .out = GPIO_OUT_5,
167 .in = GPIO_IN_5,
168 .int_status = GPIO_INT_STATUS_5,
169 .int_clear = GPIO_INT_CLEAR_5,
170 .int_en = GPIO_INT_EN_5,
171 .int_edge = GPIO_INT_EDGE_5,
172 .int_pos = GPIO_INT_POS_5,
173 .oe = GPIO_OE_5,
174 },
Shashank Mittal246f8d02011-01-21 17:12:27 -0800175};
176
177static gpioregs *find_gpio(unsigned n, unsigned *bit)
178{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800179 if (n > 132)
Shashank Mittal246f8d02011-01-21 17:12:27 -0800180 return 0;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800181 if (n > 106) {
Shashank Mittal39763072011-04-08 17:45:50 -0700182 *bit = 1 << (n - 107);
183 return GPIO_REGS + 5;
184 }
Ajay Dudanib01e5062011-12-03 23:23:42 -0800185 if (n > 94) {
Shashank Mittal246f8d02011-01-21 17:12:27 -0800186 *bit = 1 << (n - 95);
187 return GPIO_REGS + 4;
188 }
Ajay Dudanib01e5062011-12-03 23:23:42 -0800189 if (n > 67) {
Shashank Mittal246f8d02011-01-21 17:12:27 -0800190 *bit = 1 << (n - 68);
191 return GPIO_REGS + 3;
192 }
Ajay Dudanib01e5062011-12-03 23:23:42 -0800193 if (n > 42) {
Shashank Mittal246f8d02011-01-21 17:12:27 -0800194 *bit = 1 << (n - 43);
195 return GPIO_REGS + 2;
196 }
Ajay Dudanib01e5062011-12-03 23:23:42 -0800197 if (n > 15) {
Shashank Mittal246f8d02011-01-21 17:12:27 -0800198 *bit = 1 << (n - 16);
199 return GPIO_REGS + 1;
200 }
201 *bit = 1 << n;
202 return GPIO_REGS + 0;
203}
204
205int gpio_config(unsigned n, unsigned flags)
206{
207 gpioregs *r;
208 unsigned b;
209 unsigned v;
210
211 if ((r = find_gpio(n, &b)) == 0)
212 return -1;
213
214 v = readl(r->oe);
215 if (flags & GPIO_OUTPUT) {
216 writel(v | b, r->oe);
217 } else {
218 writel(v & (~b), r->oe);
219 }
220 return 0;
221}
222
223void gpio_set(unsigned n, unsigned on)
224{
225 gpioregs *r;
226 unsigned b;
227 unsigned v;
228
Ajay Dudanib01e5062011-12-03 23:23:42 -0800229 if ((r = find_gpio(n, &b)) == 0)
Shashank Mittal246f8d02011-01-21 17:12:27 -0800230 return;
231
232 v = readl(r->out);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800233 if (on) {
Shashank Mittal246f8d02011-01-21 17:12:27 -0800234 writel(v | b, r->out);
235 } else {
236 writel(v & (~b), r->out);
237 }
238}
239
240int gpio_get(unsigned n)
241{
242 gpioregs *r;
243 unsigned b;
244
Ajay Dudanib01e5062011-12-03 23:23:42 -0800245 if ((r = find_gpio(n, &b)) == 0)
246 return 0;
Shashank Mittal246f8d02011-01-21 17:12:27 -0800247
248 return (readl(r->in) & b) ? 1 : 0;
249}