[BACK]Return to lcd.c CVS log [TXT][DIR] Up to [local] / sys / arch / luna88k / dev

Annotation of sys/arch/luna88k/dev/lcd.c, Revision 1.1.1.1

1.1       nbrk        1: /* $OpenBSD: lcd.c,v 1.3 2007/02/09 14:26:09 aoyama Exp $ */
                      2: /* $NetBSD: lcd.c,v 1.2 2000/01/07 05:13:08 nisimura Exp $ */
                      3:
                      4: /*-
                      5:  * Copyright (c) 2000 The NetBSD Foundation, Inc.
                      6:  * All rights reserved.
                      7:  *
                      8:  * This code is derived from software contributed to The NetBSD Foundation
                      9:  * by Tohru Nishimura.
                     10:  *
                     11:  * Redistribution and use in source and binary forms, with or without
                     12:  * modification, are permitted provided that the following conditions
                     13:  * are met:
                     14:  * 1. Redistributions of source code must retain the above copyright
                     15:  *    notice, this list of conditions and the following disclaimer.
                     16:  * 2. Redistributions in binary form must reproduce the above copyright
                     17:  *    notice, this list of conditions and the following disclaimer in the
                     18:  *    documentation and/or other materials provided with the distribution.
                     19:  * 3. All advertising materials mentioning features or use of this software
                     20:  *    must display the following acknowledgement:
                     21:  *     This product includes software developed by the NetBSD
                     22:  *     Foundation, Inc. and its contributors.
                     23:  * 4. Neither the name of The NetBSD Foundation nor the names of its
                     24:  *    contributors may be used to endorse or promote products derived
                     25:  *    from this software without specific prior written permission.
                     26:  *
                     27:  * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
                     28:  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
                     29:  * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
                     30:  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
                     31:  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
                     32:  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
                     33:  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
                     34:  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
                     35:  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
                     36:  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
                     37:  * POSSIBILITY OF SUCH DAMAGE.
                     38:  */
                     39:
                     40: #include <sys/param.h>
                     41: #include <sys/systm.h>
                     42: #include <sys/device.h>
                     43: #include <sys/ioctl.h>
                     44: #include <sys/fcntl.h>
                     45:
                     46: #include <machine/autoconf.h>
                     47: #include <machine/conf.h>
                     48: #include <machine/lcd.h>
                     49:
                     50: #define PIO1_MODE_OUTPUT       0x84
                     51: #define PIO1_MODE_INPUT                0x94
                     52:
                     53: #define POWER  0x10
                     54:
                     55: #define ENABLE 0x80
                     56: #define DISABLE        0x00
                     57:
                     58: #define WRITE_CMD      (0x00 | 0x00)
                     59: #define WRITE_DATA     (0x00 | 0x40)
                     60: #define READ_BUSY      (0x20 | 0x00)
                     61: #define READ_DATA      (0x20 | 0x40)
                     62:
                     63: #define LCD_INIT       0x38
                     64: #define LCD_ENTRY      0x06
                     65: #define LCD_ON         0x0c
                     66: #define LCD_CLS                0x01
                     67: #define LCD_HOME       0x02
                     68: #define LCD_LOCATE(X, Y)       (((Y) & 1 ? 0xc0 : 0x80) | ((X) & 0x0f))
                     69:
                     70: #define LCD_MAXBUFLEN  80
                     71:
                     72: struct pio {
                     73:        volatile u_int8_t portA;
                     74:         volatile unsigned : 24;
                     75:        volatile u_int8_t portB;
                     76:         volatile unsigned : 24;
                     77:        volatile u_int8_t portC;
                     78:         volatile unsigned : 24;
                     79:        volatile u_int8_t cntrl;
                     80:         volatile unsigned : 24;
                     81: };
                     82:
                     83: /* Autoconf stuff */
                     84: int  lcd_match(struct device *, void *, void *);
                     85: void lcd_attach(struct device *, struct device *, void *);
                     86:
                     87: struct lcd_softc {
                     88:        struct device sc_dev;
                     89:        int sc_opened;
                     90: };
                     91:
                     92: struct cfattach lcd_ca = {
                     93:        sizeof(struct lcd_softc), lcd_match, lcd_attach
                     94: };
                     95:
                     96: struct cfdriver lcd_cd = {
                     97:        NULL, "lcd", DV_DULL, 0
                     98: };
                     99:
                    100: /* Internal prototypes */
                    101: void lcdbusywait(void);
                    102: void lcdput(int);
                    103: void lcdctrl(int);
                    104: void lcdshow(const char *);
                    105: void greeting(void);
                    106:
                    107: /* Internal variables */
                    108:                                     /* "1234567890123456" */
                    109: static const char lcd_boot_message1[] = "OpenBSD/luna88k ";
                    110: static const char lcd_boot_message2[] = "   SX-9100/DT   ";
                    111:
                    112: /*
                    113:  * Autoconf functions
                    114:  */
                    115: int
                    116: lcd_match(parent, cf, aux)
                    117:        struct device *parent;
                    118:        void *cf, *aux;
                    119: {
                    120:        struct mainbus_attach_args *ma = aux;
                    121:
                    122:        if (strcmp(ma->ma_name, lcd_cd.cd_name))
                    123:                return 0;
                    124:        if (badaddr((vaddr_t)ma->ma_addr, 4))
                    125:                return 0;
                    126:        return 1;
                    127: }
                    128:
                    129: void
                    130: lcd_attach(parent, self, aux)
                    131:        struct device *parent, *self;
                    132:        void *aux;
                    133: {
                    134:        printf("\n");
                    135:
                    136:        /* Say hello to the world on LCD. */
                    137:        greeting();
                    138: }
                    139:
                    140: /*
                    141:  * open/close/write/ioctl
                    142:  */
                    143:
                    144: int
                    145: lcdopen(dev, flags, fmt, p)
                    146:        dev_t dev;
                    147:        int flags, fmt;
                    148:        struct proc *p;
                    149: {
                    150:        int unit = minor(dev);
                    151:        struct lcd_softc *sc;
                    152:
                    153:        if (unit >= lcd_cd.cd_ndevs)
                    154:                return ENXIO;
                    155:        if ((sc = lcd_cd.cd_devs[unit]) == NULL)
                    156:                return ENXIO;
                    157:        if (sc->sc_opened)
                    158:                return EBUSY;
                    159:        sc->sc_opened = 1;
                    160:
                    161:        return 0;
                    162: }
                    163:
                    164: int
                    165: lcdclose(dev, flags, fmt, p)
                    166:        dev_t dev;
                    167:        int flags, fmt;
                    168:        struct proc *p;
                    169: {
                    170:        int unit = minor(dev);
                    171:        struct lcd_softc *sc;
                    172:
                    173:        sc = lcd_cd.cd_devs[unit];
                    174:        sc->sc_opened = 0;
                    175:
                    176:        return 0;
                    177: }
                    178:
                    179: int
                    180: lcdwrite(dev, uio, flag)
                    181:        dev_t dev;
                    182:        struct uio *uio;
                    183:        int flag;
                    184: {
                    185:        int error, len;
                    186:        int i, n;
                    187:        char buf[LCD_MAXBUFLEN];
                    188:
                    189:        len = n = uio->uio_resid;
                    190:
                    191:        if ((len < 0) || (len > LCD_MAXBUFLEN))
                    192:                return EIO;
                    193:
                    194:        while (n > 0) {
                    195:                error = uiomove(buf, n, uio);
                    196:                if (error)
                    197:                        return EIO;
                    198:                n = uio->uio_resid;
                    199:        }
                    200:
                    201:        for(i = 0; i < len; i++) {
                    202:                lcdput((int)buf[i]);
                    203:        }
                    204:
                    205:        return 0;
                    206: }
                    207:
                    208: int
                    209: lcdioctl(dev, cmd, addr, flag, p)
                    210:        dev_t dev;
                    211:        u_long cmd;
                    212:        caddr_t addr;
                    213:        int flag;
                    214:        struct proc *p;
                    215: {
                    216:        int val;
                    217:
                    218:        /* check if the device opened with write mode */
                    219:        switch(cmd) {
                    220:        case LCDCLS:
                    221:        case LCDHOME:
                    222:        case LCDMODE:
                    223:        case LCDDISP:
                    224:        case LCDMOVE:
                    225:        case LCDSEEK:
                    226:        case LCDRESTORE:
                    227:                if ((flag & FWRITE) == 0)
                    228:                        return EACCES;
                    229:                break;
                    230:        }
                    231:
                    232:        switch(cmd) {
                    233:        case LCDCLS:
                    234:                lcdctrl(LCD_CLS);
                    235:                break;
                    236:
                    237:        case LCDHOME:
                    238:                lcdctrl(LCD_HOME);
                    239:                break;
                    240:
                    241:        case LCDMODE:
                    242:                val = *(int *)addr;
                    243:                switch (val) {
                    244:                case LCDMODE_C_LEFT:
                    245:                case LCDMODE_C_RIGHT:
                    246:                case LCDMODE_D_LEFT:
                    247:                case LCDMODE_D_RIGHT:
                    248:                        lcdctrl(val);
                    249:                        break;
                    250:                default:
                    251:                        return EINVAL;
                    252:                }
                    253:                break;
                    254:
                    255:        case LCDDISP:
                    256:                val = *(int *)addr;
                    257:                if ((val & 0x7) != val)
                    258:                        return EINVAL;
                    259:                lcdctrl(val | 0x8);
                    260:                break;
                    261:
                    262:        case LCDMOVE:
                    263:                val = *(int *)addr;
                    264:                switch (val) {
                    265:                case LCDMOVE_C_LEFT:
                    266:                case LCDMOVE_C_RIGHT:
                    267:                case LCDMOVE_D_LEFT:
                    268:                case LCDMOVE_D_RIGHT:
                    269:                        lcdctrl(val);
                    270:                        break;
                    271:                default:
                    272:                        return EINVAL;
                    273:                }
                    274:                break;
                    275:
                    276:        case LCDSEEK:
                    277:                val = *(int *)addr & 0x7f;
                    278:                lcdctrl(val | 0x80);
                    279:                break;
                    280:
                    281:        case LCDRESTORE:
                    282:                greeting();
                    283:                break;
                    284:
                    285:        default:
                    286:                return ENOTTY;
                    287:        }
                    288:        return 0;
                    289: }
                    290:
                    291: /*
                    292:  * Internal functions
                    293:  */
                    294: void
                    295: lcdbusywait()
                    296: {
                    297:        struct pio *p1 = (struct pio *)0x4D000000;
                    298:        int msb, s;
                    299:
                    300:        s = splhigh();
                    301:        p1->cntrl = PIO1_MODE_INPUT;
                    302:        p1->portC = POWER | READ_BUSY | ENABLE;
                    303:        splx(s);
                    304:
                    305:        do {
                    306:                msb = p1->portA & ENABLE;
                    307:                delay(5);
                    308:        } while (msb != 0);
                    309:
                    310:        s = splhigh();
                    311:        p1->portC = POWER | READ_BUSY | DISABLE;
                    312:        splx(s);
                    313: }
                    314:
                    315: void
                    316: lcdput(cc)
                    317:        int cc;
                    318: {
                    319:        struct pio *p1 = (struct pio *)0x4D000000;
                    320:        int s;
                    321:
                    322:        lcdbusywait();
                    323:
                    324:        s = splhigh();
                    325:        p1->cntrl = PIO1_MODE_OUTPUT;
                    326:
                    327:        p1->portC = POWER | WRITE_DATA | ENABLE;
                    328:        p1->portA = cc;
                    329:        p1->portC = POWER | WRITE_DATA | DISABLE;
                    330:        splx(s);
                    331: }
                    332:
                    333: void
                    334: lcdctrl(cc)
                    335:        int cc;
                    336: {
                    337:        struct pio *p1 = (struct pio *)0x4D000000;
                    338:        int s;
                    339:
                    340:        lcdbusywait();
                    341:
                    342:        s = splhigh();
                    343:        p1->cntrl = PIO1_MODE_OUTPUT;
                    344:
                    345:        p1->portC = POWER | WRITE_CMD | ENABLE;
                    346:        p1->portA = cc;
                    347:        p1->portC = POWER | WRITE_CMD | DISABLE;
                    348:        splx(s);
                    349: }
                    350:
                    351: void
                    352: lcdshow(s)
                    353:        const char *s;
                    354: {
                    355:        int cc;
                    356:
                    357:        while ((cc = *s++) != '\0')
                    358:                lcdput(cc);
                    359: }
                    360:
                    361: void
                    362: greeting()
                    363: {
                    364:        lcdctrl(LCD_INIT);
                    365:        lcdctrl(LCD_ENTRY);
                    366:        lcdctrl(LCD_ON);
                    367:
                    368:        lcdctrl(LCD_CLS);
                    369:        lcdctrl(LCD_HOME);
                    370:
                    371:        lcdctrl(LCD_LOCATE(0, 0));
                    372:        lcdshow(lcd_boot_message1);
                    373:        lcdctrl(LCD_LOCATE(0, 1));
                    374:        lcdshow(lcd_boot_message2);
                    375: }

CVSweb