aboutsummaryrefslogtreecommitdiffstats
path: root/sound
diff options
context:
space:
mode:
Diffstat (limited to 'sound')
-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;