1/* 2 * linux/drivers/pcmcia/sa1100_neponset.c 3 * 4 * Neponset PCMCIA specific routines 5 */ 6#include <linux/module.h> 7#include <linux/kernel.h> 8#include <linux/device.h> 9#include <linux/errno.h> 10#include <linux/init.h> 11 12#include <asm/hardware.h> 13#include <asm/mach-types.h> 14#include <asm/arch/neponset.h> 15#include <asm/hardware/sa1111.h> 16 17#include "sa1111_generic.h" 18 19/* 20 * Neponset uses the Maxim MAX1600, with the following connections: 21 * 22 * MAX1600 Neponset 23 * 24 * A0VCC SA-1111 GPIO A<1> 25 * A1VCC SA-1111 GPIO A<0> 26 * A0VPP CPLD NCR A0VPP 27 * A1VPP CPLD NCR A1VPP 28 * B0VCC SA-1111 GPIO A<2> 29 * B1VCC SA-1111 GPIO A<3> 30 * B0VPP ground (slot B is CF) 31 * B1VPP ground (slot B is CF) 32 * 33 * VX VCC (5V) 34 * VY VCC3_3 (3.3V) 35 * 12INA 12V 36 * 12INB ground (slot B is CF) 37 * 38 * The MAX1600 CODE pin is tied to ground, placing the device in 39 * "Standard Intel code" mode. Refer to the Maxim data sheet for 40 * the corresponding truth table. 41 */ 42 43static int 44neponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state) 45{ 46 unsigned int ncr_mask, ncr_set, pa_dwr_mask, pa_dwr_set; 47 int ret; 48 49 switch (skt->nr) { 50 case 0: 51 pa_dwr_mask = GPIO_A0 | GPIO_A1; 52 ncr_mask = NCR_A0VPP | NCR_A1VPP; 53 54 if (state->Vpp == 0) 55 ncr_set = 0; 56 else if (state->Vpp == 120) 57 ncr_set = NCR_A1VPP; 58 else if (state->Vpp == state->Vcc) 59 ncr_set = NCR_A0VPP; 60 else { 61 printk(KERN_ERR "%s(): unrecognized VPP %u\n", 62 __FUNCTION__, state->Vpp); 63 return -1; 64 } 65 break; 66 67 case 1: 68 pa_dwr_mask = GPIO_A2 | GPIO_A3; 69 ncr_mask = 0; 70 ncr_set = 0; 71 72 if (state->Vpp != state->Vcc && state->Vpp != 0) { 73 printk(KERN_ERR "%s(): CF slot cannot support VPP %u\n", 74 __FUNCTION__, state->Vpp); 75 return -1; 76 } 77 break; 78 79 default: 80 return -1; 81 } 82 83 /* 84 * pa_dwr_set is the mask for selecting Vcc on both sockets. 85 * pa_dwr_mask selects which bits (and therefore socket) we change. 86 */ 87 switch (state->Vcc) { 88 default: 89 case 0: pa_dwr_set = 0; break; 90 case 33: pa_dwr_set = GPIO_A1|GPIO_A2; break; 91 case 50: pa_dwr_set = GPIO_A0|GPIO_A3; break; 92 } 93 94 ret = sa1111_pcmcia_configure_socket(skt, state); 95 if (ret == 0) { 96 unsigned long flags; 97 98 local_irq_save(flags); 99 NCR_0 = (NCR_0 & ~ncr_mask) | ncr_set; 100 101 local_irq_restore(flags); 102 sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set); 103 } 104 105 return 0; 106} 107 108static void neponset_pcmcia_socket_init(struct soc_pcmcia_socket *skt) 109{ 110 if (skt->nr == 0) 111 NCR_0 &= ~(NCR_A0VPP | NCR_A1VPP); 112 113 sa1111_pcmcia_socket_init(skt); 114} 115 116static struct pcmcia_low_level neponset_pcmcia_ops = { 117 .owner = THIS_MODULE, 118 .hw_init = sa1111_pcmcia_hw_init, 119 .hw_shutdown = sa1111_pcmcia_hw_shutdown, 120 .socket_state = sa1111_pcmcia_socket_state, 121 .configure_socket = neponset_pcmcia_configure_socket, 122 .socket_init = neponset_pcmcia_socket_init, 123 .socket_suspend = sa1111_pcmcia_socket_suspend, 124}; 125 126int __init pcmcia_neponset_init(struct sa1111_dev *sadev) 127{ 128 int ret = -ENODEV; 129 130 if (machine_is_assabet()) { 131 /* 132 * Set GPIO_A<3:0> to be outputs for the MAX1600, 133 * and switch to standby mode. 134 */ 135 sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0); 136 sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); 137 sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); 138 ret = sa11xx_drv_pcmcia_probe(&sadev->dev, &neponset_pcmcia_ops, 0, 2); 139 } 140 141 return ret; 142} 143