1 /* $Id: mic.c,v 1.9 2000/06/26 08:59:14 keil Exp $
3 * mic.c low level stuff for mic cards
7 * Author Stephan von Krawczynski <skraw@ithnet.com>
9 * This file is (c) under GNU PUBLIC LICENSE
13 #define __NO_VERSION__
19 extern const char *CardType
[];
21 const char *mic_revision
= "$Revision: 1.9 $";
23 #define byteout(addr,val) outb(val,addr)
24 #define bytein(addr) inb(addr)
30 /* CARD_ADR (Write) */
31 #define MIC_RESET 0x3 /* same as DOS driver */
34 readreg(unsigned int ale
, unsigned int adr
, u_char off
)
49 readfifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
* data
, int size
)
51 /* fifo read without cli because it's allready done */
54 insb(adr
, data
, size
);
59 writereg(unsigned int ale
, unsigned int adr
, u_char off
, u_char data
)
71 writefifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
* data
, int size
)
73 /* fifo write without cli because it's allready done */
75 outsb(adr
, data
, size
);
78 /* Interface functions */
81 ReadISAC(struct IsdnCardState
*cs
, u_char offset
)
83 return (readreg(cs
->hw
.mic
.adr
, cs
->hw
.mic
.isac
, offset
));
87 WriteISAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
89 writereg(cs
->hw
.mic
.adr
, cs
->hw
.mic
.isac
, offset
, value
);
93 ReadISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
95 readfifo(cs
->hw
.mic
.adr
, cs
->hw
.mic
.isac
, 0, data
, size
);
99 WriteISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
101 writefifo(cs
->hw
.mic
.adr
, cs
->hw
.mic
.isac
, 0, data
, size
);
105 ReadHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
)
107 return (readreg(cs
->hw
.mic
.adr
,
108 cs
->hw
.mic
.hscx
, offset
+ (hscx
? 0x40 : 0)));
112 WriteHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
, u_char value
)
114 writereg(cs
->hw
.mic
.adr
,
115 cs
->hw
.mic
.hscx
, offset
+ (hscx
? 0x40 : 0), value
);
119 * fast interrupt HSCX stuff goes here
122 #define READHSCX(cs, nr, reg) readreg(cs->hw.mic.adr, \
123 cs->hw.mic.hscx, reg + (nr ? 0x40 : 0))
124 #define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.mic.adr, \
125 cs->hw.mic.hscx, reg + (nr ? 0x40 : 0), data)
127 #define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.mic.adr, \
128 cs->hw.mic.hscx, (nr ? 0x40 : 0), ptr, cnt)
130 #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.mic.adr, \
131 cs->hw.mic.hscx, (nr ? 0x40 : 0), ptr, cnt)
133 #include "hscx_irq.c"
136 mic_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
138 struct IsdnCardState
*cs
= dev_id
;
142 printk(KERN_WARNING
"mic: Spurious interrupt!\n");
145 val
= readreg(cs
->hw
.mic
.adr
, cs
->hw
.mic
.hscx
, HSCX_ISTA
+ 0x40);
148 hscx_int_main(cs
, val
);
149 val
= readreg(cs
->hw
.mic
.adr
, cs
->hw
.mic
.isac
, ISAC_ISTA
);
152 isac_interrupt(cs
, val
);
153 val
= readreg(cs
->hw
.mic
.adr
, cs
->hw
.mic
.hscx
, HSCX_ISTA
+ 0x40);
155 if (cs
->debug
& L1_DEB_HSCX
)
156 debugl1(cs
, "HSCX IntStat after IntRoutine");
159 val
= readreg(cs
->hw
.mic
.adr
, cs
->hw
.mic
.isac
, ISAC_ISTA
);
161 if (cs
->debug
& L1_DEB_ISAC
)
162 debugl1(cs
, "ISAC IntStat after IntRoutine");
165 writereg(cs
->hw
.mic
.adr
, cs
->hw
.mic
.hscx
, HSCX_MASK
, 0xFF);
166 writereg(cs
->hw
.mic
.adr
, cs
->hw
.mic
.hscx
, HSCX_MASK
+ 0x40, 0xFF);
167 writereg(cs
->hw
.mic
.adr
, cs
->hw
.mic
.isac
, ISAC_MASK
, 0xFF);
168 writereg(cs
->hw
.mic
.adr
, cs
->hw
.mic
.isac
, ISAC_MASK
, 0x0);
169 writereg(cs
->hw
.mic
.adr
, cs
->hw
.mic
.hscx
, HSCX_MASK
, 0x0);
170 writereg(cs
->hw
.mic
.adr
, cs
->hw
.mic
.hscx
, HSCX_MASK
+ 0x40, 0x0);
174 release_io_mic(struct IsdnCardState
*cs
)
178 if (cs
->hw
.mic
.cfg_reg
)
179 release_region(cs
->hw
.mic
.cfg_reg
, bytecnt
);
183 mic_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
192 inithscx(cs
); /* /RTSA := ISAC RST */
202 setup_mic(struct IsdnCard
*card
))
205 struct IsdnCardState
*cs
= card
->cs
;
208 strcpy(tmp
, mic_revision
);
209 printk(KERN_INFO
"HiSax: mic driver Rev. %s\n", HiSax_getrev(tmp
));
210 if (cs
->typ
!= ISDN_CTYPE_MIC
)
214 cs
->hw
.mic
.cfg_reg
= card
->para
[1];
215 cs
->irq
= card
->para
[0];
216 cs
->hw
.mic
.adr
= cs
->hw
.mic
.cfg_reg
+ MIC_ADR
;
217 cs
->hw
.mic
.isac
= cs
->hw
.mic
.cfg_reg
+ MIC_ISAC
;
218 cs
->hw
.mic
.hscx
= cs
->hw
.mic
.cfg_reg
+ MIC_HSCX
;
220 if (check_region((cs
->hw
.mic
.cfg_reg
), bytecnt
)) {
222 "HiSax: %s config port %x-%x already in use\n",
225 cs
->hw
.mic
.cfg_reg
+ bytecnt
);
228 request_region(cs
->hw
.mic
.cfg_reg
, bytecnt
, "mic isdn");
232 "mic: defined at 0x%x IRQ %d\n",
235 cs
->readisac
= &ReadISAC
;
236 cs
->writeisac
= &WriteISAC
;
237 cs
->readisacfifo
= &ReadISACfifo
;
238 cs
->writeisacfifo
= &WriteISACfifo
;
239 cs
->BC_Read_Reg
= &ReadHSCX
;
240 cs
->BC_Write_Reg
= &WriteHSCX
;
241 cs
->BC_Send_Data
= &hscx_fill_fifo
;
242 cs
->cardmsg
= &mic_card_msg
;
243 cs
->irq_func
= &mic_interrupt
;
244 ISACVersion(cs
, "mic:");
245 if (HscxVersion(cs
, "mic:")) {
247 "mic: wrong HSCX versions check IO address\n");