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;

Reply via email to