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