2 * Copyright (c) 1997, 2001 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 MicroLink ISDN/PCI
28 * ==================================================================
30 * $FreeBSD: src/sys/i4b/layer1/isic/i4b_elsa_qs1p.c,v 1.6.2.1 2001/08/10 14:08:38 obrien Exp $
31 * $DragonFly: src/sys/net/i4b/layer1/isic/i4b_elsa_qs1p.c,v 1.5 2005/05/24 20:59:05 dillon Exp $
33 * last edit-date: [Wed Jan 24 09:09:28 2001]
35 * Note: ELSA Quickstep 1000pro PCI = ELSA MicroLink ISDN/PCI
37 *---------------------------------------------------------------------------*/
43 #if (NISIC > 0) && (NPCI > 0) && defined(ELSA_QS1PCI)
45 #include <sys/param.h>
46 #include <sys/kernel.h>
47 #include <sys/systm.h>
48 #include <sys/socket.h>
52 #include <machine/bus.h>
56 #include <bus/pci/pcireg.h>
57 #include <bus/pci/pcivar.h>
59 #include <net/i4b/include/machine/i4b_ioctl.h>
65 #define PORT0_MAPOFF 4
66 #define PORT1_MAPOFF 12
68 #define ELSA_PORT0_MAPOFF (PCIR_MAPS+PORT0_MAPOFF)
69 #define ELSA_PORT1_MAPOFF (PCIR_MAPS+PORT1_MAPOFF)
71 #define PCI_QS1000_DID 0x1000
72 #define PCI_QS1000_VID 0x1048
74 /* masks for register encoded in base addr */
76 #define ELSA_BASE_MASK 0x0ffff
77 #define ELSA_OFF_MASK 0xf0000
79 /* register id's to be encoded in base addr */
81 #define ELSA_IDISAC 0x00000
82 #define ELSA_IDHSCXA 0x10000
83 #define ELSA_IDHSCXB 0x20000
84 #define ELSA_IDIPAC 0x40000
86 /* offsets from base address */
88 #define ELSA_OFF_ALE 0x00
89 #define ELSA_OFF_RW 0x01
92 static int eqs1p_pci_probe(device_t dev);
93 static int eqs1p_pci_attach(device_t dev);
95 static device_method_t eqs1p_pci_methods[] = {
96 /* Device interface */
97 DEVMETHOD(device_probe, eqs1p_pci_probe),
98 DEVMETHOD(device_attach, eqs1p_pci_attach),
102 static driver_t eqs1p_pci_driver = {
108 static devclass_t eqs1p_pci_devclass;
110 DRIVER_MODULE(eqs1p, pci, eqs1p_pci_driver, eqs1p_pci_devclass, 0, 0);
112 /*---------------------------------------------------------------------------*
113 * ELSA MicroLink ISDN/PCI fifo read routine
114 *---------------------------------------------------------------------------*/
116 eqs1pp_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
118 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[1]);
119 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]);
124 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF);
125 bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size);
127 case ISIC_WHAT_HSCXA:
128 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF);
129 bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size);
131 case ISIC_WHAT_HSCXB:
132 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF);
133 bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size);
138 /*---------------------------------------------------------------------------*
139 * ELSA MicroLink ISDN/PCI fifo write routine
140 *---------------------------------------------------------------------------*/
142 eqs1pp_write_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
144 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[1]);
145 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]);
150 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF);
151 bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size);
153 case ISIC_WHAT_HSCXA:
154 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF);
155 bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size);
157 case ISIC_WHAT_HSCXB:
158 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF);
159 bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size);
164 /*---------------------------------------------------------------------------*
165 * ELSA MicroLink ISDN/PCI register write routine
166 *---------------------------------------------------------------------------*/
168 eqs1pp_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data)
170 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[1]);
171 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]);
176 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF+offs);
177 bus_space_write_1(t, h, ELSA_OFF_RW, data);
179 case ISIC_WHAT_HSCXA:
180 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF+offs);
181 bus_space_write_1(t, h, ELSA_OFF_RW, data);
183 case ISIC_WHAT_HSCXB:
184 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF+offs);
185 bus_space_write_1(t, h, ELSA_OFF_RW, data);
188 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_IPAC_OFF+offs);
189 bus_space_write_1(t, h, ELSA_OFF_RW, data);
194 /*---------------------------------------------------------------------------*
195 * ELSA MicroLink ISDN/PCI register read routine
196 *---------------------------------------------------------------------------*/
198 eqs1pp_read_reg(struct l1_softc *sc, int what, bus_size_t offs)
200 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[1]);
201 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]);
206 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF+offs);
207 return bus_space_read_1(t, h, ELSA_OFF_RW);
208 case ISIC_WHAT_HSCXA:
209 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF+offs);
210 return bus_space_read_1(t, h, ELSA_OFF_RW);
211 case ISIC_WHAT_HSCXB:
212 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF+offs);
213 return bus_space_read_1(t, h, ELSA_OFF_RW);
215 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_IPAC_OFF+offs);
216 return bus_space_read_1(t, h, ELSA_OFF_RW);
221 /*---------------------------------------------------------------------------*
222 * avma1pp_probe - probe for a card
223 *---------------------------------------------------------------------------*/
225 eqs1p_pci_probe(device_t dev)
227 if((pci_get_vendor(dev) == PCI_QS1000_VID) &&
228 (pci_get_device(dev) == PCI_QS1000_DID))
230 device_set_desc(dev, "ELSA MicroLink ISDN/PCI");
236 /*---------------------------------------------------------------------------*
237 * isic_attach_Eqs1pp - attach for ELSA MicroLink ISDN/PCI
238 *---------------------------------------------------------------------------*/
240 eqs1p_pci_attach(device_t dev)
243 bus_space_handle_t h;
246 int unit = device_get_unit(dev);
248 /* check max unit range */
250 if(unit >= ISIC_MAXUNIT)
252 printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for ELSA MicroLink ISDN/PCI!\n",
257 sc = &l1_sc[unit]; /* get softc */
263 sc->sc_resources.io_rid[0] = ELSA_PORT0_MAPOFF;
265 if(!(sc->sc_resources.io_base[0] =
266 bus_alloc_resource(dev, SYS_RES_IOPORT,
267 &sc->sc_resources.io_rid[0],
268 0UL, ~0UL, 1, RF_ACTIVE)))
270 printf("isic%d: Couldn't get first iobase for ELSA MicroLink ISDN/PCI!\n", unit);
274 sc->sc_resources.io_rid[1] = ELSA_PORT1_MAPOFF;
276 if(!(sc->sc_resources.io_base[1] =
277 bus_alloc_resource(dev, SYS_RES_IOPORT,
278 &sc->sc_resources.io_rid[1],
279 0UL, ~0UL, 1, RF_ACTIVE)))
281 printf("isic%d: Couldn't get second iobase for ELSA MicroLink ISDN/PCI!\n", unit);
282 isic_detach_common(dev);
286 sc->sc_port = rman_get_start(sc->sc_resources.io_base[1]);
288 if(!(sc->sc_resources.irq =
289 bus_alloc_resource(dev, SYS_RES_IRQ,
290 &sc->sc_resources.irq_rid,
291 0UL, ~0UL, 1, RF_ACTIVE | RF_SHAREABLE)))
293 printf("isic%d: Could not get irq for ELSA MicroLink ISDN/PCI!\n",unit);
294 isic_detach_common(dev);
298 sc->sc_irq = rman_get_start(sc->sc_resources.irq);
300 /* setup access routines */
303 sc->readreg = eqs1pp_read_reg;
304 sc->writereg = eqs1pp_write_reg;
306 sc->readfifo = eqs1pp_read_fifo;
307 sc->writefifo = eqs1pp_write_fifo;
309 /* setup card type */
311 sc->sc_cardtyp = CARD_TYPEP_ELSAQS1PCI;
313 /* setup IOM bus type */
315 sc->sc_bustyp = BUS_TYPE_IOM2;
317 /* setup chip type = IPAC ! */
320 sc->sc_bfifolen = IPAC_BFIFO_LEN;
322 if(isic_attach_common(dev))
324 isic_detach_common(dev);
328 if (bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET,
329 (void(*)(void*))isicintr,
332 printf("isic%d: Couldn't set up irq for ELSA MicroLink ISDN/PCI!\n", unit);
333 isic_detach_common(dev);
337 /* enable hscx/isac irq's */
339 IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0));
341 IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */
342 IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */
343 (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2));
344 IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */
346 t = rman_get_bustag(sc->sc_resources.io_base[0]);
347 h = rman_get_bushandle(sc->sc_resources.io_base[0]);
349 bus_space_write_1(t, h, 0x4c, 0x41); /* enable card interrupt */
354 #endif /* (NISIC > 0) && (NPCI > 0) && defined(ELSA_QS1PCI) */