1 /*
2 * FILE NAME au1000_gpio.c
3 *
4 * BRIEF MODULE DESCRIPTION
5 * Driver for Alchemy Au1000 GPIO.
6 *
7 * Author: MontaVista Software, Inc. <source@mvista.com>
8 * Steve Longerbeam <stevel@mvista.com>
9 *
10 * Copyright 2001 MontaVista Software Inc.
11 *
12 * This program is free software; you can redistribute it and/or modify it
13 * under the terms of the GNU General Public License as published by the
14 * Free Software Foundation; either version 2 of the License, or (at your
15 * option) any later version.
16 *
17 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED
18 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN
20 * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
23 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
24 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 *
28 * You should have received a copy of the GNU General Public License along
29 * with this program; if not, write to the Free Software Foundation, Inc.,
30 * 675 Mass Ave, Cambridge, MA 02139, USA.
31 */
32
33 #include <linux/module.h>
34 #include <linux/config.h>
35 #include <linux/types.h>
36 #include <linux/kernel.h>
37 #include <linux/miscdevice.h>
38 #include <linux/init.h>
39 #include <asm/uaccess.h>
40 #include <asm/io.h>
41 #include <asm/au1000.h>
42 #include <asm/au1000_gpio.h>
43
44 #define VERSION "0.01"
45
46 static const struct {
47 u32 active_hi;
48 u32 avail_mask;
49 } pinfunc_to_avail[15] = {
50 {1, 0x7<<16}, // 0 = SSI0 / GPIO[18:16]
51 {-1, 0}, // 1 = AC97 / SSI1
52 {1, 1<<19}, // 2 = IRDA / GPIO19
53 {1, 1<<20}, // 3 = UART0 / GPIO20
54 {1, 0x1f<<24}, // 4 = NIC2 / GPIO[28:24]
55 {1, 0x7<<29}, // 5 = I2S / GPIO[31:29]
56 {0, 1<<8}, // 6 = I2SDI / GPIO8
57 {0, 0x3f<<9}, // 7 = UART3 / GPIO[14:9]
58 {0, 1<<15}, // 8 = IRFIRSEL / GPIO15
59 {0, 1<<2}, // 9 = EXTCLK0 or OSC / GPIO2
60 {0, 1<<3}, // 10 = EXTCLK1 / GPIO3
61 {0, 1<<6}, // 11 = SMROMCKE / GPIO6
62 {1, 1<<21}, // 12 = UART1 / GPIO21
63 {1, 1<<22}, // 13 = UART2 / GPIO22
64 {1, 1<<23} // 14 = UART3 / GPIO23
65 };
66
67
get_au1000_avail_gpio_mask(void)68 u32 get_au1000_avail_gpio_mask(void)
69 {
70 int i;
71 u32 pinfunc = inl(SYS_PINFUNC);
72 u32 avail_mask = 0; // start with no gpio available
73
74 // first, check for GPIO's reprogrammed as peripheral pins
75 for (i=0; i<15; i++) {
76 if (pinfunc_to_avail[i].active_hi < 0)
77 continue;
78 if (!(pinfunc_to_avail[i].active_hi ^
79 ((pinfunc & (1<<i)) ? 1:0)))
80 avail_mask |= pinfunc_to_avail[i].avail_mask;
81 }
82
83 // check for GPIO's used as interrupt sources
84 avail_mask &= ~(inl(IC1_MASKRD) &
85 (inl(IC1_CFG0RD) | inl(IC1_CFG1RD)));
86
87 #ifdef CONFIG_USB_OHCI
88 avail_mask &= ~((1<<4) | (1<<11));
89 #ifndef CONFIG_AU1X00_USB_DEVICE
90 avail_mask &= ~((1<<5) | (1<<13));
91 #endif
92 #endif
93
94 return avail_mask;
95 }
96
97
98 /*
99 * Tristate the requested GPIO pins specified in data.
100 * Only available GPIOs will be tristated.
101 */
au1000gpio_tristate(u32 data)102 int au1000gpio_tristate(u32 data)
103 {
104 data &= get_au1000_avail_gpio_mask();
105
106 if (data)
107 outl(data, SYS_TRIOUTCLR);
108
109 return 0;
110 }
111
112
113 /*
114 * Return the pin state. Pins configured as outputs will return
115 * the output state, and pins configured as inputs (tri-stated)
116 * will return input pin state.
117 */
au1000gpio_in(u32 * data)118 int au1000gpio_in(u32 *data)
119 {
120 *data = inl(SYS_PINSTATERD);
121 return 0;
122 }
123
124
125 /*
126 * Set/clear GPIO pins. Only available GPIOs will be affected.
127 */
au1000gpio_set(u32 data)128 int au1000gpio_set(u32 data)
129 {
130 data &= get_au1000_avail_gpio_mask();
131
132 if (data)
133 outl(data, SYS_OUTPUTSET);
134 return 0;
135 }
136
au1000gpio_clear(u32 data)137 int au1000gpio_clear(u32 data)
138 {
139 data &= get_au1000_avail_gpio_mask();
140
141 if (data)
142 outl(data, SYS_OUTPUTCLR);
143 return 0;
144 }
145
146 /*
147 * Output data to GPIO pins. Only available GPIOs will be affected.
148 */
au1000gpio_out(u32 data)149 int au1000gpio_out(u32 data)
150 {
151 au1000gpio_set(data);
152 au1000gpio_clear(~data);
153 return 0;
154 }
155
156
157 EXPORT_SYMBOL(get_au1000_avail_gpio_mask);
158 EXPORT_SYMBOL(au1000gpio_tristate);
159 EXPORT_SYMBOL(au1000gpio_in);
160 EXPORT_SYMBOL(au1000gpio_set);
161 EXPORT_SYMBOL(au1000gpio_clear);
162 EXPORT_SYMBOL(au1000gpio_out);
163
164
au1000gpio_open(struct inode * inode,struct file * file)165 static int au1000gpio_open(struct inode *inode, struct file *file)
166 {
167 MOD_INC_USE_COUNT;
168
169 return 0;
170 }
171
172
au1000gpio_release(struct inode * inode,struct file * file)173 static int au1000gpio_release(struct inode *inode, struct file *file)
174 {
175 MOD_DEC_USE_COUNT;
176
177 return 0;
178 }
179
180
au1000gpio_ioctl(struct inode * inode,struct file * file,unsigned int cmd,unsigned long arg)181 static int au1000gpio_ioctl(struct inode *inode, struct file *file,
182 unsigned int cmd, unsigned long arg)
183 {
184 int status;
185 u32 val;
186
187 switch(cmd) {
188 case AU1000GPIO_IN:
189
190 status = au1000gpio_in(&val);
191 if (status != 0)
192 return status;
193
194 return put_user(val, (u32 *)arg);
195
196 case AU1000GPIO_OUT:
197
198 if (get_user(val, (u32 *)arg))
199 return -EFAULT;
200
201 return au1000gpio_out(val);
202
203 case AU1000GPIO_SET:
204
205 if (get_user(val, (u32 *)arg))
206 return -EFAULT;
207
208 return au1000gpio_set(val);
209
210 case AU1000GPIO_CLEAR:
211
212 if (get_user(val, (u32 *)arg))
213 return -EFAULT;
214
215 return au1000gpio_clear(val);
216
217 case AU1000GPIO_TRISTATE:
218
219 if (get_user(val, (u32 *)arg))
220 return -EFAULT;
221
222 return au1000gpio_tristate(val);
223
224 case AU1000GPIO_AVAIL_MASK:
225
226 return put_user(get_au1000_avail_gpio_mask(),
227 (u32 *)arg);
228
229 default:
230 return -ENOIOCTLCMD;
231
232 }
233
234 return 0;
235 }
236
237
238 static struct file_operations au1000gpio_fops =
239 {
240 owner: THIS_MODULE,
241 ioctl: au1000gpio_ioctl,
242 open: au1000gpio_open,
243 release: au1000gpio_release,
244 };
245
246
247 static struct miscdevice au1000gpio_miscdev =
248 {
249 GPIO_MINOR,
250 "au1000_gpio",
251 &au1000gpio_fops
252 };
253
254
au1000gpio_init(void)255 int __init au1000gpio_init(void)
256 {
257 misc_register(&au1000gpio_miscdev);
258 printk("Au1000 gpio driver, version %s\n", VERSION);
259 return 0;
260 }
261
262
au1000gpio_exit(void)263 void __exit au1000gpio_exit(void)
264 {
265 misc_deregister(&au1000gpio_miscdev);
266 }
267
268
269 module_init(au1000gpio_init);
270 module_exit(au1000gpio_exit);
271