Commit 748b6ec3 authored by Tom Yan's avatar Tom Yan Committed by Takashi Iwai
Browse files

ALSA: virtuoso: add de-emphasis control



Add control for the de-emphasis filter in the PCM179x DACs

Signed-off-by: default avatarTom Yan <tom.ty89@gmail.com>
Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
parent c2a7c55a
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -10,7 +10,6 @@
#define PCM1796_MUTE		0x01
#define PCM1796_DME		0x02
#define PCM1796_DMF_MASK	0x0c
#define PCM1796_DMF_DISABLED	0x00
#define PCM1796_DMF_48		0x04
#define PCM1796_DMF_441		0x08
#define PCM1796_DMF_32		0x0c
+69 −2
Original line number Diff line number Diff line
@@ -331,7 +331,7 @@ static void pcm1796_init(struct oxygen *chip)
	struct xonar_pcm179x *data = chip->model_data;

	data->pcm1796_regs[0][18 - PCM1796_REG_BASE] =
		PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
		PCM1796_FMT_24_I2S | PCM1796_ATLD;
	if (!data->broken_i2c)
		data->pcm1796_regs[0][18 - PCM1796_REG_BASE] |= PCM1796_MUTE;
	data->pcm1796_regs[0][19 - PCM1796_REG_BASE] =
@@ -621,6 +621,23 @@ static void update_pcm1796_oversampling(struct oxygen *chip)
		pcm1796_write_cached(chip, i, 20, reg);
}

static void update_pcm1796_deemph(struct oxygen *chip)
{
	struct xonar_pcm179x *data = chip->model_data;
	unsigned int i;
	u8 reg;

	reg = data->pcm1796_regs[0][18 - PCM1796_REG_BASE] & ~PCM1796_DMF_MASK;
	if (data->current_rate == 48000)
		reg |= PCM1796_DMF_48;
	else if (data->current_rate == 44100)
		reg |= PCM1796_DMF_441;
	else if (data->current_rate == 32000)
		reg |= PCM1796_DMF_32;
	for (i = 0; i < data->dacs; ++i)
		pcm1796_write_cached(chip, i, 18, reg);
}

static void set_pcm1796_params(struct oxygen *chip,
			       struct snd_pcm_hw_params *params)
{
@@ -629,6 +646,7 @@ static void set_pcm1796_params(struct oxygen *chip,
	msleep(1);
	data->current_rate = params_rate(params);
	update_pcm1796_oversampling(chip);
	update_pcm1796_deemph(chip);
}

static void update_pcm1796_volume(struct oxygen *chip)
@@ -653,9 +671,11 @@ static void update_pcm1796_mute(struct oxygen *chip)
	unsigned int i;
	u8 value;

	value = PCM1796_DMF_DISABLED | PCM1796_FMT_24_I2S | PCM1796_ATLD;
	value = data->pcm1796_regs[0][18 - PCM1796_REG_BASE];
	if (chip->dac_mute)
		value |= PCM1796_MUTE;
	else
		value &= ~PCM1796_MUTE;
	for (i = 0; i < data->dacs; ++i)
		pcm1796_write_cached(chip, i, 18, value);
}
@@ -777,6 +797,49 @@ static const struct snd_kcontrol_new rolloff_control = {
	.put = rolloff_put,
};

static int deemph_get(struct snd_kcontrol *ctl,
		       struct snd_ctl_elem_value *value)
{
	struct oxygen *chip = ctl->private_data;
	struct xonar_pcm179x *data = chip->model_data;

	value->value.integer.value[0] =
		!!(data->pcm1796_regs[0][18 - PCM1796_REG_BASE] & PCM1796_DME);
	return 0;
}

static int deemph_put(struct snd_kcontrol *ctl,
		       struct snd_ctl_elem_value *value)
{
	struct oxygen *chip = ctl->private_data;
	struct xonar_pcm179x *data = chip->model_data;
	unsigned int i;
	int changed;
	u8 reg;

	mutex_lock(&chip->mutex);
	reg = data->pcm1796_regs[0][18 - PCM1796_REG_BASE];
	if (!value->value.integer.value[0])
		reg &= ~PCM1796_DME;
	else
		reg |= PCM1796_DME;
	changed = reg != data->pcm1796_regs[0][18 - PCM1796_REG_BASE];
	if (changed) {
		for (i = 0; i < data->dacs; ++i)
			pcm1796_write(chip, i, 18, reg);
	}
	mutex_unlock(&chip->mutex);
	return changed;
}

static const struct snd_kcontrol_new deemph_control = {
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	.name = "De-emphasis Playback Switch",
	.info = snd_ctl_boolean_mono_info,
	.get = deemph_get,
	.put = deemph_put,
};

static const struct snd_kcontrol_new hdav_hdmi_control = {
	.iface = SNDRV_CTL_ELEM_IFACE_MIXER,
	.name = "HDMI Playback Switch",
@@ -1011,6 +1074,10 @@ static int add_pcm1796_controls(struct oxygen *chip)
				  snd_ctl_new1(&rolloff_control, chip));
		if (err < 0)
			return err;
		err = snd_ctl_add(chip->card,
				  snd_ctl_new1(&deemph_control, chip));
		if (err < 0)
			return err;
	}
	return 0;
}