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 $
32 * last edit-date: [Wed Jan 24 09:09:28 2001]
34 * Note: ELSA Quickstep 1000pro PCI = ELSA MicroLink ISDN/PCI
36 *---------------------------------------------------------------------------*/
42 #if (NISIC > 0) && (NPCI > 0) && defined(ELSA_QS1PCI)
44 #include <sys/param.h>
45 #include <sys/kernel.h>
46 #include <sys/systm.h>
47 #include <sys/socket.h>
51 #include <bus/pci/pcireg.h>
52 #include <bus/pci/pcivar.h>
55 #include <net/i4b/include/machine/i4b_ioctl.h>
61 #define PORT0_MAPOFF 4
62 #define PORT1_MAPOFF 12
64 #define ELSA_PORT0_MAPOFF (PCIR_MAPS+PORT0_MAPOFF)
65 #define ELSA_PORT1_MAPOFF (PCIR_MAPS+PORT1_MAPOFF)
67 #define PCI_QS1000_DID 0x1000
68 #define PCI_QS1000_VID 0x1048
70 /* masks for register encoded in base addr */
72 #define ELSA_BASE_MASK 0x0ffff
73 #define ELSA_OFF_MASK 0xf0000
75 /* register id's to be encoded in base addr */
77 #define ELSA_IDISAC 0x00000
78 #define ELSA_IDHSCXA 0x10000
79 #define ELSA_IDHSCXB 0x20000
80 #define ELSA_IDIPAC 0x40000
82 /* offsets from base address */
84 #define ELSA_OFF_ALE 0x00
85 #define ELSA_OFF_RW 0x01
88 static int eqs1p_pci_probe(device_t dev);
89 static int eqs1p_pci_attach(device_t dev);
91 static device_method_t eqs1p_pci_methods[] = {
92 /* Device interface */
93 DEVMETHOD(device_probe, eqs1p_pci_probe),
94 DEVMETHOD(device_attach, eqs1p_pci_attach),
98 static driver_t eqs1p_pci_driver = {
104 static devclass_t eqs1p_pci_devclass;
106 DRIVER_MODULE(eqs1p, pci, eqs1p_pci_driver, eqs1p_pci_devclass, NULL, NULL);
108 /*---------------------------------------------------------------------------*
109 * ELSA MicroLink ISDN/PCI fifo read routine
110 *---------------------------------------------------------------------------*/
112 eqs1pp_read_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
114 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[1]);
115 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]);
120 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF);
121 bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size);
123 case ISIC_WHAT_HSCXA:
124 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF);
125 bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size);
127 case ISIC_WHAT_HSCXB:
128 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF);
129 bus_space_read_multi_1(t, h, ELSA_OFF_RW, buf, size);
134 /*---------------------------------------------------------------------------*
135 * ELSA MicroLink ISDN/PCI fifo write routine
136 *---------------------------------------------------------------------------*/
138 eqs1pp_write_fifo(struct l1_softc *sc, int what, void *buf, size_t size)
140 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[1]);
141 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]);
146 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF);
147 bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size);
149 case ISIC_WHAT_HSCXA:
150 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF);
151 bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size);
153 case ISIC_WHAT_HSCXB:
154 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF);
155 bus_space_write_multi_1(t, h, ELSA_OFF_RW, (u_int8_t*)buf, size);
160 /*---------------------------------------------------------------------------*
161 * ELSA MicroLink ISDN/PCI register write routine
162 *---------------------------------------------------------------------------*/
164 eqs1pp_write_reg(struct l1_softc *sc, int what, bus_size_t offs, u_int8_t data)
166 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[1]);
167 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]);
172 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF+offs);
173 bus_space_write_1(t, h, ELSA_OFF_RW, data);
175 case ISIC_WHAT_HSCXA:
176 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF+offs);
177 bus_space_write_1(t, h, ELSA_OFF_RW, data);
179 case ISIC_WHAT_HSCXB:
180 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF+offs);
181 bus_space_write_1(t, h, ELSA_OFF_RW, data);
184 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_IPAC_OFF+offs);
185 bus_space_write_1(t, h, ELSA_OFF_RW, data);
190 /*---------------------------------------------------------------------------*
191 * ELSA MicroLink ISDN/PCI register read routine
192 *---------------------------------------------------------------------------*/
194 eqs1pp_read_reg(struct l1_softc *sc, int what, bus_size_t offs)
196 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[1]);
197 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[1]);
202 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_ISAC_OFF+offs);
203 return bus_space_read_1(t, h, ELSA_OFF_RW);
204 case ISIC_WHAT_HSCXA:
205 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXA_OFF+offs);
206 return bus_space_read_1(t, h, ELSA_OFF_RW);
207 case ISIC_WHAT_HSCXB:
208 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_HSCXB_OFF+offs);
209 return bus_space_read_1(t, h, ELSA_OFF_RW);
211 bus_space_write_1(t, h, ELSA_OFF_ALE, IPAC_IPAC_OFF+offs);
212 return bus_space_read_1(t, h, ELSA_OFF_RW);
217 /*---------------------------------------------------------------------------*
218 * avma1pp_probe - probe for a card
219 *---------------------------------------------------------------------------*/
221 eqs1p_pci_probe(device_t dev)
223 if((pci_get_vendor(dev) == PCI_QS1000_VID) &&
224 (pci_get_device(dev) == PCI_QS1000_DID))
226 device_set_desc(dev, "ELSA MicroLink ISDN/PCI");
232 /*---------------------------------------------------------------------------*
233 * isic_attach_Eqs1pp - attach for ELSA MicroLink ISDN/PCI
234 *---------------------------------------------------------------------------*/
236 eqs1p_pci_attach(device_t dev)
239 bus_space_handle_t h;
242 int unit = device_get_unit(dev);
244 /* check max unit range */
246 if(unit >= ISIC_MAXUNIT)
248 kprintf("isic%d: Error, unit %d >= ISIC_MAXUNIT for ELSA MicroLink ISDN/PCI!\n",
253 sc = &l1_sc[unit]; /* get softc */
259 sc->sc_resources.io_rid[0] = ELSA_PORT0_MAPOFF;
261 if(!(sc->sc_resources.io_base[0] =
262 bus_alloc_resource(dev, SYS_RES_IOPORT,
263 &sc->sc_resources.io_rid[0],
264 0UL, ~0UL, 1, RF_ACTIVE)))
266 kprintf("isic%d: Couldn't get first iobase for ELSA MicroLink ISDN/PCI!\n", unit);
270 sc->sc_resources.io_rid[1] = ELSA_PORT1_MAPOFF;
272 if(!(sc->sc_resources.io_base[1] =
273 bus_alloc_resource(dev, SYS_RES_IOPORT,
274 &sc->sc_resources.io_rid[1],
275 0UL, ~0UL, 1, RF_ACTIVE)))
277 kprintf("isic%d: Couldn't get second iobase for ELSA MicroLink ISDN/PCI!\n", unit);
278 isic_detach_common(dev);
282 sc->sc_port = rman_get_start(sc->sc_resources.io_base[1]);
284 if(!(sc->sc_resources.irq =
285 bus_alloc_resource(dev, SYS_RES_IRQ,
286 &sc->sc_resources.irq_rid,
287 0UL, ~0UL, 1, RF_ACTIVE | RF_SHAREABLE)))
289 kprintf("isic%d: Could not get irq for ELSA MicroLink ISDN/PCI!\n",unit);
290 isic_detach_common(dev);
294 sc->sc_irq = rman_get_start(sc->sc_resources.irq);
296 /* setup access routines */
299 sc->readreg = eqs1pp_read_reg;
300 sc->writereg = eqs1pp_write_reg;
302 sc->readfifo = eqs1pp_read_fifo;
303 sc->writefifo = eqs1pp_write_fifo;
305 /* setup card type */
307 sc->sc_cardtyp = CARD_TYPEP_ELSAQS1PCI;
309 /* setup IOM bus type */
311 sc->sc_bustyp = BUS_TYPE_IOM2;
313 /* setup chip type = IPAC ! */
316 sc->sc_bfifolen = IPAC_BFIFO_LEN;
318 if(isic_attach_common(dev))
320 isic_detach_common(dev);
324 if (bus_setup_intr(dev, sc->sc_resources.irq, 0,
325 (void(*)(void*))isicintr,
328 kprintf("isic%d: Couldn't set up irq for ELSA MicroLink ISDN/PCI!\n", unit);
329 isic_detach_common(dev);
333 /* enable hscx/isac irq's */
335 IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0));
337 IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */
338 IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */
339 (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2));
340 IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */
342 t = rman_get_bustag(sc->sc_resources.io_base[0]);
343 h = rman_get_bushandle(sc->sc_resources.io_base[0]);
345 bus_space_write_1(t, h, 0x4c, 0x41); /* enable card interrupt */
350 #endif /* (NISIC > 0) && (NPCI > 0) && defined(ELSA_QS1PCI) */