[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

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