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 timer_list
*t
)
164 struct IsdnCardState
*cs
= from_timer(cs
, t
, hw
.saphir
.timer
);
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
);
244 int setup_saphir(struct IsdnCard
*card
)
246 struct IsdnCardState
*cs
= card
->cs
;
249 strcpy(tmp
, saphir_rev
);
250 printk(KERN_INFO
"HiSax: HST Saphir driver Rev. %s\n", HiSax_getrev(tmp
));
251 if (cs
->typ
!= ISDN_CTYPE_HSTSAPHIR
)
255 cs
->hw
.saphir
.cfg_reg
= card
->para
[1];
256 cs
->hw
.saphir
.isac
= card
->para
[1] + ISAC_DATA
;
257 cs
->hw
.saphir
.hscx
= card
->para
[1] + HSCX_DATA
;
258 cs
->hw
.saphir
.ale
= card
->para
[1] + ADDRESS_REG
;
259 cs
->irq
= card
->para
[0];
260 if (!request_region(cs
->hw
.saphir
.cfg_reg
, 6, "saphir")) {
262 "HiSax: HST Saphir config port %x-%x already in use\n",
263 cs
->hw
.saphir
.cfg_reg
,
264 cs
->hw
.saphir
.cfg_reg
+ 5);
268 printk(KERN_INFO
"HiSax: HST Saphir config irq:%d io:0x%X\n",
269 cs
->irq
, cs
->hw
.saphir
.cfg_reg
);
272 timer_setup(&cs
->hw
.saphir
.timer
, SaphirWatchDog
, 0);
273 cs
->hw
.saphir
.timer
.expires
= jiffies
+ 4 * HZ
;
274 add_timer(&cs
->hw
.saphir
.timer
);
275 if (saphir_reset(cs
)) {
276 release_io_saphir(cs
);
279 cs
->readisac
= &ReadISAC
;
280 cs
->writeisac
= &WriteISAC
;
281 cs
->readisacfifo
= &ReadISACfifo
;
282 cs
->writeisacfifo
= &WriteISACfifo
;
283 cs
->BC_Read_Reg
= &ReadHSCX
;
284 cs
->BC_Write_Reg
= &WriteHSCX
;
285 cs
->BC_Send_Data
= &hscx_fill_fifo
;
286 cs
->cardmsg
= &saphir_card_msg
;
287 cs
->irq_func
= &saphir_interrupt
;
288 ISACVersion(cs
, "saphir:");
289 if (HscxVersion(cs
, "saphir:")) {
291 "saphir: wrong HSCX versions check IO address\n");
292 release_io_saphir(cs
);