Annotation of sys/dev/isa/ym.c, Revision 1.1
1.1 ! nbrk 1: /* $OpenBSD: ym.c,v 1.13 2006/04/07 22:41:33 jsg Exp $ */
! 2:
! 3:
! 4: /*
! 5: * Copyright (c) 1998 Constantine Sapuntzakis. All rights reserved.
! 6: *
! 7: * Redistribution and use in source and binary forms, with or without
! 8: * modification, are permitted provided that the following conditions
! 9: * are met:
! 10: * 1. Redistributions of source code must retain the above copyright
! 11: * notice, this list of conditions and the following disclaimer.
! 12: * 2. Redistributions in binary form must reproduce the above copyright
! 13: * notice, this list of conditions and the following disclaimer in the
! 14: * documentation and/or other materials provided with the distribution.
! 15: * 3. The name of the author may not be used to endorse or promote products
! 16: * derived from this software without specific prior written permission.
! 17: *
! 18: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
! 19: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
! 20: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
! 21: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
! 22: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
! 23: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
! 24: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
! 25: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
! 26: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
! 27: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
! 28: */
! 29:
! 30: #include "midi.h"
! 31:
! 32: #include <sys/param.h>
! 33: #include <sys/systm.h>
! 34: #include <sys/errno.h>
! 35: #include <sys/ioctl.h>
! 36: #include <sys/syslog.h>
! 37: #include <sys/device.h>
! 38: #include <sys/proc.h>
! 39: #include <sys/buf.h>
! 40:
! 41: #include <machine/cpu.h>
! 42: #include <machine/intr.h>
! 43: #include <machine/bus.h>
! 44:
! 45: #include <sys/audioio.h>
! 46: #include <dev/audio_if.h>
! 47: #include <dev/midi_if.h>
! 48:
! 49: #include <dev/isa/isavar.h>
! 50: #include <dev/isa/isadmavar.h>
! 51:
! 52: #include <dev/ic/ad1848reg.h>
! 53: #include <dev/isa/ad1848var.h>
! 54: #include <dev/ic/opl3sa3reg.h>
! 55: #include <dev/ic/mpuvar.h>
! 56: #include <dev/isa/ymvar.h>
! 57:
! 58: int ym_getdev(void *, struct audio_device *);
! 59: int ym_mixer_set_port(void *, mixer_ctrl_t *);
! 60: int ym_mixer_get_port(void *, mixer_ctrl_t *);
! 61: int ym_query_devinfo(void *, mixer_devinfo_t *);
! 62: int ym_intr(void *);
! 63:
! 64: static void ym_mute(struct ym_softc *, int, int);
! 65: static void ym_set_master_gain(struct ym_softc *, struct ad1848_volume *);
! 66: static void ym_set_mic_gain(struct ym_softc *, int);
! 67: static void ym_set_3d(struct ym_softc *, mixer_ctrl_t *,
! 68: struct ad1848_volume *, int);
! 69:
! 70: struct audio_hw_if ym_hw_if = {
! 71: ad1848_open,
! 72: ad1848_close,
! 73: NULL,
! 74: ad1848_query_encoding,
! 75: ad1848_set_params,
! 76: ad1848_round_blocksize,
! 77: ad1848_commit_settings,
! 78: ad1848_dma_init_output,
! 79: ad1848_dma_init_input,
! 80: ad1848_dma_output,
! 81: ad1848_dma_input,
! 82: ad1848_halt_out_dma,
! 83: ad1848_halt_in_dma,
! 84: NULL,
! 85: ym_getdev,
! 86: NULL,
! 87: ym_mixer_set_port,
! 88: ym_mixer_get_port,
! 89: ym_query_devinfo,
! 90: ad1848_malloc,
! 91: ad1848_free,
! 92: ad1848_round,
! 93: ad1848_mappage,
! 94: ad1848_get_props,
! 95: NULL,
! 96: NULL
! 97: };
! 98:
! 99:
! 100: struct cfdriver ym_cd = {
! 101: NULL, "ym", DV_DULL
! 102: };
! 103:
! 104: struct audio_device ym_device = {
! 105: "ym,ad1848",
! 106: "",
! 107: "ym"
! 108: };
! 109:
! 110: static __inline int ym_read(struct ym_softc *, int);
! 111: static __inline void ym_write(struct ym_softc *, int, int);
! 112:
! 113: #if NMIDI > 0
! 114: int ym_mpu401_open(void *, int, void (*iintr)(void *, int),
! 115: void (*ointr)(void *), void *arg);
! 116: void ym_mpu401_close(void *);
! 117: int ym_mpu401_output(void *, int);
! 118: void ym_mpu401_getinfo(void *, struct midi_info *);
! 119:
! 120: struct midi_hw_if ym_mpu401_hw_if = {
! 121: ym_mpu401_open,
! 122: ym_mpu401_close,
! 123: ym_mpu401_output,
! 124: 0, /* flush */
! 125: ym_mpu401_getinfo,
! 126: 0, /* ioctl */
! 127: };
! 128: #endif
! 129:
! 130: int
! 131: ym_intr(v)
! 132: void *v;
! 133: {
! 134: #if NMIDI > 0
! 135: struct ym_softc *sc = v;
! 136:
! 137: if ( /* XXX && */ sc->sc_hasmpu)
! 138: mpu_intr(&sc->sc_mpu_sc);
! 139: #endif
! 140: return ad1848_intr(v);
! 141: }
! 142:
! 143: void
! 144: ym_attach(sc)
! 145: struct ym_softc *sc;
! 146:
! 147: {
! 148: struct ad1848_volume vol_mid = {220, 220};
! 149: #if NMIDI > 0
! 150: struct midi_hw_if *mhw = &ym_mpu401_hw_if;
! 151: #endif
! 152:
! 153: sc->sc_ih = isa_intr_establish(sc->sc_ic, sc->ym_irq, IST_EDGE,
! 154: IPL_AUDIO, ym_intr, &sc->sc_ad1848, sc->sc_dev.dv_xname);
! 155:
! 156: ad1848_attach(&sc->sc_ad1848);
! 157: printf("\n");
! 158: sc->sc_ad1848.parent = sc;
! 159:
! 160: /* Establish chip in well known mode */
! 161: ym_set_master_gain(sc, &vol_mid);
! 162: ym_set_mic_gain(sc, 0);
! 163: sc->master_mute = 0;
! 164: ym_mute(sc, SA3_VOL_L, sc->master_mute);
! 165: ym_mute(sc, SA3_VOL_R, sc->master_mute);
! 166:
! 167: sc->mic_mute = 1;
! 168: ym_mute(sc, SA3_MIC_VOL, sc->mic_mute);
! 169:
! 170: #if NMIDI > 0
! 171: sc->sc_hasmpu = 0;
! 172: if (sc->sc_mpu_sc.iobase) {
! 173: sc->sc_mpu_sc.iot = sc->sc_iot;
! 174: if (mpu_find(&sc->sc_mpu_sc)) {
! 175: sc->sc_hasmpu = 1;
! 176: mhw = &ym_mpu401_hw_if;
! 177: }
! 178: }
! 179: midi_attach_mi(mhw, sc, &sc->sc_dev);
! 180: #endif
! 181:
! 182: audio_attach_mi(&ym_hw_if, &sc->sc_ad1848, &sc->sc_dev);
! 183: }
! 184:
! 185: static __inline int
! 186: ym_read(sc, reg)
! 187: struct ym_softc *sc;
! 188: int reg;
! 189: {
! 190: bus_space_write_1(sc->sc_iot, sc->sc_controlioh, SA3_CTL_INDEX,
! 191: (reg & 0xff));
! 192: return (bus_space_read_1(sc->sc_iot, sc->sc_controlioh, SA3_CTL_DATA));
! 193: }
! 194:
! 195: static __inline void
! 196: ym_write(sc, reg, data)
! 197: struct ym_softc *sc;
! 198: int reg;
! 199: int data;
! 200: {
! 201: bus_space_write_1(sc->sc_iot, sc->sc_controlioh, SA3_CTL_INDEX,
! 202: (reg & 0xff));
! 203: bus_space_write_1(sc->sc_iot, sc->sc_controlioh, SA3_CTL_DATA,
! 204: (data & 0xff));
! 205: }
! 206:
! 207:
! 208:
! 209: int
! 210: ym_getdev(addr, retp)
! 211: void *addr;
! 212: struct audio_device *retp;
! 213: {
! 214: *retp = ym_device;
! 215: return 0;
! 216: }
! 217:
! 218:
! 219: static ad1848_devmap_t mappings[] = {
! 220: { YM_MIDI_LVL, AD1848_KIND_LVL, AD1848_AUX2_CHANNEL },
! 221: { YM_CD_LVL, AD1848_KIND_LVL, AD1848_AUX1_CHANNEL },
! 222: { YM_DAC_LVL, AD1848_KIND_LVL, AD1848_DAC_CHANNEL },
! 223: { YM_LINE_LVL, AD1848_KIND_LVL, AD1848_LINE_CHANNEL },
! 224: { YM_SPEAKER_LVL, AD1848_KIND_LVL, AD1848_MONO_CHANNEL },
! 225: { YM_MONITOR_LVL, AD1848_KIND_LVL, AD1848_MONITOR_CHANNEL },
! 226: { YM_MIDI_MUTE, AD1848_KIND_MUTE, AD1848_AUX2_CHANNEL },
! 227: { YM_CD_MUTE, AD1848_KIND_MUTE, AD1848_AUX1_CHANNEL },
! 228: { YM_DAC_MUTE, AD1848_KIND_MUTE, AD1848_DAC_CHANNEL },
! 229: { YM_LINE_MUTE, AD1848_KIND_MUTE, AD1848_LINE_CHANNEL },
! 230: { YM_SPEAKER_MUTE, AD1848_KIND_MUTE, AD1848_MONO_CHANNEL },
! 231: { YM_MONITOR_MUTE, AD1848_KIND_MUTE, AD1848_MONITOR_CHANNEL },
! 232: { YM_REC_LVL, AD1848_KIND_RECORDGAIN, -1 },
! 233: { YM_RECORD_SOURCE, AD1848_KIND_RECORDSOURCE, -1 }
! 234: };
! 235:
! 236: #define NUMMAP (sizeof(mappings) / sizeof(mappings[0]))
! 237:
! 238:
! 239: static void
! 240: ym_mute(sc, left_reg, mute)
! 241: struct ym_softc *sc;
! 242: int left_reg;
! 243: int mute;
! 244: {
! 245: u_int8_t reg;
! 246:
! 247: reg = ym_read(sc, left_reg);
! 248: if (mute)
! 249: ym_write(sc, left_reg, reg | 0x80);
! 250: else
! 251: ym_write(sc, left_reg, reg & ~0x80);
! 252: }
! 253:
! 254: static void
! 255: ym_set_master_gain(sc, vol)
! 256: struct ym_softc *sc;
! 257: struct ad1848_volume *vol;
! 258: {
! 259: u_int atten;
! 260:
! 261: sc->master_gain = *vol;
! 262:
! 263: atten = ((AUDIO_MAX_GAIN - vol->left) * (SA3_VOL_MV + 1)) /
! 264: (AUDIO_MAX_GAIN + 1);
! 265:
! 266: ym_write(sc, SA3_VOL_L, (ym_read(sc, SA3_VOL_L) & ~SA3_VOL_MV) | atten);
! 267:
! 268: atten = ((AUDIO_MAX_GAIN - vol->right) * (SA3_VOL_MV + 1)) /
! 269: (AUDIO_MAX_GAIN + 1);
! 270:
! 271: ym_write(sc, SA3_VOL_R, (ym_read(sc, SA3_VOL_R) & ~SA3_VOL_MV) | atten);
! 272: }
! 273:
! 274: static void
! 275: ym_set_mic_gain(sc, vol)
! 276: struct ym_softc *sc;
! 277: int vol;
! 278: {
! 279: u_int atten;
! 280:
! 281: sc->mic_gain = vol;
! 282:
! 283: atten = ((AUDIO_MAX_GAIN - vol) * (SA3_MIC_MCV + 1)) /
! 284: (AUDIO_MAX_GAIN + 1);
! 285:
! 286: ym_write(sc, SA3_MIC_VOL,
! 287: (ym_read(sc, SA3_MIC_VOL) & ~SA3_MIC_MCV) | atten);
! 288: }
! 289:
! 290: static void
! 291: ym_set_3d(sc, cp, val, reg)
! 292: struct ym_softc *sc;
! 293: mixer_ctrl_t *cp;
! 294: struct ad1848_volume *val;
! 295: int reg;
! 296: {
! 297: u_int8_t e;
! 298:
! 299: ad1848_to_vol(cp, val);
! 300:
! 301: e = (val->left * (SA3_3D_BITS + 1) + (SA3_3D_BITS + 1) / 2) /
! 302: (AUDIO_MAX_GAIN + 1) << SA3_3D_LSHIFT |
! 303: (val->right * (SA3_3D_BITS + 1) + (SA3_3D_BITS + 1) / 2) /
! 304: (AUDIO_MAX_GAIN + 1) << SA3_3D_RSHIFT;
! 305:
! 306: ym_write(sc, reg, e);
! 307: }
! 308:
! 309: int
! 310: ym_mixer_set_port(addr, cp)
! 311: void *addr;
! 312: mixer_ctrl_t *cp;
! 313: {
! 314: struct ad1848_softc *ac = addr;
! 315: struct ym_softc *sc = ac->parent;
! 316: struct ad1848_volume vol;
! 317: int error = ad1848_mixer_set_port(ac, mappings, NUMMAP, cp);
! 318:
! 319: if (error != ENXIO)
! 320: return (error);
! 321:
! 322: error = 0;
! 323:
! 324: switch (cp->dev) {
! 325: case YM_OUTPUT_LVL:
! 326: ad1848_to_vol(cp, &vol);
! 327: ym_set_master_gain(sc, &vol);
! 328: break;
! 329:
! 330: case YM_OUTPUT_MUTE:
! 331: sc->master_mute = (cp->un.ord != 0);
! 332: ym_mute(sc, SA3_VOL_L, sc->master_mute);
! 333: ym_mute(sc, SA3_VOL_R, sc->master_mute);
! 334: break;
! 335:
! 336: case YM_MIC_LVL:
! 337: if (cp->un.value.num_channels != 1)
! 338: error = EINVAL;
! 339: else
! 340: ym_set_mic_gain(sc,
! 341: cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]);
! 342: break;
! 343:
! 344: case YM_MASTER_EQMODE:
! 345: sc->sc_eqmode = cp->un.ord & SA3_SYS_CTL_YMODE;
! 346: ym_write(sc, SA3_SYS_CTL, (ym_read(sc, SA3_SYS_CTL) &
! 347: ~SA3_SYS_CTL_YMODE) | sc->sc_eqmode);
! 348: break;
! 349:
! 350: case YM_MASTER_TREBLE:
! 351: ym_set_3d(sc, cp, &sc->sc_treble, SA3_3D_TREBLE);
! 352: break;
! 353:
! 354: case YM_MASTER_BASS:
! 355: ym_set_3d(sc, cp, &sc->sc_bass, SA3_3D_BASS);
! 356: break;
! 357:
! 358: case YM_MASTER_WIDE:
! 359: ym_set_3d(sc, cp, &sc->sc_wide, SA3_3D_WIDE);
! 360: break;
! 361:
! 362: case YM_MIC_MUTE:
! 363: sc->mic_mute = (cp->un.ord != 0);
! 364: ym_mute(sc, SA3_MIC_VOL, sc->mic_mute);
! 365: break;
! 366:
! 367: default:
! 368: return ENXIO;
! 369: /* NOTREACHED */
! 370: }
! 371:
! 372: return (error);
! 373: }
! 374:
! 375: int
! 376: ym_mixer_get_port(addr, cp)
! 377: void *addr;
! 378: mixer_ctrl_t *cp;
! 379: {
! 380: struct ad1848_softc *ac = addr;
! 381: struct ym_softc *sc = ac->parent;
! 382:
! 383: int error = ad1848_mixer_get_port(ac, mappings, NUMMAP, cp);
! 384:
! 385: if (error != ENXIO)
! 386: return (error);
! 387:
! 388: error = 0;
! 389:
! 390: switch (cp->dev) {
! 391: case YM_OUTPUT_LVL:
! 392: ad1848_from_vol(cp, &sc->master_gain);
! 393: break;
! 394:
! 395: case YM_OUTPUT_MUTE:
! 396: cp->un.ord = sc->master_mute;
! 397: break;
! 398:
! 399: case YM_MIC_LVL:
! 400: if (cp->un.value.num_channels != 1)
! 401: error = EINVAL;
! 402: cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = sc->mic_gain;
! 403: break;
! 404:
! 405: case YM_MASTER_EQMODE:
! 406: cp->un.ord = sc->sc_eqmode;
! 407: break;
! 408:
! 409: case YM_MASTER_TREBLE:
! 410: ad1848_from_vol(cp, &sc->sc_treble);
! 411: break;
! 412:
! 413: case YM_MASTER_BASS:
! 414: ad1848_from_vol(cp, &sc->sc_bass);
! 415: break;
! 416:
! 417: case YM_MASTER_WIDE:
! 418: ad1848_from_vol(cp, &sc->sc_wide);
! 419: break;
! 420:
! 421: case YM_MIC_MUTE:
! 422: cp->un.ord = sc->mic_mute;
! 423: break;
! 424:
! 425: default:
! 426: error = ENXIO;
! 427: break;
! 428: }
! 429:
! 430: return (error);
! 431: }
! 432:
! 433: static char *mixer_classes[] = {
! 434: AudioCinputs, AudioCrecord, AudioCoutputs, AudioCmonitor,
! 435: AudioCequalization
! 436: };
! 437:
! 438: int
! 439: ym_query_devinfo(addr, dip)
! 440: void *addr;
! 441: mixer_devinfo_t *dip;
! 442: {
! 443: static char *mixer_port_names[] = { AudioNmidi, AudioNcd, AudioNdac,
! 444: AudioNline, AudioNspeaker, AudioNmicrophone, AudioNmonitor
! 445: };
! 446:
! 447: dip->next = dip->prev = AUDIO_MIXER_LAST;
! 448:
! 449: switch (dip->index) {
! 450: case YM_INPUT_CLASS: /* input class descriptor */
! 451: case YM_OUTPUT_CLASS:
! 452: case YM_MONITOR_CLASS:
! 453: case YM_RECORD_CLASS:
! 454: case YM_EQ_CLASS:
! 455: dip->type = AUDIO_MIXER_CLASS;
! 456: dip->mixer_class = dip->index;
! 457: strlcpy(dip->label.name,
! 458: mixer_classes[dip->index - YM_INPUT_CLASS],
! 459: sizeof dip->label.name);
! 460: break;
! 461:
! 462: case YM_MIDI_LVL:
! 463: case YM_CD_LVL:
! 464: case YM_DAC_LVL:
! 465: case YM_LINE_LVL:
! 466: case YM_SPEAKER_LVL:
! 467: case YM_MIC_LVL:
! 468: case YM_MONITOR_LVL:
! 469: dip->type = AUDIO_MIXER_VALUE;
! 470: if (dip->index == YM_MONITOR_LVL)
! 471: dip->mixer_class = YM_MONITOR_CLASS;
! 472: else
! 473: dip->mixer_class = YM_INPUT_CLASS;
! 474:
! 475: dip->next = dip->index + 7;
! 476:
! 477: strlcpy(dip->label.name,
! 478: mixer_port_names[dip->index - YM_MIDI_LVL],
! 479: sizeof dip->label.name);
! 480:
! 481: if (dip->index == YM_SPEAKER_LVL ||
! 482: dip->index == YM_MIC_LVL)
! 483: dip->un.v.num_channels = 1;
! 484: else
! 485: dip->un.v.num_channels = 2;
! 486:
! 487: strlcpy(dip->un.v.units.name, AudioNvolume,
! 488: sizeof dip->un.v.units.name);
! 489: break;
! 490:
! 491: case YM_MIDI_MUTE:
! 492: case YM_CD_MUTE:
! 493: case YM_DAC_MUTE:
! 494: case YM_LINE_MUTE:
! 495: case YM_SPEAKER_MUTE:
! 496: case YM_MIC_MUTE:
! 497: case YM_MONITOR_MUTE:
! 498: if (dip->index == YM_MONITOR_MUTE)
! 499: dip->mixer_class = YM_MONITOR_CLASS;
! 500: else
! 501: dip->mixer_class = YM_INPUT_CLASS;
! 502: dip->type = AUDIO_MIXER_ENUM;
! 503: dip->prev = dip->index - 7;
! 504: mute:
! 505: strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name);
! 506: dip->un.e.num_mem = 2;
! 507: strlcpy(dip->un.e.member[0].label.name, AudioNoff,
! 508: sizeof dip->un.e.member[0].label.name);
! 509: dip->un.e.member[0].ord = 0;
! 510: strlcpy(dip->un.e.member[1].label.name, AudioNon,
! 511: sizeof dip->un.e.member[1].label.name);
! 512: dip->un.e.member[1].ord = 1;
! 513: break;
! 514:
! 515:
! 516: case YM_OUTPUT_LVL:
! 517: dip->type = AUDIO_MIXER_VALUE;
! 518: dip->mixer_class = YM_OUTPUT_CLASS;
! 519: dip->next = YM_OUTPUT_MUTE;
! 520: strlcpy(dip->label.name, AudioNmaster, sizeof dip->label.name);
! 521: dip->un.v.num_channels = 2;
! 522: strlcpy(dip->un.v.units.name, AudioNvolume,
! 523: sizeof dip->un.v.units.name);
! 524: break;
! 525:
! 526: case YM_OUTPUT_MUTE:
! 527: dip->mixer_class = YM_OUTPUT_CLASS;
! 528: dip->type = AUDIO_MIXER_ENUM;
! 529: dip->prev = YM_OUTPUT_LVL;
! 530: goto mute;
! 531:
! 532: case YM_REC_LVL: /* record level */
! 533: dip->type = AUDIO_MIXER_VALUE;
! 534: dip->mixer_class = YM_RECORD_CLASS;
! 535: dip->next = YM_RECORD_SOURCE;
! 536: strlcpy(dip->label.name, AudioNrecord, sizeof dip->label.name);
! 537: dip->un.v.num_channels = 2;
! 538: strlcpy(dip->un.v.units.name, AudioNvolume,
! 539: sizeof dip->un.v.units.name);
! 540: break;
! 541:
! 542:
! 543: case YM_RECORD_SOURCE:
! 544: dip->mixer_class = YM_RECORD_CLASS;
! 545: dip->type = AUDIO_MIXER_ENUM;
! 546: dip->prev = YM_REC_LVL;
! 547: strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name);
! 548: dip->un.e.num_mem = 4;
! 549: strlcpy(dip->un.e.member[0].label.name, AudioNmicrophone,
! 550: sizeof dip->un.e.member[0].label.name);
! 551: dip->un.e.member[0].ord = MIC_IN_PORT;
! 552: strlcpy(dip->un.e.member[1].label.name, AudioNline,
! 553: sizeof dip->un.e.member[1].label.name);
! 554: dip->un.e.member[1].ord = LINE_IN_PORT;
! 555: strlcpy(dip->un.e.member[2].label.name, AudioNdac,
! 556: sizeof dip->un.e.member[2].label.name);
! 557: dip->un.e.member[2].ord = DAC_IN_PORT;
! 558: strlcpy(dip->un.e.member[3].label.name, AudioNcd,
! 559: sizeof dip->un.e.member[3].label.name);
! 560: dip->un.e.member[3].ord = AUX1_IN_PORT;
! 561: break;
! 562:
! 563: case YM_MASTER_EQMODE:
! 564: dip->type = AUDIO_MIXER_ENUM;
! 565: dip->mixer_class = YM_EQ_CLASS;
! 566: strlcpy(dip->label.name, AudioNmode, sizeof dip->label.name);
! 567: strlcpy(dip->un.v.units.name, AudioNmode,
! 568: sizeof dip->un.v.units.name);
! 569: dip->un.e.num_mem = 4;
! 570: strlcpy(dip->un.e.member[0].label.name, AudioNdesktop,
! 571: sizeof dip->un.e.member[0].label.name);
! 572: dip->un.e.member[0].ord = SA3_SYS_CTL_YMODE0;
! 573: strlcpy(dip->un.e.member[1].label.name, AudioNlaptop,
! 574: sizeof dip->un.e.member[1].label.name);
! 575: dip->un.e.member[1].ord = SA3_SYS_CTL_YMODE1;
! 576: strlcpy(dip->un.e.member[2].label.name, AudioNsubnote,
! 577: sizeof dip->un.e.member[2].label.name);
! 578: dip->un.e.member[2].ord = SA3_SYS_CTL_YMODE2;
! 579: strlcpy(dip->un.e.member[3].label.name, AudioNhifi,
! 580: sizeof dip->un.e.member[3].label.name);
! 581: dip->un.e.member[3].ord = SA3_SYS_CTL_YMODE3;
! 582: break;
! 583:
! 584: case YM_MASTER_TREBLE:
! 585: dip->type = AUDIO_MIXER_VALUE;
! 586: dip->mixer_class = YM_EQ_CLASS;
! 587: strlcpy(dip->label.name, AudioNtreble, sizeof dip->label.name);
! 588: dip->un.v.num_channels = 2;
! 589: strlcpy(dip->un.v.units.name, AudioNtreble,
! 590: sizeof dip->un.v.units.name);
! 591: break;
! 592:
! 593: case YM_MASTER_BASS:
! 594: dip->type = AUDIO_MIXER_VALUE;
! 595: dip->mixer_class = YM_EQ_CLASS;
! 596: strlcpy(dip->label.name, AudioNbass, sizeof dip->label.name);
! 597: dip->un.v.num_channels = 2;
! 598: strlcpy(dip->un.v.units.name, AudioNbass,
! 599: sizeof dip->un.v.units.name);
! 600: break;
! 601:
! 602: case YM_MASTER_WIDE:
! 603: dip->type = AUDIO_MIXER_VALUE;
! 604: dip->mixer_class = YM_EQ_CLASS;
! 605: strlcpy(dip->label.name, AudioNsurround,
! 606: sizeof dip->label.name);
! 607: dip->un.v.num_channels = 2;
! 608: strlcpy(dip->un.v.units.name, AudioNsurround,
! 609: sizeof dip->un.v.units.name);
! 610: break;
! 611:
! 612: default:
! 613: return ENXIO;
! 614: /* NOTREACHED */
! 615: }
! 616:
! 617: return 0;
! 618: }
! 619: #if NMIDI > 0
! 620:
! 621: #define YMMPU(a) (&((struct ym_softc *)addr)->sc_mpu_sc)
! 622:
! 623: int
! 624: ym_mpu401_open(addr, flags, iintr, ointr, arg)
! 625: void *addr;
! 626: int flags;
! 627: void (*iintr)(void *, int);
! 628: void (*ointr)(void *);
! 629: void *arg;
! 630: {
! 631: return mpu_open(YMMPU(addr), flags, iintr, ointr, arg);
! 632: }
! 633:
! 634: int
! 635: ym_mpu401_output(addr, d)
! 636: void *addr;
! 637: int d;
! 638: {
! 639: return mpu_output(YMMPU(addr), d);
! 640: }
! 641:
! 642: void
! 643: ym_mpu401_close(addr)
! 644: void *addr;
! 645: {
! 646: mpu_close(YMMPU(addr));
! 647: }
! 648:
! 649: void
! 650: ym_mpu401_getinfo(addr, mi)
! 651: void *addr;
! 652: struct midi_info *mi;
! 653: {
! 654: mi->name = "YM MPU-401 UART";
! 655: mi->props = 0;
! 656: }
! 657: #endif
CVSweb