18c2ecf20Sopenharmony_ci/*
28c2ecf20Sopenharmony_ci** asm-m68k/pcmcia.c -- Amiga Linux PCMCIA support
38c2ecf20Sopenharmony_ci**                      most information was found by disassembling card.resource
48c2ecf20Sopenharmony_ci**                      I'm still looking for an official doc !
58c2ecf20Sopenharmony_ci**
68c2ecf20Sopenharmony_ci** Copyright 1997 by Alain Malek
78c2ecf20Sopenharmony_ci**
88c2ecf20Sopenharmony_ci** This file is subject to the terms and conditions of the GNU General Public
98c2ecf20Sopenharmony_ci** License.  See the file COPYING in the main directory of this archive
108c2ecf20Sopenharmony_ci** for more details.
118c2ecf20Sopenharmony_ci**
128c2ecf20Sopenharmony_ci** Created: 12/10/97 by Alain Malek
138c2ecf20Sopenharmony_ci*/
148c2ecf20Sopenharmony_ci
158c2ecf20Sopenharmony_ci#include <linux/types.h>
168c2ecf20Sopenharmony_ci#include <linux/jiffies.h>
178c2ecf20Sopenharmony_ci#include <linux/timer.h>
188c2ecf20Sopenharmony_ci#include <linux/module.h>
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci#include <asm/amigayle.h>
218c2ecf20Sopenharmony_ci#include <asm/amipcmcia.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/* gayle config byte for program voltage and access speed */
248c2ecf20Sopenharmony_cistatic unsigned char cfg_byte = GAYLE_CFG_0V|GAYLE_CFG_150NS;
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_civoid pcmcia_reset(void)
278c2ecf20Sopenharmony_ci{
288c2ecf20Sopenharmony_ci	unsigned long reset_start_time = jiffies;
298c2ecf20Sopenharmony_ci	unsigned char b;
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_ci	gayle_reset = 0x00;
328c2ecf20Sopenharmony_ci	while (time_before(jiffies, reset_start_time + 1*HZ/100));
338c2ecf20Sopenharmony_ci	b = gayle_reset;
348c2ecf20Sopenharmony_ci}
358c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pcmcia_reset);
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci
388c2ecf20Sopenharmony_ci/* copy a tuple, including tuple header. return nb bytes copied */
398c2ecf20Sopenharmony_ci/* be careful as this may trigger a GAYLE_IRQ_WR interrupt ! */
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ciint pcmcia_copy_tuple(unsigned char tuple_id, void *tuple, int max_len)
428c2ecf20Sopenharmony_ci{
438c2ecf20Sopenharmony_ci	unsigned char id, *dest;
448c2ecf20Sopenharmony_ci	int cnt, pos, len;
458c2ecf20Sopenharmony_ci
468c2ecf20Sopenharmony_ci	dest = tuple;
478c2ecf20Sopenharmony_ci	pos = 0;
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	id = gayle_attribute[pos];
508c2ecf20Sopenharmony_ci
518c2ecf20Sopenharmony_ci	while((id != CISTPL_END) && (pos < 0x10000)) {
528c2ecf20Sopenharmony_ci		len = (int)gayle_attribute[pos+2] + 2;
538c2ecf20Sopenharmony_ci		if (id == tuple_id) {
548c2ecf20Sopenharmony_ci			len = (len > max_len)?max_len:len;
558c2ecf20Sopenharmony_ci			for (cnt = 0; cnt < len; cnt++) {
568c2ecf20Sopenharmony_ci				*dest++ = gayle_attribute[pos+(cnt<<1)];
578c2ecf20Sopenharmony_ci			}
588c2ecf20Sopenharmony_ci
598c2ecf20Sopenharmony_ci			return len;
608c2ecf20Sopenharmony_ci		}
618c2ecf20Sopenharmony_ci		pos += len<<1;
628c2ecf20Sopenharmony_ci		id = gayle_attribute[pos];
638c2ecf20Sopenharmony_ci	}
648c2ecf20Sopenharmony_ci
658c2ecf20Sopenharmony_ci	return 0;
668c2ecf20Sopenharmony_ci}
678c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pcmcia_copy_tuple);
688c2ecf20Sopenharmony_ci
698c2ecf20Sopenharmony_civoid pcmcia_program_voltage(int voltage)
708c2ecf20Sopenharmony_ci{
718c2ecf20Sopenharmony_ci	unsigned char v;
728c2ecf20Sopenharmony_ci
738c2ecf20Sopenharmony_ci	switch (voltage) {
748c2ecf20Sopenharmony_ci	case PCMCIA_0V:
758c2ecf20Sopenharmony_ci		v = GAYLE_CFG_0V;
768c2ecf20Sopenharmony_ci		break;
778c2ecf20Sopenharmony_ci	case PCMCIA_5V:
788c2ecf20Sopenharmony_ci		v = GAYLE_CFG_5V;
798c2ecf20Sopenharmony_ci		break;
808c2ecf20Sopenharmony_ci	case PCMCIA_12V:
818c2ecf20Sopenharmony_ci		v = GAYLE_CFG_12V;
828c2ecf20Sopenharmony_ci		break;
838c2ecf20Sopenharmony_ci	default:
848c2ecf20Sopenharmony_ci		v = GAYLE_CFG_0V;
858c2ecf20Sopenharmony_ci	}
868c2ecf20Sopenharmony_ci
878c2ecf20Sopenharmony_ci	cfg_byte = (cfg_byte & 0xfc) | v;
888c2ecf20Sopenharmony_ci	gayle.config = cfg_byte;
898c2ecf20Sopenharmony_ci
908c2ecf20Sopenharmony_ci}
918c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pcmcia_program_voltage);
928c2ecf20Sopenharmony_ci
938c2ecf20Sopenharmony_civoid pcmcia_access_speed(int speed)
948c2ecf20Sopenharmony_ci{
958c2ecf20Sopenharmony_ci	unsigned char s;
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci	if (speed <= PCMCIA_SPEED_100NS)
988c2ecf20Sopenharmony_ci		s = GAYLE_CFG_100NS;
998c2ecf20Sopenharmony_ci	else if (speed <= PCMCIA_SPEED_150NS)
1008c2ecf20Sopenharmony_ci		s = GAYLE_CFG_150NS;
1018c2ecf20Sopenharmony_ci	else if (speed <= PCMCIA_SPEED_250NS)
1028c2ecf20Sopenharmony_ci		s = GAYLE_CFG_250NS;
1038c2ecf20Sopenharmony_ci	else
1048c2ecf20Sopenharmony_ci		s = GAYLE_CFG_720NS;
1058c2ecf20Sopenharmony_ci
1068c2ecf20Sopenharmony_ci	cfg_byte = (cfg_byte & 0xf3) | s;
1078c2ecf20Sopenharmony_ci	gayle.config = cfg_byte;
1088c2ecf20Sopenharmony_ci}
1098c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pcmcia_access_speed);
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_civoid pcmcia_write_enable(void)
1128c2ecf20Sopenharmony_ci{
1138c2ecf20Sopenharmony_ci	gayle.cardstatus = GAYLE_CS_WR|GAYLE_CS_DA;
1148c2ecf20Sopenharmony_ci}
1158c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pcmcia_write_enable);
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_civoid pcmcia_write_disable(void)
1188c2ecf20Sopenharmony_ci{
1198c2ecf20Sopenharmony_ci	gayle.cardstatus = 0;
1208c2ecf20Sopenharmony_ci}
1218c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pcmcia_write_disable);
1228c2ecf20Sopenharmony_ci
123