Home | History | Annotate | Line # | Download | only in gumstix
gxio.c revision 1.18
      1 /*	$NetBSD: gxio.c,v 1.18 2010/09/23 06:43:32 kiyohara Exp $ */
      2 /*
      3  * Copyright (C) 2005, 2006, 2007 WIDE Project and SOUM Corporation.
      4  * All rights reserved.
      5  *
      6  * Written by Takashi Kiyohara and Susumu Miki for WIDE Project and SOUM
      7  * Corporation.
      8  *
      9  * Redistribution and use in source and binary forms, with or without
     10  * modification, are permitted provided that the following conditions
     11  * are met:
     12  * 1. Redistributions of source code must retain the above copyright
     13  *    notice, this list of conditions and the following disclaimer.
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  * 3. Neither the name of the project nor the name of SOUM Corporation
     18  *    may be used to endorse or promote products derived from this software
     19  *    without specific prior written permission.
     20  *
     21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT and SOUM CORPORATION ``AS IS''
     22  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
     23  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
     24  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT AND SOUM CORPORATION
     25  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     26  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     27  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
     28  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
     29  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
     30  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
     31  * POSSIBILITY OF SUCH DAMAGE.
     32  */
     33 #include <sys/cdefs.h>
     34 __KERNEL_RCSID(0, "$NetBSD: gxio.c,v 1.18 2010/09/23 06:43:32 kiyohara Exp $");
     35 
     36 #include "opt_cputypes.h"
     37 #include "opt_gumstix.h"
     38 #include "opt_gxio.h"
     39 #if defined(OVERO)
     40 #include "opt_omap.h"
     41 #endif
     42 
     43 #include <sys/param.h>
     44 #include <sys/device.h>
     45 #include <sys/errno.h>
     46 #include <sys/kernel.h>
     47 
     48 #include <sys/systm.h>
     49 
     50 #include <machine/bootconfig.h>
     51 
     52 #include <arm/omap/omap2_gpmcreg.h>
     53 #include <arm/omap/omap2_reg.h>
     54 #if defined(OMAP3530)
     55 #include <arm/omap/omap2_intr.h>
     56 #endif
     57 #include <arm/omap/omap_var.h>
     58 #if defined(CPU_XSCALE_PXA270) || defined(CPU_XSCALE_PXA250)
     59 #include <arm/xscale/pxa2x0cpu.h>
     60 #endif
     61 #include <arm/xscale/pxa2x0reg.h>
     62 #include <arm/xscale/pxa2x0var.h>
     63 #include <arm/xscale/pxa2x0_gpio.h>
     64 #include <evbarm/gumstix/gumstixreg.h>
     65 #include <evbarm/gumstix/gumstixvar.h>
     66 
     67 #include "ioconf.h"
     68 #include "locators.h"
     69 
     70 
     71 struct gxioconf {
     72 	const char *name;
     73 	void (*config)(void);
     74 };
     75 
     76 #if defined(GUMSTIX)
     77 static int gxiomatch(device_t, cfdata_t, void *);
     78 static void gxioattach(device_t, device_t, void *);
     79 static int gxiosearch(device_t, cfdata_t, const int *, void *);
     80 static int gxioprint(void *, const char *);
     81 
     82 CFATTACH_DECL_NEW(gxio, sizeof(struct gxio_softc),
     83     gxiomatch, gxioattach, NULL, NULL);
     84 #endif
     85 
     86 void gxio_config_pin(void);
     87 void gxio_config_expansion(char *);
     88 static void gxio_config_gpio(const struct gxioconf *, char *);
     89 #if defined(GUMSTIX)
     90 static void basix_config(void);
     91 static void cfstix_config(void);
     92 static void etherstix_config(void);
     93 static void netcf_config(void);
     94 static void netcf_vx_config(void);
     95 static void netduommc_config(void);
     96 static void netduo_config(void);
     97 static void netmicrosd_config(void);
     98 static void netwifimicrosd_config(void);
     99 static void netmmc_config(void);
    100 static void wifistix_config(void);
    101 static void wifistix_cf_config(void);
    102 #elif defined(OVERO)
    103 static void eth0_config(void);
    104 static void eth1_config(void);
    105 static void chestnut_config(void);
    106 static void tobi_config(void);
    107 static void tobiduo_config(void);
    108 #endif
    109 
    110 #if defined(CPU_XSCALE_PXA250)
    111 static struct pxa2x0_gpioconf pxa255dep_gpioconf[] = {
    112 	/* Bluetooth module configuration */
    113 	{  7, GPIO_OUT | GPIO_SET },	/* power on */
    114 	{ 12, GPIO_ALT_FN_1_OUT },	/* 32kHz out. required by SingleStone */
    115 
    116 	/* AC97 configuration */
    117 	{ 29, GPIO_ALT_FN_1_IN },	/* SDATA_IN0 */
    118 
    119 	/* FFUART configuration */
    120 	{ 35, GPIO_ALT_FN_1_IN },	/* CTS */
    121 	{ 41, GPIO_ALT_FN_2_OUT },	/* RTS */
    122 
    123 #ifndef GXIO_BLUETOOTH_ON_HWUART
    124 	/* BTUART configuration */
    125 	{ 44, GPIO_ALT_FN_1_IN },	/* BTCTS */
    126 	{ 45, GPIO_ALT_FN_2_OUT },	/* BTRTS */
    127 #else
    128 	/* HWUART configuration */
    129 	{ 42, GPIO_ALT_FN_3_IN },	/* HWRXD */
    130 	{ 43, GPIO_ALT_FN_3_OUT },	/* HWTXD */
    131 	{ 44, GPIO_ALT_FN_3_IN },	/* HWCTS */
    132 	{ 45, GPIO_ALT_FN_3_OUT },	/* HWRTS */
    133 #endif
    134 
    135 #ifndef GXIO_BLUETOOTH_ON_HWUART
    136 	/* HWUART configuration */
    137 	{ 48, GPIO_ALT_FN_1_OUT },	/* HWTXD */
    138 	{ 49, GPIO_ALT_FN_1_IN },	/* HWRXD */
    139 	{ 50, GPIO_ALT_FN_1_IN },	/* HWCTS */
    140 	{ 51, GPIO_ALT_FN_1_OUT },	/* HWRTS */
    141 #endif
    142 
    143 	{ -1 }
    144 };
    145 #endif
    146 #if defined(CPU_XSCALE_PXA270)
    147 static struct pxa2x0_gpioconf verdexdep_gpioconf[] = {
    148 	/* Bluetooth module configuration */
    149 	{   9, GPIO_ALT_FN_3_OUT },	/* CHOUT<0> */
    150 	{  12, GPIO_OUT | GPIO_SET },
    151 
    152 	/* LCD configuration */
    153 	{  17, GPIO_IN },		/* backlight on */
    154 
    155 	/* FFUART configuration */
    156 	{  34, GPIO_ALT_FN_1_IN },	/* FFRXD */
    157 	{  39, GPIO_ALT_FN_2_OUT },	/* FFTXD */
    158 
    159 	/* BTUART configuration */
    160 	{  42, GPIO_ALT_FN_1_IN },	/* BTRXD */
    161 	{  43, GPIO_ALT_FN_2_OUT },	/* BTTXD */
    162 	{  44, GPIO_ALT_FN_1_IN },	/* BTCTS */
    163 	{  45, GPIO_ALT_FN_2_OUT },	/* BTRTS */
    164 
    165 	/* AC97 configuration */
    166 	{  29, GPIO_ALT_FN_1_IN },	/* SDATA_IN0 */
    167 
    168 	{ -1 }
    169 };
    170 #endif
    171 
    172 static const struct gxioconf busheader_conf[] = {
    173 #if defined(GUMSTIX)
    174 	{ "basix",		basix_config },
    175 	{ "cfstix",		cfstix_config },
    176 	{ "etherstix",		etherstix_config },
    177 	{ "netcf",		netcf_config },
    178 	{ "netcf-vx",		netcf_vx_config },
    179 	{ "netduo-mmc",		netduommc_config },
    180 	{ "netduo",		netduo_config },
    181 	{ "netmicrosd",		netmicrosd_config },
    182 	{ "netmicrosd-vx",	netmicrosd_config },
    183 	{ "netwifimicrosd",	netwifimicrosd_config },
    184 	{ "netmmc",		netmmc_config },
    185 	{ "netpro-vx",		netwifimicrosd_config },
    186 	{ "wifistix-cf",	wifistix_cf_config },
    187 	{ "wifistix",		wifistix_config },
    188 #elif defined(OVERO)
    189 	{ "chestnut43",		chestnut_config },
    190 	{ "tobi",		tobi_config },
    191 	{ "tobi-duo",		tobiduo_config },
    192 #endif
    193 	{ NULL }
    194 };
    195 
    196 int gxpcic_gpio_reset;
    197 struct gxpcic_slot_irqs gxpcic_slot_irqs[2] = { { 0, -1, -1 }, { 0, -1, -1 } };
    198 
    199 
    200 #if defined(GUMSTIX)
    201 /* ARGSUSED */
    202 static int
    203 gxiomatch(device_t parent, cfdata_t match, void *aux)
    204 {
    205 
    206 	struct pxaip_attach_args *pxa = aux;
    207 	bus_space_tag_t iot = &pxa2x0_bs_tag;
    208 	bus_space_handle_t ioh;
    209 
    210 	if (strcmp(pxa->pxa_name, match->cf_name) != 0 ||
    211 	    pxa->pxa_addr != PXAIPCF_ADDR_DEFAULT)
    212 		 return 0;
    213 
    214 	if (bus_space_map(iot,
    215 	    PXA2X0_MEMCTL_BASE, PXA2X0_MEMCTL_SIZE, 0, &ioh))
    216 		return 0;
    217 	bus_space_unmap(iot, ioh, PXA2X0_MEMCTL_SIZE);
    218 
    219 	/* nothing */
    220 	return 1;
    221 }
    222 
    223 /* ARGSUSED */
    224 static void
    225 gxioattach(device_t parent, device_t self, void *aux)
    226 {
    227 	struct gxio_softc *sc = device_private(self);
    228 
    229 	aprint_normal("\n");
    230 	aprint_naive("\n");
    231 
    232 	sc->sc_dev = self;
    233 	sc->sc_iot = &pxa2x0_bs_tag;
    234 
    235 	if (bus_space_map(sc->sc_iot,
    236 	    PXA2X0_MEMCTL_BASE, PXA2X0_MEMCTL_SIZE, 0, &sc->sc_ioh))
    237 		return;
    238 
    239 	/*
    240 	 *  Attach each gumstix(busheader)/overo expansion board devices.
    241 	 */
    242 	config_search_ia(gxiosearch, self, "gxio", NULL);
    243 }
    244 
    245 /* ARGSUSED */
    246 static int
    247 gxiosearch(device_t parent, cfdata_t cf, const int *ldesc, void *aux)
    248 {
    249 	struct gxio_softc *sc = device_private(parent);
    250 	struct gxio_attach_args gxa;
    251 
    252 	gxa.gxa_sc = sc;
    253 	gxa.gxa_iot = sc->sc_iot;
    254 	gxa.gxa_addr = cf->cf_loc[GXIOCF_ADDR];
    255 	gxa.gxa_gpirq = cf->cf_loc[GXIOCF_GPIRQ];
    256 
    257 	if (config_match(parent, cf, &gxa))
    258 		config_attach(parent, cf, &gxa, gxioprint);
    259 
    260 	return 0;
    261 }
    262 
    263 /* ARGSUSED */
    264 static int
    265 gxioprint(void *aux, const char *name)
    266 {
    267 	struct gxio_attach_args *gxa = (struct gxio_attach_args *)aux;
    268 
    269 	if (gxa->gxa_addr != GXIOCF_ADDR_DEFAULT)
    270 		printf(" addr 0x%lx", gxa->gxa_addr);
    271 	if (gxa->gxa_gpirq > 0)
    272 		printf(" gpirq %d", gxa->gxa_gpirq);
    273 	return UNCONF;
    274 }
    275 #endif
    276 
    277 
    278 /*
    279  * configure for GPIO pin and expansion boards.
    280  */
    281 void
    282 gxio_config_pin(void)
    283 {
    284 #if defined(CPU_XSCALE_PXA250)
    285 	struct pxa2x0_gpioconf *gumstix_gpioconf[] = {
    286 		pxa25x_com_ffuart_gpioconf,
    287 		pxa25x_com_stuart_gpioconf,
    288 #ifndef GXIO_BLUETOOTH_ON_HWUART
    289 		pxa25x_com_btuart_gpioconf,
    290 #endif
    291 		pxa25x_com_hwuart_gpioconf,
    292 		pxa25x_i2c_gpioconf,
    293 		pxa25x_pxaacu_gpioconf,
    294 		pxa255dep_gpioconf,
    295 		NULL
    296 	};
    297 #endif
    298 #if defined(CPU_XSCALE_PXA270)
    299 	struct pxa2x0_gpioconf *verdex_gpioconf[] = {
    300 		pxa27x_com_ffuart_gpioconf,
    301 		pxa27x_com_stuart_gpioconf,
    302 		pxa27x_com_btuart_gpioconf,
    303 		pxa27x_i2c_gpioconf,
    304 		pxa27x_pxaacu_gpioconf,
    305 		pxa27x_pxamci_gpioconf,
    306 		pxa27x_ohci_gpioconf,
    307 		verdexdep_gpioconf,
    308 		NULL
    309 	};
    310 #endif
    311 
    312 	/* XXX: turn off for power of bluetooth module */
    313 #if defined(CPU_XSCALE_PXA250)
    314 	pxa2x0_gpio_set_function(7, GPIO_OUT | GPIO_CLR);
    315 #elif defined(CPU_XSCALE_PXA270)
    316 	pxa2x0_gpio_set_function(12, GPIO_OUT | GPIO_CLR);
    317 #endif
    318 	delay(100);
    319 
    320 #if defined(CPU_XSCALE_PXA270) && defined(CPU_XSCALE_PXA250)
    321 	pxa2x0_gpio_config(
    322 	    (CPU_IS_PXA250) ? gumstix_gpioconf : verdex_gpioconf);
    323 #elif defined(CPU_XSCALE_PXA270) || defined(CPU_XSCALE_PXA250)
    324 #if defined(CPU_XSCALE_PXA270)
    325 	pxa2x0_gpio_config(verdex_gpioconf);
    326 #else
    327 	pxa2x0_gpio_config(gumstix_gpioconf);
    328 #endif
    329 #endif
    330 }
    331 
    332 void
    333 gxio_config_expansion(char *expansion)
    334 {
    335 
    336 	if (expansion == NULL) {
    337 		printf("not specified 'expansion=' in the boot args.\n");
    338 #ifdef GXIO_DEFAULT_EXPANSION
    339 		printf("configure default expansion (%s)\n",
    340 		    GXIO_DEFAULT_EXPANSION);
    341 		expansion = __UNCONST(GXIO_DEFAULT_EXPANSION);
    342 #else
    343 		return;
    344 #endif
    345 	}
    346 	gxio_config_gpio(busheader_conf, expansion);
    347 }
    348 
    349 static void
    350 gxio_config_gpio(const struct gxioconf *gxioconflist, char *expansion)
    351 {
    352 	int i, rv;
    353 
    354 	for (i = 0; i < strlen(expansion); i++)
    355 		expansion[i] = tolower(expansion[i]);
    356 	for (i = 0; gxioconflist[i].name != NULL; i++) {
    357 		rv = strncmp(expansion, gxioconflist[i].name,
    358 		    strlen(gxioconflist[i].name) + 1);
    359 		if (rv == 0) {
    360 			gxioconflist[i].config();
    361 			break;
    362 		}
    363 	}
    364 }
    365 
    366 
    367 #if defined(GUMSTIX)
    368 
    369 static void
    370 basix_config(void)
    371 {
    372 
    373 	pxa2x0_gpio_set_function(8, GPIO_ALT_FN_1_OUT);		/* MMCCS0 */
    374 	pxa2x0_gpio_set_function(53, GPIO_ALT_FN_1_OUT);	/* MMCCLK */
    375 #if 0
    376 	/* this configuration set by gxmci.c::pxamci_attach() */
    377 	pxa2x0_gpio_set_function(11, GPIO_IN);			/* nSD_DETECT */
    378 	pxa2x0_gpio_set_function(22, GPIO_IN);			/* nSD_WP */
    379 #endif
    380 }
    381 
    382 static void
    383 cfstix_config(void)
    384 {
    385 	u_int gpio, npoe_fn;
    386 #if defined(CPU_XSCALE_PXA270) && defined(CPU_XSCALE_PXA250)
    387 	int bvd = (CPU_IS_PXA250) ? 4 : 111;
    388 #else
    389 #if defined(CPU_XSCALE_PXA270)
    390 	const int bvd = 111;
    391 #else
    392 	const int bvd = 4;
    393 #endif
    394 #endif
    395 
    396 	if (CPU_IS_PXA250) {
    397 		gxpcic_slot_irqs[0].valid = 1;
    398 		gxpcic_slot_irqs[0].cd = 11;
    399 		gxpcic_slot_irqs[0].prdy = 26;
    400 		gxpcic_gpio_reset = 8;
    401 	} else {
    402 		gxpcic_slot_irqs[0].valid = 1;
    403 		gxpcic_slot_irqs[0].cd = 104;
    404 		gxpcic_slot_irqs[0].prdy = 96;
    405 		gxpcic_gpio_reset = 97;
    406 	}
    407 
    408 #if 1
    409 	/* PCD/PRDY set by pxa2x0_pcic.c::pxapcic_attach_common() */
    410 #else
    411 	pxa2x0_gpio_set_function(11, GPIO_IN);		/* PCD1 */
    412 	pxa2x0_gpio_set_function(26, GPIO_IN);		/* PRDY1/~IRQ1 */
    413 #endif
    414 	pxa2x0_gpio_set_function(bvd, GPIO_IN); 	/* BVD1/~STSCHG1 */
    415 
    416 	for (gpio = 48, npoe_fn = 0; gpio <= 53 ; gpio++)
    417 		npoe_fn |= pxa2x0_gpio_get_function(gpio);
    418 	npoe_fn &= GPIO_SET;
    419 
    420 	pxa2x0_gpio_set_function(48, GPIO_ALT_FN_2_OUT | npoe_fn); /* nPOE */
    421 	pxa2x0_gpio_set_function(49, GPIO_ALT_FN_2_OUT);	/* nPWE */
    422 	pxa2x0_gpio_set_function(50, GPIO_ALT_FN_2_OUT);	/* nPIOR */
    423 	pxa2x0_gpio_set_function(51, GPIO_ALT_FN_2_OUT);	/* nPIOW */
    424 	if (CPU_IS_PXA250) {
    425 		pxa2x0_gpio_set_function(52, GPIO_ALT_FN_2_OUT); /* nPCE1 */
    426 		pxa2x0_gpio_set_function(53, GPIO_ALT_FN_2_OUT); /* nPCE2 */
    427 		pxa2x0_gpio_set_function(54, GPIO_ALT_FN_2_OUT); /* pSKTSEL */
    428 	} else {
    429 		pxa2x0_gpio_set_function(102, GPIO_ALT_FN_1_OUT); /* nPCE1 */
    430 		pxa2x0_gpio_set_function(105, GPIO_ALT_FN_1_OUT); /* nPCE2 */
    431 		pxa2x0_gpio_set_function(79, GPIO_ALT_FN_1_OUT);  /* pSKTSEL */
    432 	}
    433 	pxa2x0_gpio_set_function(55, GPIO_ALT_FN_2_OUT);	/* nPREG */
    434 	pxa2x0_gpio_set_function(56, GPIO_ALT_FN_1_IN);		/* nPWAIT */
    435 	pxa2x0_gpio_set_function(57, GPIO_ALT_FN_1_IN);		/* nIOIS16 */
    436 }
    437 
    438 static void
    439 etherstix_config(void)
    440 {
    441 	extern struct cfdata cfdata[];
    442 #if defined(CPU_XSCALE_PXA270) && defined(CPU_XSCALE_PXA250)
    443 	int rst = (CPU_IS_PXA250) ? 80 : 32;
    444 	int irq = (CPU_IS_PXA250) ? 36 : 99;
    445 #else
    446 #if defined(CPU_XSCALE_PXA270)
    447 	const int rst = 32, irq = 99;
    448 #else
    449 	const int rst = 80, irq = 36;
    450 #endif
    451 #endif
    452 	int i;
    453 
    454 	pxa2x0_gpio_set_function(49, GPIO_ALT_FN_2_OUT);	/* nPWE */
    455 	pxa2x0_gpio_set_function(15, GPIO_ALT_FN_2_OUT);	/* nCS 1 */
    456 	pxa2x0_gpio_set_function(rst, GPIO_OUT | GPIO_SET);	/* RESET 1 */
    457 	delay(1);
    458 	pxa2x0_gpio_set_function(rst, GPIO_OUT | GPIO_CLR);
    459 	delay(50000);
    460 
    461 	for (i = 0; cfdata[i].cf_name != NULL; i++)
    462 		if (strcmp(cfdata[i].cf_name, "sm") == 0 &&
    463 		    strcmp(cfdata[i].cf_atname, "sm_gxio") == 0 &&
    464 		    cfdata[i].cf_loc[GXIOCF_ADDR] == 0x04000300 &&
    465 		    cfdata[i].cf_loc[GXIOCF_GPIRQ] == GXIOCF_GPIRQ_DEFAULT)
    466 			cfdata[i].cf_loc[GXIOCF_GPIRQ] = irq;
    467 }
    468 
    469 static void
    470 netcf_config(void)
    471 {
    472 
    473 	etherstix_config();
    474 	cfstix_config();
    475 }
    476 
    477 static void
    478 netcf_vx_config(void)
    479 {
    480 
    481 	/*
    482 	 * XXXX: More power is necessary for NIC and USB???
    483 	 * (no document.  from Linux)
    484 	 */
    485 
    486 	pxa2x0_gpio_set_function(27, GPIO_IN);
    487 	pxa2x0_gpio_set_function(107, GPIO_OUT | GPIO_CLR);
    488 	pxa2x0_gpio_set_function(118, GPIO_ALT_FN_1_IN | GPIO_CLR);
    489 
    490 	etherstix_config();
    491 	cfstix_config();
    492 	if (CPU_IS_PXA270) {
    493 		/* Overwrite */
    494 		gxpcic_slot_irqs[0].cd = 104;
    495 		gxpcic_slot_irqs[0].prdy = 109;
    496 		gxpcic_gpio_reset = 110;
    497 	};
    498 }
    499 
    500 static void
    501 netduommc_config(void)
    502 {
    503 
    504 	netduo_config();
    505 	basix_config();
    506 }
    507 
    508 static void
    509 netduo_config(void)
    510 {
    511 
    512 	etherstix_config();
    513 
    514 	pxa2x0_gpio_set_function(78, GPIO_ALT_FN_2_OUT);	/* nCS 2 */
    515 	pxa2x0_gpio_set_function(52, GPIO_OUT | GPIO_SET);	/* RESET 2 */
    516 	delay(1);
    517 	pxa2x0_gpio_set_function(52, GPIO_OUT | GPIO_CLR);
    518 	delay(50000);
    519 }
    520 
    521 static void
    522 netmicrosd_config(void)
    523 {
    524 
    525 	/* MicroSD(mci) always configure on PXA270 */
    526 
    527 	pxa2x0_gpio_set_function(49, GPIO_ALT_FN_2_OUT);	/* nPWE */
    528 	pxa2x0_gpio_set_function(15, GPIO_ALT_FN_2_OUT);	/* nCS 1 */
    529 	pxa2x0_gpio_set_function(107, GPIO_OUT | GPIO_CLR);	/* RESET 1 */
    530 	delay(hz / 2);
    531 	pxa2x0_gpio_set_function(107, GPIO_OUT | GPIO_SET);
    532 	delay(50000);
    533 }
    534 
    535 static void
    536 netwifimicrosd_config(void)
    537 {
    538 
    539 	netmicrosd_config();
    540 
    541 	cfstix_config();
    542 	/* However use pxamci. */
    543 	pxa2x0_gpio_set_function(111, GPIO_CLR | GPIO_ALT_FN_1_IN);
    544 	/* Power to Marvell 88W8385 */
    545 	pxa2x0_gpio_set_function(80, GPIO_OUT | GPIO_SET);
    546 }
    547 
    548 static void
    549 netmmc_config(void)
    550 {
    551 
    552 	etherstix_config();
    553 	basix_config();
    554 }
    555 
    556 static void
    557 wifistix_config(void)
    558 {
    559 
    560 	cfstix_config();
    561 
    562 	/* Power to Marvell 88W8385 */
    563 	pxa2x0_gpio_set_function(80, GPIO_OUT | GPIO_SET);
    564 }
    565 
    566 static void
    567 wifistix_cf_config(void)
    568 {
    569 
    570 	gxpcic_slot_irqs[1].valid = 1;
    571 	gxpcic_slot_irqs[1].cd = 36;
    572 	gxpcic_slot_irqs[1].prdy = 27;
    573 
    574 #if 1
    575 	/* this configuration set by pxa2x0_pcic.c::pxapcic_attach_common() */
    576 #else
    577 	pxa2x0_gpio_set_function(36, GPIO_IN);		/* PCD2 */
    578 	pxa2x0_gpio_set_function(27, GPIO_IN);		/* PRDY2/~IRQ2 */
    579 #endif
    580 	pxa2x0_gpio_set_function(18, GPIO_IN); 		/* BVD2/~STSCHG2 */
    581 
    582 	cfstix_config();
    583 
    584 	/* Power to Marvell 88W8385 */
    585 	pxa2x0_gpio_set_function(80, GPIO_OUT | GPIO_SET);
    586 }
    587 
    588 #elif defined(OVERO)
    589 
    590 static void
    591 eth0_config(void)
    592 {
    593 	extern struct cfdata cfdata[];
    594 	cfdata_t cf = &cfdata[0];
    595 
    596 	/*
    597 	 * ETH0 connects via CS5.  It use GPIO 176 for IRQ.
    598 	 */
    599 
    600 	while (cf->cf_name != NULL) {
    601 		if (strcmp(cf->cf_name, "smsh") == 0 &&
    602 		    cf->cf_loc[GPMCCF_INTR] == PIC_MAXSOURCES + 176)
    603 			break;
    604 		cf++;
    605 	}
    606 	if (cf->cf_name == NULL ||
    607 	    cf->cf_loc[GPMCCF_ADDR] == GPMCCF_ADDR_DEFAULT)
    608 		return;
    609 
    610 	ioreg_write(OVERO_GPMC_VBASE + GPMC_CONFIG7_5,
    611 	    GPMC_CONFIG7_CSVALID |
    612 	    GPMC_CONFIG7(GPMC_CONFIG7_MASK_16M, cf->cf_loc[GPMCCF_ADDR]));
    613 
    614 	/*
    615 	 * Maybe need NRESET and delay(9).
    616 	 * However delay(9) needs to attach mputmr.
    617 	 */
    618 }
    619 
    620 static void
    621 eth1_config(void)
    622 {
    623 	extern struct cfdata cfdata[];
    624 	cfdata_t cf = &cfdata[0];
    625 
    626 	/*
    627 	 * ETH1 connects via CS4.  It use GPIO 65 for IRQ.
    628 	 */
    629 
    630 	while (cf->cf_name != NULL) {
    631 		if (strcmp(cf->cf_name, "smsh") == 0 &&
    632 		    cf->cf_loc[GPMCCF_INTR] == PIC_MAXSOURCES + 65)
    633 			break;
    634 		cf++;
    635 	}
    636 	if (cf->cf_name == NULL ||
    637 	    cf->cf_loc[GPMCCF_ADDR] == GPMCCF_ADDR_DEFAULT)
    638 		return;
    639 
    640 	ioreg_write(OVERO_GPMC_VBASE + GPMC_CONFIG7_4,
    641 	    GPMC_CONFIG7_CSVALID |
    642 	    GPMC_CONFIG7(GPMC_CONFIG7_MASK_16M, cf->cf_loc[GPMCCF_ADDR]));
    643 
    644 	/* ETH1 is sure to be reset with ETH0. */
    645 }
    646 
    647 static void
    648 chestnut_config(void)
    649 {
    650 
    651 	eth0_config();
    652 }
    653 
    654 static void
    655 tobi_config(void)
    656 {
    657 
    658 	eth0_config();
    659 }
    660 
    661 static void
    662 tobiduo_config(void)
    663 {
    664 
    665 	eth0_config();
    666 	eth1_config();
    667 }
    668 #endif
    669