1 /* $Id: saphir.c,v 1.10.2.4 2004/01/13 23:48:39 keil Exp $
3 * low level stuff for HST Saphir 1
6 * Copyright by Karsten Keil <keil@isdn4linux.de>
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
11 * Thanks to HST High Soft Tech GmbH
15 #include <linux/init.h>
21 extern const char *CardType
[];
22 static char *saphir_rev
= "$Revision: 1.10.2.4 $";
24 #define byteout(addr,val) outb(val,addr)
25 #define bytein(addr) inb(addr)
35 readreg(unsigned int ale
, unsigned int adr
, u_char off
)
45 readfifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
* data
, int size
)
48 insb(adr
, data
, size
);
53 writereg(unsigned int ale
, unsigned int adr
, u_char off
, u_char data
)
60 writefifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
* data
, int size
)
63 outsb(adr
, data
, size
);
66 /* Interface functions */
69 ReadISAC(struct IsdnCardState
*cs
, u_char offset
)
71 return (readreg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, offset
));
75 WriteISAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
77 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, offset
, value
);
81 ReadISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
83 readfifo(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, 0, data
, size
);
87 WriteISACfifo(struct IsdnCardState
*cs
, u_char
* data
, int size
)
89 writefifo(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, 0, data
, size
);
93 ReadHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
)
95 return (readreg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
,
96 offset
+ (hscx
? 0x40 : 0)));
100 WriteHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
, u_char value
)
102 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
,
103 offset
+ (hscx
? 0x40 : 0), value
);
106 #define READHSCX(cs, nr, reg) readreg(cs->hw.saphir.ale, \
107 cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0))
108 #define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.saphir.ale, \
109 cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0), data)
111 #define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.saphir.ale, \
112 cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt)
114 #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.saphir.ale, \
115 cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt)
117 #include "hscx_irq.c"
120 saphir_interrupt(int intno
, void *dev_id
, struct pt_regs
*regs
)
122 struct IsdnCardState
*cs
= dev_id
;
126 spin_lock_irqsave(&cs
->lock
, flags
);
127 val
= readreg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
, HSCX_ISTA
+ 0x40);
130 hscx_int_main(cs
, val
);
131 val
= readreg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, ISAC_ISTA
);
134 isac_interrupt(cs
, val
);
135 val
= readreg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
, HSCX_ISTA
+ 0x40);
137 if (cs
->debug
& L1_DEB_HSCX
)
138 debugl1(cs
, "HSCX IntStat after IntRoutine");
141 val
= readreg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, ISAC_ISTA
);
143 if (cs
->debug
& L1_DEB_ISAC
)
144 debugl1(cs
, "ISAC IntStat after IntRoutine");
148 if (cs
->hw
.saphir
.timer
.function
)
149 mod_timer(&cs
->hw
.saphir
.timer
, jiffies
+1*HZ
);
151 printk(KERN_WARNING
"saphir: Spurious timer!\n");
152 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
, HSCX_MASK
, 0xFF);
153 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
, HSCX_MASK
+ 0x40, 0xFF);
154 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, ISAC_MASK
, 0xFF);
155 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, ISAC_MASK
, 0);
156 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
, HSCX_MASK
, 0);
157 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
, HSCX_MASK
+ 0x40, 0);
158 spin_unlock_irqrestore(&cs
->lock
, flags
);
163 SaphirWatchDog(struct IsdnCardState
*cs
)
167 spin_lock_irqsave(&cs
->lock
, flags
);
168 /* 5 sec WatchDog, so read at least every 4 sec */
169 cs
->readisac(cs
, ISAC_RBCH
);
170 spin_unlock_irqrestore(&cs
->lock
, flags
);
171 mod_timer(&cs
->hw
.saphir
.timer
, jiffies
+1*HZ
);
175 release_io_saphir(struct IsdnCardState
*cs
)
177 byteout(cs
->hw
.saphir
.cfg_reg
+ IRQ_REG
, 0xff);
178 del_timer(&cs
->hw
.saphir
.timer
);
179 cs
->hw
.saphir
.timer
.function
= NULL
;
180 if (cs
->hw
.saphir
.cfg_reg
)
181 release_region(cs
->hw
.saphir
.cfg_reg
, 6);
185 saphir_reset(struct IsdnCardState
*cs
)
204 printk(KERN_WARNING
"HiSax: saphir wrong IRQ %d\n",
208 byteout(cs
->hw
.saphir
.cfg_reg
+ IRQ_REG
, irq_val
);
209 byteout(cs
->hw
.saphir
.cfg_reg
+ RESET_REG
, 1);
211 byteout(cs
->hw
.saphir
.cfg_reg
+ RESET_REG
, 0);
213 byteout(cs
->hw
.saphir
.cfg_reg
+ IRQ_REG
, irq_val
);
214 byteout(cs
->hw
.saphir
.cfg_reg
+ SPARE_REG
, 0x02);
219 saphir_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
225 spin_lock_irqsave(&cs
->lock
, flags
);
227 spin_unlock_irqrestore(&cs
->lock
, flags
);
230 release_io_saphir(cs
);
233 spin_lock_irqsave(&cs
->lock
, flags
);
235 spin_unlock_irqrestore(&cs
->lock
, flags
);
245 setup_saphir(struct IsdnCard
*card
)
247 struct IsdnCardState
*cs
= card
->cs
;
250 strcpy(tmp
, saphir_rev
);
251 printk(KERN_INFO
"HiSax: HST Saphir driver Rev. %s\n", HiSax_getrev(tmp
));
252 if (cs
->typ
!= ISDN_CTYPE_HSTSAPHIR
)
256 cs
->hw
.saphir
.cfg_reg
= card
->para
[1];
257 cs
->hw
.saphir
.isac
= card
->para
[1] + ISAC_DATA
;
258 cs
->hw
.saphir
.hscx
= card
->para
[1] + HSCX_DATA
;
259 cs
->hw
.saphir
.ale
= card
->para
[1] + ADDRESS_REG
;
260 cs
->irq
= card
->para
[0];
261 if (!request_region(cs
->hw
.saphir
.cfg_reg
, 6, "saphir")) {
263 "HiSax: %s config port %x-%x already in use\n",
265 cs
->hw
.saphir
.cfg_reg
,
266 cs
->hw
.saphir
.cfg_reg
+ 5);
270 printk(KERN_INFO
"HiSax: %s config irq:%d io:0x%X\n",
271 CardType
[cs
->typ
], cs
->irq
, cs
->hw
.saphir
.cfg_reg
);
274 cs
->hw
.saphir
.timer
.function
= (void *) SaphirWatchDog
;
275 cs
->hw
.saphir
.timer
.data
= (long) cs
;
276 init_timer(&cs
->hw
.saphir
.timer
);
277 cs
->hw
.saphir
.timer
.expires
= jiffies
+ 4*HZ
;
278 add_timer(&cs
->hw
.saphir
.timer
);
279 if (saphir_reset(cs
)) {
280 release_io_saphir(cs
);
283 cs
->readisac
= &ReadISAC
;
284 cs
->writeisac
= &WriteISAC
;
285 cs
->readisacfifo
= &ReadISACfifo
;
286 cs
->writeisacfifo
= &WriteISACfifo
;
287 cs
->BC_Read_Reg
= &ReadHSCX
;
288 cs
->BC_Write_Reg
= &WriteHSCX
;
289 cs
->BC_Send_Data
= &hscx_fill_fifo
;
290 cs
->cardmsg
= &saphir_card_msg
;
291 cs
->irq_func
= &saphir_interrupt
;
292 ISACVersion(cs
, "saphir:");
293 if (HscxVersion(cs
, "saphir:")) {
295 "saphir: wrong HSCX versions check IO address\n");
296 release_io_saphir(cs
);