1 /* $Id: asuscom.c,v 1.2 1998/02/02 13:27:06 keil Exp $
3 * asuscom.c low level stuff for ASUSCOM NETWORK INC. ISDNLink cards
5 * Author Karsten Keil (keil@temic-ech.spacenet.de)
7 * Thanks to ASUSCOM NETWORK INC. Taiwan and Dynalink NL for informations
11 * Revision 1.2 1998/02/02 13:27:06 keil
17 #define __NO_VERSION__
23 extern const char *CardType
[];
25 const char *Asuscom_revision
= "$Revision: 1.2 $";
27 #define byteout(addr,val) outb(val,addr)
28 #define bytein(addr) inb(addr)
33 #define ASUS_CTRL_U7 3
34 #define ASUS_CTRL_POTS 5
36 /* CARD_ADR (Write) */
37 #define ASUS_RESET 0x80 /* Bit 7 Reset-Leitung */
40 readreg(unsigned int ale
, unsigned int adr
, u_char off
)
54 readfifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
* data
, int size
)
56 /* fifo read without cli because it's allready done */
59 insb(adr
, data
, size
);
64 writereg(unsigned int ale
, unsigned int adr
, u_char off
, u_char data
)
76 writefifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
* data
, int size
)
78 /* fifo write without cli because it's allready done */
80 outsb(adr
, data
, size
);
83 /* Interface functions */
86 ReadISAC(struct IsdnCardState
*cs
, u_char offset
)
88 return (readreg(cs
->hw
.asus
.adr
, cs
->hw
.asus
.isac
, offset
));
92 WriteISAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
94 writereg(cs
->hw
.asus
.adr
, cs
->hw
.asus
.isac
, offset
, value
);
98 ReadISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
100 readfifo(cs
->hw
.asus
.adr
, cs
->hw
.asus
.isac
, 0, data
, size
);
104 WriteISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
106 writefifo(cs
->hw
.asus
.adr
, cs
->hw
.asus
.isac
, 0, data
, size
);
110 ReadHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
)
112 return (readreg(cs
->hw
.asus
.adr
,
113 cs
->hw
.asus
.hscx
, offset
+ (hscx
? 0x40 : 0)));
117 WriteHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
, u_char value
)
119 writereg(cs
->hw
.asus
.adr
,
120 cs
->hw
.asus
.hscx
, offset
+ (hscx
? 0x40 : 0), value
);
124 * fast interrupt HSCX stuff goes here
127 #define READHSCX(cs, nr, reg) readreg(cs->hw.asus.adr, \
128 cs->hw.asus.hscx, reg + (nr ? 0x40 : 0))
129 #define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.asus.adr, \
130 cs->hw.asus.hscx, reg + (nr ? 0x40 : 0), data)
132 #define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.asus.adr, \
133 cs->hw.asus.hscx, (nr ? 0x40 : 0), ptr, cnt)
135 #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.asus.adr, \
136 cs->hw.asus.hscx, (nr ? 0x40 : 0), ptr, cnt)
138 #include "hscx_irq.c"
141 asuscom_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
143 struct IsdnCardState
*cs
= dev_id
;
144 u_char val
, stat
= 0;
147 printk(KERN_WARNING
"ISDNLink: Spurious interrupt!\n");
150 val
= readreg(cs
->hw
.asus
.adr
, cs
->hw
.asus
.hscx
, HSCX_ISTA
+ 0x40);
153 hscx_int_main(cs
, val
);
156 val
= readreg(cs
->hw
.asus
.adr
, cs
->hw
.asus
.isac
, ISAC_ISTA
);
159 isac_interrupt(cs
, val
);
162 val
= readreg(cs
->hw
.asus
.adr
, cs
->hw
.asus
.hscx
, HSCX_ISTA
+ 0x40);
164 if (cs
->debug
& L1_DEB_HSCX
)
165 debugl1(cs
, "HSCX IntStat after IntRoutine");
168 val
= readreg(cs
->hw
.asus
.adr
, cs
->hw
.asus
.isac
, ISAC_ISTA
);
170 if (cs
->debug
& L1_DEB_ISAC
)
171 debugl1(cs
, "ISAC IntStat after IntRoutine");
175 writereg(cs
->hw
.asus
.adr
, cs
->hw
.asus
.hscx
, HSCX_MASK
, 0xFF);
176 writereg(cs
->hw
.asus
.adr
, cs
->hw
.asus
.hscx
, HSCX_MASK
+ 0x40, 0xFF);
177 writereg(cs
->hw
.asus
.adr
, cs
->hw
.asus
.hscx
, HSCX_MASK
, 0x0);
178 writereg(cs
->hw
.asus
.adr
, cs
->hw
.asus
.hscx
, HSCX_MASK
+ 0x40, 0x0);
181 writereg(cs
->hw
.asus
.adr
, cs
->hw
.asus
.isac
, ISAC_MASK
, 0xFF);
182 writereg(cs
->hw
.asus
.adr
, cs
->hw
.asus
.isac
, ISAC_MASK
, 0x0);
187 release_io_asuscom(struct IsdnCardState
*cs
)
191 if (cs
->hw
.asus
.cfg_reg
)
192 release_region(cs
->hw
.asus
.cfg_reg
, bytecnt
);
196 reset_asuscom(struct IsdnCardState
*cs
)
200 byteout(cs
->hw
.asus
.adr
, ASUS_RESET
); /* Reset On */
203 current
->state
= TASK_INTERRUPTIBLE
;
205 byteout(cs
->hw
.asus
.adr
, 0); /* Reset Off */
206 current
->state
= TASK_INTERRUPTIBLE
;
208 restore_flags(flags
);
212 Asus_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
219 release_io_asuscom(cs
);
222 return(request_irq(cs
->irq
, &asuscom_interrupt
,
223 I4L_IRQ_FLAG
, "HiSax", cs
));
225 clear_pending_isac_ints(cs
);
226 clear_pending_hscx_ints(cs
);
237 setup_asuscom(struct IsdnCard
*card
))
240 struct IsdnCardState
*cs
= card
->cs
;
243 strcpy(tmp
, Asuscom_revision
);
244 printk(KERN_INFO
"HiSax: Asuscom ISDNLink driver Rev. %s\n", HiSax_getrev(tmp
));
245 if (cs
->typ
!= ISDN_CTYPE_ASUSCOM
)
249 cs
->hw
.asus
.cfg_reg
= card
->para
[1];
250 cs
->irq
= card
->para
[0];
251 cs
->hw
.asus
.adr
= cs
->hw
.asus
.cfg_reg
+ ASUS_ADR
;
252 cs
->hw
.asus
.isac
= cs
->hw
.asus
.cfg_reg
+ ASUS_ISAC
;
253 cs
->hw
.asus
.hscx
= cs
->hw
.asus
.cfg_reg
+ ASUS_HSCX
;
254 cs
->hw
.asus
.u7
= cs
->hw
.asus
.cfg_reg
+ ASUS_CTRL_U7
;
255 cs
->hw
.asus
.pots
= cs
->hw
.asus
.cfg_reg
+ ASUS_CTRL_POTS
;
257 if (check_region((cs
->hw
.asus
.cfg_reg
), bytecnt
)) {
259 "HiSax: %s config port %x-%x already in use\n",
262 cs
->hw
.asus
.cfg_reg
+ bytecnt
);
265 request_region(cs
->hw
.asus
.cfg_reg
, bytecnt
, "asuscom isdn");
269 "ISDNLink: defined at 0x%x IRQ %d\n",
272 printk(KERN_INFO
"ISDNLink: resetting card\n");
274 cs
->readisac
= &ReadISAC
;
275 cs
->writeisac
= &WriteISAC
;
276 cs
->readisacfifo
= &ReadISACfifo
;
277 cs
->writeisacfifo
= &WriteISACfifo
;
278 cs
->BC_Read_Reg
= &ReadHSCX
;
279 cs
->BC_Write_Reg
= &WriteHSCX
;
280 cs
->BC_Send_Data
= &hscx_fill_fifo
;
281 cs
->cardmsg
= &Asus_card_msg
;
282 ISACVersion(cs
, "ISDNLink:");
283 if (HscxVersion(cs
, "ISDNLink:")) {
285 "ISDNLink: wrong HSCX versions check IO address\n");
286 release_io_asuscom(cs
);