提交 09f99701 编写于 作者: T Takashi Iwai

[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: NTakashi Iwai <tiwai@suse.de>
上级 bf277785
...@@ -1037,16 +1037,24 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir, ...@@ -1037,16 +1037,24 @@ void snd_hda_set_vmaster_tlv(struct hda_codec *codec, hda_nid_t nid, int dir,
} }
/* find a mixer control element with the given name */ /* find a mixer control element with the given name */
struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec, static struct snd_kcontrol *
const char *name) _snd_hda_find_mixer_ctl(struct hda_codec *codec,
const char *name, int idx)
{ {
struct snd_ctl_elem_id id; struct snd_ctl_elem_id id;
memset(&id, 0, sizeof(id)); memset(&id, 0, sizeof(id));
id.iface = SNDRV_CTL_ELEM_IFACE_MIXER; id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
id.index = idx;
strcpy(id.name, name); strcpy(id.name, name);
return snd_ctl_find_id(codec->bus->card, &id); return snd_ctl_find_id(codec->bus->card, &id);
} }
struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
const char *name)
{
return _snd_hda_find_mixer_ctl(codec, name, 0);
}
/* create a virtual master control and add slaves */ /* create a virtual master control and add slaves */
int snd_hda_add_vmaster(struct hda_codec *codec, char *name, int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
unsigned int *tlv, const char **slaves) unsigned int *tlv, const char **slaves)
...@@ -1481,6 +1489,8 @@ static struct snd_kcontrol_new dig_mixes[] = { ...@@ -1481,6 +1489,8 @@ static struct snd_kcontrol_new dig_mixes[] = {
{ } /* end */ { } /* end */
}; };
#define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */
/** /**
* snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls * snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls
* @codec: the HDA codec * @codec: the HDA codec
...@@ -1496,9 +1506,20 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid) ...@@ -1496,9 +1506,20 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
int err; int err;
struct snd_kcontrol *kctl; struct snd_kcontrol *kctl;
struct snd_kcontrol_new *dig_mix; struct snd_kcontrol_new *dig_mix;
int idx;
for (idx = 0; idx < SPDIF_MAX_IDX; idx++) {
if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Playback Switch",
idx))
break;
}
if (idx >= SPDIF_MAX_IDX) {
printk(KERN_ERR "hda_codec: too many IEC958 outputs\n");
return -EBUSY;
}
for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) { for (dig_mix = dig_mixes; dig_mix->name; dig_mix++) {
kctl = snd_ctl_new1(dig_mix, codec); kctl = snd_ctl_new1(dig_mix, codec);
kctl->id.index = idx;
kctl->private_value = nid; kctl->private_value = nid;
err = snd_ctl_add(codec->bus->card, kctl); err = snd_ctl_add(codec->bus->card, kctl);
if (err < 0) if (err < 0)
...@@ -1595,7 +1616,17 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid) ...@@ -1595,7 +1616,17 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
int err; int err;
struct snd_kcontrol *kctl; struct snd_kcontrol *kctl;
struct snd_kcontrol_new *dig_mix; struct snd_kcontrol_new *dig_mix;
int idx;
for (idx = 0; idx < SPDIF_MAX_IDX; idx++) {
if (!_snd_hda_find_mixer_ctl(codec, "IEC958 Capture Switch",
idx))
break;
}
if (idx >= SPDIF_MAX_IDX) {
printk(KERN_ERR "hda_codec: too many IEC958 inputs\n");
return -EBUSY;
}
for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) { for (dig_mix = dig_in_ctls; dig_mix->name; dig_mix++) {
kctl = snd_ctl_new1(dig_mix, codec); kctl = snd_ctl_new1(dig_mix, codec);
kctl->private_value = nid; kctl->private_value = nid;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册