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
26 /*---------------------------------------------------------------------------
28 * isic - I4B Siemens ISDN Chipset Driver for ELSA MicroLink ISDN/PCI
29 * ==================================================================
30 * last edit-date: [Wed Jan 24 09:09:28 2001]
32 * Note: ELSA Quickstep 1000pro PCI = ELSA MicroLink ISDN/PCI
34 *---------------------------------------------------------------------------*/
36 #include <sys/cdefs.h>
37 __FBSDID("$FreeBSD$");
41 #if defined(ELSA_QS1PCI)
43 #include <sys/param.h>
44 #include <sys/kernel.h>
45 #include <sys/module.h>
46 #include <sys/systm.h>
47 #include <sys/socket.h>
51 #include <machine/bus.h>
55 #include <dev/pci/pcireg.h>
56 #include <dev/pci/pcivar.h>
58 #include <i4b/include/i4b_ioctl.h>
60 #include <i4b/layer1/isic/i4b_isic.h>
61 #include <i4b/layer1/isic/i4b_ipac.h>
67 #define ELSA_PORT0_MAPOFF PCIR_BAR(PORT0_BAR)
68 #define ELSA_PORT1_MAPOFF PCIR_BAR(PORT1_BAR)
70 #define PCI_QS1000_DID 0x1000
71 #define PCI_QS1000_VID 0x1048
73 /* masks for register encoded in base addr */
75 #define ELSA_BASE_MASK 0x0ffff
76 #define ELSA_OFF_MASK 0xf0000
78 /* register id's to be encoded in base addr */
80 #define ELSA_IDISAC 0x00000
81 #define ELSA_IDHSCXA 0x10000
82 #define ELSA_IDHSCXB 0x20000
83 #define ELSA_IDIPAC 0x40000
85 /* offsets from base address */
87 #define ELSA_OFF_ALE 0x00
88 #define ELSA_OFF_RW 0x01
91 static int eqs1p_pci_probe(device_t dev);
92 static int eqs1p_pci_attach(device_t dev);
94 static device_method_t eqs1p_pci_methods[] = {
95 /* Device interface */
96 DEVMETHOD(device_probe, eqs1p_pci_probe),
97 DEVMETHOD(device_attach, eqs1p_pci_attach),
101 static driver_t eqs1p_pci_driver = {
107 static devclass_t eqs1p_pci_devclass;
109 DRIVER_MODULE(eqs1p, pci, eqs1p_pci_driver, eqs1p_pci_devclass, 0, 0);
111 /*---------------------------------------------------------------------------*
112 * ELSA MicroLink ISDN/PCI fifo read routine
113 *---------------------------------------------------------------------------*/
115 eqs1pp_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
117 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[1]);
118 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]);
123 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF);
124 bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size);
126 case ISIC_WHAT_HSCXA:
127 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF);
128 bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size);
130 case ISIC_WHAT_HSCXB:
131 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF);
132 bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size);
137 /*---------------------------------------------------------------------------*
138 * ELSA MicroLink ISDN/PCI fifo write routine
139 *---------------------------------------------------------------------------*/
141 eqs1pp_write_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
143 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[1]);
144 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]);
149 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF);
150 bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size);
152 case ISIC_WHAT_HSCXA:
153 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF);
154 bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size);
156 case ISIC_WHAT_HSCXB:
157 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF);
158 bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size);
163 /*---------------------------------------------------------------------------*
164 * ELSA MicroLink ISDN/PCI register write routine
165 *---------------------------------------------------------------------------*/
167 eqs1pp_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data)
169 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[1]);
170 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]);
175 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF+offs);
176 bus_space_write_1(t, h, ELSA_OFF_RW, data);
178 case ISIC_WHAT_HSCXA:
179 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF+offs);
180 bus_space_write_1(t, h, ELSA_OFF_RW, data);
182 case ISIC_WHAT_HSCXB:
183 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF+offs);
184 bus_space_write_1(t, h, ELSA_OFF_RW, data);
187 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_IPAC_OFF+offs);
188 bus_space_write_1(t, h, ELSA_OFF_RW, data);
193 /*---------------------------------------------------------------------------*
194 * ELSA MicroLink ISDN/PCI register read routine
195 *---------------------------------------------------------------------------*/
197 eqs1pp_read_reg(struct l1_softc *sc, int what, bus_size_t offs)
199 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[1]);
200 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]);
205 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF+offs);
206 return bus_space_read_1(t, h, ELSA_OFF_RW);
207 case ISIC_WHAT_HSCXA:
208 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF+offs);
209 return bus_space_read_1(t, h, ELSA_OFF_RW);
210 case ISIC_WHAT_HSCXB:
211 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF+offs);
212 return bus_space_read_1(t, h, ELSA_OFF_RW);
214 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_IPAC_OFF+offs);
215 return bus_space_read_1(t, h, ELSA_OFF_RW);
220 /*---------------------------------------------------------------------------*
221 * avma1pp_probe - probe for a card
222 *---------------------------------------------------------------------------*/
224 eqs1p_pci_probe(device_t dev)
226 if((pci_get_vendor(dev) == PCI_QS1000_VID) &&
227 (pci_get_device(dev) == PCI_QS1000_DID))
229 device_set_desc(dev, "ELSA MicroLink ISDN/PCI");
235 /*---------------------------------------------------------------------------*
236 * isic_attach_Eqs1pp - attach for ELSA MicroLink ISDN/PCI
237 *---------------------------------------------------------------------------*/
239 eqs1p_pci_attach(device_t dev)
242 bus_space_handle_t h;
245 int unit = device_get_unit(dev);
247 /* check max unit range */
249 if(unit >= ISIC_MAXUNIT)
251 printf("isic%d: Error, unit %d >= ISIC_MAXUNIT for ELSA MicroLink ISDN/PCI!\n",
256 sc = &l1_sc[unit]; /* get softc */
262 sc->sc_resources.io_rid[0] = ELSA_PORT0_MAPOFF;
264 if(!(sc->sc_resources.io_base[0] =
265 bus_alloc_resource_any(dev, SYS_RES_IOPORT,
266 &sc->sc_resources.io_rid[0],
269 printf("isic%d: Couldn't get first iobase for ELSA MicroLink ISDN/PCI!\n", unit);
273 sc->sc_resources.io_rid[1] = ELSA_PORT1_MAPOFF;
275 if(!(sc->sc_resources.io_base[1] =
276 bus_alloc_resource_any(dev, SYS_RES_IOPORT,
277 &sc->sc_resources.io_rid[1],
280 printf("isic%d: Couldn't get second iobase for ELSA MicroLink ISDN/PCI!\n", unit);
281 isic_detach_common(dev);
285 sc->sc_port = rman_get_start(sc->sc_resources.io_base[1]);
287 if(!(sc->sc_resources.irq =
288 bus_alloc_resource_any(dev, SYS_RES_IRQ,
289 &sc->sc_resources.irq_rid,
290 RF_ACTIVE | RF_SHAREABLE)))
292 printf("isic%d: Could not get irq for ELSA MicroLink ISDN/PCI!\n",unit);
293 isic_detach_common(dev);
297 sc->sc_irq = rman_get_start(sc->sc_resources.irq);
299 /* setup access routines */
302 sc->readreg = eqs1pp_read_reg;
303 sc->writereg = eqs1pp_write_reg;
305 sc->readfifo = eqs1pp_read_fifo;
306 sc->writefifo = eqs1pp_write_fifo;
308 /* setup card type */
310 sc->sc_cardtyp = CARD_TYPEP_ELSAQS1PCI;
312 /* setup IOM bus type */
314 sc->sc_bustyp = BUS_TYPE_IOM2;
316 /* setup chip type = IPAC ! */
319 sc->sc_bfifolen = IPAC_BFIFO_LEN;
321 if(isic_attach_common(dev))
323 isic_detach_common(dev);
327 if(bus_setup_intr(dev, sc->sc_resources.irq, INTR_TYPE_NET,
328 NULL, (void(*)(void*))isicintr,
331 printf("isic%d: Couldn't set up irq for ELSA MicroLink ISDN/PCI!\n", unit);
332 isic_detach_common(dev);
336 /* enable hscx/isac irq's */
338 IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0));
340 IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */
341 IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */
342 (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2));
343 IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */
345 t = rman_get_bustag(sc->sc_resources.io_base[0]);
346 h = rman_get_bushandle(sc->sc_resources.io_base[0]);
348 bus_space_write_1(t, h, 0x4c, 0x41); /* enable card interrupt */
353 #endif /* defined(ELSA_QS1PCI) */