On Thu, 2007-10-25 at 11:07 +0200, Takashi Iwai wrote: > At Thu, 25 Oct 2007 15:44:42 +0800, > zhejiang wrote: > > > > On Tue, 2007-10-23 at 11:11 +0200, Takashi Iwai wrote: > > > At Mon, 22 Oct 2007 14:08:19 +0800, > > > zhejiang wrote: > > > > > > > Ah, then it's basically similar like 3-stack model but with two > > > > > headphones instead of a pair of line-out and line-in. > > > > > > > > > > Without your modification of pin config, how the driver detects? > > > > > Do you have an output of kernel message with debug option about auto > > > > > pin configs? > > > > > > > > > I don't have the hardware. > > > > I have asked the bug reporter to do the experiment, > > > > I will post it here if i get any response. > > > > > > Thanks. > > > > > > > According to the response from the reporter,here is the pin config of > > the original driver. > > > > ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2765: > > autoconfig: line_outs=3 (0xd/0xc/0xf/0x0/0x0) > > ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2769: > > speaker_outs=0 (0x0/0x0/0x0/0x0/0x0) > > ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2773: > > hp_outs=1 (0xa/0x0/0x0/0x0/0x0) > > ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/hda_codec.c:2781: > > inputs: mic=0x0, fmic=0x0, line=0x0, fline=0x0, cd=0x0, aux=0x0 > > ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/../../alsa-kernel/pci/hda/patch_sigmatel.c:1652: stac92xx_add_dyn_out_pins: total dac count=4 > > ALSA /tmp/alsa-driver-build/alsa-driver-1.0.15/pci/hda/../../alsa-kernel/pci/hda/patch_sigmatel.c:1775: dac_nids=3 (0x2/0x3/0x5/0x0/0x0) > > Interesting. Then the driver seems probing a fairly wrong pin > mapping. So obviously the PCI SSID table entry for this laptop isn't > correct. > OK, what about the patch below? > It doesn't change the pincfg, so it wouldn't work as is, though. > > > Takashi > > diff -r 09088524dd7f pci/hda/hda_codec.c > --- a/pci/hda/hda_codec.c Thu Oct 25 11:46:24 2007 +0200 > +++ b/pci/hda/hda_codec.c Thu Oct 25 12:42:00 2007 +0200 > @@ -2600,11 +2600,13 @@ int snd_hda_parse_pin_def_config(struct > 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)]; > + short sequences_hp[ARRAY_SIZE(cfg->hp_pins)]; > > memset(cfg, 0, sizeof(*cfg)); > > memset(sequences_line_out, 0, sizeof(sequences_line_out)); > memset(sequences_speaker, 0, sizeof(sequences_speaker)); > + memset(sequences_hp, 0, sizeof(sequences_hp)); > assoc_line_out = assoc_speaker = 0; > > nodes = snd_hda_get_sub_nodes(codec, codec->afg, &nid_start); > @@ -2659,9 +2661,12 @@ int snd_hda_parse_pin_def_config(struct > cfg->speaker_outs++; > break; > case AC_JACK_HP_OUT: > + seq = get_defcfg_sequence(def_conf); > + assoc = get_defcfg_association(def_conf); > if (cfg->hp_outs >= ARRAY_SIZE(cfg->hp_pins)) > continue; > cfg->hp_pins[cfg->hp_outs] = nid; > + sequences_hp[cfg->hp_outs] = (assoc << 4) | seq; > cfg->hp_outs++; > break; > case AC_JACK_MIC_IN: { > @@ -2705,7 +2710,24 @@ int snd_hda_parse_pin_def_config(struct > cfg->line_outs); > sort_pins_by_sequence(cfg->speaker_pins, sequences_speaker, > cfg->speaker_outs); > + sort_pins_by_sequence(cfg->hp_pins, sequences_hp, > + cfg->hp_outs); > > + /* if we have only one mic, make it AUTO_PIN_MIC */ > + if (!cfg->input_pins[AUTO_PIN_MIC] && > + cfg->input_pins[AUTO_PIN_FRONT_MIC]) { > + cfg->input_pins[AUTO_PIN_MIC] = > + cfg->input_pins[AUTO_PIN_FRONT_MIC]; > + cfg->input_pins[AUTO_PIN_FRONT_MIC] = 0; > + } > + /* ditto for line-in */ > + if (!cfg->input_pins[AUTO_PIN_LINE] && > + cfg->input_pins[AUTO_PIN_FRONT_LINE]) { > + cfg->input_pins[AUTO_PIN_LINE] = > + cfg->input_pins[AUTO_PIN_FRONT_LINE]; > + cfg->input_pins[AUTO_PIN_FRONT_LINE] = 0; > + } > + > /* > * FIX-UP: if no line-outs are detected, try to use speaker or HP pin > * as a primary output > diff -r 09088524dd7f pci/hda/patch_sigmatel.c > --- a/pci/hda/patch_sigmatel.c Thu Oct 25 11:46:24 2007 +0200 > +++ b/pci/hda/patch_sigmatel.c Thu Oct 25 12:42:00 2007 +0200 > @@ -1649,12 +1649,14 @@ static int stac92xx_add_control(struct s > } > > /* flag inputs as additional dynamic lineouts */ > -static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, struct auto_pin_cfg *cfg) > +static int stac92xx_add_dyn_out_pins(struct hda_codec *codec, > + struct auto_pin_cfg *cfg, > + int line_outs, hda_nid_t *line_out_pins) > { > struct sigmatel_spec *spec = codec->spec; > unsigned int wcaps, wtype; > int i, num_dacs = 0; > - > + > /* use the wcaps cache to count all DACs available for line-outs */ > for (i = 0; i < codec->num_nodes; i++) { > wcaps = codec->wcaps[i]; > @@ -1665,49 +1667,48 @@ static int stac92xx_add_dyn_out_pins(str > > snd_printdd("%s: total dac count=%d\n", __func__, num_dacs); > > - switch (cfg->line_outs) { > + switch (line_outs) { > case 3: > /* add line-in as side */ > if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 3) { > - cfg->line_out_pins[cfg->line_outs] = > + line_out_pins[line_outs] = > cfg->input_pins[AUTO_PIN_LINE]; > spec->line_switch = 1; > - cfg->line_outs++; > + line_outs++; > } > break; > case 2: > /* add line-in as clfe and mic as side */ > if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 2) { > - cfg->line_out_pins[cfg->line_outs] = > + line_out_pins[line_outs] = > cfg->input_pins[AUTO_PIN_LINE]; > spec->line_switch = 1; > - cfg->line_outs++; > + line_outs++; > } > if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 3) { > - cfg->line_out_pins[cfg->line_outs] = > + line_out_pins[line_outs] = > cfg->input_pins[AUTO_PIN_MIC]; > spec->mic_switch = 1; > - cfg->line_outs++; > + line_outs++; > } > break; > case 1: > /* add line-in as surr and mic as clfe */ > if (cfg->input_pins[AUTO_PIN_LINE] && num_dacs > 1) { > - cfg->line_out_pins[cfg->line_outs] = > + line_out_pins[line_outs] = > cfg->input_pins[AUTO_PIN_LINE]; > spec->line_switch = 1; > - cfg->line_outs++; > + line_outs++; > } > if (cfg->input_pins[AUTO_PIN_MIC] && num_dacs > 2) { > - cfg->line_out_pins[cfg->line_outs] = > + line_out_pins[line_outs] = > cfg->input_pins[AUTO_PIN_MIC]; > spec->mic_switch = 1; > - cfg->line_outs++; > + line_outs++; > } > break; > } > - > - return 0; > + return line_outs; > } > > > @@ -1731,15 +1732,16 @@ static int is_in_dac_nids(struct sigmate > * and 9202/925x. For those, dac_nids[] must be hard-coded. > */ > static int stac92xx_auto_fill_dac_nids(struct hda_codec *codec, > - struct auto_pin_cfg *cfg) > + struct auto_pin_cfg *cfg, > + int line_outs, hda_nid_t *line_out_pins) > { > struct sigmatel_spec *spec = codec->spec; > int i, j, conn_len = 0; > hda_nid_t nid, conn[HDA_MAX_CONNECTIONS]; > unsigned int wcaps, wtype; > > - for (i = 0; i < cfg->line_outs; i++) { > - nid = cfg->line_out_pins[i]; > + for (i = 0; i < line_outs; i++) { > + nid = line_out_pins[i]; > conn_len = snd_hda_get_connections(codec, nid, conn, > HDA_MAX_CONNECTIONS); > for (j = 0; j < conn_len; j++) { > @@ -1760,7 +1762,7 @@ static int stac92xx_auto_fill_dac_nids(s > /* we have already working output pins, > * so let's drop the broken ones again > */ > - cfg->line_outs = spec->multiout.num_dacs; > + line_outs = spec->multiout.num_dacs; > break; > } > /* error out, no available DAC found */ > @@ -1787,7 +1789,8 @@ static int stac92xx_auto_fill_dac_nids(s > spec->multiout.dac_nids[2], > spec->multiout.dac_nids[3], > spec->multiout.dac_nids[4]); > - return 0; > + > + return line_outs; > } > > /* create volume control/switch for the given prefx type */ > @@ -2087,6 +2090,8 @@ static int stac92xx_parse_auto_config(st > static int stac92xx_parse_auto_config(struct hda_codec *codec, hda_nid_t dig_out, hda_nid_t dig_in) > { > struct sigmatel_spec *spec = codec->spec; > + int line_outs, *line_out_p; > + hda_nid_t *line_out_pins; > int err; > > if ((err = snd_hda_parse_pin_def_config(codec, > @@ -2096,11 +2101,32 @@ static int stac92xx_parse_auto_config(st > if (! spec->autocfg.line_outs) > return 0; /* can't find valid pin config */ > > - if ((err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg)) < 0) > + /* if we have multiple headphones and no line-outs, > + * let's set up headphones as primary outputs and allow > + * surround outputs > + */ > + if (spec->autocfg.line_out_type == AUTO_PIN_SPEAKER_OUT && > + spec->autocfg.hp_outs > 1) { > + line_out_p = &spec->autocfg.hp_outs; > + line_out_pins = spec->autocfg.hp_pins; > + } else { > + line_out_p = &spec->autocfg.line_outs; > + line_out_pins = spec->autocfg.line_out_pins; > + } > + line_outs = *line_out_p; > + err = stac92xx_add_dyn_out_pins(codec, &spec->autocfg, > + line_outs, line_out_pins); > + if (err < 0) > return err; > - if (spec->multiout.num_dacs == 0) > - if ((err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg)) < 0) > + line_outs = err; > + if (spec->multiout.num_dacs == 0) { > + err = stac92xx_auto_fill_dac_nids(codec, &spec->autocfg, > + line_outs, line_out_pins); > + if (err < 0) > return err; > + line_outs = err; > + } > + *line_out_p = line_outs; /* store back to autocfg */ > > err = stac92xx_auto_create_multi_out_ctls(codec, &spec->autocfg); > The stac92xx_auto_create_multi_out_ctls() create controls according to cfg->line_outs. This patch seems to leave the cfg->line_outs unchanged. It will be 1 . So I think that we need to modify stac92xx_auto_create_multi_out_ctls(),let it to use the right line_outs. Thanks! _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel