blob: aaf8bb18f1fde49cc19805055ecd33e2f4d7b265 [file] [log] [blame]
Ajay Dudani232ce812009-12-02 00:14:11 -08001/*
2 * Copyright (c) 2008, Google Inc.
3 * All rights reserved.
4 *
Duy Truongf3ac7b32013-02-13 01:07:28 -08005 * Copyright (c) 2009-2010, The Linux Foundation. All rights reserved.
Shashank Mittal37040832010-08-24 15:57:57 -07006 *
Ajay Dudani232ce812009-12-02 00:14:11 -08007 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * * Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * * Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in
14 * the documentation and/or other materials provided with the
15 * distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
20 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
21 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
22 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
23 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
24 * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
25 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
27 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28 * SUCH DAMAGE.
29 */
30
31#include <debug.h>
32#include <reg.h>
33#include <platform/iomap.h>
34#include <dev/gpio.h>
35
36#include "gpio_hw.h"
37
38typedef struct gpioregs gpioregs;
39
Ajay Dudanib01e5062011-12-03 23:23:42 -080040struct gpioregs {
Ajay Dudani232ce812009-12-02 00:14:11 -080041 unsigned out;
42 unsigned in;
43 unsigned int_status;
44 unsigned int_clear;
45 unsigned int_en;
46 unsigned int_edge;
47 unsigned int_pos;
48 unsigned oe;
49};
50
51static gpioregs GPIO_REGS[] = {
52 {
Ajay Dudanib01e5062011-12-03 23:23:42 -080053 .out = GPIO_OUT_0,
54 .in = GPIO_IN_0,
55 .int_status = GPIO_INT_STATUS_0,
56 .int_clear = GPIO_INT_CLEAR_0,
57 .int_en = GPIO_INT_EN_0,
58 .int_edge = GPIO_INT_EDGE_0,
59 .int_pos = GPIO_INT_POS_0,
60 .oe = GPIO_OE_0,
61 },
Ajay Dudani232ce812009-12-02 00:14:11 -080062 {
Ajay Dudanib01e5062011-12-03 23:23:42 -080063 .out = GPIO_OUT_1,
64 .in = GPIO_IN_1,
65 .int_status = GPIO_INT_STATUS_1,
66 .int_clear = GPIO_INT_CLEAR_1,
67 .int_en = GPIO_INT_EN_1,
68 .int_edge = GPIO_INT_EDGE_1,
69 .int_pos = GPIO_INT_POS_1,
70 .oe = GPIO_OE_1,
71 },
Ajay Dudani232ce812009-12-02 00:14:11 -080072 {
Ajay Dudanib01e5062011-12-03 23:23:42 -080073 .out = GPIO_OUT_2,
74 .in = GPIO_IN_2,
75 .int_status = GPIO_INT_STATUS_2,
76 .int_clear = GPIO_INT_CLEAR_2,
77 .int_en = GPIO_INT_EN_2,
78 .int_edge = GPIO_INT_EDGE_2,
79 .int_pos = GPIO_INT_POS_2,
80 .oe = GPIO_OE_2,
81 },
Ajay Dudani232ce812009-12-02 00:14:11 -080082 {
Ajay Dudanib01e5062011-12-03 23:23:42 -080083 .out = GPIO_OUT_3,
84 .in = GPIO_IN_3,
85 .int_status = GPIO_INT_STATUS_3,
86 .int_clear = GPIO_INT_CLEAR_3,
87 .int_en = GPIO_INT_EN_3,
88 .int_edge = GPIO_INT_EDGE_3,
89 .int_pos = GPIO_INT_POS_3,
90 .oe = GPIO_OE_3,
91 },
Ajay Dudani232ce812009-12-02 00:14:11 -080092 {
Ajay Dudanib01e5062011-12-03 23:23:42 -080093 .out = GPIO_OUT_4,
94 .in = GPIO_IN_4,
95 .int_status = GPIO_INT_STATUS_4,
96 .int_clear = GPIO_INT_CLEAR_4,
97 .int_en = GPIO_INT_EN_4,
98 .int_edge = GPIO_INT_EDGE_4,
99 .int_pos = GPIO_INT_POS_4,
100 .oe = GPIO_OE_4,
101 },
Ajay Dudani232ce812009-12-02 00:14:11 -0800102 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800103 .out = GPIO_OUT_5,
104 .in = GPIO_IN_5,
105 .int_status = GPIO_INT_STATUS_5,
106 .int_clear = GPIO_INT_CLEAR_5,
107 .int_en = GPIO_INT_EN_5,
108 .int_edge = GPIO_INT_EDGE_5,
109 .int_pos = GPIO_INT_POS_5,
110 .oe = GPIO_OE_5,
111 },
Ajay Dudani232ce812009-12-02 00:14:11 -0800112 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800113 .out = GPIO_OUT_6,
114 .in = GPIO_IN_6,
115 .int_status = GPIO_INT_STATUS_6,
116 .int_clear = GPIO_INT_CLEAR_6,
117 .int_en = GPIO_INT_EN_6,
118 .int_edge = GPIO_INT_EDGE_6,
119 .int_pos = GPIO_INT_POS_6,
120 .oe = GPIO_OE_6,
121 },
Ajay Dudani232ce812009-12-02 00:14:11 -0800122 {
Ajay Dudanib01e5062011-12-03 23:23:42 -0800123 .out = GPIO_OUT_7,
124 .in = GPIO_IN_7,
125 .int_status = GPIO_INT_STATUS_7,
126 .int_clear = GPIO_INT_CLEAR_7,
127 .int_en = GPIO_INT_EN_7,
128 .int_edge = GPIO_INT_EDGE_7,
129 .int_pos = GPIO_INT_POS_7,
130 .oe = GPIO_OE_7,
131 },
Ajay Dudani232ce812009-12-02 00:14:11 -0800132};
133
134static gpioregs *find_gpio(unsigned n, unsigned *bit)
135{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800136 if (n > 150) {
Shashank Mittal37040832010-08-24 15:57:57 -0700137 *bit = 1 << (n - 151);
Ajay Dudani232ce812009-12-02 00:14:11 -0800138 return GPIO_REGS + 7;
139 }
Ajay Dudanib01e5062011-12-03 23:23:42 -0800140 if (n > 133) {
Shashank Mittal37040832010-08-24 15:57:57 -0700141 *bit = 1 << (n - 134);
Ajay Dudani232ce812009-12-02 00:14:11 -0800142 return GPIO_REGS + 6;
143 }
Ajay Dudanib01e5062011-12-03 23:23:42 -0800144 if (n > 106) {
Shashank Mittal37040832010-08-24 15:57:57 -0700145 *bit = 1 << (n - 107);
Ajay Dudani232ce812009-12-02 00:14:11 -0800146 return GPIO_REGS + 5;
147 }
Ajay Dudanib01e5062011-12-03 23:23:42 -0800148 if (n > 94) {
Ajay Dudani232ce812009-12-02 00:14:11 -0800149 *bit = 1 << (n - 95);
150 return GPIO_REGS + 4;
151 }
Ajay Dudanib01e5062011-12-03 23:23:42 -0800152 if (n > 67) {
Ajay Dudani232ce812009-12-02 00:14:11 -0800153 *bit = 1 << (n - 68);
154 return GPIO_REGS + 3;
155 }
Ajay Dudanib01e5062011-12-03 23:23:42 -0800156 if (n > 43) {
Shashank Mittal37040832010-08-24 15:57:57 -0700157 *bit = 1 << (n - 44);
Ajay Dudani232ce812009-12-02 00:14:11 -0800158 return GPIO_REGS + 2;
159 }
Ajay Dudanib01e5062011-12-03 23:23:42 -0800160 if (n > 15) {
Ajay Dudani232ce812009-12-02 00:14:11 -0800161 *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;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800191
192 if ((r = find_gpio(n, &b)) == 0)
193 return;
Ajay Dudani232ce812009-12-02 00:14:11 -0800194
195 v = readl(r->out);
Ajay Dudanib01e5062011-12-03 23:23:42 -0800196 if (on) {
Ajay Dudani232ce812009-12-02 00:14:11 -0800197 writel(v | b, r->out);
198 } else {
199 writel(v & (~b), r->out);
200 }
201}
202
203int gpio_get(unsigned n)
204{
205 gpioregs *r;
206 unsigned b;
207
Ajay Dudanib01e5062011-12-03 23:23:42 -0800208 if ((r = find_gpio(n, &b)) == 0)
209 return 0;
Ajay Dudani232ce812009-12-02 00:14:11 -0800210
211 return (readl(r->in) & b) ? 1 : 0;
212}
213
Chandan Uddaraju14e57eb2010-06-28 12:11:06 -0700214void platform_config_interleaved_mode_gpios(void)
215{
Ajay Dudanib01e5062011-12-03 23:23:42 -0800216 /* configure EB2_CS1 through GPIO86 */
217 writel(GPIO_ALT_FUNC_PAGE_REG, 0x56);
218 writel(GPIO_ALT_FUNC_CFG_REG, 0x04);
Chandan Uddaraju14e57eb2010-06-28 12:11:06 -0700219 /* configure the EBI2_BUSY1_N through GPIO115 */
Ajay Dudanib01e5062011-12-03 23:23:42 -0800220 writel(GPIO_ALT_FUNC_PAGE_REG, 0x73);
221 writel(GPIO_ALT_FUNC_CFG_REG, 0x08);
Chandan Uddaraju14e57eb2010-06-28 12:11:06 -0700222}
Shashank Mittal37040832010-08-24 15:57:57 -0700223
224/* Enables all gpios passed in table*/
225int platform_gpios_enable(const struct msm_gpio *table, int size)
226{
227 int rc;
228 int i;
229 const struct msm_gpio *g;
230 for (i = 0; i < size; i++) {
231 g = table + i;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800232 /* Enable gpio */
Shashank Mittal37040832010-08-24 15:57:57 -0700233 rc = gpio_tlmm_config(g->gpio_cfg, GPIO_ENABLE);
234 if (rc) {
235 goto err;
236 }
237 }
238 return 0;
Ajay Dudanib01e5062011-12-03 23:23:42 -0800239 err:
Shashank Mittal37040832010-08-24 15:57:57 -0700240 return rc;
241}