1/* 2 * drivers/pcmcia/sa1100_assabet.c 3 * 4 * PCMCIA implementation routines for Assabet 5 * 6 */ 7#include <linux/module.h> 8#include <linux/kernel.h> 9#include <linux/errno.h> 10#include <linux/interrupt.h> 11#include <linux/device.h> 12#include <linux/init.h> 13#include <linux/gpio.h> 14 15#include <asm/mach-types.h> 16#include <mach/assabet.h> 17 18#include "sa1100_generic.h" 19 20static int assabet_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 21{ 22 skt->stat[SOC_STAT_CD].gpio = ASSABET_GPIO_CF_CD; 23 skt->stat[SOC_STAT_CD].name = "CF CD"; 24 skt->stat[SOC_STAT_BVD1].gpio = ASSABET_GPIO_CF_BVD1; 25 skt->stat[SOC_STAT_BVD1].name = "CF BVD1"; 26 skt->stat[SOC_STAT_BVD2].gpio = ASSABET_GPIO_CF_BVD2; 27 skt->stat[SOC_STAT_BVD2].name = "CF BVD2"; 28 skt->stat[SOC_STAT_RDY].gpio = ASSABET_GPIO_CF_IRQ; 29 skt->stat[SOC_STAT_RDY].name = "CF RDY"; 30 31 return 0; 32} 33 34static void 35assabet_pcmcia_socket_state(struct soc_pcmcia_socket *skt, struct pcmcia_state *state) 36{ 37 state->vs_3v = 1; /* Can only apply 3.3V on Assabet. */ 38 state->vs_Xv = 0; 39} 40 41static int 42assabet_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) 43{ 44 unsigned int mask; 45 46 switch (state->Vcc) { 47 case 0: 48 mask = 0; 49 break; 50 51 case 50: 52 printk(KERN_WARNING "%s(): CS asked for 5V, applying 3.3V...\n", 53 __func__); 54 55 case 33: /* Can only apply 3.3V to the CF slot. */ 56 mask = ASSABET_BCR_CF_PWR; 57 break; 58 59 default: 60 printk(KERN_ERR "%s(): unrecognized Vcc %u\n", __func__, 61 state->Vcc); 62 return -1; 63 } 64 65 /* Silently ignore Vpp, speaker enable. */ 66 67 if (state->flags & SS_RESET) 68 mask |= ASSABET_BCR_CF_RST; 69 if (!(state->flags & SS_OUTPUT_ENA)) 70 mask |= ASSABET_BCR_CF_BUS_OFF; 71 72 ASSABET_BCR_frob(ASSABET_BCR_CF_RST | ASSABET_BCR_CF_PWR | 73 ASSABET_BCR_CF_BUS_OFF, mask); 74 75 return 0; 76} 77 78/* 79 * Disable card status IRQs on suspend. 80 */ 81static void assabet_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) 82{ 83 /* 84 * Tristate the CF bus signals. Also assert CF 85 * reset as per user guide page 4-11. 86 */ 87 ASSABET_BCR_set(ASSABET_BCR_CF_BUS_OFF | ASSABET_BCR_CF_RST); 88} 89 90static struct pcmcia_low_level assabet_pcmcia_ops = { 91 .owner = THIS_MODULE, 92 .hw_init = assabet_pcmcia_hw_init, 93 .socket_state = assabet_pcmcia_socket_state, 94 .configure_socket = assabet_pcmcia_configure_socket, 95 .socket_suspend = assabet_pcmcia_socket_suspend, 96}; 97 98int pcmcia_assabet_init(struct device *dev) 99{ 100 int ret = -ENODEV; 101 102 if (machine_is_assabet() && !machine_has_neponset()) 103 ret = sa11xx_drv_pcmcia_probe(dev, &assabet_pcmcia_ops, 1, 1); 104 105 return ret; 106} 107