diff options
author | Edd Barrett <edd@cvs.openbsd.org> | 2009-12-01 23:17:12 +0000 |
---|---|---|
committer | Edd Barrett <edd@cvs.openbsd.org> | 2009-12-01 23:17:12 +0000 |
commit | 1f9ad602a4969729752c8cbc0a2809b5bc3f73a3 (patch) | |
tree | 7a580e7acfa6707f3eb6388f41eb8afb5cddd256 /sys/arch/sparc64/dev | |
parent | 684c26fc7b905cdccfde3d5b19dbb7a9dd28c0ef (diff) |
Fix the mixer interface for the CE4231 sound card found in Sun machines. Still a
lot of room for improvement in the driver, but atleast it works now.
OK kettenis@, ratchov@
Diffstat (limited to 'sys/arch/sparc64/dev')
-rw-r--r-- | sys/arch/sparc64/dev/ce4231.c | 704 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/ce4231var.h | 14 |
2 files changed, 434 insertions, 284 deletions
diff --git a/sys/arch/sparc64/dev/ce4231.c b/sys/arch/sparc64/dev/ce4231.c index 3849e4c3f1d..6a112220ee1 100644 --- a/sys/arch/sparc64/dev/ce4231.c +++ b/sys/arch/sparc64/dev/ce4231.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ce4231.c,v 1.22 2008/04/21 00:32:42 jakemsr Exp $ */ +/* $OpenBSD: ce4231.c,v 1.23 2009/12/01 23:17:11 edd Exp $ */ /* * Copyright (c) 1999 Jason L. Wright (jason@thought.net) @@ -57,44 +57,57 @@ #include <sparc64/dev/ebusvar.h> #include <sparc64/dev/ce4231var.h> +/* AD1418 provides basic registers, CS4231 extends with more */ #include <dev/ic/ad1848reg.h> #include <dev/ic/cs4231reg.h> +/* Mixer classes and mixer knobs */ #define CSAUDIO_DAC_LVL 0 #define CSAUDIO_LINE_IN_LVL 1 #define CSAUDIO_MIC_LVL 2 #define CSAUDIO_CD_LVL 3 #define CSAUDIO_MONITOR_LVL 4 -#define CSAUDIO_OUTPUT_LVL 5 -#define CSAUDIO_LINE_IN_MUTE 6 -#define CSAUDIO_DAC_MUTE 7 -#define CSAUDIO_CD_MUTE 8 -#define CSAUDIO_MIC_MUTE 9 -#define CSAUDIO_MONITOR_MUTE 10 -#define CSAUDIO_OUTPUT_MUTE 11 -#define CSAUDIO_REC_LVL 12 -#define CSAUDIO_RECORD_SOURCE 13 -#define CSAUDIO_OUTPUT 14 -#define CSAUDIO_INPUT_CLASS 15 -#define CSAUDIO_OUTPUT_CLASS 16 -#define CSAUDIO_RECORD_CLASS 17 -#define CSAUDIO_MONITOR_CLASS 18 +#define CSAUDIO_LINE_IN_MUTE 5 +#define CSAUDIO_DAC_MUTE 6 +#define CSAUDIO_CD_MUTE 7 +#define CSAUDIO_MIC_MUTE 8 +#define CSAUDIO_MONITOR_MUTE 9 +#define CSAUDIO_REC_LVL 10 +#define CSAUDIO_RECORD_SOURCE 11 +#define CSAUDIO_INPUT_CLASS 12 +#define CSAUDIO_OUTPUT_CLASS 13 +#define CSAUDIO_RECORD_CLASS 14 +/* The dac can output to these destinations, which *do* have mute + * controls, but share levels with the main DAC + */ +#define CSAUDIO_DAC_MONO_MUTE 15 +#define CSAUDIO_DAC_LINE_MUTE 16 +#define CSAUDIO_DAC_HDPH_MUTE 17 +/* Physical volume/attenuation registers, array indexes for + * sc->sc_volume/sc->sc_mute + * + * Based upon my Sun blade 1000: + * AUX2 is usually CD in + * MONO is usually a mic + */ #define CSPORT_AUX2 0 #define CSPORT_AUX1 1 #define CSPORT_DAC 2 #define CSPORT_LINEIN 3 #define CSPORT_MONO 4 #define CSPORT_MONITOR 5 -#define CSPORT_SPEAKER 6 -#define CSPORT_LINEOUT 7 -#define CSPORT_HEADPHONE 8 +#define CSPORT_ADC 6 -#define MIC_IN_PORT 0 -#define LINE_IN_PORT 1 -#define AUX1_IN_PORT 2 +/* Recording sources */ +#define LINE_IN_PORT 0 +#define AUX1_IN_PORT 1 +#define MIC_IN_PORT 2 #define DAC_IN_PORT 3 +/* Bits on the ADC reg that determine recording source */ +#define CS_REC_SRC_BITS 0xc0 + #ifdef AUDIO_DEBUG #define DPRINTF(x) printf x #else @@ -103,9 +116,11 @@ #define CS_TIMEOUT 90000 -#define CS_PC_LINEMUTE XCTL0_ENABLE +#define CS_PC_LINEMUTE XCTL1_ENABLE #define CS_PC_HDPHMUTE XCTL1_ENABLE #define CS_AFS_PI 0x10 +#define MONO_INPUT_MUTE 0x80 +#define MIX_MUTE 0x00 /* Read/write CS4231 direct registers */ #define CS_WRITE(sc,r,v) \ @@ -132,6 +147,7 @@ int ce4231_pintr(void *); int ce4231_set_speed(struct ce4231_softc *, u_long *); void ce4231_setup_output(struct ce4231_softc *sc); +void ce4231_setup_input(struct ce4231_softc *sc); void ce4231_write(struct ce4231_softc *, u_int8_t, u_int8_t); u_int8_t ce4231_read(struct ce4231_softc *, u_int8_t); @@ -290,12 +306,13 @@ ce4231_attach(parent, self, aux) audio_attach_mi(&ce4231_sa_hw_if, sc, &sc->sc_dev); - /* Default to speaker, unmuted, reasonable volume */ - sc->sc_out_port = CSPORT_SPEAKER; - sc->sc_mute[CSPORT_SPEAKER] = 1; - sc->sc_mute[CSPORT_MONITOR] = 1; - sc->sc_volume[CSPORT_SPEAKER].left = 192; - sc->sc_volume[CSPORT_SPEAKER].right = 192; + /* Default to all dacouts unmuted, reasonable volume */ + sc->sc_monoout_enable = 1; + sc->sc_lineout_enable = 1; + sc->sc_hdphout_enable = 1; + sc->sc_mute[CSPORT_DAC] = 1; /* dac itself not muted */ + sc->sc_volume[CSPORT_DAC].left = 192; + sc->sc_volume[CSPORT_DAC].right = 192; /* XXX get real burst... */ sc->sc_burst = EBDCSR_BURST_8; @@ -404,8 +421,11 @@ ce4231_open(addr, flags) struct ce4231_softc *sc = addr; int tries; + DPRINTF(("ce4231_open\n")); + if (sc->sc_open) return (EBUSY); + sc->sc_open = 1; sc->sc_locked = 0; sc->sc_rintr = 0; @@ -431,6 +451,7 @@ ce4231_open(addr, flags) ce4231_read(sc, SP_MISC_INFO) | MODE2); ce4231_setup_output(sc); + ce4231_setup_input(sc); ce4231_write(sc, SP_PIN_CONTROL, ce4231_read(sc, SP_PIN_CONTROL) | INTERRUPT_ENABLE); @@ -438,50 +459,161 @@ ce4231_open(addr, flags) return (0); } +/* Set volume/attenuation values and mute settings for outputs */ void ce4231_setup_output(sc) struct ce4231_softc *sc; { - u_int8_t pc, mi, rm, lm; + u_int8_t pc, mi, rm = 0, lm = 0; - pc = ce4231_read(sc, SP_PIN_CONTROL) | CS_PC_HDPHMUTE | CS_PC_LINEMUTE; - mi = ce4231_read(sc, CS_MONO_IO_CONTROL) | MONO_OUTPUT_MUTE; + /* DAC-output attenuation */ + DPRINTF(("ce4231_setup_output: DAC out = %d, %d\n", + sc->sc_volume[CSPORT_DAC].left, + sc->sc_volume[CSPORT_DAC].right)); + lm = (255 - sc->sc_volume[CSPORT_DAC].left) >> 2; + rm = (255 - sc->sc_volume[CSPORT_DAC].right) >> 2; - lm = ce4231_read(sc, SP_LEFT_OUTPUT_CONTROL); - lm &= ~OUTPUT_ATTEN_BITS; - lm |= ((~(sc->sc_volume[CSPORT_SPEAKER].left >> 2)) & - OUTPUT_ATTEN_BITS) | OUTPUT_MUTE; + /* DAC out mute setting */ + if (!sc->sc_mute[CSPORT_DAC]) { + DPRINTF(("ce4231_setup_output: DAC out muted\n")); + lm = lm | OUTPUT_MUTE; + rm = rm | OUTPUT_MUTE; + } - rm = ce4231_read(sc, SP_RIGHT_OUTPUT_CONTROL); - rm &= ~OUTPUT_ATTEN_BITS; - rm |= ((~(sc->sc_volume[CSPORT_SPEAKER].right >> 2)) & - OUTPUT_ATTEN_BITS) | OUTPUT_MUTE; + /* Commit DAC-out settings */ + ce4231_write(sc, SP_LEFT_OUTPUT_CONTROL, lm); + ce4231_write(sc, SP_RIGHT_OUTPUT_CONTROL, rm); - if (sc->sc_mute[CSPORT_MONITOR]) { - lm &= ~OUTPUT_MUTE; - rm &= ~OUTPUT_MUTE; + /* Mono DAC-out mute settings */ + mi = ce4231_read(sc, CS_MONO_IO_CONTROL) & ~MONO_OUTPUT_MUTE; + if (!sc->sc_monoout_enable) { + DPRINTF(("ce4231_setup_output: DAC mono output is enabled")); + mi = mi | MONO_OUTPUT_MUTE; } - switch (sc->sc_out_port) { - case CSPORT_HEADPHONE: - if (sc->sc_mute[CSPORT_SPEAKER]) - pc &= ~CS_PC_HDPHMUTE; - break; - case CSPORT_SPEAKER: - if (sc->sc_mute[CSPORT_SPEAKER]) - mi &= ~MONO_OUTPUT_MUTE; - break; - case CSPORT_LINEOUT: - if (sc->sc_mute[CSPORT_SPEAKER]) - pc &= ~CS_PC_LINEMUTE; - break; + /* Merge in mono input settings, as in same 8 bits */ + mi = mi | (ce4231_read(sc, CS_MONO_IO_CONTROL) & MONO_INPUT_MUTE); + + /* Commit mono dacout settings */ + ce4231_write(sc, CS_MONO_IO_CONTROL, mi); + + /* Line and headphone dacout mutes */ + pc = (ce4231_read(sc, SP_PIN_CONTROL) & + ~CS_PC_HDPHMUTE) & ~CS_PC_LINEMUTE; + if (!sc->sc_lineout_enable) { + DPRINTF(("ce4231_setup_output: DAC line output is enabled")); + pc = pc | CS_PC_LINEMUTE; + } + if (!sc->sc_hdphout_enable) { + DPRINTF(("ce4231_setup_output: DAC hdph output is enabled")); + pc = pc | CS_PC_HDPHMUTE; } - ce4231_write(sc, SP_LEFT_OUTPUT_CONTROL, lm); - ce4231_write(sc, SP_RIGHT_OUTPUT_CONTROL, rm); + /* Commit line/headphone DAC-out settings */ ce4231_write(sc, SP_PIN_CONTROL, pc); - ce4231_write(sc, CS_MONO_IO_CONTROL, mi); +} + +/* Set volume/attenuation values and mute settings for outputs */ +void +ce4231_setup_input(sc) + struct ce4231_softc *sc; +{ + + u_int8_t line_l, line_r, mono, aux2_l, aux2_r, monitor, + adc_l, adc_r; + + /* Line-in gain */ + DPRINTF(("ce4231_setup_input: line in gain = %d,%d\n", + sc->sc_volume[CSPORT_LINEIN].left, + sc->sc_volume[CSPORT_LINEIN].right)); + line_l = sc->sc_volume[CSPORT_LINEIN].left >> 3; + line_r = sc->sc_volume[CSPORT_LINEIN].right >> 3; + DPRINTF(("ce4231_setup_input: line-in gain (on card) = %d,%d\n", + line_l, line_r)); + + /* Line-in mute */ + if (!sc->sc_mute[CSPORT_LINEIN]) { + DPRINTF(("ce4231_setup_input: line-in mute is enabled\n")); + line_l = line_l | CS_PC_LINEMUTE; + line_r = line_r| CS_PC_LINEMUTE; + } + + /* Commit line-in settings to card */ + ce4231_write(sc, CS_LEFT_LINE_CONTROL, line_l); + ce4231_write(sc, CS_RIGHT_LINE_CONTROL, line_r); + + /* Mono-in attenuation */ + DPRINTF(("ce4231_setup_input: mono-in gain = %d\n", + sc->sc_volume[CSPORT_MONO].left)); + mono = (255 - sc->sc_volume[CSPORT_MONO].left) >> 4; + DPRINTF(("ce4231_setup_input: mono-in attenuation (on card) = %d\n", + mono)); + + /* Mono-in mute */ + if (!sc->sc_mute[CSPORT_MONO]) { + DPRINTF(("ce4231_setup_input: mono-in mute is enabled\n")); + mono = mono | MONO_INPUT_MUTE; + } + + /* Merge in mono dacout setting, as in the same 8 bits */ + mono = mono | (ce4231_read(sc, CS_MONO_IO_CONTROL) & MONO_OUTPUT_MUTE); + + /* Commit mono-in settings */ + ce4231_write(sc, CS_MONO_IO_CONTROL, mono); + + /* CD/aux2 gain */ + DPRINTF(("ce4231_setup_input: cd/aux2 gain = %d,%d\n", + sc->sc_volume[CSPORT_AUX2].left, + sc->sc_volume[CSPORT_AUX2].right)); + aux2_l = sc->sc_volume[CSPORT_AUX2].left >> 3; + aux2_r = sc->sc_volume[CSPORT_AUX2].right >> 3; + DPRINTF(("ce4231_setup_input: cd/aux2 gain (on card) = %d,%d\n", + aux2_l, aux2_r)); + + /* CD/aux2-input mute */ + if (!sc->sc_mute[CSPORT_AUX2]) { + DPRINTF(("ce4231_setup_input: cd/aux2-in mute is enabled\n")); + aux2_l = aux2_l | AUX_INPUT_MUTE; + aux2_r = aux2_r | AUX_INPUT_MUTE; + } + + /* Commit cd/aux2 settings */ + ce4231_write(sc, SP_LEFT_AUX2_CONTROL, aux2_l); + ce4231_write(sc, SP_RIGHT_AUX2_CONTROL, aux2_r); + + /* Monitor attenuation */ + DPRINTF(("ce4231_setup_input: monitor gain = %d\n", + sc->sc_volume[CSPORT_MONITOR].left)); + monitor = (0xff - sc->sc_volume[CSPORT_MONITOR].left) & MIX_ATTEN_MASK; + DPRINTF(("ce4231_setup_input: monitor attenuation (on card) = %d\n", + monitor >> 2)); + + /* Monitor mute */ + if (!sc->sc_mute[CSPORT_MONITOR]) { + monitor |= DIGITAL_MIX1_ENABLE; + } + + /* Commit monitor settings */ + ce4231_write(sc, SP_DIGITAL_MIX, monitor); + + /* ADC-in gain */ + DPRINTF(("ce4231_setup_input: adc gain = %d,%d\n", + sc->sc_volume[CSPORT_ADC].left, + sc->sc_volume[CSPORT_ADC].right)); + adc_l = sc->sc_volume[CSPORT_ADC].left >> 4; + adc_r = sc->sc_volume[CSPORT_ADC].right >> 4; + DPRINTF(("ce4231_setup_input: adc gain (on card) = %d,%d\n", + adc_l, adc_r)); + + /* Record source is one of *_INPUT_PORT */ + adc_l = adc_l | (sc->sc_rec_src << 6); + adc_r = adc_r | (sc->sc_rec_src << 6); + + ce4231_write(sc, SP_LEFT_INPUT_CONTROL, adc_l); + ce4231_write(sc, SP_RIGHT_INPUT_CONTROL, adc_r); + + return; } void @@ -576,75 +708,71 @@ ce4231_set_params(addr, setmode, usemode, p, r) void (*pswcode)(void *, u_char *, int cnt) = NULL; void (*rswcode)(void *, u_char *, int cnt) = NULL; + if (p->precision > 16) + p->precision = 16; switch (enc) { case AUDIO_ENCODING_ULAW: if (p->precision != 8) - return (EINVAL); + p->precision = 8; bits = FMT_ULAW >> 5; break; case AUDIO_ENCODING_ALAW: if (p->precision != 8) - return (EINVAL); + p->precision = 8; bits = FMT_ALAW >> 5; break; case AUDIO_ENCODING_SLINEAR_LE: if (p->precision == 8) { bits = FMT_PCM8 >> 5; pswcode = rswcode = change_sign8; - } else if (p->precision == 16) + } else bits = FMT_TWOS_COMP >> 5; - else - return (EINVAL); break; case AUDIO_ENCODING_ULINEAR: if (p->precision != 8) - return (EINVAL); + p->precision = 8; bits = FMT_PCM8 >> 5; break; case AUDIO_ENCODING_SLINEAR_BE: if (p->precision == 8) { bits = FMT_PCM8 >> 5; pswcode = rswcode = change_sign8; - } else if (p->precision == 16) + } else bits = FMT_TWOS_COMP_BE >> 5; - else - return (EINVAL); break; case AUDIO_ENCODING_SLINEAR: if (p->precision != 8) - return (EINVAL); + p->precision = 8; bits = FMT_PCM8 >> 5; pswcode = rswcode = change_sign8; break; case AUDIO_ENCODING_ULINEAR_LE: if (p->precision == 8) bits = FMT_PCM8 >> 5; - else if (p->precision == 16) { + else { bits = FMT_TWOS_COMP >> 5; pswcode = rswcode = change_sign16_le; - } else - return (EINVAL); + } break; case AUDIO_ENCODING_ULINEAR_BE: if (p->precision == 8) bits = FMT_PCM8 >> 5; - else if (p->precision == 16) { + else { bits = FMT_TWOS_COMP_BE >> 5; pswcode = rswcode = change_sign16_be; - } else - return (EINVAL); + } break; case AUDIO_ENCODING_ADPCM: if (p->precision != 8) - return (EINVAL); + p->precision = 8; bits = FMT_ADPCM >> 5; break; default: return (EINVAL); } - if (p->channels != 1 && p->channels != 2) - return (EINVAL); + if (p->channels > 2) + p->channels = 2; err = ce4231_set_speed(sc, &p->sample_rate); if (err) @@ -784,160 +912,176 @@ ce4231_set_port(addr, cp) DPRINTF(("ce4231_set_port: port=%d type=%d\n", cp->dev, cp->type)); + /* XXX a lot of duplicated code here, sometime in the future + * make a function like: + * set_soft_volume(struct ce4231_softc *sc, mixer_ctrl_t *cp); + */ + switch (cp->dev) { case CSAUDIO_DAC_LVL: if (cp->type != AUDIO_MIXER_VALUE) break; - if (cp->un.value.num_channels == 1) - ce4231_write(sc, SP_LEFT_AUX1_CONTROL, - cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] & - LINE_INPUT_ATTEN_BITS); - else if (cp->un.value.num_channels == 2) { - ce4231_write(sc, SP_LEFT_AUX1_CONTROL, - cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] & - LINE_INPUT_ATTEN_BITS); - ce4231_write(sc, SP_RIGHT_AUX1_CONTROL, - cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] & - LINE_INPUT_ATTEN_BITS); + if (cp->un.value.num_channels == 1) { + sc->sc_volume[CSPORT_DAC].left = + cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; + sc->sc_volume[CSPORT_DAC].right = + cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; + } else if (cp->un.value.num_channels == 2) { + sc->sc_volume[CSPORT_DAC].left = + cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; + sc->sc_volume[CSPORT_DAC].right = + cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; } else break; + ce4231_setup_output(sc); error = 0; break; case CSAUDIO_LINE_IN_LVL: if (cp->type != AUDIO_MIXER_VALUE) break; - if (cp->un.value.num_channels == 1) - ce4231_write(sc, CS_LEFT_LINE_CONTROL, - cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] & - AUX_INPUT_ATTEN_BITS); - else if (cp->un.value.num_channels == 2) { - ce4231_write(sc, CS_LEFT_LINE_CONTROL, - cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] & - AUX_INPUT_ATTEN_BITS); - ce4231_write(sc, CS_RIGHT_LINE_CONTROL, - cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] & - AUX_INPUT_ATTEN_BITS); - } else - break; - error = 0; - break; - case CSAUDIO_MIC_LVL: - if (cp->type != AUDIO_MIXER_VALUE) - break; if (cp->un.value.num_channels == 1) { -#if 0 - ce4231_write(sc, CS_MONO_IO_CONTROL, - cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] & - MONO_INPUT_ATTEN_BITS); -#endif + sc->sc_volume[CSPORT_LINEIN].left = + cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; + sc->sc_volume[CSPORT_LINEIN].right = + cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; + } else if (cp->un.value.num_channels == 2) { + sc->sc_volume[CSPORT_LINEIN].left = + cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; + sc->sc_volume[CSPORT_LINEIN].right = + cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; } else break; + ce4231_setup_input(sc); error = 0; break; - case CSAUDIO_CD_LVL: + case CSAUDIO_MIC_LVL: if (cp->type != AUDIO_MIXER_VALUE) break; if (cp->un.value.num_channels == 1) { - ce4231_write(sc, SP_LEFT_AUX2_CONTROL, - cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] & - LINE_INPUT_ATTEN_BITS); + sc->sc_volume[CSPORT_MONO].left = + cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; + sc->sc_volume[CSPORT_MONO].right = + cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; } else if (cp->un.value.num_channels == 2) { - ce4231_write(sc, SP_LEFT_AUX2_CONTROL, - cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] & - LINE_INPUT_ATTEN_BITS); - ce4231_write(sc, SP_RIGHT_AUX2_CONTROL, - cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] & - LINE_INPUT_ATTEN_BITS); + sc->sc_volume[CSPORT_MONO].left = + cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; + sc->sc_volume[CSPORT_MONO].right = + cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; } else break; + ce4231_setup_input(sc); error = 0; break; - case CSAUDIO_MONITOR_LVL: - if (cp->type != AUDIO_MIXER_VALUE) - break; - if (cp->un.value.num_channels == 1) - ce4231_write(sc, SP_DIGITAL_MIX, - cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] << 2); - else - break; - error = 0; - break; - case CSAUDIO_OUTPUT_LVL: + case CSAUDIO_CD_LVL: if (cp->type != AUDIO_MIXER_VALUE) break; if (cp->un.value.num_channels == 1) { - sc->sc_volume[CSPORT_SPEAKER].left = + sc->sc_volume[CSPORT_AUX2].left = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; - sc->sc_volume[CSPORT_SPEAKER].right = + sc->sc_volume[CSPORT_AUX2].right = cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; - } - else if (cp->un.value.num_channels == 2) { - sc->sc_volume[CSPORT_SPEAKER].left = + } else if (cp->un.value.num_channels == 2) { + sc->sc_volume[CSPORT_AUX2].left = cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; - sc->sc_volume[CSPORT_SPEAKER].right = + sc->sc_volume[CSPORT_AUX2].right = cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; - } - else + } else break; - - ce4231_setup_output(sc); + ce4231_setup_input(sc); error = 0; break; - case CSAUDIO_OUTPUT: - if (cp->type != AUDIO_MIXER_ENUM) - break; - if (cp->un.ord != CSPORT_LINEOUT && - cp->un.ord != CSPORT_SPEAKER && - cp->un.ord != CSPORT_HEADPHONE) - return (EINVAL); - sc->sc_out_port = cp->un.ord; - ce4231_setup_output(sc); + case CSAUDIO_MONITOR_LVL: + if (cp->type != AUDIO_MIXER_VALUE || + cp->un.value.num_channels != 1) + break; + sc->sc_volume[CSPORT_MONITOR].left = + cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; + ce4231_setup_input(sc); error = 0; + break; case CSAUDIO_LINE_IN_MUTE: if (cp->type != AUDIO_MIXER_ENUM) break; sc->sc_mute[CSPORT_LINEIN] = cp->un.ord ? 1 : 0; + ce4231_setup_input(sc); error = 0; break; case CSAUDIO_DAC_MUTE: if (cp->type != AUDIO_MIXER_ENUM) break; - sc->sc_mute[CSPORT_AUX1] = cp->un.ord ? 1 : 0; + sc->sc_mute[CSPORT_DAC] = cp->un.ord ? 1 : 0; + ce4231_setup_output(sc); error = 0; break; case CSAUDIO_CD_MUTE: if (cp->type != AUDIO_MIXER_ENUM) break; sc->sc_mute[CSPORT_AUX2] = cp->un.ord ? 1 : 0; + ce4231_setup_input(sc); error = 0; break; case CSAUDIO_MIC_MUTE: if (cp->type != AUDIO_MIXER_ENUM) break; sc->sc_mute[CSPORT_MONO] = cp->un.ord ? 1 : 0; + ce4231_setup_input(sc); error = 0; break; case CSAUDIO_MONITOR_MUTE: if (cp->type != AUDIO_MIXER_ENUM) break; sc->sc_mute[CSPORT_MONITOR] = cp->un.ord ? 1 : 0; + ce4231_setup_input(sc); error = 0; break; - case CSAUDIO_OUTPUT_MUTE: + case CSAUDIO_DAC_MONO_MUTE: if (cp->type != AUDIO_MIXER_ENUM) break; - sc->sc_mute[CSPORT_SPEAKER] = cp->un.ord ? 1 : 0; + sc->sc_monoout_enable = cp->un.ord ? 1 : 0; + ce4231_setup_output(sc); + error = 0; + break; + case CSAUDIO_DAC_LINE_MUTE: + if (cp->type != AUDIO_MIXER_ENUM) + break; + sc->sc_lineout_enable = cp->un.ord ? 1 : 0; + ce4231_setup_output(sc); + error = 0; + break; + case CSAUDIO_DAC_HDPH_MUTE: + if (cp->type != AUDIO_MIXER_ENUM) + break; + sc->sc_hdphout_enable = cp->un.ord ? 1 : 0; ce4231_setup_output(sc); error = 0; break; case CSAUDIO_REC_LVL: if (cp->type != AUDIO_MIXER_VALUE) break; + if (cp->un.value.num_channels == 1) { + sc->sc_volume[CSPORT_ADC].left = + cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; + sc->sc_volume[CSPORT_ADC].right = + cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]; + } else if (cp->un.value.num_channels == 2) { + sc->sc_volume[CSPORT_ADC].left = + cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT]; + sc->sc_volume[CSPORT_ADC].right = + cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT]; + } else + break; + ce4231_setup_input(sc); + error = 0; + break; + case CSAUDIO_RECORD_SOURCE: if (cp->type != AUDIO_MIXER_ENUM) break; + sc->sc_rec_src = cp->un.ord; + ce4231_setup_input(sc); + error = 0; break; } @@ -952,23 +1096,21 @@ ce4231_get_port(addr, cp) struct ce4231_softc *sc = (struct ce4231_softc *)addr; int error = EINVAL; - DPRINTF(("ce4231_get_port: port=%d type=%d\n", cp->dev, cp->type)); - switch (cp->dev) { case CSAUDIO_DAC_LVL: if (cp->type != AUDIO_MIXER_VALUE) break; if (cp->un.value.num_channels == 1) - cp->un.value.level[AUDIO_MIXER_LEVEL_MONO]= - ce4231_read(sc, SP_LEFT_AUX1_CONTROL) & - LINE_INPUT_ATTEN_BITS; + cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = + 255 - ((ce4231_read(sc, SP_LEFT_OUTPUT_CONTROL) & + OUTPUT_ATTEN_BITS) << 2); else if (cp->un.value.num_channels == 2) { cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = - ce4231_read(sc, SP_LEFT_AUX1_CONTROL) & - LINE_INPUT_ATTEN_BITS; + 255 - ((ce4231_read(sc, SP_LEFT_OUTPUT_CONTROL) & + OUTPUT_ATTEN_BITS) << 2); cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = - ce4231_read(sc, SP_RIGHT_AUX1_CONTROL) & - LINE_INPUT_ATTEN_BITS; + 255 - ((ce4231_read(sc, SP_RIGHT_OUTPUT_CONTROL) & + OUTPUT_ATTEN_BITS) << 2); } else break; error = 0; @@ -978,12 +1120,15 @@ ce4231_get_port(addr, cp) break; if (cp->un.value.num_channels == 1) cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = - ce4231_read(sc, CS_LEFT_LINE_CONTROL) & AUX_INPUT_ATTEN_BITS; + (ce4231_read(sc, CS_LEFT_LINE_CONTROL) & + LINE_INPUT_ATTEN_BITS) << 3; else if (cp->un.value.num_channels == 2) { cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = - ce4231_read(sc, CS_LEFT_LINE_CONTROL) & AUX_INPUT_ATTEN_BITS; + (ce4231_read(sc, CS_LEFT_LINE_CONTROL) & + LINE_INPUT_ATTEN_BITS) << 3; cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = - ce4231_read(sc, CS_RIGHT_LINE_CONTROL) & AUX_INPUT_ATTEN_BITS; + (ce4231_read(sc, CS_RIGHT_LINE_CONTROL) & + LINE_INPUT_ATTEN_BITS) << 3; } else break; error = 0; @@ -992,11 +1137,9 @@ ce4231_get_port(addr, cp) if (cp->type != AUDIO_MIXER_VALUE) break; if (cp->un.value.num_channels == 1) { -#if 0 cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = - ce4231_read(sc, CS_MONO_IO_CONTROL) & - MONO_INPUT_ATTEN_BITS; -#endif + (255 - (ce4231_read(sc, CS_MONO_IO_CONTROL) & + MONO_INPUT_ATTEN_BITS)) << 4; } else break; error = 0; @@ -1006,17 +1149,16 @@ ce4231_get_port(addr, cp) break; if (cp->un.value.num_channels == 1) cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = - ce4231_read(sc, SP_LEFT_AUX2_CONTROL) & - LINE_INPUT_ATTEN_BITS; + (ce4231_read(sc, SP_LEFT_AUX2_CONTROL) & + LINE_INPUT_ATTEN_BITS) << 3; else if (cp->un.value.num_channels == 2) { cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = - ce4231_read(sc, SP_LEFT_AUX2_CONTROL) & - LINE_INPUT_ATTEN_BITS; + (ce4231_read(sc, SP_LEFT_AUX2_CONTROL) & + LINE_INPUT_ATTEN_BITS) << 3; cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = - ce4231_read(sc, SP_RIGHT_AUX2_CONTROL) & - LINE_INPUT_ATTEN_BITS; - } - else + (ce4231_read(sc, SP_RIGHT_AUX2_CONTROL) & + LINE_INPUT_ATTEN_BITS) << 3; + } else break; error = 0; break; @@ -1026,59 +1168,70 @@ ce4231_get_port(addr, cp) if (cp->un.value.num_channels != 1) break; cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = - ce4231_read(sc, SP_DIGITAL_MIX) >> 2; - error = 0; - break; - case CSAUDIO_OUTPUT_LVL: - if (cp->type != AUDIO_MIXER_VALUE) - break; - if (cp->un.value.num_channels == 1) - cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = - sc->sc_volume[CSPORT_SPEAKER].left; - else if (cp->un.value.num_channels == 2) { - cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = - sc->sc_volume[CSPORT_SPEAKER].left; - cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = - sc->sc_volume[CSPORT_SPEAKER].right; - } - else - break; + (0xff & MIX_ATTEN_MASK) - + (ce4231_read(sc, SP_DIGITAL_MIX) & MIX_ATTEN_MASK); error = 0; break; case CSAUDIO_LINE_IN_MUTE: if (cp->type != AUDIO_MIXER_ENUM) break; - cp->un.ord = sc->sc_mute[CSPORT_LINEIN] ? 1 : 0; + cp->un.ord = ce4231_read(sc, CS_LEFT_LINE_CONTROL) & + CS_PC_LINEMUTE ? 0 : 1; error = 0; break; case CSAUDIO_DAC_MUTE: if (cp->type != AUDIO_MIXER_ENUM) break; - cp->un.ord = sc->sc_mute[CSPORT_AUX1] ? 1 : 0; + cp->un.ord = ce4231_read(sc, SP_LEFT_OUTPUT_CONTROL) & + OUTPUT_MUTE ? 0 : 1; error = 0; break; case CSAUDIO_CD_MUTE: if (cp->type != AUDIO_MIXER_ENUM) break; - cp->un.ord = sc->sc_mute[CSPORT_AUX2] ? 1 : 0; + //cp->un.ord = sc->sc_mute[CSPORT_AUX2] ? 1 : 0; + cp->un.ord = ce4231_read(sc, SP_LEFT_AUX2_CONTROL) & + AUX_INPUT_MUTE ? 0 : 1; error = 0; break; case CSAUDIO_MIC_MUTE: if (cp->type != AUDIO_MIXER_ENUM) break; - cp->un.ord = sc->sc_mute[CSPORT_MONO] ? 1 : 0; + //cp->un.ord = sc->sc_mute[CSPORT_MONO] ? 1 : 0; + cp->un.ord = ce4231_read(sc, CS_MONO_IO_CONTROL) & + MONO_INPUT_MUTE ? 0 : 1; error = 0; break; case CSAUDIO_MONITOR_MUTE: if (cp->type != AUDIO_MIXER_ENUM) break; - cp->un.ord = sc->sc_mute[CSPORT_MONITOR] ? 1 : 0; + //cp->un.ord = sc->sc_mute[CSPORT_MONITOR] ? 1 : 0; + cp->un.ord = ce4231_read(sc, SP_DIGITAL_MIX) & + DIGITAL_MIX1_ENABLE ? 0 : 1; + error = 0; + break; + case CSAUDIO_DAC_MONO_MUTE: + if (cp->type != AUDIO_MIXER_ENUM) + break; + //cp->un.ord = sc->sc_monoout_enable ? 1 : 0; + cp->un.ord = ce4231_read(sc, CS_MONO_IO_CONTROL) & + MONO_OUTPUT_MUTE ? 0 : 1; + error = 0; + break; + case CSAUDIO_DAC_LINE_MUTE: + if (cp->type != AUDIO_MIXER_ENUM) + break; + //cp->un.ord = sc->sc_lineout_enable ? 1 : 0; + cp->un.ord = ce4231_read(sc, SP_PIN_CONTROL) & CS_PC_LINEMUTE + ? 0 : 1; error = 0; break; - case CSAUDIO_OUTPUT_MUTE: + case CSAUDIO_DAC_HDPH_MUTE: if (cp->type != AUDIO_MIXER_ENUM) break; - cp->un.ord = sc->sc_mute[CSPORT_SPEAKER] ? 1 : 0; + //cp->un.ord = sc->sc_hdphout_enable ? 1 : 0; + cp->un.ord = ce4231_read(sc, SP_PIN_CONTROL) & CS_PC_HDPHMUTE + ? 0 : 1; error = 0; break; case CSAUDIO_REC_LVL: @@ -1086,12 +1239,12 @@ ce4231_get_port(addr, cp) break; if (cp->un.value.num_channels == 1) { cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] = - AUDIO_MIN_GAIN; + ce4231_read(sc, SP_LEFT_INPUT_CONTROL) << 4; } else if (cp->un.value.num_channels == 2) { cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = - AUDIO_MIN_GAIN; + ce4231_read(sc, SP_LEFT_INPUT_CONTROL) << 4; cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = - AUDIO_MIN_GAIN; + ce4231_read(sc, SP_RIGHT_INPUT_CONTROL) << 4; } else break; error = 0; @@ -1099,13 +1252,13 @@ ce4231_get_port(addr, cp) case CSAUDIO_RECORD_SOURCE: if (cp->type != AUDIO_MIXER_ENUM) break; - cp->un.ord = MIC_IN_PORT; - error = 0; - break; - case CSAUDIO_OUTPUT: - if (cp->type != AUDIO_MIXER_ENUM) + + /* AUX in disabled for now until we know what it does */ + if (cp->un.ord == AUX1_IN_PORT) break; - cp->un.ord = sc->sc_out_port; + + cp->un.ord = ce4231_read(sc, SP_LEFT_INPUT_CONTROL & + CS_REC_SRC_BITS) >> 6; error = 0; break; } @@ -1120,19 +1273,20 @@ ce4231_query_devinfo(addr, dip) int err = 0; switch (dip->index) { - case CSAUDIO_MIC_LVL: /* mono/microphone mixer */ + case CSAUDIO_MIC_LVL: /* Mono/microphone mixer */ dip->type = AUDIO_MIXER_VALUE; dip->mixer_class = CSAUDIO_INPUT_CLASS; dip->prev = AUDIO_MIXER_LAST; dip->next = CSAUDIO_MIC_MUTE; - strlcpy(dip->label.name, AudioNmicrophone, sizeof dip->label.name); + strlcpy(dip->label.name, AudioNmicrophone, + sizeof dip->label.name); dip->un.v.num_channels = 1; strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); break; - case CSAUDIO_DAC_LVL: /* dacout */ + case CSAUDIO_DAC_LVL: /* DAC out */ dip->type = AUDIO_MIXER_VALUE; - dip->mixer_class = CSAUDIO_INPUT_CLASS; + dip->mixer_class = CSAUDIO_OUTPUT_CLASS; dip->prev = AUDIO_MIXER_LAST; dip->next = CSAUDIO_DAC_MUTE; strlcpy(dip->label.name, AudioNdac, sizeof dip->label.name); @@ -1140,7 +1294,7 @@ ce4231_query_devinfo(addr, dip) strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); break; - case CSAUDIO_LINE_IN_LVL: /* line */ + case CSAUDIO_LINE_IN_LVL: /* Line */ dip->type = AUDIO_MIXER_VALUE; dip->mixer_class = CSAUDIO_INPUT_CLASS; dip->prev = AUDIO_MIXER_LAST; @@ -1150,7 +1304,7 @@ ce4231_query_devinfo(addr, dip) strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); break; - case CSAUDIO_CD_LVL: /* cd */ + case CSAUDIO_CD_LVL: /* CD */ dip->type = AUDIO_MIXER_VALUE; dip->mixer_class = CSAUDIO_INPUT_CLASS; dip->prev = AUDIO_MIXER_LAST; @@ -1160,26 +1314,6 @@ ce4231_query_devinfo(addr, dip) strlcpy(dip->un.v.units.name, AudioNvolume, sizeof dip->un.v.units.name); break; - case CSAUDIO_MONITOR_LVL: /* monitor level */ - dip->type = AUDIO_MIXER_VALUE; - dip->mixer_class = CSAUDIO_MONITOR_CLASS; - dip->prev = AUDIO_MIXER_LAST; - dip->next = CSAUDIO_MONITOR_MUTE; - strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name); - dip->un.v.num_channels = 1; - strlcpy(dip->un.v.units.name, AudioNvolume, - sizeof dip->un.v.units.name); - break; - case CSAUDIO_OUTPUT_LVL: - dip->type = AUDIO_MIXER_VALUE; - dip->mixer_class = CSAUDIO_OUTPUT_CLASS; - dip->prev = AUDIO_MIXER_LAST; - dip->next = CSAUDIO_OUTPUT_MUTE; - strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name); - dip->un.v.num_channels = 2; - strlcpy(dip->un.v.units.name, AudioNvolume, - sizeof dip->un.v.units.name); - break; case CSAUDIO_LINE_IN_MUTE: dip->type = AUDIO_MIXER_ENUM; dip->mixer_class = CSAUDIO_INPUT_CLASS; @@ -1188,9 +1322,9 @@ ce4231_query_devinfo(addr, dip) goto mute; case CSAUDIO_DAC_MUTE: dip->type = AUDIO_MIXER_ENUM; - dip->mixer_class = CSAUDIO_INPUT_CLASS; + dip->mixer_class = CSAUDIO_OUTPUT_CLASS; dip->prev = CSAUDIO_DAC_LVL; - dip->next = AUDIO_MIXER_LAST; + dip->next = CSAUDIO_DAC_MONO_MUTE; goto mute; case CSAUDIO_CD_MUTE: dip->type = AUDIO_MIXER_ENUM; @@ -1204,21 +1338,49 @@ ce4231_query_devinfo(addr, dip) dip->prev = CSAUDIO_MIC_LVL; dip->next = AUDIO_MIXER_LAST; goto mute; + case CSAUDIO_MONITOR_LVL: /* Monitor level */ + dip->type = AUDIO_MIXER_VALUE; + dip->mixer_class = CSAUDIO_OUTPUT_CLASS; + dip->prev = AUDIO_MIXER_LAST; + dip->next = CSAUDIO_MONITOR_MUTE; + strlcpy(dip->label.name, AudioNmonitor, sizeof dip->label.name); + dip->un.v.num_channels = 1; + strlcpy(dip->un.v.units.name, AudioNvolume, + sizeof dip->un.v.units.name); + break; case CSAUDIO_MONITOR_MUTE: dip->type = AUDIO_MIXER_ENUM; dip->mixer_class = CSAUDIO_OUTPUT_CLASS; dip->prev = CSAUDIO_MONITOR_LVL; dip->next = AUDIO_MIXER_LAST; goto mute; - case CSAUDIO_OUTPUT_MUTE: + case CSAUDIO_DAC_MONO_MUTE: /* The DAC has a mono out, usually spkr */ dip->type = AUDIO_MIXER_ENUM; dip->mixer_class = CSAUDIO_OUTPUT_CLASS; - dip->prev = CSAUDIO_OUTPUT_LVL; - dip->next = AUDIO_MIXER_LAST; - goto mute; - + dip->prev = CSAUDIO_DAC_MUTE; + dip->next = CSAUDIO_DAC_LINE_MUTE; + /* Custom name, as we already have a mute in this class */ + strlcpy(dip->label.name, "monomute", sizeof "monomute"); + goto mute1; + case CSAUDIO_DAC_LINE_MUTE: + dip->type = AUDIO_MIXER_ENUM; + dip->mixer_class = CSAUDIO_OUTPUT_CLASS; + dip->prev = CSAUDIO_DAC_MONO_MUTE; + dip->next = CSAUDIO_DAC_HDPH_MUTE; + /* Custom name */ + strlcpy(dip->label.name, "linemute", sizeof "linemute"); + goto mute1; + case CSAUDIO_DAC_HDPH_MUTE: + dip->type = AUDIO_MIXER_ENUM; + dip->mixer_class = CSAUDIO_OUTPUT_CLASS; + dip->prev = CSAUDIO_DAC_LINE_MUTE; + dip->next = CSAUDIO_MONITOR_LVL; + /* Custom name */ + strlcpy(dip->label.name, "hdphmute", sizeof "hdphmute"); + goto mute1; mute: strlcpy(dip->label.name, AudioNmute, sizeof dip->label.name); + mute1: dip->un.e.num_mem = 2; strlcpy(dip->un.e.member[0].label.name, AudioNon, sizeof dip->un.e.member[0].label.name); @@ -1227,7 +1389,7 @@ ce4231_query_devinfo(addr, dip) sizeof dip->un.e.member[1].label.name); dip->un.e.member[1].ord = 1; break; - case CSAUDIO_REC_LVL: /* record level */ + case CSAUDIO_REC_LVL: dip->type = AUDIO_MIXER_VALUE; dip->mixer_class = CSAUDIO_RECORD_CLASS; dip->prev = AUDIO_MIXER_LAST; @@ -1243,58 +1405,40 @@ ce4231_query_devinfo(addr, dip) dip->prev = CSAUDIO_REC_LVL; dip->next = AUDIO_MIXER_LAST; strlcpy(dip->label.name, AudioNsource, sizeof dip->label.name); - dip->un.e.num_mem = 3; - strlcpy(dip->un.e.member[0].label.name, AudioNcd, + dip->un.e.num_mem = 4; + + strlcpy(dip->un.e.member[0].label.name, AudioNline, sizeof dip->un.e.member[0].label.name); - dip->un.e.member[0].ord = DAC_IN_PORT; - strlcpy(dip->un.e.member[1].label.name, AudioNmicrophone, + dip->un.e.member[0].ord = LINE_IN_PORT; + + strlcpy(dip->un.e.member[1].label.name, "aux", sizeof dip->un.e.member[1].label.name); - dip->un.e.member[1].ord = MIC_IN_PORT; - strlcpy(dip->un.e.member[2].label.name, AudioNdac, + dip->un.e.member[1].ord = AUX1_IN_PORT; + + strlcpy(dip->un.e.member[2].label.name, AudioNmicrophone, sizeof dip->un.e.member[2].label.name); - dip->un.e.member[2].ord = AUX1_IN_PORT; - strlcpy(dip->un.e.member[3].label.name, AudioNline, + dip->un.e.member[2].ord = MIC_IN_PORT; + + strlcpy(dip->un.e.member[3].label.name, AudioNdac, sizeof dip->un.e.member[3].label.name); - dip->un.e.member[3].ord = LINE_IN_PORT; - break; - case CSAUDIO_OUTPUT: - dip->type = AUDIO_MIXER_ENUM; - dip->mixer_class = CSAUDIO_MONITOR_CLASS; - dip->prev = dip->next = AUDIO_MIXER_LAST; - strlcpy(dip->label.name, AudioNoutput, sizeof dip->label.name); - dip->un.e.num_mem = 3; - strlcpy(dip->un.e.member[0].label.name, AudioNspeaker, - sizeof dip->un.e.member[0].label.name); - dip->un.e.member[0].ord = CSPORT_SPEAKER; - strlcpy(dip->un.e.member[1].label.name, AudioNline, - sizeof dip->un.e.member[1].label.name); - dip->un.e.member[1].ord = CSPORT_LINEOUT; - strlcpy(dip->un.e.member[2].label.name, AudioNheadphone, - sizeof dip->un.e.member[2].label.name); - dip->un.e.member[2].ord = CSPORT_HEADPHONE; + dip->un.e.member[3].ord = DAC_IN_PORT; + break; - case CSAUDIO_INPUT_CLASS: /* input class descriptor */ + case CSAUDIO_INPUT_CLASS: /* Input class descriptor */ dip->type = AUDIO_MIXER_CLASS; dip->mixer_class = CSAUDIO_INPUT_CLASS; dip->prev = AUDIO_MIXER_LAST; dip->next = AUDIO_MIXER_LAST; strlcpy(dip->label.name, AudioCinputs, sizeof dip->label.name); break; - case CSAUDIO_OUTPUT_CLASS: /* output class descriptor */ + case CSAUDIO_OUTPUT_CLASS: /* Output class descriptor */ dip->type = AUDIO_MIXER_CLASS; dip->mixer_class = CSAUDIO_OUTPUT_CLASS; dip->prev = AUDIO_MIXER_LAST; dip->next = AUDIO_MIXER_LAST; strlcpy(dip->label.name, AudioCoutputs, sizeof dip->label.name); break; - case CSAUDIO_MONITOR_CLASS: /* monitor class descriptor */ - dip->type = AUDIO_MIXER_CLASS; - dip->mixer_class = CSAUDIO_MONITOR_CLASS; - dip->prev = AUDIO_MIXER_LAST; - dip->next = AUDIO_MIXER_LAST; - strlcpy(dip->label.name, AudioCmonitor, sizeof dip->label.name); - break; - case CSAUDIO_RECORD_CLASS: /* record class descriptor */ + case CSAUDIO_RECORD_CLASS: /* Record class descriptor */ dip->type = AUDIO_MIXER_CLASS; dip->mixer_class = CSAUDIO_RECORD_CLASS; dip->prev = AUDIO_MIXER_LAST; diff --git a/sys/arch/sparc64/dev/ce4231var.h b/sys/arch/sparc64/dev/ce4231var.h index 85a3c383542..e9c7b82d0f1 100644 --- a/sys/arch/sparc64/dev/ce4231var.h +++ b/sys/arch/sparc64/dev/ce4231var.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ce4231var.h,v 1.8 2006/06/02 20:00:56 miod Exp $ */ +/* $OpenBSD: ce4231var.h,v 1.9 2009/12/01 23:17:11 edd Exp $ */ /* * Copyright (c) 1999 Jason L. Wright (jason@thought.net) @@ -52,6 +52,9 @@ struct cs_volume { u_int8_t right; }; +/* number of levels on the card, these relate to CSPORT_* */ +#define CS4231_LVLS 7 + struct ce4231_softc { struct device sc_dev; /* base device */ struct intrhand sc_ih; /* interrupt vectoring */ @@ -69,9 +72,12 @@ struct ce4231_softc { void (*sc_pintr)(void *); /* output completion intr handler */ void *sc_parg; /* arg for sc_pintr() */ - char sc_mute[9]; /* which devs are muted */ - u_int8_t sc_out_port; /* output port */ - struct cs_volume sc_volume[9]; /* software volume */ + char sc_mute[CS4231_LVLS]; /* which devs are muted */ + u_int8_t sc_monoout_enable; /* whether the mono dacout is on */ + u_int8_t sc_lineout_enable; /* whether the line dacout is on */ + u_int8_t sc_hdphout_enable; /* whether the cans dacout is on */ + u_int8_t sc_rec_src; /* recording src */ + struct cs_volume sc_volume[CS4231_LVLS]; /* software volume */ int sc_format_bits; int sc_speed_bits; |