At Wed, 7 Oct 2009 15:34:59 -0500 (CDT), manoj.iyer@xxxxxxxxxxxxx wrote: > > > Takashi San, > > Like I reported earlier, the patch you mailed me (See patch below) breaks > sound on Toshiba NB200/205 again, even with my quirk. This can't be. The patch I sent changes only the auto-parser, so with the quirk it must be skipped. > Any chance that we > can work on getting this fixed? If you point me in the right direction I > can dig into this some, also, mainline > http://kernel.ubuntu.com/~kernel-ppa/mainline/v2.6.32-rc1/ does not work. > iirc, you mentioned that this patch made it into mainline as well. Try 2.6.32-rc3 as is. If it doesn't work, please give alsa-info.sh output back. thanks, Takashi > > Thanks > > On Thu, 1 Oct 2009, Takashi Iwai wrote: > > > At Thu, 01 Oct 2009 10:26:05 +0200, > > I wrote: > >> > >> At Thu, 1 Oct 2009 02:11:35 -0500 (CDT), > >> manoj.iyer@xxxxxxxxxxxxx wrote: > >>> > >>>> 2.6.31.x is way too old for testing the new stuff :) > >>>> Any chance to test 2.6.32-rc1? > >>> > >>> http://kernel.ubuntu.com/~kernel-ppa/mainline/v2.6.32-rc1/ > >>> > >>> I tried the 2.6.32-rc1 today, and sound does not work for me on the NB200. > >> > >> OK, thanks for checking. > >> After looking at the code a bit more deeply, it turned out that the > >> BIOS auto-parser doesn't work with this particular configuration (the > >> speaker with mono pin 0x17). > >> > >> I'm going to fix it later, but I applied your patch as the quick fix > >> for the time being. > > > > Could you try the patch below with model=auto? > > This will make the auto-parser working, hopefully. > > > > > > thanks, > > > > Takashi > > > > --- > > diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c > > index 87da5e8..7810d3d 100644 > > --- a/sound/pci/hda/patch_realtek.c > > +++ b/sound/pci/hda/patch_realtek.c > > @@ -17146,70 +17146,145 @@ static struct alc_config_preset alc662_presets[] = { > > * BIOS auto configuration > > */ > > > > +/* convert from MIX nid to DAC */ > > +static inline hda_nid_t alc662_mix_to_dac(hda_nid_t nid) > > +{ > > + if (nid == 0x0f) > > + return 0x02; > > + else if (nid >= 0x0c && nid <= 0x0e) > > + return nid - 0x0c + 0x02; > > + else > > + return 0; > > +} > > + > > +/* get MIX nid connected to the given pin targeted to DAC */ > > +static hda_nid_t alc662_dac_to_mix(struct hda_codec *codec, hda_nid_t pin, > > + hda_nid_t dac) > > +{ > > + hda_nid_t mix[4]; > > + int i, num; > > + > > + num = snd_hda_get_connections(codec, pin, mix, ARRAY_SIZE(mix)); > > + for (i = 0; i < num; i++) { > > + if (alc662_mix_to_dac(mix[i]) == dac) > > + return mix[i]; > > + } > > + return 0; > > +} > > + > > +/* look for an empty DAC slot */ > > +static hda_nid_t alc662_look_for_dac(struct hda_codec *codec, hda_nid_t pin) > > +{ > > + struct alc_spec *spec = codec->spec; > > + hda_nid_t srcs[5]; > > + int i, j, num; > > + > > + num = snd_hda_get_connections(codec, pin, srcs, ARRAY_SIZE(srcs)); > > + if (num < 0) > > + return 0; > > + for (i = 0; i < num; i++) { > > + hda_nid_t nid = alc662_mix_to_dac(srcs[i]); > > + if (!nid) > > + continue; > > + for (j = 0; j < spec->multiout.num_dacs; j++) > > + if (spec->multiout.dac_nids[j] == nid) > > + break; > > + if (j >= spec->multiout.num_dacs) > > + return nid; > > + } > > + return 0; > > +} > > + > > +/* fill in the dac_nids table from the parsed pin configuration */ > > +static int alc662_auto_fill_dac_nids(struct hda_codec *codec, > > + const struct auto_pin_cfg *cfg) > > +{ > > + struct alc_spec *spec = codec->spec; > > + int i; > > + hda_nid_t dac; > > + > > + spec->multiout.dac_nids = spec->private_dac_nids; > > + for (i = 0; i < cfg->line_outs; i++) { > > + dac = alc662_look_for_dac(codec, cfg->line_out_pins[i]); > > + if (!dac) > > + continue; > > + spec->multiout.dac_nids[spec->multiout.num_dacs++] = dac; > > + } > > + return 0; > > +} > > + > > +static int alc662_add_vol_ctl(struct alc_spec *spec, const char *pfx, > > + hda_nid_t nid, unsigned int chs) > > +{ > > + char name[32]; > > + sprintf(name, "%s Playback Volume", pfx); > > + return add_control(spec, ALC_CTL_WIDGET_VOL, name, > > + HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT)); > > +} > > + > > +static int alc662_add_sw_ctl(struct alc_spec *spec, const char *pfx, > > + hda_nid_t nid, unsigned int chs) > > +{ > > + char name[32]; > > + sprintf(name, "%s Playback Switch", pfx); > > + return add_control(spec, ALC_CTL_WIDGET_MUTE, name, > > + HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_INPUT)); > > +} > > + > > +#define alc662_add_stereo_vol(spec, pfx, nid) \ > > + alc662_add_vol_ctl(spec, pfx, nid, 3) > > +#define alc662_add_stereo_sw(spec, pfx, nid) \ > > + alc662_add_sw_ctl(spec, pfx, nid, 3) > > + > > /* add playback controls from the parsed DAC table */ > > -static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, > > +static int alc662_auto_create_multi_out_ctls(struct hda_codec *codec, > > const struct auto_pin_cfg *cfg) > > { > > - char name[32]; > > + struct alc_spec *spec = codec->spec; > > static const char *chname[4] = { > > "Front", "Surround", NULL /*CLFE*/, "Side" > > }; > > - hda_nid_t nid; > > + hda_nid_t nid, mix; > > int i, err; > > > > for (i = 0; i < cfg->line_outs; i++) { > > - if (!spec->multiout.dac_nids[i]) > > + nid = spec->multiout.dac_nids[i]; > > + if (!nid) > > + continue; > > + mix = alc662_dac_to_mix(codec, cfg->line_out_pins[i], nid); > > + if (!mix) > > continue; > > - nid = alc880_idx_to_dac(i); > > if (i == 2) { > > /* Center/LFE */ > > - err = add_control(spec, ALC_CTL_WIDGET_VOL, > > - "Center Playback Volume", > > - HDA_COMPOSE_AMP_VAL(nid, 1, 0, > > - HDA_OUTPUT)); > > + err = alc662_add_vol_ctl(spec, "Center", nid, 1); > > if (err < 0) > > return err; > > - err = add_control(spec, ALC_CTL_WIDGET_VOL, > > - "LFE Playback Volume", > > - HDA_COMPOSE_AMP_VAL(nid, 2, 0, > > - HDA_OUTPUT)); > > + err = alc662_add_vol_ctl(spec, "LFE", nid, 2); > > if (err < 0) > > return err; > > - err = add_control(spec, ALC_CTL_WIDGET_MUTE, > > - "Center Playback Switch", > > - HDA_COMPOSE_AMP_VAL(0x0e, 1, 0, > > - HDA_INPUT)); > > + err = alc662_add_sw_ctl(spec, "Center", mix, 1); > > if (err < 0) > > return err; > > - err = add_control(spec, ALC_CTL_WIDGET_MUTE, > > - "LFE Playback Switch", > > - HDA_COMPOSE_AMP_VAL(0x0e, 2, 0, > > - HDA_INPUT)); > > + err = alc662_add_sw_ctl(spec, "LFE", mix, 2); > > if (err < 0) > > return err; > > } else { > > const char *pfx; > > if (cfg->line_outs == 1 && > > cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) { > > - if (!cfg->hp_pins) > > + if (cfg->hp_outs) > > pfx = "Speaker"; > > else > > pfx = "PCM"; > > } else > > pfx = chname[i]; > > - sprintf(name, "%s Playback Volume", pfx); > > - err = add_control(spec, ALC_CTL_WIDGET_VOL, name, > > - HDA_COMPOSE_AMP_VAL(nid, 3, 0, > > - HDA_OUTPUT)); > > + err = alc662_add_vol_ctl(spec, pfx, nid, 3); > > if (err < 0) > > return err; > > if (cfg->line_outs == 1 && > > cfg->line_out_type == AUTO_PIN_SPEAKER_OUT) > > pfx = "Speaker"; > > - sprintf(name, "%s Playback Switch", pfx); > > - err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, > > - HDA_COMPOSE_AMP_VAL(alc880_idx_to_mixer(i), > > - 3, 0, HDA_INPUT)); > > + err = alc662_add_sw_ctl(spec, pfx, mix, 3); > > if (err < 0) > > return err; > > } > > @@ -17218,54 +17293,38 @@ static int alc662_auto_create_multi_out_ctls(struct alc_spec *spec, > > } > > > > /* add playback controls for speaker and HP outputs */ > > -static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, > > +/* return DAC nid if any new DAC is assigned */ > > +static int alc662_auto_create_extra_out(struct hda_codec *codec, hda_nid_t pin, > > const char *pfx) > > { > > - hda_nid_t nid; > > + struct alc_spec *spec = codec->spec; > > + hda_nid_t nid, mix; > > int err; > > - char name[32]; > > > > if (!pin) > > return 0; > > - > > - if (pin == 0x17) { > > - /* ALC663 has a mono output pin on 0x17 */ > > + nid = alc662_look_for_dac(codec, pin); > > + if (!nid) { > > + char name[32]; > > + /* the corresponding DAC is already occupied */ > > + if (!(get_wcaps(codec, pin) & AC_WCAP_OUT_AMP)) > > + return 0; /* no way */ > > + /* create a switch only */ > > sprintf(name, "%s Playback Switch", pfx); > > - err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, > > - HDA_COMPOSE_AMP_VAL(pin, 2, 0, HDA_OUTPUT)); > > - return err; > > + return add_control(spec, ALC_CTL_WIDGET_MUTE, name, > > + HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); > > } > > > > - if (alc880_is_fixed_pin(pin)) { > > - nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); > > - /* printk(KERN_DEBUG "DAC nid=%x\n",nid); */ > > - /* specify the DAC as the extra output */ > > - if (!spec->multiout.hp_nid) > > - spec->multiout.hp_nid = nid; > > - else > > - spec->multiout.extra_out_nid[0] = nid; > > - /* control HP volume/switch on the output mixer amp */ > > - nid = alc880_idx_to_dac(alc880_fixed_pin_idx(pin)); > > - sprintf(name, "%s Playback Volume", pfx); > > - err = add_control(spec, ALC_CTL_WIDGET_VOL, name, > > - HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT)); > > - if (err < 0) > > - return err; > > - sprintf(name, "%s Playback Switch", pfx); > > - err = add_control(spec, ALC_CTL_BIND_MUTE, name, > > - HDA_COMPOSE_AMP_VAL(nid, 3, 2, HDA_INPUT)); > > - if (err < 0) > > - return err; > > - } else if (alc880_is_multi_pin(pin)) { > > - /* set manual connection */ > > - /* we have only a switch on HP-out PIN */ > > - sprintf(name, "%s Playback Switch", pfx); > > - err = add_control(spec, ALC_CTL_WIDGET_MUTE, name, > > - HDA_COMPOSE_AMP_VAL(pin, 3, 0, HDA_OUTPUT)); > > - if (err < 0) > > - return err; > > - } > > - return 0; > > + mix = alc662_dac_to_mix(codec, pin, nid); > > + if (!mix) > > + return 0; > > + err = alc662_add_vol_ctl(spec, pfx, nid, 3); > > + if (err < 0) > > + return err; > > + err = alc662_add_sw_ctl(spec, pfx, mix, 3); > > + if (err < 0) > > + return err; > > + return nid; > > } > > > > /* create playback/capture controls for input pins */ > > @@ -17274,30 +17333,35 @@ static int alc662_auto_create_extra_out(struct alc_spec *spec, hda_nid_t pin, > > > > static void alc662_auto_set_output_and_unmute(struct hda_codec *codec, > > hda_nid_t nid, int pin_type, > > - int dac_idx) > > + hda_nid_t dac) > > { > > + int i, num; > > + hda_nid_t srcs[4]; > > + > > alc_set_pin_output(codec, nid, pin_type); > > /* need the manual connection? */ > > - if (alc880_is_multi_pin(nid)) { > > - struct alc_spec *spec = codec->spec; > > - int idx = alc880_multi_pin_idx(nid); > > - snd_hda_codec_write(codec, alc880_idx_to_selector(idx), 0, > > - AC_VERB_SET_CONNECT_SEL, > > - alc880_dac_to_idx(spec->multiout.dac_nids[dac_idx])); > > + num = snd_hda_get_connections(codec, nid, srcs, ARRAY_SIZE(srcs)); > > + if (num <= 1) > > + return; > > + for (i = 0; i < num; i++) { > > + if (alc662_mix_to_dac(srcs[i]) != dac) > > + continue; > > + snd_hda_codec_write(codec, nid, 0, AC_VERB_SET_CONNECT_SEL, i); > > + return; > > } > > } > > > > static void alc662_auto_init_multi_out(struct hda_codec *codec) > > { > > struct alc_spec *spec = codec->spec; > > + int pin_type = get_pin_type(spec->autocfg.line_out_type); > > int i; > > > > for (i = 0; i <= HDA_SIDE; i++) { > > hda_nid_t nid = spec->autocfg.line_out_pins[i]; > > - int pin_type = get_pin_type(spec->autocfg.line_out_type); > > if (nid) > > alc662_auto_set_output_and_unmute(codec, nid, pin_type, > > - i); > > + spec->multiout.dac_nids[i]); > > } > > } > > > > @@ -17307,12 +17371,13 @@ static void alc662_auto_init_hp_out(struct hda_codec *codec) > > hda_nid_t pin; > > > > pin = spec->autocfg.hp_pins[0]; > > - if (pin) /* connect to front */ > > - /* use dac 0 */ > > - alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, 0); > > + if (pin) > > + alc662_auto_set_output_and_unmute(codec, pin, PIN_HP, > > + spec->multiout.hp_nid); > > pin = spec->autocfg.speaker_pins[0]; > > if (pin) > > - alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, 0); > > + alc662_auto_set_output_and_unmute(codec, pin, PIN_OUT, > > + spec->multiout.extra_out_nid[0]); > > } > > > > #define ALC662_PIN_CD_NID ALC880_PIN_CD_NID > > @@ -17350,21 +17415,25 @@ static int alc662_parse_auto_config(struct hda_codec *codec) > > if (!spec->autocfg.line_outs) > > return 0; /* can't find valid BIOS pin config */ > > > > - err = alc880_auto_fill_dac_nids(spec, &spec->autocfg); > > + err = alc662_auto_fill_dac_nids(codec, &spec->autocfg); > > if (err < 0) > > return err; > > - err = alc662_auto_create_multi_out_ctls(spec, &spec->autocfg); > > + err = alc662_auto_create_multi_out_ctls(codec, &spec->autocfg); > > if (err < 0) > > return err; > > - err = alc662_auto_create_extra_out(spec, > > + err = alc662_auto_create_extra_out(codec, > > spec->autocfg.speaker_pins[0], > > "Speaker"); > > if (err < 0) > > return err; > > - err = alc662_auto_create_extra_out(spec, spec->autocfg.hp_pins[0], > > + if (err) > > + spec->multiout.extra_out_nid[0] = err; > > + err = alc662_auto_create_extra_out(codec, spec->autocfg.hp_pins[0], > > "Headphone"); > > if (err < 0) > > return err; > > + if (err) > > + spec->multiout.hp_nid = err; > > err = alc662_auto_create_input_ctls(codec, &spec->autocfg); > > if (err < 0) > > return err; > > > _______________________________________________ Alsa-devel mailing list Alsa-devel@xxxxxxxxxxxxxxxx http://mailman.alsa-project.org/mailman/listinfo/alsa-devel