1/* 2 * linux/drivers/pcmcia/pxa2xx_lubbock.c 3 * 4 * Author: George Davis 5 * Created: Jan 10, 2002 6 * Copyright: MontaVista Software Inc. 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License version 2 as 10 * published by the Free Software Foundation. 11 * 12 * Originally based upon linux/drivers/pcmcia/sa1100_neponset.c 13 * 14 * Lubbock PCMCIA specific routines. 15 * 16 */ 17#include <linux/module.h> 18#include <linux/kernel.h> 19#include <linux/device.h> 20#include <linux/errno.h> 21#include <linux/init.h> 22#include <linux/delay.h> 23 24#include <asm/hardware.h> 25#include <asm/hardware/sa1111.h> 26#include <asm/mach-types.h> 27#include <asm/arch/pxa-regs.h> 28#include <asm/arch/lubbock.h> 29 30#include "sa1111_generic.h" 31 32static int 33lubbock_pcmcia_hw_init(struct soc_pcmcia_socket *skt) 34{ 35 /* 36 * Setup default state of GPIO outputs 37 * before we enable them as outputs. 38 */ 39 GPSR(GPIO48_nPOE) = 40 GPIO_bit(GPIO48_nPOE) | 41 GPIO_bit(GPIO49_nPWE) | 42 GPIO_bit(GPIO50_nPIOR) | 43 GPIO_bit(GPIO51_nPIOW) | 44 GPIO_bit(GPIO52_nPCE_1) | 45 GPIO_bit(GPIO53_nPCE_2); 46 47 pxa_gpio_mode(GPIO48_nPOE_MD); 48 pxa_gpio_mode(GPIO49_nPWE_MD); 49 pxa_gpio_mode(GPIO50_nPIOR_MD); 50 pxa_gpio_mode(GPIO51_nPIOW_MD); 51 pxa_gpio_mode(GPIO52_nPCE_1_MD); 52 pxa_gpio_mode(GPIO53_nPCE_2_MD); 53 pxa_gpio_mode(GPIO54_pSKTSEL_MD); 54 pxa_gpio_mode(GPIO55_nPREG_MD); 55 pxa_gpio_mode(GPIO56_nPWAIT_MD); 56 pxa_gpio_mode(GPIO57_nIOIS16_MD); 57 58 return sa1111_pcmcia_hw_init(skt); 59} 60 61static int 62lubbock_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, 63 const socket_state_t *state) 64{ 65 unsigned int pa_dwr_mask, pa_dwr_set, misc_mask, misc_set; 66 int ret = 0; 67 68 pa_dwr_mask = pa_dwr_set = misc_mask = misc_set = 0; 69 70 /* Lubbock uses the Maxim MAX1602, with the following connections: 71 * 72 * Socket 0 (PCMCIA): 73 * MAX1602 Lubbock Register 74 * Pin Signal 75 * ----- ------- ---------------------- 76 * A0VPP S0_PWR0 SA-1111 GPIO A<0> 77 * A1VPP S0_PWR1 SA-1111 GPIO A<1> 78 * A0VCC S0_PWR2 SA-1111 GPIO A<2> 79 * A1VCC S0_PWR3 SA-1111 GPIO A<3> 80 * VX VCC 81 * VY +3.3V 82 * 12IN +12V 83 * CODE +3.3V Cirrus Code, CODE = High (VY) 84 * 85 * Socket 1 (CF): 86 * MAX1602 Lubbock Register 87 * Pin Signal 88 * ----- ------- ---------------------- 89 * A0VPP GND VPP is not connected 90 * A1VPP GND VPP is not connected 91 * A0VCC S1_PWR0 MISC_WR<14> 92 * A1VCC S1_PWR1 MISC_WR<15> 93 * VX VCC 94 * VY +3.3V 95 * 12IN GND VPP is not connected 96 * CODE +3.3V Cirrus Code, CODE = High (VY) 97 * 98 */ 99 100 again: 101 switch (skt->nr) { 102 case 0: 103 pa_dwr_mask = GPIO_A0 | GPIO_A1 | GPIO_A2 | GPIO_A3; 104 105 switch (state->Vcc) { 106 case 0: /* Hi-Z */ 107 break; 108 109 case 33: /* VY */ 110 pa_dwr_set |= GPIO_A3; 111 break; 112 113 case 50: /* VX */ 114 pa_dwr_set |= GPIO_A2; 115 break; 116 117 default: 118 printk(KERN_ERR "%s(): unrecognized Vcc %u\n", 119 __FUNCTION__, state->Vcc); 120 ret = -1; 121 } 122 123 switch (state->Vpp) { 124 case 0: /* Hi-Z */ 125 break; 126 127 case 120: /* 12IN */ 128 pa_dwr_set |= GPIO_A1; 129 break; 130 131 default: /* VCC */ 132 if (state->Vpp == state->Vcc) 133 pa_dwr_set |= GPIO_A0; 134 else { 135 printk(KERN_ERR "%s(): unrecognized Vpp %u\n", 136 __FUNCTION__, state->Vpp); 137 ret = -1; 138 break; 139 } 140 } 141 break; 142 143 case 1: 144 misc_mask = (1 << 15) | (1 << 14); 145 146 switch (state->Vcc) { 147 case 0: /* Hi-Z */ 148 break; 149 150 case 33: /* VY */ 151 misc_set |= 1 << 15; 152 break; 153 154 case 50: /* VX */ 155 misc_set |= 1 << 14; 156 break; 157 158 default: 159 printk(KERN_ERR "%s(): unrecognized Vcc %u\n", 160 __FUNCTION__, state->Vcc); 161 ret = -1; 162 break; 163 } 164 165 if (state->Vpp != state->Vcc && state->Vpp != 0) { 166 printk(KERN_ERR "%s(): CF slot cannot support Vpp %u\n", 167 __FUNCTION__, state->Vpp); 168 ret = -1; 169 break; 170 } 171 break; 172 173 default: 174 ret = -1; 175 } 176 177 if (ret == 0) 178 ret = sa1111_pcmcia_configure_socket(skt, state); 179 180 if (ret == 0) { 181 lubbock_set_misc_wr(misc_mask, misc_set); 182 sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, pa_dwr_set); 183 } 184 185 if (ret == 0 && state->Vcc == 33) { 186 struct pcmcia_state new_state; 187 188 /* 189 * HACK ALERT: 190 * We can't sense the voltage properly on Lubbock before 191 * actually applying some power to the socket (catch 22). 192 * Resense the socket Voltage Sense pins after applying 193 * socket power. 194 * 195 * Note: It takes about 2.5ms for the MAX1602 VCC output 196 * to rise. 197 */ 198 mdelay(3); 199 200 sa1111_pcmcia_socket_state(skt, &new_state); 201 202 if (!new_state.vs_3v && !new_state.vs_Xv) { 203 /* 204 * Switch to 5V, Configure socket with 5V voltage 205 */ 206 lubbock_set_misc_wr(misc_mask, 0); 207 sa1111_set_io(SA1111_DEV(skt->dev), pa_dwr_mask, 0); 208 209 /* 210 * It takes about 100ms to turn off Vcc. 211 */ 212 mdelay(100); 213 214 ((socket_state_t *)state)->Vcc = 50; 215 ((socket_state_t *)state)->Vpp = 50; 216 goto again; 217 } 218 } 219 220 return ret; 221} 222 223static struct pcmcia_low_level lubbock_pcmcia_ops = { 224 .owner = THIS_MODULE, 225 .hw_init = lubbock_pcmcia_hw_init, 226 .hw_shutdown = sa1111_pcmcia_hw_shutdown, 227 .socket_state = sa1111_pcmcia_socket_state, 228 .configure_socket = lubbock_pcmcia_configure_socket, 229 .socket_init = sa1111_pcmcia_socket_init, 230 .socket_suspend = sa1111_pcmcia_socket_suspend, 231 .first = 0, 232 .nr = 2, 233}; 234 235#include "pxa2xx_base.h" 236 237int __init pcmcia_lubbock_init(struct sa1111_dev *sadev) 238{ 239 int ret = -ENODEV; 240 241 if (machine_is_lubbock()) { 242 /* 243 * Set GPIO_A<3:0> to be outputs for the MAX1600, 244 * and switch to standby mode. 245 */ 246 sa1111_set_io_dir(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0, 0); 247 sa1111_set_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); 248 sa1111_set_sleep_io(sadev, GPIO_A0|GPIO_A1|GPIO_A2|GPIO_A3, 0); 249 250 /* Set CF Socket 1 power to standby mode. */ 251 lubbock_set_misc_wr((1 << 15) | (1 << 14), 0); 252 253 sadev->dev.platform_data = &lubbock_pcmcia_ops; 254 ret = __pxa2xx_drv_pcmcia_probe(&sadev->dev); 255 } 256 257 return ret; 258} 259 260MODULE_LICENSE("GPL"); 261