No empty .Rs/.Re
[netbsd-mini2440.git] / sys / dev / isa / isic_isa_tel_s0163.c
blob1d5ed35c8c469d290bf950a235913acda82fbc0f
1 /*
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
10 * are met:
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
33 * SUCH DAMAGE.
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]
44 * -hm clean up
45 * -hm more cleanup
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>
60 #else
61 #include <sys/ioctl.h>
62 #endif
63 #include <sys/kernel.h>
64 #include <sys/systm.h>
65 #include <sys/mbuf.h>
67 #if defined(__NetBSD__) && __NetBSD_Version__ >= 104230000
68 #include <sys/callout.h>
69 #endif
71 #ifdef __FreeBSD__
72 #include <machine/clock.h>
73 #include <i386/isa/isa_device.h>
74 #elif defined(__bsdi__)
75 /* XXX */
76 #else
77 #include <sys/bus.h>
78 #include <sys/device.h>
79 #endif
81 #include <sys/socket.h>
82 #include <net/if.h>
84 #ifdef __FreeBSD__
85 #include <machine/i4b_debug.h>
86 #include <machine/i4b_ioctl.h>
87 #else
88 #include <netisdn/i4b_debug.h>
89 #include <netisdn/i4b_ioctl.h>
90 #endif
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);
109 #endif
111 /*---------------------------------------------------------------------------*
112 * Teles S0/16.3 read fifo routine
113 *---------------------------------------------------------------------------*/
114 #if defined(__FreeBSD__) || defined(__bsdi__)
116 static void
117 tels0163_read_fifo(void *buf, const void *base, size_t len)
119 insb((int)base + 0x3e, (u_char *)buf, (u_int)len);
122 #else
124 static void
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);
133 #endif
135 /*---------------------------------------------------------------------------*
136 * Teles S0/16.3 write fifo routine
137 *---------------------------------------------------------------------------*/
138 #if defined(__FreeBSD__) || defined(__bsdi__)
140 static void
141 tels0163_write_fifo(void *base, const void *buf, size_t len)
143 outsb((int)base + 0x3e, (u_char *)buf, (u_int)len);
146 #else
148 static void
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);
156 #endif
158 /*---------------------------------------------------------------------------*
159 * Teles S0/16.3 ISAC put register routine
160 *---------------------------------------------------------------------------*/
161 #if defined(__FreeBSD__) || defined(__bsdi__)
163 static void
164 tels0163_write_reg(u_char *base, u_int offset, u_int v)
166 outb((int)base + offset, (u_char)v);
169 #else
171 static void
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);
179 #endif
181 /*---------------------------------------------------------------------------*
182 * Teles S0/16.3 ISAC get register routine
183 *---------------------------------------------------------------------------*/
184 #if defined(__FreeBSD__) || defined(__bsdi__)
186 static u_char
187 tels0163_read_reg(u_char *base, u_int offset)
189 return (inb((int)base + offset));
192 #else
194 static u_int8_t
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);
203 #endif
205 /*---------------------------------------------------------------------------*
206 * isic_probe_s0163 - probe for Teles S0/16.3 and compatibles
207 *---------------------------------------------------------------------------*/
208 #ifdef __FreeBSD__
210 isic_probe_s0163(struct isa_device *dev)
212 struct isic_softc *sc = &l1_sc[dev->id_unit];
213 u_char byte;
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);
221 return(0);
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);
231 return(0);
233 sc->sc_irq = dev->id_irq;
235 /* check if memory addr specified */
237 if(dev->id_maddr)
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);
241 return(0);
244 dev->id_msize = 0;
246 /* check if we got an iobase */
248 switch(dev->id_iobase)
250 case 0xd80:
251 case 0xe80:
252 case 0xf80:
253 break;
255 default:
256 printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16.3!\n",
257 dev->id_unit, dev->id_iobase);
258 return(0);
259 break;
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",
266 dev->id_unit, byte);
267 return(0);
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",
273 dev->id_unit, byte);
274 return(0);
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",
280 dev->id_unit, byte);
281 return(0);
284 /* setup access routines */
286 sc->clearirq = NULL;
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;
301 sc->sc_ipac = 0;
302 sc->sc_bfifolen = HSCX_FIFO_LEN;
304 /* setup ISAC and HSCX base addr */
306 switch(dev->id_iobase)
308 case 0xd80:
309 ISAC_BASE = (void *) 0x960;
310 HSCX_A_BASE = (void *) 0x160;
311 HSCX_B_BASE = (void *) 0x560;
312 break;
314 case 0xe80:
315 ISAC_BASE = (void *) 0xa60;
316 HSCX_A_BASE = (void *) 0x260;
317 HSCX_B_BASE = (void *) 0x660;
318 break;
320 case 0xf80:
321 ISAC_BASE = (void *) 0xb60;
322 HSCX_A_BASE = (void *) 0x360;
323 HSCX_B_BASE = (void *) 0x760;
324 break;
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",
338 dev->id_unit);
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));
343 return (0);
346 return (1);
349 #elif defined(__bsdi__)
351 static int
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)
360 case 0xd80:
361 case 0xe80:
362 case 0xf80:
363 break;
365 default:
366 printf("isic%d: Error, invalid iobase 0x%x specified for Teles S0/16.3!\n",
367 unit, ia->ia_iobase);
368 return(0);
369 break;
371 sc->sc_port = ia->ia_iobase;
373 /* setup access routines */
375 sc->clearirq = NULL;
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;
390 sc->sc_ipac = 0;
391 sc->sc_bfifolen = HSCX_FIFO_LEN;
393 /* setup ISAC and HSCX base addr */
395 switch(ia->ia_iobase)
397 case 0xd80:
398 ISAC_BASE = (void *) 0x960;
399 HSCX_A_BASE = (void *) 0x160;
400 HSCX_B_BASE = (void *) 0x560;
401 break;
403 case 0xe80:
404 ISAC_BASE = (void *) 0xa60;
405 HSCX_A_BASE = (void *) 0x260;
406 HSCX_B_BASE = (void *) 0x660;
407 break;
409 case 0xf80:
410 ISAC_BASE = (void *) 0xb60;
411 HSCX_A_BASE = (void *) 0x360;
412 HSCX_B_BASE = (void *) 0x760;
413 break;
415 return 1;
419 isic_probe_s0163(device_t dev, cfdata_t cf,
420 struct isa_attach_args *ia)
422 u_char byte;
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);
429 return(0);
432 /* check if memory addr specified */
434 if(ia->ia_maddr)
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);
438 return 0;
441 /* Set up a temporary softc for the probe */
443 if (set_softc(sc, ia, cf->cf_unit) == 0)
444 return 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",
449 cf->cf_unit, byte);
450 return(0);
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",
456 cf->cf_unit, byte);
457 return(0);
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",
463 cf->cf_unit, byte);
464 return(0);
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",
478 cf->cf_unit);
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));
483 return (0);
486 return (1);
490 #else
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;
497 u_int8_t b0, b1, b2;
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))
504 return 1;
506 return 0;
508 #endif
510 /*---------------------------------------------------------------------------*
511 * isic_attach_s0163 - attach Teles S0/16.3 and compatibles
512 *---------------------------------------------------------------------------*/
513 #ifdef __FreeBSD__
515 isic_attach_s0163(struct isa_device *dev)
517 u_char irq;
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);
523 return(0);
526 /* configure IRQ */
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);
534 return (1);
537 #elif defined(__bsdi__)
539 extern int
540 isic_attach_s0163(device_t parent, device_t self, struct isa_attach_args *ia)
542 u_char irq;
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];
555 /* configure IRQ */
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);
563 return 1;
565 #else
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];
574 /* configure 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 */
584 sc->clearirq = NULL;
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;
599 sc->sc_ipac = 0;
600 sc->sc_bfifolen = HSCX_FIFO_LEN;
602 return (1);
604 #endif
606 #endif /* ISICISA_TEL_S0_16_3 */