2 * Copyright (c) 1997, 1998 Hellmuth Michaelis. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 *---------------------------------------------------------------------------
27 * isic - I4B Siemens ISDN Chipset Driver for ELSA Quickstep 1000pro ISA
28 * =====================================================================
30 * $Id: i4b_elsa_qs1i.c,v 1.1 1998/12/27 21:46:45 phk Exp $
32 * last edit-date: [Mon Dec 14 17:27:08 1998]
34 *---------------------------------------------------------------------------*/
49 #if (NISIC > 0) && (NPNP > 0) && defined(ELSA_QS1ISA)
51 #include <sys/param.h>
52 #include <sys/kernel.h>
53 #include <sys/systm.h>
55 #include <sys/socket.h>
60 #include <sys/ioccom.h>
62 #include <sys/ioctl.h>
64 #include <machine/clock.h>
65 #include <i386/isa/isa_device.h>
66 #include <i386/isa/pnp.h>
68 #include <machine/bus.h>
69 #include <sys/device.h>
73 #include <machine/i4b_debug.h>
74 #include <machine/i4b_ioctl.h>
76 #include <i4b/i4b_debug.h>
77 #include <i4b/i4b_ioctl.h>
80 #include <i4b/include/i4b_global.h>
81 #include <i4b/include/i4b_l1l2.h>
82 #include <i4b/include/i4b_mbuf.h>
84 #include <i4b/layer1/i4b_l1.h>
85 #include <i4b/layer1/i4b_isac.h>
86 #include <i4b/layer1/i4b_hscx.h>
89 /* static void i4b_eq1i_clrirq(void* base); */
91 static void i4b_eq1i_clrirq(struct isic_softc *sc);
92 void isic_attach_Eqs1pi __P((struct isic_softc *sc));
95 /* masks for register encoded in base addr */
97 #define ELSA_BASE_MASK 0x0ffff
98 #define ELSA_OFF_MASK 0xf0000
100 /* register id's to be encoded in base addr */
102 #define ELSA_IDISAC 0x00000
103 #define ELSA_IDHSCXA 0x10000
104 #define ELSA_IDHSCXB 0x20000
106 /* offsets from base address */
108 #define ELSA_OFF_ISAC 0x00
109 #define ELSA_OFF_HSCX 0x02
110 #define ELSA_OFF_OFF 0x03
111 #define ELSA_OFF_CTRL 0x04
112 #define ELSA_OFF_CFG 0x05
113 #define ELSA_OFF_TIMR 0x06
114 #define ELSA_OFF_IRQ 0x07
116 /* control register (write access) */
118 #define ELSA_CTRL_LED_YELLOW 0x02
119 #define ELSA_CTRL_LED_GREEN 0x08
120 #define ELSA_CTRL_RESET 0x20
121 #define ELSA_CTRL_TIMEREN 0x80
122 #define ELSA_CTRL_SECRET 0x50
124 /*---------------------------------------------------------------------------*
125 * ELSA QuickStep 1000pro/ISA clear IRQ routine
126 *---------------------------------------------------------------------------*/
130 i4b_eq1i_clrirq(void* base)
132 outb((u_int)base + ELSA_OFF_IRQ, 0);
137 i4b_eq1i_clrirq(struct isic_softc *sc)
139 bus_space_tag_t t = sc->sc_maps[0].t;
140 bus_space_handle_t h = sc->sc_maps[0].h;
141 bus_space_write_1(t, h, ELSA_OFF_IRQ, 0);
145 /*---------------------------------------------------------------------------*
146 * ELSA QuickStep 1000pro/ISA ISAC get fifo routine
147 *---------------------------------------------------------------------------*/
151 eqs1pi_read_fifo(void *buf, const void *base, size_t len)
153 if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXB)
155 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, 0x40);
156 insb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX), (u_char *)buf, (u_int)len);
158 else if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXA)
160 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, 0);
161 insb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX), (u_char *)buf, (u_int)len);
163 else /* if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDISAC) */
165 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, 0);
166 insb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ISAC), (u_char *)buf, (u_int)len);
173 eqs1pi_read_fifo(struct isic_softc *sc, int what, void *buf, size_t size)
175 bus_space_tag_t t = sc->sc_maps[0].t;
176 bus_space_handle_t h = sc->sc_maps[0].h;
179 bus_space_write_1(t, h, ELSA_OFF_OFF, 0);
180 bus_space_read_multi_1(t, h, ELSA_OFF_ISAC, buf, size);
182 case ISIC_WHAT_HSCXA:
183 bus_space_write_1(t, h, ELSA_OFF_OFF, 0);
184 bus_space_read_multi_1(t, h, ELSA_OFF_HSCX, buf, size);
186 case ISIC_WHAT_HSCXB:
187 bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40);
188 bus_space_read_multi_1(t, h, ELSA_OFF_HSCX, buf, size);
195 /*---------------------------------------------------------------------------*
196 * ELSA QuickStep 1000pro/ISA ISAC put fifo routine
197 *---------------------------------------------------------------------------*/
201 eqs1pi_write_fifo(void *base, const void *buf, size_t len)
203 if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXB)
205 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, 0x40);
206 outsb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX), (u_char *)buf, (u_int)len);
208 else if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXA)
210 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, 0);
211 outsb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX), (u_char *)buf, (u_int)len);
213 else /* if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDISAC) */
215 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, 0);
216 outsb((((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ISAC), (u_char *)buf, (u_int)len);
223 eqs1pi_write_fifo(struct isic_softc *sc, int what, const void *buf, size_t size)
225 bus_space_tag_t t = sc->sc_maps[0].t;
226 bus_space_handle_t h = sc->sc_maps[0].h;
229 bus_space_write_1(t, h, ELSA_OFF_OFF, 0);
230 bus_space_write_multi_1(t, h, ELSA_OFF_ISAC, (u_int8_t*)buf, size);
232 case ISIC_WHAT_HSCXA:
233 bus_space_write_1(t, h, ELSA_OFF_OFF, 0);
234 bus_space_write_multi_1(t, h, ELSA_OFF_HSCX, (u_int8_t*)buf, size);
236 case ISIC_WHAT_HSCXB:
237 bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40);
238 bus_space_write_multi_1(t, h, ELSA_OFF_HSCX, (u_int8_t*)buf, size);
244 /*---------------------------------------------------------------------------*
245 * ELSA QuickStep 1000pro/ISA ISAC put register routine
246 *---------------------------------------------------------------------------*/
250 eqs1pi_write_reg(u_char *base, u_int offset, u_int v)
252 if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXB)
254 outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, (u_char)(offset+0x40));
255 outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX, (u_char)v);
257 else if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXA)
259 outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, (u_char)offset);
260 outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX, (u_char)v);
262 else /* if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDISAC) */
264 outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, (u_char)offset);
265 outb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ISAC, (u_char)v);
272 eqs1pi_write_reg(struct isic_softc *sc, int what, bus_size_t offs, u_int8_t data)
274 bus_space_tag_t t = sc->sc_maps[0].t;
275 bus_space_handle_t h = sc->sc_maps[0].h;
278 bus_space_write_1(t, h, ELSA_OFF_OFF, offs);
279 bus_space_write_1(t, h, ELSA_OFF_ISAC, data);
281 case ISIC_WHAT_HSCXA:
282 bus_space_write_1(t, h, ELSA_OFF_OFF, offs);
283 bus_space_write_1(t, h, ELSA_OFF_HSCX, data);
285 case ISIC_WHAT_HSCXB:
286 bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40+offs);
287 bus_space_write_1(t, h, ELSA_OFF_HSCX, data);
293 /*---------------------------------------------------------------------------*
294 * ELSA QuickStep 1000pro/ISA ISAC get register routine
295 *---------------------------------------------------------------------------*/
299 eqs1pi_read_reg(u_char *base, u_int offset)
301 if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXB)
303 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, (u_char)(offset+0x40));
304 return(inb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX));
306 else if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDHSCXA)
308 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, (u_char)offset);
309 return(inb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_HSCX));
311 else /* if(((u_int)base & ELSA_OFF_MASK) == ELSA_IDISAC) */
313 outb((u_int)((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_OFF, (u_char)offset);
314 return(inb(((u_int)base & ELSA_BASE_MASK) + ELSA_OFF_ISAC));
321 eqs1pi_read_reg(struct isic_softc *sc, int what, bus_size_t offs)
323 bus_space_tag_t t = sc->sc_maps[0].t;
324 bus_space_handle_t h = sc->sc_maps[0].h;
327 bus_space_write_1(t, h, ELSA_OFF_OFF, offs);
328 return bus_space_read_1(t, h, ELSA_OFF_ISAC);
329 case ISIC_WHAT_HSCXA:
330 bus_space_write_1(t, h, ELSA_OFF_OFF, offs);
331 return bus_space_read_1(t, h, ELSA_OFF_HSCX);
332 case ISIC_WHAT_HSCXB:
333 bus_space_write_1(t, h, ELSA_OFF_OFF, 0x40+offs);
334 return bus_space_read_1(t, h, ELSA_OFF_HSCX);
343 /*---------------------------------------------------------------------------*
344 * isic_probe_Eqs1pi - probe for ELSA QuickStep 1000pro/ISA and compatibles
345 *---------------------------------------------------------------------------*/
347 isic_probe_Eqs1pi(struct isa_device *dev, unsigned int iobase2)
349 struct isic_softc *sc = &isic_sc[dev->id_unit];
351 /* check max unit range */
353 if(dev->id_unit >= ISIC_MAXUNIT)
355 printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for ELSA QuickStep 1000pro/ISA!\n",
356 dev->id_unit, dev->id_unit);
359 sc->sc_unit = dev->id_unit;
361 /* check IRQ validity */
363 switch(ffs(dev->id_irq) - 1)
376 printf("isic%d: Error, invalid IRQ [%d] specified for ELSA QuickStep 1000pro/ISA!\n",
377 dev->id_unit, ffs(dev->id_irq)-1);
381 sc->sc_irq = dev->id_irq;
383 /* check if memory addr specified */
387 printf("isic%d: Error, mem addr 0x%lx specified for ELSA QuickStep 1000pro/ISA!\n",
388 dev->id_unit, (u_long)dev->id_maddr);
393 /* check if we got an iobase */
395 if(!((dev->id_iobase >= 0x160) && (dev->id_iobase <= 0x360)))
397 printf("isic%d: Error, invalid iobase 0x%x specified for ELSA QuickStep 1000pro/ISA!\n",
398 dev->id_unit, dev->id_iobase);
401 sc->sc_port = dev->id_iobase;
403 /* setup access routines */
405 /* XXX no "sc_clearirq" in sight... /phk
406 sc->sc_clearirq = i4b_eq1i_clrirq;
408 sc->readreg = eqs1pi_read_reg;
409 sc->writereg = eqs1pi_write_reg;
411 sc->readfifo = eqs1pi_read_fifo;
412 sc->writefifo = eqs1pi_write_fifo;
414 /* setup card type */
416 sc->sc_cardtyp = CARD_TYPEP_ELSAQS1ISA;
418 /* setup IOM bus type */
420 sc->sc_bustyp = BUS_TYPE_IOM2;
423 sc->sc_bfifolen = HSCX_FIFO_LEN;
425 /* setup ISAC and HSCX base addr */
427 ISAC_BASE = (caddr_t) ((u_int)dev->id_iobase | ELSA_IDISAC);
428 HSCX_A_BASE = (caddr_t) ((u_int)dev->id_iobase | ELSA_IDHSCXA);
429 HSCX_B_BASE = (caddr_t) ((u_int)dev->id_iobase | ELSA_IDHSCXB);
432 * Read HSCX A/B VSTR. Expected value for the ELSA QuickStep 1000pro
433 * ISA card is 0x05 ( = version 2.1 ) in the least significant bits.
436 if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) ||
437 ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
439 printf("isic%d: HSCX VSTR test failed for ELSA QuickStep 1000pro/ISA\n",
441 printf("isic%d: HSC0: VSTR: %#x\n",
442 dev->id_unit, HSCX_READ(0, H_VSTR));
443 printf("isic%d: HSC1: VSTR: %#x\n",
444 dev->id_unit, HSCX_READ(1, H_VSTR));
451 /*---------------------------------------------------------------------------*
452 * isic_attach_s0163P - attach ELSA QuickStep 1000pro/ISA
453 *---------------------------------------------------------------------------*/
455 isic_attach_Eqs1pi(struct isa_device *dev, unsigned int iobase2)
457 u_char byte = ELSA_CTRL_SECRET;
459 byte &= ~ELSA_CTRL_RESET;
460 outb(dev->id_iobase + ELSA_OFF_CTRL, byte);
462 byte |= ELSA_CTRL_RESET;
463 outb(dev->id_iobase + ELSA_OFF_CTRL, byte);
466 outb(dev->id_iobase + ELSA_OFF_IRQ, 0xff);
471 #else /* !__FreeBSD__ */
474 isic_attach_Eqs1pi(struct isic_softc *sc)
476 bus_space_tag_t t = sc->sc_maps[0].t;
477 bus_space_handle_t h = sc->sc_maps[0].h;
478 u_char byte = ELSA_CTRL_SECRET;
480 byte &= ~ELSA_CTRL_RESET;
481 bus_space_write_1(t, h, ELSA_OFF_CTRL, byte);
483 byte |= ELSA_CTRL_RESET;
484 bus_space_write_1(t, h, ELSA_OFF_CTRL, byte);
487 bus_space_write_1(t, h, ELSA_OFF_IRQ, 0xff);
489 /* setup access routines */
491 sc->clearirq = i4b_eq1i_clrirq;
492 sc->readreg = eqs1pi_read_reg;
493 sc->writereg = eqs1pi_write_reg;
495 sc->readfifo = eqs1pi_read_fifo;
496 sc->writefifo = eqs1pi_write_fifo;
498 /* setup card type */
500 sc->sc_cardtyp = CARD_TYPEP_ELSAQS1ISA;
502 /* setup IOM bus type */
504 sc->sc_bustyp = BUS_TYPE_IOM2;
507 sc->sc_bfifolen = HSCX_FIFO_LEN;
512 #endif /* (NISIC > 0) && (NPNP > 0) && defined(ELSA_QS1ISA) */