1*4882a593Smuzhiyun /* 2*4882a593Smuzhiyun ** asm-m68k/pcmcia.c -- Amiga Linux PCMCIA support 3*4882a593Smuzhiyun ** most information was found by disassembling card.resource 4*4882a593Smuzhiyun ** I'm still looking for an official doc ! 5*4882a593Smuzhiyun ** 6*4882a593Smuzhiyun ** Copyright 1997 by Alain Malek 7*4882a593Smuzhiyun ** 8*4882a593Smuzhiyun ** This file is subject to the terms and conditions of the GNU General Public 9*4882a593Smuzhiyun ** License. See the file COPYING in the main directory of this archive 10*4882a593Smuzhiyun ** for more details. 11*4882a593Smuzhiyun ** 12*4882a593Smuzhiyun ** Created: 12/10/97 by Alain Malek 13*4882a593Smuzhiyun */ 14*4882a593Smuzhiyun 15*4882a593Smuzhiyun #include <linux/types.h> 16*4882a593Smuzhiyun #include <linux/jiffies.h> 17*4882a593Smuzhiyun #include <linux/timer.h> 18*4882a593Smuzhiyun #include <linux/module.h> 19*4882a593Smuzhiyun 20*4882a593Smuzhiyun #include <asm/amigayle.h> 21*4882a593Smuzhiyun #include <asm/amipcmcia.h> 22*4882a593Smuzhiyun 23*4882a593Smuzhiyun /* gayle config byte for program voltage and access speed */ 24*4882a593Smuzhiyun static unsigned char cfg_byte = GAYLE_CFG_0V|GAYLE_CFG_150NS; 25*4882a593Smuzhiyun pcmcia_reset(void)26*4882a593Smuzhiyunvoid pcmcia_reset(void) 27*4882a593Smuzhiyun { 28*4882a593Smuzhiyun unsigned long reset_start_time = jiffies; 29*4882a593Smuzhiyun unsigned char b; 30*4882a593Smuzhiyun 31*4882a593Smuzhiyun gayle_reset = 0x00; 32*4882a593Smuzhiyun while (time_before(jiffies, reset_start_time + 1*HZ/100)); 33*4882a593Smuzhiyun b = gayle_reset; 34*4882a593Smuzhiyun } 35*4882a593Smuzhiyun EXPORT_SYMBOL(pcmcia_reset); 36*4882a593Smuzhiyun 37*4882a593Smuzhiyun 38*4882a593Smuzhiyun /* copy a tuple, including tuple header. return nb bytes copied */ 39*4882a593Smuzhiyun /* be careful as this may trigger a GAYLE_IRQ_WR interrupt ! */ 40*4882a593Smuzhiyun pcmcia_copy_tuple(unsigned char tuple_id,void * tuple,int max_len)41*4882a593Smuzhiyunint pcmcia_copy_tuple(unsigned char tuple_id, void *tuple, int max_len) 42*4882a593Smuzhiyun { 43*4882a593Smuzhiyun unsigned char id, *dest; 44*4882a593Smuzhiyun int cnt, pos, len; 45*4882a593Smuzhiyun 46*4882a593Smuzhiyun dest = tuple; 47*4882a593Smuzhiyun pos = 0; 48*4882a593Smuzhiyun 49*4882a593Smuzhiyun id = gayle_attribute[pos]; 50*4882a593Smuzhiyun 51*4882a593Smuzhiyun while((id != CISTPL_END) && (pos < 0x10000)) { 52*4882a593Smuzhiyun len = (int)gayle_attribute[pos+2] + 2; 53*4882a593Smuzhiyun if (id == tuple_id) { 54*4882a593Smuzhiyun len = (len > max_len)?max_len:len; 55*4882a593Smuzhiyun for (cnt = 0; cnt < len; cnt++) { 56*4882a593Smuzhiyun *dest++ = gayle_attribute[pos+(cnt<<1)]; 57*4882a593Smuzhiyun } 58*4882a593Smuzhiyun 59*4882a593Smuzhiyun return len; 60*4882a593Smuzhiyun } 61*4882a593Smuzhiyun pos += len<<1; 62*4882a593Smuzhiyun id = gayle_attribute[pos]; 63*4882a593Smuzhiyun } 64*4882a593Smuzhiyun 65*4882a593Smuzhiyun return 0; 66*4882a593Smuzhiyun } 67*4882a593Smuzhiyun EXPORT_SYMBOL(pcmcia_copy_tuple); 68*4882a593Smuzhiyun pcmcia_program_voltage(int voltage)69*4882a593Smuzhiyunvoid pcmcia_program_voltage(int voltage) 70*4882a593Smuzhiyun { 71*4882a593Smuzhiyun unsigned char v; 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun switch (voltage) { 74*4882a593Smuzhiyun case PCMCIA_0V: 75*4882a593Smuzhiyun v = GAYLE_CFG_0V; 76*4882a593Smuzhiyun break; 77*4882a593Smuzhiyun case PCMCIA_5V: 78*4882a593Smuzhiyun v = GAYLE_CFG_5V; 79*4882a593Smuzhiyun break; 80*4882a593Smuzhiyun case PCMCIA_12V: 81*4882a593Smuzhiyun v = GAYLE_CFG_12V; 82*4882a593Smuzhiyun break; 83*4882a593Smuzhiyun default: 84*4882a593Smuzhiyun v = GAYLE_CFG_0V; 85*4882a593Smuzhiyun } 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun cfg_byte = (cfg_byte & 0xfc) | v; 88*4882a593Smuzhiyun gayle.config = cfg_byte; 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun } 91*4882a593Smuzhiyun EXPORT_SYMBOL(pcmcia_program_voltage); 92*4882a593Smuzhiyun pcmcia_access_speed(int speed)93*4882a593Smuzhiyunvoid pcmcia_access_speed(int speed) 94*4882a593Smuzhiyun { 95*4882a593Smuzhiyun unsigned char s; 96*4882a593Smuzhiyun 97*4882a593Smuzhiyun if (speed <= PCMCIA_SPEED_100NS) 98*4882a593Smuzhiyun s = GAYLE_CFG_100NS; 99*4882a593Smuzhiyun else if (speed <= PCMCIA_SPEED_150NS) 100*4882a593Smuzhiyun s = GAYLE_CFG_150NS; 101*4882a593Smuzhiyun else if (speed <= PCMCIA_SPEED_250NS) 102*4882a593Smuzhiyun s = GAYLE_CFG_250NS; 103*4882a593Smuzhiyun else 104*4882a593Smuzhiyun s = GAYLE_CFG_720NS; 105*4882a593Smuzhiyun 106*4882a593Smuzhiyun cfg_byte = (cfg_byte & 0xf3) | s; 107*4882a593Smuzhiyun gayle.config = cfg_byte; 108*4882a593Smuzhiyun } 109*4882a593Smuzhiyun EXPORT_SYMBOL(pcmcia_access_speed); 110*4882a593Smuzhiyun pcmcia_write_enable(void)111*4882a593Smuzhiyunvoid pcmcia_write_enable(void) 112*4882a593Smuzhiyun { 113*4882a593Smuzhiyun gayle.cardstatus = GAYLE_CS_WR|GAYLE_CS_DA; 114*4882a593Smuzhiyun } 115*4882a593Smuzhiyun EXPORT_SYMBOL(pcmcia_write_enable); 116*4882a593Smuzhiyun pcmcia_write_disable(void)117*4882a593Smuzhiyunvoid pcmcia_write_disable(void) 118*4882a593Smuzhiyun { 119*4882a593Smuzhiyun gayle.cardstatus = 0; 120*4882a593Smuzhiyun } 121*4882a593Smuzhiyun EXPORT_SYMBOL(pcmcia_write_disable); 122*4882a593Smuzhiyun 123