Intel8x0 8 channel sound

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



For some intel 8x0 cards there is 8 channel sound (such as the ALC850 chip
on NFORCE 4 boards), and this has not been patched yet though the patch has
been on the bug tracker.  Here it is again updated for 1.0.16.  There is
also a patch for the configuration in alsa-lib for cards/NFORCE.conf.  I
have been patching my sources every time I update my kernel, I figured it
was time for someone to actually submit this somewhere else.  The patch was
written by Martin Ellis.
--- alsa-driver-1.0.16/alsa-kernel/pci/intel8x0.c.orig	2008-02-05 04:23:24.000000000 -0500
+++ alsa-driver-1.0.16/alsa-kernel/pci/intel8x0.c	2008-02-14 14:48:59.015625000 -0500
@@ -153,11 +153,12 @@
 #define   ICH_PCM_SPDIF_NONE	0x00000000	/* reserved - undefined */
 #define   ICH_PCM_SPDIF_78	0x40000000	/* s/pdif pcm on slots 7&8 */
 #define   ICH_PCM_SPDIF_69	0x80000000	/* s/pdif pcm on slots 6&9 */
 #define   ICH_PCM_SPDIF_1011	0xc0000000	/* s/pdif pcm on slots 10&11 */
 #define   ICH_PCM_20BIT		0x00400000	/* 20-bit samples (ICH4) */
-#define   ICH_PCM_246_MASK	0x00300000	/* 6 channels (not all chips) */
+#define   ICH_PCM_246_MASK	0x00300000	/* 6/8 channels (not all chips) */
+#define   ICH_PCM_8		0x00300000	/* 8 channels (not all chips) */
 #define   ICH_PCM_6		0x00200000	/* 6 channels (not all chips) */
 #define   ICH_PCM_4		0x00100000	/* 4 channels (not all chips) */
 #define   ICH_PCM_2		0x00000000	/* 2 channels (stereo) */
 #define   ICH_SIS_PCM_246_MASK	0x000000c0	/* 6 channels (SIS7012) */
 #define   ICH_SIS_PCM_6		0x00000080	/* 6 channels (SIS7012) */
@@ -380,10 +381,11 @@
 	struct snd_pcm *pcm[6];
 	struct ichdev ichd[6];
 
 	unsigned multi4: 1,
 		 multi6: 1,
+		 multi8: 1,
 		 dra: 1,
 		 smp20bit: 1;
 	unsigned in_ac97_init: 1,
 		 in_sdin_init: 1;
 	unsigned in_measurement: 1;	/* during ac97 clock measurement */
@@ -993,10 +995,12 @@
 		cnt &= ~(ICH_PCM_246_MASK | ICH_PCM_20BIT);
 		if (runtime->channels == 4 || dbl)
 			cnt |= ICH_PCM_4;
 		else if (runtime->channels == 6)
 			cnt |= ICH_PCM_6;
+		else if (runtime->channels == 8)
+			cnt |= ICH_PCM_8;
 		if (chip->device_type == DEVICE_NFORCE) {
 			/* reset to 2ch once to keep the 6 channel data in alignment,
 			 * to start from Front Left always
 			 */
 			if (cnt & ICH_PCM_246_MASK) {
@@ -1102,10 +1106,20 @@
 	.count = ARRAY_SIZE(channels6),
 	.list = channels6,
 	.mask = 0,
 };
 
+static unsigned int channels8[] = {
+	2, 4, 6, 8,
+};
+
+static struct snd_pcm_hw_constraint_list hw_constraints_channels8 = {
+	.count = ARRAY_SIZE(channels8),
+	.list = channels8,
+	.mask = 0,
+};
+
 static int snd_intel8x0_pcm_open(struct snd_pcm_substream *substream, struct ichdev *ichdev)
 {
 	struct intel8x0 *chip = snd_pcm_substream_chip(substream);
 	struct snd_pcm_runtime *runtime = substream->runtime;
 	int err;
@@ -1132,11 +1146,15 @@
 
 	err = snd_intel8x0_pcm_open(substream, &chip->ichd[ICHD_PCMOUT]);
 	if (err < 0)
 		return err;
 
-	if (chip->multi6) {
+	if (chip->multi8) {
+		runtime->hw.channels_max = 8;
+		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
+					   &hw_constraints_channels8);
+	} else if (chip->multi6) {
 		runtime->hw.channels_max = 6;
 		snd_pcm_hw_constraint_list(runtime, 0, SNDRV_PCM_HW_PARAM_CHANNELS,
 					   &hw_constraints_channels6);
 	} else if (chip->multi4) {
 		runtime->hw.channels_max = 4;
@@ -2193,12 +2211,14 @@
 		}
 		iputbyte(chip, ICHREG(SDM), tmp);
 	}
 	if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_PCM_SLEFT)) {
 		chip->multi4 = 1;
-		if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_LFE))
+		if (pbus->pcms[0].r[0].slots & (1 << AC97_SLOT_LFE)) {
 			chip->multi6 = 1;
+			chip->multi8 = 1; /* MARTIN ELLIS - FIXME - need correct way to check if 8 channels supported */
+		}
 	}
 	if (pbus->pcms[0].r[1].rslots[0]) {
 		chip->dra = 1;
 	}
 	if (chip->device_type == DEVICE_INTEL_ICH4) {
--- alsa-driver-1.0.16/alsa-kernel/pci/ac97/ac97_patch.c.orig	2008-02-05 04:23:24.000000000 -0500
+++ alsa-driver-1.0.16/alsa-kernel/pci/ac97/ac97_patch.c	2008-02-14 14:51:46.296875000 -0500
@@ -112,14 +112,14 @@
 	return 0;
 }
 
 static int ac97_channel_mode_info(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_info *uinfo)
 {
-	static const char *texts[] = { "2ch", "4ch", "6ch" };
+	static const char *texts[] = { "2ch", "4ch", "6ch", "8ch" };
 	if (kcontrol->private_value)
 		return ac97_enum_text_info(kcontrol, uinfo, texts, 2); /* 4ch only */
-	return ac97_enum_text_info(kcontrol, uinfo, texts, 3);
+	return ac97_enum_text_info(kcontrol, uinfo, texts, 4);
 }
 
 static int ac97_channel_mode_get(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol)
 {
 	struct snd_ac97 *ac97 = snd_kcontrol_chip(kcontrol);
@@ -208,10 +208,15 @@
 static inline int is_shared_micin(struct snd_ac97 *ac97)
 {
 	return !ac97->indep_surround && !is_clfe_on(ac97);
 }
 
+static inline int alc850_is_aux_back_surround(struct snd_ac97 *ac97)
+{
+	return is_surround_on(ac97);
+}
+
 
 /* The following snd_ac97_ymf753_... items added by David Shust (dshust@xxxxxxxxxxxxx) */
 /* Modified for YMF743 by Keita Maehara <maehara@xxxxxxxxxx> */
 
 /* It is possible to indicate to the Yamaha YMF7x3 the type of
@@ -2814,14 +2819,16 @@
 }
 
 
 #define AC97_ALC850_JACK_SELECT	0x76
 #define AC97_ALC850_MISC1	0x7a
+#define AC97_ALC850_MULTICH	0x6a
 
 static void alc850_update_jacks(struct snd_ac97 *ac97)
 {
 	int shared;
+	int aux_is_back_surround;
 	
 	/* shared Line-In / Surround Out */
 	shared = is_shared_surrout(ac97);
 	/* SURR 1kOhm (bit4), Amp (bit5) */
 	snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<4)|(1<<5),
@@ -2835,10 +2842,15 @@
 	snd_ac97_update_bits(ac97, AC97_ALC850_MISC1, (1<<12)|(1<<13),
 			     shared ? (1<<12) : (1<<13));
 	/* MIC-IN = 1, CENTER-LFE = 5 */
 	snd_ac97_update_bits(ac97, AC97_ALC850_JACK_SELECT, 7 << 4,
 			     shared ? (5<<4) : (1<<4));
+
+	aux_is_back_surround = alc850_is_aux_back_surround(ac97);
+	/* Aux is Back Surround */
+	snd_ac97_update_bits(ac97, AC97_ALC850_MULTICH, 1 << 10,
+			     aux_is_back_surround ? (1<<10) : (0<<10));
 }
 
 static const struct snd_kcontrol_new snd_ac97_controls_alc850[] = {
 	AC97_PAGE_SINGLE("Duplicate Front", AC97_ALC650_MULTICH, 0, 1, 0, 0),
 	AC97_SINGLE("Mic Front Input Switch", AC97_ALC850_JACK_SELECT, 15, 1, 1),
@@ -2876,10 +2888,11 @@
 	/* adjust default values */
 	/* set default: spdif-in enabled,
 	   spdif-in monitor off, spdif-in PCM off
 	   center on mic off, surround on line-in off
 	   duplicate front off
+	   NB default bit 10=0 = Aux is Capture, not Back Surround
 	*/
 	snd_ac97_write_cache(ac97, AC97_ALC650_MULTICH, 1<<15);
 	/* SURR_OUT: on, Surr 1kOhm: on, Surr Amp: off, Front 1kOhm: off
 	 * Front Amp: on, Vref: enable, Center 1kOhm: on, Mix: on
 	 */
--- alsa-lib-1.0.16/src/conf/cards/NFORCE.conf.orig	2008-02-05 04:23:44.000000000 -0500
+++ alsa-lib-1.0.16/src/conf/cards/NFORCE.conf	2008-02-14 14:57:13.218750000 -0500
@@ -169,10 +169,83 @@
 		name "PCM Playback Volume"
 		card $CARD
 	}
 }
 
+<confdir:pcm/surround71.conf>
+
+NFORCE.pcm.surround71.0 {
+    @args [ CARD ]
+    @args.CARD {
+        type string
+    }
+    type softvol
+    slave.pcm {
+        type route
+        ttable.0.0 1
+        ttable.1.1 1
+        ttable.2.4 1
+        ttable.3.5 1
+        ttable.4.2 1
+        ttable.5.3 1
+        ttable.6.6 1
+        ttable.7.7 1
+        slave.pcm {
+            type hooks
+            slave.pcm {
+                type hw
+                card $CARD
+                device 0
+            }
+            hooks.0 {
+                type ctl_elems
+                hook_args [
+                {
+                    name "Channel Mode"
+                    preserve true
+                    value "8ch"
+                    lock true
+                    optional true
+                }
+                # for old drivers
+                {
+                    name "Line-In As Surround"
+                    preserve true
+                    value true
+                    optional true
+                }
+                {
+                    name "Mic As Center/LFE"
+                    preserve true
+                    value true
+                    optional true
+                }
+                {
+                    name "Surround Down Mix"
+                    preserve true
+                    value off
+                    lock true
+                    optional true
+                }
+                {
+                    name "Center/LFE Down Mix"
+                    preserve true
+                    value off
+                    lock true
+                    optional true
+                }
+                ]
+            }
+        }
+        slave.channels 8
+    }
+    control {
+        name "PCM Playback Volume"
+        card $CARD
+    }
+}
+
 <confdir:pcm/iec958.conf>
 
 NFORCE.pcm.iec958.0 {
 	@args [ CARD AES0 AES1 AES2 AES3 ]
 	@args.CARD {
_______________________________________________
Alsa-devel mailing list
Alsa-devel@xxxxxxxxxxxxxxxx
http://mailman.alsa-project.org/mailman/listinfo/alsa-devel

[Index of Archives]     [ALSA User]     [Linux Audio Users]     [Kernel Archive]     [Asterisk PBX]     [Photo Sharing]     [Linux Sound]     [Video 4 Linux]     [Gimp]     [Yosemite News]

  Powered by Linux