On Fri, Jun 19, 2009 at 08:07:05PM +0100, Edd Barrett wrote: > Hello, > > I am seeing odd behavior from mixerctl on a Sun Blade 1000. The machine > is running a snapshot I downloaded yesterday. It seems I can not set the > volume to a comfortable setting: > > ---8<--- > # dmesg | grep audio > audioce0 at ebus0 addr 200000-2000ff, 702000-70200f, 704000-70400f, > 722000-722003 ivec 0x20 ivec 0x21: nvaddrs 0 > audio0 at audioce0 > > # mixerctl > inputs.dac=31,31 > inputs.dac.mute=off > inputs.line=8,8 > inputs.line.mute=on > inputs.mic=0 > inputs.mic.mute=on > inputs.cd=8,8 > inputs.cd.mute=on > monitor.monitor=0 > outputs.monitor.mute=off > outputs.output=192,192 > outputs.output.mute=off > record.record=0,0 > record.record.source=mic > monitor.output=spkr > > # mixerctl inputs.dac=200 > inputs.dac: 31,31 -> 8,8 > # mixerctl inputs.dac=230 > inputs.dac: 8,8 -> 6,6 > ---8<--- > > Playing a video using mplayer, I can hear this very quietly from the > internal speaker. The hardware is known to be good, and the same task > works fine under solaris 10. > > Any clues what may be wrong here? I am willing to have a look at the > code myself if no-one has any ideas.
please do ;) the mixer interface in audioce(4) looks sorta bogus. I guess the driver was not really finished? maybe the following will help get you started? -- [email protected] SDF Public Access UNIX System - http://sdf.lonestar.org first chunk: don't be so fussy about unsupported formats, use something that is supported. second and third: use the DAC register for inputs.dac and scale audio(4) volume range to hardware range. Index: ce4231.c =================================================================== RCS file: /cvs/src/sys/arch/sparc64/dev/ce4231.c,v retrieving revision 1.22 diff -u -p ce4231.c --- ce4231.c 21 Apr 2008 00:32:42 -0000 1.22 +++ ce4231.c 20 Jun 2009 00:51:10 -0000 @@ -576,75 +576,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) @@ -788,17 +784,17 @@ ce4231_set_port(addr, cp) 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) { + ce4231_write(sc, SP_LEFT_OUTPUT_CONTROL, + (cp->un.value.level[AUDIO_MIXER_LEVEL_MONO] >> 2) & + OUTPUT_ATTEN_BITS); + } else if (cp->un.value.num_channels == 2) { + ce4231_write(sc, SP_LEFT_OUTPUT_CONTROL, + (cp->un.value.level[AUDIO_MIXER_LEVEL_LEFT] >> 2) & + OUTPUT_ATTEN_BITS); + ce4231_write(sc, SP_RIGHT_OUTPUT_CONTROL, + (cp->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] >> 2) & + OUTPUT_ATTEN_BITS); } else break; error = 0; @@ -960,15 +956,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, SP_LEFT_AUX1_CONTROL) & - LINE_INPUT_ATTEN_BITS; + (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; + (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; + (ce4231_read(sc, SP_RIGHT_OUTPUT_CONTROL) & + OUTPUT_ATTEN_BITS) << 2; } else break; error = 0;
