/* TODO: we have to use the shift value atm to represent register * id due to current HAL ID MACROS not being unique. */ static int put_mixer(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_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; abe_dsp_pm_get(abe); if (ucontrol->value.integer.value[0]) { abe->opp.widget[mc->reg] |= ucontrol->value.integer.value[0]<<mc->shift; snd_soc_dapm_mixer_update_power(widget, kcontrol, 1); omap_aess_enable_gain(abe->aess, mc->reg); } else { abe->opp.widget[mc->reg] &= ~(0x1<<mc->shift); snd_soc_dapm_mixer_update_power(widget, kcontrol, 0); omap_aess_disable_gain(abe->aess, mc->reg); } pm_runtime_put_sync(abe->dev); return 1; }
/* We have to create a fake left and right HP mixers because * the codec only has a single control that is shared by both channels. * This makes it impossible to determine the audio path. */ static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol); struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm); struct wm9712_priv *wm9712 = snd_soc_codec_get_drvdata(codec); unsigned int val = ucontrol->value.integer.value[0]; struct soc_mixer_control *mc = (struct soc_mixer_control *)kcontrol->private_value; unsigned int mixer, mask, shift, old; struct snd_soc_dapm_update update = { 0 }; bool change; mixer = mc->shift >> 8; shift = mc->shift & 0xff; mask = 1 << shift; mutex_lock(&wm9712->lock); old = wm9712->hp_mixer[mixer]; if (ucontrol->value.integer.value[0]) wm9712->hp_mixer[mixer] |= mask; else wm9712->hp_mixer[mixer] &= ~mask; change = old != wm9712->hp_mixer[mixer]; if (change) { update.kcontrol = kcontrol; update.reg = wm9712_mixer_mute_regs[shift]; update.mask = 0x8000; if ((wm9712->hp_mixer[0] & mask) || (wm9712->hp_mixer[1] & mask)) update.val = 0x0; else update.val = 0x8000; snd_soc_dapm_mixer_update_power(dapm, kcontrol, val, &update); } mutex_unlock(&wm9712->lock); return change; }
int tse850_put_mix(struct snd_kcontrol *kctrl, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kctrl); struct snd_soc_card *card = dapm->card; struct tse850_priv *tse850 = snd_soc_card_get_drvdata(card); int connect = !!ucontrol->value.integer.value[0]; if (tse850->add_cache == connect) return 0; /* * Hmmm, this gpiod_set_value_cansleep call should probably happen * inside snd_soc_dapm_mixer_update_power in the loop. */ gpiod_set_value_cansleep(tse850->add, connect); tse850->add_cache = connect; snd_soc_dapm_mixer_update_power(dapm, kctrl, connect, NULL); return 1; }