Expand PMF_FN_* macros.
[netbsd-mini2440.git] / sys / arch / evbarm / tisdp24xx / if_sm_gpmc.c
blob1a6c09ddf9d59328cb22a0d185953be93d1bb6ea
1 /* adapted from: */
2 /* NetBSD: if_sm_emifs.c,v 1.1.6.1 2007/02/24 19:03:14 snj Exp */
4 /*
5 * OSK5912 SMC91Cxx wrapper, based on sys/arch/evbarm/viper/if_sm_pxaip.c
7 * Copyright (c) 2005 Antti Kantee. All Rights Reserved.
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. All advertising materials mentioning features or use of this software
18 * must display the following acknowledgement:
19 * This product includes software developed by The NetBSD
20 * Foundation, Inc. and its contributors.
21 * 4. The name of the company nor the name of the author may be used to
22 * endorse or promote products derived from this software without specific
23 * prior written permission.
25 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
26 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
27 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
28 * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
29 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
30 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
31 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
32 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
33 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
34 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
35 * SUCH DAMAGE.
38 #include <sys/cdefs.h>
39 __KERNEL_RCSID(0, "$NetBSD: if_sm_gpmc.c,v 1.2 2008/04/27 18:58:47 matt Exp $");
41 #include "locators.h"
43 #include <sys/param.h>
44 #include <sys/systm.h>
45 #include <sys/device.h>
47 #include <net/if.h>
48 #include <net/if_ether.h>
49 #include <net/if_media.h>
51 #include <machine/intr.h>
52 #include <machine/bus.h>
54 #include <dev/mii/mii.h>
55 #include <dev/mii/miivar.h>
57 #include <dev/ic/smc91cxxreg.h>
58 #include <dev/ic/smc91cxxvar.h>
60 #include <arch/arm/omap/omap2_gpmcvar.h>
61 #include <arch/arm/omap/omap_gpio.h>
63 static int sm_gpmc_match(struct device *, struct cfdata *, void *);
64 static void sm_gpmc_attach(struct device *, struct device *, void *);
66 struct sm_gpmc_softc {
67 struct smc91cxx_softc sc_sm;
68 struct evcnt sc_incomplete_ev;
69 struct evcnt sc_spurious_ev;
70 void *ih;
73 CFATTACH_DECL(sm_gpmc, sizeof(struct sm_gpmc_softc), sm_gpmc_match,
74 sm_gpmc_attach, NULL, NULL);
76 static int
77 sm_gpmc_match(struct device *parent, struct cfdata *match, void *aux)
79 struct gpmc_attach_args *gpmc = aux;
81 if (gpmc->gpmc_addr == GPMCCF_ADDR_DEFAULT)
82 panic("sm must have addr specified in config.");
84 if (gpmc->gpmc_intr == GPMCCF_INTR_DEFAULT)
85 panic("sm must have intr specified in config.");
87 /* Trust the config file. */
88 return (1);
91 static int
92 sm_gpmc_intr(void *arg)
94 struct sm_gpmc_softc * const gpmcsc = (struct sm_gpmc_softc *)arg;
95 struct smc91cxx_softc * const sc = &gpmcsc->sc_sm;
97 if (bus_space_read_2(sc->sc_bst, sc->sc_bsh, 0x1a)) {
98 int rv = smc91cxx_intr(sc);
99 if (bus_space_read_2(sc->sc_bst, sc->sc_bsh, 0x1a))
100 gpmcsc->sc_incomplete_ev.ev_count++;
101 return rv;
102 } else {
103 gpmcsc->sc_spurious_ev.ev_count++;
104 return 0;
108 static void
109 sm_gpmc_attach(struct device *parent, struct device *self, void *aux)
111 struct sm_gpmc_softc *gpmcsc = (struct sm_gpmc_softc *)self;
112 struct smc91cxx_softc *sc = &gpmcsc->sc_sm;
113 struct gpmc_attach_args *gpmc = aux;
114 bus_space_tag_t bst;
115 bus_space_handle_t bsh;
116 uint8_t enaddr[ETHER_ADDR_LEN];
117 unsigned int count = 0;
119 bst = gpmc->gpmc_iot;
121 /* map i/o space */
122 if (bus_space_map(bst, gpmc->gpmc_addr, SMC_IOSIZE + 16, 0, &bsh) != 0) {
123 aprint_error(": sm_gpmc_attach: can't map i/o space");
124 return;
127 aprint_normal("\n");
129 /* fill in master sc */
130 sc->sc_bst = bst;
131 sc->sc_bsh = bsh;
133 /* register the interrupt handler */
134 gpmcsc->ih = intr_establish(gpmc->gpmc_intr, IPL_NET, IST_LEVEL,
135 sm_gpmc_intr, gpmcsc);
137 if (gpmcsc->ih == NULL) {
138 aprint_error(": couldn't establish interrupt\n");
139 bus_space_unmap(bst, bsh, SMC_IOSIZE + 16);
140 return;
143 evcnt_attach_dynamic(&gpmcsc->sc_spurious_ev, EVCNT_TYPE_INTR, NULL,
144 self->dv_xname, "spurious intr");
145 evcnt_attach_dynamic(&gpmcsc->sc_incomplete_ev, EVCNT_TYPE_INTR, NULL,
146 self->dv_xname, "incomplete intr");
148 SMC_SELECT_BANK(sc, 1);
149 for (count = 0; count < ETHER_ADDR_LEN; count += 2) {
150 uint16_t tmp;
151 tmp = bus_space_read_2(bst, bsh, IAR_ADDR0_REG_W + count);
152 enaddr[count + 1] = (tmp >> 8) & 0xff;
153 enaddr[count] = tmp & 0xff;
157 * Reset the SMC
159 bus_space_write_2(bst, bsh, 0x1c, 1);
160 delay(2);
161 bus_space_write_2(bst, bsh, 0x1c, 6);
164 * Wait for the reset to complete.
166 while (bus_space_read_2(bst, bsh, 0x1a) & 1) {
167 if (++count > 1000) {
168 aprint_error(": didn't come out of reset\n");
169 return;
173 /* Perform generic attach. */
174 sc->sc_flags |= SMC_FLAGS_ENABLED;
175 smc91cxx_attach(sc, enaddr);