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

Annotation of sys/arch/mac68k/dev/asc.c, Revision 1.1

1.1     ! nbrk        1: /*     $OpenBSD: asc.c,v 1.25 2006/09/16 10:42:23 miod Exp $   */
        !             2: /*     $NetBSD: asc.c,v 1.20 1997/02/24 05:47:33 scottr Exp $  */
        !             3:
        !             4: /*
        !             5:  * Copyright (C) 1997 Scott Reynolds
        !             6:  * All rights reserved.
        !             7:  *
        !             8:  * Redistribution and use in source and binary forms, with or without
        !             9:  * modification, are permitted provided that the following conditions
        !            10:  * are met:
        !            11:  * 1. Redistributions of source code must retain the above copyright
        !            12:  *    notice, this list of conditions and the following disclaimer.
        !            13:  * 2. Redistributions in binary form must reproduce the above copyright
        !            14:  *    notice, this list of conditions and the following disclaimer in the
        !            15:  *    documentation and/or other materials provided with the distribution.
        !            16:  * 3. The name of the author may not be used to endorse or promote products
        !            17:  *    derived from this software without specific prior written permission.
        !            18:  *
        !            19:  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
        !            20:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            21:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            22:  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            23:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            24:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            25:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            26:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            27:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
        !            28:  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            29:  */
        !            30: /*-
        !            31:  * Copyright (C) 1993  Allen K. Briggs, Chris P. Caputo,
        !            32:  *                     Michael L. Finch, Bradley A. Grantham, and
        !            33:  *                     Lawrence A. Kesteloot
        !            34:  * All rights reserved.
        !            35:  *
        !            36:  * Redistribution and use in source and binary forms, with or without
        !            37:  * modification, are permitted provided that the following conditions
        !            38:  * are met:
        !            39:  * 1. Redistributions of source code must retain the above copyright
        !            40:  *    notice, this list of conditions and the following disclaimer.
        !            41:  * 2. Redistributions in binary form must reproduce the above copyright
        !            42:  *    notice, this list of conditions and the following disclaimer in the
        !            43:  *    documentation and/or other materials provided with the distribution.
        !            44:  * 3. All advertising materials mentioning features or use of this software
        !            45:  *    must display the following acknowledgement:
        !            46:  *     This product includes software developed by the Alice Group.
        !            47:  * 4. The names of the Alice Group or any of its members may not be used
        !            48:  *    to endorse or promote products derived from this software without
        !            49:  *    specific prior written permission.
        !            50:  *
        !            51:  * THIS SOFTWARE IS PROVIDED BY THE ALICE GROUP ``AS IS'' AND ANY EXPRESS OR
        !            52:  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
        !            53:  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
        !            54:  * IN NO EVENT SHALL THE ALICE GROUP BE LIABLE FOR ANY DIRECT, INDIRECT,
        !            55:  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
        !            56:  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
        !            57:  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
        !            58:  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
        !            59:  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
        !            60:  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
        !            61:  */
        !            62:
        !            63: /*
        !            64:  * ASC driver code and console bell support
        !            65:  */
        !            66:
        !            67: #include <sys/types.h>
        !            68: #include <sys/cdefs.h>
        !            69: #include <sys/errno.h>
        !            70: #include <sys/time.h>
        !            71: #include <sys/systm.h>
        !            72: #include <sys/param.h>
        !            73: #include <sys/device.h>
        !            74: #include <sys/fcntl.h>
        !            75: #include <sys/poll.h>
        !            76: #include <sys/timeout.h>
        !            77:
        !            78: #include <uvm/uvm_extern.h>
        !            79: #include <uvm/uvm_pmap.h>
        !            80:
        !            81: #include <machine/autoconf.h>
        !            82: #include <machine/cpu.h>
        !            83: #include <machine/bus.h>
        !            84:
        !            85: #include <mac68k/dev/ascvar.h>
        !            86: #include <mac68k/dev/obiovar.h>
        !            87:
        !            88: #define        MAC68K_ASC_BASE         0x50f14000
        !            89: #define        MAC68K_IIFX_ASC_BASE    0x50f10000
        !            90: #define        MAC68K_ASC_LEN          0x01000
        !            91:
        !            92: static u_int8_t                asc_wave_tab[0x800];
        !            93:
        !            94: static int     asc_ring_bell(void *, int, int, int);
        !            95: static void    asc_stop_bell(void *);
        !            96:
        !            97: static int     ascmatch(struct device *, void *, void *);
        !            98: static void    ascattach(struct device *, struct device *, void *);
        !            99:
        !           100: struct cfattach asc_ca = {
        !           101:        sizeof(struct asc_softc), ascmatch, ascattach
        !           102: };
        !           103:
        !           104: struct cfdriver asc_cd = {
        !           105:        NULL, "asc", DV_DULL
        !           106: };
        !           107:
        !           108: static int
        !           109: ascmatch(parent, vcf, aux)
        !           110:        struct device *parent;
        !           111:        void *vcf;
        !           112:        void *aux;
        !           113: {
        !           114:        struct obio_attach_args *oa = (struct obio_attach_args *)aux;
        !           115:        bus_addr_t addr;
        !           116:        bus_space_handle_t bsh;
        !           117:        int rval = 0;
        !           118:
        !           119:        if (oa->oa_addr != (-1))
        !           120:                addr = (bus_addr_t)oa->oa_addr;
        !           121:        else if (current_mac_model->machineid == MACH_MACTV)
        !           122:                return 0;
        !           123:        else if (current_mac_model->machineid == MACH_MACIIFX)
        !           124:                addr = (bus_addr_t)MAC68K_IIFX_ASC_BASE;
        !           125:        else
        !           126:                addr = (bus_addr_t)MAC68K_ASC_BASE;
        !           127:
        !           128:        if (bus_space_map(oa->oa_tag, addr, MAC68K_ASC_LEN, 0, &bsh))
        !           129:                return (0);
        !           130:
        !           131:        if (mac68k_bus_space_probe(oa->oa_tag, bsh, 0, 1))
        !           132:                rval = 1;
        !           133:        else
        !           134:                rval = 0;
        !           135:
        !           136:        bus_space_unmap(oa->oa_tag, bsh, MAC68K_ASC_LEN);
        !           137:
        !           138:        return rval;
        !           139: }
        !           140:
        !           141: static void
        !           142: ascattach(parent, self, aux)
        !           143:        struct device *parent, *self;
        !           144:        void *aux;
        !           145: {
        !           146:        struct asc_softc *sc = (struct asc_softc *)self;
        !           147:        struct obio_attach_args *oa = (struct obio_attach_args *)aux;
        !           148:        bus_addr_t addr;
        !           149:        int i;
        !           150:
        !           151:        sc->sc_tag = oa->oa_tag;
        !           152:        if (oa->oa_addr != (-1))
        !           153:                addr = (bus_addr_t)oa->oa_addr;
        !           154:        else if (current_mac_model->machineid == MACH_MACIIFX)
        !           155:                addr = (bus_addr_t)MAC68K_IIFX_ASC_BASE;
        !           156:        else
        !           157:                addr = (bus_addr_t)MAC68K_ASC_BASE;
        !           158:        if (bus_space_map(sc->sc_tag, addr, MAC68K_ASC_LEN, 0,
        !           159:            &sc->sc_handle)) {
        !           160:                printf(": can't map memory space\n");
        !           161:                return;
        !           162:        }
        !           163:        sc->sc_open = 0;
        !           164:        sc->sc_ringing = 0;
        !           165:        timeout_set(&sc->sc_bell_tmo, asc_stop_bell, sc);
        !           166:
        !           167:        for (i = 0; i < 256; i++) {     /* up part of wave, four voices? */
        !           168:                asc_wave_tab[i] = i / 4;
        !           169:                asc_wave_tab[i + 512] = i / 4;
        !           170:                asc_wave_tab[i + 1024] = i / 4;
        !           171:                asc_wave_tab[i + 1536] = i / 4;
        !           172:        }
        !           173:        for (i = 0; i < 256; i++) {     /* down part of wave, four voices? */
        !           174:                asc_wave_tab[i + 256] = 0x3f - (i / 4);
        !           175:                asc_wave_tab[i + 768] = 0x3f - (i / 4);
        !           176:                asc_wave_tab[i + 1280] = 0x3f - (i / 4);
        !           177:                asc_wave_tab[i + 1792] = 0x3f - (i / 4);
        !           178:        }
        !           179:
        !           180:        printf(": Apple Sound Chip");
        !           181:        if (oa->oa_addr != (-1))
        !           182:                printf(" at %x", oa->oa_addr);
        !           183:        printf("\n");
        !           184:
        !           185:        mac68k_set_bell_callback(asc_ring_bell, sc);
        !           186: }
        !           187:
        !           188: int
        !           189: ascopen(dev, flag, mode, p)
        !           190:        dev_t dev;
        !           191:        int flag;
        !           192:        int mode;
        !           193:        struct proc *p;
        !           194: {
        !           195:        struct asc_softc *sc;
        !           196:        int unit;
        !           197:
        !           198:        unit = ASCUNIT(dev);
        !           199:        if (unit >= asc_cd.cd_ndevs)
        !           200:                return (ENXIO);
        !           201:        sc = asc_cd.cd_devs[unit];
        !           202:        if (sc == NULL)
        !           203:                return (ENXIO);
        !           204:        if (sc->sc_open)
        !           205:                return (EBUSY);
        !           206:        sc->sc_open = 1;
        !           207:
        !           208:        return (0);
        !           209: }
        !           210:
        !           211: int
        !           212: ascclose(dev, flag, mode, p)
        !           213:        dev_t dev;
        !           214:        int flag;
        !           215:        int mode;
        !           216:        struct proc *p;
        !           217: {
        !           218:        struct asc_softc *sc;
        !           219:
        !           220:        sc = asc_cd.cd_devs[ASCUNIT(dev)];
        !           221:        sc->sc_open = 0;
        !           222:
        !           223:        return (0);
        !           224: }
        !           225:
        !           226: int
        !           227: ascread(dev, uio, ioflag)
        !           228:        dev_t dev;
        !           229:        struct uio *uio;
        !           230:        int ioflag;
        !           231: {
        !           232:        return (ENXIO);
        !           233: }
        !           234:
        !           235: int
        !           236: ascwrite(dev, uio, ioflag)
        !           237:        dev_t dev;
        !           238:        struct uio *uio;
        !           239:        int ioflag;
        !           240: {
        !           241:        return (ENXIO);
        !           242: }
        !           243:
        !           244: int
        !           245: ascioctl(dev, cmd, data, flag, p)
        !           246:        dev_t dev;
        !           247:        int cmd;
        !           248:        caddr_t data;
        !           249:        int flag;
        !           250:        struct proc *p;
        !           251: {
        !           252:        struct asc_softc *sc;
        !           253:        int error;
        !           254:        int unit = ASCUNIT(dev);
        !           255:
        !           256:        sc = asc_cd.cd_devs[unit];
        !           257:        error = 0;
        !           258:
        !           259:        switch (cmd) {
        !           260:        default:
        !           261:                error = EINVAL;
        !           262:                break;
        !           263:        }
        !           264:        return (error);
        !           265: }
        !           266:
        !           267: int
        !           268: ascpoll(dev, events, p)
        !           269:        dev_t dev;
        !           270:        int events;
        !           271:        struct proc *p;
        !           272: {
        !           273:        /* always fails => never blocks */
        !           274:        return (events & (POLLOUT | POLLWRNORM));
        !           275: }
        !           276:
        !           277: paddr_t
        !           278: ascmmap(dev, off, prot)
        !           279:        dev_t dev;
        !           280:        off_t off;
        !           281:        int prot;
        !           282: {
        !           283:        int unit = ASCUNIT(dev);
        !           284:        struct asc_softc *sc;
        !           285:        paddr_t pa;
        !           286:
        !           287:        sc = asc_cd.cd_devs[unit];
        !           288:        if (off >= 0 && off < MAC68K_ASC_LEN) {
        !           289:                (void)pmap_extract(pmap_kernel(),
        !           290:                    (vaddr_t)bus_space_vaddr(sc->sc_tag, sc->sc_handle), &pa);
        !           291:                return atop(pa + off);
        !           292:        }
        !           293:
        !           294:        return (-1);
        !           295: }
        !           296:
        !           297: static int
        !           298: asc_ring_bell(arg, freq, length, volume)
        !           299:        void *arg;
        !           300:        int freq, length, volume;
        !           301: {
        !           302:        struct asc_softc *sc = (struct asc_softc *)arg;
        !           303:        unsigned long cfreq;
        !           304:        int i;
        !           305:
        !           306:        if (!sc)
        !           307:                return (ENODEV);
        !           308:
        !           309:        if (sc->sc_ringing == 0) {
        !           310:                bus_space_set_region_1(sc->sc_tag, sc->sc_handle,
        !           311:                    0, 0, 0x800);
        !           312:                bus_space_write_region_1(sc->sc_tag, sc->sc_handle,
        !           313:                    0, asc_wave_tab, 0x800);
        !           314:
        !           315:                /* Fix this.  Need to find exact ASC sampling freq */
        !           316:                cfreq = 65536 * freq / 466;
        !           317:
        !           318:                /* printf("beep: from %d, %02x %02x %02x %02x\n",
        !           319:                 * cur_beep.freq, (cfreq >> 24) & 0xff, (cfreq >> 16) & 0xff,
        !           320:                 * (cfreq >> 8) & 0xff, (cfreq) & 0xff); */
        !           321:                for (i = 0; i < 8; i++) {
        !           322:                        bus_space_write_1(sc->sc_tag, sc->sc_handle,
        !           323:                            0x814 + 8 * i, (cfreq >> 24) & 0xff);
        !           324:                        bus_space_write_1(sc->sc_tag, sc->sc_handle,
        !           325:                            0x815 + 8 * i, (cfreq >> 16) & 0xff);
        !           326:                        bus_space_write_1(sc->sc_tag, sc->sc_handle,
        !           327:                            0x816 + 8 * i, (cfreq >> 8) & 0xff);
        !           328:                        bus_space_write_1(sc->sc_tag, sc->sc_handle,
        !           329:                            0x817 + 8 * i, (cfreq) & 0xff);
        !           330:                }               /* frequency; should put cur_beep.freq in here
        !           331:                                 * somewhere. */
        !           332:
        !           333:                bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x807, 3); /* 44 ? */
        !           334:                bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x806,
        !           335:                    255 * volume / 100);
        !           336:                bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x805, 0);
        !           337:                bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x80f, 0);
        !           338:                bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x802, 2); /* sampled */
        !           339:                bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x801, 2); /* enable sampled */
        !           340:                sc->sc_ringing = 1;
        !           341:                timeout_add(&sc->sc_bell_tmo, length);
        !           342:        }
        !           343:
        !           344:        return (0);
        !           345: }
        !           346:
        !           347: static void
        !           348: asc_stop_bell(arg)
        !           349:        void *arg;
        !           350: {
        !           351:        struct asc_softc *sc = (struct asc_softc *)arg;
        !           352:
        !           353:        if (!sc)
        !           354:                return;
        !           355:
        !           356:        if (sc->sc_ringing > 1000 || sc->sc_ringing < 0)
        !           357:                panic("bell got out of sync?");
        !           358:
        !           359:        if (--sc->sc_ringing == 0)      /* disable ASC */
        !           360:                bus_space_write_1(sc->sc_tag, sc->sc_handle, 0x801, 0);
        !           361: }
        !           362:
        !           363: int asckqfilter(dev_t, struct knote *);
        !           364:
        !           365: int
        !           366: asckqfilter(dev, kn)
        !           367:        dev_t dev;
        !           368:        struct knote *kn;
        !           369: {
        !           370:        return (1);
        !           371: }

CVSweb