diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-02-18 06:23:13 -0500 |
---|---|---|
committer | Takashi Iwai <tiwai@suse.de> | 2008-04-24 06:00:11 -0400 |
commit | 4235a31784f59c9be5ff71534743c055091f9735 (patch) | |
tree | 87080055fed0c3f25a3c816c182a6db5739430b6 /sound/pci/intel8x0.c | |
parent | 2eef1258e54722b1c4efac6e5760d2153f96c4b4 (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/intel8x0.c')
-rw-r--r-- | sound/pci/intel8x0.c | 28 |
1 files changed, 25 insertions, 3 deletions
diff --git a/sound/pci/intel8x0.c b/sound/pci/intel8x0.c index c52abd0bf22e..07782ba9c74d 100644 --- a/sound/pci/intel8x0.c +++ b/sound/pci/intel8x0.c | |||
@@ -155,7 +155,8 @@ DEFINE_REGSET(SP, 0x60); /* SPDIF out */ | |||
155 | #define ICH_PCM_SPDIF_69 0x80000000 /* s/pdif pcm on slots 6&9 */ | 155 | #define ICH_PCM_SPDIF_69 0x80000000 /* s/pdif pcm on slots 6&9 */ |
156 | #define ICH_PCM_SPDIF_1011 0xc0000000 /* s/pdif pcm on slots 10&11 */ | 156 | #define ICH_PCM_SPDIF_1011 0xc0000000 /* s/pdif pcm on slots 10&11 */ |
157 | #define ICH_PCM_20BIT 0x00400000 /* 20-bit samples (ICH4) */ | 157 | #define ICH_PCM_20BIT 0x00400000 /* 20-bit samples (ICH4) */ |
158 | #define ICH_PCM_246_MASK 0x00300000 /* 6 channels (not all chips) */ | 158 | #define ICH_PCM_246_MASK 0x00300000 /* chan mask (not all chips) */ |
159 | #define ICH_PCM_8 0x00300000 /* 8 channels (not all chips) */ | ||
159 | #define ICH_PCM_6 0x00200000 /* 6 channels (not all chips) */ | 160 | #define ICH_PCM_6 0x00200000 /* 6 channels (not all chips) */ |
160 | #define ICH_PCM_4 0x00100000 /* 4 channels (not all chips) */ | 161 | #define ICH_PCM_4 0x00100000 /* 4 channels (not all chips) */ |
161 | #define ICH_PCM_2 0x00000000 /* 2 channels (stereo) */ | 162 | #define ICH_PCM_2 0x00000000 /* 2 channels (stereo) */ |
@@ -382,6 +383,7 @@ struct intel8x0 { | |||
382 | 383 | ||
383 | unsigned multi4: 1, | 384 | unsigned multi4: 1, |
384 | multi6: 1, | 385 | multi6: 1, |
386 | multi8 :1, | ||
385 | dra: 1, | 387 | dra: 1, |
386 | smp20bit: 1; | 388 | smp20bit: 1; |
387 | unsigned in_ac97_init: 1, | 389 | unsigned in_ac97_init: 1, |
@@ -997,6 +999,8 @@ static void snd_intel8x0_setup_pcm_out(struct intel8x0 *chip, | |||
997 | cnt |= ICH_PCM_4; | 999 | cnt |= ICH_PCM_4; |
998 | else if (runtime->channels == 6) | 1000 | else if (runtime->channels == 6) |
999 | cnt |= ICH_PCM_6; | 1001 | cnt |= ICH_PCM_6; |
1002 | else if (runtime->channels == 8) | ||
1003 | cnt |= ICH_PCM_8; | ||
1000 | if (chip->device_type == DEVICE_NFORCE) { | 1004 | if (chip->device_type == DEVICE_NFORCE) { |
1001 | /* reset to 2ch once to keep the 6 channel data in alignment, | 1005 | /* reset to 2ch once to keep the 6 channel data in alignment, |
1002 | * to start from Front Left always | 1006 | * to start from Front Left always |
@@ -1106,6 +1110,16 @@ static struct snd_pcm_hw_constraint_list hw_constraints_channels6 = { | |||
1106 | .mask = 0, | 1110 | .mask = 0, |
1107 | }; | 1111 | }; |
1108 | 1112 | ||
1113 | static unsigned int channels8[] = { | ||
1114 | 2, 4, 6, 8, | ||
1115 | }; | ||
1116 | |||
1117 | static struct snd_pcm_hw_constraint_list hw_constraints_channels8 = { | ||
1118 | .count = ARRAY_SIZE(channels8), | ||
1119 | .list = channels8, | ||
1120 | .mask = 0, | ||
1121 | }; | ||
1122 | |||
1109 | static int snd_intel8x0_pcm_open(struct snd_pcm_substream *substream, struct ichdev *ichdev) | 1123 | static int snd_intel8x0_pcm_open(struct snd_pcm_substream *substream, struct ichdev *ichdev) |
1110 | { | 1124 | { |
1111 | struct intel8x0 *chip = snd_pcm_substream_chip(substream); | 1125 | struct intel8x0 *chip = snd_pcm_substream_chip(substream); |
@@ -1136,7 +1150,12 @@ static int snd_intel8x0_playback_open(struct snd_pcm_substream *substream) | |||
1136 | if (err < 0) | 1150 | if (err < 0) |
1137 | return err; | 1151 | return err; |
1138 | 1152 | ||
1139 | if (chip->multi6) { | 1153 | if (chip->multi8) { |
1154 | runtime->hw.channels_max = 8; | ||
1155 | snd_pcm_hw_constraint_list(runtime, 0, | ||
1156 | SNDRV_PCM_HW_PARAM_CHANNELS, | ||
1157 | &hw_constraints_channels8); | ||
1158 | } else if (chip->multi6) { | ||
1140 | runtime->hw.channels_max = 6; | 1159 | runtime->hw.channels_max = 6; |
1141 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, | 1160 | snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS, |
1142 | &hw_constraints_channels6); | 1161 | &hw_constraints_channels6); |
@@ -2203,8 +2222,11 @@ static int __devinit snd_intel8x0_mixer(struct intel8x0 *chip, int ac97_clock, | |||
2203 | } | 2222 | } |
2204 | if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_PCM_SLEFT)) { | 2223 | if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_PCM_SLEFT)) { |
2205 | chip->multi4 = 1; | 2224 | chip->multi4 = 1; |
2206 | if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_LFE)) | 2225 | if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_LFE)) { |
2207 | chip->multi6 = 1; | 2226 | chip->multi6 = 1; |
2227 | if (chip->ac97[0]->flags & AC97_HAS_8CH) | ||
2228 | chip->multi8 = 1; | ||
2229 | } | ||
2208 | } | 2230 | } |
2209 | if (pbus->pcms[0].r[1].rslots[0]) { | 2231 | if (pbus->pcms[0].r[1].rslots[0]) { |
2210 | chip->dra = 1; | 2232 | chip->dra = 1; |