Linux 2.1.127
[davej-history.git] / drivers / isdn / hisax / asuscom.c
blob6980a2888685c9d4fa5ef812dcae9a5026498e02
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
10 * $Log: asuscom.c,v $
11 * Revision 1.2 1998/02/02 13:27:06 keil
12 * New
17 #define __NO_VERSION__
18 #include "hisax.h"
19 #include "isac.h"
20 #include "hscx.h"
21 #include "isdnl1.h"
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)
30 #define ASUS_ISAC 0
31 #define ASUS_HSCX 1
32 #define ASUS_ADR 2
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 */
39 static inline u_char
40 readreg(unsigned int ale, unsigned int adr, u_char off)
42 register u_char ret;
43 long flags;
45 save_flags(flags);
46 cli();
47 byteout(ale, off);
48 ret = bytein(adr);
49 restore_flags(flags);
50 return (ret);
53 static inline void
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 */
58 byteout(ale, off);
59 insb(adr, data, size);
63 static inline void
64 writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
66 long flags;
68 save_flags(flags);
69 cli();
70 byteout(ale, off);
71 byteout(adr, data);
72 restore_flags(flags);
75 static inline void
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 */
79 byteout(ale, off);
80 outsb(adr, data, size);
83 /* Interface functions */
85 static u_char
86 ReadISAC(struct IsdnCardState *cs, u_char offset)
88 return (readreg(cs->hw.asus.adr, cs->hw.asus.isac, offset));
91 static void
92 WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
94 writereg(cs->hw.asus.adr, cs->hw.asus.isac, offset, value);
97 static void
98 ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
100 readfifo(cs->hw.asus.adr, cs->hw.asus.isac, 0, data, size);
103 static void
104 WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
106 writefifo(cs->hw.asus.adr, cs->hw.asus.isac, 0, data, size);
109 static u_char
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)));
116 static void
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"
140 static void
141 asuscom_interrupt(int intno, void *dev_id, struct pt_regs *regs)
143 struct IsdnCardState *cs = dev_id;
144 u_char val, stat = 0;
146 if (!cs) {
147 printk(KERN_WARNING "ISDNLink: Spurious interrupt!\n");
148 return;
150 val = readreg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_ISTA + 0x40);
151 Start_HSCX:
152 if (val) {
153 hscx_int_main(cs, val);
154 stat |= 1;
156 val = readreg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_ISTA);
157 Start_ISAC:
158 if (val) {
159 isac_interrupt(cs, val);
160 stat |= 2;
162 val = readreg(cs->hw.asus.adr, cs->hw.asus.hscx, HSCX_ISTA + 0x40);
163 if (val) {
164 if (cs->debug & L1_DEB_HSCX)
165 debugl1(cs, "HSCX IntStat after IntRoutine");
166 goto Start_HSCX;
168 val = readreg(cs->hw.asus.adr, cs->hw.asus.isac, ISAC_ISTA);
169 if (val) {
170 if (cs->debug & L1_DEB_ISAC)
171 debugl1(cs, "ISAC IntStat after IntRoutine");
172 goto Start_ISAC;
174 if (stat & 1) {
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);
180 if (stat & 2) {
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);
186 void
187 release_io_asuscom(struct IsdnCardState *cs)
189 int bytecnt = 8;
191 if (cs->hw.asus.cfg_reg)
192 release_region(cs->hw.asus.cfg_reg, bytecnt);
195 static void
196 reset_asuscom(struct IsdnCardState *cs)
198 long flags;
200 byteout(cs->hw.asus.adr, ASUS_RESET); /* Reset On */
201 save_flags(flags);
202 sti();
203 current->state = TASK_INTERRUPTIBLE;
204 schedule_timeout(1);
205 byteout(cs->hw.asus.adr, 0); /* Reset Off */
206 current->state = TASK_INTERRUPTIBLE;
207 schedule_timeout(1);
208 restore_flags(flags);
211 static int
212 Asus_card_msg(struct IsdnCardState *cs, int mt, void *arg)
214 switch (mt) {
215 case CARD_RESET:
216 reset_asuscom(cs);
217 return(0);
218 case CARD_RELEASE:
219 release_io_asuscom(cs);
220 return(0);
221 case CARD_SETIRQ:
222 return(request_irq(cs->irq, &asuscom_interrupt,
223 I4L_IRQ_FLAG, "HiSax", cs));
224 case CARD_INIT:
225 clear_pending_isac_ints(cs);
226 clear_pending_hscx_ints(cs);
227 initisac(cs);
228 inithscx(cs);
229 return(0);
230 case CARD_TEST:
231 return(0);
233 return(0);
236 __initfunc(int
237 setup_asuscom(struct IsdnCard *card))
239 int bytecnt;
240 struct IsdnCardState *cs = card->cs;
241 char tmp[64];
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)
246 return (0);
248 bytecnt = 8;
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)) {
258 printk(KERN_WARNING
259 "HiSax: %s config port %x-%x already in use\n",
260 CardType[card->typ],
261 cs->hw.asus.cfg_reg,
262 cs->hw.asus.cfg_reg + bytecnt);
263 return (0);
264 } else {
265 request_region(cs->hw.asus.cfg_reg, bytecnt, "asuscom isdn");
268 printk(KERN_INFO
269 "ISDNLink: defined at 0x%x IRQ %d\n",
270 cs->hw.asus.cfg_reg,
271 cs->irq);
272 printk(KERN_INFO "ISDNLink: resetting card\n");
273 reset_asuscom(cs);
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:")) {
284 printk(KERN_WARNING
285 "ISDNLink: wrong HSCX versions check IO address\n");
286 release_io_asuscom(cs);
287 return (0);
289 return (1);