revert between 56095 -> 55830 in arch
[AROS.git] / arch / m68k-amiga / card / lowlevel.c
blobbd62284897368397fc099a59eb3570c3b1f82167
1 /*
2 Copyright © 1995-2011, The AROS Development Team. All rights reserved.
3 $Id$
5 Desc:
6 Lang: English
7 */
9 #include <exec/types.h>
10 #include <proto/exec.h>
11 #include <proto/graphics.h>
12 #include <hardware/custom.h>
14 #include "card_intern.h"
16 #define INTDEBUG(x) ;
18 /* Card Change Detect interrupt */
20 AROS_INTH1(card_level6, struct CardResource *, CardResource)
22 AROS_INTFUNC_INIT
24 volatile struct GayleIO *gio = (struct GayleIO*)GAYLE_BASE;
25 UBYTE intreq, intena;
27 intreq = gio->intreq;
28 if (!(intreq & GAYLE_IRQ_CCDET) )
29 return 0; /* not ours */
30 intena = gio->intena;
31 gio->intreq = ~GAYLE_IRQ_CCDET;
32 if (!(intena & GAYLE_IRQ_CCDET))
33 return 0; /* not ours either */
34 if (CardResource->disabled) {
35 pcmcia_reset(CardResource);
36 return 0; /* huh? shouldn't happen */
39 CardResource->disabled = TRUE;
40 pcmcia_reset(CardResource);
42 Signal(CardResource->task, CardResource->signalmask);
44 INTDEBUG(bug("PCMCIA Card Change Detect interrupt\n"));
46 return 1;
48 AROS_INTFUNC_EXIT
51 /* All other PCMCIA related interrupts */
53 #define INTMASK (GAYLE_IRQ_BVD1 | GAYLE_IRQ_BVD2 | GAYLE_IRQ_WR | GAYLE_IRQ_BSY)
54 #define NOINTMASK (GAYLE_IRQ_IDE | GAYLE_IRQ_CCDET)
56 AROS_INTH1(card_level2, struct CardResource *, CardResource)
58 AROS_INTFUNC_INIT
60 struct CardHandle *cah = CardResource->ownedcard;
61 volatile struct GayleIO *gio = (struct GayleIO*)GAYLE_BASE;
62 UBYTE intreq, intena, status;
63 BOOL poststatus = FALSE;
65 intreq = gio->intreq & INTMASK;
66 if (!intreq)
67 return 0; /* not ours */
68 status = ((intreq ^ INTMASK) & INTMASK) | NOINTMASK | CardResource->resetberr;
69 intena = gio->intena;
71 INTDEBUG(bug("%02x %02x\n", intena, intreq));
73 if (!(intena & intreq)) {
74 gio->intreq = status;
75 return 0; /* not ours either */
78 if (CardResource->disabled) {
79 gio->intreq = status;
80 pcmcia_reset(CardResource);
81 return 0; /* huh? shouldn't happen */
83 intreq &= intena;
85 status = intreq;
86 if (cah && !CardResource->removed && cah->cah_CardStatus) {
87 if (cah->cah_CardFlags & CARDF_POSTSTATUS)
88 poststatus = TRUE;
89 INTDEBUG(bug("cah_CardStatus(%d,%x,%x)\n",
90 intreq,
91 cah->cah_CardStatus->is_Data,
92 cah->cah_CardStatus->is_Code));
93 status = AROS_CARDC(cah->cah_CardStatus->is_Code, cah->cah_CardStatus->is_Data, status);
94 INTDEBUG(bug("returned=%d\n", status));
96 if (status) {
97 status = (status ^ INTMASK) & INTMASK;
98 gio->intreq = status | NOINTMASK | CardResource->resetberr;
100 if (poststatus) {
101 INTDEBUG(bug("poststatus\n"));
102 AROS_CARDC(cah->cah_CardStatus->is_Code, cah->cah_CardStatus->is_Data, 0);
103 INTDEBUG(bug("returned\n"));
106 INTDEBUG(bug("exit\n"));
108 return 1;
110 AROS_INTFUNC_EXIT
113 void pcmcia_reset(struct CardResource *CardResource)
115 volatile struct GayleIO *gio = (struct GayleIO*)GAYLE_BASE;
117 /* Reset PCMCIA configuration, disable interrupts */
118 gio->config = 0;
119 gio->status = 0;
120 /* Disable all PCMCIA interrupts */
121 gio->intena &= ~(GAYLE_INT_CCDET | GAYLE_INT_BVD1 | GAYLE_INT_BVD2 | GAYLE_INT_WR | GAYLE_INT_BSY);
122 pcmcia_clear_requests(CardResource);
125 void pcmcia_clear_requests(struct CardResource *CardResource)
127 volatile struct GayleIO *gio = (struct GayleIO*)GAYLE_BASE;
129 /* Clear all interrupt requests except IDE interrupt */
130 gio->intreq = GAYLE_IRQ_IDE | CardResource->resetberr;
133 void pcmcia_enable_interrupts(void)
135 volatile struct GayleIO *gio = (struct GayleIO*)GAYLE_BASE;
137 /* Enable all interrupts except BVD2 */
138 gio->intena |= GAYLE_INT_CCDET | GAYLE_INT_BVD1 | GAYLE_INT_WR | GAYLE_INT_BSY;
141 BOOL pcmcia_havecard(void)
143 volatile struct GayleIO *gio = (struct GayleIO*)GAYLE_BASE;
145 return gio->status & GAYLE_CS_CCDET;
148 void pcmcia_disable(void)
150 volatile struct GayleIO *gio = (struct GayleIO*)GAYLE_BASE;
152 gio->status = GAYLE_CS_DIS;
155 void pcmcia_enable(void)
157 volatile struct GayleIO *gio = (struct GayleIO*)GAYLE_BASE;
159 gio->status = 0;
162 /* ugly busy wait */
163 static void waitframe(UBYTE frames)
165 volatile struct Custom *custom = (struct Custom*)0xdff000;
166 UWORD vpos = 0;
168 while (frames != 0) {
169 while (vpos < 128)
170 vpos = custom->vhposr >> 8;
171 while (vpos >= 128)
172 vpos = custom->vhposr >> 8;
173 frames--;
177 void pcmcia_cardreset(struct CardResource *CardResource)
179 volatile struct GayleIO *gio = (struct GayleIO*)GAYLE_BASE;
180 UBYTE x, rb, intena;
182 Disable();
183 rb = CardResource->resetberr;
184 CardResource->resetberr = GAYLE_IRQ_CARD_RESET_MASK;
185 intena = gio->intena;
186 gio->intena = 0;
187 gio->intreq = GAYLE_IRQ_IDE | GAYLE_IRQ_CARD_RESET_MASK;
188 Enable();
190 waitframe(10);
192 Disable();
193 CardResource->resetberr = rb;
194 x = GAYLE_IRQ_IDE | CardResource->resetberr;
195 gio->intreq = x;
196 Enable();
198 waitframe(10);
200 gio->intena = intena;
202 CARDDEBUG(bug("PCMCIA card reset %02x\n", x));