diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-01-07 15:16:37 +0100 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 17:29:45 +0100 |
commit | 5aba4f8ec72b2b880c694b5ce58e67be508f7b7a (patch) | |
tree | f1b2ddb355c434d27e17bf78de9e8cd2d8e1a4a1 | |
parent | f11b799282201fbd8c88b51815176a902b1f15b8 (diff) | |
download | linux-3.10-5aba4f8ec72b2b880c694b5ce58e67be508f7b7a.tar.gz linux-3.10-5aba4f8ec72b2b880c694b5ce58e67be508f7b7a.tar.bz2 linux-3.10-5aba4f8ec72b2b880c694b5ce58e67be508f7b7a.zip |
[ALSA] hda-intel - Support multiple devices
It turned out that there can be multiple HD-audio devices on a single
machine (e.g. on-board audio and HDMI on graphic cards), so we need to
support multiple devices with snd-hda-intel driver.
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Jaroslav Kysela <perex@perex.cz>
-rw-r--r-- | Documentation/sound/alsa/ALSA-Configuration.txt | 7 | ||||
-rw-r--r-- | sound/pci/hda/hda_intel.c | 62 |
2 files changed, 40 insertions, 29 deletions
diff --git a/Documentation/sound/alsa/ALSA-Configuration.txt b/Documentation/sound/alsa/ALSA-Configuration.txt index aded3b4f088..afdb6ffeae5 100644 --- a/Documentation/sound/alsa/ALSA-Configuration.txt +++ b/Documentation/sound/alsa/ALSA-Configuration.txt @@ -744,9 +744,12 @@ Prior to version 0.9.0rc4 options had a 'snd_' prefix. This was removed. 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 'snd_' prefix. This was removed. 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 --git a/sound/pci/hda/hda_intel.c b/sound/pci/hda/hda_intel.c index 41edf85db38..a37e8946c7b 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c @@ -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 @@ -87,10 +90,6 @@ 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}," "{Intel, ICH6M}," @@ -1038,7 +1037,8 @@ static unsigned int azx_max_codecs[] __devinitdata = { [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(struct azx *chip, const char *model) 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(struct azx *chip, const char *model) 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_list[] __devinitdata = { {} }; -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(struct azx *chip) * 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 snd_card *card, struct pci_dev *pci, 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 void power_down_all_codecs(struct azx *chip) 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 pci_dev *pci, 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; |