]> git.ipfire.org Git - people/pmueller/ipfire-2.x.git/blob - src/patches/suse-2.6.27.25/patches.drivers/alsa-hda-stac-reduce-volume-scale
Reenabled linux-xen and xen-image build
[people/pmueller/ipfire-2.x.git] / src / patches / suse-2.6.27.25 / patches.drivers / alsa-hda-stac-reduce-volume-scale
1 From 7c7767ebe2fa847c91a0dd5551ca422aba359473 Mon Sep 17 00:00:00 2001
2 From: Takashi Iwai <tiwai@suse.de>
3 Date: Tue, 20 Jan 2009 15:28:38 +0100
4 Subject: ALSA: hda - Halve too large volume scales for STAC/IDT codecs
5 Patch-mainline:
6 References: bnc#466428
7
8 STAC/IDT codecs have often too large volume scales such as -96dB,
9 and exposing this as is results in too large scale in percentage
10 representation.
11
12 This patch adds the check of the volume scale and halves the
13 volume range if it's too large automatically.
14
15 Signed-off-by: Takashi Iwai <tiwai@suse.de>
16
17 ---
18 sound/pci/hda/patch_sigmatel.c | 41 +++++++++++++++++++++++++++++++++--------
19 1 file changed, 33 insertions(+), 8 deletions(-)
20
21 --- a/sound/pci/hda/patch_sigmatel.c
22 +++ b/sound/pci/hda/patch_sigmatel.c
23 @@ -155,6 +155,7 @@ struct sigmatel_spec {
24 unsigned int alt_switch: 1;
25 unsigned int hp_detect: 1;
26 unsigned int spdif_mute: 1;
27 + unsigned int check_volume_offset:1;
28
29 /* gpio lines */
30 unsigned int eapd_mask;
31 @@ -183,6 +184,8 @@ struct sigmatel_spec {
32 struct hda_multi_out multiout;
33 hda_nid_t dac_nids[5];
34
35 + int volume_offset;
36 +
37 /* capture */
38 hda_nid_t *adc_nids;
39 unsigned int num_adcs;
40 @@ -1310,6 +1313,8 @@ static int stac92xx_build_controls(struc
41 unsigned int vmaster_tlv[4];
42 snd_hda_set_vmaster_tlv(codec, spec->multiout.dac_nids[0],
43 HDA_OUTPUT, vmaster_tlv);
44 + /* correct volume offset */
45 + vmaster_tlv[2] += vmaster_tlv[3] * spec->volume_offset;
46 err = snd_hda_add_vmaster(codec, "Master Playback Volume",
47 vmaster_tlv, slave_vols);
48 if (err < 0)
49 @@ -2885,14 +2890,34 @@ static int stac92xx_auto_fill_dac_nids(s
50 }
51
52 /* create volume control/switch for the given prefx type */
53 -static int create_controls(struct sigmatel_spec *spec, const char *pfx, hda_nid_t nid, int chs)
54 +static int create_controls(struct hda_codec *codec, const char *pfx,
55 + hda_nid_t nid, int chs)
56 {
57 + struct sigmatel_spec *spec = codec->spec;
58 char name[32];
59 int err;
60
61 + if (!spec->check_volume_offset) {
62 + unsigned int caps, step, nums, db_scale;
63 + caps = query_amp_caps(codec, nid, HDA_OUTPUT);
64 + step = (caps & AC_AMPCAP_STEP_SIZE) >>
65 + AC_AMPCAP_STEP_SIZE_SHIFT;
66 + step = (step + 1) * 25; /* in .01dB unit */
67 + nums = (caps & AC_AMPCAP_NUM_STEPS) >>
68 + AC_AMPCAP_NUM_STEPS_SHIFT;
69 + db_scale = nums * step;
70 + /* if dB scale is over -64dB, and finer enough,
71 + * let's reduce it to half
72 + */
73 + if (db_scale > 6400 && nums >= 0x1f)
74 + spec->volume_offset = nums / 2;
75 + spec->check_volume_offset = 1;
76 + }
77 +
78 sprintf(name, "%s Playback Volume", pfx);
79 err = stac92xx_add_control(spec, STAC_CTL_WIDGET_VOL, name,
80 - HDA_COMPOSE_AMP_VAL(nid, chs, 0, HDA_OUTPUT));
81 + HDA_COMPOSE_AMP_VAL_OFS(nid, chs, 0, HDA_OUTPUT,
82 + spec->volume_offset));
83 if (err < 0)
84 return err;
85 sprintf(name, "%s Playback Switch", pfx);
86 @@ -2948,10 +2973,10 @@ static int stac92xx_auto_create_multi_ou
87
88 if (i == 2) {
89 /* Center/LFE */
90 - err = create_controls(spec, "Center", nid, 1);
91 + err = create_controls(codec, "Center", nid, 1);
92 if (err < 0)
93 return err;
94 - err = create_controls(spec, "LFE", nid, 2);
95 + err = create_controls(codec, "LFE", nid, 2);
96 if (err < 0)
97 return err;
98
99 @@ -2967,7 +2992,7 @@ static int stac92xx_auto_create_multi_ou
100 }
101
102 } else {
103 - err = create_controls(spec, chname[i], nid, 3);
104 + err = create_controls(codec, chname[i], nid, 3);
105 if (err < 0)
106 return err;
107 }
108 @@ -3074,13 +3099,13 @@ static int stac92xx_auto_create_hp_ctls(
109 static const char *pfxs[] = {
110 "Speaker", "External Speaker", "Speaker2",
111 };
112 - err = create_controls(spec, pfxs[i - old_num_dacs],
113 + err = create_controls(codec, pfxs[i - old_num_dacs],
114 spec->multiout.dac_nids[i], 3);
115 if (err < 0)
116 return err;
117 }
118 if (spec->multiout.hp_nid) {
119 - err = create_controls(spec, "Headphone",
120 + err = create_controls(codec, "Headphone",
121 spec->multiout.hp_nid, 3);
122 if (err < 0)
123 return err;
124 @@ -3670,7 +3695,7 @@ static int stac9200_auto_create_lfe_ctls
125 }
126
127 if (lfe_pin) {
128 - err = create_controls(spec, "LFE", lfe_pin, 1);
129 + err = create_controls(codec, "LFE", lfe_pin, 1);
130 if (err < 0)
131 return err;
132 }