Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev A backend for Databook's TCIC family of PCMCIA chips.



details:   https://anonhg.NetBSD.org/src/rev/91cbbe6750b3
branches:  trunk
changeset: 467361:91cbbe6750b3
user:      bad <bad%NetBSD.org@localhost>
date:      Tue Mar 23 20:04:14 1999 +0000

description:
A backend for Databook's TCIC family of PCMCIA chips.

Thanks to Andreas Lohrum, O'Reilly Verlag, Terry Moore, and Holger Czukay
for hardware, documentation, and support.

diffstat:

 sys/dev/ic/tcic2.c      |  1402 +++++++++++++++++++++++++++++++++++++++++++++++
 sys/dev/ic/tcic2reg.h   |   826 +++++++++++++++++++++++++++
 sys/dev/ic/tcic2var.h   |   358 ++++++++++++
 sys/dev/isa/tcic2_isa.c |   369 ++++++++++++
 4 files changed, 2955 insertions(+), 0 deletions(-)

diffs (truncated from 2971 to 300 lines):

diff -r b553d26ad161 -r 91cbbe6750b3 sys/dev/ic/tcic2.c
--- /dev/null   Thu Jan 01 00:00:00 1970 +0000
+++ b/sys/dev/ic/tcic2.c        Tue Mar 23 20:04:14 1999 +0000
@@ -0,0 +1,1402 @@
+/*     $NetBSD: tcic2.c,v 1.1 1999/03/23 20:04:14 bad Exp $    */
+
+#undef TCICDEBUG
+
+/*
+ * Copyright (c) 1998, 1999 Christoph Badura.  All rights reserved.
+ * Copyright (c) 1997 Marc Horowitz.  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.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *     This product includes software developed by Marc Horowitz.
+ * 4. The name of the author may not be used to endorse or promote products
+ *    derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+#include <sys/extent.h>
+#include <sys/malloc.h>
+#include <sys/kthread.h>
+
+#include <vm/vm.h>
+
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <dev/pcmcia/pcmciareg.h>
+#include <dev/pcmcia/pcmciavar.h>
+
+#include <dev/ic/tcic2reg.h>
+#include <dev/ic/tcic2var.h>
+
+#include "locators.h"
+
+#ifdef TCICDEBUG
+int    tcic_debug = 1;
+#define        DPRINTF(arg) if (tcic_debug) printf arg;
+#else
+#define        DPRINTF(arg)
+#endif
+
+/*
+ * Individual drivers will allocate their own memory and io regions. Memory
+ * regions must be a multiple of 4k, aligned on a 4k boundary.
+ */
+
+#define        TCIC_MEM_ALIGN  TCIC_MEM_PAGESIZE
+
+void   tcic_attach_socket __P((struct tcic_handle *));
+void   tcic_init_socket __P((struct tcic_handle *));
+
+int    tcic_submatch __P((struct device *, struct cfdata *, void *));
+int    tcic_print  __P((void *arg, const char *pnp));
+int    tcic_intr_socket __P((struct tcic_handle *));
+
+void   tcic_attach_card __P((struct tcic_handle *));
+void   tcic_detach_card __P((struct tcic_handle *, int));
+void   tcic_deactivate_card __P((struct tcic_handle *));
+
+void   tcic_chip_do_mem_map __P((struct tcic_handle *, int));
+void   tcic_chip_do_io_map __P((struct tcic_handle *, int));
+
+void   tcic_create_event_thread __P((void *));
+void   tcic_event_thread __P((void *));
+
+void   tcic_queue_event __P((struct tcic_handle *, int));
+
+/* Map between irq numbers and internal representation */
+#if 1
+int tcic_irqmap[] =
+    { 0, 0, 0, 3, 4, 5, 6, 7, 0, 0, 10, 1, 0, 0, 14, 0 };
+int tcic_valid_irqs = 0x4cf8;
+#else
+int tcic_irqmap[] =    /* irqs 9 and 6 switched, some ISA cards */
+    { 0, 0, 0, 3, 4, 5, 0, 7, 0, 6, 10, 1, 0, 0, 14, 0 };
+int tcic_valid_irqs = 0x4eb8;
+#endif
+
+int tcic_mem_speed = 250;      /* memory access time in nanoseconds */
+int tcic_io_speed = 165;       /* io access time in nanoseconds */
+
+/*
+ * Check various reserved and otherwise in their value restricted bits.
+ */
+int
+tcic_check_reserved_bits(iot, ioh)
+       bus_space_tag_t iot;
+       bus_space_handle_t ioh;
+{
+       int val, auxreg;
+
+       DPRINTF(("tcic: chkrsvd 1\n"));
+       /* R_ADDR bit 30:28 have a restricted range. */
+       val = (bus_space_read_2(iot, ioh, TCIC_R_ADDR2) & TCIC_SS_MASK)
+           >> TCIC_SS_SHIFT;
+       if (val > 1)
+               return 0;
+
+       DPRINTF(("tcic: chkrsvd 2\n"));
+       /* R_SCTRL bits 6,2,1 are reserved. */
+       val = bus_space_read_1(iot, ioh, TCIC_R_SCTRL);
+       if (val & TCIC_SCTRL_RSVD)
+               return 0;
+
+       DPRINTF(("tcic: chkrsvd 3\n"));
+       /* R_ICSR bit 2 must be same as bit 3. */
+       val = bus_space_read_1(iot, ioh, TCIC_R_ICSR);
+       if (((val >> 1) & 1) != ((val >> 2) & 1))
+               return 0;
+
+       DPRINTF(("tcic: chkrsvd 4\n"));
+       /* R_IENA bits 7,2 are reserverd. */
+       val = bus_space_read_1(iot, ioh, TCIC_R_IENA);
+       if (val & TCIC_IENA_RSVD)
+               return 0;
+
+       DPRINTF(("tcic: chkrsvd 5\n"));
+       /* Some aux registers have reserved bits. */
+       /* Which are we looking at? */
+       auxreg = bus_space_read_1(iot, ioh, TCIC_R_MODE)
+           & TCIC_AR_MASK;
+       val = bus_space_read_2(iot, ioh, TCIC_R_AUX);
+       DPRINTF(("tcic: auxreg 0x%02x val 0x%04x\n", auxreg, val));
+       switch (auxreg) {
+       case TCIC_AR_SYSCFG:
+               if (INVALID_AR_SYSCFG(val))
+                       return 0;
+               break;
+       case TCIC_AR_ILOCK:
+               if (INVALID_AR_ILOCK(val))
+                       return 0;
+               break;
+       case TCIC_AR_TEST:
+               if (INVALID_AR_TEST(val))
+                       return 0;
+               break;
+       }
+
+       DPRINTF(("tcic: chkrsvd 6\n"));
+       /* XXX fails if pcmcia bios is enabled. */
+       /* Various bits set or not depending if in RESET mode. */
+       val = bus_space_read_1(iot, ioh, TCIC_R_SCTRL);
+       if (val & TCIC_SCTRL_RESET) {
+               DPRINTF(("tcic: chkrsvd 7\n"));
+               /* Address bits must be 0 */
+               val = bus_space_read_2(iot, ioh, TCIC_R_ADDR);
+               if (val != 0)
+                       return 0;
+               val = bus_space_read_2(iot, ioh, TCIC_R_ADDR2);
+               if (val != 0)
+                       return 0;
+               DPRINTF(("tcic: chkrsvd 8\n"));
+               /* EDC bits must be 0 */
+               val = bus_space_read_2(iot, ioh, TCIC_R_EDC);
+               if (val != 0)
+                       return 0;
+               /* We're OK, so take it out of reset. XXX -chb */
+               bus_space_write_1(iot, ioh, TCIC_R_SCTRL, 0);
+       }
+       else {  /* not in RESET mode */
+               int omode;
+               int val1, val2;
+               DPRINTF(("tcic: chkrsvd 9\n"));
+               /* Programming timers must have expired. */
+               val = bus_space_read_1(iot, ioh, TCIC_R_SSTAT);
+               if ((val & (TCIC_SSTAT_6US|TCIC_SSTAT_10US|TCIC_SSTAT_PROGTIME))
+                   != (TCIC_SSTAT_6US|TCIC_SSTAT_10US|TCIC_SSTAT_PROGTIME))
+                       return 0;
+               DPRINTF(("tcic: chkrsvd 10\n"));
+               /*
+                * EDC bits should change on read from data space
+                * as long as either EDC or the data are nonzero.
+                */
+                if ((bus_space_read_2(iot, ioh, TCIC_R_ADDR2)
+                    & TCIC_ADDR2_INDREG) != 0) {
+                       val1 = bus_space_read_2(iot, ioh, TCIC_R_EDC);
+                       val2 = bus_space_read_2(iot, ioh, TCIC_R_DATA);
+                       if (val1 | val2) {
+                               val1 = bus_space_read_2(iot, ioh, TCIC_R_EDC);
+                               if (val1 == val2)
+                                       return 0;
+                       }
+               }
+               DPRINTF(("tcic: chkrsvd 11\n"));
+               /* XXX what does this check? -chb */
+               omode = bus_space_read_1(iot, ioh, TCIC_R_MODE);
+               val1 = omode ^ TCIC_AR_MASK;
+               bus_space_write_1(iot, ioh, TCIC_R_MODE, val1);
+               val2 = bus_space_read_1(iot, ioh, TCIC_R_MODE);
+               bus_space_write_1(iot, ioh, TCIC_R_MODE, omode);
+               if ( val1 != val2)
+                       return 0;
+       }
+       /* All tests passed */
+       return 1;
+}
+
+/*
+ * Read chip ID from AR_ILOCK in test mode.
+ */
+int
+tcic_chipid(iot, ioh)
+       bus_space_tag_t iot;
+       bus_space_handle_t ioh;
+{
+       unsigned id, otest;
+
+       otest = tcic_read_aux_2(iot, ioh, TCIC_AR_TEST);
+       tcic_write_aux_2(iot, ioh, TCIC_AR_TEST, TCIC_TEST_DIAG);
+       id = tcic_read_aux_2(iot, ioh, TCIC_AR_ILOCK);
+       tcic_write_aux_2(iot, ioh, TCIC_AR_TEST, otest);
+       id &= TCIC_ILOCKTEST_ID_MASK;
+       id >>= TCIC_ILOCKTEST_ID_SHFT;
+
+       /* clear up IRQs inside tcic. XXX -chb */
+       while (bus_space_read_1(iot, ioh, TCIC_R_ICSR))
+               bus_space_write_1(iot, ioh, TCIC_R_ICSR, TCIC_ICSR_JAM);
+
+       return id;
+}
+/*
+ * Indicate whether the driver can handle the chip.
+ */
+int
+tcic_chipid_known(id)
+       int id;
+{
+       /* XXX only know how to handle DB86082 -chb */
+       switch (id) {
+       case TCIC_CHIPID_DB86082_1:
+       case TCIC_CHIPID_DB86082A:
+       case TCIC_CHIPID_DB86082B_ES:
+       case TCIC_CHIPID_DB86082B:
+       case TCIC_CHIPID_DB86084_1:
+       case TCIC_CHIPID_DB86084A:
+       case TCIC_CHIPID_DB86184_1:
+       case TCIC_CHIPID_DB86072_1_ES:
+       case TCIC_CHIPID_DB86072_1:
+               return 1;
+       }
+
+       return 0;
+}
+
+char *
+tcic_chipid_to_string(id)
+       int id;
+{
+       switch (id) {
+       case TCIC_CHIPID_DB86082_1:
+               return ("Databook DB86082");
+       case TCIC_CHIPID_DB86082A:
+               return ("Databook DB86082A");
+       case TCIC_CHIPID_DB86082B_ES:
+               return ("Databook DB86082B-es");
+       case TCIC_CHIPID_DB86082B:
+               return ("Databook DB86082B");
+       case TCIC_CHIPID_DB86084_1:
+               return ("Databook DB86084");
+       case TCIC_CHIPID_DB86084A:
+               return ("Databook DB86084A");
+       case TCIC_CHIPID_DB86184_1:
+               return ("Databook DB86184");
+       case TCIC_CHIPID_DB86072_1_ES:
+               return ("Databook DB86072-es");
+       case TCIC_CHIPID_DB86072_1:
+               return ("Databook DB86072");
+       }
+
+       return ("Unknown controller");
+}
+/*
+ * Return bitmask of IRQs that the chip can handle.
+ * XXX should be table driven.
+ */



Home | Main Index | Thread Index | Old Index