Gitweb:     
http://git.kernel.org/git/?p=linux/kernel/git/torvalds/linux-2.6.git;a=commit;h=81937d3bac582ea2249dc2c8891d3371635e8b64
Commit:     81937d3bac582ea2249dc2c8891d3371635e8b64
Parent:     bdd148a307e230517bf891c108e0eec68ba5d10f
Author:     Steve Longerbeam <[EMAIL PROTECTED]>
AuthorDate: Tue May 8 15:33:03 2007 +0200
Committer:  Jaroslav Kysela <[EMAIL PROTECTED]>
CommitDate: Fri May 11 16:56:18 2007 +0200

    [ALSA] Add speaker pin sequencing to 
hda_codec.c:snd_hda_parse_pin_def_config()
    
    Some verb tables (such as an Asus VT sent by IDT) contain only speaker
    outs in the default pin configs, and no line-outs. In such a case the
    speaker sequence numbers have to be used to order the speaker out
    pins, just as is being done for line-out pins. Then, when speaker-outs
    are copied to line-outs, the line-outs will be ordered properly.
    
    Signed-off-by: Steve Longerbeam <[EMAIL PROTECTED]>
    Signed-off-by: Takashi Iwai <[EMAIL PROTECTED]>
    Signed-off-by: Jaroslav Kysela <[EMAIL PROTECTED]>
---
 sound/pci/hda/hda_codec.c |  106 +++++++++++++++++++++++++++++----------------
 1 files changed, 69 insertions(+), 37 deletions(-)

diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index ff12de4..14649d5 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -2112,6 +2112,32 @@ static int __devinit is_in_nid_list(hda_nid_t nid, 
hda_nid_t *list)
        return 0;
 }
 
+
+/*
+ * Sort an associated group of pins according to their sequence numbers.
+ */
+static void sort_pins_by_sequence(hda_nid_t * pins, short * sequences,
+                                 int num_pins)
+{
+       int i, j;
+       short seq;
+       hda_nid_t nid;
+       
+       for (i = 0; i < num_pins; i++) {
+               for (j = i + 1; j < num_pins; j++) {
+                       if (sequences[i] > sequences[j]) {
+                               seq = sequences[i];
+                               sequences[i] = sequences[j];
+                               sequences[j] = seq;
+                               nid = pins[i];
+                               pins[i] = pins[j];
+                               pins[j] = nid;
+                       }
+               }
+       }
+}
+
+
 /*
  * Parse all pin widgets and store the useful pin nids to cfg
  *
@@ -2134,13 +2160,16 @@ int __devinit snd_hda_parse_pin_def_config(struct 
hda_codec *codec,
                                           hda_nid_t *ignore_nids)
 {
        hda_nid_t nid, nid_start;
-       int i, j, nodes;
-       short seq, assoc_line_out, sequences[ARRAY_SIZE(cfg->line_out_pins)];
+       int nodes;
+       short seq, assoc_line_out, assoc_speaker;
+       short sequences_line_out[ARRAY_SIZE(cfg->line_out_pins)];
+       short sequences_speaker[ARRAY_SIZE(cfg->speaker_pins)];
 
        memset(cfg, 0, sizeof(*cfg));
 
-       memset(sequences, 0, sizeof(sequences));
-       assoc_line_out = 0;
+       memset(sequences_line_out, 0, sizeof(sequences_line_out));
+       memset(sequences_speaker, 0, sizeof(sequences_speaker));
+       assoc_line_out = assoc_speaker = 0;
 
        nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start);
        for (nid = nid_start; nid < nodes + nid_start; nid++) {
@@ -2175,13 +2204,22 @@ int __devinit snd_hda_parse_pin_def_config(struct 
hda_codec *codec,
                        if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins))
                                continue;
                        cfg->line_out_pins[cfg->line_outs] = nid;
-                       sequences[cfg->line_outs] = seq;
+                       sequences_line_out[cfg->line_outs] = seq;
                        cfg->line_outs++;
                        break;
                case AC_JACK_SPEAKER:
+                       seq = get_defcfg_sequence(def_conf);
+                       assoc = get_defcfg_association(def_conf);
+                       if (! assoc)
+                               continue;
+                       if (! assoc_speaker)
+                               assoc_speaker = assoc;
+                       else if (assoc_speaker != assoc)
+                               continue;
                        if (cfg->speaker_outs >= ARRAY_SIZE(cfg->speaker_pins))
                                continue;
                        cfg->speaker_pins[cfg->speaker_outs] = nid;
+                       sequences_speaker[cfg->speaker_outs] = seq;
                        cfg->speaker_outs++;
                        break;
                case AC_JACK_HP_OUT:
@@ -2227,16 +2265,32 @@ int __devinit snd_hda_parse_pin_def_config(struct 
hda_codec *codec,
        }
 
        /* sort by sequence */
-       for (i = 0; i < cfg->line_outs; i++)
-               for (j = i + 1; j < cfg->line_outs; j++)
-                       if (sequences[i] > sequences[j]) {
-                               seq = sequences[i];
-                               sequences[i] = sequences[j];
-                               sequences[j] = seq;
-                               nid = cfg->line_out_pins[i];
-                               cfg->line_out_pins[i] = cfg->line_out_pins[j];
-                               cfg->line_out_pins[j] = nid;
-                       }
+       sort_pins_by_sequence(cfg->line_out_pins, sequences_line_out,
+                             cfg->line_outs);
+       sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker,
+                             cfg->speaker_outs);
+       
+       /*
+        * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
+        * as a primary output
+        */
+       if (!cfg->line_outs) {
+               if (cfg->speaker_outs) {
+                       cfg->line_outs = cfg->speaker_outs;
+                       memcpy(cfg->line_out_pins, cfg->speaker_pins,
+                              sizeof(cfg->speaker_pins));
+                       cfg->speaker_outs = 0;
+                       memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
+                       cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
+               } else if (cfg->hp_outs) {
+                       cfg->line_outs = cfg->hp_outs;
+                       memcpy(cfg->line_out_pins, cfg->hp_pins,
+                              sizeof(cfg->hp_pins));
+                       cfg->hp_outs = 0;
+                       memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
+                       cfg->line_out_type = AUTO_PIN_HP_OUT;
+               }
+       }
 
        /* Reorder the surround channels
         * ALSA sequence is front/surr/clfe/side
@@ -2278,28 +2332,6 @@ int __devinit snd_hda_parse_pin_def_config(struct 
hda_codec *codec,
                   cfg->input_pins[AUTO_PIN_CD],
                   cfg->input_pins[AUTO_PIN_AUX]);
 
-       /*
-        * FIX-UP: if no line-outs are detected, try to use speaker or HP pin
-        * as a primary output
-        */
-       if (!cfg->line_outs) {
-               if (cfg->speaker_outs) {
-                       cfg->line_outs = cfg->speaker_outs;
-                       memcpy(cfg->line_out_pins, cfg->speaker_pins,
-                              sizeof(cfg->speaker_pins));
-                       cfg->speaker_outs = 0;
-                       memset(cfg->speaker_pins, 0, sizeof(cfg->speaker_pins));
-                       cfg->line_out_type = AUTO_PIN_SPEAKER_OUT;
-               } else if (cfg->hp_outs) {
-                       cfg->line_outs = cfg->hp_outs;
-                       memcpy(cfg->line_out_pins, cfg->hp_pins,
-                              sizeof(cfg->hp_pins));
-                       cfg->hp_outs = 0;
-                       memset(cfg->hp_pins, 0, sizeof(cfg->hp_pins));
-                       cfg->line_out_type = AUTO_PIN_HP_OUT;
-               }
-       }
-
        return 0;
 }
 
-
To unsubscribe from this list: send the line "unsubscribe git-commits-head" in
the body of a message to [EMAIL PROTECTED]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to