[alsa-devel] [PATCH 2/2] ASoC: wm9712/wm9713: Replace virtual registers with custom put/get callbacks
Lars-Peter Clausen
lars at metafoo.de
Fri Nov 7 10:52:56 CET 2014
On 11/03/2014 07:33 PM, Lars-Peter Clausen wrote:
> The wm9712/wm9713 has separate mixers for the left and the right channel,
> but the inputs to the mixers are enabled/disabled by the same control.
> Currently this is implemented by the driver by registering two virtual
> controls for each physical control, one for the left mixer and one for the
> right mixer.
>
> Using virtual registers will no longer work when the driver has
> been converted to regmap. This patch converts the driver to use controls
> with custom put/get callbacks instead which implement the logic making sure
> that the physical control is unmuted when either the left or the right
> control is unmuted.
>
> Signed-off-by: Lars-Peter Clausen <lars at metafoo.de>
Hi Charles,
Given your usual fast responses on patches I'm suspecting that this one may
have been lost. If not I apologize for the noise.
Thanks,
- Lars
> ---
> sound/soc/codecs/wm9712.c | 163 +++++++++++++++++++++++++++++-----------------
> sound/soc/codecs/wm9713.c | 153 +++++++++++++++++++++++++------------------
> 2 files changed, 194 insertions(+), 122 deletions(-)
>
> diff --git a/sound/soc/codecs/wm9712.c b/sound/soc/codecs/wm9712.c
> index f3aab6e..3fad37e 100644
> --- a/sound/soc/codecs/wm9712.c
> +++ b/sound/soc/codecs/wm9712.c
> @@ -23,6 +23,11 @@
> #include <sound/tlv.h>
> #include "wm9712.h"
>
> +struct wm9712_priv {
> + unsigned int hp_mixer[2];
> + struct mutex lock;
> +};
> +
> static unsigned int ac97_read(struct snd_soc_codec *codec,
> unsigned int reg);
> static int ac97_write(struct snd_soc_codec *codec,
> @@ -48,12 +53,10 @@ static const u16 wm9712_reg[] = {
> 0x0000, 0x0000, 0x0000, 0x0000, /* 6e */
> 0x0000, 0x0000, 0x0000, 0x0006, /* 76 */
> 0x0001, 0x0000, 0x574d, 0x4c12, /* 7e */
> - 0x0000, 0x0000 /* virtual hp mixers */
> };
>
> -/* virtual HP mixers regs */
> -#define HPL_MIXER 0x80
> -#define HPR_MIXER 0x82
> +#define HPL_MIXER 0x0
> +#define HPR_MIXER 0x1
>
> static const char *wm9712_alc_select[] = {"None", "Left", "Right", "Stereo"};
> static const char *wm9712_alc_mux[] = {"Stereo", "Left", "Right", "None"};
> @@ -157,75 +160,108 @@ SOC_SINGLE_TLV("Mic 2 Volume", AC97_MIC, 0, 31, 1, main_tlv),
> SOC_SINGLE_TLV("Mic Boost Volume", AC97_MIC, 7, 1, 0, boost_tlv),
> };
>
> +static const unsigned int wm9712_mixer_mute_regs[] = {
> + AC97_VIDEO,
> + AC97_PCM,
> + AC97_LINE,
> + AC97_PHONE,
> + AC97_CD,
> + AC97_PC_BEEP,
> +};
> +
> /* 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 mixer_event(struct snd_soc_dapm_widget *w,
> - struct snd_kcontrol *k, int event)
> +static int wm9712_hp_mixer_put(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> {
> - u16 l, r, beep, line, phone, mic, pcm, aux;
> -
> - l = ac97_read(w->codec, HPL_MIXER);
> - r = ac97_read(w->codec, HPR_MIXER);
> - beep = ac97_read(w->codec, AC97_PC_BEEP);
> - mic = ac97_read(w->codec, AC97_VIDEO);
> - phone = ac97_read(w->codec, AC97_PHONE);
> - line = ac97_read(w->codec, AC97_LINE);
> - pcm = ac97_read(w->codec, AC97_PCM);
> - aux = ac97_read(w->codec, AC97_CD);
> -
> - if (l & 0x1 || r & 0x1)
> - ac97_write(w->codec, AC97_VIDEO, mic & 0x7fff);
> + 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.enumerated.item[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;
> + 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.enumerated.item[0])
> + wm9712->hp_mixer[mixer] |= mask;
> else
> - ac97_write(w->codec, AC97_VIDEO, mic | 0x8000);
> + 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);
> + }
>
> - if (l & 0x2 || r & 0x2)
> - ac97_write(w->codec, AC97_PCM, pcm & 0x7fff);
> - else
> - ac97_write(w->codec, AC97_PCM, pcm | 0x8000);
> + mutex_unlock(&wm9712->lock);
>
> - if (l & 0x4 || r & 0x4)
> - ac97_write(w->codec, AC97_LINE, line & 0x7fff);
> - else
> - ac97_write(w->codec, AC97_LINE, line | 0x8000);
> + return change;
> +}
>
> - if (l & 0x8 || r & 0x8)
> - ac97_write(w->codec, AC97_PHONE, phone & 0x7fff);
> - else
> - ac97_write(w->codec, AC97_PHONE, phone | 0x8000);
> +static int wm9712_hp_mixer_get(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);
> + struct soc_mixer_control *mc =
> + (struct soc_mixer_control *)kcontrol->private_value;
> + unsigned int shift, mixer;
>
> - if (l & 0x10 || r & 0x10)
> - ac97_write(w->codec, AC97_CD, aux & 0x7fff);
> - else
> - ac97_write(w->codec, AC97_CD, aux | 0x8000);
> + mixer = mc->shift >> 8;
> + shift = mc->shift & 0xff;
>
> - if (l & 0x20 || r & 0x20)
> - ac97_write(w->codec, AC97_PC_BEEP, beep & 0x7fff);
> - else
> - ac97_write(w->codec, AC97_PC_BEEP, beep | 0x8000);
> + ucontrol->value.enumerated.item[0] =
> + (wm9712->hp_mixer[mixer] >> shift) & 1;
>
> return 0;
> }
>
> +#define WM9712_HP_MIXER_CTRL(xname, xmixer, xshift) { \
> + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
> + .info = snd_soc_info_volsw, \
> + .get = wm9712_hp_mixer_get, .put = wm9712_hp_mixer_put, \
> + .private_value = SOC_SINGLE_VALUE(SND_SOC_NOPM, \
> + (xmixer << 8) | xshift, 1, 0, 0) \
> +}
> +
> /* Left Headphone Mixers */
> static const struct snd_kcontrol_new wm9712_hpl_mixer_controls[] = {
> - SOC_DAPM_SINGLE("PCBeep Bypass Switch", HPL_MIXER, 5, 1, 0),
> - SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 4, 1, 0),
> - SOC_DAPM_SINGLE("Phone Bypass Switch", HPL_MIXER, 3, 1, 0),
> - SOC_DAPM_SINGLE("Line Bypass Switch", HPL_MIXER, 2, 1, 0),
> - SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 1, 1, 0),
> - SOC_DAPM_SINGLE("Mic Sidetone Switch", HPL_MIXER, 0, 1, 0),
> + WM9712_HP_MIXER_CTRL("PCBeep Bypass Switch", HPL_MIXER, 5),
> + WM9712_HP_MIXER_CTRL("Aux Playback Switch", HPL_MIXER, 4),
> + WM9712_HP_MIXER_CTRL("Phone Bypass Switch", HPL_MIXER, 3),
> + WM9712_HP_MIXER_CTRL("Line Bypass Switch", HPL_MIXER, 2),
> + WM9712_HP_MIXER_CTRL("PCM Playback Switch", HPL_MIXER, 1),
> + WM9712_HP_MIXER_CTRL("Mic Sidetone Switch", HPL_MIXER, 0),
> };
>
> /* Right Headphone Mixers */
> static const struct snd_kcontrol_new wm9712_hpr_mixer_controls[] = {
> - SOC_DAPM_SINGLE("PCBeep Bypass Switch", HPR_MIXER, 5, 1, 0),
> - SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 4, 1, 0),
> - SOC_DAPM_SINGLE("Phone Bypass Switch", HPR_MIXER, 3, 1, 0),
> - SOC_DAPM_SINGLE("Line Bypass Switch", HPR_MIXER, 2, 1, 0),
> - SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 1, 1, 0),
> - SOC_DAPM_SINGLE("Mic Sidetone Switch", HPR_MIXER, 0, 1, 0),
> + WM9712_HP_MIXER_CTRL("PCBeep Bypass Switch", HPR_MIXER, 5),
> + WM9712_HP_MIXER_CTRL("Aux Playback Switch", HPR_MIXER, 4),
> + WM9712_HP_MIXER_CTRL("Phone Bypass Switch", HPR_MIXER, 3),
> + WM9712_HP_MIXER_CTRL("Line Bypass Switch", HPR_MIXER, 2),
> + WM9712_HP_MIXER_CTRL("PCM Playback Switch", HPR_MIXER, 1),
> + WM9712_HP_MIXER_CTRL("Mic Sidetone Switch", HPR_MIXER, 0),
> };
>
> /* Speaker Mixer */
> @@ -299,12 +335,10 @@ SND_SOC_DAPM_MUX("Right Mic Select Source", SND_SOC_NOPM, 0, 0,
> SND_SOC_DAPM_MUX("Differential Source", SND_SOC_NOPM, 0, 0,
> &wm9712_diff_sel_controls),
> SND_SOC_DAPM_MIXER("AC97 Mixer", SND_SOC_NOPM, 0, 0, NULL, 0),
> -SND_SOC_DAPM_MIXER_E("Left HP Mixer", AC97_INT_PAGING, 9, 1,
> - &wm9712_hpl_mixer_controls[0], ARRAY_SIZE(wm9712_hpl_mixer_controls),
> - mixer_event, SND_SOC_DAPM_POST_REG),
> -SND_SOC_DAPM_MIXER_E("Right HP Mixer", AC97_INT_PAGING, 8, 1,
> - &wm9712_hpr_mixer_controls[0], ARRAY_SIZE(wm9712_hpr_mixer_controls),
> - mixer_event, SND_SOC_DAPM_POST_REG),
> +SND_SOC_DAPM_MIXER("Left HP Mixer", AC97_INT_PAGING, 9, 1,
> + &wm9712_hpl_mixer_controls[0], ARRAY_SIZE(wm9712_hpl_mixer_controls)),
> +SND_SOC_DAPM_MIXER("Right HP Mixer", AC97_INT_PAGING, 8, 1,
> + &wm9712_hpr_mixer_controls[0], ARRAY_SIZE(wm9712_hpr_mixer_controls)),
> SND_SOC_DAPM_MIXER("Phone Mixer", AC97_INT_PAGING, 6, 1,
> &wm9712_phone_mixer_controls[0], ARRAY_SIZE(wm9712_phone_mixer_controls)),
> SND_SOC_DAPM_MIXER("Speaker Mixer", AC97_INT_PAGING, 7, 1,
> @@ -471,8 +505,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
> {
> u16 *cache = codec->reg_cache;
>
> - if (reg < 0x7c)
> - soc_ac97_ops->write(codec->ac97, reg, val);
> + soc_ac97_ops->write(codec->ac97, reg, val);
> reg = reg >> 1;
> if (reg < (ARRAY_SIZE(wm9712_reg)))
> cache[reg] = val;
> @@ -684,6 +717,16 @@ static struct snd_soc_codec_driver soc_codec_dev_wm9712 = {
>
> static int wm9712_probe(struct platform_device *pdev)
> {
> + struct wm9712_priv *wm9712;
> +
> + wm9712 = devm_kzalloc(&pdev->dev, sizeof(*wm9712), GFP_KERNEL);
> + if (wm9712 == NULL)
> + return -ENOMEM;
> +
> + mutex_init(&wm9712->lock);
> +
> + platform_set_drvdata(pdev, wm9712);
> +
> return snd_soc_register_codec(&pdev->dev,
> &soc_codec_dev_wm9712, wm9712_dai, ARRAY_SIZE(wm9712_dai));
> }
> diff --git a/sound/soc/codecs/wm9713.c b/sound/soc/codecs/wm9713.c
> index ac13fc8..998e4c7 100644
> --- a/sound/soc/codecs/wm9713.c
> +++ b/sound/soc/codecs/wm9713.c
> @@ -31,6 +31,8 @@
>
> struct wm9713_priv {
> u32 pll_in; /* PLL input frequency */
> + unsigned int hp_mixer[2];
> + struct mutex lock;
> };
>
> static unsigned int ac97_read(struct snd_soc_codec *codec,
> @@ -59,12 +61,10 @@ static const u16 wm9713_reg[] = {
> 0x0000, 0x0000, 0x0000, 0x0000,
> 0x0000, 0x0000, 0x0000, 0x0006,
> 0x0001, 0x0000, 0x574d, 0x4c13,
> - 0x0000, 0x0000
> };
>
> -/* virtual HP mixers regs */
> -#define HPL_MIXER 0x80
> -#define HPR_MIXER 0x82
> +#define HPL_MIXER 0
> +#define HPR_MIXER 1
>
> static const char *wm9713_mic_mixer[] = {"Stereo", "Mic 1", "Mic 2", "Mute"};
> static const char *wm9713_rec_mux[] = {"Stereo", "Left", "Right", "Mute"};
> @@ -233,6 +233,14 @@ static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w,
> return 0;
> }
>
> +static const unsigned int wm9713_mixer_mute_regs[] = {
> + AC97_PC_BEEP,
> + AC97_MASTER_TONE,
> + AC97_PHONE,
> + AC97_REC_SEL,
> + AC97_PCM,
> + AC97_AUX,
> +};
>
> /* 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.
> @@ -240,73 +248,95 @@ static int wm9713_voice_shutdown(struct snd_soc_dapm_widget *w,
> * register map, thus we add a new (virtual) register to help determine the
> * audio route within the device.
> */
> -static int mixer_event(struct snd_soc_dapm_widget *w,
> - struct snd_kcontrol *kcontrol, int event)
> +static int wm9713_hp_mixer_put(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> {
> - u16 l, r, beep, tone, phone, rec, pcm, aux;
> -
> - l = ac97_read(w->codec, HPL_MIXER);
> - r = ac97_read(w->codec, HPR_MIXER);
> - beep = ac97_read(w->codec, AC97_PC_BEEP);
> - tone = ac97_read(w->codec, AC97_MASTER_TONE);
> - phone = ac97_read(w->codec, AC97_PHONE);
> - rec = ac97_read(w->codec, AC97_REC_SEL);
> - pcm = ac97_read(w->codec, AC97_PCM);
> - aux = ac97_read(w->codec, AC97_AUX);
> -
> - if (event & SND_SOC_DAPM_PRE_REG)
> - return 0;
> - if ((l & 0x1) || (r & 0x1))
> - ac97_write(w->codec, AC97_PC_BEEP, beep & 0x7fff);
> + struct snd_soc_dapm_context *dapm = snd_soc_dapm_kcontrol_dapm(kcontrol);
> + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(dapm);
> + struct wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
> + unsigned int val = ucontrol->value.enumerated.item[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;
> + bool change;
> +
> + mixer = mc->shift >> 8;
> + shift = mc->shift & 0xff;
> + mask = (1 << shift);
> +
> + mutex_lock(&wm9713->lock);
> + old = wm9713->hp_mixer[mixer];
> + if (ucontrol->value.enumerated.item[0])
> + wm9713->hp_mixer[mixer] |= mask;
> else
> - ac97_write(w->codec, AC97_PC_BEEP, beep | 0x8000);
> + wm9713->hp_mixer[mixer] &= ~mask;
> +
> + change = old != wm9713->hp_mixer[mixer];
> + if (change) {
> + update.kcontrol = kcontrol;
> + update.reg = wm9713_mixer_mute_regs[shift];
> + update.mask = 0x8000;
> + if ((wm9713->hp_mixer[0] & mask) ||
> + (wm9713->hp_mixer[1] & mask))
> + update.val = 0x0;
> + else
> + update.val = 0x8000;
> +
> + snd_soc_dapm_mixer_update_power(dapm, kcontrol, val,
> + &update);
> + }
>
> - if ((l & 0x2) || (r & 0x2))
> - ac97_write(w->codec, AC97_MASTER_TONE, tone & 0x7fff);
> - else
> - ac97_write(w->codec, AC97_MASTER_TONE, tone | 0x8000);
> + mutex_unlock(&wm9713->lock);
>
> - if ((l & 0x4) || (r & 0x4))
> - ac97_write(w->codec, AC97_PHONE, phone & 0x7fff);
> - else
> - ac97_write(w->codec, AC97_PHONE, phone | 0x8000);
> + return change;
> +}
>
> - if ((l & 0x8) || (r & 0x8))
> - ac97_write(w->codec, AC97_REC_SEL, rec & 0x7fff);
> - else
> - ac97_write(w->codec, AC97_REC_SEL, rec | 0x8000);
> +static int wm9713_hp_mixer_get(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 wm9713_priv *wm9713 = snd_soc_codec_get_drvdata(codec);
> + struct soc_mixer_control *mc =
> + (struct soc_mixer_control *)kcontrol->private_value;
> + unsigned int mixer, shift;
>
> - if ((l & 0x10) || (r & 0x10))
> - ac97_write(w->codec, AC97_PCM, pcm & 0x7fff);
> - else
> - ac97_write(w->codec, AC97_PCM, pcm | 0x8000);
> + mixer = mc->shift >> 8;
> + shift = mc->shift & 0xff;
>
> - if ((l & 0x20) || (r & 0x20))
> - ac97_write(w->codec, AC97_AUX, aux & 0x7fff);
> - else
> - ac97_write(w->codec, AC97_AUX, aux | 0x8000);
> + ucontrol->value.enumerated.item[0] =
> + (wm9713->hp_mixer[mixer] >> shift) & 1;
>
> return 0;
> }
>
> +#define WM9713_HP_MIXER_CTRL(xname, xmixer, xshift) { \
> + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, .name = xname, \
> + .info = snd_soc_info_volsw, \
> + .get = wm9713_hp_mixer_get, .put = wm9713_hp_mixer_put, \
> + .private_value = SOC_DOUBLE_VALUE(SND_SOC_NOPM, \
> + xshift, xmixer, 1, 0, 0) \
> +}
> +
> /* Left Headphone Mixers */
> static const struct snd_kcontrol_new wm9713_hpl_mixer_controls[] = {
> -SOC_DAPM_SINGLE("Beep Playback Switch", HPL_MIXER, 5, 1, 0),
> -SOC_DAPM_SINGLE("Voice Playback Switch", HPL_MIXER, 4, 1, 0),
> -SOC_DAPM_SINGLE("Aux Playback Switch", HPL_MIXER, 3, 1, 0),
> -SOC_DAPM_SINGLE("PCM Playback Switch", HPL_MIXER, 2, 1, 0),
> -SOC_DAPM_SINGLE("MonoIn Playback Switch", HPL_MIXER, 1, 1, 0),
> -SOC_DAPM_SINGLE("Bypass Playback Switch", HPL_MIXER, 0, 1, 0),
> +WM9713_HP_MIXER_CTRL("Beep Playback Switch", HPL_MIXER, 5),
> +WM9713_HP_MIXER_CTRL("Voice Playback Switch", HPL_MIXER, 4),
> +WM9713_HP_MIXER_CTRL("Aux Playback Switch", HPL_MIXER, 3),
> +WM9713_HP_MIXER_CTRL("PCM Playback Switch", HPL_MIXER, 2),
> +WM9713_HP_MIXER_CTRL("MonoIn Playback Switch", HPL_MIXER, 1),
> +WM9713_HP_MIXER_CTRL("Bypass Playback Switch", HPL_MIXER, 0),
> };
>
> /* Right Headphone Mixers */
> static const struct snd_kcontrol_new wm9713_hpr_mixer_controls[] = {
> -SOC_DAPM_SINGLE("Beep Playback Switch", HPR_MIXER, 5, 1, 0),
> -SOC_DAPM_SINGLE("Voice Playback Switch", HPR_MIXER, 4, 1, 0),
> -SOC_DAPM_SINGLE("Aux Playback Switch", HPR_MIXER, 3, 1, 0),
> -SOC_DAPM_SINGLE("PCM Playback Switch", HPR_MIXER, 2, 1, 0),
> -SOC_DAPM_SINGLE("MonoIn Playback Switch", HPR_MIXER, 1, 1, 0),
> -SOC_DAPM_SINGLE("Bypass Playback Switch", HPR_MIXER, 0, 1, 0),
> +WM9713_HP_MIXER_CTRL("Beep Playback Switch", HPR_MIXER, 5),
> +WM9713_HP_MIXER_CTRL("Voice Playback Switch", HPR_MIXER, 4),
> +WM9713_HP_MIXER_CTRL("Aux Playback Switch", HPR_MIXER, 3),
> +WM9713_HP_MIXER_CTRL("PCM Playback Switch", HPR_MIXER, 2),
> +WM9713_HP_MIXER_CTRL("MonoIn Playback Switch", HPR_MIXER, 1),
> +WM9713_HP_MIXER_CTRL("Bypass Playback Switch", HPR_MIXER, 0),
> };
>
> /* headphone capture mux */
> @@ -428,12 +458,10 @@ SND_SOC_DAPM_MUX("Mic A Source", SND_SOC_NOPM, 0, 0,
> &wm9713_mic_sel_mux_controls),
> SND_SOC_DAPM_MUX("Mic B Source", SND_SOC_NOPM, 0, 0,
> &wm9713_micb_sel_mux_controls),
> -SND_SOC_DAPM_MIXER_E("Left HP Mixer", AC97_EXTENDED_MID, 3, 1,
> - &wm9713_hpl_mixer_controls[0], ARRAY_SIZE(wm9713_hpl_mixer_controls),
> - mixer_event, SND_SOC_DAPM_POST_REG),
> -SND_SOC_DAPM_MIXER_E("Right HP Mixer", AC97_EXTENDED_MID, 2, 1,
> - &wm9713_hpr_mixer_controls[0], ARRAY_SIZE(wm9713_hpr_mixer_controls),
> - mixer_event, SND_SOC_DAPM_POST_REG),
> +SND_SOC_DAPM_MIXER("Left HP Mixer", AC97_EXTENDED_MID, 3, 1,
> + &wm9713_hpl_mixer_controls[0], ARRAY_SIZE(wm9713_hpl_mixer_controls)),
> +SND_SOC_DAPM_MIXER("Right HP Mixer", AC97_EXTENDED_MID, 2, 1,
> + &wm9713_hpr_mixer_controls[0], ARRAY_SIZE(wm9713_hpr_mixer_controls)),
> SND_SOC_DAPM_MIXER("Mono Mixer", AC97_EXTENDED_MID, 0, 1,
> &wm9713_mono_mixer_controls[0], ARRAY_SIZE(wm9713_mono_mixer_controls)),
> SND_SOC_DAPM_MIXER("Speaker Mixer", AC97_EXTENDED_MID, 1, 1,
> @@ -666,8 +694,7 @@ static int ac97_write(struct snd_soc_codec *codec, unsigned int reg,
> unsigned int val)
> {
> u16 *cache = codec->reg_cache;
> - if (reg < 0x7c)
> - soc_ac97_ops->write(codec->ac97, reg, val);
> + soc_ac97_ops->write(codec->ac97, reg, val);
> reg = reg >> 1;
> if (reg < (ARRAY_SIZE(wm9713_reg)))
> cache[reg] = val;
> @@ -1251,6 +1278,8 @@ static int wm9713_probe(struct platform_device *pdev)
> if (wm9713 == NULL)
> return -ENOMEM;
>
> + mutex_init(&wm9713->lock);
> +
> platform_set_drvdata(pdev, wm9713);
>
> return snd_soc_register_codec(&pdev->dev,
>
More information about the Alsa-devel
mailing list