[BACK]Return to gxpcic.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / evbarm / gumstix

Annotation of src/sys/arch/evbarm/gumstix/gxpcic.c, Revision 1.2.4.2

1.2.4.2 ! ad          1: /*     $NetBSD: gxpcic.c,v 1.2.4.1 2006/11/18 21:29:10 ad Exp $ */
        !             2: /*
        !             3:  * Copyright (C) 2005, 2006 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: /*
        !            34:  * Copyright (c) 2002, 2003, 2005  Genetec corp.  All rights reserved.
        !            35:  *
        !            36:  * PCMCIA/CF support for TWINTAIL (G4255EB)
        !            37:  * Written by Hiroyuki Bessho for Genetec corp.
        !            38:  *
        !            39:  * Redistribution and use in source and binary forms, with or without
        !            40:  * modification, are permitted provided that the following conditions
        !            41:  * are met:
        !            42:  * 1. Redistributions of source code must retain the above copyright
        !            43:  *    notice, this list of conditions and the following disclaimer.
        !            44:  * 2. Redistributions in binary form must reproduce the above copyright
        !            45:  *    notice, this list of conditions and the following disclaimer in the
        !            46:  *    documentation and/or other materials provided with the distribution.
        !            47:  * 3. The name of Genetec corp. may not be used to endorse
        !            48:  *    or promote products derived from this software without specific prior
        !            49:  *    written permission.
        !            50:  *
        !            51:  * THIS SOFTWARE IS PROVIDED BY GENETEC CORP. ``AS IS'' AND
        !            52:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
        !            53:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
        !            54:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORP.
        !            55:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
        !            56:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
        !            57:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
        !            58:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
        !            59:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
        !            60:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
        !            61:  * POSSIBILITY OF SUCH DAMAGE.
        !            62:  */
        !            63:
        !            64: #include <sys/types.h>
        !            65: #include <sys/param.h>
        !            66: #include <sys/systm.h>
        !            67: #include <sys/device.h>
        !            68: #include <sys/callout.h>
        !            69: #include <sys/kernel.h>
        !            70: #include <sys/kthread.h>
        !            71: #include <sys/malloc.h>
        !            72: #include <uvm/uvm.h>
        !            73:
        !            74: #include <machine/bus.h>
        !            75: #include <machine/intr.h>
        !            76:
        !            77: #include <dev/pcmcia/pcmciareg.h>
        !            78: #include <dev/pcmcia/pcmciavar.h>
        !            79: #include <dev/pcmcia/pcmciachip.h>
        !            80:
        !            81: #include <arch/arm/xscale/pxa2x0var.h>
        !            82: #include <arch/arm/xscale/pxa2x0reg.h>
        !            83: #include <arch/arm/sa11x0/sa11xx_pcicvar.h>
        !            84: #include <arch/evbarm/gumstix/gumstixvar.h>
        !            85:
        !            86:
        !            87: #ifdef DEBUG
        !            88: #define DPRINTF(arg)   printf arg
        !            89: #else
        !            90: #define DPRINTF(arg)
        !            91: #endif
        !            92:
        !            93: #define HAVE_CARD(r)   (!((r) & GPIO_SET))
        !            94:
        !            95: #define GXIO_GPIO8_RESET       8
        !            96: #define GXIO_GPIRQ11_nCD       11
        !            97: #define GXIO_GPIO26_READY      26
        !            98:
        !            99: struct gxpcic_softc;
        !           100:
        !           101: struct gxpcic_socket {
        !           102:        struct sapcic_socket ss;        /* inherit socket for sa11x0 pcic */
        !           103: };
        !           104:
        !           105: struct gxpcic_softc {
        !           106:        struct sapcic_softc sc_pc;      /* inherit SA11xx pcic */
        !           107:
        !           108:        bus_space_tag_t sc_iot;
        !           109:        bus_space_handle_t sc_ioh;
        !           110:        int sc_gpirq;
        !           111:
        !           112:        struct gxpcic_socket sc_socket[2];
        !           113:        int sc_cards;
        !           114: };
        !           115:
        !           116: static int     gxpcic_match(struct device *, struct cfdata *, void *);
        !           117: static void    gxpcic_attach(struct device *, struct device *, void *);
        !           118:
        !           119: static int     gxpcic_card_detect(void *);
        !           120: static int     gxpcic_read(struct sapcic_socket *, int);
        !           121: static void    gxpcic_write(struct sapcic_socket *, int, int);
        !           122: static void    gxpcic_set_power(struct sapcic_socket *, int);
        !           123: static void    gxpcic_clear_intr(int);
        !           124: static void    *gxpcic_intr_establish(struct sapcic_socket *, int,
        !           125:                                       int (*)(void *), void *);
        !           126: static void    gxpcic_intr_disestablish(struct sapcic_socket *, void *);
        !           127:
        !           128: CFATTACH_DECL(gxpcic, sizeof(struct gxpcic_softc),
        !           129:     gxpcic_match, gxpcic_attach, NULL, NULL);
        !           130:
        !           131: static struct sapcic_tag gxpcic_tag = {
        !           132:        gxpcic_read,
        !           133:        gxpcic_write,
        !           134:        gxpcic_set_power,
        !           135:        gxpcic_clear_intr,
        !           136:        gxpcic_intr_establish,
        !           137:        gxpcic_intr_disestablish,
        !           138: };
        !           139:
        !           140:
        !           141: static int
        !           142: gxpcic_match(struct device *parent, struct cfdata *cf, void *aux)
        !           143: {
        !           144:        struct {
        !           145:                int gpio;
        !           146:                u_int fn;
        !           147:        } gpiomodes[] = {
        !           148:                { 48, GPIO_ALT_FN_2_OUT },              /* nPOE */
        !           149:                { 49, GPIO_ALT_FN_2_OUT },              /* nPWE */
        !           150:                { 50, GPIO_ALT_FN_2_OUT },              /* nPIOR */
        !           151:                { 51, GPIO_ALT_FN_2_OUT },              /* nPIOW */
        !           152:                { 54, GPIO_ALT_FN_2_OUT },              /* pSKTSEL */
        !           153:                { 55, GPIO_ALT_FN_2_OUT },              /* nPREG */
        !           154:                { 56, GPIO_ALT_FN_1_IN },               /* nPWAIT */
        !           155:                { 57, GPIO_ALT_FN_1_IN },               /* nIOIS16 */
        !           156:                { -1 }
        !           157:        };
        !           158:        u_int reg;
        !           159:        int i;
        !           160:
        !           161:        for (i = 0; gpiomodes[i].gpio != -1; i++) {
        !           162:                reg = pxa2x0_gpio_get_function(gpiomodes[i].gpio);
        !           163:                if (GPIO_FN(reg) != GPIO_FN(gpiomodes[i].fn) ||
        !           164:                    GPIO_FN_IS_OUT(reg) != GPIO_FN_IS_OUT(gpiomodes[i].fn))
        !           165:                        break;
        !           166:        }
        !           167:        if (gpiomodes[i].gpio != -1)
        !           168:                return 0;
        !           169:
        !           170:        return  1;      /* match */
        !           171: }
        !           172:
        !           173: static void
        !           174: gxpcic_attach(struct device *parent, struct device *self, void *aux)
        !           175: {
        !           176:        struct gxio_softc *gxsc = (struct gxio_softc *)parent;
        !           177:        struct gxpcic_softc *sc = (struct gxpcic_softc *)self;
        !           178:        struct gxio_attach_args *gxa = aux;
        !           179:        struct pcmciabus_attach_args paa;
        !           180:        int mecr, val, i, n;
        !           181:
        !           182:        printf("\n");
        !           183:
        !           184:        sc->sc_iot = sc->sc_pc.sc_iot = gxa->gxa_iot;
        !           185:        sc->sc_ioh = gxsc->sc_ioh;
        !           186:        sc->sc_gpirq = gxa->gxa_gpirq;
        !           187:        sc->sc_cards = 0;
        !           188:
        !           189:        n = bus_space_read_4(sc->sc_iot, sc->sc_ioh, MEMCTL_MECR) & MECR_NOS ?
        !           190:            2 : 1;
        !           191:        for (i = 0; i < n; i++) {
        !           192:                sc->sc_socket[i].ss.sc = &sc->sc_pc;
        !           193:                sc->sc_socket[i].ss.socket = 0;
        !           194:                sc->sc_socket[i].ss.pcictag_cookie = NULL;
        !           195:                sc->sc_socket[i].ss.pcictag = &gxpcic_tag;
        !           196:                sc->sc_socket[i].ss.event_thread = NULL;
        !           197:                sc->sc_socket[i].ss.event = 0;
        !           198:                sc->sc_socket[i].ss.laststatus = SAPCIC_CARD_INVALID;
        !           199:                sc->sc_socket[i].ss.shutdown = 0;
        !           200:
        !           201:                /* 3.3V only? */
        !           202:                sc->sc_socket[i].ss.power_capability = SAPCIC_POWER_3V;
        !           203:
        !           204:                bus_space_write_4(sc->sc_iot, sc->sc_ioh, MEMCTL_MCMEM(i),
        !           205:                    MC_TIMING_VAL(10,10,30));
        !           206:                bus_space_write_4(sc->sc_iot, sc->sc_ioh, MEMCTL_MCATT(i),
        !           207:                    MC_TIMING_VAL(10,10,30));
        !           208:                bus_space_write_4(sc->sc_iot, sc->sc_ioh, MEMCTL_MCIO(i),
        !           209:                    MC_TIMING_VAL(6,6,17));
        !           210:
        !           211:                paa.paa_busname = "pcmcia";
        !           212:                paa.pct = (pcmcia_chipset_tag_t)&sa11x0_pcmcia_functions;
        !           213:                paa.pch = (pcmcia_chipset_handle_t)&sc->sc_socket[i].ss;
        !           214:                paa.iobase = 0;
        !           215:                paa.iosize = 0x4000000;
        !           216:
        !           217:                sc->sc_socket[i].ss.pcmcia =
        !           218:                    (struct device *)config_found_ia(&sc->sc_pc.sc_dev,
        !           219:                    "pcmciabus", &paa, NULL);
        !           220:
        !           221:                /* interrupt for card insertion/removal */
        !           222:                gxio_intr_establish(sc, GXIO_GPIRQ11_nCD, IST_EDGE_BOTH,
        !           223:                    IPL_BIO, gxpcic_card_detect, &sc->sc_socket[i]);
        !           224:
        !           225:                /* if card was insert then set CIT */
        !           226:                val = pxa2x0_gpio_get_function(GXIO_GPIRQ11_nCD);
        !           227:                if (HAVE_CARD(val)) {
        !           228:                        mecr = bus_space_read_4(
        !           229:                            sc->sc_iot, sc->sc_ioh, MEMCTL_MECR);
        !           230:                        bus_space_write_4(sc->sc_iot,
        !           231:                            sc->sc_ioh, MEMCTL_MECR, mecr | MECR_CIT);
        !           232:                }
        !           233:
        !           234:                /* schedule kthread creation */
        !           235:                kthread_create(sapcic_kthread_create, &sc->sc_socket[i].ss);
        !           236:        }
        !           237:
        !           238: }
        !           239:
        !           240: static int
        !           241: gxpcic_card_detect(void *arg)
        !           242: {
        !           243:        struct gxpcic_socket *socket = arg;
        !           244:        struct gxpcic_softc *sc = (struct gxpcic_softc *)socket->ss.sc;
        !           245:        int sock_no = socket->ss.socket;
        !           246:        int mecr, last, val, s;
        !           247:
        !           248:        s = splbio();
        !           249:        last = sc->sc_cards;
        !           250:        val = pxa2x0_gpio_get_function(GXIO_GPIRQ11_nCD);
        !           251:        if (HAVE_CARD(val)) {
        !           252:                sc->sc_cards |= 1<<sock_no;
        !           253:                /* if it is the first card, turn on expansion memory control. */
        !           254:                if (last == 0) {
        !           255:                        mecr = bus_space_read_4(
        !           256:                            sc->sc_iot, sc->sc_ioh, MEMCTL_MECR);
        !           257:                        bus_space_write_4(sc->sc_iot,
        !           258:                            sc->sc_ioh, MEMCTL_MECR, mecr | MECR_CIT);
        !           259:                }
        !           260:        } else {
        !           261:                sc->sc_cards &= ~(1<<sock_no);
        !           262:                /* if we loast all cards, turn off expansion memory control. */
        !           263:                if (sc->sc_cards == 0) {
        !           264:                        mecr = bus_space_read_4(
        !           265:                            sc->sc_iot, sc->sc_ioh, MEMCTL_MECR);
        !           266:                        bus_space_write_4(sc->sc_iot,
        !           267:                            sc->sc_ioh, MEMCTL_MECR, mecr & ~MECR_CIT);
        !           268:                }
        !           269:        }
        !           270:        splx(s);
        !           271:
        !           272:        DPRINTF(("%s: card %d %s\n", sc->sc_pc.sc_dev.dv_xname, sock_no,
        !           273:            HAVE_CARD(val) ? "inserted" : "removed"));
        !           274:
        !           275:        sapcic_intr(arg);
        !           276:
        !           277:        return 1;
        !           278: }
        !           279:
        !           280: /* ARGSUSED */
        !           281: static int
        !           282: gxpcic_read(struct sapcic_socket *so, int which)
        !           283: {
        !           284:        int reg;
        !           285:
        !           286:        switch (which) {
        !           287:        case SAPCIC_STATUS_CARD:
        !           288:                reg = pxa2x0_gpio_get_function(GXIO_GPIRQ11_nCD);
        !           289:                return (HAVE_CARD(reg) ?
        !           290:                    SAPCIC_CARD_VALID : SAPCIC_CARD_INVALID);
        !           291:
        !           292:        case SAPCIC_STATUS_READY:
        !           293:                reg = pxa2x0_gpio_get_function(GXIO_GPIO26_READY);
        !           294:                return (reg & GPIO_SET ? 1 : 0);
        !           295:
        !           296:        default:
        !           297:                panic("%s: bogus register", __FUNCTION__);
        !           298:        }
        !           299: }
        !           300:
        !           301: /* ARGSUSED */
        !           302: static void
        !           303: gxpcic_write(struct sapcic_socket *so, int which, int arg)
        !           304: {
        !           305:
        !           306:        switch (which) {
        !           307:        case SAPCIC_CONTROL_RESET:
        !           308: #if 0  /* XXXX: Our PXA2x0 no necessary ??? */
        !           309:                if (arg)
        !           310:                        pxa2x0_gpio_set_function(GXIO_GPIO8_RESET, GPIO_SET);
        !           311:                else
        !           312:                        pxa2x0_gpio_set_function(GXIO_GPIO8_RESET, GPIO_CLR);
        !           313: #endif
        !           314:                break;
        !           315:
        !           316:        case SAPCIC_CONTROL_LINEENABLE:
        !           317:                break;
        !           318:
        !           319:        case SAPCIC_CONTROL_WAITENABLE:
        !           320:                break;
        !           321:
        !           322:        case SAPCIC_CONTROL_POWERSELECT:
        !           323:                break;
        !           324:
        !           325:        default:
        !           326:                panic("%s: bogus register", __FUNCTION__);
        !           327:        }
        !           328: }
        !           329:
        !           330: static void
        !           331: gxpcic_set_power(struct sapcic_socket *__so, int arg)
        !           332: {
        !           333:
        !           334:        if(arg != SAPCIC_POWER_OFF && arg != SAPCIC_POWER_3V)
        !           335:                panic("%s: bogus arg\n", __FUNCTION__);
        !           336:
        !           337:        /* 3.3V only? */
        !           338: }
        !           339:
        !           340: /* ARGSUSED */
        !           341: static void
        !           342: gxpcic_clear_intr(int arg)
        !           343: {
        !           344:
        !           345:        /* nothing to do */
        !           346: }
        !           347:
        !           348: static void *
        !           349: gxpcic_intr_establish(struct sapcic_socket *so, int level,
        !           350:     int (* ih_fun)(void *), void *ih_arg)
        !           351: {
        !           352:        __attribute__((unused))struct gxpcic_softc *sc =
        !           353:            (struct gxpcic_softc *)so->sc;
        !           354:        int gpirq;
        !           355:
        !           356:        gpirq = GXIO_GPIO26_READY;
        !           357:
        !           358:        DPRINTF(("%s: card %d gpio %d\n",
        !           359:            sc->sc_pc.sc_dev.dv_xname, so->socket, gpirq));
        !           360:
        !           361:        return gxio_intr_establish(sc, gpirq, IST_EDGE_FALLING, level,
        !           362:            ih_fun, ih_arg);
        !           363: }
        !           364:
        !           365: static void
        !           366: gxpcic_intr_disestablish(struct sapcic_socket *so, void *ih)
        !           367: {
        !           368:        __attribute__((unused))struct gxpcic_softc *sc =
        !           369:            (struct gxpcic_softc *)so->sc;
        !           370:
        !           371:        gxio_intr_disestablish(sc, ih);
        !           372: }

CVSweb <webmaster@jp.NetBSD.org>