aboutsummaryrefslogtreecommitdiffstats
path: root/sound/pci/hda/hda_codec.c
diff options
context:
space:
mode:
authorTakashi Iwai <tiwai@suse.de>2008-02-04 06:31:13 -0500
committerTakashi Iwai <tiwai@suse.de>2008-04-24 06:00:06 -0400
commit09f99701393c7b66bde01df6c292fe5d9f843033 (patch)
tree0b312161cb903b036f1dd5d679e4d7a1e55b5149 /sound/pci/hda/hda_codec.c
parentbf277785d6921b8a9f8339ad5ad632aef6cae73c (diff)
[ALSA] hda-codec - Allow multiple SPDIF devices
The current code doesn't allow multiple SPDIF devices, and causes errors when multiple SPDIF devices are found (e.g. SPDIF out and HDMI). This patch allows multiple SPDIF devices by incrementing the index automatically. Signed-off-by: Takashi Iwai <tiwai@suse.de>
Diffstat (limited to 'sound/pci/hda/hda_codec.c')
-rw-r--r--sound/pci/hda/hda_codec.c35
1 files changed, 33 insertions, 2 deletions
diff --git a/sound/pci/hda/hda_codec.c b/sound/pci/hda/hda_codec.c
index 37c413923db8..ab3bb7997cd2 100644
--- a/sound/pci/hda/hda_codec.c
+++ b/sound/pci/hda/hda_codec.c
@@ -1037,16 +1037,24 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
1037} 1037}
1038 1038
1039/* find a mixer control element with the given name */ 1039/* find a mixer control element with the given name */
1040struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, 1040static struct snd_kcontrol *
1041 const char *name) 1041_snd_hda_find_mixer_ctl(struct hda_codec *codec,
1042 const char *name, int idx)
1042{ 1043{
1043 struct snd_ctl_elem_id id; 1044 struct snd_ctl_elem_id id;
1044 memset(&id, 0, sizeof(id)); 1045 memset(&id, 0, sizeof(id));
1045 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; 1046 id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
1047 id.index = idx;
1046 strcpy(id.name, name); 1048 strcpy(id.name, name);
1047 return snd_ctl_find_id(codec->bus->card, &id); 1049 return snd_ctl_find_id(codec->bus->card, &id);
1048} 1050}
1049 1051
1052struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
1053 const char *name)
1054{
1055 return _snd_hda_find_mixer_ctl(codec, name, 0);
1056}
1057
1050/* create a virtual master control and add slaves */ 1058/* create a virtual master control and add slaves */
1051int snd_hda_add_vmaster(struct hda_codec *codec, char *name, 1059int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
1052 unsigned int *tlv, const char **slaves) 1060 unsigned int *tlv, const char **slaves)
@@ -1481,6 +1489,8 @@ static struct snd_kcontrol_new dig_mixes[] = {
1481 { } /* end */ 1489 { } /* end */
1482}; 1490};
1483 1491
1492#define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */
1493
1484/** 1494/**
1485 * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls 1495 * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls
1486 * @codec: the HDA codec 1496 * @codec: the HDA codec
@@ -1496,9 +1506,20 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
1496 int err; 1506 int err;
1497 struct snd_kcontrol *kctl; 1507 struct snd_kcontrol *kctl;
1498 struct snd_kcontrol_new *dig_mix; 1508 struct snd_kcontrol_new *dig_mix;
1509 int idx;
1499 1510
1511 for (idx = 0; idx < SPDIF_MAX_IDX; idx++) {
1512 if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch",
1513 idx))
1514 break;
1515 }
1516 if (idx >= SPDIF_MAX_IDX) {
1517 printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
1518 return -EBUSY;
1519 }
1500 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { 1520 for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
1501 kctl = snd_ctl_new1(dig_mix, codec); 1521 kctl = snd_ctl_new1(dig_mix, codec);
1522 kctl->id.index = idx;
1502 kctl->private_value = nid; 1523 kctl->private_value = nid;
1503 err = snd_ctl_add(codec->bus->card, kctl); 1524 err = snd_ctl_add(codec->bus->card, kctl);
1504 if (err < 0) 1525 if (err < 0)
@@ -1595,7 +1616,17 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
1595 int err; 1616 int err;
1596 struct snd_kcontrol *kctl; 1617 struct snd_kcontrol *kctl;
1597 struct snd_kcontrol_new *dig_mix; 1618 struct snd_kcontrol_new *dig_mix;
1619 int idx;
1598 1620
1621 for (idx = 0; idx < SPDIF_MAX_IDX; idx++) {
1622 if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch",
1623 idx))
1624 break;
1625 }
1626 if (idx >= SPDIF_MAX_IDX) {
1627 printk(KERN_ERR "hda_codec: too many IEC958 inputs\n");
1628 return -EBUSY;
1629 }
1599 for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) { 1630 for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
1600 kctl = snd_ctl_new1(dig_mix, codec); 1631 kctl = snd_ctl_new1(dig_mix, codec);
1601 kctl->private_value = nid; 1632 kctl->private_value = nid;