示例#1
0
文件: arizona.c 项目: SelfImp/m75
int arizona_mux_put(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
	struct snd_soc_codec *codec = widget->codec;
	struct snd_soc_card *card = codec->card;
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	unsigned int val, mux, change;
	unsigned int mask;
	struct snd_soc_dapm_update update;
	int wi;

	if (ucontrol->value.enumerated.item[0] > e->max - 1)
		return -EINVAL;
	mux = ucontrol->value.enumerated.item[0];
	val = e->values[ucontrol->value.enumerated.item[0]] << e->shift_l;
	mask = e->mask << e->shift_l;
	if (e->shift_l != e->shift_r) {
		if (ucontrol->value.enumerated.item[1] > e->max - 1)
			return -EINVAL;
		val |= e->values[ucontrol->value.enumerated.item[1]] << e->shift_r;
		mask |= e->mask << e->shift_r;
	}

	change = snd_soc_test_bits(widget->codec, e->reg, mask, val);

	if (change) {
		for (wi = 0; wi < wlist->num_widgets; wi++) {

			widget = wlist->widgets[wi];

			widget->value = val;

			update.kcontrol = kcontrol;
			update.widget = widget;
			update.reg = e->reg;
			update.mask = mask;
			update.val = val;
			widget->dapm->update = &update;

			snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e);

			widget->dapm->update = NULL;
		}
	}

	return change;
}
示例#2
0
文件: adau17x1.c 项目: krzk/linux
/*
 * 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_component *component = snd_soc_dapm_kcontrol_component(kcontrol);
	struct snd_soc_dapm_context *dapm = snd_soc_component_get_dapm(component);
	struct adau *adau = snd_soc_component_get_drvdata(component);
	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_component_test_bits(component, 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;
}
static int ul_mux_put_route(struct snd_kcontrol *kcontrol,
	struct snd_ctl_elem_value *ucontrol)
{
	struct snd_soc_dapm_widget_list *wlist = snd_kcontrol_chip(kcontrol);
	struct snd_soc_dapm_widget *widget = wlist->widgets[0];
	struct snd_soc_platform *platform = widget->platform;
	struct omap_abe *abe = snd_soc_platform_get_drvdata(platform);
	struct soc_enum *e = (struct soc_enum *)kcontrol->private_value;
	int mux = ucontrol->value.enumerated.item[0];
	int reg = e->reg - OMAP_ABE_MUX(0);

	if (mux > OMAP_ABE_ROUTES_UL) {
		pr_err("inavlid mux %d\n", mux);
		return 0;
	}

	abe_dsp_pm_get(abe);

	/* TODO: remove the gap */
	if (reg < 8) {
		/* 0  .. 9   = MM_UL */
		abe->mixer.route_ul[reg] = router[mux];
	} else if (reg < 12) {
		/* 10 .. 11  = MM_UL2 */
		/* 12 .. 13  = VX_UL */
		abe->mixer.route_ul[reg + 2] = router[mux];
	}

	/* 2nd arg here is unused */
	omap_aess_set_router_configuration(abe->aess, UPROUTE, 0, (u32 *)abe->mixer.route_ul);

	if (router[mux] != ZERO_labelID)
		abe->opp.widget[e->reg] = e->shift_l;
	else
		abe->opp.widget[e->reg] = 0;

	snd_soc_dapm_mux_update_power(widget, kcontrol, mux, e);
	pm_runtime_put_sync(abe->dev);

	return 1;
}