[BACK]Return to s3c2410_spi.c CVS log [TXT][DIR] Up to [local] / sys / arch / arm / s3c2xx0

Annotation of sys/arch/arm/s3c2xx0/s3c2410_spi.c, Revision 1.1.1.1

1.1       nbrk        1: /* $NetBSD: s3c2410_spi.c,v 1.4 2005/12/11 12:16:51 christos Exp $ */
                      2:
                      3: /*
                      4:  * Copyright (c) 2004  Genetec Corporation.  All rights reserved.
                      5:  * Written by Hiroyuki Bessho for Genetec Corporation.
                      6:  *
                      7:  * Redistribution and use in source and binary forms, with or without
                      8:  * modification, are permitted provided that the following conditions
                      9:  * are met:
                     10:  * 1. Redistributions of source code must retain the above copyright
                     11:  *    notice, this list of conditions and the following disclaimer.
                     12:  * 2. Redistributions in binary form must reproduce the above copyright
                     13:  *    notice, this list of conditions and the following disclaimer in the
                     14:  *    documentation and/or other materials provided with the distribution.
                     15:  * 3. The name of Genetec Corporation may not be used to endorse or
                     16:  *    promote products derived from this software without specific prior
                     17:  *    written permission.
                     18:  *
                     19:  * THIS SOFTWARE IS PROVIDED BY GENETEC CORPORATION ``AS IS'' AND
                     20:  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     21:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     22:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL GENETEC CORPORATION
                     23:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     24:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     25:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     26:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     27:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     28:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     29:  * POSSIBILITY OF SUCH DAMAGE.
                     30:  */
                     31:
                     32: /*
                     33:  * Support S3C2410's SPI dirver.
                     34:  * Real works are done by drivers attached to SPI ports.
                     35:  */
                     36:
                     37: #include <sys/cdefs.h>
                     38: __KERNEL_RCSID(0, "$NetBSD: s3c2410_spi.c,v 1.4 2005/12/11 12:16:51 christos Exp $");
                     39:
                     40: #include <sys/param.h>
                     41: #include <sys/systm.h>
                     42: #include <sys/conf.h>
                     43:
                     44: #include <machine/bus.h>
                     45: #include <machine/cpu.h>
                     46:
                     47: #include <arm/s3c2xx0/s3c24x0var.h>
                     48: #include <arm/s3c2xx0/s3c24x0reg.h>
                     49: #include <arm/s3c2xx0/s3c2410reg.h>
                     50:
                     51: #include <arm/s3c2xx0/s3c24x0_spi.h>
                     52:
                     53: #include "locators.h"
                     54:
                     55: struct ssspi_softc {
                     56:        struct device dev;
                     57:
                     58:        bus_space_tag_t    iot;
                     59:        bus_space_handle_t ioh;
                     60:        short   index;
                     61: };
                     62:
                     63:
                     64: /* prototypes */
                     65: static int     ssspi_match(struct device *, struct cfdata *, void *);
                     66: static void    ssspi_attach(struct device *, struct device *, void *);
                     67: static int     ssspi_search(struct device *, struct cfdata *,
                     68:                             const int *, void *);
                     69: static int     ssspi_print(void *, const char *);
                     70:
                     71: /* attach structures */
                     72: CFATTACH_DECL(ssspi, sizeof(struct ssspi_softc), ssspi_match, ssspi_attach,
                     73:     NULL, NULL);
                     74:
                     75:
                     76: static int
                     77: ssspi_print(void *aux, const char *name)
                     78: {
                     79:        struct ssspi_attach_args *spia = aux;
                     80:
                     81:        if (spia->spia_aux_intr != SSSPICF_INTR_DEFAULT)
                     82:                printf(" intr %d", spia->spia_aux_intr);
                     83:         return (UNCONF);
                     84: }
                     85:
                     86: int
                     87: ssspi_match(struct device *parent, struct cfdata *match, void *aux)
                     88: {
                     89:        struct s3c2xx0_attach_args *sa = aux;
                     90:
                     91:        /* S3C2410 have only two SPIs */
                     92:        switch (sa->sa_index) {
                     93:        case 0:
                     94:        case 1:
                     95:                break;
                     96:        default:
                     97:                return 0;
                     98:        }
                     99:
                    100:        return 1;
                    101: }
                    102:
                    103: void
                    104: ssspi_attach(struct device *parent, struct device *self, void *aux)
                    105: {
                    106:        struct ssspi_softc *sc = (struct ssspi_softc*)self;
                    107:        struct s3c2xx0_attach_args *sa = (struct s3c2xx0_attach_args *)aux;
                    108:        bus_space_tag_t iot = sa->sa_iot;
                    109:
                    110:        static bus_space_handle_t spi_ioh = 0;
                    111:
                    112:        /* we map all registers for SPI0 and SPI1 at once, then
                    113:           use subregions */
                    114:        if (spi_ioh == 0) {
                    115:                if (bus_space_map(iot, S3C2410_SPI0_BASE,
                    116:                                  2 * S3C24X0_SPI_SIZE,
                    117:                                  0, &spi_ioh)) {
                    118:                        aprint_error(": can't map registers\n");
                    119:                        return;
                    120:                }
                    121:        }
                    122:
                    123:        aprint_normal("\n");
                    124:
                    125:        sc->index = sa->sa_index;
                    126:        sc->iot = iot;
                    127:
                    128:        bus_space_subregion(iot, spi_ioh, sc->index == 0 ? 0 : S3C24X0_SPI_SIZE,
                    129:            S3C24X0_SPI_SIZE, &sc->ioh);
                    130:
                    131:        /*
                    132:         *  Attach child devices
                    133:         */
                    134:        config_search_ia(ssspi_search, self, "ssspi", NULL);
                    135: }
                    136:
                    137: int
                    138: ssspi_search(parent, cf, ldesc, aux)
                    139:        struct device *parent;
                    140:        struct cfdata *cf;
                    141:        const int *ldesc;
                    142:        void *aux;
                    143: {
                    144:        struct ssspi_softc *sc = (struct ssspi_softc *)parent;
                    145:        struct ssspi_attach_args spia;
                    146:        static const unsigned char intr[] = { S3C24X0_INT_SPI0,
                    147:                                              S3C2410_INT_SPI1 };
                    148:
                    149:        KASSERT(sc->index == 0 || sc->index == 1);
                    150:
                    151:        spia.spia_iot = sc->iot;
                    152:        spia.spia_ioh = sc->ioh;
                    153:        spia.spia_gpioh = s3c2xx0_softc->sc_gpio_ioh;
                    154:        spia.spia_index = sc->index;
                    155:        spia.spia_intr = intr[sc->index];
                    156:        spia.spia_aux_intr = cf->cf_loc[SSSPICF_INTR];
                    157:        spia.spia_dmat = s3c2xx0_softc->sc_dmat;
                    158:
                    159:         if (config_match(parent, cf, &spia))
                    160:                 config_attach(parent, cf, &spia, ssspi_print);
                    161:
                    162:         return 0;
                    163: }
                    164:
                    165: /*
                    166:  * Intiialze SPI port. called by child devices.
                    167:  */
                    168: int
                    169: s3c24x0_spi_setup(struct ssspi_softc *sc, uint32_t mode, int bps, int use_ss)
                    170: {
                    171:        int pclk = s3c2xx0_softc->sc_pclk;
                    172:        int prescaler;
                    173:        uint32_t pgcon, pecon;
                    174:        bus_space_handle_t gpioh = s3c2xx0_softc->sc_gpio_ioh;
                    175:        bus_space_tag_t iot = sc->iot;
                    176:
                    177:        if (bps > 1) {
                    178:                prescaler = pclk / 2 / bps - 1;
                    179:
                    180:                if (prescaler <= 0 || 0xff < prescaler)
                    181:                        return -1;
                    182:                bus_space_write_1(sc->iot, sc->ioh, SPI_SPPRE, prescaler);
                    183:        }
                    184:
                    185:
                    186:        if (sc->index == 0) {
                    187:                pecon = bus_space_read_4(iot, gpioh, GPIO_PECON);
                    188:
                    189:                if (use_ss) {
                    190:                        pgcon = bus_space_read_4(iot, gpioh, GPIO_PGCON);
                    191:                        pgcon = GPIO_SET_FUNC(pgcon, 2, PCON_ALTFUN2);
                    192:                        bus_space_write_4(iot, gpioh, GPIO_PGCON, pgcon);
                    193:                }
                    194:
                    195:                pecon = GPIO_SET_FUNC(pecon, 11, PCON_ALTFUN2); /* SPIMISO0 */
                    196:                pecon = GPIO_SET_FUNC(pecon, 12, PCON_ALTFUN2); /* SPIMOSI0 */
                    197:                pecon = GPIO_SET_FUNC(pecon, 13, PCON_ALTFUN2); /* SPICL0 */
                    198:
                    199:                bus_space_write_4(iot, gpioh, GPIO_PECON, pecon);
                    200:        }
                    201:        else {
                    202:                pgcon = bus_space_read_4(iot, gpioh, GPIO_PGCON);
                    203:
                    204:                if (use_ss)
                    205:                        pgcon = GPIO_SET_FUNC(pgcon, 3, PCON_ALTFUN2);
                    206:
                    207:                pgcon = GPIO_SET_FUNC(pgcon, 5, PCON_ALTFUN2); /* SPIMISO1 */
                    208:                pgcon = GPIO_SET_FUNC(pgcon, 6, PCON_ALTFUN2); /* SPIMOSI1 */
                    209:                pgcon = GPIO_SET_FUNC(pgcon, 7, PCON_ALTFUN2); /* SPICLK1 */
                    210:
                    211:                bus_space_write_4(iot, gpioh, GPIO_PGCON, pgcon);
                    212:        }
                    213:
                    214:        bus_space_write_4(iot, sc->ioh, SPI_SPCON, mode);
                    215:
                    216:        return 0;
                    217: }

CVSweb