Loading Documentation/sound/alsa/HD-Audio-Models.txt +1 −0 Original line number Diff line number Diff line Loading @@ -349,6 +349,7 @@ STAC92HD83* ref Reference board mic-ref Reference board with power management for ports dell-s14 Dell laptop dell-vostro-3500 Dell Vostro 3500 laptop hp HP laptops with (inverted) mute-LED hp-dv7-4000 HP dv-7 4000 auto BIOS setup (default) Loading sound/core/vmaster.c +14 −4 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ struct link_slave { struct link_ctl_info info; int vals[2]; /* current values */ unsigned int flags; struct snd_kcontrol *kctl; /* original kcontrol pointer */ struct snd_kcontrol slave; /* the copy of original control entry */ }; Loading Loading @@ -252,6 +253,7 @@ int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, slave->count * sizeof(*slave->vd), GFP_KERNEL); if (!srec) return -ENOMEM; srec->kctl = slave; srec->slave = *slave; memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd)); srec->master = master_link; Loading Loading @@ -333,10 +335,18 @@ static int master_put(struct snd_kcontrol *kcontrol, static void master_free(struct snd_kcontrol *kcontrol) { struct link_master *master = snd_kcontrol_chip(kcontrol); struct link_slave *slave; list_for_each_entry(slave, &master->slaves, list) slave->master = NULL; struct link_slave *slave, *n; /* free all slave links and retore the original slave kctls */ list_for_each_entry_safe(slave, n, &master->slaves, list) { struct snd_kcontrol *sctl = slave->kctl; struct list_head olist = sctl->list; memcpy(sctl, &slave->slave, sizeof(*sctl)); memcpy(sctl->vd, slave->slave.vd, sctl->count * sizeof(*sctl->vd)); sctl->list = olist; /* keep the current linked-list */ kfree(slave); } kfree(master); } Loading sound/pci/hda/hda_codec.c +43 −21 Original line number Diff line number Diff line Loading @@ -2331,6 +2331,39 @@ int snd_hda_codec_reset(struct hda_codec *codec) return 0; } typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *); /* apply the function to all matching slave ctls in the mixer list */ static int map_slaves(struct hda_codec *codec, const char * const *slaves, map_slave_func_t func, void *data) { struct hda_nid_item *items; const char * const *s; int i, err; items = codec->mixers.list; for (i = 0; i < codec->mixers.used; i++) { struct snd_kcontrol *sctl = items[i].kctl; if (!sctl || !sctl->id.name || sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) continue; for (s = slaves; *s; s++) { if (!strcmp(sctl->id.name, *s)) { err = func(data, sctl); if (err) return err; break; } } } return 0; } static int check_slave_present(void *data, struct snd_kcontrol *sctl) { return 1; } /** * snd_hda_add_vmaster - create a virtual master control and add slaves * @codec: HD-audio codec Loading @@ -2351,12 +2384,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, unsigned int *tlv, const char * const *slaves) { struct snd_kcontrol *kctl; const char * const *s; int err; for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) ; if (!*s) { err = map_slaves(codec, slaves, check_slave_present, NULL); if (err != 1) { snd_printdd("No slave found for %s\n", name); return 0; } Loading @@ -2367,23 +2398,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, if (err < 0) return err; for (s = slaves; *s; s++) { struct snd_kcontrol *sctl; int i = 0; for (;;) { sctl = _snd_hda_find_mixer_ctl(codec, *s, i); if (!sctl) { if (!i) snd_printdd("Cannot find slave %s, " "skipped\n", *s); break; } err = snd_ctl_add_slave(kctl, sctl); err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave, kctl); if (err < 0) return err; i++; } } return 0; } EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); Loading Loading @@ -4752,6 +4770,7 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, memset(sequences_hp, 0, sizeof(sequences_hp)); assoc_line_out = 0; codec->ignore_misc_bit = true; end_nid = codec->start_nid + codec->num_nodes; for (nid = codec->start_nid; nid < end_nid; nid++) { unsigned int wid_caps = get_wcaps(codec, nid); Loading @@ -4767,6 +4786,9 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, continue; def_conf = snd_hda_codec_get_pincfg(codec, nid); if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & AC_DEFCFG_MISC_NO_PRESENCE)) codec->ignore_misc_bit = false; conn = get_defcfg_connect(def_conf); if (conn == AC_JACK_PORT_NONE) continue; Loading sound/pci/hda/hda_codec.h +1 −0 Original line number Diff line number Diff line Loading @@ -854,6 +854,7 @@ struct hda_codec { unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ unsigned int pins_shutup:1; /* pins are shut up */ unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ #ifdef CONFIG_SND_HDA_POWER_SAVE unsigned int power_on :1; /* current (global) power-state */ unsigned int power_transition :1; /* power-state in transition */ Loading sound/pci/hda/hda_local.h +9 −7 Original line number Diff line number Diff line Loading @@ -510,13 +510,15 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && /* disable MISC_NO_PRESENCE check because it may break too * many devices */ /*(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & AC_DEFCFG_MISC_NO_PRESENCE)) &&*/ (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT)) return false; if (!codec->ignore_misc_bit && (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & AC_DEFCFG_MISC_NO_PRESENCE)) return false; if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) return false; return true; } /* flags for hda_nid_item */ Loading Loading
Documentation/sound/alsa/HD-Audio-Models.txt +1 −0 Original line number Diff line number Diff line Loading @@ -349,6 +349,7 @@ STAC92HD83* ref Reference board mic-ref Reference board with power management for ports dell-s14 Dell laptop dell-vostro-3500 Dell Vostro 3500 laptop hp HP laptops with (inverted) mute-LED hp-dv7-4000 HP dv-7 4000 auto BIOS setup (default) Loading
sound/core/vmaster.c +14 −4 Original line number Diff line number Diff line Loading @@ -52,6 +52,7 @@ struct link_slave { struct link_ctl_info info; int vals[2]; /* current values */ unsigned int flags; struct snd_kcontrol *kctl; /* original kcontrol pointer */ struct snd_kcontrol slave; /* the copy of original control entry */ }; Loading Loading @@ -252,6 +253,7 @@ int _snd_ctl_add_slave(struct snd_kcontrol *master, struct snd_kcontrol *slave, slave->count * sizeof(*slave->vd), GFP_KERNEL); if (!srec) return -ENOMEM; srec->kctl = slave; srec->slave = *slave; memcpy(srec->slave.vd, slave->vd, slave->count * sizeof(*slave->vd)); srec->master = master_link; Loading Loading @@ -333,10 +335,18 @@ static int master_put(struct snd_kcontrol *kcontrol, static void master_free(struct snd_kcontrol *kcontrol) { struct link_master *master = snd_kcontrol_chip(kcontrol); struct link_slave *slave; list_for_each_entry(slave, &master->slaves, list) slave->master = NULL; struct link_slave *slave, *n; /* free all slave links and retore the original slave kctls */ list_for_each_entry_safe(slave, n, &master->slaves, list) { struct snd_kcontrol *sctl = slave->kctl; struct list_head olist = sctl->list; memcpy(sctl, &slave->slave, sizeof(*sctl)); memcpy(sctl->vd, slave->slave.vd, sctl->count * sizeof(*sctl->vd)); sctl->list = olist; /* keep the current linked-list */ kfree(slave); } kfree(master); } Loading
sound/pci/hda/hda_codec.c +43 −21 Original line number Diff line number Diff line Loading @@ -2331,6 +2331,39 @@ int snd_hda_codec_reset(struct hda_codec *codec) return 0; } typedef int (*map_slave_func_t)(void *, struct snd_kcontrol *); /* apply the function to all matching slave ctls in the mixer list */ static int map_slaves(struct hda_codec *codec, const char * const *slaves, map_slave_func_t func, void *data) { struct hda_nid_item *items; const char * const *s; int i, err; items = codec->mixers.list; for (i = 0; i < codec->mixers.used; i++) { struct snd_kcontrol *sctl = items[i].kctl; if (!sctl || !sctl->id.name || sctl->id.iface != SNDRV_CTL_ELEM_IFACE_MIXER) continue; for (s = slaves; *s; s++) { if (!strcmp(sctl->id.name, *s)) { err = func(data, sctl); if (err) return err; break; } } } return 0; } static int check_slave_present(void *data, struct snd_kcontrol *sctl) { return 1; } /** * snd_hda_add_vmaster - create a virtual master control and add slaves * @codec: HD-audio codec Loading @@ -2351,12 +2384,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, unsigned int *tlv, const char * const *slaves) { struct snd_kcontrol *kctl; const char * const *s; int err; for (s = slaves; *s && !snd_hda_find_mixer_ctl(codec, *s); s++) ; if (!*s) { err = map_slaves(codec, slaves, check_slave_present, NULL); if (err != 1) { snd_printdd("No slave found for %s\n", name); return 0; } Loading @@ -2367,23 +2398,10 @@ int snd_hda_add_vmaster(struct hda_codec *codec, char *name, if (err < 0) return err; for (s = slaves; *s; s++) { struct snd_kcontrol *sctl; int i = 0; for (;;) { sctl = _snd_hda_find_mixer_ctl(codec, *s, i); if (!sctl) { if (!i) snd_printdd("Cannot find slave %s, " "skipped\n", *s); break; } err = snd_ctl_add_slave(kctl, sctl); err = map_slaves(codec, slaves, (map_slave_func_t)snd_ctl_add_slave, kctl); if (err < 0) return err; i++; } } return 0; } EXPORT_SYMBOL_HDA(snd_hda_add_vmaster); Loading Loading @@ -4752,6 +4770,7 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, memset(sequences_hp, 0, sizeof(sequences_hp)); assoc_line_out = 0; codec->ignore_misc_bit = true; end_nid = codec->start_nid + codec->num_nodes; for (nid = codec->start_nid; nid < end_nid; nid++) { unsigned int wid_caps = get_wcaps(codec, nid); Loading @@ -4767,6 +4786,9 @@ int snd_hda_parse_pin_defcfg(struct hda_codec *codec, continue; def_conf = snd_hda_codec_get_pincfg(codec, nid); if (!(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & AC_DEFCFG_MISC_NO_PRESENCE)) codec->ignore_misc_bit = false; conn = get_defcfg_connect(def_conf); if (conn == AC_JACK_PORT_NONE) continue; Loading
sound/pci/hda/hda_codec.h +1 −0 Original line number Diff line number Diff line Loading @@ -854,6 +854,7 @@ struct hda_codec { unsigned int no_sticky_stream:1; /* no sticky-PCM stream assignment */ unsigned int pins_shutup:1; /* pins are shut up */ unsigned int no_trigger_sense:1; /* don't trigger at pin-sensing */ unsigned int ignore_misc_bit:1; /* ignore MISC_NO_PRESENCE bit */ #ifdef CONFIG_SND_HDA_POWER_SAVE unsigned int power_on :1; /* current (global) power-state */ unsigned int power_transition :1; /* power-state in transition */ Loading
sound/pci/hda/hda_local.h +9 −7 Original line number Diff line number Diff line Loading @@ -510,13 +510,15 @@ int snd_hda_jack_detect(struct hda_codec *codec, hda_nid_t nid); static inline bool is_jack_detectable(struct hda_codec *codec, hda_nid_t nid) { return (snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT) && /* disable MISC_NO_PRESENCE check because it may break too * many devices */ /*(get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid) & AC_DEFCFG_MISC_NO_PRESENCE)) &&*/ (get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP); if (!(snd_hda_query_pin_caps(codec, nid) & AC_PINCAP_PRES_DETECT)) return false; if (!codec->ignore_misc_bit && (get_defcfg_misc(snd_hda_codec_get_pincfg(codec, nid)) & AC_DEFCFG_MISC_NO_PRESENCE)) return false; if (!(get_wcaps(codec, nid) & AC_WCAP_UNSOL_CAP)) return false; return true; } /* flags for hda_nid_item */ Loading