2 * drivers/pcmcia/sa1100_trizeps.c
4 * PCMCIA implementation routines for Trizeps
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>
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" },
34 ******************************************************/
35 static int trizeps_pcmcia_init(struct sa1100_pcmcia_socket
*skt
)
37 skt
->irq
= TRIZEPS_IRQ_PCMCIA_IRQ0
;
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
));
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
));
60 TRIZEPS_BCR_set(TRIZEPS_BCR1
, TRIZEPS_nPCM_ENA_REG
);
65 ******************************************************/
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
84 ******************************************************/
86 trizeps_pcmcia_configure_socket(struct sa1100_pcmcia_socket
*skt
,
87 const socket_state_t
*state
)
91 local_irq_save(flags
);
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
);
102 TRIZEPS_BCR_clear(TRIZEPS_BCR1
, TRIZEPS_PCM_V3_EN_REG
);
103 TRIZEPS_BCR_set(TRIZEPS_BCR1
, TRIZEPS_PCM_V5_EN_REG
);
107 TRIZEPS_BCR_set(TRIZEPS_BCR1
, TRIZEPS_PCM_V3_EN_REG
);
108 TRIZEPS_BCR_clear(TRIZEPS_BCR1
, TRIZEPS_PCM_V5_EN_REG
);
111 printk(KERN_ERR
"%s(): unrecognized Vcc %u\n", __FUNCTION__
,
113 local_irq_restore(flags
);
117 if (state
->flags
& SS_RESET
)
118 TRIZEPS_BCR_set(TRIZEPS_BCR1
, TRIZEPS_nPCM_RESET_DISABLE
); // Reset
120 TRIZEPS_BCR_clear(TRIZEPS_BCR1
, TRIZEPS_nPCM_RESET_DISABLE
); // no Reset
122 printk(" vcc=%u vpp=%u -->reset=%i\n",
125 ((BCR_read(1) & nPCM_RESET_DISABLE)? 1:0));
127 local_irq_restore(flags
);
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
)
160 if (machine_is_trizeps())
161 ret
= sa11xx_drv_pcmcia_probe(dev
, &trizeps_pcmcia_ops
, 0,
162 NUMBER_OF_TRIZEPS_PCMCIA_SLOTS
);