11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* $Id: saphir.c,v 1.10.2.4 2004/01/13 23:48:39 keil Exp $
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * low level stuff for HST Saphir 1
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Author       Karsten Keil
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright    by Karsten Keil      <keil@isdn4linux.de>
7475be4d85a274d0961593db41cf85689db1d583cJoe Perches *
81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This software may be used and distributed according to the terms
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * of the GNU General Public License, incorporated herein by reference.
101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Thanks to    HST High Soft Tech GmbH
121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h>
161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "hisax.h"
171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "isac.h"
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "hscx.h"
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "isdnl1.h"
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char *saphir_rev = "$Revision: 1.10.2.4 $";
221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
23475be4d85a274d0961593db41cf85689db1d583cJoe Perches#define byteout(addr, val) outb(val, addr)
241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define bytein(addr) inb(addr)
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ISAC_DATA	0
271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define HSCX_DATA	1
281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define ADDRESS_REG	2
291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define IRQ_REG		3
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define SPARE_REG	4
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define RESET_REG	5
321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline u_char
341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsreadreg(unsigned int ale, unsigned int adr, u_char off)
351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	register u_char ret;
371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byteout(ale, off);
391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ret = bytein(adr);
401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (ret);
411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void
44475be4d85a274d0961593db41cf85689db1d583cJoe Perchesreadfifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byteout(ale, off);
471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	insb(adr, data, size);
481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void
521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldswritereg(unsigned int ale, unsigned int adr, u_char off, u_char data)
531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byteout(ale, off);
551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byteout(adr, data);
561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic inline void
59475be4d85a274d0961593db41cf85689db1d583cJoe Percheswritefifo(unsigned int ale, unsigned int adr, u_char off, u_char *data, int size)
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byteout(ale, off);
621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	outsb(adr, data, size);
631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* Interface functions */
661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u_char
681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsReadISAC(struct IsdnCardState *cs, u_char offset)
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, offset));
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsWriteISAC(struct IsdnCardState *cs, u_char offset, u_char value)
751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	writereg(cs->hw.saphir.ale, cs->hw.saphir.isac, offset, value);
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
80475be4d85a274d0961593db41cf85689db1d583cJoe PerchesReadISACfifo(struct IsdnCardState *cs, u_char *data, int size)
811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	readfifo(cs->hw.saphir.ale, cs->hw.saphir.isac, 0, data, size);
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
86475be4d85a274d0961593db41cf85689db1d583cJoe PerchesWriteISACfifo(struct IsdnCardState *cs, u_char *data, int size)
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	writefifo(cs->hw.saphir.ale, cs->hw.saphir.isac, 0, data, size);
891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic u_char
921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsReadHSCX(struct IsdnCardState *cs, int hscx, u_char offset)
931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx,
95475be4d85a274d0961593db41cf85689db1d583cJoe Perches			offset + (hscx ? 0x40 : 0)));
961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsWriteHSCX(struct IsdnCardState *cs, int hscx, u_char offset, u_char value)
1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx,
102475be4d85a274d0961593db41cf85689db1d583cJoe Perches		 offset + (hscx ? 0x40 : 0), value);
1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
105475be4d85a274d0961593db41cf85689db1d583cJoe Perches#define READHSCX(cs, nr, reg) readreg(cs->hw.saphir.ale,		\
106475be4d85a274d0961593db41cf85689db1d583cJoe Perches				      cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0))
107475be4d85a274d0961593db41cf85689db1d583cJoe Perches#define WRITEHSCX(cs, nr, reg, data) writereg(cs->hw.saphir.ale,	\
108475be4d85a274d0961593db41cf85689db1d583cJoe Perches					      cs->hw.saphir.hscx, reg + (nr ? 0x40 : 0), data)
1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
110475be4d85a274d0961593db41cf85689db1d583cJoe Perches#define READHSCXFIFO(cs, nr, ptr, cnt) readfifo(cs->hw.saphir.ale,	\
111475be4d85a274d0961593db41cf85689db1d583cJoe Perches						cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt)
1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
113475be4d85a274d0961593db41cf85689db1d583cJoe Perches#define WRITEHSCXFIFO(cs, nr, ptr, cnt) writefifo(cs->hw.saphir.ale,	\
114475be4d85a274d0961593db41cf85689db1d583cJoe Perches						  cs->hw.saphir.hscx, (nr ? 0x40 : 0), ptr, cnt)
1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "hscx_irq.c"
1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic irqreturn_t
1197d12e780e003f93433d49ce78cfedf4b4c52adc5David Howellssaphir_interrupt(int intno, void *dev_id)
1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct IsdnCardState *cs = dev_id;
1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_char val;
1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long flags;
1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irqsave(&cs->lock, flags);
1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	val = readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_ISTA + 0x40);
127475be4d85a274d0961593db41cf85689db1d583cJoe PerchesStart_HSCX:
1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (val)
1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		hscx_int_main(cs, val);
1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	val = readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_ISTA);
131475be4d85a274d0961593db41cf85689db1d583cJoe PerchesStart_ISAC:
1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (val)
1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		isac_interrupt(cs, val);
1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	val = readreg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_ISTA + 0x40);
1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (val) {
1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (cs->debug & L1_DEB_HSCX)
1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			debugl1(cs, "HSCX IntStat after IntRoutine");
1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto Start_HSCX;
1391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	val = readreg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_ISTA);
1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (val) {
1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		if (cs->debug & L1_DEB_ISAC)
1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds			debugl1(cs, "ISAC IntStat after IntRoutine");
1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto Start_ISAC;
1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Watchdog */
147475be4d85a274d0961593db41cf85689db1d583cJoe Perches	if (cs->hw.saphir.timer.function)
148475be4d85a274d0961593db41cf85689db1d583cJoe Perches		mod_timer(&cs->hw.saphir.timer, jiffies + 1 * HZ);
1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	else
1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk(KERN_WARNING "saphir: Spurious timer!\n");
1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK, 0xFF);
1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK + 0x40, 0xFF);
1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	writereg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_MASK, 0xFF);
1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	writereg(cs->hw.saphir.ale, cs->hw.saphir.isac, ISAC_MASK, 0);
1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK, 0);
1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	writereg(cs->hw.saphir.ale, cs->hw.saphir.hscx, HSCX_MASK + 0x40, 0);
1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irqrestore(&cs->lock, flags);
1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return IRQ_HANDLED;
1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void
1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsSaphirWatchDog(struct IsdnCardState *cs)
1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long flags;
1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_lock_irqsave(&cs->lock, flags);
167475be4d85a274d0961593db41cf85689db1d583cJoe Perches	/* 5 sec WatchDog, so read at least every 4 sec */
1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->readisac(cs, ISAC_RBCH);
1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	spin_unlock_irqrestore(&cs->lock, flags);
170475be4d85a274d0961593db41cf85689db1d583cJoe Perches	mod_timer(&cs->hw.saphir.timer, jiffies + 1 * HZ);
1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
173672c3fd9069e5a138f9d4afc9aeb5aa34aacce32Adrian Bunkstatic void
1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsrelease_io_saphir(struct IsdnCardState *cs)
1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byteout(cs->hw.saphir.cfg_reg + IRQ_REG, 0xff);
1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	del_timer(&cs->hw.saphir.timer);
1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->hw.saphir.timer.function = NULL;
1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cs->hw.saphir.cfg_reg)
1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		release_region(cs->hw.saphir.cfg_reg, 6);
1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssaphir_reset(struct IsdnCardState *cs)
1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_char irq_val;
1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
188475be4d85a274d0961593db41cf85689db1d583cJoe Perches	switch (cs->irq) {
189475be4d85a274d0961593db41cf85689db1d583cJoe Perches	case 5: irq_val = 0;
190475be4d85a274d0961593db41cf85689db1d583cJoe Perches		break;
191475be4d85a274d0961593db41cf85689db1d583cJoe Perches	case 3: irq_val = 1;
192475be4d85a274d0961593db41cf85689db1d583cJoe Perches		break;
193475be4d85a274d0961593db41cf85689db1d583cJoe Perches	case 11:
194475be4d85a274d0961593db41cf85689db1d583cJoe Perches		irq_val = 2;
195475be4d85a274d0961593db41cf85689db1d583cJoe Perches		break;
196475be4d85a274d0961593db41cf85689db1d583cJoe Perches	case 12:
197475be4d85a274d0961593db41cf85689db1d583cJoe Perches		irq_val = 3;
198475be4d85a274d0961593db41cf85689db1d583cJoe Perches		break;
199475be4d85a274d0961593db41cf85689db1d583cJoe Perches	case 15:
200475be4d85a274d0961593db41cf85689db1d583cJoe Perches		irq_val = 4;
201475be4d85a274d0961593db41cf85689db1d583cJoe Perches		break;
202475be4d85a274d0961593db41cf85689db1d583cJoe Perches	default:
203475be4d85a274d0961593db41cf85689db1d583cJoe Perches		printk(KERN_WARNING "HiSax: saphir wrong IRQ %d\n",
204475be4d85a274d0961593db41cf85689db1d583cJoe Perches		       cs->irq);
205475be4d85a274d0961593db41cf85689db1d583cJoe Perches		return (1);
2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val);
2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byteout(cs->hw.saphir.cfg_reg + RESET_REG, 1);
2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mdelay(10);
2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byteout(cs->hw.saphir.cfg_reg + RESET_REG, 0);
2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	mdelay(10);
2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byteout(cs->hw.saphir.cfg_reg + IRQ_REG, irq_val);
2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	byteout(cs->hw.saphir.cfg_reg + SPARE_REG, 0x02);
2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (0);
2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int
2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldssaphir_card_msg(struct IsdnCardState *cs, int mt, void *arg)
2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	u_long flags;
2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	switch (mt) {
223475be4d85a274d0961593db41cf85689db1d583cJoe Perches	case CARD_RESET:
224475be4d85a274d0961593db41cf85689db1d583cJoe Perches		spin_lock_irqsave(&cs->lock, flags);
225475be4d85a274d0961593db41cf85689db1d583cJoe Perches		saphir_reset(cs);
226475be4d85a274d0961593db41cf85689db1d583cJoe Perches		spin_unlock_irqrestore(&cs->lock, flags);
227475be4d85a274d0961593db41cf85689db1d583cJoe Perches		return (0);
228475be4d85a274d0961593db41cf85689db1d583cJoe Perches	case CARD_RELEASE:
229475be4d85a274d0961593db41cf85689db1d583cJoe Perches		release_io_saphir(cs);
230475be4d85a274d0961593db41cf85689db1d583cJoe Perches		return (0);
231475be4d85a274d0961593db41cf85689db1d583cJoe Perches	case CARD_INIT:
232475be4d85a274d0961593db41cf85689db1d583cJoe Perches		spin_lock_irqsave(&cs->lock, flags);
233475be4d85a274d0961593db41cf85689db1d583cJoe Perches		inithscxisac(cs, 3);
234475be4d85a274d0961593db41cf85689db1d583cJoe Perches		spin_unlock_irqrestore(&cs->lock, flags);
235475be4d85a274d0961593db41cf85689db1d583cJoe Perches		return (0);
236475be4d85a274d0961593db41cf85689db1d583cJoe Perches	case CARD_TEST:
237475be4d85a274d0961593db41cf85689db1d583cJoe Perches		return (0);
2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
239475be4d85a274d0961593db41cf85689db1d583cJoe Perches	return (0);
2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
243ed5a84cdf593e54969518e82762786fbe1284ce4Greg Kroah-Hartmanint setup_saphir(struct IsdnCard *card)
2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	struct IsdnCardState *cs = card->cs;
2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	char tmp[64];
2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	strcpy(tmp, saphir_rev);
2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	printk(KERN_INFO "HiSax: HST Saphir driver Rev. %s\n", HiSax_getrev(tmp));
2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (cs->typ != ISDN_CTYPE_HSTSAPHIR)
2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (0);
2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* IO-Ports */
2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->hw.saphir.cfg_reg = card->para[1];
2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->hw.saphir.isac = card->para[1] + ISAC_DATA;
2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->hw.saphir.hscx = card->para[1] + HSCX_DATA;
2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->hw.saphir.ale = card->para[1] + ADDRESS_REG;
2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->irq = card->para[0];
2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (!request_region(cs->hw.saphir.cfg_reg, 6, "saphir")) {
2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk(KERN_WARNING
261475be4d85a274d0961593db41cf85689db1d583cJoe Perches		       "HiSax: HST Saphir config port %x-%x already in use\n",
262475be4d85a274d0961593db41cf85689db1d583cJoe Perches		       cs->hw.saphir.cfg_reg,
263475be4d85a274d0961593db41cf85689db1d583cJoe Perches		       cs->hw.saphir.cfg_reg + 5);
2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (0);
2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2678349304d12cf1313bdbd6eb2083701d86809be24Jeff Garzik	printk(KERN_INFO "HiSax: HST Saphir config irq:%d io:0x%X\n",
2688349304d12cf1313bdbd6eb2083701d86809be24Jeff Garzik	       cs->irq, cs->hw.saphir.cfg_reg);
2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	setup_isac(cs);
2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->hw.saphir.timer.function = (void *) SaphirWatchDog;
2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->hw.saphir.timer.data = (long) cs;
2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	init_timer(&cs->hw.saphir.timer);
274475be4d85a274d0961593db41cf85689db1d583cJoe Perches	cs->hw.saphir.timer.expires = jiffies + 4 * HZ;
2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	add_timer(&cs->hw.saphir.timer);
2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (saphir_reset(cs)) {
2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		release_io_saphir(cs);
2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (0);
2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->readisac = &ReadISAC;
2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->writeisac = &WriteISAC;
2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->readisacfifo = &ReadISACfifo;
2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->writeisacfifo = &WriteISACfifo;
2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->BC_Read_Reg = &ReadHSCX;
2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->BC_Write_Reg = &WriteHSCX;
2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->BC_Send_Data = &hscx_fill_fifo;
2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->cardmsg = &saphir_card_msg;
2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	cs->irq_func = &saphir_interrupt;
2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	ISACVersion(cs, "saphir:");
2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	if (HscxVersion(cs, "saphir:")) {
2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		printk(KERN_WARNING
292475be4d85a274d0961593db41cf85689db1d583cJoe Perches		       "saphir: wrong HSCX versions check IO address\n");
2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		release_io_saphir(cs);
2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		return (0);
2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	}
2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return (1);
2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
298