11da177e4SLinus Torvalds /* 21da177e4SLinus Torvalds ** asm-m68k/pcmcia.c -- Amiga Linux PCMCIA support 31da177e4SLinus Torvalds ** most information was found by disassembling card.resource 41da177e4SLinus Torvalds ** I'm still looking for an official doc ! 51da177e4SLinus Torvalds ** 61da177e4SLinus Torvalds ** Copyright 1997 by Alain Malek 71da177e4SLinus Torvalds ** 81da177e4SLinus Torvalds ** This file is subject to the terms and conditions of the GNU General Public 91da177e4SLinus Torvalds ** License. See the file COPYING in the main directory of this archive 101da177e4SLinus Torvalds ** for more details. 111da177e4SLinus Torvalds ** 121da177e4SLinus Torvalds ** Created: 12/10/97 by Alain Malek 131da177e4SLinus Torvalds */ 141da177e4SLinus Torvalds 151da177e4SLinus Torvalds #include <linux/types.h> 161da177e4SLinus Torvalds #include <linux/jiffies.h> 171da177e4SLinus Torvalds #include <linux/timer.h> 188b169fa2SAdrian Bunk #include <linux/module.h> 198b169fa2SAdrian Bunk 201da177e4SLinus Torvalds #include <asm/amigayle.h> 211da177e4SLinus Torvalds #include <asm/amipcmcia.h> 221da177e4SLinus Torvalds 231da177e4SLinus Torvalds /* gayle config byte for program voltage and access speed */ 241da177e4SLinus Torvalds static unsigned char cfg_byte = GAYLE_CFG_0V|GAYLE_CFG_150NS; 251da177e4SLinus Torvalds pcmcia_reset(void)261da177e4SLinus Torvaldsvoid pcmcia_reset(void) 271da177e4SLinus Torvalds { 281da177e4SLinus Torvalds unsigned long reset_start_time = jiffies; 291da177e4SLinus Torvalds 301da177e4SLinus Torvalds gayle_reset = 0x00; 311da177e4SLinus Torvalds while (time_before(jiffies, reset_start_time + 1*HZ/100)); 32*ac0b5591SGeert Uytterhoeven READ_ONCE(gayle_reset); 331da177e4SLinus Torvalds } 348b169fa2SAdrian Bunk EXPORT_SYMBOL(pcmcia_reset); 351da177e4SLinus Torvalds 361da177e4SLinus Torvalds 371da177e4SLinus Torvalds /* copy a tuple, including tuple header. return nb bytes copied */ 380c79cf6aSSimon Arlott /* be careful as this may trigger a GAYLE_IRQ_WR interrupt ! */ 391da177e4SLinus Torvalds pcmcia_copy_tuple(unsigned char tuple_id,void * tuple,int max_len)401da177e4SLinus Torvaldsint pcmcia_copy_tuple(unsigned char tuple_id, void *tuple, int max_len) 411da177e4SLinus Torvalds { 421da177e4SLinus Torvalds unsigned char id, *dest; 431da177e4SLinus Torvalds int cnt, pos, len; 441da177e4SLinus Torvalds 451da177e4SLinus Torvalds dest = tuple; 461da177e4SLinus Torvalds pos = 0; 471da177e4SLinus Torvalds 481da177e4SLinus Torvalds id = gayle_attribute[pos]; 491da177e4SLinus Torvalds 501da177e4SLinus Torvalds while((id != CISTPL_END) && (pos < 0x10000)) { 511da177e4SLinus Torvalds len = (int)gayle_attribute[pos+2] + 2; 521da177e4SLinus Torvalds if (id == tuple_id) { 531da177e4SLinus Torvalds len = (len > max_len)?max_len:len; 541da177e4SLinus Torvalds for (cnt = 0; cnt < len; cnt++) { 551da177e4SLinus Torvalds *dest++ = gayle_attribute[pos+(cnt<<1)]; 561da177e4SLinus Torvalds } 571da177e4SLinus Torvalds 581da177e4SLinus Torvalds return len; 591da177e4SLinus Torvalds } 601da177e4SLinus Torvalds pos += len<<1; 611da177e4SLinus Torvalds id = gayle_attribute[pos]; 621da177e4SLinus Torvalds } 631da177e4SLinus Torvalds 641da177e4SLinus Torvalds return 0; 651da177e4SLinus Torvalds } 668b169fa2SAdrian Bunk EXPORT_SYMBOL(pcmcia_copy_tuple); 671da177e4SLinus Torvalds pcmcia_program_voltage(int voltage)681da177e4SLinus Torvaldsvoid pcmcia_program_voltage(int voltage) 691da177e4SLinus Torvalds { 701da177e4SLinus Torvalds unsigned char v; 711da177e4SLinus Torvalds 721da177e4SLinus Torvalds switch (voltage) { 731da177e4SLinus Torvalds case PCMCIA_0V: 741da177e4SLinus Torvalds v = GAYLE_CFG_0V; 751da177e4SLinus Torvalds break; 761da177e4SLinus Torvalds case PCMCIA_5V: 771da177e4SLinus Torvalds v = GAYLE_CFG_5V; 781da177e4SLinus Torvalds break; 791da177e4SLinus Torvalds case PCMCIA_12V: 801da177e4SLinus Torvalds v = GAYLE_CFG_12V; 811da177e4SLinus Torvalds break; 821da177e4SLinus Torvalds default: 831da177e4SLinus Torvalds v = GAYLE_CFG_0V; 841da177e4SLinus Torvalds } 851da177e4SLinus Torvalds 861da177e4SLinus Torvalds cfg_byte = (cfg_byte & 0xfc) | v; 871da177e4SLinus Torvalds gayle.config = cfg_byte; 881da177e4SLinus Torvalds 891da177e4SLinus Torvalds } 908b169fa2SAdrian Bunk EXPORT_SYMBOL(pcmcia_program_voltage); 911da177e4SLinus Torvalds pcmcia_access_speed(int speed)921da177e4SLinus Torvaldsvoid pcmcia_access_speed(int speed) 931da177e4SLinus Torvalds { 941da177e4SLinus Torvalds unsigned char s; 951da177e4SLinus Torvalds 961da177e4SLinus Torvalds if (speed <= PCMCIA_SPEED_100NS) 971da177e4SLinus Torvalds s = GAYLE_CFG_100NS; 981da177e4SLinus Torvalds else if (speed <= PCMCIA_SPEED_150NS) 991da177e4SLinus Torvalds s = GAYLE_CFG_150NS; 1001da177e4SLinus Torvalds else if (speed <= PCMCIA_SPEED_250NS) 1011da177e4SLinus Torvalds s = GAYLE_CFG_250NS; 1021da177e4SLinus Torvalds else 1031da177e4SLinus Torvalds s = GAYLE_CFG_720NS; 1041da177e4SLinus Torvalds 1051da177e4SLinus Torvalds cfg_byte = (cfg_byte & 0xf3) | s; 1061da177e4SLinus Torvalds gayle.config = cfg_byte; 1071da177e4SLinus Torvalds } 1088b169fa2SAdrian Bunk EXPORT_SYMBOL(pcmcia_access_speed); 1091da177e4SLinus Torvalds pcmcia_write_enable(void)1101da177e4SLinus Torvaldsvoid pcmcia_write_enable(void) 1111da177e4SLinus Torvalds { 1121da177e4SLinus Torvalds gayle.cardstatus = GAYLE_CS_WR|GAYLE_CS_DA; 1131da177e4SLinus Torvalds } 1148b169fa2SAdrian Bunk EXPORT_SYMBOL(pcmcia_write_enable); 1151da177e4SLinus Torvalds pcmcia_write_disable(void)1161da177e4SLinus Torvaldsvoid pcmcia_write_disable(void) 1171da177e4SLinus Torvalds { 1181da177e4SLinus Torvalds gayle.cardstatus = 0; 1191da177e4SLinus Torvalds } 1208b169fa2SAdrian Bunk EXPORT_SYMBOL(pcmcia_write_disable); 1218b169fa2SAdrian Bunk 122