Home | History | Annotate | Line # | Download | only in adm5120
      1  1.8  thorpej /* $NetBSD: adm5120_extio.c,v 1.8 2021/08/07 16:18:58 thorpej Exp $ */
      2  1.1   dyoung 
      3  1.1   dyoung /*-
      4  1.1   dyoung  * Copyright (c) 2007 David Young.  All rights reserved.
      5  1.1   dyoung  *
      6  1.1   dyoung  * Redistribution and use in source and binary forms, with or
      7  1.1   dyoung  * without modification, are permitted provided that the following
      8  1.1   dyoung  * conditions are met:
      9  1.1   dyoung  * 1. Redistributions of source code must retain the above copyright
     10  1.1   dyoung  *    notice, this list of conditions and the following disclaimer.
     11  1.1   dyoung  * 2. Redistributions in binary form must reproduce the above
     12  1.1   dyoung  *    copyright notice, this list of conditions and the following
     13  1.1   dyoung  *    disclaimer in the documentation and/or other materials provided
     14  1.1   dyoung  *    with the distribution.
     15  1.1   dyoung  * 3. The name of the author may not be used to endorse or promote
     16  1.1   dyoung  *    products derived from this software without specific prior
     17  1.1   dyoung  *    written permission.
     18  1.1   dyoung  *
     19  1.1   dyoung  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY
     20  1.1   dyoung  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
     21  1.1   dyoung  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
     22  1.1   dyoung  * PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR
     23  1.1   dyoung  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
     24  1.1   dyoung  * OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     25  1.1   dyoung  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
     26  1.1   dyoung  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     27  1.1   dyoung  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
     28  1.1   dyoung  * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     29  1.1   dyoung  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
     30  1.1   dyoung  * OF SUCH DAMAGE.
     31  1.1   dyoung  */
     32  1.1   dyoung /*
     33  1.1   dyoung  * Copyright 2002 Wasabi Systems, Inc.
     34  1.1   dyoung  * All rights reserved.
     35  1.1   dyoung  *
     36  1.1   dyoung  * Written by Simon Burge for Wasabi Systems, Inc.
     37  1.1   dyoung  *
     38  1.1   dyoung  * Redistribution and use in source and binary forms, with or without
     39  1.1   dyoung  * modification, are permitted provided that the following conditions
     40  1.1   dyoung  * are met:
     41  1.1   dyoung  * 1. Redistributions of source code must retain the above copyright
     42  1.1   dyoung  *    notice, this list of conditions and the following disclaimer.
     43  1.1   dyoung  * 2. Redistributions in binary form must reproduce the above copyright
     44  1.1   dyoung  *    notice, this list of conditions and the following disclaimer in the
     45  1.1   dyoung  *    documentation and/or other materials provided with the distribution.
     46  1.1   dyoung  * 3. All advertising materials mentioning features or use of this software
     47  1.1   dyoung  *    must display the following acknowledgement:
     48  1.1   dyoung  *      This product includes software developed for the NetBSD Project by
     49  1.1   dyoung  *      Wasabi Systems, Inc.
     50  1.1   dyoung  * 4. The name of Wasabi Systems, Inc. may not be used to endorse
     51  1.1   dyoung  *    or promote products derived from this software without specific prior
     52  1.1   dyoung  *    written permission.
     53  1.1   dyoung  *
     54  1.1   dyoung  * THIS SOFTWARE IS PROVIDED BY WASABI SYSTEMS, INC. ``AS IS'' AND
     55  1.1   dyoung  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     56  1.1   dyoung  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     57  1.1   dyoung  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL WASABI SYSTEMS, INC
     58  1.1   dyoung  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     59  1.1   dyoung  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     60  1.1   dyoung  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     61  1.1   dyoung  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     62  1.1   dyoung  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     63  1.1   dyoung  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     64  1.1   dyoung  * POSSIBILITY OF SUCH DAMAGE.
     65  1.1   dyoung  */
     66  1.1   dyoung 
     67  1.1   dyoung #include <sys/cdefs.h>
     68  1.8  thorpej __KERNEL_RCSID(0, "$NetBSD: adm5120_extio.c,v 1.8 2021/08/07 16:18:58 thorpej Exp $");
     69  1.1   dyoung 
     70  1.1   dyoung #include <sys/param.h>
     71  1.1   dyoung #include <sys/systm.h>
     72  1.1   dyoung #include <sys/device.h>
     73  1.1   dyoung 
     74  1.5   dyoung #include <sys/bus.h>
     75  1.1   dyoung 
     76  1.1   dyoung #include <mips/cache.h>
     77  1.1   dyoung #include <mips/cpuregs.h>
     78  1.1   dyoung 
     79  1.1   dyoung #include <mips/adm5120/include/adm5120reg.h>
     80  1.1   dyoung #include <mips/adm5120/include/adm5120var.h>
     81  1.1   dyoung #include <mips/adm5120/include/adm5120_mainbusvar.h>
     82  1.1   dyoung #include <mips/adm5120/include/adm5120_extiovar.h>
     83  1.1   dyoung 
     84  1.1   dyoung #include "locators.h"
     85  1.1   dyoung 
     86  1.1   dyoung #ifdef EXTIO_DEBUG
     87  1.1   dyoung int extio_debug = 1;
     88  1.1   dyoung #define	EXTIO_DPRINTF(__fmt, ...)		\
     89  1.1   dyoung do {						\
     90  1.1   dyoung 	if (extio_debug)			\
     91  1.1   dyoung 		printf((__fmt), __VA_ARGS__);	\
     92  1.1   dyoung } while (/*CONSTCOND*/0)
     93  1.1   dyoung #else /* !EXTIO_DEBUG */
     94  1.1   dyoung #define	EXTIO_DPRINTF(__fmt, ...)	do { } while (/*CONSTCOND*/0)
     95  1.1   dyoung #endif /* EXTIO_DEBUG */
     96  1.1   dyoung 
     97  1.6      chs static int	extio_match(device_t, cfdata_t, void *);
     98  1.6      chs static void	extio_attach(device_t, device_t, void *);
     99  1.6      chs static int	extio_submatch(device_t, cfdata_t, const int *, void *);
    100  1.1   dyoung static int	extio_print(void *, const char *);
    101  1.1   dyoung 
    102  1.6      chs CFATTACH_DECL_NEW(extio, sizeof(struct extio_softc),
    103  1.1   dyoung     extio_match, extio_attach, NULL, NULL);
    104  1.1   dyoung 
    105  1.1   dyoung /* There can be only one. */
    106  1.1   dyoung int	extio_found;
    107  1.1   dyoung 
    108  1.1   dyoung struct extiodev {
    109  1.1   dyoung 	const char	*ed_name;
    110  1.1   dyoung 	bus_addr_t	ed_addr;
    111  1.1   dyoung 	int		ed_irq;
    112  1.1   dyoung 	uint32_t	ed_gpio_mask;
    113  1.1   dyoung 	int		ed_cfio;
    114  1.1   dyoung };
    115  1.1   dyoung 
    116  1.1   dyoung struct extiodev extiodevs[] = {
    117  1.1   dyoung 	{"wdc",		ADM5120_BASE_EXTIO0,	0,	__BIT(4),	1},
    118  1.1   dyoung 	{NULL,		0,			0,	0x0,		0},
    119  1.1   dyoung };
    120  1.1   dyoung 
    121  1.1   dyoung static int
    122  1.6      chs extio_match(device_t parent, cfdata_t match, void *aux)
    123  1.1   dyoung {
    124  1.1   dyoung 	return !extio_found;
    125  1.1   dyoung }
    126  1.1   dyoung 
    127  1.1   dyoung static void
    128  1.1   dyoung extio_attach_args_create(struct extio_attach_args *ea, struct extiodev *ed,
    129  1.1   dyoung     void *gpio, bus_space_tag_t st)
    130  1.1   dyoung {
    131  1.1   dyoung 	ea->ea_name = ed->ed_name;
    132  1.1   dyoung 	ea->ea_addr = ed->ed_addr;
    133  1.1   dyoung 	ea->ea_irq = ed->ed_irq;
    134  1.1   dyoung 	ea->ea_st = st;
    135  1.1   dyoung 	ea->ea_gpio = gpio;
    136  1.1   dyoung 	ea->ea_gpio_mask = ed->ed_gpio_mask;
    137  1.1   dyoung 	ea->ea_cfio = ed->ed_cfio;
    138  1.1   dyoung }
    139  1.1   dyoung 
    140  1.1   dyoung static void
    141  1.1   dyoung extio_mpmc_dump(struct extio_softc *sc)
    142  1.1   dyoung {
    143  1.1   dyoung 	EXTIO_DPRINTF("%s: regs:\n"
    144  1.1   dyoung 	    "  ctl 0x%08" PRIx32 "\n"
    145  1.1   dyoung 	    "  sts 0x%08" PRIx32 "\n"
    146  1.1   dyoung 	    "   sc 0x%08" PRIx32 "\n"
    147  1.1   dyoung 	    "  sww 0x%08" PRIx32 "\n"
    148  1.1   dyoung 	    "  swo 0x%08" PRIx32 "\n"
    149  1.1   dyoung 	    "  swr 0x%08" PRIx32 "\n"
    150  1.1   dyoung 	    "  swp 0x%08" PRIx32 "\n"
    151  1.1   dyoung 	    " swwr 0x%08" PRIx32 "\n"
    152  1.1   dyoung 	    "  swt 0x%08" PRIx32 "\n", __func__,
    153  1.1   dyoung 	    bus_space_read_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_CONTROL),
    154  1.1   dyoung 	    bus_space_read_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_STATUS),
    155  1.1   dyoung 	    bus_space_read_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_SC(2)),
    156  1.1   dyoung 	    bus_space_read_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_SWW(2)),
    157  1.1   dyoung 	    bus_space_read_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_SWO(2)),
    158  1.1   dyoung 	    bus_space_read_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_SWR(2)),
    159  1.1   dyoung 	    bus_space_read_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_SWP(2)),
    160  1.1   dyoung 	    bus_space_read_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_SWWR(2)),
    161  1.1   dyoung 	    bus_space_read_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_SWT(2)));
    162  1.1   dyoung }
    163  1.1   dyoung 
    164  1.1   dyoung static void
    165  1.1   dyoung extio_mpmc_init(struct extio_softc *sc)
    166  1.1   dyoung {
    167  1.1   dyoung 	int i, s;
    168  1.1   dyoung #if 0
    169  1.1   dyoung 	uint32_t control;
    170  1.1   dyoung #endif
    171  1.1   dyoung 	uint32_t status;
    172  1.1   dyoung 
    173  1.1   dyoung 	/* Map MultiPort Memory Controller */
    174  1.1   dyoung 	if (bus_space_map(sc->sc_obiot, ADM5120_BASE_MPMC, 0x280, 0,
    175  1.1   dyoung 	                  &sc->sc_mpmch) != 0) {
    176  1.6      chs 		aprint_error_dev(sc->sc_dev, "unable to map MPMC\n");
    177  1.1   dyoung 		return;
    178  1.1   dyoung 	}
    179  1.1   dyoung 
    180  1.1   dyoung 	extio_mpmc_dump(sc);
    181  1.1   dyoung 
    182  1.1   dyoung #if 0
    183  1.1   dyoung 	control = bus_space_read_4(sc->sc_obiot, sc->sc_mpmch,
    184  1.1   dyoung 	    ADM5120_MPMC_CONTROL) | ADM5120_MPMC_CONTROL_DWB;
    185  1.1   dyoung 	bus_space_write_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_CONTROL,
    186  1.1   dyoung 	    control);
    187  1.1   dyoung #endif
    188  1.1   dyoung 
    189  1.1   dyoung 	s = splhigh();
    190  1.1   dyoung 	/* I wait for MPMC to become idle, and then I enter low-power mode
    191  1.1   dyoung 	 * so that I can safely set the static configuration.
    192  1.1   dyoung 	 */
    193  1.1   dyoung 	for (i = 1000; --i > 0; ) {
    194  1.1   dyoung 		status = bus_space_read_4(sc->sc_obiot, sc->sc_mpmch,
    195  1.1   dyoung 		    ADM5120_MPMC_STATUS);
    196  1.1   dyoung 		if ((status &
    197  1.1   dyoung 		     (ADM5120_MPMC_STATUS_WBS|ADM5120_MPMC_STATUS_BU)) == 0)
    198  1.1   dyoung 			break;
    199  1.1   dyoung 		delay(10);
    200  1.1   dyoung 	}
    201  1.1   dyoung 
    202  1.1   dyoung 	if (i == 0) {
    203  1.6      chs 		aprint_error_dev(sc->sc_dev,
    204  1.2   dyoung 		    "timeout waiting for MPMC idle\n");
    205  1.1   dyoung 		splx(s);
    206  1.1   dyoung 		return;
    207  1.1   dyoung 	} else
    208  1.6      chs 		EXTIO_DPRINTF("%s: MPMC idle\n", device_xname(sc->sc_dev));
    209  1.1   dyoung 
    210  1.1   dyoung #if 0
    211  1.1   dyoung 	control = bus_space_read_4(sc->sc_obiot, sc->sc_mpmch,
    212  1.1   dyoung 	    ADM5120_MPMC_CONTROL) | ADM5120_MPMC_CONTROL_ME |
    213  1.1   dyoung 	    ADM5120_MPMC_CONTROL_LPM;
    214  1.1   dyoung 	bus_space_write_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_CONTROL,
    215  1.1   dyoung 	    control);
    216  1.1   dyoung #endif
    217  1.1   dyoung 
    218  1.1   dyoung 	/*
    219  1.1   dyoung 	 * Configure external I/O to suit the CompactFlash card.
    220  1.1   dyoung 	 *
    221  1.1   dyoung 	 * Static Configuration 2
    222  1.1   dyoung 	 *
    223  1.1   dyoung 	 * 1 Enable 'async page mode four'.
    224  1.1   dyoung 	 * 2 'Byte lane state' bits for active low for both read & write.
    225  1.1   dyoung 	 * 3 No buffer, no write protection.
    226  1.1   dyoung 	 * 4 No extended wait.
    227  1.1   dyoung 	 * 5 Active low chip select.
    228  1.1   dyoung 	 * 7 8-bit memory width.
    229  1.1   dyoung 	 */
    230  1.1   dyoung 	bus_space_write_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_SC(2),
    231  1.1   dyoung 	    ADM5120_MPMC_SC_BLS|ADM5120_MPMC_SC_PM|ADM5120_MPMC_SC_MW_8B);
    232  1.1   dyoung 
    233  1.1   dyoung 	/*
    234  1.1   dyoung 	 * Static Wait Wen 2: after asserting chip select, wait 3 HCLK cycles
    235  1.1   dyoung 	 * before asserting write enable.
    236  1.1   dyoung 	 */
    237  1.1   dyoung 	bus_space_write_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_SWW(2),
    238  1.1   dyoung 	    __SHIFTIN(2, ADM5120_MPMC_SWW_WWE));
    239  1.1   dyoung 
    240  1.1   dyoung 	/*
    241  1.1   dyoung 	 * Static Wait Oen 2: after selecting chip select, wait 3 HCLK cycles
    242  1.1   dyoung 	 * before asserting output enable.
    243  1.1   dyoung 	 */
    244  1.1   dyoung 	bus_space_write_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_SWO(2),
    245  1.1   dyoung 	    __SHIFTIN(3, ADM5120_MPMC_SWO_WOE));
    246  1.1   dyoung 
    247  1.1   dyoung 	/*
    248  1.1   dyoung 	 * Static Wait Rd 2: set wait state time to 27 HCLK cycles.
    249  1.1   dyoung 	 */
    250  1.1   dyoung 	bus_space_write_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_SWR(2),
    251  1.1   dyoung 	    __SHIFTIN(26, ADM5120_MPMC_SWR_NMRW));
    252  1.1   dyoung 
    253  1.1   dyoung 	/*
    254  1.1   dyoung 	 * Static Wait Wait Page 2: set wait state time to 30 HCLK cycles.
    255  1.1   dyoung 	 */
    256  1.1   dyoung 	bus_space_write_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_SWP(2),
    257  1.1   dyoung 	    __SHIFTIN(29, ADM5120_MPMC_SWP_WPS));
    258  1.1   dyoung 
    259  1.1   dyoung 	/*
    260  1.1   dyoung 	 * Static Wait Wait Wr 2: set wait state time to 22 HCLK cycles.
    261  1.1   dyoung 	 */
    262  1.1   dyoung 	bus_space_write_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_SWWR(2),
    263  1.1   dyoung 	    __SHIFTIN(20, ADM5120_MPMC_SWWR_WWS));
    264  1.1   dyoung 
    265  1.1   dyoung 	/*
    266  1.1   dyoung 	 * Static Wait Wait Turn 2: 10 HCLK cycles for turnaround.
    267  1.1   dyoung 	 */
    268  1.1   dyoung 	bus_space_write_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_SWT(2),
    269  1.1   dyoung 	    __SHIFTIN(9, ADM5120_MPMC_SWT_WAITTURN));
    270  1.1   dyoung 
    271  1.1   dyoung #if 0
    272  1.1   dyoung 	/* Leave low-power mode. */
    273  1.1   dyoung 	control = bus_space_read_4(sc->sc_obiot, sc->sc_mpmch,
    274  1.1   dyoung 	    ADM5120_MPMC_CONTROL) &
    275  1.1   dyoung 	    ~(ADM5120_MPMC_CONTROL_LPM|ADM5120_MPMC_CONTROL_DWB);
    276  1.1   dyoung 	bus_space_write_4(sc->sc_obiot, sc->sc_mpmch, ADM5120_MPMC_CONTROL,
    277  1.1   dyoung 	    control);
    278  1.1   dyoung 	splx(s);
    279  1.1   dyoung #endif
    280  1.1   dyoung 
    281  1.1   dyoung 	extio_mpmc_dump(sc);
    282  1.1   dyoung }
    283  1.1   dyoung 
    284  1.1   dyoung static void
    285  1.6      chs extio_attach(device_t parent, device_t self, void *aux)
    286  1.1   dyoung {
    287  1.6      chs 	struct extio_softc *sc = device_private(self);
    288  1.1   dyoung 	struct mainbus_attach_args *ma = (struct mainbus_attach_args *)aux;
    289  1.1   dyoung 	struct extio_attach_args ea;
    290  1.1   dyoung 	struct extiodev *ed;
    291  1.1   dyoung 	struct adm5120_config *admc = &adm5120_configuration;
    292  1.1   dyoung 
    293  1.1   dyoung 	extio_found = 1;
    294  1.1   dyoung 	printf("\n");
    295  1.1   dyoung 
    296  1.6      chs 	sc->sc_dev = self;
    297  1.1   dyoung 	sc->sc_gpio = ma->ma_gpio;
    298  1.1   dyoung 	sc->sc_obiot = ma->ma_obiot;
    299  1.1   dyoung 	sc->sc_gpioh = ma->ma_gpioh;
    300  1.1   dyoung 
    301  1.1   dyoung 	EXTIO_DPRINTF("%s: %d\n", __func__, __LINE__);
    302  1.1   dyoung 
    303  1.1   dyoung 	sc->sc_pm.pm_map = &sc->sc_map[0];
    304  1.1   dyoung 
    305  1.1   dyoung 	/* Map GPIO[0] (WAIT#) for input.
    306  1.1   dyoung 	 *
    307  1.1   dyoung 	 * If WAIT# is high (inactive), then enable WAIT# handshake for
    308  1.1   dyoung 	 * EXTIO0 accesses.  Otherwise, assume that WAIT# is
    309  1.1   dyoung 	 * stuck low (active), in which case all accesses would timeout
    310  1.1   dyoung 	 * if we enabled WAIT# handshake.
    311  1.1   dyoung 	 *
    312  1.1   dyoung 	 * Map GPIO[1:2].  Program 5120 to treat GPIO[1:2] as
    313  1.1   dyoung 	 * Chip Select / Interrupt pins for External I/O #0.
    314  1.1   dyoung 	 *
    315  1.1   dyoung 	 * Map GPIO[3:4].  Program 5120 to treat GPIO[3:4] as
    316  1.1   dyoung 	 * Chip Select / Interrupt pins for External I/O #1.
    317  1.1   dyoung 	 *
    318  1.1   dyoung 	 * Use GPIO[4] for interrupts.  (Not yet.)
    319  1.1   dyoung 	 */
    320  1.1   dyoung 	if (gpio_pin_map(sc->sc_gpio, 0, __BITS(0, 4), &sc->sc_pm) != 0) {
    321  1.6      chs 		aprint_error_dev(sc->sc_dev, "failed to map GPIO[1:2]\n");
    322  1.1   dyoung 	}
    323  1.1   dyoung 	EXTIO_DPRINTF("%s: %d\n", __func__, __LINE__);
    324  1.1   dyoung 	gpio_pin_ctl(sc->sc_gpio, &sc->sc_pm, 0, GPIO_PIN_INPUT);
    325  1.1   dyoung 	gpio_pin_ctl(sc->sc_gpio, &sc->sc_pm, 1, GPIO_PIN_OUTPUT);
    326  1.1   dyoung 	gpio_pin_ctl(sc->sc_gpio, &sc->sc_pm, 2, GPIO_PIN_INPUT);
    327  1.1   dyoung 	gpio_pin_ctl(sc->sc_gpio, &sc->sc_pm, 3, GPIO_PIN_OUTPUT);
    328  1.1   dyoung 	gpio_pin_ctl(sc->sc_gpio, &sc->sc_pm, 4, GPIO_PIN_INPUT);
    329  1.1   dyoung 	gpio_pin_write(sc->sc_gpio, &sc->sc_pm, 1, 0);
    330  1.1   dyoung 	gpio_pin_write(sc->sc_gpio, &sc->sc_pm, 3, 0);
    331  1.1   dyoung 
    332  1.1   dyoung 	EXTIO_DPRINTF("%s: %d\n", __func__, __LINE__);
    333  1.1   dyoung 
    334  1.1   dyoung 	if (gpio_pin_read(sc->sc_gpio, &sc->sc_pm, 0) == GPIO_PIN_HIGH) {
    335  1.1   dyoung 		EXTIO_DPRINTF("%s: WAIT# inactive\n",
    336  1.6      chs 		    device_xname(sc->sc_dev));
    337  1.1   dyoung 		bus_space_write_4(sc->sc_obiot, sc->sc_gpioh, ADM5120_GPIO2,
    338  1.1   dyoung 		    ADM5120_GPIO2_EW | ADM5120_GPIO2_CSX0 | ADM5120_GPIO2_CSX1);
    339  1.1   dyoung 	} else {
    340  1.6      chs 		aprint_error_dev(sc->sc_dev, "WAIT# active; may be stuck\n");
    341  1.1   dyoung 		bus_space_write_4(sc->sc_obiot, sc->sc_gpioh, ADM5120_GPIO2,
    342  1.1   dyoung 		    ADM5120_GPIO2_CSX0 | ADM5120_GPIO2_CSX1);
    343  1.1   dyoung 	}
    344  1.1   dyoung 	EXTIO_DPRINTF("%s: %d\n", __func__, __LINE__);
    345  1.1   dyoung 
    346  1.1   dyoung 	/* Map MultiPort Memory Controller */
    347  1.1   dyoung 	if (bus_space_map(sc->sc_obiot, ADM5120_BASE_MPMC, 0x280, 0,
    348  1.1   dyoung 	                  &sc->sc_mpmch) != 0) {
    349  1.6      chs 		aprint_error_dev(sc->sc_dev, "unable to map MPMC\n");
    350  1.1   dyoung 		return;
    351  1.1   dyoung 	}
    352  1.1   dyoung 
    353  1.1   dyoung 	extio_mpmc_init(sc);
    354  1.1   dyoung 	EXTIO_DPRINTF("%s: %d\n", __func__, __LINE__);
    355  1.1   dyoung 
    356  1.1   dyoung 	/* Program 5120 for level interrupts on GPIO[4] (INTX1).  (Not yet.)
    357  1.1   dyoung 	 *
    358  1.1   dyoung 	 * Map interrupt.  (Not yet.  In the mean time, use flags 0x1000 in
    359  1.1   dyoung 	 * kernel configuration so that wdc(4) will expect no interrupts.)
    360  1.1   dyoung 	 */
    361  1.1   dyoung 
    362  1.1   dyoung 	cfio_bus_mem_init(&sc->sc_cfio, &admc->extio_space);
    363  1.1   dyoung 
    364  1.1   dyoung 	for (ed = extiodevs; ed->ed_name != NULL; ed++) {
    365  1.1   dyoung 		EXTIO_DPRINTF("%s: %d\n", __func__, __LINE__);
    366  1.1   dyoung 		extio_attach_args_create(&ea, ed, sc->sc_gpio,
    367  1.1   dyoung 		    (ed->ed_cfio) ? &sc->sc_cfio : &admc->extio_space);
    368  1.1   dyoung 		EXTIO_DPRINTF("%s: %d\n", __func__, __LINE__);
    369  1.7  thorpej 		config_found(self, &ea, extio_print,
    370  1.8  thorpej 		    CFARGS(.submatch = extio_submatch,
    371  1.8  thorpej 			   .iattr = "extio"));
    372  1.1   dyoung 	}
    373  1.1   dyoung 	EXTIO_DPRINTF("%s: %d\n", __func__, __LINE__);
    374  1.1   dyoung 	extio_mpmc_dump(sc);
    375  1.1   dyoung }
    376  1.1   dyoung 
    377  1.1   dyoung static int
    378  1.6      chs extio_submatch(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
    379  1.1   dyoung {
    380  1.1   dyoung 	struct extio_attach_args *ea = aux;
    381  1.1   dyoung 
    382  1.1   dyoung 	if (cf->cf_loc[EXTIOCF_CFIO] != EXTIOCF_CFIO_DEFAULT &&
    383  1.1   dyoung 	    cf->cf_loc[EXTIOCF_CFIO] != ea->ea_cfio)
    384  1.1   dyoung 		return 0;
    385  1.1   dyoung 
    386  1.1   dyoung 	if (cf->cf_loc[EXTIOCF_GPIO_MASK] != EXTIOCF_GPIO_MASK_DEFAULT &&
    387  1.1   dyoung 	    cf->cf_loc[EXTIOCF_GPIO_MASK] != ea->ea_gpio_mask)
    388  1.1   dyoung 		return 0;
    389  1.1   dyoung 
    390  1.1   dyoung 	if (cf->cf_loc[EXTIOCF_IRQ] != EXTIOCF_IRQ_DEFAULT &&
    391  1.1   dyoung 	    cf->cf_loc[EXTIOCF_IRQ] != ea->ea_irq)
    392  1.1   dyoung 		return 0;
    393  1.1   dyoung 
    394  1.1   dyoung 	if (cf->cf_loc[EXTIOCF_ADDR] != EXTIOCF_ADDR_DEFAULT &&
    395  1.1   dyoung 	    cf->cf_loc[EXTIOCF_ADDR] != ea->ea_addr)
    396  1.1   dyoung 		return 0;
    397  1.1   dyoung 
    398  1.1   dyoung 	return config_match(parent, cf, aux);
    399  1.1   dyoung }
    400  1.1   dyoung 
    401  1.1   dyoung static int
    402  1.1   dyoung extio_print(void *aux, const char *pnp)
    403  1.1   dyoung {
    404  1.1   dyoung 	struct extio_attach_args *ea = aux;
    405  1.1   dyoung 
    406  1.1   dyoung 	if (pnp != NULL)
    407  1.1   dyoung 		aprint_normal("%s at %s", ea->ea_name, pnp);
    408  1.1   dyoung 	if (ea->ea_cfio != EXTIOCF_CFIO_DEFAULT)
    409  1.1   dyoung 		aprint_normal(" cfio");
    410  1.1   dyoung 	if (ea->ea_addr != EXTIOCF_ADDR_DEFAULT)
    411  1.4     matt 		aprint_normal(" addr 0x%"PRIxBUSADDR, ea->ea_addr);
    412  1.1   dyoung 	if (ea->ea_gpio_mask != EXTIOCF_GPIO_MASK_DEFAULT)
    413  1.1   dyoung 		aprint_normal(" gpio_mask 0x%02x", ea->ea_gpio_mask);
    414  1.1   dyoung 
    415  1.1   dyoung 	return UNCONF;
    416  1.1   dyoung }
    417