1 /*
2  * drivers/pcmcia/sa1100_adsbitsy.c
3  *
4  * PCMCIA implementation routines for ADS Bitsy
5  *
6  * 9/18/01 Woojung
7  *         Fixed wrong PCMCIA voltage setting
8  *
9  * 7/5/01 Woojung Huh <whuh@applieddata.net>
10  *
11  */
12 #include <linux/kernel.h>
13 #include <linux/sched.h>
14 
15 #include <asm/hardware.h>
16 
17 #include "sa1100_generic.h"
18 #include "sa1111_generic.h"
19 
adsbitsy_pcmcia_init(struct pcmcia_init * init)20 static int adsbitsy_pcmcia_init(struct pcmcia_init *init)
21 {
22   /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
23   PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
24 
25   /* Disable Power 3.3V/5V for PCMCIA/CF */
26   PA_DWR |= GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3;
27 
28   /* Why? */
29   MECR = 0x09430943;
30 
31   return sa1111_pcmcia_init(init);
32 }
33 
34 static int
adsbitsy_pcmcia_configure_socket(const struct pcmcia_configure * conf)35 adsbitsy_pcmcia_configure_socket(const struct pcmcia_configure *conf)
36 {
37   unsigned int pa_dwr_mask, pa_dwr_set;
38   int ret;
39 
40   switch (conf->sock) {
41   case 0:
42     pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
43 
44     switch (conf->vcc) {
45     default:
46     case 0:	pa_dwr_set = GPIO_GPIO0 | GPIO_GPIO1;	break;
47     case 33:	pa_dwr_set = GPIO_GPIO1;		break;
48     case 50:	pa_dwr_set = GPIO_GPIO0;		break;
49     }
50     break;
51 
52   case 1:
53     pa_dwr_mask = GPIO_GPIO2 | GPIO_GPIO3;
54 
55     switch (conf->vcc) {
56     default:
57     case 0:	pa_dwr_set = 0;				break;
58     case 33:	pa_dwr_set = GPIO_GPIO2;		break;
59     case 50:	pa_dwr_set = GPIO_GPIO3;		break;
60     }
61 
62   default:
63     return -1;
64   }
65 
66   if (conf->vpp != conf->vcc && conf->vpp != 0) {
67     printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n",
68 		__FUNCTION__, conf->vpp);
69     return -1;
70   }
71 
72   ret = sa1111_pcmcia_configure_socket(conf);
73   if (ret == 0) {
74     unsigned long flags;
75 
76     local_irq_save(flags);
77     PA_DWR = (PA_DWR & ~pa_dwr_mask) | pa_dwr_set;
78     local_irq_restore(flags);
79   }
80 
81   return ret;
82 }
83 
84 struct pcmcia_low_level adsbitsy_pcmcia_ops = {
85   init:			adsbitsy_pcmcia_init,
86   shutdown:		sa1111_pcmcia_shutdown,
87   socket_state:		sa1111_pcmcia_socket_state,
88   get_irq_info:		sa1111_pcmcia_get_irq_info,
89   configure_socket:	adsbitsy_pcmcia_configure_socket,
90 
91   socket_init:		sa1111_pcmcia_socket_init,
92   socket_suspend:	sa1111_pcmcia_socket_suspend,
93 };
94 
95