[alsa-devel] Realtek ALC883 support on Albatron KI690-AM2 motherboard

Takashi Iwai tiwai at suse.de
Tue Dec 18 13:34:56 CET 2007


At Tue, 18 Dec 2007 13:11:49 +0100,
I wrote:
> 
> At Fri, 14 Dec 2007 17:32:54 -0500,
> Andrew Paprocki wrote:
> > 
> > Takashi,
> > 
> > Running with the hg alsa head with full debug, I see the following
> > output.. The 01:05.2 device is an ATI HDMI port. I appear to have a
> > card0 after this which is the ALC883 chip. Do you know why the HDMI
> > port is not correctly detected as an "ATI RS600 HDMI" according to the
> > patch_atihdmi.c file? Do I need to pass any parameters to the module?
> 
> Oh, that's an unexpected problem.
> 
> Right now, snd-hda-intel driver is designed for a single device.
> I wrote it so because I thought the device is only for on-board.
> But now, ATI ships the graphic card with the extra sound
> controller, and this conflicts.
> 
> So, we need a major change in the driver code to allow multiple
> devices.  OK, I'll hack it so that it can go to 2.6.25 kernel...

The below is a quick hack to support multiple cards.

Could you give it a try?


Takashi


diff -r f405fa5b9e7e Documentation/ALSA-Configuration.txt
--- a/Documentation/ALSA-Configuration.txt	Tue Dec 18 13:14:21 2007 +0100
+++ b/Documentation/ALSA-Configuration.txt	Tue Dec 18 15:16:06 2007 +0100
@@ -744,9 +744,12 @@ Prior to version 0.9.0rc4 options had a 
 		VIA VT8251/VT8237A,
 		SIS966, ULI M5461
 
+    [Multiple options for each card instance]
     model	- force the model name
     position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)
     probe_mask  - Bitmask to probe codecs (default = -1, meaning all slots)
+    
+    [Single (global) options]
     single_cmd  - Use single immediate commands to communicate with
 		codecs (for debugging only)
     enable_msi	- Enable Message Signaled Interrupt (MSI) (default = off)
@@ -755,8 +758,8 @@ Prior to version 0.9.0rc4 options had a 
     power_save_controller - Reset HD-audio controller in power-saving mode
 		(default = on)
 
-    This module supports one card and autoprobe.
-
+    This module supports multiple cards and autoprobe.
+    
     Each codec may have a model table for different configurations.
     If your machine isn't listed there, the default (usually minimal)
     configuration is set up.  You can pass "model=<name>" option to
diff -r f405fa5b9e7e pci/hda/hda_intel.c
--- a/pci/hda/hda_intel.c	Tue Dec 18 13:14:21 2007 +0100
+++ b/pci/hda/hda_intel.c	Tue Dec 18 15:16:06 2007 +0100
@@ -50,29 +50,32 @@
 #include "hda_codec.h"
 
 
-static int index = SNDRV_DEFAULT_IDX1;
-static char *id = SNDRV_DEFAULT_STR1;
-static char *model;
-static int position_fix;
-static int probe_mask = -1;
+static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX;
+static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR;
+static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP;
+static char *model[SNDRV_CARDS];
+static int position_fix[SNDRV_CARDS];
+static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1};
 static int single_cmd;
 static int enable_msi;
 
-module_param(index, int, 0444);
+module_param_array(index, int, NULL, 0444);
 MODULE_PARM_DESC(index, "Index value for Intel HD audio interface.");
-module_param(id, charp, 0444);
+module_param_array(id, charp, NULL, 0444);
 MODULE_PARM_DESC(id, "ID string for Intel HD audio interface.");
-module_param(model, charp, 0444);
+module_param_array(enable, bool, NULL, 0444);
+MODULE_PARM_DESC(enable, "Enable Intel HD audio interface.");
+module_param_array(model, charp, NULL, 0444);
 MODULE_PARM_DESC(model, "Use the given board model.");
-module_param(position_fix, int, 0444);
+module_param_array(position_fix, int, NULL, 0444);
 MODULE_PARM_DESC(position_fix, "Fix DMA pointer "
 		 "(0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size).");
-module_param(probe_mask, int, 0444);
+module_param_array(probe_mask, int, NULL, 0444);
 MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1).");
 module_param(single_cmd, bool, 0444);
 MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs "
 		 "(for debugging only).");
-module_param(enable_msi, int, 0);
+module_param(enable_msi, int, 0444);
 MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)");
 
 #ifdef CONFIG_SND_HDA_POWER_SAVE
@@ -86,10 +89,6 @@ module_param(power_save_controller, bool
 module_param(power_save_controller, bool, 0644);
 MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode.");
 #endif
-
-/* just for backward compatibility */
-static int enable;
-module_param(enable, bool, 0444);
 
 MODULE_LICENSE("GPL");
 MODULE_SUPPORTED_DEVICE("{{Intel, ICH6},"
@@ -1038,7 +1037,8 @@ static unsigned int azx_max_codecs[] __d
 	[AZX_DRIVER_NVIDIA] = 3,	/* FIXME: correct? */
 };
 
-static int __devinit azx_codec_create(struct azx *chip, const char *model)
+static int __devinit azx_codec_create(struct azx *chip, const char *model,
+				      unsigned int codec_probe_mask)
 {
 	struct hda_bus_template bus_temp;
 	int c, codecs, audio_codecs, err;
@@ -1059,7 +1059,7 @@ static int __devinit azx_codec_create(st
 
 	codecs = audio_codecs = 0;
 	for (c = 0; c < AZX_MAX_CODECS; c++) {
-		if ((chip->codec_mask & (1 << c)) & probe_mask) {
+		if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
 			struct hda_codec *codec;
 			err = snd_hda_codec_new(chip->bus, c, &codec);
 			if (err < 0)
@@ -1072,7 +1072,7 @@ static int __devinit azx_codec_create(st
 	if (!audio_codecs) {
 		/* probe additional slots if no codec is found */
 		for (; c < azx_max_codecs[chip->driver_type]; c++) {
-			if ((chip->codec_mask & (1 << c)) & probe_mask) {
+			if ((chip->codec_mask & (1 << c)) & codec_probe_mask) {
 				err = snd_hda_codec_new(chip->bus, c, NULL);
 				if (err < 0)
 					continue;
@@ -1683,18 +1683,18 @@ static struct snd_pci_quirk probe_mask_l
 	{}
 };
 
-static void __devinit check_probe_mask(struct azx *chip)
+static void __devinit check_probe_mask(struct azx *chip, int dev)
 {
 	const struct snd_pci_quirk *q;
 
-	if (probe_mask == -1) {
+	if (probe_mask[dev] == -1) {
 		q = snd_pci_quirk_lookup(chip->pci, probe_mask_list);
 		if (q) {
 			printk(KERN_INFO
 			       "hda_intel: probe_mask set to 0x%x "
 			       "for device %04x:%04x\n",
 			       q->value, q->subvendor, q->subdevice);
-			probe_mask = q->value;
+			probe_mask[dev] = q->value;
 		}
 	}
 }
@@ -1704,7 +1704,7 @@ static void __devinit check_probe_mask(s
  * constructor
  */
 static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci,
-				int driver_type,
+				int dev, int driver_type,
 				struct azx **rchip)
 {
 	struct azx *chip;
@@ -1734,8 +1734,8 @@ static int __devinit azx_create(struct s
 	chip->driver_type = driver_type;
 	chip->msi = enable_msi;
 
-	chip->position_fix = check_position_fix(chip, position_fix);
-	check_probe_mask(chip);
+	chip->position_fix = check_position_fix(chip, position_fix[dev]);
+	check_probe_mask(chip, dev);
 
 	chip->single_cmd = single_cmd;
 
@@ -1876,17 +1876,25 @@ static int __devinit azx_probe(struct pc
 static int __devinit azx_probe(struct pci_dev *pci,
 			       const struct pci_device_id *pci_id)
 {
+	static int dev;
 	struct snd_card *card;
 	struct azx *chip;
 	int err;
 
-	card = snd_card_new(index, id, THIS_MODULE, 0);
+	if (dev >= SNDRV_CARDS)
+		return -ENODEV;
+	if (!enable[dev]) {
+		dev++;
+		return -ENOENT;
+	}
+
+	card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0);
 	if (!card) {
 		snd_printk(KERN_ERR SFX "Error creating card!\n");
 		return -ENOMEM;
 	}
 
-	err = azx_create(card, pci, pci_id->driver_data, &chip);
+	err = azx_create(card, pci, dev, pci_id->driver_data, &chip);
 	if (err < 0) {
 		snd_card_free(card);
 		return err;
@@ -1894,7 +1902,7 @@ static int __devinit azx_probe(struct pc
 	card->private_data = chip;
 
 	/* create codec instances */
-	err = azx_codec_create(chip, model);
+	err = azx_codec_create(chip, model[dev], probe_mask[dev]);
 	if (err < 0) {
 		snd_card_free(card);
 		return err;


More information about the Alsa-devel mailing list