[BACK]Return to imxuart.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / sys / arch / arm / imx

Annotation of src/sys/arch/arm/imx/imxuart.c, Revision 1.1.24.1

1.1.24.1! yamt        1: /* $Id$ */
        !             2: #include <sys/types.h>
        !             3: #include <sys/systm.h>
        !             4: #include <sys/device.h>
        !             5: #include <sys/conf.h>
        !             6:
        !             7: #include <arm/armreg.h>
        !             8:
        !             9: #include <sys/tty.h>
        !            10: #include <sys/termios.h>
        !            11: #include <dev/cons.h>
        !            12:
        !            13: #include <machine/bus.h>
        !            14: #include <arm/imx/imx31var.h>
        !            15: #include <arm/imx/imxuartreg.h>
        !            16: #include <arm/imx/imxuartvar.h>
        !            17: #include <evbarm/imx31/imx31lk_reg.h>
        !            18:
        !            19: #define IMXUART_UNIT_MASK      0x7ffff
        !            20: #define IMXUART_DIALOUT_MASK   0x80000
        !            21:
        !            22: #define IMXUART_UNIT(dev)      (minor(dev) & IMXUART_UNIT_MASK)
        !            23: #define IMXUART_DIALOUT(dev)   (minor(dev) & IMXUART_DIALOUT_MASK)
        !            24:
        !            25:
        !            26:
        !            27: #define __TRACE        imxuart_puts(&imxuart_softc, __FUNCTION__ )
        !            28:
        !            29: extern struct bus_space imx31_bs_tag;
        !            30:
        !            31: imxuart_softc_t imxuart_softc = { { 0, }, };
        !            32:
        !            33: uint32_t imxuart_snapshot_data[32];
        !            34: const char *imxuart_test_string =
        !            35:        "0123456789012345678901234567890123456789\r\n";
        !            36:
        !            37:
        !            38: cons_decl(imxuart);
        !            39: static struct consdev imxuartcntab = cons_init(imxuart);
        !            40:
        !            41: #ifdef NOTYET
        !            42: dev_type_open(imxuartopen);
        !            43: dev_type_close(imxuartclose);
        !            44: dev_type_read(imxuartread);
        !            45: dev_type_write(imxuartwrite);
        !            46: dev_type_ioctl(imxuartioctl);
        !            47: dev_type_stop(imxuartstop);
        !            48: dev_type_tty(imxuarttty);
        !            49: dev_type_poll(imxuartpoll);
        !            50: const struct cdevsw imxuart_cdevsw = {
        !            51:         imxuartopen, imxuartclose, imxuartread, imxuartwrite,
        !            52:        imxuartioctl, imxuartstop, imxuarttty, imxuartpoll,
        !            53:        nommap, ttykqfilter, D_TTY
        !            54: };
        !            55: #else
        !            56: const struct cdevsw imxuart_cdevsw = {
        !            57:         nullopen, nullclose, nullread, nullwrite,
        !            58:        nullioctl, nullstop, notty, nullpoll,
        !            59:        nommap, nullkqfilter, D_TTY
        !            60: };
        !            61: #endif
        !            62:
        !            63:
        !            64: int  imxuart_cnattach(bus_space_tag_t, bus_addr_t, int, int, int, tcflag_t);
        !            65: int  imxuart_puts(imxuart_softc_t *, const char *);
        !            66: int  imxuart_putchar(imxuart_softc_t *, int);
        !            67: int  imxuart_getchar(imxuart_softc_t *);
        !            68:
        !            69: static int  imxuart_urxd_brk(void);
        !            70: static void imxuart_urxd_err(imxuart_softc_t *, uint32_t);
        !            71:
        !            72: static int imxuart_match(struct device *, struct cfdata *, void *);
        !            73: static void imxuart_attach(struct device *, struct device *, void *);
        !            74:
        !            75: static void imxuart_start(struct tty *);
        !            76: static int  imxuart_param(struct tty *, struct termios *);
        !            77: static void imxuart_shutdownhook(void *arg);
        !            78:
        !            79: CFATTACH_DECL(imxuart, sizeof(struct imxuart_softc),
        !            80:     imxuart_match, imxuart_attach, NULL, NULL);
        !            81:
        !            82:
        !            83: /*
        !            84:  * disable the specified IMX UART interrupt in softc
        !            85:  * return -1 on error
        !            86:  * else return previous enabled state
        !            87:  */
        !            88: static __inline int
        !            89: imxuart_intrspec_dis(imxuart_softc_t *sc, imxuart_intrix_t ix)
        !            90: {
        !            91:        const imxuart_intrspec_t *spec = &imxuart_intrspec_tab[ix];
        !            92:        uint32_t v;
        !            93:        uint32_t b;
        !            94:        const uint32_t syncbit = 1 << 31;
        !            95:        uint n;
        !            96:
        !            97:        if (ix >= IMXUART_INTRSPEC_TAB_SZ)
        !            98:                return -1;
        !            99:
        !           100:        v = (1 << ix);
        !           101:        if ((sc->sc_intrspec_enb & v) == 0)
        !           102:                return 0;
        !           103:        sc->sc_intrspec_enb &= ~v;
        !           104:
        !           105:        n = spec->enb_reg;
        !           106:        b = spec->enb_bit;
        !           107:        v = sc->sc_ucr[n];
        !           108:        v &= ~b;
        !           109:        v |= syncbit;
        !           110:        sc->sc_ucr[n] = v;
        !           111:
        !           112:        n = spec->flg_reg;
        !           113:        b = spec->flg_bit;
        !           114:        v = sc->sc_usr[n];
        !           115:        v &= ~b;
        !           116:        v |= syncbit;
        !           117:        sc->sc_usr[n] = v;
        !           118:
        !           119:        return 1;
        !           120: }
        !           121:
        !           122: /*
        !           123:  * enable the specified IMX UART interrupt in softc
        !           124:  * return -1 on error
        !           125:  * else return previous enabled state
        !           126:  */
        !           127: static __inline int
        !           128: imxuart_intrspec_enb(imxuart_softc_t *sc, imxuart_intrix_t ix)
        !           129: {
        !           130:        const imxuart_intrspec_t *spec = &imxuart_intrspec_tab[ix];
        !           131:        uint32_t v;
        !           132:        uint n;
        !           133:        const uint32_t syncbit = 1 << 31;
        !           134:
        !           135:        if (ix >= IMXUART_INTRSPEC_TAB_SZ)
        !           136:                return -1;
        !           137:
        !           138:        v = (1 << ix);
        !           139:        if ((sc->sc_intrspec_enb & v) != 0)
        !           140:                return 1;
        !           141:        sc->sc_intrspec_enb |= v;
        !           142:
        !           143:
        !           144:        n = spec->enb_reg;
        !           145:        v = spec->enb_bit;
        !           146:        v |= syncbit;
        !           147:        sc->sc_ucr[n] |= v;
        !           148:
        !           149:        n = spec->flg_reg;
        !           150:        v = spec->flg_bit;
        !           151:        v |= syncbit;
        !           152:        sc->sc_usr[n] |= v;
        !           153:
        !           154:        return 0;
        !           155: }
        !           156:
        !           157: /*
        !           158:  * sync softc interrupt spec to UART Control regs
        !           159:  */
        !           160: static __inline void
        !           161: imxuart_intrspec_sync(imxuart_softc_t *sc)
        !           162: {
        !           163:        int i;
        !           164:        uint32_t r;
        !           165:        uint32_t v;
        !           166:        const uint32_t syncbit = 1 << 31;
        !           167:        const uint32_t mask[4] = {
        !           168:                IMXUART_INTRS_UCR1,
        !           169:                IMXUART_INTRS_UCR2,
        !           170:                IMXUART_INTRS_UCR3,
        !           171:                IMXUART_INTRS_UCR4
        !           172:        };
        !           173:
        !           174:        for (i=0; i < 4; i++) {
        !           175:                v = sc->sc_ucr[i];
        !           176:                if (v & syncbit) {
        !           177:                        v &= ~syncbit;
        !           178:                        sc->sc_ucr[i] = v;
        !           179:                        r = bus_space_read_4(sc->sc_bt, sc->sc_bh, IMX_UCRn(i));
        !           180:                        r &= ~mask[i];
        !           181:                        r |= v;
        !           182:                        bus_space_write_4(sc->sc_bt, sc->sc_bh, IMX_UCRn(i), r);
        !           183:                }
        !           184:        }
        !           185: }
        !           186:
        !           187:
        !           188: int
        !           189: imxuart_init(imxuart_softc_t *sc, uint bh)
        !           190: {
        !           191:        if (sc == 0)
        !           192:                sc = &imxuart_softc;
        !           193:        sc->sc_init_cnt++;
        !           194:        cn_tab = &imxuartcntab;
        !           195:        sc->sc_bt = &imx31_bs_tag;
        !           196:        sc->sc_bh = bh;
        !           197:
        !           198:        memset(&sc->sc_errors, 0, sizeof(sc->sc_errors));
        !           199:
        !           200:        return 0;
        !           201: }
        !           202:
        !           203: int
        !           204: imxuart_puts(imxuart_softc_t *sc, const char *s)
        !           205: {
        !           206:        char c;
        !           207:        int err = -2;
        !           208:
        !           209:        for(;;) {
        !           210:                c = *s++;
        !           211:                if (c == '\0')
        !           212:                        break;
        !           213:                err = imxuart_putchar(sc, c);
        !           214:        }
        !           215:        return err;
        !           216: }
        !           217:
        !           218: int
        !           219: imxuart_putchar(imxuart_softc_t *sc, int c)
        !           220: {
        !           221:        uint32_t r;
        !           222:
        !           223:        for (;;) {
        !           224:                r = bus_space_read_4(sc->sc_bt, sc->sc_bh, IMX_UTS);
        !           225:                if ((r & IMX_UTS_TXFUL) == 0)
        !           226:                        break;
        !           227:        }
        !           228:
        !           229:        r = (uint32_t)c & IMX_UTXD_TX_DATA;
        !           230:        bus_space_write_4(sc->sc_bt, sc->sc_bh, IMX_UTXD, r);
        !           231:
        !           232:        return 0;
        !           233: }
        !           234:
        !           235: int
        !           236: imxuart_getchar(imxuart_softc_t *sc)
        !           237: {
        !           238:        uint32_t r;
        !           239:        int c;
        !           240:
        !           241:        for(;;) {
        !           242:                r = bus_space_read_4(sc->sc_bt, sc->sc_bh, IMX_URXD);
        !           243:                if (r & IMX_URXD_ERR) {
        !           244:                        imxuart_urxd_err(sc, r);
        !           245:                        continue;
        !           246:                }
        !           247:                if (r & IMX_URXD_CHARDY) {
        !           248:                        c = (int)(r & IMX_URXD_RX_DATA);
        !           249:                        break;
        !           250:                }
        !           251:        }
        !           252:
        !           253:        return c;
        !           254: }
        !           255:
        !           256: static int
        !           257: imxuart_urxd_brk(void)
        !           258: {
        !           259: #ifdef DDB
        !           260:        if (cn_tab == &imxuartcntab) {
        !           261:                Debugger();
        !           262:                return 0;
        !           263:        }
        !           264: #endif
        !           265:        return 1;
        !           266: }
        !           267:
        !           268: static void
        !           269: imxuart_urxd_err(imxuart_softc_t *sc, uint32_t r)
        !           270: {
        !           271:        if (r & IMX_URXD_BRK)
        !           272:                if (imxuart_urxd_brk() == 0)
        !           273:                        return;
        !           274:
        !           275:        sc->sc_errors.err++;
        !           276:        if (r & IMX_URXD_BRK)
        !           277:                sc->sc_errors.brk++;
        !           278:        if (r & IMX_URXD_PRERR)
        !           279:                sc->sc_errors.prerr++;
        !           280:        if (r & IMX_URXD_FRMERR)
        !           281:                sc->sc_errors.frmerr++;
        !           282:        if (r & IMX_URXD_OVRRUN)
        !           283:                sc->sc_errors.ovrrun++;
        !           284: }
        !           285:
        !           286: static int
        !           287: imxuart_snapshot(imxuart_softc_t *sc, uint32_t *p)
        !           288: {
        !           289:        int i;
        !           290:        const uint r[] = {      IMX_URXD, IMX_UTXD, IMX_UCR1, IMX_UCR2,
        !           291:                        IMX_UCR3, IMX_UCR4, IMX_UFCR, IMX_USR1,
        !           292:                        IMX_USR2, IMX_UESC, IMX_UTIM, IMX_UBIR,
        !           293:                        IMX_UBMR, IMX_UBRC, IMX_ONEMS, IMX_UTS };
        !           294:
        !           295:        for (i=0; i < ((sizeof(r)/sizeof(r[0]))); i++) {
        !           296:                *p++ = sc->sc_bh + r[i];
        !           297:                *p++ = bus_space_read_4(sc->sc_bt, sc->sc_bh, r[i]);
        !           298:        }
        !           299:        return 0;
        !           300: }
        !           301:
        !           302: int
        !           303: imxuart_test(void)
        !           304: {
        !           305:        imxuart_softc_t *sc = &imxuart_softc;
        !           306:        int n;
        !           307:        int err;
        !           308:
        !           309:        err = imxuart_init(sc, 1);
        !           310:        if (err != 0)
        !           311:                return err;
        !           312:
        !           313:        if (0) {
        !           314:                extern u_int cpufunc_id(void);
        !           315:                err = cpufunc_id();
        !           316:                return err;
        !           317:        }
        !           318:
        !           319: #if 0
        !           320:        err = imxuart_snapshot(sc, imxuart_snapshot_data);
        !           321:        if (err != 0)
        !           322:                return err;
        !           323: #endif
        !           324:
        !           325:
        !           326:        err = imxuart_putchar(sc, 'x');
        !           327:        if (err != 0)
        !           328:                return err;
        !           329:
        !           330:        for (n=100; n--; ) {
        !           331:                err = imxuart_puts(sc, imxuart_test_string);
        !           332:                if (err != 0)
        !           333:                        break;
        !           334:        }
        !           335:
        !           336:        err = imxuart_snapshot(sc, imxuart_snapshot_data);
        !           337:        if (err != 0)
        !           338:                return err;
        !           339:
        !           340:        return err;
        !           341: }
        !           342:
        !           343: static int
        !           344: imxuart_match(struct device *parent, struct cfdata *cf, void *aux)
        !           345: {
        !           346:        struct aips_attach_args * const aipsa = aux;
        !           347:
        !           348:        switch (aipsa->aipsa_addr) {
        !           349:        case IMX_UART1_BASE:
        !           350:        case IMX_UART2_BASE:
        !           351:        case IMX_UART3_BASE:
        !           352:        case IMX_UART4_BASE:
        !           353:        case IMX_UART5_BASE:
        !           354:                return 1;
        !           355:        default:
        !           356:                return 0;
        !           357:        }
        !           358: }
        !           359:
        !           360: static void
        !           361: imxuart_attach(struct device *parent, struct device *self, void *aux)
        !           362: {
        !           363:        imxuart_softc_t *sc = (void *)self;
        !           364:        struct aips_attach_args * const aipsa = aux;
        !           365:        struct tty *tp;
        !           366:
        !           367:        sc->sc_bt = aipsa->aipsa_memt;
        !           368:        sc->sc_addr = aipsa->aipsa_addr;
        !           369:        sc->sc_size = aipsa->aipsa_size;
        !           370:        sc->sc_intr = aipsa->aipsa_intr;
        !           371:
        !           372:        sc->sc_tty = tp = ttymalloc();
        !           373:        tp->t_oproc = imxuart_start;
        !           374:        tp->t_param = imxuart_param;
        !           375:        tty_attach(tp);
        !           376:
        !           377:        shutdownhook_establish(imxuart_shutdownhook, sc);
        !           378:
        !           379:        printf("\n");
        !           380: }
        !           381:
        !           382: void
        !           383: imxuartcnprobe(struct consdev *cp)
        !           384: {
        !           385:        int major;
        !           386:
        !           387:        __TRACE;
        !           388:        major = cdevsw_lookup_major(&imxuart_cdevsw);
        !           389:        cp->cn_dev = makedev(major, 0);                 /* XXX unit 0 */
        !           390:        cp->cn_pri = CN_REMOTE;
        !           391: }
        !           392:
        !           393: static void
        !           394: imxuart_start(struct tty *tp)
        !           395: {
        !           396:        __TRACE;
        !           397: }
        !           398:
        !           399: static int
        !           400: imxuart_param(struct tty *tp, struct termios *termios)
        !           401: {
        !           402:        __TRACE;
        !           403:        return 0;
        !           404: }
        !           405:
        !           406: static void
        !           407: imxuart_shutdownhook(void *arg)
        !           408: {
        !           409:        __TRACE;
        !           410: }
        !           411:
        !           412: void
        !           413: imxuartcninit(struct consdev *cp)
        !           414: {
        !           415:        __TRACE;
        !           416: }
        !           417:
        !           418: int
        !           419: imxuartcngetc(dev_t dev)
        !           420: {
        !           421:        struct imxuart_softc *sc;
        !           422:        uint unit;
        !           423:        int c;
        !           424:
        !           425:        unit = IMXUART_UNIT(dev);
        !           426:        if (unit != 0)
        !           427:                return 0;
        !           428:        sc = &imxuart_softc;
        !           429:        c = imxuart_getchar(sc);
        !           430:        return c;
        !           431: }
        !           432:
        !           433: void
        !           434: imxuartcnputc(dev_t dev, int c)
        !           435: {
        !           436:        (void)imxuart_putchar(&imxuart_softc, c);
        !           437: }
        !           438:
        !           439: void
        !           440: imxuartcnpollc(dev_t dev, int mode)
        !           441: {
        !           442:        /* always polled for now */
        !           443: }
        !           444: int
        !           445: imxuart_cnattach(bus_space_tag_t iot, bus_addr_t iobase,
        !           446:        int rate, int frequency, int type, tcflag_t cflag)
        !           447: {
        !           448:        cn_tab = &imxuartcntab;
        !           449:        return 0;
        !           450: }
        !           451:

CVSweb <webmaster@jp.NetBSD.org>