diff options
author | Takashi Iwai <tiwai@suse.de> | 2008-01-07 09:16:37 -0500 |
---|---|---|
committer | Jaroslav Kysela <perex@perex.cz> | 2008-01-31 11:29:45 -0500 |
commit | 5aba4f8ec72b2b880c694b5ce58e67be508f7b7a (patch) | |
tree | f1b2ddb355c434d27e17bf78de9e8cd2d8e1a4a1 | |
parent | f11b799282201fbd8c88b51815176a902b1f15b8 (diff) |
[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 aded3b4f0889..afdb6ffeae55 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. | |||
744 | VIA VT8251/VT8237A, | 744 | VIA VT8251/VT8237A, |
745 | SIS966, ULI M5461 | 745 | SIS966, ULI M5461 |
746 | 746 | ||
747 | [Multiple options for each card instance] | ||
747 | model - force the model name | 748 | model - force the model name |
748 | position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) | 749 | position_fix - Fix DMA pointer (0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size) |
749 | probe_mask - Bitmask to probe codecs (default = -1, meaning all slots) | 750 | probe_mask - Bitmask to probe codecs (default = -1, meaning all slots) |
751 | |||
752 | [Single (global) options] | ||
750 | single_cmd - Use single immediate commands to communicate with | 753 | single_cmd - Use single immediate commands to communicate with |
751 | codecs (for debugging only) | 754 | codecs (for debugging only) |
752 | enable_msi - Enable Message Signaled Interrupt (MSI) (default = off) | 755 | 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. | |||
755 | power_save_controller - Reset HD-audio controller in power-saving mode | 758 | power_save_controller - Reset HD-audio controller in power-saving mode |
756 | (default = on) | 759 | (default = on) |
757 | 760 | ||
758 | This module supports one card and autoprobe. | 761 | This module supports multiple cards and autoprobe. |
759 | 762 | ||
760 | Each codec may have a model table for different configurations. | 763 | Each codec may have a model table for different configurations. |
761 | If your machine isn't listed there, the default (usually minimal) | 764 | If your machine isn't listed there, the default (usually minimal) |
762 | configuration is set up. You can pass "model=<name>" option to | 765 | 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 41edf85db38b..a37e8946c7b0 100644 --- a/sound/pci/hda/hda_intel.c +++ b/sound/pci/hda/hda_intel.c | |||
@@ -50,29 +50,32 @@ | |||
50 | #include "hda_codec.h" | 50 | #include "hda_codec.h" |
51 | 51 | ||
52 | 52 | ||
53 | static int index = SNDRV_DEFAULT_IDX1; | 53 | static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; |
54 | static char *id = SNDRV_DEFAULT_STR1; | 54 | static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; |
55 | static char *model; | 55 | static int enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; |
56 | static int position_fix; | 56 | static char *model[SNDRV_CARDS]; |
57 | static int probe_mask = -1; | 57 | static int position_fix[SNDRV_CARDS]; |
58 | static int probe_mask[SNDRV_CARDS] = {[0 ... (SNDRV_CARDS-1)] = -1}; | ||
58 | static int single_cmd; | 59 | static int single_cmd; |
59 | static int enable_msi; | 60 | static int enable_msi; |
60 | 61 | ||
61 | module_param(index, int, 0444); | 62 | module_param_array(index, int, NULL, 0444); |
62 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); | 63 | MODULE_PARM_DESC(index, "Index value for Intel HD audio interface."); |
63 | module_param(id, charp, 0444); | 64 | module_param_array(id, charp, NULL, 0444); |
64 | MODULE_PARM_DESC(id, "ID string for Intel HD audio interface."); | 65 | MODULE_PARM_DESC(id, "ID string for Intel HD audio interface."); |
65 | module_param(model, charp, 0444); | 66 | module_param_array(enable, bool, NULL, 0444); |
67 | MODULE_PARM_DESC(enable, "Enable Intel HD audio interface."); | ||
68 | module_param_array(model, charp, NULL, 0444); | ||
66 | MODULE_PARM_DESC(model, "Use the given board model."); | 69 | MODULE_PARM_DESC(model, "Use the given board model."); |
67 | module_param(position_fix, int, 0444); | 70 | module_param_array(position_fix, int, NULL, 0444); |
68 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer " | 71 | MODULE_PARM_DESC(position_fix, "Fix DMA pointer " |
69 | "(0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); | 72 | "(0 = auto, 1 = none, 2 = POSBUF, 3 = FIFO size)."); |
70 | module_param(probe_mask, int, 0444); | 73 | module_param_array(probe_mask, int, NULL, 0444); |
71 | MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); | 74 | MODULE_PARM_DESC(probe_mask, "Bitmask to probe codecs (default = -1)."); |
72 | module_param(single_cmd, bool, 0444); | 75 | module_param(single_cmd, bool, 0444); |
73 | MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " | 76 | MODULE_PARM_DESC(single_cmd, "Use single command to communicate with codecs " |
74 | "(for debugging only)."); | 77 | "(for debugging only)."); |
75 | module_param(enable_msi, int, 0); | 78 | module_param(enable_msi, int, 0444); |
76 | MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); | 79 | MODULE_PARM_DESC(enable_msi, "Enable Message Signaled Interrupt (MSI)"); |
77 | 80 | ||
78 | #ifdef CONFIG_SND_HDA_POWER_SAVE | 81 | #ifdef CONFIG_SND_HDA_POWER_SAVE |
@@ -87,10 +90,6 @@ module_param(power_save_controller, bool, 0644); | |||
87 | MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); | 90 | MODULE_PARM_DESC(power_save_controller, "Reset controller in power save mode."); |
88 | #endif | 91 | #endif |
89 | 92 | ||
90 | /* just for backward compatibility */ | ||
91 | static int enable; | ||
92 | module_param(enable, bool, 0444); | ||
93 | |||
94 | MODULE_LICENSE("GPL"); | 93 | MODULE_LICENSE("GPL"); |
95 | MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," | 94 | MODULE_SUPPORTED_DEVICE("{{Intel, ICH6}," |
96 | "{Intel, ICH6M}," | 95 | "{Intel, ICH6M}," |
@@ -1038,7 +1037,8 @@ static unsigned int azx_max_codecs[] __devinitdata = { | |||
1038 | [AZX_DRIVER_NVIDIA] = 3, /* FIXME: correct? */ | 1037 | [AZX_DRIVER_NVIDIA] = 3, /* FIXME: correct? */ |
1039 | }; | 1038 | }; |
1040 | 1039 | ||
1041 | static int __devinit azx_codec_create(struct azx *chip, const char *model) | 1040 | static int __devinit azx_codec_create(struct azx *chip, const char *model, |
1041 | unsigned int codec_probe_mask) | ||
1042 | { | 1042 | { |
1043 | struct hda_bus_template bus_temp; | 1043 | struct hda_bus_template bus_temp; |
1044 | int c, codecs, audio_codecs, err; | 1044 | int c, codecs, audio_codecs, err; |
@@ -1059,7 +1059,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) | |||
1059 | 1059 | ||
1060 | codecs = audio_codecs = 0; | 1060 | codecs = audio_codecs = 0; |
1061 | for (c = 0; c < AZX_MAX_CODECS; c++) { | 1061 | for (c = 0; c < AZX_MAX_CODECS; c++) { |
1062 | if ((chip->codec_mask & (1 << c)) & probe_mask) { | 1062 | if ((chip->codec_mask & (1 << c)) & codec_probe_mask) { |
1063 | struct hda_codec *codec; | 1063 | struct hda_codec *codec; |
1064 | err = snd_hda_codec_new(chip->bus, c, &codec); | 1064 | err = snd_hda_codec_new(chip->bus, c, &codec); |
1065 | if (err < 0) | 1065 | if (err < 0) |
@@ -1072,7 +1072,7 @@ static int __devinit azx_codec_create(struct azx *chip, const char *model) | |||
1072 | if (!audio_codecs) { | 1072 | if (!audio_codecs) { |
1073 | /* probe additional slots if no codec is found */ | 1073 | /* probe additional slots if no codec is found */ |
1074 | for (; c < azx_max_codecs[chip->driver_type]; c++) { | 1074 | for (; c < azx_max_codecs[chip->driver_type]; c++) { |
1075 | if ((chip->codec_mask & (1 << c)) & probe_mask) { | 1075 | if ((chip->codec_mask & (1 << c)) & codec_probe_mask) { |
1076 | err = snd_hda_codec_new(chip->bus, c, NULL); | 1076 | err = snd_hda_codec_new(chip->bus, c, NULL); |
1077 | if (err < 0) | 1077 | if (err < 0) |
1078 | continue; | 1078 | continue; |
@@ -1683,18 +1683,18 @@ static struct snd_pci_quirk probe_mask_list[] __devinitdata = { | |||
1683 | {} | 1683 | {} |
1684 | }; | 1684 | }; |
1685 | 1685 | ||
1686 | static void __devinit check_probe_mask(struct azx *chip) | 1686 | static void __devinit check_probe_mask(struct azx *chip, int dev) |
1687 | { | 1687 | { |
1688 | const struct snd_pci_quirk *q; | 1688 | const struct snd_pci_quirk *q; |
1689 | 1689 | ||
1690 | if (probe_mask == -1) { | 1690 | if (probe_mask[dev] == -1) { |
1691 | q = snd_pci_quirk_lookup(chip->pci, probe_mask_list); | 1691 | q = snd_pci_quirk_lookup(chip->pci, probe_mask_list); |
1692 | if (q) { | 1692 | if (q) { |
1693 | printk(KERN_INFO | 1693 | printk(KERN_INFO |
1694 | "hda_intel: probe_mask set to 0x%x " | 1694 | "hda_intel: probe_mask set to 0x%x " |
1695 | "for device %04x:%04x\n", | 1695 | "for device %04x:%04x\n", |
1696 | q->value, q->subvendor, q->subdevice); | 1696 | q->value, q->subvendor, q->subdevice); |
1697 | probe_mask = q->value; | 1697 | probe_mask[dev] = q->value; |
1698 | } | 1698 | } |
1699 | } | 1699 | } |
1700 | } | 1700 | } |
@@ -1704,7 +1704,7 @@ static void __devinit check_probe_mask(struct azx *chip) | |||
1704 | * constructor | 1704 | * constructor |
1705 | */ | 1705 | */ |
1706 | static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | 1706 | static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, |
1707 | int driver_type, | 1707 | int dev, int driver_type, |
1708 | struct azx **rchip) | 1708 | struct azx **rchip) |
1709 | { | 1709 | { |
1710 | struct azx *chip; | 1710 | struct azx *chip; |
@@ -1734,8 +1734,8 @@ static int __devinit azx_create(struct snd_card *card, struct pci_dev *pci, | |||
1734 | chip->driver_type = driver_type; | 1734 | chip->driver_type = driver_type; |
1735 | chip->msi = enable_msi; | 1735 | chip->msi = enable_msi; |
1736 | 1736 | ||
1737 | chip->position_fix = check_position_fix(chip, position_fix); | 1737 | chip->position_fix = check_position_fix(chip, position_fix[dev]); |
1738 | check_probe_mask(chip); | 1738 | check_probe_mask(chip, dev); |
1739 | 1739 | ||
1740 | chip->single_cmd = single_cmd; | 1740 | chip->single_cmd = single_cmd; |
1741 | 1741 | ||
@@ -1876,17 +1876,25 @@ static void power_down_all_codecs(struct azx *chip) | |||
1876 | static int __devinit azx_probe(struct pci_dev *pci, | 1876 | static int __devinit azx_probe(struct pci_dev *pci, |
1877 | const struct pci_device_id *pci_id) | 1877 | const struct pci_device_id *pci_id) |
1878 | { | 1878 | { |
1879 | static int dev; | ||
1879 | struct snd_card *card; | 1880 | struct snd_card *card; |
1880 | struct azx *chip; | 1881 | struct azx *chip; |
1881 | int err; | 1882 | int err; |
1882 | 1883 | ||
1883 | card = snd_card_new(index, id, THIS_MODULE, 0); | 1884 | if (dev >= SNDRV_CARDS) |
1885 | return -ENODEV; | ||
1886 | if (!enable[dev]) { | ||
1887 | dev++; | ||
1888 | return -ENOENT; | ||
1889 | } | ||
1890 | |||
1891 | card = snd_card_new(index[dev], id[dev], THIS_MODULE, 0); | ||
1884 | if (!card) { | 1892 | if (!card) { |
1885 | snd_printk(KERN_ERR SFX "Error creating card!\n"); | 1893 | snd_printk(KERN_ERR SFX "Error creating card!\n"); |
1886 | return -ENOMEM; | 1894 | return -ENOMEM; |
1887 | } | 1895 | } |
1888 | 1896 | ||
1889 | err = azx_create(card, pci, pci_id->driver_data, &chip); | 1897 | err = azx_create(card, pci, dev, pci_id->driver_data, &chip); |
1890 | if (err < 0) { | 1898 | if (err < 0) { |
1891 | snd_card_free(card); | 1899 | snd_card_free(card); |
1892 | return err; | 1900 | return err; |
@@ -1894,7 +1902,7 @@ static int __devinit azx_probe(struct pci_dev *pci, | |||
1894 | card->private_data = chip; | 1902 | card->private_data = chip; |
1895 | 1903 | ||
1896 | /* create codec instances */ | 1904 | /* create codec instances */ |
1897 | err = azx_codec_create(chip, model); | 1905 | err = azx_codec_create(chip, model[dev], probe_mask[dev]); |
1898 | if (err < 0) { | 1906 | if (err < 0) { |
1899 | snd_card_free(card); | 1907 | snd_card_free(card); |
1900 | return err; | 1908 | return err; |