2 * drivers/pcmcia/sa1100_flexanet.c
4 * PCMCIA implementation routines for Flexanet.
5 * by Jordi Colomer, 09/05/2001
8 #include <linux/module.h>
9 #include <linux/kernel.h>
10 #include <linux/sched.h>
11 #include <linux/device.h>
12 #include <linux/init.h>
14 #include <asm/hardware.h>
15 #include <asm/mach-types.h>
17 #include "sa1100_generic.h"
19 static struct pcmcia_irqs irqs
[] = {
20 { 0, IRQ_GPIO_CF1_CD
, "CF1_CD" },
21 { 0, IRQ_GPIO_CF1_BVD1
, "CF1_BVD1" },
22 { 1, IRQ_GPIO_CF2_CD
, "CF2_CD" },
23 { 1, IRQ_GPIO_CF2_BVD1
, "CF2_BVD1" }
27 * Socket initialization.
29 * Called by sa1100_pcmcia_driver_init on startup.
31 static int flexanet_pcmcia_hw_init(struct soc_pcmcia_socket
*skt
)
33 skt
->irq
= skt
->nr
? IRQ_GPIO_CF2_IRQ
: IRQ_GPIO_CF1_IRQ
;
35 return soc_pcmcia_request_irqs(skt
, irqs
, ARRAY_SIZE(irqs
));
42 static void flexanet_pcmcia_hw_shutdown(struct soc_pcmcia_socket
*skt
)
44 soc_pcmcia_free_irqs(skt
, irqs
, ARRAY_SIZE(irqs
));
49 * Get the state of the sockets.
51 * Sockets in Flexanet are 3.3V only, without BVD2.
55 flexanet_pcmcia_socket_state(struct soc_pcmcia_socket
*skt
,
56 struct pcmcia_state
*state
)
58 unsigned long levels
= GPLR
; /* Sense the GPIOs, asynchronously */
62 state
->detect
= ((levels
& GPIO_CF1_NCD
)==0)?1:0;
63 state
->ready
= (levels
& GPIO_CF1_IRQ
)?1:0;
64 state
->bvd1
= (levels
& GPIO_CF1_BVD1
)?1:0;
71 case 1: /* Socket 1 */
72 state
->detect
= ((levels
& GPIO_CF2_NCD
)==0)?1:0;
73 state
->ready
= (levels
& GPIO_CF2_IRQ
)?1:0;
74 state
->bvd1
= (levels
& GPIO_CF2_BVD1
)?1:0;
88 flexanet_pcmcia_configure_socket(struct soc_pcmcia_socket
*skt
,
89 const socket_state_t
*state
)
91 unsigned long value
, flags
, mask
;
93 /* Ignore the VCC level since it is 3.3V and always on */
96 printk(KERN_WARNING
"%s(): CS asked to power off.\n",
101 printk(KERN_WARNING
"%s(): CS asked for 5V, applying 3.3V...\n",
108 printk(KERN_ERR
"%s(): unrecognized Vcc %u\n", __FUNCTION__
,
113 /* Reset the slot(s) using the controls in the BCR */
118 mask
= FHH_BCR_CF1_RST
;
121 mask
= FHH_BCR_CF2_RST
;
125 local_irq_save(flags
);
127 value
= flexanet_BCR
;
128 value
= (state
->flags
& SS_RESET
) ? (value
| mask
) : (value
& ~mask
);
129 FHH_BCR
= flexanet_BCR
= value
;
131 local_irq_restore(flags
);
136 static void flexanet_pcmcia_socket_init(struct soc_pcmcia_socket
*skt
)
138 soc_pcmcia_enable_irqs(skt
, irqs
, ARRAY_SIZE(irqs
));
141 static void flexanet_pcmcia_socket_suspend(struct soc_pcmcia_socket
*skt
)
143 soc_pcmcia_disable_irqs(skt
, irqs
, ARRAY_SIZE(irqs
));
147 * The set of socket operations
150 static struct pcmcia_low_level flexanet_pcmcia_ops
= {
151 .owner
= THIS_MODULE
,
152 .hw_init
= flexanet_pcmcia_hw_init
,
153 .hw_shutdown
= flexanet_pcmcia_hw_shutdown
,
154 .socket_state
= flexanet_pcmcia_socket_state
,
155 .configure_socket
= flexanet_pcmcia_configure_socket
,
156 .socket_init
= flexanet_pcmcia_socket_init
,
157 .socket_suspend
= flexanet_pcmcia_socket_suspend
,
160 int __init
pcmcia_flexanet_init(struct device
*dev
)
164 if (machine_is_flexanet())
165 ret
= sa11xx_drv_pcmcia_probe(dev
, &flexanet_pcmcia_ops
, 0, 2);