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