blob: ba82a8c0316fe87609cf81ec667531c161544ea5 [file] [log] [blame]
Brian Swetlandd5b7ac12009-01-02 01:32:12 -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 */
38#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
44/* same pin map as above, output enable */
45#define GPIO_OE_0 GPIO1_REG(0x10)
46#define GPIO_OE_1 GPIO2_REG(0x08)
47#define GPIO_OE_2 GPIO1_REG(0x14)
48#define GPIO_OE_3 GPIO1_REG(0x18)
49#define GPIO_OE_4 GPIO1_REG(0x1C)
50
51/* same pin map as above, input read */
52#define GPIO_IN_0 GPIO1_REG(0x34)
53#define GPIO_IN_1 GPIO2_REG(0x20)
54#define GPIO_IN_2 GPIO1_REG(0x38)
55#define GPIO_IN_3 GPIO1_REG(0x3C)
56#define GPIO_IN_4 GPIO1_REG(0x40)
57
58/* same pin map as above, 1=edge 0=level interrup */
59#define GPIO_INT_EDGE_0 GPIO1_REG(0x60)
60#define GPIO_INT_EDGE_1 GPIO2_REG(0x50)
61#define GPIO_INT_EDGE_2 GPIO1_REG(0x64)
62#define GPIO_INT_EDGE_3 GPIO1_REG(0x68)
63#define GPIO_INT_EDGE_4 GPIO1_REG(0x6C)
64
65/* same pin map as above, 1=positive 0=negative */
66#define GPIO_INT_POS_0 GPIO1_REG(0x70)
67#define GPIO_INT_POS_1 GPIO2_REG(0x58)
68#define GPIO_INT_POS_2 GPIO1_REG(0x74)
69#define GPIO_INT_POS_3 GPIO1_REG(0x78)
70#define GPIO_INT_POS_4 GPIO1_REG(0x7C)
71
72/* same pin map as above, interrupt enable */
73#define GPIO_INT_EN_0 GPIO1_REG(0x80)
74#define GPIO_INT_EN_1 GPIO2_REG(0x60)
75#define GPIO_INT_EN_2 GPIO1_REG(0x84)
76#define GPIO_INT_EN_3 GPIO1_REG(0x88)
77#define GPIO_INT_EN_4 GPIO1_REG(0x8C)
78
79/* same pin map as above, write 1 to clear interrupt */
80#define GPIO_INT_CLEAR_0 GPIO1_REG(0x90)
81#define GPIO_INT_CLEAR_1 GPIO2_REG(0x68)
82#define GPIO_INT_CLEAR_2 GPIO1_REG(0x94)
83#define GPIO_INT_CLEAR_3 GPIO1_REG(0x98)
84#define GPIO_INT_CLEAR_4 GPIO1_REG(0x9C)
85
86/* same pin map as above, 1=interrupt pending */
87#define GPIO_INT_STATUS_0 GPIO1_REG(0xA0)
88#define GPIO_INT_STATUS_1 GPIO2_REG(0x70)
89#define GPIO_INT_STATUS_2 GPIO1_REG(0xA4)
90#define GPIO_INT_STATUS_3 GPIO1_REG(0xA8)
91#define GPIO_INT_STATUS_4 GPIO1_REG(0xAC)
92
93typedef struct gpioregs gpioregs;
94
95struct gpioregs
96{
97 unsigned out;
98 unsigned in;
99 unsigned int_status;
100 unsigned int_clear;
101 unsigned int_en;
102 unsigned int_edge;
103 unsigned int_pos;
104 unsigned oe;
105};
106
107static gpioregs GPIO_REGS[] = {
108 {
109 .out = GPIO_OUT_0,
110 .in = GPIO_IN_0,
111 .int_status = GPIO_INT_STATUS_0,
112 .int_clear = GPIO_INT_CLEAR_0,
113 .int_en = GPIO_INT_EN_0,
114 .int_edge = GPIO_INT_EDGE_0,
115 .int_pos = GPIO_INT_POS_0,
116 .oe = GPIO_OE_0,
117 },
118 {
119 .out = GPIO_OUT_1,
120 .in = GPIO_IN_1,
121 .int_status = GPIO_INT_STATUS_1,
122 .int_clear = GPIO_INT_CLEAR_1,
123 .int_en = GPIO_INT_EN_1,
124 .int_edge = GPIO_INT_EDGE_1,
125 .int_pos = GPIO_INT_POS_1,
126 .oe = GPIO_OE_1,
127 },
128 {
129 .out = GPIO_OUT_2,
130 .in = GPIO_IN_2,
131 .int_status = GPIO_INT_STATUS_2,
132 .int_clear = GPIO_INT_CLEAR_2,
133 .int_en = GPIO_INT_EN_2,
134 .int_edge = GPIO_INT_EDGE_2,
135 .int_pos = GPIO_INT_POS_2,
136 .oe = GPIO_OE_2,
137 },
138 {
139 .out = GPIO_OUT_3,
140 .in = GPIO_IN_3,
141 .int_status = GPIO_INT_STATUS_3,
142 .int_clear = GPIO_INT_CLEAR_3,
143 .int_en = GPIO_INT_EN_3,
144 .int_edge = GPIO_INT_EDGE_3,
145 .int_pos = GPIO_INT_POS_3,
146 .oe = GPIO_OE_3,
147 },
148 {
149 .out = GPIO_OUT_4,
150 .in = GPIO_IN_4,
151 .int_status = GPIO_INT_STATUS_4,
152 .int_clear = GPIO_INT_CLEAR_4,
153 .int_en = GPIO_INT_EN_4,
154 .int_edge = GPIO_INT_EDGE_4,
155 .int_pos = GPIO_INT_POS_4,
156 .oe = GPIO_OE_4,
157 },
158};
159
160static gpioregs *find_gpio(unsigned n, unsigned *bit)
161{
162 if(n > 106)
163 return 0;
164 if(n > 94) {
165 *bit = 1 << (n - 95);
166 return GPIO_REGS + 4;
167 }
168 if(n > 67) {
169 *bit = 1 << (n - 68);
170 return GPIO_REGS + 3;
171 }
172 if(n > 42) {
173 *bit = 1 << (n - 43);
174 return GPIO_REGS + 2;
175 }
176 if(n > 15) {
177 *bit = 1 << (n - 16);
178 return GPIO_REGS + 1;
179 }
180 *bit = 1 << n;
181 return GPIO_REGS + 0;
182}
183
184int gpio_config(unsigned n, unsigned flags)
185{
186 gpioregs *r;
187 unsigned b;
188 unsigned v;
189
190 if ((r = find_gpio(n, &b)) == 0)
191 return -1;
192
193 v = readl(r->oe);
194 if (flags & GPIO_OUTPUT) {
195 writel(v | b, r->oe);
196 } else {
197 writel(v & (~b), r->oe);
198 }
199}
200
201void gpio_set(unsigned n, unsigned on)
202{
203 gpioregs *r;
204 unsigned b;
205 unsigned v;
206
207 if((r = find_gpio(n, &b)) == 0)
208 return;
209
210 v = readl(r->out);
211 if(on) {
212 writel(v | b, r->out);
213 } else {
214 writel(v & (~b), r->out);
215 }
216}
217
218int gpio_get(unsigned n)
219{
220 gpioregs *r;
221 unsigned b;
222
223 if((r = find_gpio(n, &b)) == 0) return 0;
224
225 return (readl(r->in) & b) ? 1 : 0;
226}
227