more debug output
[linux-2.4.git] / drivers / pcmcia / sa1100_shannon.c
1 /*
2  * drivers/pcmcia/sa1100_shannon.c
3  *
4  * PCMCIA implementation routines for Shannon
5  *
6  */
7 #include <linux/kernel.h>
8 #include <linux/sched.h>
9
10 #include <asm/hardware.h>
11 #include <asm/arch/shannon.h>
12 #include <asm/irq.h>
13 #include "sa1100_generic.h"
14
15 static int shannon_pcmcia_init(struct pcmcia_init *init)
16 {
17         int irq, res;
18
19         /* All those are inputs */
20         GPDR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | 
21                   SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1);
22         GAFR &= ~(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1 | 
23                   SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1);
24
25         /* Set transition detect */
26         set_GPIO_IRQ_edge(SHANNON_GPIO_EJECT_0 | SHANNON_GPIO_EJECT_1, GPIO_NO_EDGES);
27         set_GPIO_IRQ_edge(SHANNON_GPIO_RDY_0 | SHANNON_GPIO_RDY_1, GPIO_FALLING_EDGE);
28
29         /* Register interrupts */
30         irq = SHANNON_IRQ_GPIO_EJECT_0;
31         res = request_irq(irq, init->handler, SA_INTERRUPT, "PCMCIA_CD_0", NULL);
32         if (res < 0) goto irq_err;
33         irq = SHANNON_IRQ_GPIO_EJECT_1;
34         res = request_irq(irq, init->handler, SA_INTERRUPT, "PCMCIA_CD_1", NULL);
35         if (res < 0) goto irq_err;
36
37         return 2;
38 irq_err:
39         printk(KERN_ERR "%s: Request for IRQ %d failed\n", __FUNCTION__, irq);
40         return -1;
41 }
42
43 static int shannon_pcmcia_shutdown(void)
44 {
45         /* disable IRQs */
46         free_irq(SHANNON_IRQ_GPIO_EJECT_0, NULL);
47         free_irq(SHANNON_IRQ_GPIO_EJECT_1, NULL);
48
49         return 0;
50 }
51
52 static int shannon_pcmcia_socket_state(struct pcmcia_state_array *state_array)
53 {
54         unsigned long levels;
55
56         memset(state_array->state, 0,
57                state_array->size * sizeof(struct pcmcia_state));
58
59         levels = GPLR;
60
61         state_array->state[0].detect = (levels & SHANNON_GPIO_EJECT_0) ? 0 : 1;
62         state_array->state[0].ready  = (levels & SHANNON_GPIO_RDY_0) ? 1 : 0;
63         state_array->state[0].wrprot = 0; /* Not available on Shannon. */
64         state_array->state[0].bvd1 = 1; 
65         state_array->state[0].bvd2 = 1; 
66         state_array->state[0].vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
67         state_array->state[0].vs_Xv  = 0;
68
69         state_array->state[1].detect = (levels & SHANNON_GPIO_EJECT_1) ? 0 : 1;
70         state_array->state[1].ready  = (levels & SHANNON_GPIO_RDY_1) ? 1 : 0;
71         state_array->state[1].wrprot = 0; /* Not available on Shannon. */
72         state_array->state[1].bvd1 = 1; 
73         state_array->state[1].bvd2 = 1; 
74         state_array->state[1].vs_3v  = 1; /* FIXME Can only apply 3.3V on Shannon. */
75         state_array->state[1].vs_Xv  = 0;
76
77         return 1;
78 }
79
80 static int shannon_pcmcia_get_irq_info(struct pcmcia_irq_info *info)
81 {
82         if (info->sock == 0)
83                 info->irq = SHANNON_IRQ_GPIO_RDY_0;
84         else if (info->sock == 1)
85                 info->irq = SHANNON_IRQ_GPIO_RDY_1;
86         else return -1;
87         
88         return 0;
89 }
90
91 static int shannon_pcmcia_configure_socket(const struct pcmcia_configure *configure)
92 {
93
94         switch (configure->vcc) {
95         case 0: /* power off */;
96                 printk(KERN_WARNING __FUNCTION__"(): CS asked for 0V, still applying 3.3V..\n");
97                 break;
98         case 50:
99                 printk(KERN_WARNING __FUNCTION__"(): CS asked for 5V, applying 3.3V..\n");
100         case 33:
101                 break;
102         default:
103                 printk(KERN_ERR __FUNCTION__"(): unrecognized Vcc %u\n",
104                        configure->vcc);
105                 return -1;
106         }
107
108         printk(KERN_WARNING __FUNCTION__"(): Warning, Can't perform reset\n");
109         
110         /* Silently ignore Vpp, output enable, speaker enable. */
111
112         return 0;
113 }
114
115 static int shannon_pcmcia_socket_init(int sock)
116 {
117         if (sock == 0)
118                 set_GPIO_IRQ_edge(SHANNON_GPIO_EJECT_0, GPIO_BOTH_EDGES);
119         else if (sock == 1)
120                 set_GPIO_IRQ_edge(SHANNON_GPIO_EJECT_1, GPIO_BOTH_EDGES);
121
122         return 0;
123 }
124
125 static int shannon_pcmcia_socket_suspend(int sock)
126 {
127         if (sock == 0)
128                 set_GPIO_IRQ_edge(SHANNON_GPIO_EJECT_0, GPIO_NO_EDGES);
129         else if (sock == 1)
130                 set_GPIO_IRQ_edge(SHANNON_GPIO_EJECT_1, GPIO_NO_EDGES);
131
132         return 0;
133 }
134
135 struct pcmcia_low_level shannon_pcmcia_ops = {
136         init:                   shannon_pcmcia_init,
137         shutdown:               shannon_pcmcia_shutdown,
138         socket_state:           shannon_pcmcia_socket_state,
139         get_irq_info:           shannon_pcmcia_get_irq_info,
140         configure_socket:       shannon_pcmcia_configure_socket,
141
142         socket_init:            shannon_pcmcia_socket_init,
143         socket_suspend:         shannon_pcmcia_socket_suspend,
144 };