Exemplo n.º 1
0
static int adau17x1_dsp_mux_enum_get(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
	struct adau *adau = snd_soc_codec_get_drvdata(codec);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	unsigned int stream = e->shift_l;
	unsigned int reg, val;
	int ret;

	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
		reg = ADAU17X1_SERIAL_INPUT_ROUTE;
	else
		reg = ADAU17X1_SERIAL_OUTPUT_ROUTE;

	ret = regmap_read(adau->regmap, reg, &val);
	if (ret)
		return ret;

	if (val != 0)
		val = 1;
	ucontrol->value.enumerated.item[0] = val;

	return 0;
}
Exemplo n.º 2
0
static int txsrc_put(struct snd_kcontrol *kcontrol,
		     struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	unsigned int val = ucontrol->value.enumerated.item[0] << e->shift_l;
	unsigned int mask = 1 << e->shift_l;
	unsigned int txpwr;

	if (val != 0 && val != mask)
		return -EINVAL;

	snd_soc_dapm_mutex_lock(dapm);

	if (snd_soc_test_bits(codec, e->reg, mask, val)) {
		/* save the current power state of the transmitter */
		txpwr = snd_soc_read(codec, WM8804_PWRDN) & 0x4;

		/* power down the transmitter */
		snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, 0x4);

		/* set the tx source */
		snd_soc_update_bits(codec, e->reg, mask, val);

		/* restore the transmitter's configuration */
		snd_soc_update_bits(codec, WM8804_PWRDN, 0x4, txpwr);
	}

	snd_soc_dapm_mutex_unlock(dapm);

	return 0;
}
Exemplo n.º 3
0
/*
 * The MUX register for the Capture and Playback MUXs selects either DSP as
 * source/destination or one of the TDM slots. The TDM slot is selected via
 * snd_soc_dai_set_tdm_slot(), so we only expose whether to go to the DSP or
 * directly to the DAI interface with this control.
 */
static int adau17x1_dsp_mux_enum_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_codec *codec = snd_soc_dapm_kcontrol_codec(kcontrol);
	struct snd_soc_dapm_context *dapm = snd_soc_codec_get_dapm(codec);
	struct adau *adau = snd_soc_codec_get_drvdata(codec);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	struct snd_soc_dapm_update update;
	unsigned int stream = e->shift_l;
	unsigned int val, change;
	int reg;

	if (ucontrol->value.enumerated.item[0] >= e->items)
		return -EINVAL;

	switch (ucontrol->value.enumerated.item[0]) {
	case 0:
		val = 0;
		adau->dsp_bypass[stream] = false;
		break;
	default:
		val = (adau->tdm_slot[stream] * 2) + 1;
		adau->dsp_bypass[stream] = true;
		break;
	}

	if (stream == SNDRV_PCM_STREAM_PLAYBACK)
		reg = ADAU17X1_SERIAL_INPUT_ROUTE;
	else
		reg = ADAU17X1_SERIAL_OUTPUT_ROUTE;

	change = snd_soc_test_bits(codec, reg, 0xff, val);
	if (change) {
		update.kcontrol = kcontrol;
		update.mask = 0xff;
		update.reg = reg;
		update.val = val;

		snd_soc_dapm_mux_update_power(dapm, kcontrol,
				ucontrol->value.enumerated.item[0], e, &update);
	}

	return change;
}