1 /*
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 <boot/boot.h>
30 #include <msm7k/gpio.h>
31
32 /* gross */
33
34 typedef struct gpioregs gpioregs;
35
36 struct gpioregs
37 {
38 unsigned out;
39 unsigned in;
40 unsigned int_status;
41 unsigned int_clear;
42 unsigned int_en;
43 unsigned int_edge;
44 unsigned int_pos;
45 unsigned oe;
46 };
47
48 static gpioregs GPIO_REGS[] = {
49 {
50 .out = GPIO_OUT_0,
51 .in = GPIO_IN_0,
52 .int_status = GPIO_INT_STATUS_0,
53 .int_clear = GPIO_INT_CLEAR_0,
54 .int_en = GPIO_INT_EN_0,
55 .int_edge = GPIO_INT_EDGE_0,
56 .int_pos = GPIO_INT_POS_0,
57 .oe = GPIO_OE_0,
58 },
59 {
60 .out = GPIO_OUT_1,
61 .in = GPIO_IN_1,
62 .int_status = GPIO_INT_STATUS_1,
63 .int_clear = GPIO_INT_CLEAR_1,
64 .int_en = GPIO_INT_EN_1,
65 .int_edge = GPIO_INT_EDGE_1,
66 .int_pos = GPIO_INT_POS_1,
67 .oe = GPIO_OE_1,
68 },
69 {
70 .out = GPIO_OUT_2,
71 .in = GPIO_IN_2,
72 .int_status = GPIO_INT_STATUS_2,
73 .int_clear = GPIO_INT_CLEAR_2,
74 .int_en = GPIO_INT_EN_2,
75 .int_edge = GPIO_INT_EDGE_2,
76 .int_pos = GPIO_INT_POS_2,
77 .oe = GPIO_OE_2,
78 },
79 {
80 .out = GPIO_OUT_3,
81 .in = GPIO_IN_3,
82 .int_status = GPIO_INT_STATUS_3,
83 .int_clear = GPIO_INT_CLEAR_3,
84 .int_en = GPIO_INT_EN_3,
85 .int_edge = GPIO_INT_EDGE_3,
86 .int_pos = GPIO_INT_POS_3,
87 .oe = GPIO_OE_3,
88 },
89 {
90 .out = GPIO_OUT_4,
91 .in = GPIO_IN_4,
92 .int_status = GPIO_INT_STATUS_4,
93 .int_clear = GPIO_INT_CLEAR_4,
94 .int_en = GPIO_INT_EN_4,
95 .int_edge = GPIO_INT_EDGE_4,
96 .int_pos = GPIO_INT_POS_4,
97 .oe = GPIO_OE_4,
98 },
99 };
100
find_gpio(unsigned n,unsigned * bit)101 static gpioregs *find_gpio(unsigned n, unsigned *bit)
102 {
103 if(n > 106) return 0;
104 if(n > 94) {
105 *bit = 1 << (n - 95);
106 return GPIO_REGS + 4;
107 }
108 if(n > 67) {
109 *bit = 1 << (n - 68);
110 return GPIO_REGS + 3;
111 }
112 if(n > 42) {
113 *bit = 1 << (n - 43);
114 return GPIO_REGS + 2;
115 }
116 if(n > 15) {
117 *bit = 1 << (n - 16);
118 return GPIO_REGS + 1;
119 }
120 *bit = 1 << n;
121 return GPIO_REGS + 0;
122 }
123
gpio_output_enable(unsigned n,unsigned out)124 void gpio_output_enable(unsigned n, unsigned out)
125 {
126 gpioregs *r;
127 unsigned b;
128 unsigned v;
129
130 if((r = find_gpio(n, &b)) == 0) return;
131
132 v = readl(r->oe);
133 if(out) {
134 writel(v | b, r->oe);
135 } else {
136 writel(v & (~b), r->oe);
137 }
138 }
139
gpio_write(unsigned n,unsigned on)140 void gpio_write(unsigned n, unsigned on)
141 {
142 gpioregs *r;
143 unsigned b;
144 unsigned v;
145
146 if((r = find_gpio(n, &b)) == 0) return;
147
148 v = readl(r->out);
149 if(on) {
150 writel(v | b, r->out);
151 } else {
152 writel(v & (~b), r->out);
153 }
154 }
155
gpio_read(unsigned n)156 int gpio_read(unsigned n)
157 {
158 gpioregs *r;
159 unsigned b;
160
161 if((r = find_gpio(n, &b)) == 0) return 0;
162
163 return (readl(r->in) & b) ? 1 : 0;
164 }
165
gpio_dir(int nr,int out)166 void gpio_dir(int nr, int out)
167 {
168 gpio_output_enable(nr, out);
169 }
170
gpio_set(int nr,int set)171 void gpio_set(int nr, int set)
172 {
173 gpio_write(nr, set);
174 }
175
gpio_get(int nr)176 int gpio_get(int nr)
177 {
178 return gpio_read(nr);
179 }
180
181
182