xref: /OK3568_Linux_fs/kernel/arch/m68k/amiga/pcmcia.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
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*4882a593Smuzhiyun void 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*4882a593Smuzhiyun int 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*4882a593Smuzhiyun void 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*4882a593Smuzhiyun void 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*4882a593Smuzhiyun void 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*4882a593Smuzhiyun void pcmcia_write_disable(void)
118*4882a593Smuzhiyun {
119*4882a593Smuzhiyun 	gayle.cardstatus = 0;
120*4882a593Smuzhiyun }
121*4882a593Smuzhiyun EXPORT_SYMBOL(pcmcia_write_disable);
122*4882a593Smuzhiyun 
123