diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-01-10 10:53:55 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 11:29:54 -0500 |
commit | 2134ea4f37d36addbe86d4901f6c67a22a5db006 (patch) | |
tree | 804d187d5c46d71246db2d8919a59e2e7feef956 /sound/pci/hda/patch_analog.c | |
parent | 3b0a5f22d4649433a5842ffc7313803292e95718 (diff) |
[ALSA] hda-codec - Add virtual master controls
Add master controls using vmaster to codecs that have no real hardware
master volume registers.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
Diffstat (limited to 'sound/pci/hda/patch_analog.c')
-rw-r--r-- | sound/pci/hda/patch_analog.c | 69 |
1 files changed, 69 insertions, 0 deletions
diff --git a/sound/pci/hda/patch_analog.c b/sound/pci/hda/patch_analog.c index 6664a0688ef5..b0755407be9d 100644 --- a/sound/pci/hda/patch_analog.c +++ b/sound/pci/hda/patch_analog.c | |||
@@ -78,6 +78,11 @@ struct ad198x_spec { | |||
78 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 78 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
79 | struct hda_loopback_check loopback; | 79 | struct hda_loopback_check loopback; |
80 | #endif | 80 | #endif |
81 | /* for virtual master */ | ||
82 | hda_nid_t vmaster_nid; | ||
83 | u32 vmaster_tlv[4]; | ||
84 | const char **slave_vols; | ||
85 | const char **slave_sws; | ||
81 | }; | 86 | }; |
82 | 87 | ||
83 | /* | 88 | /* |
@@ -125,6 +130,28 @@ static int ad198x_init(struct hda_codec *codec) | |||
125 | return 0; | 130 | return 0; |
126 | } | 131 | } |
127 | 132 | ||
133 | static const char *ad_slave_vols[] = { | ||
134 | "Front Playback Volume", | ||
135 | "Surround Playback Volume", | ||
136 | "Center Playback Volume", | ||
137 | "LFE Playback Volume", | ||
138 | "Side Playback Volume", | ||
139 | "Headphone Playback Volume", | ||
140 | "Mono Playback Volume", | ||
141 | NULL | ||
142 | }; | ||
143 | |||
144 | static const char *ad_slave_sws[] = { | ||
145 | "Front Playback Switch", | ||
146 | "Surround Playback Switch", | ||
147 | "Center Playback Switch", | ||
148 | "LFE Playback Switch", | ||
149 | "Side Playback Switch", | ||
150 | "Headphone Playback Switch", | ||
151 | "Mono Playback Switch", | ||
152 | NULL | ||
153 | }; | ||
154 | |||
128 | static int ad198x_build_controls(struct hda_codec *codec) | 155 | static int ad198x_build_controls(struct hda_codec *codec) |
129 | { | 156 | { |
130 | struct ad198x_spec *spec = codec->spec; | 157 | struct ad198x_spec *spec = codec->spec; |
@@ -146,6 +173,27 @@ static int ad198x_build_controls(struct hda_codec *codec) | |||
146 | if (err < 0) | 173 | if (err < 0) |
147 | return err; | 174 | return err; |
148 | } | 175 | } |
176 | |||
177 | /* if we have no master control, let's create it */ | ||
178 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Volume")) { | ||
179 | snd_hda_set_vmaster_tlv(codec, spec->vmaster_nid, | ||
180 | HDA_OUTPUT, spec->vmaster_tlv); | ||
181 | err = snd_hda_add_vmaster(codec, "Master Playback Volume", | ||
182 | spec->vmaster_tlv, | ||
183 | (spec->slave_vols ? | ||
184 | spec->slave_vols : ad_slave_vols)); | ||
185 | if (err < 0) | ||
186 | return err; | ||
187 | } | ||
188 | if (!snd_hda_find_mixer_ctl(codec, "Master Playback Switch")) { | ||
189 | err = snd_hda_add_vmaster(codec, "Master Playback Switch", | ||
190 | NULL, | ||
191 | (spec->slave_sws ? | ||
192 | spec->slave_sws : ad_slave_sws)); | ||
193 | if (err < 0) | ||
194 | return err; | ||
195 | } | ||
196 | |||
149 | return 0; | 197 | return 0; |
150 | } | 198 | } |
151 | 199 | ||
@@ -899,6 +947,7 @@ static int patch_ad1986a(struct hda_codec *codec) | |||
899 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 947 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
900 | spec->loopback.amplist = ad1986a_loopbacks; | 948 | spec->loopback.amplist = ad1986a_loopbacks; |
901 | #endif | 949 | #endif |
950 | spec->vmaster_nid = 0x1b; | ||
902 | 951 | ||
903 | codec->patch_ops = ad198x_patch_ops; | 952 | codec->patch_ops = ad198x_patch_ops; |
904 | 953 | ||
@@ -1141,6 +1190,7 @@ static int patch_ad1983(struct hda_codec *codec) | |||
1141 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 1190 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
1142 | spec->loopback.amplist = ad1983_loopbacks; | 1191 | spec->loopback.amplist = ad1983_loopbacks; |
1143 | #endif | 1192 | #endif |
1193 | spec->vmaster_nid = 0x05; | ||
1144 | 1194 | ||
1145 | codec->patch_ops = ad198x_patch_ops; | 1195 | codec->patch_ops = ad198x_patch_ops; |
1146 | 1196 | ||
@@ -1537,6 +1587,7 @@ static int patch_ad1981(struct hda_codec *codec) | |||
1537 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 1587 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
1538 | spec->loopback.amplist = ad1981_loopbacks; | 1588 | spec->loopback.amplist = ad1981_loopbacks; |
1539 | #endif | 1589 | #endif |
1590 | spec->vmaster_nid = 0x05; | ||
1540 | 1591 | ||
1541 | codec->patch_ops = ad198x_patch_ops; | 1592 | codec->patch_ops = ad198x_patch_ops; |
1542 | 1593 | ||
@@ -2850,6 +2901,7 @@ static int patch_ad1988(struct hda_codec *codec) | |||
2850 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 2901 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
2851 | spec->loopback.amplist = ad1988_loopbacks; | 2902 | spec->loopback.amplist = ad1988_loopbacks; |
2852 | #endif | 2903 | #endif |
2904 | spec->vmaster_nid = 0x04; | ||
2853 | 2905 | ||
2854 | return 0; | 2906 | return 0; |
2855 | } | 2907 | } |
@@ -3016,6 +3068,19 @@ static struct hda_amp_list ad1884_loopbacks[] = { | |||
3016 | }; | 3068 | }; |
3017 | #endif | 3069 | #endif |
3018 | 3070 | ||
3071 | static const char *ad1884_slave_vols[] = { | ||
3072 | "PCM Playback Volume", | ||
3073 | "Mic Playback Volume", | ||
3074 | "Mono Playback Volume", | ||
3075 | "Front Mic Playback Volume", | ||
3076 | "Mic Playback Volume", | ||
3077 | "CD Playback Volume", | ||
3078 | "Internal Mic Playback Volume", | ||
3079 | "Docking Mic Playback Volume" | ||
3080 | "Beep Playback Volume", | ||
3081 | NULL | ||
3082 | }; | ||
3083 | |||
3019 | static int patch_ad1884(struct hda_codec *codec) | 3084 | static int patch_ad1884(struct hda_codec *codec) |
3020 | { | 3085 | { |
3021 | struct ad198x_spec *spec; | 3086 | struct ad198x_spec *spec; |
@@ -3043,6 +3108,9 @@ static int patch_ad1884(struct hda_codec *codec) | |||
3043 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3108 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3044 | spec->loopback.amplist = ad1884_loopbacks; | 3109 | spec->loopback.amplist = ad1884_loopbacks; |
3045 | #endif | 3110 | #endif |
3111 | spec->vmaster_nid = 0x04; | ||
3112 | /* we need to cover all playback volumes */ | ||
3113 | spec->slave_vols = ad1884_slave_vols; | ||
3046 | 3114 | ||
3047 | codec->patch_ops = ad198x_patch_ops; | 3115 | codec->patch_ops = ad198x_patch_ops; |
3048 | 3116 | ||
@@ -3485,6 +3553,7 @@ static int patch_ad1882(struct hda_codec *codec) | |||
3485 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 3553 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
3486 | spec->loopback.amplist = ad1882_loopbacks; | 3554 | spec->loopback.amplist = ad1882_loopbacks; |
3487 | #endif | 3555 | #endif |
3556 | spec->vmaster_nid = 0x04; | ||
3488 | 3557 | ||
3489 | codec->patch_ops = ad198x_patch_ops; | 3558 | codec->patch_ops = ad198x_patch_ops; |
3490 | 3559 | ||