3 * AMD Alchemy Pb1550 boards specific pcmcia routines.
5 * Copyright 2004 Embedded Edge LLC
7 * Based on au1000_pb1550.c:
8 * Copyright 2002 MontaVista Software Inc.
9 * Author: MontaVista Software, Inc.
10 * ppopov@mvista.com or source@mvista.com
12 * ########################################################################
14 * This program is free software; you can distribute it and/or modify it
15 * under the terms of the GNU General Public License (Version 2) as
16 * published by the Free Software Foundation.
18 * This program is distributed in the hope it will be useful, but WITHOUT
19 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
20 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
23 * You should have received a copy of the GNU General Public License along
24 * with this program; if not, write to the Free Software Foundation, Inc.,
25 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
27 * ########################################################################
31 #include <linux/module.h>
32 #include <linux/init.h>
33 #include <linux/config.h>
34 #include <linux/delay.h>
35 #include <linux/ioport.h>
36 #include <linux/kernel.h>
37 #include <linux/tqueue.h>
38 #include <linux/timer.h>
40 #include <linux/proc_fs.h>
41 #include <linux/version.h>
42 #include <linux/types.h>
44 #include <pcmcia/version.h>
45 #include <pcmcia/cs_types.h>
46 #include <pcmcia/cs.h>
47 #include <pcmcia/ss.h>
48 #include <pcmcia/bulkmem.h>
49 #include <pcmcia/cistpl.h>
50 #include <pcmcia/bus_ops.h>
51 #include "cs_internal.h"
55 #include <asm/system.h>
57 #include <asm/au1000.h>
58 #include <asm/au1000_pcmcia.h>
60 #include <asm/pb1550.h>
63 static int pb1550_pcmcia_init(struct pcmcia_init *init)
65 bcsr->pcmcia = 0; /* turn off power */
67 return PCMCIA_NUM_SOCKS;
70 static int pb1550_pcmcia_shutdown(void)
72 bcsr->pcmcia = 0; /* turn off power */
78 pb1550_pcmcia_socket_state(unsigned sock, struct pcmcia_state *state)
83 if(sock > PCMCIA_MAX_SOCK) return -1;
91 vs = bcsr->status & BCSR_STATUS_PCMCIA0VS;
92 inserted = !(bcsr->status & (1<<4));
95 vs = (bcsr->status & BCSR_STATUS_PCMCIA1VS)>>2;
96 inserted = !(bcsr->status & (1<<5));
99 DEBUG(KERN_DEBUG "pb1550 socket %d: inserted %d, vs %d\n",
100 sock, inserted, vs, bcsr->status);
111 /* return without setting 'detect' */
112 printk(KERN_ERR "pb1550 bad VS (%d)\n", vs);
119 /* if the card was previously inserted and then ejected,
120 * we should turn off power to it
122 if ((sock == 0) && (bcsr->pcmcia & BCSR_PCMCIA_PC0RST)) {
123 bcsr->pcmcia &= ~(BCSR_PCMCIA_PC0RST |
124 BCSR_PCMCIA_PC0DRVEN |
128 else if ((sock == 1) && (bcsr->pcmcia & BCSR_PCMCIA_PC1RST)) {
129 bcsr->pcmcia &= ~(BCSR_PCMCIA_PC1RST |
130 BCSR_PCMCIA_PC1DRVEN |
143 static int pb1550_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
145 if(info->sock > PCMCIA_MAX_SOCK) return -1;
147 if(info->sock == 0) {
148 info->irq = AU1000_GPIO_0;
151 info->irq = AU1000_GPIO_1;
158 pb1550_pcmcia_configure_socket(const struct pcmcia_configure *configure)
161 int sock = configure->sock;
163 if(sock > PCMCIA_MAX_SOCK) return -1;
165 DEBUG(KERN_DEBUG "socket %d Vcc %dV Vpp %dV, reset %d\n",
166 sock, configure->vcc, configure->vpp, configure->reset);
168 /* pcmcia reg was set to zero at init time. Be careful when
169 * initializing a socket not to wipe out the settings of the
173 pwr &= ~(0xf << sock*8); /* clear voltage settings */
175 switch(configure->vcc){
177 pwr |= SET_VCC_VPP(0,0,sock);
179 case 50: /* Vcc 5V */
180 switch(configure->vpp) {
182 pwr |= SET_VCC_VPP(2,0,sock);
185 pwr |= SET_VCC_VPP(2,1,sock);
188 pwr |= SET_VCC_VPP(2,2,sock);
192 pwr |= SET_VCC_VPP(0,0,sock);
193 printk("%s: bad Vcc/Vpp (%d:%d)\n",
200 case 33: /* Vcc 3.3V */
201 switch(configure->vpp) {
203 pwr |= SET_VCC_VPP(1,0,sock);
206 pwr |= SET_VCC_VPP(1,2,sock);
209 pwr |= SET_VCC_VPP(1,1,sock);
213 pwr |= SET_VCC_VPP(0,0,sock);
214 printk("%s: bad Vcc/Vpp (%d:%d)\n",
221 default: /* what's this ? */
222 pwr |= SET_VCC_VPP(0,0,sock);
223 printk(KERN_ERR "%s: bad Vcc %d\n",
224 __FUNCTION__, configure->vcc);
232 if (!configure->reset) {
233 pwr |= BCSR_PCMCIA_PC0DRVEN;
236 pwr |= BCSR_PCMCIA_PC0RST;
241 pwr &= ~(BCSR_PCMCIA_PC0RST | BCSR_PCMCIA_PC0DRVEN);
247 if (!configure->reset) {
248 pwr |= BCSR_PCMCIA_PC1DRVEN;
251 pwr |= BCSR_PCMCIA_PC1RST;
256 pwr &= ~(BCSR_PCMCIA_PC1RST | BCSR_PCMCIA_PC1DRVEN);
264 struct pcmcia_low_level au1x00_pcmcia_ops = {
266 pb1550_pcmcia_shutdown,
267 pb1550_pcmcia_socket_state,
268 pb1550_pcmcia_get_irq_info,
269 pb1550_pcmcia_configure_socket