originated on bugs@ ...
On Wed, Apr 08, 2009 at 06:40:37PM -0400, Joe Gidi wrote:
here's a diff that attempts to discover a "main input mixer", and mutes
the built-in mic on it.
this might only be useful on realtek codecs. sigmatel/idt codecs
don't seem to use mixers, but rather selectors, and analog devices
codecs have overly complicated connections (mic input might come
through another widget).
--
jakemsr@sdf.lonestar.org
SDF Public Access UNIX System -
http://sdf.lonestar.org
Index: azalia.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/azalia.c,v
retrieving revision 1.130
diff -N -u -p azalia.c
--- azalia.c 1 May 2009 04:00:40 -0000 1.130
+++ azalia.c 3 May 2009 12:22:14 -0000
@@ -213,6 +213,7 @@ int azalia_codec_init_volgroups(codec_t *);
int azalia_codec_sort_pins(codec_t *);
int azalia_codec_select_micadc(codec_t *);
int azalia_codec_select_spkrdac(codec_t *);
+int azalia_codec_find_inputmixer(codec_t *);
int azalia_widget_init(widget_t *, const codec_t *, int);
int azalia_widget_label_widgets(codec_t *);
@@ -1356,6 +1357,10 @@ azalia_codec_init(codec_t *this)
if (err)
return err;
+ err = azalia_codec_find_inputmixer(this);
+ if (err)
+ return err;
+
err = azalia_codec_select_spkrdac(this);
if (err)
return err;
@@ -1387,6 +1392,52 @@ azalia_codec_init(codec_t *this)
return err;
return 0;
+}
+
+int
+azalia_codec_find_inputmixer(codec_t *this)
+{
+ widget_t *w;
+ int i, j;
+
+ this->input_mixer = -1;
+
+ FOR_EACH_WIDGET(this, i) {
+ w = &this->w[i];
+ if (w->type != COP_AWTYPE_AUDIO_MIXER)
+ continue;
+
+ /* can input from a pin */
+ for (j = 0; j < this->nipins; j++) {
+ if (azalia_codec_fnode(this, this->ipins[j].nid,
+ w->nid, 0) != -1)
+ break;
+ }
+ if (j == this->nipins)
+ continue;
+
+ /* can output to a pin */
+ for (j = 0; j < this->nopins; j++) {
+ if (azalia_codec_fnode(this, w->nid,
+ this->opins[j].nid, 0) != -1)
+ break;
+ }
+ if (j == this->nopins)
+ continue;
+
+ /* can output to an ADC */
+ for (j = 0; j < this->na_adcs; j++) {
+ if (azalia_codec_fnode(this, w->nid,
+ this->a_adcs[j], 0) != -1)
+ break;
+ }
+ if (j == this->na_adcs)
+ continue;
+
+ this->input_mixer = i;
+ break;
+ }
+ return(0);
}
int
Index: azalia.h
===================================================================
RCS file: /cvs/src/sys/dev/pci/azalia.h,v
retrieving revision 1.44
diff -N -u -p azalia.h
--- azalia.h 1 May 2009 02:55:16 -0000 1.44
+++ azalia.h 3 May 2009 12:22:14 -0000
@@ -668,6 +668,7 @@ typedef struct codec_t {
nid_t mic_adc;
nid_t speaker; /* fixed (internal) speaker */
nid_t spkr_dac;
+ nid_t input_mixer;
int spkr_muters;
int spkr_mute_method;
Index: azalia_codec.c
===================================================================
RCS file: /cvs/src/sys/dev/pci/azalia_codec.c,v
retrieving revision 1.122
diff -N -u -p azalia_codec.c
--- azalia_codec.c 1 May 2009 03:45:17 -0000 1.122
+++ azalia_codec.c 3 May 2009 12:22:15 -0000
@@ -1278,6 +1278,9 @@ azalia_generic_mixer_default(codec_t *this)
for (j = 0; j < w->nconnections; j++) {
if (!azalia_widget_enabled(this, w->connections[j]))
continue;
+ if (w->nid == this->input_mixer &&
+ w->connections[j] == this->mic)
+ continue;
mc.un.mask |= 1 << j;
}
azalia_generic_mixer_set(this, m->nid, m->target, &mc);