1 /* $Id: s0box.c,v 2.4.6.2 2001/09/23 22:24:51 kai Exp $
3 * low level stuff for Creatix S0BOX
6 * Copyright by Enrik Berkhan <enrik@starfleet.inka.de>
8 * This software may be used and distributed according to the terms
9 * of the GNU General Public License, incorporated herein by reference.
13 #include <linux/init.h>
19 extern const char *CardType
[];
20 const char *s0box_revision
= "$Revision: 2.4.6.2 $";
21 static spinlock_t s0box_lock
= SPIN_LOCK_UNLOCKED
;
24 writereg(struct IsdnCardState
*cs
, int addr
, u8 off
, u8 val
)
27 unsigned long padr
= cs
->hw
.teles3
.cfg_reg
;
29 spin_lock_irqsave(&s0box_lock
, flags
);
32 outb_p((addr
+off
)&0x7f,padr
);
38 spin_unlock_irqrestore(&s0box_lock
, flags
);
41 static u8 nibtab
[] = { 1, 9, 5, 0xd, 3, 0xb, 7, 0xf,
42 0, 0, 0, 0, 0, 0, 0, 0,
43 0, 8, 4, 0xc, 2, 0xa, 6, 0xe } ;
46 readreg(struct IsdnCardState
*cs
, int addr
, u8 off
)
50 unsigned long padr
= cs
->hw
.teles3
.cfg_reg
;
52 spin_lock_irqsave(&s0box_lock
, flags
);
55 outb_p((addr
+off
)|0x80,padr
);
58 n1
= (inb_p(padr
+1) >> 3) & 0x17;
60 n2
= (inb_p(padr
+1) >> 3) & 0x17;
63 spin_unlock_irqrestore(&s0box_lock
, flags
);
64 return nibtab
[n1
] | (nibtab
[n2
] << 4);
68 read_fifo(struct IsdnCardState
*cs
, signed int adr
, u8
* data
, int size
)
72 unsigned long padr
= cs
->hw
.teles3
.cfg_reg
;
76 outb_p(adr
|0x80, padr
);
78 for (i
=0; i
<size
; i
++) {
80 n1
= (inb_p(padr
+1) >> 3) & 0x17;
82 n2
= (inb_p(padr
+1) >> 3) & 0x17;
83 *(data
++)=nibtab
[n1
] | (nibtab
[n2
] << 4);
90 write_fifo(struct IsdnCardState
*cs
, signed int adr
, u8
* data
, int size
)
93 unsigned long padr
= cs
->hw
.teles3
.cfg_reg
;
97 outb_p(adr
&0x7f, padr
);
98 for (i
=0; i
<size
; i
++) {
100 outb_p(*(data
++), padr
);
101 outb_p(0x17, padr
+2);
108 isac_read(struct IsdnCardState
*cs
, u8 offset
)
110 return readreg(cs
, cs
->hw
.teles3
.isac
, offset
);
114 isac_write(struct IsdnCardState
*cs
, u8 offset
, u8 value
)
116 writereg(cs
, cs
->hw
.teles3
.isac
, offset
, value
);
120 isac_read_fifo(struct IsdnCardState
*cs
, u8
* data
, int size
)
122 read_fifo(cs
, cs
->hw
.teles3
.isacfifo
, data
, size
);
126 isac_write_fifo(struct IsdnCardState
*cs
, u8
* data
, int size
)
128 write_fifo(cs
, cs
->hw
.teles3
.isacfifo
, data
, size
);
131 static struct dc_hw_ops isac_ops
= {
132 .read_reg
= isac_read
,
133 .write_reg
= isac_write
,
134 .read_fifo
= isac_read_fifo
,
135 .write_fifo
= isac_write_fifo
,
139 hscx_read(struct IsdnCardState
*cs
, int hscx
, u8 offset
)
141 return readreg(cs
, cs
->hw
.teles3
.hscx
[hscx
], offset
);
145 hscx_write(struct IsdnCardState
*cs
, int hscx
, u8 offset
, u8 value
)
147 writereg(cs
, cs
->hw
.teles3
.hscx
[hscx
], offset
, value
);
151 hscx_read_fifo(struct IsdnCardState
*cs
, int hscx
, u8
*data
, int size
)
153 read_fifo(cs
, cs
->hw
.teles3
.hscxfifo
[hscx
], data
, size
);
157 hscx_write_fifo(struct IsdnCardState
*cs
, int hscx
, u8
*data
, int size
)
159 write_fifo(cs
, cs
->hw
.teles3
.hscxfifo
[hscx
], data
, size
);
162 static struct bc_hw_ops hscx_ops
= {
163 .read_reg
= hscx_read
,
164 .write_reg
= hscx_write
,
165 .read_fifo
= hscx_read_fifo
,
166 .write_fifo
= hscx_write_fifo
,
169 static struct card_ops s0box_ops
= {
170 .init
= inithscxisac
,
171 .release
= hisax_release_resources
,
172 .irq_func
= hscxisac_irq
,
176 s0box_probe(struct IsdnCardState
*cs
, struct IsdnCard
*card
)
178 cs
->hw
.teles3
.cfg_reg
= card
->para
[1];
179 cs
->hw
.teles3
.hscx
[0] = -0x20;
180 cs
->hw
.teles3
.hscx
[1] = 0x0;
181 cs
->hw
.teles3
.isac
= 0x20;
182 cs
->hw
.teles3
.isacfifo
= cs
->hw
.teles3
.isac
+ 0x3e;
183 cs
->hw
.teles3
.hscxfifo
[0] = cs
->hw
.teles3
.hscx
[0] + 0x3e;
184 cs
->hw
.teles3
.hscxfifo
[1] = cs
->hw
.teles3
.hscx
[1] + 0x3e;
185 cs
->irq
= card
->para
[0];
186 if (!request_io(&cs
->rs
, cs
->hw
.teles3
.cfg_reg
, 8, "S0Box parallel I/O"))
189 "HiSax: %s config irq:%d isac:0x%x cfg:0x%x\n",
190 CardType
[cs
->typ
], cs
->irq
,
191 cs
->hw
.teles3
.isac
, cs
->hw
.teles3
.cfg_reg
);
193 "HiSax: hscx A:0x%x hscx B:0x%x\n",
194 cs
->hw
.teles3
.hscx
[0], cs
->hw
.teles3
.hscx
[1]);
195 cs
->card_ops
= &s0box_ops
;
196 if (hscxisac_setup(cs
, &isac_ops
, &hscx_ops
))
200 hisax_release_resources(cs
);
205 setup_s0box(struct IsdnCard
*card
)
209 strcpy(tmp
, s0box_revision
);
210 printk(KERN_INFO
"HiSax: S0Box IO driver Rev. %s\n", HiSax_getrev(tmp
));
211 if (s0box_probe(card
->cs
, card
))