aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2014-09-01 04:07:04 -0400
committerTakashi Iwai <tiwai@suse.de>2014-09-03 10:39:29 -0400
commitd89c6c0c91af0344b52dd21ca48dd29821fee677 (patch)
tree5d8a3b5c2e2c5aaf1c2c790386187b63c92c9825
parentaec856d0a8308cb34360c88a73b517c3a1fce170 (diff)
ALSA: hda - Add TLV_DB_SCALE_MUTE bit for relevant controls
The DACs on Sigmatel/IDT codecs do mute at the lowest volume level, and in the earlier drivers, we passed TLV_DB_SCALE_MUTE bit for each volume control element like Speaker and Headphone as well as Master. Along with the translation to the generic parser, however, the TLV bit was lost for the slave controls (e.g. Speaker) but set only to Master. In theory this should have sufficed, but apps, particularly PA, do care the slave volume bits, so we seem to see a regression in the volume controls. This patch adds a flag to hda_gen_spec to specify the DAC mute feature, and adds the TLV bit properly for all relevant volume controls. Also, the TLV bit for vmaster is set in hda_generic.c, so that we can get rid of all tricks from the codec driver side. As the similar hack is applied to Conexant 5051 stuff, we can get rid of it as well. BugLink: https://bugs.launchpad.net/bugs/1357928 Signed-off-by: Takashi Iwai <tiwai@suse.de>
-rw-r--r--sound/pci/hda/hda_generic.c9
-rw-r--r--sound/pci/hda/hda_generic.h1
-rw-r--r--sound/pci/hda/patch_conexant.c8
-rw-r--r--sound/pci/hda/patch_sigmatel.c5
4 files changed, 12 insertions, 11 deletions
diff --git a/sound/pci/hda/hda_generic.c b/sound/pci/hda/hda_generic.c
index b956449ddada..95121e818b4d 100644
--- a/sound/pci/hda/hda_generic.c
+++ b/sound/pci/hda/hda_generic.c
@@ -31,6 +31,7 @@
31#include <linux/module.h> 31#include <linux/module.h>
32#include <sound/core.h> 32#include <sound/core.h>
33#include <sound/jack.h> 33#include <sound/jack.h>
34#include <sound/tlv.h>
34#include "hda_codec.h" 35#include "hda_codec.h"
35#include "hda_local.h" 36#include "hda_local.h"
36#include "hda_auto_parser.h" 37#include "hda_auto_parser.h"
@@ -1105,6 +1106,7 @@ enum {
1105 */ 1106 */
1106static int assign_out_path_ctls(struct hda_codec *codec, struct nid_path *path) 1107static int assign_out_path_ctls(struct hda_codec *codec, struct nid_path *path)
1107{ 1108{
1109 struct hda_gen_spec *spec = codec->spec;
1108 hda_nid_t nid; 1110 hda_nid_t nid;
1109 unsigned int val; 1111 unsigned int val;
1110 int badness = 0; 1112 int badness = 0;
@@ -1119,6 +1121,8 @@ static int assign_out_path_ctls(struct hda_codec *codec, struct nid_path *path)
1119 nid = look_for_out_vol_nid(codec, path); 1121 nid = look_for_out_vol_nid(codec, path);
1120 if (nid) { 1122 if (nid) {
1121 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT); 1123 val = HDA_COMPOSE_AMP_VAL(nid, 3, 0, HDA_OUTPUT);
1124 if (spec->dac_min_mute)
1125 val |= HDA_AMP_VAL_MIN_MUTE;
1122 if (is_ctl_used(codec, val, NID_PATH_VOL_CTL)) 1126 if (is_ctl_used(codec, val, NID_PATH_VOL_CTL))
1123 badness += BAD_SHARED_VOL; 1127 badness += BAD_SHARED_VOL;
1124 else 1128 else
@@ -1880,9 +1884,12 @@ static int parse_output_paths(struct hda_codec *codec)
1880 path = snd_hda_get_path_from_idx(codec, spec->out_paths[0]); 1884 path = snd_hda_get_path_from_idx(codec, spec->out_paths[0]);
1881 if (path) 1885 if (path)
1882 spec->vmaster_nid = look_for_out_vol_nid(codec, path); 1886 spec->vmaster_nid = look_for_out_vol_nid(codec, path);
1883 if (spec->vmaster_nid) 1887 if (spec->vmaster_nid) {
1884 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, 1888 snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid,
1885 HDA_OUTPUT, spec->vmaster_tlv); 1889 HDA_OUTPUT, spec->vmaster_tlv);
1890 if (spec->dac_min_mute)
1891 spec->vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
1892 }
1886 } 1893 }
1887 1894
1888 /* set initial pinctl targets */ 1895 /* set initial pinctl targets */
diff --git a/sound/pci/hda/hda_generic.h b/sound/pci/hda/hda_generic.h
index bb2dea743986..3f95f1d3f1f8 100644
--- a/sound/pci/hda/hda_generic.h
+++ b/sound/pci/hda/hda_generic.h
@@ -231,6 +231,7 @@ struct hda_gen_spec {
231 unsigned int add_stereo_mix_input:1; /* add aamix as a capture src */ 231 unsigned int add_stereo_mix_input:1; /* add aamix as a capture src */
232 unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */ 232 unsigned int add_jack_modes:1; /* add i/o jack mode enum ctls */
233 unsigned int power_down_unused:1; /* power down unused widgets */ 233 unsigned int power_down_unused:1; /* power down unused widgets */
234 unsigned int dac_min_mute:1; /* minimal = mute for DACs */
234 235
235 /* other internal flags */ 236 /* other internal flags */
236 unsigned int no_analog:1; /* digital I/O only */ 237 unsigned int no_analog:1; /* digital I/O only */
diff --git a/sound/pci/hda/patch_conexant.c b/sound/pci/hda/patch_conexant.c
index 6f2fa838b635..c0b03c112187 100644
--- a/sound/pci/hda/patch_conexant.c
+++ b/sound/pci/hda/patch_conexant.c
@@ -26,7 +26,6 @@
26#include <linux/module.h> 26#include <linux/module.h>
27#include <sound/core.h> 27#include <sound/core.h>
28#include <sound/jack.h> 28#include <sound/jack.h>
29#include <sound/tlv.h>
30 29
31#include "hda_codec.h" 30#include "hda_codec.h"
32#include "hda_local.h" 31#include "hda_local.h"
@@ -779,6 +778,7 @@ static const struct hda_model_fixup cxt5066_fixup_models[] = {
779 */ 778 */
780static void add_cx5051_fake_mutes(struct hda_codec *codec) 779static void add_cx5051_fake_mutes(struct hda_codec *codec)
781{ 780{
781 struct conexant_spec *spec = codec->spec;
782 static hda_nid_t out_nids[] = { 782 static hda_nid_t out_nids[] = {
783 0x10, 0x11, 0 783 0x10, 0x11, 0
784 }; 784 };
@@ -788,6 +788,7 @@ static void add_cx5051_fake_mutes(struct hda_codec *codec)
788 snd_hda_override_amp_caps(codec, *p, HDA_OUTPUT, 788 snd_hda_override_amp_caps(codec, *p, HDA_OUTPUT,
789 AC_AMPCAP_MIN_MUTE | 789 AC_AMPCAP_MIN_MUTE |
790 query_amp_caps(codec, *p, HDA_OUTPUT)); 790 query_amp_caps(codec, *p, HDA_OUTPUT));
791 spec->gen.dac_min_mute = true;
791} 792}
792 793
793static int patch_conexant_auto(struct hda_codec *codec) 794static int patch_conexant_auto(struct hda_codec *codec)
@@ -860,11 +861,6 @@ static int patch_conexant_auto(struct hda_codec *codec)
860 if (err < 0) 861 if (err < 0)
861 goto error; 862 goto error;
862 863
863 if (codec->vendor_id == 0x14f15051) {
864 /* minimum value is actually mute */
865 spec->gen.vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
866 }
867
868 codec->patch_ops = cx_auto_patch_ops; 864 codec->patch_ops = cx_auto_patch_ops;
869 865
870 /* Some laptops with Conexant chips show stalls in S3 resume, 866 /* Some laptops with Conexant chips show stalls in S3 resume,
diff --git a/sound/pci/hda/patch_sigmatel.c b/sound/pci/hda/patch_sigmatel.c
index ea823e1100da..f26ec04a29b5 100644
--- a/sound/pci/hda/patch_sigmatel.c
+++ b/sound/pci/hda/patch_sigmatel.c
@@ -32,7 +32,6 @@
32#include <linux/module.h> 32#include <linux/module.h>
33#include <sound/core.h> 33#include <sound/core.h>
34#include <sound/jack.h> 34#include <sound/jack.h>
35#include <sound/tlv.h>
36#include "hda_codec.h" 35#include "hda_codec.h"
37#include "hda_local.h" 36#include "hda_local.h"
38#include "hda_auto_parser.h" 37#include "hda_auto_parser.h"
@@ -4227,9 +4226,6 @@ static int stac_parse_auto_config(struct hda_codec *codec)
4227 if (err < 0) 4226 if (err < 0)
4228 return err; 4227 return err;
4229 4228
4230 /* minimum value is actually mute */
4231 spec->gen.vmaster_tlv[3] |= TLV_DB_SCALE_MUTE;
4232
4233 /* setup analog beep controls */ 4229 /* setup analog beep controls */
4234 if (spec->anabeep_nid > 0) { 4230 if (spec->anabeep_nid > 0) {
4235 err = stac_auto_create_beep_ctls(codec, 4231 err = stac_auto_create_beep_ctls(codec,
@@ -4413,6 +4409,7 @@ static int alloc_stac_spec(struct hda_codec *codec)
4413 snd_hda_gen_spec_init(&spec->gen); 4409 snd_hda_gen_spec_init(&spec->gen);
4414 codec->spec = spec; 4410 codec->spec = spec;
4415 codec->no_trigger_sense = 1; /* seems common with STAC/IDT codecs */ 4411 codec->no_trigger_sense = 1; /* seems common with STAC/IDT codecs */
4412 spec->gen.dac_min_mute = true;
4416 return 0; 4413 return 0;
4417} 4414}
4418 4415