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