/* Same as snd_soc_dapm_put_volsw, but change power state */ static int wm8350_dapm_put_volsw(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); struct snd_soc_codec *codec = widget->codec; if (ucontrol->value.integer.value[0]) { if (codec->dapm_state != SNDRV_CTL_POWER_D0) { wm8350_dapm_event(codec, SNDRV_CTL_POWER_D1); snd_soc_dapm_put_volsw(kcontrol, ucontrol); wm8350_dapm_event(codec, SNDRV_CTL_POWER_D0); } else snd_soc_dapm_put_volsw(kcontrol, ucontrol); } else { snd_soc_dapm_put_volsw(kcontrol, ucontrol); wm8350_dapm_event(codec, SNDRV_CTL_POWER_D3hot); } }
/* * When used with DAC outputs only the WM8903 charge pump supports * operation in class W mode, providing very low power consumption * when used with digital sources. Enable and disable this mode * automatically depending on the mixer configuration. * * All the relevant controls are simple switches. */ static int wm8903_class_w_put(struct snd_kcontrol *kcontrol, struct snd_ctl_elem_value *ucontrol) { struct snd_soc_dapm_widget *widget = snd_kcontrol_chip(kcontrol); struct snd_soc_codec *codec = widget->codec; struct wm8903_priv *wm8903 = codec->private_data; struct i2c_client *i2c = codec->control_data; u16 reg; int ret; reg = snd_soc_read(codec, WM8903_CLASS_W_0); /* Turn it off if we're about to enable bypass */ if (ucontrol->value.integer.value[0]) { if (wm8903->class_w_users == 0) { dev_dbg(&i2c->dev, "Disabling Class W\n"); snd_soc_write(codec, WM8903_CLASS_W_0, reg & ~(WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V)); } wm8903->class_w_users++; } /* Implement the change */ ret = snd_soc_dapm_put_volsw(kcontrol, ucontrol); /* If we've just disabled the last bypass path turn Class W on */ if (!ucontrol->value.integer.value[0]) { if (wm8903->class_w_users == 1) { dev_dbg(&i2c->dev, "Enabling Class W\n"); snd_soc_write(codec, WM8903_CLASS_W_0, reg | WM8903_CP_DYN_FREQ | WM8903_CP_DYN_V); } wm8903->class_w_users--; } dev_dbg(&i2c->dev, "Bypass use count now %d\n", wm8903->class_w_users); return ret; }