blob: 0b1272b7eca2853f5f90ce7d64856a7e7e07f221 [file] [log] [blame]
Dima Zavin86aafc22009-01-20 19:25:49 -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#include "gpio_hw.h"
35
36typedef struct gpioregs gpioregs;
37
38struct gpioregs
39{
40 unsigned out;
41 unsigned in;
42 unsigned int_status;
43 unsigned int_clear;
44 unsigned int_en;
45 unsigned int_edge;
46 unsigned int_pos;
47 unsigned oe;
48};
49
50static gpioregs GPIO_REGS[] = {
51 {
52 .out = GPIO_OUT_0,
53 .in = GPIO_IN_0,
54 .int_status = GPIO_INT_STATUS_0,
55 .int_clear = GPIO_INT_CLEAR_0,
56 .int_en = GPIO_INT_EN_0,
57 .int_edge = GPIO_INT_EDGE_0,
58 .int_pos = GPIO_INT_POS_0,
59 .oe = GPIO_OE_0,
60 },
61 {
62 .out = GPIO_OUT_1,
63 .in = GPIO_IN_1,
64 .int_status = GPIO_INT_STATUS_1,
65 .int_clear = GPIO_INT_CLEAR_1,
66 .int_en = GPIO_INT_EN_1,
67 .int_edge = GPIO_INT_EDGE_1,
68 .int_pos = GPIO_INT_POS_1,
69 .oe = GPIO_OE_1,
70 },
71 {
72 .out = GPIO_OUT_2,
73 .in = GPIO_IN_2,
74 .int_status = GPIO_INT_STATUS_2,
75 .int_clear = GPIO_INT_CLEAR_2,
76 .int_en = GPIO_INT_EN_2,
77 .int_edge = GPIO_INT_EDGE_2,
78 .int_pos = GPIO_INT_POS_2,
79 .oe = GPIO_OE_2,
80 },
81 {
82 .out = GPIO_OUT_3,
83 .in = GPIO_IN_3,
84 .int_status = GPIO_INT_STATUS_3,
85 .int_clear = GPIO_INT_CLEAR_3,
86 .int_en = GPIO_INT_EN_3,
87 .int_edge = GPIO_INT_EDGE_3,
88 .int_pos = GPIO_INT_POS_3,
89 .oe = GPIO_OE_3,
90 },
91 {
92 .out = GPIO_OUT_4,
93 .in = GPIO_IN_4,
94 .int_status = GPIO_INT_STATUS_4,
95 .int_clear = GPIO_INT_CLEAR_4,
96 .int_en = GPIO_INT_EN_4,
97 .int_edge = GPIO_INT_EDGE_4,
98 .int_pos = GPIO_INT_POS_4,
99 .oe = GPIO_OE_4,
100 },
101 {
102 .out = GPIO_OUT_5,
103 .in = GPIO_IN_5,
104 .int_status = GPIO_INT_STATUS_5,
105 .int_clear = GPIO_INT_CLEAR_5,
106 .int_en = GPIO_INT_EN_5,
107 .int_edge = GPIO_INT_EDGE_5,
108 .int_pos = GPIO_INT_POS_5,
109 .oe = GPIO_OE_5,
110 },
111 {
112 .out = GPIO_OUT_6,
113 .in = GPIO_IN_6,
114 .int_status = GPIO_INT_STATUS_6,
115 .int_clear = GPIO_INT_CLEAR_6,
116 .int_en = GPIO_INT_EN_6,
117 .int_edge = GPIO_INT_EDGE_6,
118 .int_pos = GPIO_INT_POS_6,
119 .oe = GPIO_OE_6,
120 },
121 {
122 .out = GPIO_OUT_7,
123 .in = GPIO_IN_7,
124 .int_status = GPIO_INT_STATUS_7,
125 .int_clear = GPIO_INT_CLEAR_7,
126 .int_en = GPIO_INT_EN_7,
127 .int_edge = GPIO_INT_EDGE_7,
128 .int_pos = GPIO_INT_POS_7,
129 .oe = GPIO_OE_7,
130 },
131};
132
133static gpioregs *find_gpio(unsigned n, unsigned *bit)
134{
135 if(n > 164) return 0;
136 if(n > 152) {
137 *bit = 1 << (n - 153);
138 return GPIO_REGS + 7;
139 }
140 if(n > 121) {
141 *bit = 1 << (n - 122);
142 return GPIO_REGS + 6;
143 }
144 if(n > 103) {
145 *bit = 1 << (n - 104);
146 return GPIO_REGS + 5;
147 }
148 if(n > 94) {
149 *bit = 1 << (n - 95);
150 return GPIO_REGS + 4;
151 }
152 if(n > 67) {
153 *bit = 1 << (n - 68);
154 return GPIO_REGS + 3;
155 }
156 if(n > 42) {
157 *bit = 1 << (n - 43);
158 return GPIO_REGS + 2;
159 }
160 if(n > 15) {
161 *bit = 1 << (n - 16);
162 return GPIO_REGS + 1;
163 }
164 *bit = 1 << n;
165 return GPIO_REGS + 0;
166}
167
168int gpio_config(unsigned n, unsigned flags)
169{
170 gpioregs *r;
171 unsigned b;
172 unsigned v;
173
174 if ((r = find_gpio(n, &b)) == 0)
175 return -1;
176
177 v = readl(r->oe);
178 if (flags & GPIO_OUTPUT) {
179 writel(v | b, r->oe);
180 } else {
181 writel(v & (~b), r->oe);
182 }
183 return 0;
184}
185
186void gpio_set(unsigned n, unsigned on)
187{
188 gpioregs *r;
189 unsigned b;
190 unsigned v;
191
192 if((r = find_gpio(n, &b)) == 0) return;
193
194 v = readl(r->out);
195 if(on) {
196 writel(v | b, r->out);
197 } else {
198 writel(v & (~b), r->out);
199 }
200}
201
202int gpio_get(unsigned n)
203{
204 gpioregs *r;
205 unsigned b;
206
207 if((r = find_gpio(n, &b)) == 0) return 0;
208
209 return (readl(r->in) & b) ? 1 : 0;
210}
211
212