11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * drivers/pcmcia/sa1100_simpad.c 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * PCMCIA implementation routines for simpad 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/kernel.h> 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/device.h> 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 12a09e64fbc0094e3073dbb09c3b4bfe4ab669244bRussell King#include <mach/hardware.h> 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/mach-types.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/irq.h> 15a09e64fbc0094e3073dbb09c3b4bfe4ab669244bRussell King#include <mach/simpad.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "sa1100_generic.h" 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int simpad_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 21de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 23b1d8a5f91796179f33de9cd7fb26052fcc47b4faRussell King skt->stat[SOC_STAT_CD].gpio = GPIO_CF_CD; 24b1d8a5f91796179f33de9cd7fb26052fcc47b4faRussell King skt->stat[SOC_STAT_CD].name = "CF_CD"; 25b1d8a5f91796179f33de9cd7fb26052fcc47b4faRussell King skt->stat[SOC_STAT_RDY].gpio = GPIO_CF_IRQ; 26b1d8a5f91796179f33de9cd7fb26052fcc47b4faRussell King skt->stat[SOC_STAT_RDY].name = "CF_RDY"; 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 28b1d8a5f91796179f33de9cd7fb26052fcc47b4faRussell King return 0; 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void simpad_pcmcia_hw_shutdown(struct soc_pcmcia_socket *skt) 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Disable CF bus: */ 34de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich /*simpad_set_cs3_bit(PCMCIA_BUFF_DIS);*/ 35de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich simpad_clear_cs3_bit(PCMCIA_RESET); 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssimpad_pcmcia_socket_state(struct soc_pcmcia_socket *skt, 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pcmcia_state *state) 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 42de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich long cs3reg = simpad_get_cs3_ro(); 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 44b1d8a5f91796179f33de9cd7fb26052fcc47b4faRussell King /* the detect signal is inverted - fix that up here */ 45b1d8a5f91796179f33de9cd7fb26052fcc47b4faRussell King state->detect = !state->detect; 46b1d8a5f91796179f33de9cd7fb26052fcc47b4faRussell King 47de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich state->bvd1 = 1; /* Might be cs3reg & PCMCIA_BVD1 */ 48de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich state->bvd2 = 1; /* Might be cs3reg & PCMCIA_BVD2 */ 49de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich 50de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich if ((cs3reg & (PCMCIA_VS1|PCMCIA_VS2)) == 51de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich (PCMCIA_VS1|PCMCIA_VS2)) { 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds state->vs_3v=0; 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds state->vs_Xv=0; 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } else { 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds state->vs_3v=1; 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds state->vs_Xv=0; 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssimpad_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const socket_state_t *state) 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_irq_save(flags); 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Murphy: see table of MIC2562a-1 */ 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (state->Vcc) { 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 71de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 33: 75de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich simpad_clear_cs3_bit(VCC_3V_EN|EN1); 76de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich simpad_set_cs3_bit(VCC_5V_EN|EN0); 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 50: 80de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich simpad_clear_cs3_bit(VCC_5V_EN|EN1); 81de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich simpad_set_cs3_bit(VCC_3V_EN|EN0); 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "%s(): unrecognized Vcc %u\n", 862e11cb4c52ffbadab4844b28803577ba7272b221Harvey Harrison __func__, state->Vcc); 87de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich simpad_clear_cs3_bit(VCC_3V_EN|VCC_5V_EN|EN0|EN1); 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_irq_restore(flags); 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return -1; 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_irq_restore(flags); 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void simpad_pcmcia_socket_suspend(struct soc_pcmcia_socket *skt) 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 100de0bc0d1b008d1240c03a0bac4f5534f995ab802Jochen Friedrich simpad_set_cs3_bit(PCMCIA_RESET); 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct pcmcia_low_level simpad_pcmcia_ops = { 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .owner = THIS_MODULE, 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .hw_init = simpad_pcmcia_hw_init, 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .hw_shutdown = simpad_pcmcia_hw_shutdown, 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .socket_state = simpad_pcmcia_socket_state, 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .configure_socket = simpad_pcmcia_configure_socket, 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .socket_suspend = simpad_pcmcia_socket_suspend, 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1125b85e04e93f9a2963e88156cae8629ee72efd890Uwe Kleine-Königint __devinit pcmcia_simpad_init(struct device *dev) 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret = -ENODEV; 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (machine_is_simpad()) 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ret = sa11xx_drv_pcmcia_probe(dev, &simpad_pcmcia_ops, 1, 1); 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 121