more debug output
[linux-2.4.git] / drivers / pcmcia / sa1100_xp860.c
1 /*
2  * drivers/pcmcia/sa1100_xp860.c
3  *
4  * XP860 PCMCIA specific routines
5  *
6  */
7 #include <linux/kernel.h>
8 #include <linux/delay.h>
9 #include <linux/sched.h>
10
11 #include <asm/hardware.h>
12 #include <asm/irq.h>
13 #include "sa1100_generic.h"
14
15 #define NCR_A0VPP       (1<<16)
16 #define NCR_A1VPP       (1<<17)
17
18 static int xp860_pcmcia_init(struct pcmcia_init *init)
19 {
20   /* Set GPIO_A<3:0> to be outputs for PCMCIA/CF power controller: */
21   PA_DDR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
22   
23   /* MAX1600 to standby mode: */
24   PA_DWR &= ~(GPIO_GPIO0 | GPIO_GPIO1 | GPIO_GPIO2 | GPIO_GPIO3);
25
26 #error Consider the following comment
27   /*
28    * 1- Please move GPDR initialisation  where it is interrupt or preemption
29    *    safe (like from xp860_map_io).
30    * 2- The GPCR line is bogus i.e. it will simply have absolutely no effect.
31    *    Please see its definition in the SA1110 manual.
32    * 3- Please do not use NCR_* values!
33    */
34   GPDR |= (NCR_A0VPP | NCR_A1VPP);
35   GPCR &= ~(NCR_A0VPP | NCR_A1VPP);
36
37   return sa1111_pcmcia_init(init);
38 }
39
40 static int
41 xp860_pcmcia_configure_socket(const struct pcmcia_configure *conf)
42 {
43   unsigned int gpio_mask, pa_dwr_mask;
44   unsigned int gpio_set, pa_dwr_set;
45   int ret;
46
47   /* Neponset uses the Maxim MAX1600, with the following connections:
48 #warning ^^^ This isn't a neponset!
49    *
50    *   MAX1600      Neponset
51    *
52    *    A0VCC        SA-1111 GPIO A<1>
53    *    A1VCC        SA-1111 GPIO A<0>
54    *    A0VPP        CPLD NCR A0VPP
55    *    A1VPP        CPLD NCR A1VPP
56    *    B0VCC        SA-1111 GPIO A<2>
57    *    B1VCC        SA-1111 GPIO A<3>
58    *    B0VPP        ground (slot B is CF)
59    *    B1VPP        ground (slot B is CF)
60    *
61    *     VX          VCC (5V)
62    *     VY          VCC3_3 (3.3V)
63    *     12INA       12V
64    *     12INB       ground (slot B is CF)
65    *
66    * The MAX1600 CODE pin is tied to ground, placing the device in 
67    * "Standard Intel code" mode. Refer to the Maxim data sheet for
68    * the corresponding truth table.
69    */
70
71   switch (conf->sock) {
72   case 0:
73     pa_dwr_mask = GPIO_GPIO0 | GPIO_GPIO1;
74     gpio_mask = NCR_A0VPP | NCR_A1VPP;
75
76     switch (conf->vcc) {
77     default:
78     case 0:     pa_dwr_set = 0;                 break;
79     case 33:    pa_dwr_set = GPIO_GPIO1;        break;
80     case 50:    pa_dwr_set = GPIO_GPIO0;        break;
81     }
82
83     switch (conf->vpp) {
84     case 0:     gpio_set = 0;                   break;
85     case 120:   gpio_set = NCR_A1VPP;           break;
86
87     default:
88       if (conf->vpp == conf->vcc)
89         gpio_set = NCR_A0VPP;
90       else {
91         printk(KERN_ERR "%s(): unrecognized Vpp %u\n",
92                __FUNCTION__, conf->vpp);
93         return -1;
94       }
95     }
96     break;
97
98   case 1:
99     pa_dwr_mask = GPIO_GPIO2 | GPIO_GPIO3;
100     gpio_mask = 0;
101     gpio_set = 0;
102
103     switch (conf->vcc) {
104     default:
105     case 0:     pa_dwr_set = 0;                 break;
106     case 33:    pa_dwr_set = GPIO_GPIO2;        break;
107     case 50:    pa_dwr_set = GPIO_GPIO3;        break;
108     }
109
110     if (conf->vpp != conf->vcc && conf->vpp != 0) {
111       printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n",
112              __FUNCTION__, conf->vpp);
113       return -1;
114     }
115     break;
116   }
117
118   ret = sa1111_pcmcia_configure_socket(conf);
119   if (ret == 0) {
120     unsigned long flags;
121
122     local_irq_save(flags);
123     PA_DWR = (PA_DWR & ~pa_dwr_mask) | pa_dwr_set;
124     GPSR = gpio_set;
125     GPCR = gpio_set ^ gpio_mask;
126     local_irq_restore(flags);
127   }
128
129   return ret;
130 }
131
132 struct pcmcia_low_level xp860_pcmcia_ops = { 
133   init:                 xp860_pcmcia_init,
134   shutdown:             sa1111_pcmcia_shutdown,
135   socket_state:         sa1111_pcmcia_socket_state,
136   get_irq_info:         sa1111_pcmcia_get_irq_info,
137   configure_socket:     xp860_pcmcia_configure_socket,
138
139   socket_init:          sa1111_pcmcia_socket_init,
140   socket_suspend:       sa1111_pcmcia_socket_suspend,
141 };
142