• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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