summaryrefslogtreecommitdiffstats
path: root/sys/i4b
diff options
context:
space:
mode:
authorhm <hm@FreeBSD.org>2001-01-26 13:16:11 +0000
committerhm <hm@FreeBSD.org>2001-01-26 13:16:11 +0000
commitcb91e4fe80eacdb4ad1e48c068c22bf240e354f0 (patch)
tree055f49d9c260da71b070ecbea783ef5f4aa61bd6 /sys/i4b
parente1ad448f1deb07db95b9a06c4daf83b4097431d6 (diff)
downloadFreeBSD-src-cb91e4fe80eacdb4ad1e48c068c22bf240e354f0.zip
FreeBSD-src-cb91e4fe80eacdb4ad1e48c068c22bf240e354f0.tar.gz
Add experimental support for Eicon.Diehl DIVA 2.0 and 2.02 ISA PnP cards.
Thanks a lot to Jakob Schripsema (sch@kpn.com) for pointing out similarities of the Eicon 2.02 to the Siemens I-surf driver !
Diffstat (limited to 'sys/i4b')
-rw-r--r--sys/i4b/layer1/isic/i4b_diva.c398
-rw-r--r--sys/i4b/layer1/isic/i4b_isic.h4
-rw-r--r--sys/i4b/layer1/isic/i4b_isic_pnp.c21
3 files changed, 420 insertions, 3 deletions
diff --git a/sys/i4b/layer1/isic/i4b_diva.c b/sys/i4b/layer1/isic/i4b_diva.c
new file mode 100644
index 0000000..0177961
--- /dev/null
+++ b/sys/i4b/layer1/isic/i4b_diva.c
@@ -0,0 +1,398 @@
+/*
+ * Copyright (c) 2001 Hellmuth Michaelis. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *---------------------------------------------------------------------------
+ *
+ * Eicon Diehl DIVA 2.0 or 2.02 (ISA PnP) support for isic driver
+ * --------------------------------------------------------------
+ *
+ * $FreeBSD$
+ *
+ * last edit-date: [Fri Jan 26 13:57:10 2001]
+ *
+ *---------------------------------------------------------------------------*/
+
+#include "isic.h"
+#include "opt_i4b.h"
+
+#if NISIC > 0 && defined EICON_DIVA
+
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/socket.h>
+
+#include <net/if.h>
+
+#include <machine/i4b_ioctl.h>
+
+#include <i4b/layer1/isic/i4b_isic.h>
+#include <i4b/layer1/isic/i4b_ipac.h>
+#include <i4b/layer1/isic/i4b_isic.h>
+#include <i4b/layer1/isic/i4b_hscx.h>
+
+/* offsets from base address */
+
+#define DIVA_IPAC_OFF_ALE 0x00
+#define DIVA_IPAC_OFF_RW 0x01
+
+#define DIVA_ISAC_OFF_RW 0x02
+#define DIVA_ISAC_OFF_ALE 0x06
+
+#define DIVA_HSCX_OFF_RW 0x00
+#define DIVA_HSCX_OFF_ALE 0x04
+
+#define DIVA_CTRL_OFF 0x07
+#define DIVA_CTRL_RDIST 0x01
+#define DIVA_CTRL_WRRST 0x08
+#define DIVA_CTRL_WRLDA 0x20
+#define DIVA_CTRL_WRLDB 0x40
+#define DIVA_CTRL_WRICL 0x80
+
+/* HSCX channel base offsets */
+
+#define DIVA_HSCXA 0x00
+#define DIVA_HSCXB 0x40
+
+/*---------------------------------------------------------------------------*
+ * Eicon Diehl DIVA 2.02
+ *---------------------------------------------------------------------------*/
+static void
+diva_ipac_read_fifo(struct l1_softc *sc,int what,void *buf,size_t size)
+{
+ bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
+ bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
+
+ switch ( what )
+ {
+ case ISIC_WHAT_ISAC:
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,IPAC_ISAC_OFF);
+ bus_space_read_multi_1(t,h,DIVA_IPAC_OFF_RW,buf,size);
+ break;
+ case ISIC_WHAT_HSCXA:
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,IPAC_HSCXA_OFF);
+ bus_space_read_multi_1(t,h,DIVA_IPAC_OFF_RW,buf,size);
+ break;
+ case ISIC_WHAT_HSCXB:
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,IPAC_HSCXB_OFF);
+ bus_space_read_multi_1(t,h,DIVA_IPAC_OFF_RW,buf,size);
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Eicon Diehl DIVA 2.02
+ *---------------------------------------------------------------------------*/
+static void
+diva_ipac_write_fifo(struct l1_softc *sc,int what,void *buf,size_t size)
+{
+ bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
+ bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
+
+ switch ( what )
+ {
+ case ISIC_WHAT_ISAC:
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,IPAC_ISAC_OFF);
+ bus_space_write_multi_1(t,h,DIVA_IPAC_OFF_RW,buf,size);
+ break;
+ case ISIC_WHAT_HSCXA:
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,IPAC_HSCXA_OFF);
+ bus_space_write_multi_1(t,h,DIVA_IPAC_OFF_RW,buf,size);
+ break;
+ case ISIC_WHAT_HSCXB:
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,IPAC_HSCXB_OFF);
+ bus_space_write_multi_1(t,h,DIVA_IPAC_OFF_RW,buf,size);
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Eicon Diehl DIVA 2.02
+ *---------------------------------------------------------------------------*/
+static void
+diva_ipac_write_reg(struct l1_softc *sc,int what,bus_size_t reg,u_int8_t data)
+{
+ bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
+ bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
+
+ switch ( what )
+ {
+ case ISIC_WHAT_ISAC:
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_ISAC_OFF);
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_RW,data);
+ break;
+ case ISIC_WHAT_HSCXA:
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_HSCXA_OFF);
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_RW,data);
+ break;
+ case ISIC_WHAT_HSCXB:
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_HSCXB_OFF);
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_RW,data);
+ break;
+ case ISIC_WHAT_IPAC:
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_IPAC_OFF);
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_RW,data);
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Eicon Diehl DIVA 2.02
+ *---------------------------------------------------------------------------*/
+static u_int8_t
+diva_ipac_read_reg(struct l1_softc *sc,int what,bus_size_t reg)
+{
+ bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
+ bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
+
+ switch ( what )
+ {
+ case ISIC_WHAT_ISAC:
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_ISAC_OFF);
+ return bus_space_read_1(t,h,DIVA_IPAC_OFF_RW);
+ case ISIC_WHAT_HSCXA:
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_HSCXA_OFF);
+ return bus_space_read_1(t,h,DIVA_IPAC_OFF_RW);
+ case ISIC_WHAT_HSCXB:
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_HSCXB_OFF);
+ return bus_space_read_1(t,h,DIVA_IPAC_OFF_RW);
+ case ISIC_WHAT_IPAC:
+ bus_space_write_1(t,h,DIVA_IPAC_OFF_ALE,reg+IPAC_IPAC_OFF);
+ return bus_space_read_1(t,h,DIVA_IPAC_OFF_RW);
+ default:
+ return 0;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Eicon Diehl DIVA 2.02
+ *---------------------------------------------------------------------------*/
+int
+isic_attach_diva_ipac(device_t dev)
+{
+ int unit = device_get_unit(dev);
+ struct l1_softc *sc = &l1_sc[unit];
+
+ /* setup access routines */
+
+ sc->clearirq = NULL;
+ sc->readreg = diva_ipac_read_reg;
+ sc->writereg = diva_ipac_write_reg;
+
+ sc->readfifo = diva_ipac_read_fifo;
+ sc->writefifo = diva_ipac_write_fifo;
+
+ /* setup card type */
+
+ sc->sc_cardtyp = CARD_TYPEP_DIVA_ISA;
+
+ /* setup IOM bus type */
+
+ sc->sc_bustyp = BUS_TYPE_IOM2;
+
+ /* setup chip type = IPAC */
+
+ sc->sc_ipac = 1;
+ sc->sc_bfifolen = IPAC_BFIFO_LEN;
+
+ /* enable hscx/isac irq's */
+
+ IPAC_WRITE(IPAC_MASK, (IPAC_MASK_INT1 | IPAC_MASK_INT0));
+
+ IPAC_WRITE(IPAC_ACFG, 0); /* outputs are open drain */
+
+ IPAC_WRITE(IPAC_AOE, /* aux 5..2 are inputs, 7, 6 outputs */
+ (IPAC_AOE_OE5 | IPAC_AOE_OE4 | IPAC_AOE_OE3 | IPAC_AOE_OE2));
+
+ IPAC_WRITE(IPAC_ATX, 0xff); /* set all output lines high */
+
+ return(0);
+}
+
+/*---------------------------------------------------------------------------*
+ * Eicon Diehl DIVA 2.0
+ *---------------------------------------------------------------------------*/
+static void
+diva_read_fifo(struct l1_softc *sc,int what,void *buf,size_t size)
+{
+ bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
+ bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
+
+ switch(what)
+ {
+ case ISIC_WHAT_ISAC:
+ bus_space_write_1(t,h,DIVA_ISAC_OFF_ALE,0);
+ bus_space_read_multi_1(t,h,DIVA_ISAC_OFF_RW,buf,size);
+ break;
+
+ case ISIC_WHAT_HSCXA:
+ bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,DIVA_HSCXA);
+ bus_space_read_multi_1(t,h,DIVA_HSCX_OFF_RW,buf,size);
+ break;
+
+ case ISIC_WHAT_HSCXB:
+ bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,DIVA_HSCXB);
+ bus_space_read_multi_1(t,h,DIVA_HSCX_OFF_RW,buf,size);
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Eicon Diehl DIVA 2.0
+ *---------------------------------------------------------------------------*/
+static void
+diva_write_fifo(struct l1_softc *sc,int what,void *buf,size_t size)
+{
+ bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
+ bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
+
+ switch(what)
+ {
+ case ISIC_WHAT_ISAC:
+ bus_space_write_1(t,h,DIVA_ISAC_OFF_ALE,0);
+ bus_space_write_multi_1(t,h,DIVA_ISAC_OFF_RW,buf,size);
+ break;
+
+ case ISIC_WHAT_HSCXA:
+ bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,DIVA_HSCXA);
+ bus_space_write_multi_1(t,h,DIVA_HSCX_OFF_RW,buf,size);
+ break;
+
+ case ISIC_WHAT_HSCXB:
+ bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,DIVA_HSCXB);
+ bus_space_write_multi_1(t,h,DIVA_HSCX_OFF_RW,buf,size);
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Eicon Diehl DIVA 2.0
+ *---------------------------------------------------------------------------*/
+static void
+diva_write_reg(struct l1_softc *sc,int what,bus_size_t reg,u_int8_t data)
+{
+ bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
+ bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
+
+ switch(what)
+ {
+ case ISIC_WHAT_ISAC:
+ bus_space_write_1(t,h,DIVA_ISAC_OFF_ALE,reg);
+ bus_space_write_1(t,h,DIVA_ISAC_OFF_RW,data);
+ break;
+
+ case ISIC_WHAT_HSCXA:
+ bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,reg+DIVA_HSCXA);
+ bus_space_write_1(t,h,DIVA_HSCX_OFF_RW,data);
+ break;
+
+ case ISIC_WHAT_HSCXB:
+ bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,reg+DIVA_HSCXB);
+ bus_space_write_1(t,h,DIVA_HSCX_OFF_RW,data);
+ break;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Eicon Diehl DIVA 2.0
+ *---------------------------------------------------------------------------*/
+static u_int8_t
+diva_read_reg(struct l1_softc *sc,int what,bus_size_t reg)
+{
+ bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
+ bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
+
+ switch(what)
+ {
+ case ISIC_WHAT_ISAC:
+ bus_space_write_1(t,h,DIVA_ISAC_OFF_ALE,reg);
+ return bus_space_read_1(t,h,DIVA_ISAC_OFF_RW);
+
+ case ISIC_WHAT_HSCXA:
+ bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,reg+DIVA_HSCXA);
+ return bus_space_read_1(t,h,DIVA_HSCX_OFF_RW);
+
+ case ISIC_WHAT_HSCXB:
+ bus_space_write_1(t,h,DIVA_HSCX_OFF_ALE,reg+DIVA_HSCXB);
+ return bus_space_read_1(t,h,DIVA_HSCX_OFF_RW);
+
+ default:
+ return 0;
+ }
+}
+
+/*---------------------------------------------------------------------------*
+ * Eicon Diehl DIVA 2.0
+ *---------------------------------------------------------------------------*/
+int
+isic_attach_diva(device_t dev)
+{
+ int unit = device_get_unit(dev);
+ struct l1_softc *sc = &l1_sc[unit];
+ bus_space_tag_t t = rman_get_bustag(sc->sc_resources.io_base[0]);
+ bus_space_handle_t h = rman_get_bushandle(sc->sc_resources.io_base[0]);
+
+ /* setup access routines */
+
+ sc->clearirq = NULL;
+ sc->readreg = diva_read_reg;
+ sc->writereg = diva_write_reg;
+
+ sc->readfifo = diva_read_fifo;
+ sc->writefifo = diva_write_fifo;
+
+ /* setup card type */
+
+ sc->sc_cardtyp = CARD_TYPEP_DIVA_ISA;
+
+ /* setup IOM bus type */
+
+ sc->sc_bustyp = BUS_TYPE_IOM2;
+
+ /* setup chip type = ISAC/HSCX */
+
+ sc->sc_ipac = 0;
+ sc->sc_bfifolen = HSCX_FIFO_LEN;
+
+ /* Read HSCX A/B VSTR. Expected value is 0x05 (V2.1). */
+
+ if( ((HSCX_READ(0, H_VSTR) & 0xf) != 0x5) ||
+ ((HSCX_READ(1, H_VSTR) & 0xf) != 0x5) )
+ {
+ printf("isic%d: HSCX VSTR test failed for Eicon DIVA 2.0\n",
+ sc->sc_unit);
+ printf("isic%d: HSC0: VSTR: %#x\n",
+ sc->sc_unit, HSCX_READ(0, H_VSTR));
+ printf("isic%d: HSC1: VSTR: %#x\n",
+ sc->sc_unit, HSCX_READ(1, H_VSTR));
+ return ENXIO;
+ }
+ /* reset on */
+ bus_space_write_1(t,h,DIVA_CTRL_OFF,0);
+ DELAY(100);
+ /* reset off */
+ bus_space_write_1(t,h,DIVA_CTRL_OFF,DIVA_CTRL_WRRST);
+ return(0);
+}
+
+#endif /* NISIC > 0 && defined EICON_DIVA */
diff --git a/sys/i4b/layer1/isic/i4b_isic.h b/sys/i4b/layer1/isic/i4b_isic.h
index bab0215..feb06af 100644
--- a/sys/i4b/layer1/isic/i4b_isic.h
+++ b/sys/i4b/layer1/isic/i4b_isic.h
@@ -29,7 +29,7 @@
*
* $FreeBSD$
*
- * last edit-date: [Wed Jan 24 09:23:24 2001]
+ * last edit-date: [Fri Jan 26 13:55:12 2001]
*
*---------------------------------------------------------------------------*/
@@ -323,5 +323,7 @@ extern int isic_attach_sws(device_t dev);
extern int isic_attach_siemens_isurf(device_t dev);
extern int isic_attach_asi(device_t dev);
extern int isic_attach_Dyn(device_t dev);
+extern int isic_attach_diva(device_t dev);
+extern int isic_attach_diva_ipac(device_t dev);
#endif /* _I4B_ISIC_H_ */
diff --git a/sys/i4b/layer1/isic/i4b_isic_pnp.c b/sys/i4b/layer1/isic/i4b_isic_pnp.c
index 099d256..e02878d 100644
--- a/sys/i4b/layer1/isic/i4b_isic_pnp.c
+++ b/sys/i4b/layer1/isic/i4b_isic_pnp.c
@@ -39,7 +39,7 @@
*
* $FreeBSD$
*
- * last edit-date: [Wed Jan 24 09:31:38 2001]
+ * last edit-date: [Fri Jan 26 14:01:04 2001]
*
*---------------------------------------------------------------------------*/
@@ -69,6 +69,8 @@
#define VID_AVMPNP 0x0009cd06 /* AVM Fritz! PnP */
#define VID_SIESURF2 0x2000254d /* Siemens I-Surf 2.0 PnP*/
#define VID_ASUSCOM_IPAC 0x90167506 /* Asuscom (with IPAC) */
+#define VID_EICON_DIVA_20 0x7100891c /* Eicon DIVA 2.0 ISAC/HSCX */
+#define VID_EICON_DIVA_202 0xa100891c /* Eicon DIVA 2.02 IPAC */
static struct isic_pnp_ids {
u_long vend_id;
@@ -97,11 +99,15 @@ static struct isic_pnp_ids {
{ VID_AVMPNP, "AVM Fritz!Card PnP" },
#endif
#ifdef SIEMENS_ISURF2
- { VID_SIESURF2, "Siemens I-Surf 2.0 PnP" },
+ { VID_SIESURF2, "Siemens I-Surf 2.0 PnP" },
#endif
#ifdef ASUSCOM_IPAC
{ VID_ASUSCOM_IPAC, "Asuscom ISDNLink 128 PnP" },
#endif
+#ifdef EICON_DIVA
+ { VID_EICON_DIVA_20, "Eicon.Diehl DIVA 2.0 ISA PnP" },
+ { VID_EICON_DIVA_202, "Eicon.Diehl DIVA 2.02 ISA PnP" },
+#endif
{ 0, 0 }
};
@@ -270,6 +276,17 @@ isic_pnp_attach(device_t dev)
ret = isic_attach_asi(dev);
break;
#endif
+#ifdef EICON_DIVA
+ case VID_EICON_DIVA_20:
+ sc->sc_cardtyp = CARD_TYPEP_DIVA_ISA;
+ ret = isic_attach_diva(dev);
+ break;
+
+ case VID_EICON_DIVA_202:
+ sc->sc_cardtyp = CARD_TYPEP_DIVA_ISA;
+ ret = isic_attach_diva_ipac(dev);
+ break;
+#endif
default:
printf("isic%d: Error, no driver for %s\n", unit, name);
ret = ENXIO;
OpenPOWER on IntegriCloud