162306a36Sopenharmony_ci/* 262306a36Sopenharmony_ci** asm-m68k/pcmcia.c -- Amiga Linux PCMCIA support 362306a36Sopenharmony_ci** most information was found by disassembling card.resource 462306a36Sopenharmony_ci** I'm still looking for an official doc ! 562306a36Sopenharmony_ci** 662306a36Sopenharmony_ci** Copyright 1997 by Alain Malek 762306a36Sopenharmony_ci** 862306a36Sopenharmony_ci** This file is subject to the terms and conditions of the GNU General Public 962306a36Sopenharmony_ci** License. See the file COPYING in the main directory of this archive 1062306a36Sopenharmony_ci** for more details. 1162306a36Sopenharmony_ci** 1262306a36Sopenharmony_ci** Created: 12/10/97 by Alain Malek 1362306a36Sopenharmony_ci*/ 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_ci#include <linux/types.h> 1662306a36Sopenharmony_ci#include <linux/jiffies.h> 1762306a36Sopenharmony_ci#include <linux/timer.h> 1862306a36Sopenharmony_ci#include <linux/module.h> 1962306a36Sopenharmony_ci 2062306a36Sopenharmony_ci#include <asm/amigayle.h> 2162306a36Sopenharmony_ci#include <asm/amipcmcia.h> 2262306a36Sopenharmony_ci 2362306a36Sopenharmony_ci/* gayle config byte for program voltage and access speed */ 2462306a36Sopenharmony_cistatic unsigned char cfg_byte = GAYLE_CFG_0V|GAYLE_CFG_150NS; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_civoid pcmcia_reset(void) 2762306a36Sopenharmony_ci{ 2862306a36Sopenharmony_ci unsigned long reset_start_time = jiffies; 2962306a36Sopenharmony_ci unsigned char b; 3062306a36Sopenharmony_ci 3162306a36Sopenharmony_ci gayle_reset = 0x00; 3262306a36Sopenharmony_ci while (time_before(jiffies, reset_start_time + 1*HZ/100)); 3362306a36Sopenharmony_ci b = gayle_reset; 3462306a36Sopenharmony_ci} 3562306a36Sopenharmony_ciEXPORT_SYMBOL(pcmcia_reset); 3662306a36Sopenharmony_ci 3762306a36Sopenharmony_ci 3862306a36Sopenharmony_ci/* copy a tuple, including tuple header. return nb bytes copied */ 3962306a36Sopenharmony_ci/* be careful as this may trigger a GAYLE_IRQ_WR interrupt ! */ 4062306a36Sopenharmony_ci 4162306a36Sopenharmony_ciint pcmcia_copy_tuple(unsigned char tuple_id, void *tuple, int max_len) 4262306a36Sopenharmony_ci{ 4362306a36Sopenharmony_ci unsigned char id, *dest; 4462306a36Sopenharmony_ci int cnt, pos, len; 4562306a36Sopenharmony_ci 4662306a36Sopenharmony_ci dest = tuple; 4762306a36Sopenharmony_ci pos = 0; 4862306a36Sopenharmony_ci 4962306a36Sopenharmony_ci id = gayle_attribute[pos]; 5062306a36Sopenharmony_ci 5162306a36Sopenharmony_ci while((id != CISTPL_END) && (pos < 0x10000)) { 5262306a36Sopenharmony_ci len = (int)gayle_attribute[pos+2] + 2; 5362306a36Sopenharmony_ci if (id == tuple_id) { 5462306a36Sopenharmony_ci len = (len > max_len)?max_len:len; 5562306a36Sopenharmony_ci for (cnt = 0; cnt < len; cnt++) { 5662306a36Sopenharmony_ci *dest++ = gayle_attribute[pos+(cnt<<1)]; 5762306a36Sopenharmony_ci } 5862306a36Sopenharmony_ci 5962306a36Sopenharmony_ci return len; 6062306a36Sopenharmony_ci } 6162306a36Sopenharmony_ci pos += len<<1; 6262306a36Sopenharmony_ci id = gayle_attribute[pos]; 6362306a36Sopenharmony_ci } 6462306a36Sopenharmony_ci 6562306a36Sopenharmony_ci return 0; 6662306a36Sopenharmony_ci} 6762306a36Sopenharmony_ciEXPORT_SYMBOL(pcmcia_copy_tuple); 6862306a36Sopenharmony_ci 6962306a36Sopenharmony_civoid pcmcia_program_voltage(int voltage) 7062306a36Sopenharmony_ci{ 7162306a36Sopenharmony_ci unsigned char v; 7262306a36Sopenharmony_ci 7362306a36Sopenharmony_ci switch (voltage) { 7462306a36Sopenharmony_ci case PCMCIA_0V: 7562306a36Sopenharmony_ci v = GAYLE_CFG_0V; 7662306a36Sopenharmony_ci break; 7762306a36Sopenharmony_ci case PCMCIA_5V: 7862306a36Sopenharmony_ci v = GAYLE_CFG_5V; 7962306a36Sopenharmony_ci break; 8062306a36Sopenharmony_ci case PCMCIA_12V: 8162306a36Sopenharmony_ci v = GAYLE_CFG_12V; 8262306a36Sopenharmony_ci break; 8362306a36Sopenharmony_ci default: 8462306a36Sopenharmony_ci v = GAYLE_CFG_0V; 8562306a36Sopenharmony_ci } 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci cfg_byte = (cfg_byte & 0xfc) | v; 8862306a36Sopenharmony_ci gayle.config = cfg_byte; 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_ci} 9162306a36Sopenharmony_ciEXPORT_SYMBOL(pcmcia_program_voltage); 9262306a36Sopenharmony_ci 9362306a36Sopenharmony_civoid pcmcia_access_speed(int speed) 9462306a36Sopenharmony_ci{ 9562306a36Sopenharmony_ci unsigned char s; 9662306a36Sopenharmony_ci 9762306a36Sopenharmony_ci if (speed <= PCMCIA_SPEED_100NS) 9862306a36Sopenharmony_ci s = GAYLE_CFG_100NS; 9962306a36Sopenharmony_ci else if (speed <= PCMCIA_SPEED_150NS) 10062306a36Sopenharmony_ci s = GAYLE_CFG_150NS; 10162306a36Sopenharmony_ci else if (speed <= PCMCIA_SPEED_250NS) 10262306a36Sopenharmony_ci s = GAYLE_CFG_250NS; 10362306a36Sopenharmony_ci else 10462306a36Sopenharmony_ci s = GAYLE_CFG_720NS; 10562306a36Sopenharmony_ci 10662306a36Sopenharmony_ci cfg_byte = (cfg_byte & 0xf3) | s; 10762306a36Sopenharmony_ci gayle.config = cfg_byte; 10862306a36Sopenharmony_ci} 10962306a36Sopenharmony_ciEXPORT_SYMBOL(pcmcia_access_speed); 11062306a36Sopenharmony_ci 11162306a36Sopenharmony_civoid pcmcia_write_enable(void) 11262306a36Sopenharmony_ci{ 11362306a36Sopenharmony_ci gayle.cardstatus = GAYLE_CS_WR|GAYLE_CS_DA; 11462306a36Sopenharmony_ci} 11562306a36Sopenharmony_ciEXPORT_SYMBOL(pcmcia_write_enable); 11662306a36Sopenharmony_ci 11762306a36Sopenharmony_civoid pcmcia_write_disable(void) 11862306a36Sopenharmony_ci{ 11962306a36Sopenharmony_ci gayle.cardstatus = 0; 12062306a36Sopenharmony_ci} 12162306a36Sopenharmony_ciEXPORT_SYMBOL(pcmcia_write_disable); 12262306a36Sopenharmony_ci 123