More meth updates.
[linux-2.6/linux-mips.git] / drivers / pcmcia / sa1100_trizeps.c
blob752bba3b6c35358af2f385e30bfe4fd0f750e056
1 /*
2 * drivers/pcmcia/sa1100_trizeps.c
4 * PCMCIA implementation routines for Trizeps
6 * Authors:
7 * Andreas Hofer <ho@dsa-ac.de>,
8 * Peter Lueg <pl@dsa-ac.de>,
9 * Guennadi Liakhovetski <gl@dsa-ac.de>
12 #include <linux/module.h>
13 #include <linux/kernel.h>
14 #include <linux/sched.h>
15 #include <linux/device.h>
16 #include <linux/init.h>
18 #include <asm/hardware.h>
19 #include <asm/arch/trizeps.h>
20 #include <asm/mach-types.h>
21 #include <asm/system.h>
22 #include <asm/irq.h>
23 #include "sa1100_generic.h"
25 #define NUMBER_OF_TRIZEPS_PCMCIA_SLOTS 1
27 static struct pcmcia_irqs irqs[] = {
28 { 0, TRIZEPS_IRQ_PCMCIA_CD0, "PCMCIA_CD0" },
31 /**
34 ******************************************************/
35 static int trizeps_pcmcia_init(struct sa1100_pcmcia_socket *skt)
37 skt->irq = TRIZEPS_IRQ_PCMCIA_IRQ0;
39 /* Enable CF bus: */
40 TRIZEPS_BCR_clear(TRIZEPS_BCR1, TRIZEPS_nPCM_ENA_REG);
42 /* All those are inputs */
43 GPDR &= ~((GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_CD0))
44 | (GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_IRQ0)));
46 return sa11xx_request_irqs(skt, irqs, ARRAY_SIZE(irqs));
49 /**
52 ******************************************************/
53 static void trizeps_pcmcia_shutdown(struct sa1100_pcmcia_socket *skt)
55 printk(">>>>>PCMCIA TRIZEPS shutdown\n");
57 sa11xx_free_irqs(skt, irqs, ARRAY_SIZE(irqs));
59 /* Disable CF bus: */
60 TRIZEPS_BCR_set(TRIZEPS_BCR1, TRIZEPS_nPCM_ENA_REG);
63 /**
65 ******************************************************/
66 static void
67 trizeps_pcmcia_socket_state(struct sa1100_pcmcia_socket *skt,
68 struct pcmcia_state *state_array)
70 unsigned long levels = GPLR;
72 state->detect = ((levels & GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_CD0)) == 0) ? 1 : 0;
73 state->ready = ((levels & GPIO_GPIO(TRIZEPS_GPIO_PCMCIA_IRQ0)) != 0) ? 1 : 0;
74 state->bvd1 = ((TRIZEPS_BCR1 & TRIZEPS_PCM_BVD1) !=0 ) ? 1 : 0;
75 state->bvd2 = ((TRIZEPS_BCR1 & TRIZEPS_PCM_BVD2) != 0) ? 1 : 0;
76 state->wrprot = 0; // not write protected
77 state->vs_3v = ((TRIZEPS_BCR1 & TRIZEPS_nPCM_VS1) == 0) ? 1 : 0; //VS1=0 -> vs_3v=1
78 state->vs_Xv = ((TRIZEPS_BCR1 & TRIZEPS_nPCM_VS2) == 0) ? 1 : 0; //VS2=0 -> vs_Xv=1
81 /**
84 ******************************************************/
85 static int
86 trizeps_pcmcia_configure_socket(struct sa1100_pcmcia_socket *skt,
87 const socket_state_t *state)
89 unsigned long flags;
91 local_irq_save(flags);
93 switch (state->Vcc) {
94 case 0:
95 printk(">>> PCMCIA Power off\n");
96 TRIZEPS_BCR_clear(TRIZEPS_BCR1, TRIZEPS_PCM_V3_EN_REG);
97 TRIZEPS_BCR_clear(TRIZEPS_BCR1, TRIZEPS_PCM_V5_EN_REG);
98 break;
100 case 33:
101 // 3.3V Power on
102 TRIZEPS_BCR_clear(TRIZEPS_BCR1, TRIZEPS_PCM_V3_EN_REG);
103 TRIZEPS_BCR_set(TRIZEPS_BCR1, TRIZEPS_PCM_V5_EN_REG);
104 break;
105 case 50:
106 // 5.0V Power on
107 TRIZEPS_BCR_set(TRIZEPS_BCR1, TRIZEPS_PCM_V3_EN_REG);
108 TRIZEPS_BCR_clear(TRIZEPS_BCR1, TRIZEPS_PCM_V5_EN_REG);
109 break;
110 default:
111 printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __FUNCTION__,
112 state->Vcc);
113 local_irq_restore(flags);
114 return -1;
117 if (state->flags & SS_RESET)
118 TRIZEPS_BCR_set(TRIZEPS_BCR1, TRIZEPS_nPCM_RESET_DISABLE); // Reset
119 else
120 TRIZEPS_BCR_clear(TRIZEPS_BCR1, TRIZEPS_nPCM_RESET_DISABLE); // no Reset
122 printk(" vcc=%u vpp=%u -->reset=%i\n",
123 state->Vcc,
124 state->Vpp,
125 ((BCR_read(1) & nPCM_RESET_DISABLE)? 1:0));
127 local_irq_restore(flags);
129 return 0;
132 static void trizeps_pcmcia_socket_init(struct sa1100_pcmcia_socket *skt)
134 sa11xx_enable_irqs(skt, irqs, ARRAY_SIZE(irqs));
137 static void trizeps_pcmcia_socket_suspend(struct sa1100_pcmcia_socket *skt)
139 sa11xx_disable_irqs(skt, irqs, ARRAY_SIZE(irqs));
143 * low-level PCMCIA interface
145 ******************************************************/
146 struct pcmcia_low_level trizeps_pcmcia_ops = {
147 .owner = THIS_MODULE,
148 .hw_init = trizeps_pcmcia_hw_init,
149 .hw_shutdown = trizeps_pcmcia_hw_shutdown,
150 .socket_state = trizeps_pcmcia_socket_state,
151 .configure_socket = trizeps_pcmcia_configure_socket,
152 .socket_init = trizeps_pcmcia_socket_init,
153 .socket_suspend = trizeps_pcmcia_socket_suspend,
156 int __init pcmcia_trizeps_init(struct device *dev)
158 int ret = -ENODEV;
160 if (machine_is_trizeps())
161 ret = sa11xx_drv_pcmcia_probe(dev, &trizeps_pcmcia_ops, 0,
162 NUMBER_OF_TRIZEPS_PCMCIA_SLOTS);
164 return ret;