Current-Users archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
Re: hdaudio(4) "mixerctl -a" -> panic
mpumford%black-star.demon.co.uk@localhost said:
> The value in the step part of the amplifier capabilities is a step
> size in 0.25db increments where a value of zero maps to 0.25db step
> rate and 1 is 0.5db.
I meant the number of steps which was 0. (It is called just "step"
in the code which is somewhat misleading.)
Just looked it up in the spec -- this means that the amplifier
gain cannot be changed. I think that in this case no mixer variable
should be created for the gain. Probably the amplifier has at least
the capability to "mute" the channel then, and a mixer variable should
be created for that (as azalia does).
I'm playing with the appended patch -- it still has the strange effect
on my laptop that unmuting activates the internal speaker even if an
external one is connected. I don't understand yet how things are
wired together.
best regards
Matthias
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------
Forschungszentrum Juelich GmbH
52425 Juelich
Sitz der Gesellschaft: Juelich
Eingetragen im Handelsregister des Amtsgerichts Dueren Nr. HR B 3498
Vorsitzende des Aufsichtsrats: MinDir'in Baerbel Brumme-Bothe
Geschaeftsfuehrung: Prof. Dr. Achim Bachem (Vorsitzender),
Dr. Ulrich Krafft (stellv. Vorsitzender), Prof. Dr.-Ing. Harald Bolt,
Prof. Dr. Sebastian M. Schmidt
------------------------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------
#
# old_revision [7f31056b0cd0586ef5a507e0cf6c6a83408f7191]
#
# patch "sys/dev/pci/hdaudio/hdaudio_afg.c"
# from [8990c8145447763c436993bd1d7dd3b2b39e5f9f]
# to [c871be6b0691492d24062510984d2f1a9b709e94]
#
============================================================
--- sys/dev/pci/hdaudio/hdaudio_afg.c 8990c8145447763c436993bd1d7dd3b2b39e5f9f
+++ sys/dev/pci/hdaudio/hdaudio_afg.c c871be6b0691492d24062510984d2f1a9b709e94
@@ -637,12 +637,14 @@ hdaudio_afg_widget_getcaps(struct hdaudi
w->w_waspin = false;
+#if 0
if (COP_CFG_DEFAULT_DEVICE(config) == COP_DEVICE_SPEAKER &&
(wcap & (COP_AWCAP_INAMP_PRESENT|COP_AWCAP_OUTAMP_PRESENT)) == 0) {
wcap &= ~COP_AWCAP_TYPE_MASK;
wcap |= (COP_AWCAP_TYPE_BEEP_GENERATOR << COP_AWCAP_TYPE_SHIFT);
w->w_waspin = true;
}
+#endif
return wcap;
}
@@ -2355,6 +2357,75 @@ static void
}
static void
+buildmixer_value(struct hdaudio_mixer *mx, struct hdaudio_control *ctl,
+ int type)
+{
+
+ mx->mx_ctl = ctl;
+ mx->mx_di.type = AUDIO_MIXER_VALUE;
+ mx->mx_di.prev = mx->mx_di.next = AUDIO_MIXER_LAST;
+ mx->mx_di.un.v.num_channels = 2; /* XXX */
+ mx->mx_di.un.v.delta = 256 / (ctl->ctl_step + 1);
+ strcpy(mx->mx_di.label.name, hdaudio_afg_mixer_names[type]);
+ switch (type) {
+ case HDAUDIO_MIXER_VOLUME:
+ case HDAUDIO_MIXER_BASS:
+ case HDAUDIO_MIXER_TREBLE:
+ case HDAUDIO_MIXER_OGAIN:
+ mx->mx_di.mixer_class =
+ HDAUDIO_MIXER_CLASS_OUTPUTS;
+ break;
+ case HDAUDIO_MIXER_MIC:
+ case HDAUDIO_MIXER_MONITOR:
+ mx->mx_di.mixer_class =
+ HDAUDIO_MIXER_CLASS_RECORD;
+ break;
+ default:
+ mx->mx_di.mixer_class =
+ HDAUDIO_MIXER_CLASS_INPUTS;
+ break;
+ }
+ strcpy(mx->mx_di.un.v.units.name, AudioNvolume);
+}
+
+static void
+buildmixer_mute(struct hdaudio_mixer *mx, struct hdaudio_control *ctl,
+ int type)
+{
+
+ mx->mx_ctl = ctl;
+ mx->mx_di.type = AUDIO_MIXER_ENUM;
+ mx->mx_di.prev = mx->mx_di.next = AUDIO_MIXER_LAST;
+ mx->mx_di.un.e.num_mem = 2;
+ mx->mx_di.un.e.member[0].ord = 0;
+ strlcpy(mx->mx_di.un.e.member[0].label.name, AudioNoff,
+ MAX_AUDIO_DEV_LEN);
+ mx->mx_di.un.e.member[1].ord = 1;
+ strlcpy(mx->mx_di.un.e.member[1].label.name, AudioNon,
+ MAX_AUDIO_DEV_LEN);
+ strcpy(mx->mx_di.label.name, hdaudio_afg_mixer_names[type]);
+ strlcat(mx->mx_di.label.name, ".mute", MAX_AUDIO_DEV_LEN);
+ switch (type) {
+ case HDAUDIO_MIXER_VOLUME:
+ case HDAUDIO_MIXER_BASS:
+ case HDAUDIO_MIXER_TREBLE:
+ case HDAUDIO_MIXER_OGAIN:
+ mx->mx_di.mixer_class =
+ HDAUDIO_MIXER_CLASS_OUTPUTS;
+ break;
+ case HDAUDIO_MIXER_MIC:
+ case HDAUDIO_MIXER_MONITOR:
+ mx->mx_di.mixer_class =
+ HDAUDIO_MIXER_CLASS_RECORD;
+ break;
+ default:
+ mx->mx_di.mixer_class =
+ HDAUDIO_MIXER_CLASS_INPUTS;
+ break;
+ }
+}
+
+static void
hdaudio_afg_build_mixers(struct hdaudio_afg_softc *sc)
{
struct hdaudio_mixer *mx;
@@ -2375,7 +2446,7 @@ hdaudio_afg_build_mixers(struct hdaudio_
}
for (i = 0; i < HDAUDIO_MIXER_NRDEVICES; i++) {
if (audiomask & (1 << i))
- ++nmixers;
+ nmixers += 2; /* value and mute */
}
/* XXXJDM TODO: softvol */
/* Declare master volume if needed */
@@ -2461,40 +2532,16 @@ hdaudio_afg_build_mixers(struct hdaudio_
}
if (ctl == NULL)
continue;
- mx[index].mx_ctl = ctl;
- mx[index].mx_di.index = index;
- mx[index].mx_di.type = AUDIO_MIXER_VALUE;
- mx[index].mx_di.prev = mx[index].mx_di.next = AUDIO_MIXER_LAST;
- mx[index].mx_di.un.v.num_channels = 2; /* XXX */
- mx[index].mx_di.un.v.delta = 256 / (ctl->ctl_step + 1);
- strcpy(mx[index].mx_di.label.name, hdaudio_afg_mixer_names[i]);
- switch (i) {
- case HDAUDIO_MIXER_VOLUME:
- case HDAUDIO_MIXER_BASS:
- case HDAUDIO_MIXER_TREBLE:
- case HDAUDIO_MIXER_OGAIN:
- mx[index].mx_di.mixer_class =
- HDAUDIO_MIXER_CLASS_OUTPUTS;
- hda_trace(sc, " adding outputs.%s\n",
- mx[index].mx_di.label.name);
- break;
- case HDAUDIO_MIXER_MIC:
- case HDAUDIO_MIXER_MONITOR:
- mx[index].mx_di.mixer_class =
- HDAUDIO_MIXER_CLASS_RECORD;
- hda_trace(sc, " adding record.%s\n",
- mx[index].mx_di.label.name);
- break;
- default:
- mx[index].mx_di.mixer_class =
- HDAUDIO_MIXER_CLASS_INPUTS;
- hda_trace(sc, " adding inputs.%s\n",
- mx[index].mx_di.label.name);
- break;
+ if (ctl->ctl_step) {
+ mx[index].mx_di.index = index;
+ buildmixer_value(&mx[index], ctl, i);
+ ++index;
}
- strcpy(mx[index].mx_di.un.v.units.name, AudioNvolume);
-
- ++index;
+ if (ctl->ctl_mute) {
+ mx[index].mx_di.index = index;
+ buildmixer_mute(&mx[index], ctl, i);
+ ++index;
+ }
}
/* DAC selector */
@@ -3356,6 +3403,8 @@ hdaudio_afg_set_port(void *opaque, mixer
struct hdaudio_mixer *mx;
struct hdaudio_control *ctl;
int i, divisor;
+ uint32_t mute;
+ int left, right;
if (mc->dev < 0 || mc->dev >= sc->sc_nmixers)
return EINVAL;
@@ -3385,15 +3434,18 @@ hdaudio_afg_set_port(void *opaque, mixer
return 0;
}
- if (ctl->ctl_step == 0)
- divisor = 128; /* ??? - just avoid div by 0 */
- else
+ mute = HDAUDIO_AMP_MUTE_DEFAULT;
+ left = right = HDAUDIO_AMP_VOL_DEFAULT;
+
+ if (mc->type == AUDIO_MIXER_VALUE) {
+ KASSERT(ctl->ctl_step != 0);
divisor = 255 / ctl->ctl_step;
+ left = mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] / divisor;
+ right = mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] / divisor;
+ } else if (mc->type == AUDIO_MIXER_ENUM)
+ mute = mc->un.ord;
- hdaudio_afg_control_amp_set(ctl, HDAUDIO_AMP_MUTE_NONE,
- mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] / divisor,
- mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] / divisor);
-
+ hdaudio_afg_control_amp_set(ctl, mute, left, right);
return 0;
}
@@ -3435,13 +3487,16 @@ hdaudio_afg_get_port(void *opaque, mixer
return 0;
}
- if (ctl->ctl_step == 0)
- factor = 128; /* ??? - just avoid div by 0 */
- else
+ if (mc->type == AUDIO_MIXER_VALUE) {
+ KASSERT(ctl->ctl_step != 0);
factor = 255 / ctl->ctl_step;
-
- mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] = ctl->ctl_left * factor;
- mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] = ctl->ctl_right * factor;
+ mc->un.value.level[AUDIO_MIXER_LEVEL_LEFT] =
+ ctl->ctl_left * factor;
+ mc->un.value.level[AUDIO_MIXER_LEVEL_RIGHT] =
+ ctl->ctl_right * factor;
+ } else if (mc->type == AUDIO_MIXER_ENUM) {
+ mc->un.ord = ctl->ctl_muted;
+ }
return 0;
}
Home |
Main Index |
Thread Index |
Old Index