[alsa-devel] When select 2.1 profile in pulseaudio, how do pulseaudio select notebook 's internal subwoofer or 5.1 external speaker ?

Raymond Yau superquad.vortex2 at gmail.com
Sun Jul 12 04:16:05 CEST 2015


> >
> > Are you sure that it is alsa driver bug since pulseaudio seem not using
> > line out jack to mute internal speakers ?
>
> No, I'm not. I set all my jacks to line out and it works now.
>

Do pulseaudio 2.1 profile select the internal subwoofer or your 5.1
external speaker ?

diff --git a/sound/pci/hda/hda_auto_parser.c
b/sound/pci/hda/hda_auto_parser.c
index 03b7399..c9e45e7 100644
@@ -952,6 +960,7 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
     const struct snd_pci_quirk *q;
     int id = HDA_FIXUP_ID_NOT_SET;
     const char *name = NULL;
+    int i;

     if (codec->fixup_id != HDA_FIXUP_ID_NOT_SET)
         return;
@@ -966,6 +975,9 @@ void snd_hda_pick_fixup(struct hda_codec *codec,
         return;
     }

+    if (!snd_hda_get_int_hint(codec, "alt_config", &i))
+        codec->alt_config = i;
+
     if (codec->modelname && models) {
         while (models->name) {
             if (!strcmp(codec->modelname, models->name)) {
diff --git a/sound/pci/hda/hda_codec.h b/sound/pci/hda/hda_codec.h
index 12837ab..38841db 100644
--- a/sound/pci/hda/hda_codec.h
+++ b/sound/pci/hda/hda_codec.h
@@ -283,6 +283,8 @@ struct hda_codec {

     /* additional init verbs */
     struct snd_array verbs;
+    int alt_config;
+    int combo_jack;
 };

 #define dev_to_hda_codec(_dev)    container_of(_dev, struct hda_codec,
core.dev)
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index ac0db16..12ee7f7 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -39,7 +39,6 @@
 #include "hda_beep.h"
 #include "hda_generic.h"

-
 /**
  * snd_hda_gen_spec_init - initialize hda_gen_spec struct
  * @spec: hda_gen_spec object to initialize
@@ -180,10 +179,10 @@ static void parse_user_hints(struct hda_codec *codec)
     /* the following two are just for compatibility */
     val = snd_hda_get_bool_hint(codec, "add_out_jack_modes");
     if (val >= 0)
-        spec->add_jack_modes = !!val;
+        spec->add_out_jack_modes = !!val;
     val = snd_hda_get_bool_hint(codec, "add_in_jack_modes");
     if (val >= 0)
-        spec->add_jack_modes = !!val;
+        spec->add_in_jack_modes = !!val;
     val = snd_hda_get_bool_hint(codec, "add_jack_modes");
     if (val >= 0)
         spec->add_jack_modes = !!val;
@@ -2648,7 +2720,7 @@ static void get_jack_mode_name(struct hda_codec
*codec, hda_nid_t pin,
 static int get_out_jack_num_items(struct hda_codec *codec, hda_nid_t pin)
 {
     struct hda_gen_spec *spec = codec->spec;
-    if (spec->add_jack_modes) {
+    if (spec->add_jack_modes || spec->add_out_jack_modes) {
         unsigned int pincap = snd_hda_query_pin_caps(codec, pin);
         if ((pincap & AC_PINCAP_OUT) && (pincap & AC_PINCAP_HP_DRV))
             return 2;
@@ -2791,7 +2863,7 @@ static int get_in_jack_num_items(struct hda_codec
*codec, hda_nid_t pin)
 {
     struct hda_gen_spec *spec = codec->spec;
     int nitems = 0;
-    if (spec->add_jack_modes)
+    if (spec->add_jack_modes || spec->add_in_jack_modes)
         nitems = hweight32(get_vref_caps(codec, pin));
     return nitems ? nitems : 1;
 }
@@ -3287,7 +3359,7 @@ static int create_input_ctls(struct hda_codec *codec)
         if (err < 0)
             return err;

-        if (spec->add_jack_modes) {
+        if (spec->add_jack_modes || spec->add_in_jack_modes) {
             err = create_in_jack_mode(codec, pin);
             if (err < 0)
                 return err;
@@ -4895,13 +4971,13 @@ int snd_hda_gen_parse_auto_config(struct hda_codec
*codec,
      */
     if (spec->hp_mic_pin &&
         (spec->auto_mic || spec->input_mux.num_items == 1 ||
-         spec->add_jack_modes)) {
+         spec->add_jack_modes || spec->add_in_jack_modes)) {
         err = create_hp_mic_jack_mode(codec, spec->hp_mic_pin);
         if (err < 0)
             return err;
     }

-    if (spec->add_jack_modes) {
+    if (spec->add_jack_modes || spec->add_out_jack_modes) {
         if (cfg->line_out_type != AUTO_PIN_SPEAKER_OUT) {
             err = create_out_jack_modes(codec, cfg->line_outs,
                             cfg->line_out_pins);
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index 56e4139..f10c55b 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -227,6 +229,8 @@ struct hda_gen_spec {
     unsigned int prefer_hp_amp:1; /* enable HP amp for speaker if any */
     unsigned int add_stereo_mix_input:2; /* add aamix as a capture src */
     unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */
+    unsigned int add_in_jack_modes:1; /* add in jack mode enum ctls */
+    unsigned int add_out_jack_modes:1; /* add out jack mode enum ctls */
     unsigned int power_down_unused:1; /* power down unused widgets */
     unsigned int dac_min_mute:1; /* minimal = mute for DACs */

diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 8e02cdf..b13f588 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -1914,6 +1914,62 @@ static void alc889_fixup_mba21_vref(struct hda_codec
*codec,
         alc889_fixup_mac_pins(codec, nids, ARRAY_SIZE(nids));
 }

+static const struct snd_pcm_chmap_elem acer_pcm_chmaps[] = {
+    { .channels = 2,
+      .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR } },
+    { .channels = 4,
+      .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+           SNDRV_CHMAP_LFE, SNDRV_CHMAP_NA } }, /* LFE only on left */
+    { .channels = 4,
+      .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+           SNDRV_CHMAP_RL, SNDRV_CHMAP_RR } },
+    { .channels = 6,
+      .map = { SNDRV_CHMAP_FL, SNDRV_CHMAP_FR,
+           SNDRV_CHMAP_RL, SNDRV_CHMAP_RR,
+           SNDRV_CHMAP_FC, SNDRV_CHMAP_LFE } },
+    { }
+};
+
+static void alc888_fixup_acer_aspire_4930g(struct hda_codec *codec,
+                    const struct hda_fixup *fix, int action)
+{
+    static const struct hda_pintbl subwoofer_cfg[] = {
+        { 0x16, 0x90170111 }, /* internal subwoofer */
+        {}
+    };
+    static const struct hda_pintbl front_cfg[] = {
+        { 0x15, 0x02014010},
+        {}
+    };
+    static const struct hda_pintbl rear_cfg[] = {
+        { 0x1a, 0x02014011},
+        {}
+    };
+    static const struct hda_pintbl clfe_cfg[] = {
+        { 0x18, 0x02014012},
+        {}
+    };
+    struct alc_spec *spec = codec->spec;
+    switch(action){
+    case HDA_FIXUP_ACT_PRE_PROBE:
+        snd_hda_apply_pincfgs(codec, subwoofer_cfg);
+        spec->gen.add_out_jack_modes = true;
+        switch(codec->alt_config){
+        case 3:
+            snd_hda_apply_pincfgs(codec, clfe_cfg);
+        case 2:
+            snd_hda_apply_pincfgs(codec, rear_cfg);
+        case 1:
+            snd_hda_apply_pincfgs(codec, front_cfg);
+            break;
+        }
+        break;
+    case HDA_FIXUP_ACT_BUILD:
+        spec->gen.pcm_rec[0]->stream[0].chmap = acer_pcm_chmaps;
+        break;
+    }
+}
+
 /* Don't take HP output as primary
  * Strangely, the speaker output doesn't work on Vaio Z and some Vaio
  * all-in-one desktop PCs (for example VGC-LN51JGB) through DAC 0x05
@@ -2048,12 +2104,8 @@ static const struct hda_fixup alc882_fixups[] = {
         .v.func = alc889_fixup_coef,
     },
     [ALC882_FIXUP_ACER_ASPIRE_4930G] = {
-        .type = HDA_FIXUP_PINS,
-        .v.pins = (const struct hda_pintbl[]) {
-            { 0x16, 0x99130111 }, /* CLFE speaker */
-            { 0x17, 0x99130112 }, /* surround speaker */
-            { }
-        },
+        .type = HDA_FIXUP_FUNC,
+        .v.func = alc888_fixup_acer_aspire_4930g,
         .chained = true,
         .chain_id = ALC882_FIXUP_GPIO1,
     },


More information about the Alsa-devel mailing list