1/* 2 * drivers/pcmcia/sa1100_cerf.c 3 * 4 * PCMCIA implementation routines for CerfBoard 5 * Based off the Assabet. 6 * 7 */ 8#include <linux/module.h> 9#include <linux/kernel.h> 10#include <linux/device.h> 11#include <linux/init.h> 12#include <linux/delay.h> 13 14#include <mach/hardware.h> 15#include <asm/mach-types.h> 16#include <asm/irq.h> 17#include <mach/cerf.h> 18#include "sa1100_generic.h" 19 20#define CERF_SOCKET 1 21 22static struct pcmcia_irqs irqs[] = { 23 { CERF_SOCKET, CERF_IRQ_GPIO_CF_CD, "CF_CD" }, 24 { CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD2, "CF_BVD2" }, 25 { CERF_SOCKET, CERF_IRQ_GPIO_CF_BVD1, "CF_BVD1" } 26}; 27 28static int cerf_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 29{ 30 skt->socket.pci_irq = CERF_IRQ_GPIO_CF_IRQ; 31 32 return soc_pcmcia_request_irqs(skt, irqs, ARRAY_SIZE(irqs)); 33} 34 35static void cerf_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 36{ 37 soc_pcmcia_free_irqs(skt, irqs, ARRAY_SIZE(irqs)); 38} 39 40static void 41cerf_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) 42{ 43 unsigned long levels = GPLR; 44 45 state->detect = (levels & CERF_GPIO_CF_CD) ?0:1; 46 state->ready = (levels & CERF_GPIO_CF_IRQ) ?1:0; 47 state->bvd1 = (levels & CERF_GPIO_CF_BVD1)?1:0; 48 state->bvd2 = (levels & CERF_GPIO_CF_BVD2)?1:0; 49 state->wrprot = 0; 50 state->vs_3v = 1; 51 state->vs_Xv = 0; 52} 53 54static int 55cerf_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, 56 const socket_state_t *state) 57{ 58 switch (state->Vcc) { 59 case 0: 60 case 50: 61 case 33: 62 break; 63 64 default: 65 printk(KERN_ERR "%s(): unrecognized Vcc %u\n", 66 __func__, state->Vcc); 67 return -1; 68 } 69 70 if (state->flags & SS_RESET) { 71 GPSR = CERF_GPIO_CF_RESET; 72 } else { 73 GPCR = CERF_GPIO_CF_RESET; 74 } 75 76 return 0; 77} 78 79static void cerf_pcmcia_socket_init(struct soc_pcmcia_socket *skt) 80{ 81 soc_pcmcia_enable_irqs(skt, irqs, ARRAY_SIZE(irqs)); 82} 83 84static void cerf_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) 85{ 86 soc_pcmcia_disable_irqs(skt, irqs, ARRAY_SIZE(irqs)); 87} 88 89static struct pcmcia_low_level cerf_pcmcia_ops = { 90 .owner = THIS_MODULE, 91 .hw_init = cerf_pcmcia_hw_init, 92 .hw_shutdown = cerf_pcmcia_hw_shutdown, 93 .socket_state = cerf_pcmcia_socket_state, 94 .configure_socket = cerf_pcmcia_configure_socket, 95 96 .socket_init = cerf_pcmcia_socket_init, 97 .socket_suspend = cerf_pcmcia_socket_suspend, 98}; 99 100int __init pcmcia_cerf_init(struct device *dev) 101{ 102 int ret = -ENODEV; 103 104 if (machine_is_cerf()) 105 ret = sa11xx_drv_pcmcia_probe(dev, &cerf_pcmcia_ops, CERF_SOCKET, 1); 106 107 return ret; 108} 109