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

Annotation of sys/arch/arm/sa11x0/sa1111_gpio.c, Revision 1.1

1.1     ! nbrk        1: /*     $Id$    */
        !             2: #include <sys/cdefs.h>
        !             3:
        !             4: #include <sys/param.h>
        !             5: #include <sys/systm.h>
        !             6: #include <sys/device.h>
        !             7: #include <sys/malloc.h>
        !             8: #include <sys/evcount.h>
        !             9: #include <sys/queue.h>
        !            10: #include <uvm/uvm_extern.h>
        !            11:
        !            12: #include <machine/bus.h>
        !            13: #include <machine/intr.h>
        !            14: #include <machine/lock.h>
        !            15:
        !            16: #include <arm/sa11x0/sa11x1_var.h>
        !            17: #include <arm/sa11x0/sa1111_reg.h>
        !            18: #include <arm/sa11x0/sa1111_intr.h>
        !            19: #include <arm/sa11x0/sa1111_gpiovar.h>
        !            20:
        !            21: /*
        !            22:  * SA-1111 GPIO controller.
        !            23:  * It featurs three blocks:
        !            24:  *  - GPIO_A[0:3]
        !            25:  *  - GPIO_B[0:5]
        !            26:  *  - GPIO_C[0:7]
        !            27:  * We can control data value (level) and direction individually for each pin.
        !            28:  */
        !            29:
        !            30: struct sacgpio_softc {
        !            31:        struct device   sc_dev;
        !            32:        bus_space_tag_t sc_bust;
        !            33:        bus_space_handle_t      sc_bush;
        !            34: };
        !            35:
        !            36: /* autoconf glue */
        !            37: int    sacgpio_match(struct device *parent, void *cf, void *aux);
        !            38: void   sacgpio_attach(struct device *parent, struct device *self, void *aux);
        !            39:
        !            40: struct cfattach        sacgpio_ca = {
        !            41:        sizeof(struct sacgpio_softc),
        !            42:        sacgpio_match,
        !            43:        sacgpio_attach,
        !            44:        NULL,
        !            45:        NULL
        !            46: };
        !            47: struct cfdriver        sacgpio_cd = {
        !            48:        NULL,
        !            49:        "sacgpio",
        !            50:        DV_DULL
        !            51: };
        !            52:
        !            53: struct sacgpio_softc *sacgpio_sc;
        !            54:
        !            55: int
        !            56: sacgpio_match(struct device *parent, void *cf, void *aux)
        !            57: {
        !            58:        struct sacc_attach_args *saa = aux;
        !            59:
        !            60:        if (saa->sac_typecookie == SACC_TYPE_GPIO && sacgpio_sc == NULL)
        !            61:                return(1);
        !            62:
        !            63:        return(0);
        !            64: }
        !            65:
        !            66: void
        !            67: sacgpio_attach(struct device *parent, struct device *self, void *aux)
        !            68: {
        !            69:        struct sacgpio_softc *sc = (struct sacgpio_softc*)self;
        !            70:        struct sacc_attach_args *saa = aux;
        !            71:        sc->sc_bust = saa->sac_iot;
        !            72:        sc->sc_bush = saa->sac_bush;
        !            73:
        !            74:        /*
        !            75:         * Nothing to do. Just register default sc and return.
        !            76:         */
        !            77:        printf(": SA-1111 GPIO controller\n");
        !            78:
        !            79:        sacgpio_sc = sc;
        !            80: }
        !            81:
        !            82: /*
        !            83:  * Read value of port x.
        !            84:  */
        !            85: int
        !            86: sa1111_gpio_get_bit(int gpiobank, uint8_t gpio)
        !            87: {
        !            88:        struct sacgpio_softc *sc = sacgpio_sc;
        !            89:        bus_addr_t      reg;
        !            90:
        !            91:        if (sc == NULL)
        !            92:                panic("sa1111_gpio_get_bit: sacgpio not configured");
        !            93:
        !            94:        /* select bank */
        !            95:        switch (gpiobank) {
        !            96:                case SACGPIO_BANKA:
        !            97:                        /* block A has only 4 pins */
        !            98:                        if (gpio > 3)
        !            99:                                panic("%s: sa1111_gpio_get_bit: bogus gpio %d in bank A",
        !           100:                                                sc->sc_dev.dv_xname, gpio);
        !           101:                        reg = SACCGPIOA_DVR;
        !           102:                        break;
        !           103:                case SACGPIO_BANKB:
        !           104:                        /* block B has only 6 pins */
        !           105:                        if (gpio > 5)
        !           106:                                panic("%s: sa1111_gpio_get_bit: bogus gpio %d in bank B",
        !           107:                                                sc->sc_dev.dv_xname, gpio);
        !           108:                        reg = SACCGPIOB_DVR;
        !           109:                        break;
        !           110:                case SACGPIO_BANKC:
        !           111:                        reg = SACCGPIOC_DVR;
        !           112:                        break;
        !           113:                default:
        !           114:                        panic("%s: sa1111_gpio_get_bit: bogus gpio bank 0x%x",
        !           115:                                        sc->sc_dev.dv_xname, gpiobank);
        !           116:        }
        !           117:
        !           118:        return( bus_space_read_4(sc->sc_bust, sc->sc_bush, reg) & (1 << gpio) );
        !           119: }
        !           120:
        !           121: /*
        !           122:  * Set value of port x to 1.
        !           123:  */
        !           124: void
        !           125: sa1111_gpio_set_bit(int gpiobank, uint8_t gpio)
        !           126: {
        !           127:        struct sacgpio_softc *sc = sacgpio_sc;
        !           128:        bus_addr_t      reg;
        !           129:        uint32_t        oldval;
        !           130:
        !           131:        if (sc == NULL)
        !           132:                panic("sa1111_gpio_set_bit: sacgpio not configured");
        !           133:
        !           134:        /* select bank */
        !           135:        switch (gpiobank) {
        !           136:                case SACGPIO_BANKA:
        !           137:                        /* block A has only 4 pins */
        !           138:                        if (gpio > 3)
        !           139:                                panic("%s: sa1111_gpio_set_bit: bogus gpio %d in bank A",
        !           140:                                                sc->sc_dev.dv_xname, gpio);
        !           141:                        reg = SACCGPIOA_DVR;
        !           142:                        break;
        !           143:                case SACGPIO_BANKB:
        !           144:                        /* block B has only 6 pins */
        !           145:                        if (gpio > 5)
        !           146:                                panic("%s: sa1111_gpio_set_bit: bogus gpio %d in bank B",
        !           147:                                                sc->sc_dev.dv_xname, gpio);
        !           148:                        reg = SACCGPIOB_DVR;
        !           149:                        break;
        !           150:                case SACGPIO_BANKC:
        !           151:                        reg = SACCGPIOC_DVR;
        !           152:                        break;
        !           153:                default:
        !           154:                        panic("%s: sa1111_gpio_set_bit: bogus gpio bank 0x%x",
        !           155:                                        sc->sc_dev.dv_xname, gpiobank);
        !           156:        }
        !           157:        oldval = bus_space_read_4(sc->sc_bust, sc->sc_bush, reg);
        !           158:        bus_space_write_4(sc->sc_bust, sc->sc_bush, reg, oldval | 1 << gpio);
        !           159: }
        !           160:
        !           161: /*
        !           162:  * Set value of port x to 0.
        !           163:  */
        !           164: void
        !           165: sa1111_gpio_clear_bit(int gpiobank, uint8_t gpio)
        !           166: {
        !           167:        struct sacgpio_softc *sc = sacgpio_sc;
        !           168:        bus_addr_t      reg;
        !           169:        uint32_t        oldval;
        !           170:
        !           171:        if (sc == NULL)
        !           172:                panic("sa1111_gpio_glear_bit: sacgpio not configured");
        !           173:
        !           174:        /* select bank */
        !           175:        switch (gpiobank) {
        !           176:                case SACGPIO_BANKA:
        !           177:                        /* block A has only 4 pins */
        !           178:                        if (gpio > 3)
        !           179:                                panic("%s: sa1111_gpio_clear_bit: bogus gpio %d in bank A",
        !           180:                                                sc->sc_dev.dv_xname, gpio);
        !           181:                        reg = SACCGPIOA_DVR;
        !           182:                        break;
        !           183:                case SACGPIO_BANKB:
        !           184:                        /* block B has only 6 pins */
        !           185:                        if (gpio > 5)
        !           186:                                panic("%s: sa1111_gpio_clear_bit: bogus gpio %d in bank B",
        !           187:                                                sc->sc_dev.dv_xname, gpio);
        !           188:                        reg = SACCGPIOB_DVR;
        !           189:                        break;
        !           190:                case SACGPIO_BANKC:
        !           191:                        reg = SACCGPIOC_DVR;
        !           192:                        break;
        !           193:                default:
        !           194:                        panic("%s: sa1111_gpio_clear_sit: bogus gpio bank 0x%x",
        !           195:                                        sc->sc_dev.dv_xname, gpiobank);
        !           196:        }
        !           197:        oldval = bus_space_read_4(sc->sc_bust, sc->sc_bush, reg);
        !           198:        bus_space_write_4(sc->sc_bust, sc->sc_bush, reg, oldval & ~(1 << gpio));
        !           199: }
        !           200:
        !           201: /*
        !           202:  * Set port direction.
        !           203:  */
        !           204: void
        !           205: sa1111_gpio_set_dir(int gpiobank, uint8_t gpio, int dir)
        !           206: {
        !           207:        struct sacgpio_softc *sc = sacgpio_sc;
        !           208:        bus_addr_t      reg;
        !           209:        uint32_t        olddir;
        !           210:
        !           211:        if (sc == NULL)
        !           212:                panic("sa1111_gpio_set_dir: sacgpio not configured");
        !           213:
        !           214:        /* select bank */
        !           215:        switch (gpiobank) {
        !           216:                case SACGPIO_BANKA:
        !           217:                        /* block A has only 4 pins */
        !           218:                        if (gpio > 3)
        !           219:                                panic("%s: sa1111_gpio_set_dir: bogus gpio %d in bank A",
        !           220:                                                sc->sc_dev.dv_xname, gpio);
        !           221:                        reg = SACCGPIOA_DDR;
        !           222:                        break;
        !           223:                case SACGPIO_BANKB:
        !           224:                        /* block B has only 6 pins */
        !           225:                        if (gpio > 5)
        !           226:                                panic("%s: sa1111_gpio_set_dir: bogus gpio %d in bank B",
        !           227:                                                sc->sc_dev.dv_xname, gpio);
        !           228:                        reg = SACCGPIOB_DDR;
        !           229:                        break;
        !           230:                case SACGPIO_BANKC:
        !           231:                        reg = SACCGPIOC_DDR;
        !           232:                        break;
        !           233:                default:
        !           234:                        panic("%s: sa1111_gpio_set_dir: bogus gpio bank 0x%x",
        !           235:                                        sc->sc_dev.dv_xname, gpiobank);
        !           236:        }
        !           237:        /* direction */
        !           238:        olddir = bus_space_read_4(sc->sc_bust, sc->sc_bush, reg);
        !           239:        switch (dir) {
        !           240:                case SACGPIO_DIR_INPUT:
        !           241:                        olddir |= 1 << gpio;
        !           242:                        break;
        !           243:                case SACGPIO_DIR_OUTPUT:
        !           244:                        olddir &= ~(1 << gpio);
        !           245:                        break;
        !           246:                default:
        !           247:                        panic("%s: sa1111_gpio_set_dir: bogus direction 0x%x",
        !           248:                                        sc->sc_dev.dv_xname, dir);
        !           249:        }
        !           250:        bus_space_write_4(sc->sc_bust, sc->sc_bush, reg, olddir);
        !           251: }
        !           252:
        !           253: /*
        !           254:  * Get port direction.
        !           255:  */
        !           256: u_int
        !           257: sa1111_gpio_get_dir(int gpiobank, uint8_t gpio)
        !           258: {
        !           259:        struct sacgpio_softc *sc = sacgpio_sc;
        !           260:        bus_addr_t      reg;
        !           261:        int     dir;
        !           262:
        !           263:        if (sc == NULL)
        !           264:                panic("sa1111_gpio_get_dir: sacgpio not configured");
        !           265:
        !           266:        /* select bank */
        !           267:        switch (gpiobank) {
        !           268:                case SACGPIO_BANKA:
        !           269:                        /* block A has only 4 pins */
        !           270:                        if (gpio > 3)
        !           271:                                panic("%s: sa1111_gpio_get_dir: bogus gpio %d in bank A",
        !           272:                                                sc->sc_dev.dv_xname, gpio);
        !           273:                        reg = SACCGPIOA_DDR;
        !           274:                        break;
        !           275:                case SACGPIO_BANKB:
        !           276:                        /* block B has only 6 pins */
        !           277:                        if (gpio > 5)
        !           278:                                panic("%s: sa1111_gpio_get_dir: bogus gpio %d in bank B",
        !           279:                                                sc->sc_dev.dv_xname, gpio);
        !           280:                        reg = SACCGPIOB_DDR;
        !           281:                        break;
        !           282:                case SACGPIO_BANKC:
        !           283:                        reg = SACCGPIOC_DDR;
        !           284:                        break;
        !           285:                default:
        !           286:                        panic("%s: sa1111_gpio_get_dir: bogus gpio bank 0x%x",
        !           287:                                        sc->sc_dev.dv_xname, gpiobank);
        !           288:        }
        !           289:
        !           290:        dir = bus_space_read_4(sc->sc_bust, sc->sc_bush, reg) & ~(1 << gpio);
        !           291:
        !           292:        return (dir ? SACGPIO_DIR_INPUT : SACGPIO_DIR_OUTPUT);
        !           293: }
        !           294:
        !           295:

CVSweb