2 * Copyright (c) 1996 Arne Helme. All rights reserved.
4 * Copyright (c) 1996 Gary Jennejohn. All rights reserved.
6 * Copyright (c) 1997, 1999 Hellmuth Michaelis. All rights reserved.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the author nor the names of any co-contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 * 4. Altered versions must be plainly marked as such, and must not be
21 * misrepresented as being the original software and/or documentation.
23 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
27 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
28 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
29 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
32 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 *---------------------------------------------------------------------------
37 * isic - I4B Siemens ISDN Chipset Driver for Teles S0/16.3
38 * ========================================================
40 * $Id: isic_isa_tel_s0163.c,v 1.12 2009/05/12 09:10:15 cegger Exp $
42 * last edit-date: [Fri Jan 5 11:37:22 2001]
46 * -hm NetBSD patches from Martin
47 * -hm VSTR detection for older 16.3 cards
49 *---------------------------------------------------------------------------*/
51 #include <sys/cdefs.h>
52 __KERNEL_RCSID(0, "$NetBSD: isic_isa_tel_s0163.c,v 1.11 2009/05/12 08:44:19 cegger Exp $");
54 #include "opt_isicisa.h"
55 #ifdef ISICISA_TEL_S0_16_3
57 #include <sys/param.h>
58 #if defined(__FreeBSD__) && __FreeBSD__ >= 3
59 #include <sys/ioccom.h>
61 #include <sys/ioctl.h>
63 #include <sys/kernel.h>
64 #include <sys/systm.h>
67 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
68 #include <sys/callout.h>
72 #include <machine/clock.h>
73 #include <i386/isa/isa_device.h>
74 #elif defined(__bsdi__)
78 #include <sys/device.h>
81 #include <sys/socket.h>
85 #include <machine/i4b_debug.h>
86 #include <machine/i4b_ioctl.h>
88 #include <netisdn/i4b_debug.h>
89 #include <netisdn/i4b_ioctl.h>
92 #include <netisdn/i4b_global.h>
93 #include <netisdn/i4b_debug.h>
94 #include <netisdn/i4b_l2.h>
95 #include <netisdn/i4b_l1l2.h>
96 #include <netisdn/i4b_mbuf.h>
98 #include <dev/ic/isic_l1.h>
99 #include <dev/ic/isac.h>
100 #include <dev/ic/hscx.h>
102 static u_char intr_no
[] = { 1, 1, 0, 2, 4, 6, 1, 1, 1, 0, 8, 10, 12, 1, 1, 14 };
104 #if !defined(__FreeBSD__) && !defined(__bsdi__)
105 static u_int8_t
tels0163_read_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
);
106 static void tels0163_write_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
, u_int8_t data
);
107 static void tels0163_read_fifo(struct isic_softc
*sc
, int what
, void *buf
, size_t size
);
108 static void tels0163_write_fifo(struct isic_softc
*sc
, int what
, const void *data
, size_t size
);
111 /*---------------------------------------------------------------------------*
112 * Teles S0/16.3 read fifo routine
113 *---------------------------------------------------------------------------*/
114 #if defined(__FreeBSD__) || defined(__bsdi__)
117 tels0163_read_fifo(void *buf
, const void *base
, size_t len
)
119 insb((int)base
+ 0x3e, (u_char
*)buf
, (u_int
)len
);
125 tels0163_read_fifo(struct isic_softc
*sc
, int what
, void *buf
, size_t size
)
127 bus_space_tag_t t
= sc
->sc_maps
[what
+1].t
;
128 bus_space_handle_t h
= sc
->sc_maps
[what
+1].h
;
129 bus_size_t o
= sc
->sc_maps
[what
+1].offset
;
130 bus_space_read_multi_1(t
, h
, o
+ 0x1e, buf
, size
);
135 /*---------------------------------------------------------------------------*
136 * Teles S0/16.3 write fifo routine
137 *---------------------------------------------------------------------------*/
138 #if defined(__FreeBSD__) || defined(__bsdi__)
141 tels0163_write_fifo(void *base
, const void *buf
, size_t len
)
143 outsb((int)base
+ 0x3e, (u_char
*)buf
, (u_int
)len
);
149 tels0163_write_fifo(struct isic_softc
*sc
, int what
, const void *buf
, size_t size
)
151 bus_space_tag_t t
= sc
->sc_maps
[what
+1].t
;
152 bus_space_handle_t h
= sc
->sc_maps
[what
+1].h
;
153 bus_size_t o
= sc
->sc_maps
[what
+1].offset
;
154 bus_space_write_multi_1(t
, h
, o
+ 0x1e, buf
, size
);
158 /*---------------------------------------------------------------------------*
159 * Teles S0/16.3 ISAC put register routine
160 *---------------------------------------------------------------------------*/
161 #if defined(__FreeBSD__) || defined(__bsdi__)
164 tels0163_write_reg(u_char
*base
, u_int offset
, u_int v
)
166 outb((int)base
+ offset
, (u_char
)v
);
172 tels0163_write_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
, u_int8_t data
)
174 bus_space_tag_t t
= sc
->sc_maps
[what
+1].t
;
175 bus_space_handle_t h
= sc
->sc_maps
[what
+1].h
;
176 bus_size_t o
= sc
->sc_maps
[what
+1].offset
;
177 bus_space_write_1(t
, h
, o
+ offs
- 0x20, data
);
181 /*---------------------------------------------------------------------------*
182 * Teles S0/16.3 ISAC get register routine
183 *---------------------------------------------------------------------------*/
184 #if defined(__FreeBSD__) || defined(__bsdi__)
187 tels0163_read_reg(u_char
*base
, u_int offset
)
189 return (inb((int)base
+ offset
));
195 tels0163_read_reg(struct isic_softc
*sc
, int what
, bus_size_t offs
)
197 bus_space_tag_t t
= sc
->sc_maps
[what
+1].t
;
198 bus_space_handle_t h
= sc
->sc_maps
[what
+1].h
;
199 bus_size_t o
= sc
->sc_maps
[what
+1].offset
;
200 return bus_space_read_1(t
, h
, o
+ offs
- 0x20);
205 /*---------------------------------------------------------------------------*
206 * isic_probe_s0163 - probe for Teles S0/16.3 and compatibles
207 *---------------------------------------------------------------------------*/
210 isic_probe_s0163(struct isa_device
*dev
)
212 struct isic_softc
*sc
= &l1_sc
[dev
->id_unit
];
215 /* check max unit range */
217 if(dev
->id_unit
>= ISIC_MAXUNIT
)
219 printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for Teles S0/16.3!\n",
220 dev
->id_unit
, dev
->id_unit
);
223 sc
->sc_unit
= dev
->id_unit
;
225 /* check IRQ validity */
227 if((intr_no
[ffs(dev
->id_irq
) - 1]) == 1)
229 printf("isic%d: Error, invalid IRQ [%d] specified for Teles S0/16.3!\n",
230 dev
->id_unit
, ffs(dev
->id_irq
)-1);
233 sc
->sc_irq
= dev
->id_irq
;
235 /* check if memory addr specified */
239 printf("isic%d: Error, mem addr 0x%lx specified for Teles S0/16.3!\n",
240 dev
->id_unit
, (u_long
)dev
->id_maddr
);
246 /* check if we got an iobase */
248 switch(dev
->id_iobase
)
256 printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16.3!\n",
257 dev
->id_unit
, dev
->id_iobase
);
261 sc
->sc_port
= dev
->id_iobase
;
263 if(((byte
= inb(sc
->sc_port
)) != 0x51) && (byte
!= 0x10))
265 printf("isic%d: Error, signature 1 0x%x != 0x51 or 0x10 for Teles S0/16.3!\n",
270 if((byte
= inb(sc
->sc_port
+ 1)) != 0x93)
272 printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16.3!\n",
277 if(((byte
= inb(sc
->sc_port
+ 2)) != 0x1c) && (byte
!= 0x1f))
279 printf("isic%d: Error, signature 3 0x%x != (0x1c||0x1f) for Teles S0/16.3!\n",
284 /* setup access routines */
287 sc
->readreg
= tels0163_read_reg
;
288 sc
->writereg
= tels0163_write_reg
;
290 sc
->readfifo
= tels0163_read_fifo
;
291 sc
->writefifo
= tels0163_write_fifo
;
293 /* setup card type */
295 sc
->sc_cardtyp
= CARD_TYPEP_16_3
;
297 /* setup IOM bus type */
299 sc
->sc_bustyp
= BUS_TYPE_IOM2
;
302 sc
->sc_bfifolen
= HSCX_FIFO_LEN
;
304 /* setup ISAC and HSCX base addr */
306 switch(dev
->id_iobase
)
309 ISAC_BASE
= (void *) 0x960;
310 HSCX_A_BASE
= (void *) 0x160;
311 HSCX_B_BASE
= (void *) 0x560;
315 ISAC_BASE
= (void *) 0xa60;
316 HSCX_A_BASE
= (void *) 0x260;
317 HSCX_B_BASE
= (void *) 0x660;
321 ISAC_BASE
= (void *) 0xb60;
322 HSCX_A_BASE
= (void *) 0x360;
323 HSCX_B_BASE
= (void *) 0x760;
328 * Read HSCX A/B VSTR. Expected value for the S0/16.3 card is
329 * 0x05 or 0x04 (for older 16.3's) in the least significant bits.
332 if( (((HSCX_READ(0, H_VSTR
) & 0xf) != 0x5) &&
333 ((HSCX_READ(0, H_VSTR
) & 0xf) != 0x4)) ||
334 (((HSCX_READ(1, H_VSTR
) & 0xf) != 0x5) &&
335 ((HSCX_READ(1, H_VSTR
) & 0xf) != 0x4)) )
337 printf("isic%d: HSCX VSTR test failed for Teles S0/16.3\n",
339 printf("isic%d: HSC0: VSTR: %#x\n",
340 dev
->id_unit
, HSCX_READ(0, H_VSTR
));
341 printf("isic%d: HSC1: VSTR: %#x\n",
342 dev
->id_unit
, HSCX_READ(1, H_VSTR
));
349 #elif defined(__bsdi__)
352 set_softc(struct isic_softc
*sc
, struct isa_attach_args
*ia
, int unit
)
354 sc
->sc_irq
= ia
->ia_irq
;
356 /* check if we got an iobase */
358 switch(ia
->ia_iobase
)
366 printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16.3!\n",
367 unit
, ia
->ia_iobase
);
371 sc
->sc_port
= ia
->ia_iobase
;
373 /* setup access routines */
376 sc
->readreg
= tels0163_read_reg
;
377 sc
->writereg
= tels0163_write_reg
;
379 sc
->readfifo
= tels0163_read_fifo
;
380 sc
->writefifo
= tels0163_write_fifo
;
382 /* setup card type */
384 sc
->sc_cardtyp
= CARD_TYPEP_16_3
;
386 /* setup IOM bus type */
388 sc
->sc_bustyp
= BUS_TYPE_IOM2
;
391 sc
->sc_bfifolen
= HSCX_FIFO_LEN
;
393 /* setup ISAC and HSCX base addr */
395 switch(ia
->ia_iobase
)
398 ISAC_BASE
= (void *) 0x960;
399 HSCX_A_BASE
= (void *) 0x160;
400 HSCX_B_BASE
= (void *) 0x560;
404 ISAC_BASE
= (void *) 0xa60;
405 HSCX_A_BASE
= (void *) 0x260;
406 HSCX_B_BASE
= (void *) 0x660;
410 ISAC_BASE
= (void *) 0xb60;
411 HSCX_A_BASE
= (void *) 0x360;
412 HSCX_B_BASE
= (void *) 0x760;
419 isic_probe_s0163(device_t dev
, cfdata_t cf
,
420 struct isa_attach_args
*ia
)
423 struct isic_softc dummysc
, *sc
= &dummysc
;
425 if((intr_no
[ffs(ia
->ia_irq
) - 1]) == 1)
427 printf("isic%d: Error, invalid IRQ [%d] specified for Teles S0/16.3!\n",
428 cf
->cf_unit
, ffs(ia
->ia_irq
)-1);
432 /* check if memory addr specified */
436 printf("isic%d: Error, mem addr 0x%lx specified for Teles S0/16.3!\n",
437 cf
->cf_unit
, (u_long
)ia
->ia_maddr
);
441 /* Set up a temporary softc for the probe */
443 if (set_softc(sc
, ia
, cf
->cf_unit
) == 0)
446 if((byte
= inb(sc
->sc_port
)) != 0x51)
448 printf("isic%d: Error, signature 1 0x%x != 0x51 for Teles S0/16.3!\n",
453 if((byte
= inb(sc
->sc_port
+ 1)) != 0x93)
455 printf("isic%d: Error, signature 2 0x%x != 0x93 for Teles S0/16.3!\n",
460 if(((byte
= inb(sc
->sc_port
+ 2)) != 0x1c) && (byte
!= 0x1f))
462 printf("isic%d: Error, signature 3 0x%x != (0x1c||0x1f) for Teles S0/16.3!\n",
468 * Read HSCX A/B VSTR. Expected value for the S0/16.3 card is
469 * 0x05 or 0x04 (for older 16.3's) in the least significant bits.
472 if( (((HSCX_READ(0, H_VSTR
) & 0xf) != 0x5) &&
473 ((HSCX_READ(0, H_VSTR
) & 0xf) != 0x4)) ||
474 (((HSCX_READ(1, H_VSTR
) & 0xf) != 0x5) &&
475 ((HSCX_READ(1, H_VSTR
) & 0xf) != 0x4)) )
477 printf("isic%d: HSCX VSTR test failed for Teles S0/16.3\n",
479 printf("isic%d: HSC0: VSTR: %#x\n",
480 cf
->cf_unit
, HSCX_READ(0, H_VSTR
));
481 printf("isic%d: HSC1: VSTR: %#x\n",
482 cf
->cf_unit
, HSCX_READ(1, H_VSTR
));
493 isic_probe_s0163(struct isic_attach_args
*ia
)
495 bus_space_tag_t t
= ia
->ia_maps
[0].t
;
496 bus_space_handle_t h
= ia
->ia_maps
[0].h
;
499 b0
= bus_space_read_1(t
, h
, 0);
500 b1
= bus_space_read_1(t
, h
, 1);
501 b2
= bus_space_read_1(t
, h
, 2);
503 if (b0
== 0x51 && b1
== 0x93 && (b2
== 0x1c || b2
== 0x1f))
510 /*---------------------------------------------------------------------------*
511 * isic_attach_s0163 - attach Teles S0/16.3 and compatibles
512 *---------------------------------------------------------------------------*/
515 isic_attach_s0163(struct isa_device
*dev
)
519 if((irq
= intr_no
[ffs(dev
->id_irq
) - 1]) == 1)
521 printf("isic%d: Attach error, invalid IRQ [%d] specified for Teles S0/16.3!\n",
522 dev
->id_unit
, ffs(dev
->id_irq
)-1);
528 DELAY(SEC_DELAY
/ 10);
529 outb(dev
->id_iobase
+ 4, irq
);
531 DELAY(SEC_DELAY
/ 10);
532 outb(dev
->id_iobase
+ 4, irq
| 0x01);
537 #elif defined(__bsdi__)
540 isic_attach_s0163(device_t parent
, device_t self
, struct isa_attach_args
*ia
)
543 struct isic_softc
*sc
= (struct isic_softc
*)self
;
544 int unit
= sc
->sc_dev
.dv_unit
;
546 /* Commit the probed attachement values */
548 if (set_softc(sc
, ia
, unit
) == 0)
549 panic("isic_attach_s0163: set_softc");
551 if (((unsigned)sc
->sc_unit
) >= NISIC
)
552 panic("attach isic%d; NISIC=%d", sc
->sc_unit
, NISIC
);
553 l1_sc
[sc
->sc_unit
] = sc
;
554 irq
= intr_no
[ffs(sc
->sc_irq
) - 1];
557 DELAY(SEC_DELAY
/ 10);
558 outb(sc
->sc_port
+ 4, irq
);
560 DELAY(SEC_DELAY
/ 10);
561 outb(sc
->sc_port
+ 4, irq
| 0x01);
568 isic_attach_s0163(struct isic_softc
*sc
)
570 bus_space_tag_t t
= sc
->sc_maps
[0].t
;
571 bus_space_handle_t h
= sc
->sc_maps
[0].h
;
572 u_int8_t irq
= intr_no
[sc
->sc_irq
];
576 DELAY(SEC_DELAY
/ 10);
577 bus_space_write_1(t
, h
, 4, irq
);
579 DELAY(SEC_DELAY
/ 10);
580 bus_space_write_1(t
, h
, 4, irq
| 0x01);
582 /* setup access routines */
585 sc
->readreg
= tels0163_read_reg
;
586 sc
->writereg
= tels0163_write_reg
;
588 sc
->readfifo
= tels0163_read_fifo
;
589 sc
->writefifo
= tels0163_write_fifo
;
591 /* setup card type */
593 sc
->sc_cardtyp
= CARD_TYPEP_16_3
;
595 /* setup IOM bus type */
597 sc
->sc_bustyp
= BUS_TYPE_IOM2
;
600 sc
->sc_bfifolen
= HSCX_FIFO_LEN
;
606 #endif /* ISICISA_TEL_S0_16_3 */