Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 99dcab46 authored by Michael Gernoth's avatar Michael Gernoth Committed by Takashi Iwai
Browse files

ALSA: emu10k1: add toggles for E-mu 1010 optical ports



The optical ports on the E-mu 1010 (and dock) can be configured
for ADAT- or S/PDIF-mode, which is currently hardcoded to ADAT.
Add two mixer elements to expose this setting.
Tested on an E-mu 1010 PCIe with connected Micro Dock.

Signed-off-by: default avatarMichael Gernoth <michael@gernoth.net>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent cab2ed74
Loading
Loading
Loading
Loading
+118 −0
Original line number Original line Diff line number Diff line
@@ -806,6 +806,108 @@ static struct snd_kcontrol_new snd_emu1010_internal_clock =
	.put =          snd_emu1010_internal_clock_put
	.put =          snd_emu1010_internal_clock_put
};
};


static int snd_emu1010_optical_out_info(struct snd_kcontrol *kcontrol,
					  struct snd_ctl_elem_info *uinfo)
{
	static const char * const texts[2] = {
		"SPDIF", "ADAT"
	};

	return snd_ctl_enum_info(uinfo, 1, 2, texts);
}

static int snd_emu1010_optical_out_get(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{
	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);

	ucontrol->value.enumerated.item[0] = emu->emu1010.optical_out;
	return 0;
}

static int snd_emu1010_optical_out_put(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{
	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
	unsigned int val;
	u32 tmp;
	int change = 0;

	val = ucontrol->value.enumerated.item[0];
	/* Limit: uinfo->value.enumerated.items = 2; */
	if (val >= 2)
		return -EINVAL;
	change = (emu->emu1010.optical_out != val);
	if (change) {
		emu->emu1010.optical_out = val;
		tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) |
			(emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0);
		snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);
	}
	return change;
}

static struct snd_kcontrol_new snd_emu1010_optical_out = {
	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE,
	.iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
	.name =         "Optical Output Mode",
	.count =	1,
	.info =         snd_emu1010_optical_out_info,
	.get =          snd_emu1010_optical_out_get,
	.put =          snd_emu1010_optical_out_put
};

static int snd_emu1010_optical_in_info(struct snd_kcontrol *kcontrol,
					  struct snd_ctl_elem_info *uinfo)
{
	static const char * const texts[2] = {
		"SPDIF", "ADAT"
	};

	return snd_ctl_enum_info(uinfo, 1, 2, texts);
}

static int snd_emu1010_optical_in_get(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{
	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);

	ucontrol->value.enumerated.item[0] = emu->emu1010.optical_in;
	return 0;
}

static int snd_emu1010_optical_in_put(struct snd_kcontrol *kcontrol,
					struct snd_ctl_elem_value *ucontrol)
{
	struct snd_emu10k1 *emu = snd_kcontrol_chip(kcontrol);
	unsigned int val;
	u32 tmp;
	int change = 0;

	val = ucontrol->value.enumerated.item[0];
	/* Limit: uinfo->value.enumerated.items = 2; */
	if (val >= 2)
		return -EINVAL;
	change = (emu->emu1010.optical_in != val);
	if (change) {
		emu->emu1010.optical_in = val;
		tmp = (emu->emu1010.optical_in ? EMU_HANA_OPTICAL_IN_ADAT : 0) |
			(emu->emu1010.optical_out ? EMU_HANA_OPTICAL_OUT_ADAT : 0);
		snd_emu1010_fpga_write(emu, EMU_HANA_OPTICAL_TYPE, tmp);
	}
	return change;
}

static struct snd_kcontrol_new snd_emu1010_optical_in = {
	.access =	SNDRV_CTL_ELEM_ACCESS_READWRITE,
	.iface =        SNDRV_CTL_ELEM_IFACE_MIXER,
	.name =         "Optical Input Mode",
	.count =	1,
	.info =         snd_emu1010_optical_in_info,
	.get =          snd_emu1010_optical_in_get,
	.put =          snd_emu1010_optical_in_put
};

static int snd_audigy_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
static int snd_audigy_i2c_capture_source_info(struct snd_kcontrol *kcontrol,
					  struct snd_ctl_elem_info *uinfo)
					  struct snd_ctl_elem_info *uinfo)
{
{
@@ -2051,6 +2153,14 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
			snd_ctl_new1(&snd_emu1010_internal_clock, emu));
			snd_ctl_new1(&snd_emu1010_internal_clock, emu));
		if (err < 0)
		if (err < 0)
			return err;
			return err;
		err = snd_ctl_add(card,
			snd_ctl_new1(&snd_emu1010_optical_out, emu));
		if (err < 0)
			return err;
		err = snd_ctl_add(card,
			snd_ctl_new1(&snd_emu1010_optical_in, emu));
		if (err < 0)
			return err;


	} else if (emu->card_capabilities->emu_model) {
	} else if (emu->card_capabilities->emu_model) {
		/* all other e-mu cards for now */
		/* all other e-mu cards for now */
@@ -2086,6 +2196,14 @@ int snd_emu10k1_mixer(struct snd_emu10k1 *emu,
			snd_ctl_new1(&snd_emu1010_internal_clock, emu));
			snd_ctl_new1(&snd_emu1010_internal_clock, emu));
		if (err < 0)
		if (err < 0)
			return err;
			return err;
		err = snd_ctl_add(card,
			snd_ctl_new1(&snd_emu1010_optical_out, emu));
		if (err < 0)
			return err;
		err = snd_ctl_add(card,
			snd_ctl_new1(&snd_emu1010_optical_in, emu));
		if (err < 0)
			return err;
	}
	}


	if ( emu->card_capabilities->i2c_adc) {
	if ( emu->card_capabilities->i2c_adc) {