Skip to content

Commit

Permalink
[ALSA] hda-codec - Allow multiple SPDIF devices
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Takashi Iwai committed Apr 24, 2008
1 parent bf27778 commit 09f9970
Showing 1 changed file with 33 additions and 2 deletions.
35 changes: 33 additions & 2 deletions sound/pci/hda/hda_codec.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 */
struct snd_kcontrol *snd_hda_find_mixer_ctl(struct hda_codec *codec,
const char *name)
static struct snd_kcontrol *
_snd_hda_find_mixer_ctl(struct hda_codec *codec,
const char *name, int idx)
{
struct snd_ctl_elem_id id;
memset(&id, 0, sizeof(id));
id.iface = SNDRV_CTL_ELEM_IFACE_MIXER;
id.index = idx;
strcpy(id.name, name);
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 */
int snd_hda_add_vmaster(struct hda_codec *codec, char *name,
unsigned int *tlv, const char **slaves)
Expand Down Expand Up @@ -1481,6 +1489,8 @@ static struct snd_kcontrol_new dig_mixes[] = {
{ } /* end */
};

#define SPDIF_MAX_IDX 4 /* 4 instances should be enough to probe */

/**
* snd_hda_create_spdif_out_ctls - create Output SPDIF-related controls
* @codec: the HDA codec
Expand All @@ -1496,9 +1506,20 @@ int snd_hda_create_spdif_out_ctls(struct hda_codec *codec, hda_nid_t nid)
int err;
struct snd_kcontrol *kctl;
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++) {
kctl = snd_ctl_new1(dig_mix, codec);
kctl->id.index = idx;
kctl->private_value = nid;
err = snd_ctl_add(codec->bus->card, kctl);
if (err < 0)
Expand Down Expand Up @@ -1595,7 +1616,17 @@ int snd_hda_create_spdif_in_ctls(struct hda_codec *codec, hda_nid_t nid)
int err;
struct snd_kcontrol *kctl;
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++) {
kctl = snd_ctl_new1(dig_mix, codec);
kctl->private_value = nid;
Expand Down

0 comments on commit 09f9970

Please sign in to comment.