1 /* $Id: saphir.c,v 1.1.1.1 2005/04/11 02:50:23 jack 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 #define __NO_VERSION__
16 #include <linux/init.h>
22 extern const char *CardType[];
23 static char *saphir_rev = "$Revision: 1.1.1.1 $";
25 #define byteout(addr,val) outb(val,addr)
26 #define bytein(addr) inb(addr)
36 readreg(unsigned int ale, unsigned int adr, u_char off)
50 readfifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
52 /* fifo read without cli because it's allready done */
55 insb(adr, data, size);
60 writereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
72 writefifo(unsigned int ale, unsigned int adr, u_char off, u_char * data, int size)
74 /* fifo write without cli because it's allready done */
76 outsb(adr, data, size);
79 /* Interface functions */
82 ReadISAC(struct IsdnCardState *cs, u_char offset)
84 return (readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, offset));
88 WriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
90 writereg(cs->hw.saphir.ale, cs->hw.saphir.isac, offset, value);
94 ReadISACfifo(struct IsdnCardState *cs, u_char * data, int size)
96 readfifo(cs->hw.saphir.ale, cs->hw.saphir.isac, 0, data, size);
100 WriteISACfifo(struct IsdnCardState *cs, u_char * data, int size)
102 writefifo(cs->hw.saphir.ale, cs->hw.saphir.isac, 0, data, size);
106 ReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
108 return (readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx,
109 offset + (hscx ? 0x40 : 0)));
113 WriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
115 writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx,
116 offset + (hscx ? 0x40 : 0), value);
119 #define READHSCX(cs, nr, reg) readreg(cs->hw.saphir.ale, \
120 cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0))
121 #define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.saphir.ale, \
122 cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0), data)
124 #define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.saphir.ale, \
125 cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt)
127 #define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.saphir.ale, \
128 cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt)
130 #include "hscx_irq.c"
133 saphir_interrupt(int intno, void *dev_id, struct pt_regs *regs)
135 struct IsdnCardState *cs = dev_id;
139 printk(KERN_WARNING "saphir: Spurious interrupt!\n");
142 val = readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_ISTA + 0x40);
145 hscx_int_main(cs, val);
146 val = readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_ISTA);
149 isac_interrupt(cs, val);
150 val = readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_ISTA + 0x40);
152 if (cs->debug & L1_DEB_HSCX)
153 debugl1(cs, "HSCX IntStat after IntRoutine");
156 val = readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_ISTA);
158 if (cs->debug & L1_DEB_ISAC)
159 debugl1(cs, "ISAC IntStat after IntRoutine");
163 if (cs->hw.saphir.timer.function)
164 mod_timer(&cs->hw.saphir.timer, jiffies+1*HZ);
166 printk(KERN_WARNING "saphir: Spurious timer!\n");
167 writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK, 0xFF);
168 writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK + 0x40, 0xFF);
169 writereg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_MASK, 0xFF);
170 writereg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_MASK, 0);
171 writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK, 0);
172 writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK + 0x40, 0);
176 SaphirWatchDog(struct IsdnCardState *cs)
178 /* 5 sec WatchDog, so read at least every 4 sec */
179 cs->readisac(cs, ISAC_RBCH);
180 mod_timer(&cs->hw.saphir.timer, jiffies+1*HZ);
184 release_io_saphir(struct IsdnCardState *cs)
190 byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff);
191 del_timer(&cs->hw.saphir.timer);
192 cs->hw.saphir.timer.function = NULL;
193 restore_flags(flags);
194 if (cs->hw.saphir.cfg_reg)
195 release_region(cs->hw.saphir.cfg_reg, 6);
199 saphir_reset(struct IsdnCardState *cs)
219 printk(KERN_WARNING "HiSax: saphir wrong IRQ %d\n",
223 byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val);
226 byteout(cs->hw.saphir.cfg_reg + RESET_REG, 1);
227 set_current_state(TASK_UNINTERRUPTIBLE);
228 schedule_timeout((30*HZ)/1000); /* Timeout 30ms */
229 byteout(cs->hw.saphir.cfg_reg + RESET_REG, 0);
230 set_current_state(TASK_UNINTERRUPTIBLE);
231 schedule_timeout((30*HZ)/1000); /* Timeout 30ms */
232 restore_flags(flags);
233 byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val);
234 byteout(cs->hw.saphir.cfg_reg + SPARE_REG, 0x02);
239 saphir_card_msg(struct IsdnCardState *cs, int mt, void *arg)
246 release_io_saphir(cs);
259 setup_saphir(struct IsdnCard *card)
261 struct IsdnCardState *cs = card->cs;
264 strcpy(tmp, saphir_rev);
265 printk(KERN_INFO "HiSax: HST Saphir driver Rev. %s\n", HiSax_getrev(tmp));
266 if (cs->typ != ISDN_CTYPE_HSTSAPHIR)
270 cs->hw.saphir.cfg_reg = card->para[1];
271 cs->hw.saphir.isac = card->para[1] + ISAC_DATA;
272 cs->hw.saphir.hscx = card->para[1] + HSCX_DATA;
273 cs->hw.saphir.ale = card->para[1] + ADDRESS_REG;
274 cs->irq = card->para[0];
275 if (check_region((cs->hw.saphir.cfg_reg), 6)) {
277 "HiSax: %s config port %x-%x already in use\n",
279 cs->hw.saphir.cfg_reg,
280 cs->hw.saphir.cfg_reg + 5);
283 request_region(cs->hw.saphir.cfg_reg,6, "saphir");
286 "HiSax: %s config irq:%d io:0x%X\n",
287 CardType[cs->typ], cs->irq,
288 cs->hw.saphir.cfg_reg);
290 cs->hw.saphir.timer.function = (void *) SaphirWatchDog;
291 cs->hw.saphir.timer.data = (long) cs;
292 init_timer(&cs->hw.saphir.timer);
293 cs->hw.saphir.timer.expires = jiffies + 4*HZ;
294 add_timer(&cs->hw.saphir.timer);
295 if (saphir_reset(cs)) {
296 release_io_saphir(cs);
299 cs->readisac = &ReadISAC;
300 cs->writeisac = &WriteISAC;
301 cs->readisacfifo = &ReadISACfifo;
302 cs->writeisacfifo = &WriteISACfifo;
303 cs->BC_Read_Reg = &ReadHSCX;
304 cs->BC_Write_Reg = &WriteHSCX;
305 cs->BC_Send_Data = &hscx_fill_fifo;
306 cs->cardmsg = &saphir_card_msg;
307 cs->irq_func = &saphir_interrupt;
308 ISACVersion(cs, "saphir:");
309 if (HscxVersion(cs, "saphir:")) {
311 "saphir: wrong HSCX versions check IO address\n");
312 release_io_saphir(cs);