aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/ac97/ac97_patch.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-02-18 06:23:13 -0500
committerTakashi Iwai <tiwai@suse.de>2008-04-24 06:00:11 -0400
commit4235a31784f59c9be5ff71534743c055091f9735 (patch)
tree87080055fed0c3f25a3c816c182a6db5739430b6 /sound/pci/ac97/ac97_patch.c
parent2eef1258e54722b1c4efac6e5760d2153f96c4b4 (diff)
[ALSA] intel8x0 - Add support of 8 channel sound
Added the support of 8 channel sound for codecs that are known to work. So far, only ALC850 is marked as a 8ch-support codec. This fix is a modified version of the patch on ALSA BTS#2097 by Martin Ellis: https://bugtrack.alsa-project.org/alsa-bug/view.php?id=2097 Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/ac97/ac97_patch.c')
-rw-r--r--sound/pci/ac97/ac97_patch.c46
1 files changed, 33 insertions, 13 deletions
diff --git a/sound/pci/ac97/ac97_patch.c b/sound/pci/ac97/ac97_patch.c
index 50c637e55ffa..39198e505b12 100644
--- a/sound/pci/ac97/ac97_patch.c
+++ b/sound/pci/ac97/ac97_patch.c
@@ -114,10 +114,9 @@ static int ac97_surround_jack_mode_put(struct snd_kcontrol *kcontrol, struct snd
114 114
115static int ac97_channel_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo) 115static int ac97_channel_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
116{ 116{
117 static const char *texts[] = { "2ch", "4ch", "6ch" }; 117 static const char *texts[] = { "2ch", "4ch", "6ch", "8ch" };
118 if (kcontrol->private_value) 118 return ac97_enum_text_info(kcontrol, uinfo, texts,
119 return ac97_enum_text_info(kcontrol, uinfo, texts, 2); /* 4ch only */ 119 kcontrol->private_value);
120 return ac97_enum_text_info(kcontrol, uinfo, texts, 3);
121} 120}
122 121
123static int ac97_channel_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) 122static int ac97_channel_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
@@ -133,13 +132,8 @@ static int ac97_channel_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
133 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol); 132 struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
134 unsigned char mode = ucontrol->value.enumerated.item[0]; 133 unsigned char mode = ucontrol->value.enumerated.item[0];
135 134
136 if (kcontrol->private_value) { 135 if (mode >= kcontrol->private_value)
137 if (mode >= 2) 136 return -EINVAL;
138 return -EINVAL;
139 } else {
140 if (mode >= 3)
141 return -EINVAL;
142 }
143 137
144 if (mode != ac97->channel_mode) { 138 if (mode != ac97->channel_mode) {
145 ac97->channel_mode = mode; 139 ac97->channel_mode = mode;
@@ -158,6 +152,7 @@ static int ac97_channel_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
158 .get = ac97_surround_jack_mode_get, \ 152 .get = ac97_surround_jack_mode_get, \
159 .put = ac97_surround_jack_mode_put, \ 153 .put = ac97_surround_jack_mode_put, \
160 } 154 }
155/* 6ch */
161#define AC97_CHANNEL_MODE_CTL \ 156#define AC97_CHANNEL_MODE_CTL \
162 { \ 157 { \
163 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 158 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
@@ -165,7 +160,9 @@ static int ac97_channel_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
165 .info = ac97_channel_mode_info, \ 160 .info = ac97_channel_mode_info, \
166 .get = ac97_channel_mode_get, \ 161 .get = ac97_channel_mode_get, \
167 .put = ac97_channel_mode_put, \ 162 .put = ac97_channel_mode_put, \
163 .private_value = 3, \
168 } 164 }
165/* 4ch */
169#define AC97_CHANNEL_MODE_4CH_CTL \ 166#define AC97_CHANNEL_MODE_4CH_CTL \
170 { \ 167 { \
171 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \ 168 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
@@ -173,7 +170,17 @@ static int ac97_channel_mode_put(struct snd_kcontrol *kcontrol, struct snd_ctl_e
173 .info = ac97_channel_mode_info, \ 170 .info = ac97_channel_mode_info, \
174 .get = ac97_channel_mode_get, \ 171 .get = ac97_channel_mode_get, \
175 .put = ac97_channel_mode_put, \ 172 .put = ac97_channel_mode_put, \
176 .private_value = 1, \ 173 .private_value = 2, \
174 }
175/* 8ch */
176#define AC97_CHANNEL_MODE_8CH_CTL \
177 { \
178 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, \
179 .name = "Channel Mode", \
180 .info = ac97_channel_mode_info, \
181 .get = ac97_channel_mode_get, \
182 .put = ac97_channel_mode_put, \
183 .private_value = 4, \
177 } 184 }
178 185
179static inline int is_surround_on(struct snd_ac97 *ac97) 186static inline int is_surround_on(struct snd_ac97 *ac97)
@@ -210,6 +217,10 @@ static inline int is_shared_micin(struct snd_ac97 *ac97)
210 return !ac97->indep_surround && !is_clfe_on(ac97); 217 return !ac97->indep_surround && !is_clfe_on(ac97);
211} 218}
212 219
220static inline int alc850_is_aux_back_surround(struct snd_ac97 *ac97)
221{
222 return is_surround_on(ac97);
223}
213 224
214/* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */ 225/* The following snd_ac97_ymf753_... items added by David Shust (dshust@shustring.com) */
215/* Modified for YMF743 by Keita Maehara <maehara@debian.org> */ 226/* Modified for YMF743 by Keita Maehara <maehara@debian.org> */
@@ -2816,10 +2827,12 @@ static int patch_alc655(struct snd_ac97 * ac97)
2816 2827
2817#define AC97_ALC850_JACK_SELECT 0x76 2828#define AC97_ALC850_JACK_SELECT 0x76
2818#define AC97_ALC850_MISC1 0x7a 2829#define AC97_ALC850_MISC1 0x7a
2830#define AC97_ALC850_MULTICH 0x6a
2819 2831
2820static void alc850_update_jacks(struct snd_ac97 *ac97) 2832static void alc850_update_jacks(struct snd_ac97 *ac97)
2821{ 2833{
2822 int shared; 2834 int shared;
2835 int aux_is_back_surround;
2823 2836
2824 /* shared Line-In / Surround Out */ 2837 /* shared Line-In / Surround Out */
2825 shared = is_shared_surrout(ac97); 2838 shared = is_shared_surrout(ac97);
@@ -2837,13 +2850,18 @@ static void alc850_update_jacks(struct snd_ac97 *ac97)
2837 /* MIC-IN = 1, CENTER-LFE = 5 */ 2850 /* MIC-IN = 1, CENTER-LFE = 5 */
2838 snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4, 2851 snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4,
2839 shared ? (5<<4) : (1<<4)); 2852 shared ? (5<<4) : (1<<4));
2853
2854 aux_is_back_surround = alc850_is_aux_back_surround(ac97);
2855 /* Aux is Back Surround */
2856 snd_ac97_update_bits(ac97, AC97_ALC850_MULTICH, 1 << 10,
2857 aux_is_back_surround ? (1<<10) : (0<<10));
2840} 2858}
2841 2859
2842static const struct snd_kcontrol_new snd_ac97_controls_alc850[] = { 2860static const struct snd_kcontrol_new snd_ac97_controls_alc850[] = {
2843 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0), 2861 AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
2844 AC97_SINGLE("Mic Front Input Switch", AC97_ALC850_JACK_SELECT, 15, 1, 1), 2862 AC97_SINGLE("Mic Front Input Switch", AC97_ALC850_JACK_SELECT, 15, 1, 1),
2845 AC97_SURROUND_JACK_MODE_CTL, 2863 AC97_SURROUND_JACK_MODE_CTL,
2846 AC97_CHANNEL_MODE_CTL, 2864 AC97_CHANNEL_MODE_8CH_CTL,
2847}; 2865};
2848 2866
2849static int patch_alc850_specific(struct snd_ac97 *ac97) 2867static int patch_alc850_specific(struct snd_ac97 *ac97)
@@ -2869,6 +2887,7 @@ static int patch_alc850(struct snd_ac97 *ac97)
2869 ac97->build_ops = &patch_alc850_ops; 2887 ac97->build_ops = &patch_alc850_ops;
2870 2888
2871 ac97->spec.dev_flags = 0; /* for IEC958 playback route - ALC655 compatible */ 2889 ac97->spec.dev_flags = 0; /* for IEC958 playback route - ALC655 compatible */
2890 ac97->flags |= AC97_HAS_8CH;
2872 2891
2873 /* assume only page 0 for writing cache */ 2892 /* assume only page 0 for writing cache */
2874 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR); 2893 snd_ac97_update_bits(ac97, AC97_INT_PAGING, AC97_PAGE_MASK, AC97_PAGE_VENDOR);
@@ -2878,6 +2897,7 @@ static int patch_alc850(struct snd_ac97 *ac97)
2878 spdif-in monitor off, spdif-in PCM off 2897 spdif-in monitor off, spdif-in PCM off
2879 center on mic off, surround on line-in off 2898 center on mic off, surround on line-in off
2880 duplicate front off 2899 duplicate front off
2900 NB default bit 10=0 = Aux is Capture, not Back Surround
2881 */ 2901 */
2882 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15); 2902 snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15);
2883 /* SURR_OUT: on, Surr 1kOhm: on, Surr Amp: off, Front 1kOhm: off 2903 /* SURR_OUT: on, Surr 1kOhm: on, Surr Amp: off, Front 1kOhm: off