[alsa-devel] [PATCH] Add sequence parsing for speaker-outs in snd_hda_parse_pin_def_config()
Any comments on this patch? It really is needed because some BIOS's only define speaker-out's in the HDA codec default pin configs, and no line-outs. So speaker-out's must be sequenced just as is being done for line-out's, otherwise the surround pin assignments will be wrong.
Steve
Steve Longerbeam wrote:
changeset: 5028:01537f056c79 tag: tip user: stevel@embeddedalley.com date: Thu May 03 10:30:04 2007 -0700 summary: 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 stevel@embeddedalley.com
diff -r c7366efee611 -r 01537f056c79 pci/hda/hda_codec.c --- a/pci/hda/hda_codec.c Thu May 03 10:24:35 2007 -0700 +++ b/pci/hda/hda_codec.c Thu May 03 10:30:04 2007 -0700 @@ -2112,6 +2112,32 @@ static int __devinit is_in_nid_list(hda_ 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_conf 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_conf if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins)) continue; cfg->line_out_pins[cfg->line_outs] = nid;
sequences[cfg->line_outs] = seq;
case AC_JACK_SPEAKER:sequences_line_out[cfg->line_outs] = seq; cfg->line_outs++; break;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; case AC_JACK_HP_OUT:sequences_speaker[cfg->speaker_outs] = seq; cfg->speaker_outs++; break;@@ -2227,16 +2265,32 @@ int __devinit snd_hda_parse_pin_def_conf }
/* 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_conf 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;
}
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Hi Steve,
At Sat, 05 May 2007 11:16:44 -0700, Steve Longerbeam wrote:
Any comments on this patch? It really is needed because some BIOS's only define speaker-out's in the HDA codec default pin configs, and no line-outs. So speaker-out's must be sequenced just as is being done for line-out's, otherwise the surround pin assignments will be wrong.
I've been (and am still) sick since the last week, so I couldn't check posts on ML but only private mails. At the next time, if you'd like a patch review for merge, please add my address to Cc so that it'll reach to me certainly.
Your patch looks nice, but unfortunately I have no test machines with HD-audio around my bed... Will test and merge to the upstream soon after I'm recovered :)
Thanks,
Takashi
Steve
Steve Longerbeam wrote:
changeset: 5028:01537f056c79 tag: tip user: stevel@embeddedalley.com date: Thu May 03 10:30:04 2007 -0700 summary: 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 stevel@embeddedalley.com
diff -r c7366efee611 -r 01537f056c79 pci/hda/hda_codec.c --- a/pci/hda/hda_codec.c Thu May 03 10:24:35 2007 -0700 +++ b/pci/hda/hda_codec.c Thu May 03 10:30:04 2007 -0700 @@ -2112,6 +2112,32 @@ static int __devinit is_in_nid_list(hda_ 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_conf 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_conf if (cfg->line_outs >= ARRAY_SIZE(cfg->line_out_pins)) continue; cfg->line_out_pins[cfg->line_outs] = nid;
sequences[cfg->line_outs] = seq;
case AC_JACK_SPEAKER:sequences_line_out[cfg->line_outs] = seq; cfg->line_outs++; break;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; case AC_JACK_HP_OUT:sequences_speaker[cfg->speaker_outs] = seq; cfg->speaker_outs++; break;@@ -2227,16 +2265,32 @@ int __devinit snd_hda_parse_pin_def_conf }
/* 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_conf 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;
}
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
Alsa-devel mailing list Alsa-devel@alsa-project.org http://mailman.alsa-project.org/mailman/listinfo/alsa-devel
participants (2)
-
Steve Longerbeam -
Takashi Iwai