2 * Copyright (c) 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 * Eicon Diehl DIVA 2.0 or 2.02 (ISA PnP) support for isic driver
28 * --------------------------------------------------------------
30 * $FreeBSD: src/sys/i4b/layer1/isic/i4b_diva.c,v 1.1.2.1 2001/08/10 14:08:38 obrien Exp $
31 * $DragonFly: src/sys/net/i4b/layer1/isic/i4b_diva.c,v 1.5 2006/12/22 23:44:56 swildner Exp $
33 * last edit-date: [Fri Jan 26 13:57:10 2001]
35 *---------------------------------------------------------------------------*/
40 #if NISIC > 0 && defined EICON_DIVA
42 #include <sys/param.h>
43 #include <sys/systm.h>
44 #include <sys/socket.h>
48 #include <net/i4b/include/machine/i4b_ioctl.h>
55 /* offsets from base address */
57 #define DIVA_IPAC_OFF_ALE 0x00
58 #define DIVA_IPAC_OFF_RW 0x01
60 #define DIVA_ISAC_OFF_RW 0x02
61 #define DIVA_ISAC_OFF_ALE 0x06
63 #define DIVA_HSCX_OFF_RW 0x00
64 #define DIVA_HSCX_OFF_ALE 0x04
66 #define DIVA_CTRL_OFF 0x07
67 #define DIVA_CTRL_RDIST 0x01
68 #define DIVA_CTRL_WRRST 0x08
69 #define DIVA_CTRL_WRLDA 0x20
70 #define DIVA_CTRL_WRLDB 0x40
71 #define DIVA_CTRL_WRICL 0x80
73 /* HSCX channel base offsets */
75 #define DIVA_HSCXA 0x00
76 #define DIVA_HSCXB 0x40
78 /*---------------------------------------------------------------------------*
79 * Eicon Diehl DIVA 2.02
80 *---------------------------------------------------------------------------*/
82 diva_ipac_read_fifo(struct l1_softc *sc,int what,void *buf,size_t size)
84 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
85 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
90 bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,IPAC_ISAC_OFF);
91 bus_space_read_multi_1(t,h,DIVA_IPAC_OFF_RW,buf,size);
94 bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,IPAC_HSCXA_OFF);
95 bus_space_read_multi_1(t,h,DIVA_IPAC_OFF_RW,buf,size);
98 bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,IPAC_HSCXB_OFF);
99 bus_space_read_multi_1(t,h,DIVA_IPAC_OFF_RW,buf,size);
104 /*---------------------------------------------------------------------------*
105 * Eicon Diehl DIVA 2.02
106 *---------------------------------------------------------------------------*/
108 diva_ipac_write_fifo(struct l1_softc *sc,int what,void *buf,size_t size)
110 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
111 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
116 bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,IPAC_ISAC_OFF);
117 bus_space_write_multi_1(t,h,DIVA_IPAC_OFF_RW,buf,size);
119 case ISIC_WHAT_HSCXA:
120 bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,IPAC_HSCXA_OFF);
121 bus_space_write_multi_1(t,h,DIVA_IPAC_OFF_RW,buf,size);
123 case ISIC_WHAT_HSCXB:
124 bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,IPAC_HSCXB_OFF);
125 bus_space_write_multi_1(t,h,DIVA_IPAC_OFF_RW,buf,size);
130 /*---------------------------------------------------------------------------*
131 * Eicon Diehl DIVA 2.02
132 *---------------------------------------------------------------------------*/
134 diva_ipac_write_reg(struct l1_softc *sc,int what,bus_size_t reg,u_int8_t data)
136 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
137 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
142 bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_ISAC_OFF);
143 bus_space_write_1(t,h,DIVA_IPAC_OFF_RW,data);
145 case ISIC_WHAT_HSCXA:
146 bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_HSCXA_OFF);
147 bus_space_write_1(t,h,DIVA_IPAC_OFF_RW,data);
149 case ISIC_WHAT_HSCXB:
150 bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_HSCXB_OFF);
151 bus_space_write_1(t,h,DIVA_IPAC_OFF_RW,data);
154 bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_IPAC_OFF);
155 bus_space_write_1(t,h,DIVA_IPAC_OFF_RW,data);
160 /*---------------------------------------------------------------------------*
161 * Eicon Diehl DIVA 2.02
162 *---------------------------------------------------------------------------*/
164 diva_ipac_read_reg(struct l1_softc *sc,int what,bus_size_t reg)
166 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
167 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
172 bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_ISAC_OFF);
173 return bus_space_read_1(t,h,DIVA_IPAC_OFF_RW);
174 case ISIC_WHAT_HSCXA:
175 bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_HSCXA_OFF);
176 return bus_space_read_1(t,h,DIVA_IPAC_OFF_RW);
177 case ISIC_WHAT_HSCXB:
178 bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_HSCXB_OFF);
179 return bus_space_read_1(t,h,DIVA_IPAC_OFF_RW);
181 bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_IPAC_OFF);
182 return bus_space_read_1(t,h,DIVA_IPAC_OFF_RW);
188 /*---------------------------------------------------------------------------*
189 * Eicon Diehl DIVA 2.02
190 *---------------------------------------------------------------------------*/
192 isic_attach_diva_ipac(device_t dev)
194 int unit = device_get_unit(dev);
195 struct l1_softc *sc = &l1_sc[unit];
197 /* setup access routines */
200 sc->readreg = diva_ipac_read_reg;
201 sc->writereg = diva_ipac_write_reg;
203 sc->readfifo = diva_ipac_read_fifo;
204 sc->writefifo = diva_ipac_write_fifo;
206 /* setup card type */
208 sc->sc_cardtyp = CARD_TYPEP_DIVA_ISA;
210 /* setup IOM bus type */
212 sc->sc_bustyp = BUS_TYPE_IOM2;
214 /* setup chip type = IPAC */
217 sc->sc_bfifolen = IPAC_BFIFO_LEN;
219 /* enable hscx/isac irq's */
221 IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0));
223 IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */
225 IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */
226 (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2));
228 IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */
233 /*---------------------------------------------------------------------------*
234 * Eicon Diehl DIVA 2.0
235 *---------------------------------------------------------------------------*/
237 diva_read_fifo(struct l1_softc *sc,int what,void *buf,size_t size)
239 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
240 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
245 bus_space_write_1(t,h,DIVA_ISAC_OFF_ALE,0);
246 bus_space_read_multi_1(t,h,DIVA_ISAC_OFF_RW,buf,size);
249 case ISIC_WHAT_HSCXA:
250 bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,DIVA_HSCXA);
251 bus_space_read_multi_1(t,h,DIVA_HSCX_OFF_RW,buf,size);
254 case ISIC_WHAT_HSCXB:
255 bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,DIVA_HSCXB);
256 bus_space_read_multi_1(t,h,DIVA_HSCX_OFF_RW,buf,size);
261 /*---------------------------------------------------------------------------*
262 * Eicon Diehl DIVA 2.0
263 *---------------------------------------------------------------------------*/
265 diva_write_fifo(struct l1_softc *sc,int what,void *buf,size_t size)
267 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
268 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
273 bus_space_write_1(t,h,DIVA_ISAC_OFF_ALE,0);
274 bus_space_write_multi_1(t,h,DIVA_ISAC_OFF_RW,buf,size);
277 case ISIC_WHAT_HSCXA:
278 bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,DIVA_HSCXA);
279 bus_space_write_multi_1(t,h,DIVA_HSCX_OFF_RW,buf,size);
282 case ISIC_WHAT_HSCXB:
283 bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,DIVA_HSCXB);
284 bus_space_write_multi_1(t,h,DIVA_HSCX_OFF_RW,buf,size);
289 /*---------------------------------------------------------------------------*
290 * Eicon Diehl DIVA 2.0
291 *---------------------------------------------------------------------------*/
293 diva_write_reg(struct l1_softc *sc,int what,bus_size_t reg,u_int8_t data)
295 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
296 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
301 bus_space_write_1(t,h,DIVA_ISAC_OFF_ALE,reg);
302 bus_space_write_1(t,h,DIVA_ISAC_OFF_RW,data);
305 case ISIC_WHAT_HSCXA:
306 bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,reg+DIVA_HSCXA);
307 bus_space_write_1(t,h,DIVA_HSCX_OFF_RW,data);
310 case ISIC_WHAT_HSCXB:
311 bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,reg+DIVA_HSCXB);
312 bus_space_write_1(t,h,DIVA_HSCX_OFF_RW,data);
317 /*---------------------------------------------------------------------------*
318 * Eicon Diehl DIVA 2.0
319 *---------------------------------------------------------------------------*/
321 diva_read_reg(struct l1_softc *sc,int what,bus_size_t reg)
323 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
324 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
329 bus_space_write_1(t,h,DIVA_ISAC_OFF_ALE,reg);
330 return bus_space_read_1(t,h,DIVA_ISAC_OFF_RW);
332 case ISIC_WHAT_HSCXA:
333 bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,reg+DIVA_HSCXA);
334 return bus_space_read_1(t,h,DIVA_HSCX_OFF_RW);
336 case ISIC_WHAT_HSCXB:
337 bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,reg+DIVA_HSCXB);
338 return bus_space_read_1(t,h,DIVA_HSCX_OFF_RW);
345 /*---------------------------------------------------------------------------*
346 * Eicon Diehl DIVA 2.0
347 *---------------------------------------------------------------------------*/
349 isic_attach_diva(device_t dev)
351 int unit = device_get_unit(dev);
352 struct l1_softc *sc = &l1_sc[unit];
353 bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
354 bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
356 /* setup access routines */
359 sc->readreg = diva_read_reg;
360 sc->writereg = diva_write_reg;
362 sc->readfifo = diva_read_fifo;
363 sc->writefifo = diva_write_fifo;
365 /* setup card type */
367 sc->sc_cardtyp = CARD_TYPEP_DIVA_ISA;
369 /* setup IOM bus type */
371 sc->sc_bustyp = BUS_TYPE_IOM2;
373 /* setup chip type = ISAC/HSCX */
376 sc->sc_bfifolen = HSCX_FIFO_LEN;
378 /* Read HSCX A/B VSTR. Expected value is 0x05 (V2.1). */
380 if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) ||
381 ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
383 kprintf("isic%d: HSCX VSTR test failed for Eicon DIVA 2.0\n",
385 kprintf("isic%d: HSC0: VSTR: %#x\n",
386 sc->sc_unit, HSCX_READ(0, H_VSTR));
387 kprintf("isic%d: HSC1: VSTR: %#x\n",
388 sc->sc_unit, HSCX_READ(1, H_VSTR));
392 bus_space_write_1(t,h,DIVA_CTRL_OFF,0);
395 bus_space_write_1(t,h,DIVA_CTRL_OFF,DIVA_CTRL_WRRST);
399 #endif /* NISIC > 0 && defined EICON_DIVA */