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 static char *saphir_rev
= "$Revision: 1.10.2.4 $";
23 #define byteout(addr, val) outb(val, addr)
24 #define bytein(addr) inb(addr)
34 readreg(unsigned int ale
, unsigned int adr
, u_char off
)
44 readfifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
*data
, int size
)
47 insb(adr
, data
, size
);
52 writereg(unsigned int ale
, unsigned int adr
, u_char off
, u_char data
)
59 writefifo(unsigned int ale
, unsigned int adr
, u_char off
, u_char
*data
, int size
)
62 outsb(adr
, data
, size
);
65 /* Interface functions */
68 ReadISAC(struct IsdnCardState
*cs
, u_char offset
)
70 return (readreg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, offset
));
74 WriteISAC(struct IsdnCardState
*cs
, u_char offset
, u_char value
)
76 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, offset
, value
);
80 ReadISACfifo(struct IsdnCardState
*cs
, u_char
*data
, int size
)
82 readfifo(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, 0, data
, size
);
86 WriteISACfifo(struct IsdnCardState
*cs
, u_char
*data
, int size
)
88 writefifo(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, 0, data
, size
);
92 ReadHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
)
94 return (readreg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
,
95 offset
+ (hscx
? 0x40 : 0)));
99 WriteHSCX(struct IsdnCardState
*cs
, int hscx
, u_char offset
, u_char value
)
101 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
,
102 offset
+ (hscx
? 0x40 : 0), value
);
105 #define READHSCX(cs, nr, reg) readreg(cs->hw.saphir.ale, \
106 cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0))
107 #define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.saphir.ale, \
108 cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0), data)
110 #define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.saphir.ale, \
111 cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt)
113 #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.saphir.ale, \
114 cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt)
116 #include "hscx_irq.c"
119 saphir_interrupt(int intno
, void *dev_id
)
121 struct IsdnCardState
*cs
= dev_id
;
125 spin_lock_irqsave(&cs
->lock
, flags
);
126 val
= readreg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
, HSCX_ISTA
+ 0x40);
129 hscx_int_main(cs
, val
);
130 val
= readreg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, ISAC_ISTA
);
133 isac_interrupt(cs
, val
);
134 val
= readreg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
, HSCX_ISTA
+ 0x40);
136 if (cs
->debug
& L1_DEB_HSCX
)
137 debugl1(cs
, "HSCX IntStat after IntRoutine");
140 val
= readreg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, ISAC_ISTA
);
142 if (cs
->debug
& L1_DEB_ISAC
)
143 debugl1(cs
, "ISAC IntStat after IntRoutine");
147 if (cs
->hw
.saphir
.timer
.function
)
148 mod_timer(&cs
->hw
.saphir
.timer
, jiffies
+ 1 * HZ
);
150 printk(KERN_WARNING
"saphir: Spurious timer!\n");
151 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
, HSCX_MASK
, 0xFF);
152 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
, HSCX_MASK
+ 0x40, 0xFF);
153 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, ISAC_MASK
, 0xFF);
154 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.isac
, ISAC_MASK
, 0);
155 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
, HSCX_MASK
, 0);
156 writereg(cs
->hw
.saphir
.ale
, cs
->hw
.saphir
.hscx
, HSCX_MASK
+ 0x40, 0);
157 spin_unlock_irqrestore(&cs
->lock
, flags
);
162 SaphirWatchDog(struct IsdnCardState
*cs
)
166 spin_lock_irqsave(&cs
->lock
, flags
);
167 /* 5 sec WatchDog, so read at least every 4 sec */
168 cs
->readisac(cs
, ISAC_RBCH
);
169 spin_unlock_irqrestore(&cs
->lock
, flags
);
170 mod_timer(&cs
->hw
.saphir
.timer
, jiffies
+ 1 * HZ
);
174 release_io_saphir(struct IsdnCardState
*cs
)
176 byteout(cs
->hw
.saphir
.cfg_reg
+ IRQ_REG
, 0xff);
177 del_timer(&cs
->hw
.saphir
.timer
);
178 cs
->hw
.saphir
.timer
.function
= NULL
;
179 if (cs
->hw
.saphir
.cfg_reg
)
180 release_region(cs
->hw
.saphir
.cfg_reg
, 6);
184 saphir_reset(struct IsdnCardState
*cs
)
203 printk(KERN_WARNING
"HiSax: saphir wrong IRQ %d\n",
207 byteout(cs
->hw
.saphir
.cfg_reg
+ IRQ_REG
, irq_val
);
208 byteout(cs
->hw
.saphir
.cfg_reg
+ RESET_REG
, 1);
210 byteout(cs
->hw
.saphir
.cfg_reg
+ RESET_REG
, 0);
212 byteout(cs
->hw
.saphir
.cfg_reg
+ IRQ_REG
, irq_val
);
213 byteout(cs
->hw
.saphir
.cfg_reg
+ SPARE_REG
, 0x02);
218 saphir_card_msg(struct IsdnCardState
*cs
, int mt
, void *arg
)
224 spin_lock_irqsave(&cs
->lock
, flags
);
226 spin_unlock_irqrestore(&cs
->lock
, flags
);
229 release_io_saphir(cs
);
232 spin_lock_irqsave(&cs
->lock
, flags
);
234 spin_unlock_irqrestore(&cs
->lock
, flags
);
243 int setup_saphir(struct IsdnCard
*card
)
245 struct IsdnCardState
*cs
= card
->cs
;
248 strcpy(tmp
, saphir_rev
);
249 printk(KERN_INFO
"HiSax: HST Saphir driver Rev. %s\n", HiSax_getrev(tmp
));
250 if (cs
->typ
!= ISDN_CTYPE_HSTSAPHIR
)
254 cs
->hw
.saphir
.cfg_reg
= card
->para
[1];
255 cs
->hw
.saphir
.isac
= card
->para
[1] + ISAC_DATA
;
256 cs
->hw
.saphir
.hscx
= card
->para
[1] + HSCX_DATA
;
257 cs
->hw
.saphir
.ale
= card
->para
[1] + ADDRESS_REG
;
258 cs
->irq
= card
->para
[0];
259 if (!request_region(cs
->hw
.saphir
.cfg_reg
, 6, "saphir")) {
261 "HiSax: HST Saphir config port %x-%x already in use\n",
262 cs
->hw
.saphir
.cfg_reg
,
263 cs
->hw
.saphir
.cfg_reg
+ 5);
267 printk(KERN_INFO
"HiSax: HST Saphir config irq:%d io:0x%X\n",
268 cs
->irq
, cs
->hw
.saphir
.cfg_reg
);
271 cs
->hw
.saphir
.timer
.function
= (void *) SaphirWatchDog
;
272 cs
->hw
.saphir
.timer
.data
= (long) cs
;
273 init_timer(&cs
->hw
.saphir
.timer
);
274 cs
->hw
.saphir
.timer
.expires
= jiffies
+ 4 * HZ
;
275 add_timer(&cs
->hw
.saphir
.timer
);
276 if (saphir_reset(cs
)) {
277 release_io_saphir(cs
);
280 cs
->readisac
= &ReadISAC
;
281 cs
->writeisac
= &WriteISAC
;
282 cs
->readisacfifo
= &ReadISACfifo
;
283 cs
->writeisacfifo
= &WriteISACfifo
;
284 cs
->BC_Read_Reg
= &ReadHSCX
;
285 cs
->BC_Write_Reg
= &WriteHSCX
;
286 cs
->BC_Send_Data
= &hscx_fill_fifo
;
287 cs
->cardmsg
= &saphir_card_msg
;
288 cs
->irq_func
= &saphir_interrupt
;
289 ISACVersion(cs
, "saphir:");
290 if (HscxVersion(cs
, "saphir:")) {
292 "saphir: wrong HSCX versions check IO address\n");
293 release_io_saphir(cs
);