From 3ec7a20593d243f54d38a9b62f9ecd59aed1c1eb Mon Sep 17 00:00:00 2001 From: Ola Lilja Date: Wed, 6 Jul 2011 10:25:47 +0200 Subject: Ux500 ASoC: Move mic-regulators into DAPM-paths Race-conditions could occur when mic-regulators were turned on/off outside DAPM-paths. They are now moved into machine-driver DAPM-paths. ST-Ericsson Linux next: NA ST-Ericsson ID: 348272 ST-Ericsson FOSS-OUT ID: Trivial Change-Id: I27b7225326db9c0ccaaabf5aec5bbc9c3cfbd573 Signed-off-by: Ola Lilja Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/26679 Reviewed-by: Roger NILSSON1 Tested-by: Roger NILSSON1 Reviewed-by: Jonas ABERG Conflicts: sound/soc/codecs/ab8500_audio.c sound/soc/ux500/ux500_ab8500.c Change-Id: Ic32c44f335a54a7a52fb395503af860ba2aae94d Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/30844 Reviewed-by: Roger NILSSON1 Tested-by: Roger NILSSON1 Reviewed-by: Avinash A Tested-by: Avinash A --- sound/soc/codecs/ab8500_audio.c | 38 +++----- sound/soc/ux500/ux500_ab8500.c | 209 +++++++++++++++++++++++++++------------- 2 files changed, 156 insertions(+), 91 deletions(-) (limited to 'sound') diff --git a/sound/soc/codecs/ab8500_audio.c b/sound/soc/codecs/ab8500_audio.c index 1a4db42e333..a3ae8296825 100644 --- a/sound/soc/codecs/ab8500_audio.c +++ b/sound/soc/codecs/ab8500_audio.c @@ -646,7 +646,7 @@ static const struct snd_kcontrol_new dapm_pwm2vib2[] = { SOC_DAPM_ENUM("Vibra 2 Controller", dapm_enum_pwm2vib2), }; -/* DAPM Widgets */ +/* DAPM-widgets */ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = { /* Headset path */ @@ -772,7 +772,7 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = { SND_SOC_DAPM_INPUT("LINL"), SND_SOC_DAPM_INPUT("LINR"), - SND_SOC_DAPM_INPUT("MIC2"), + SND_SOC_DAPM_INPUT("MIC2 Input"), SND_SOC_DAPM_SWITCH("LineIn Left", SND_SOC_NOPM, 0, 0, dapm_linl_mute), SND_SOC_DAPM_SWITCH("LineIn Right", SND_SOC_NOPM, 0, 0, dapm_linr_mute), @@ -809,8 +809,7 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = { /* Microphone 1 path */ - SND_SOC_DAPM_INPUT("MIC1A"), - SND_SOC_DAPM_INPUT("MIC1B"), + SND_SOC_DAPM_INPUT("MIC1 Input"), SND_SOC_DAPM_MUX("Mic 1A or 1B Select Capture Route", SND_SOC_NOPM, 0, 0, dapm_mic1ab_select), @@ -853,12 +852,7 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = { /* Digital Microphone path */ - SND_SOC_DAPM_INPUT("DMIC1"), - SND_SOC_DAPM_INPUT("DMIC2"), - SND_SOC_DAPM_INPUT("DMIC3"), - SND_SOC_DAPM_INPUT("DMIC4"), - SND_SOC_DAPM_INPUT("DMIC5"), - SND_SOC_DAPM_INPUT("DMIC6"), + SND_SOC_DAPM_INPUT("DMIC Input"), SND_SOC_DAPM_SWITCH("DMic 1", SND_SOC_NOPM, 0, 0, dapm_dmic1_mute), SND_SOC_DAPM_SWITCH("DMic 2", SND_SOC_NOPM, 0, 0, dapm_dmic2_mute), @@ -904,9 +898,9 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = { SND_SOC_DAPM_MIXER("STFIR2 Gain", SND_SOC_NOPM, 0, 0, NULL, 0), }; -/* DAPM interconnection */ +/* DAPM-routes */ -static const struct snd_soc_dapm_route intercon[] = { +static const struct snd_soc_dapm_route dapm_routes[] = { /* Headset path */ {"DA1 Channel Gain", NULL, "DA_IN1"}, @@ -992,7 +986,7 @@ static const struct snd_soc_dapm_route intercon[] = { {"LineIn Left", "Capture Switch", "LINL"}, {"LineIn Right", "Capture Switch", "LINR"}, - {"Mic 2", "Capture Switch", "MIC2"}, + {"Mic 2", "Capture Switch", "MIC2 Input"}, {"LINL Enable", NULL, "LineIn Left"}, {"LINR Enable", NULL, "LineIn Right"}, @@ -1018,8 +1012,8 @@ static const struct snd_soc_dapm_route intercon[] = { /* Microphone 1 path */ - {"Mic 1A or 1B Select Capture Route", "Mic 1A", "MIC1A"}, - {"Mic 1A or 1B Select Capture Route", "Mic 1B", "MIC1B"}, + {"Mic 1A or 1B Select Capture Route", "Mic 1A", "MIC1 Input"}, + {"Mic 1A or 1B Select Capture Route", "Mic 1B", "MIC1 Input"}, {"Mic 1", "Capture Switch", "Mic 1A or 1B Select Capture Route"}, @@ -1051,12 +1045,12 @@ static const struct snd_soc_dapm_route intercon[] = { /* Digital Microphone path */ - {"DMic 1", "Capture Switch", "DMIC1"}, - {"DMic 2", "Capture Switch", "DMIC2"}, - {"DMic 3", "Capture Switch", "DMIC3"}, - {"DMic 4", "Capture Switch", "DMIC4"}, - {"DMic 5", "Capture Switch", "DMIC5"}, - {"DMic 6", "Capture Switch", "DMIC6"}, + {"DMic 1", "Capture Switch", "DMIC Input"}, + {"DMic 2", "Capture Switch", "DMIC Input"}, + {"DMic 3", "Capture Switch", "DMIC Input"}, + {"DMic 4", "Capture Switch", "DMIC Input"}, + {"DMic 5", "Capture Switch", "DMIC Input"}, + {"DMic 6", "Capture Switch", "DMIC Input"}, {"AD 1 Select Capture Route", "DMic 1", "DMic 1"}, {"AD 2 Select Capture Route", "DMic 2", "DMic 2"}, @@ -2011,7 +2005,7 @@ static int ab8500_codec_add_widgets(struct snd_soc_codec *codec) return ret; } - ret = snd_soc_dapm_add_routes(&codec->dapm, intercon, ARRAY_SIZE(intercon)); + ret = snd_soc_dapm_add_routes(&codec->dapm, dapm_routes, ARRAY_SIZE(dapm_routes)); if (ret < 0) { pr_err("%s: Failed to add DAPM routes (%d).\n", __func__, ret); diff --git a/sound/soc/ux500/ux500_ab8500.c b/sound/soc/ux500/ux500_ab8500.c index 128820b51cd..47d4b84f21a 100644 --- a/sound/soc/ux500/ux500_ab8500.c +++ b/sound/soc/ux500/ux500_ab8500.c @@ -19,8 +19,9 @@ #include #include #include -#include #include +#include +#include #include #include #include @@ -82,55 +83,6 @@ static bool reg_enabled[4] = { static unsigned int tx_slots = DEF_TX_SLOTS; static unsigned int rx_slots = DEF_RX_SLOTS; -/* Machine-driver ALSA-controls */ - -static int mclk_input_control_info(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_info *uinfo) -{ - uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; - uinfo->count = 1; - uinfo->value.enumerated.items = 2; - if (uinfo->value.enumerated.item) { - uinfo->value.enumerated.item = 1; - strcpy(uinfo->value.enumerated.name, "ULPCLK"); - } else { - strcpy(uinfo->value.enumerated.name, "SYSCLK"); - } - return 0; -} - -static int mclk_input_control_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - ucontrol->value.enumerated.item[0] = master_clock_sel; - return 0; -} - -static int mclk_input_control_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - unsigned int val; - - val = (ucontrol->value.enumerated.item[0] != 0); - if (master_clock_sel == val) - return 0; - - master_clock_sel = val; - - return 1; -} - -static const struct snd_kcontrol_new mclk_input_control = { - .iface = SNDRV_CTL_ELEM_IFACE_MIXER, - .name = "Master Clock Select", - .index = 0, - .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, - .info = mclk_input_control_info, - .get = mclk_input_control_get, - .put = mclk_input_control_put, - .private_value = 1 /* ULPCLK */ -}; - /* Regulators */ static int enable_regulator(enum regulator_idx idx) @@ -209,6 +161,137 @@ err_get: return status; } +/* Controls - Non-DAPM Non-ASoC */ + +static int mclk_input_control_info(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_info *uinfo) +{ + uinfo->type = SNDRV_CTL_ELEM_TYPE_ENUMERATED; + uinfo->count = 1; + uinfo->value.enumerated.items = 2; + if (uinfo->value.enumerated.item) { + uinfo->value.enumerated.item = 1; + strcpy(uinfo->value.enumerated.name, "ULPCLK"); + } else { + strcpy(uinfo->value.enumerated.name, "SYSCLK"); + } + return 0; +} + +static int mclk_input_control_get(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + ucontrol->value.enumerated.item[0] = master_clock_sel; + return 0; +} + +static int mclk_input_control_put(struct snd_kcontrol *kcontrol, + struct snd_ctl_elem_value *ucontrol) +{ + unsigned int val; + + val = (ucontrol->value.enumerated.item[0] != 0); + if (master_clock_sel == val) + return 0; + + master_clock_sel = val; + + return 1; +} + +static const struct snd_kcontrol_new mclk_input_control = { + .iface = SNDRV_CTL_ELEM_IFACE_MIXER, + .name = "Master Clock Select", + .index = 0, + .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, + .info = mclk_input_control_info, + .get = mclk_input_control_get, + .put = mclk_input_control_put, + .private_value = 1 /* ULPCLK */ +}; + +/* DAPM-events */ + +static int dapm_mic1reg_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + int ret = 0; + + if (SND_SOC_DAPM_EVENT_ON(event)) + ret = enable_regulator(REGULATOR_AMIC1); + else + disable_regulator(REGULATOR_AMIC1); + + return ret; +} + +static int dapm_mic2reg_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + int ret = 0; + + if (SND_SOC_DAPM_EVENT_ON(event)) + ret = enable_regulator(REGULATOR_AMIC2); + else + disable_regulator(REGULATOR_AMIC2); + + return ret; +} + +static int dapm_dmicreg_event(struct snd_soc_dapm_widget *w, + struct snd_kcontrol *k, int event) +{ + int ret = 0; + + if (SND_SOC_DAPM_EVENT_ON(event)) + ret = enable_regulator(REGULATOR_DMIC); + else + disable_regulator(REGULATOR_DMIC); + + return ret; +} + +/* DAPM-widgets */ + +static const struct snd_soc_dapm_widget ux500_ab8500_dapm_widgets[] = { + SND_SOC_DAPM_MIC("MIC1 Regulator", dapm_mic1reg_event), + SND_SOC_DAPM_MIC("MIC2 Regulator", dapm_mic2reg_event), + SND_SOC_DAPM_MIC("DMIC Regulator", dapm_dmicreg_event), +}; + +/* DAPM-routes */ + +static const struct snd_soc_dapm_route ux500_ab8500_dapm_intercon[] = { + {"MIC1 Input", NULL, "MIC1 Regulator"}, + {"MIC2 Input", NULL, "MIC2 Regulator"}, + {"DMIC Input", NULL, "DMIC Regulator"}, +}; + +static int add_widgets(struct snd_soc_codec *codec) +{ + int ret; + + ret = snd_soc_dapm_new_controls(&codec->dapm, + ux500_ab8500_dapm_widgets, + ARRAY_SIZE(ux500_ab8500_dapm_widgets)); + if (ret < 0) { + pr_err("%s: Failed to create DAPM controls (%d).\n", + __func__, ret); + return ret; + } + + ret = snd_soc_dapm_add_routes(&codec->dapm, + ux500_ab8500_dapm_intercon, + ARRAY_SIZE(ux500_ab8500_dapm_intercon)); + if (ret < 0) { + pr_err("%s: Failed to add DAPM routes (%d).\n", + __func__, ret); + return ret; + } + + return 0; +} + /* Power/clock control */ static int ux500_ab8500_power_control_inc(void) @@ -295,18 +378,6 @@ int ux500_ab8500_startup(struct snd_pcm_substream *substream) pr_debug("%s: Enter\n", __func__); - /* If we start recording we better enable the needed mic-regulators */ - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - if (ab8500_audio_dapm_path_active(AB8500_AUDIO_DAPM_PATH_DMIC)) - ret += enable_regulator(REGULATOR_DMIC); - if (ab8500_audio_dapm_path_active(AB8500_AUDIO_DAPM_PATH_AMIC1)) - ret += enable_regulator(REGULATOR_AMIC1); - if (ab8500_audio_dapm_path_active(AB8500_AUDIO_DAPM_PATH_AMIC2)) - ret += enable_regulator(REGULATOR_AMIC2); - if (ret != 0) - return ret; - } - /* Enable gpio.1-clock (needed by DSP in burst mode) */ ret = clk_enable(clk_ptr_gpio1); if (ret) { @@ -327,13 +398,6 @@ void ux500_ab8500_shutdown(struct snd_pcm_substream *substream) else rx_slots = DEF_RX_SLOTS; - /* Disable all mic-regulators that were enabled when we stop recording */ - if (substream->stream == SNDRV_PCM_STREAM_CAPTURE) { - disable_regulator(REGULATOR_DMIC); - disable_regulator(REGULATOR_AMIC1); - disable_regulator(REGULATOR_AMIC2); - } - clk_disable(clk_ptr_gpio1); ux500_ab8500_power_control_dec(); } @@ -528,6 +592,13 @@ int ux500_ab8500_machine_codec_init(struct snd_soc_pcm_runtime *rtd) ab8500_power_count = 0; + /* Add DAPM-widgets */ + ret = add_widgets(codec); + if (ret < 0) { + pr_err("%s: Failed add widgets (%d).\n", __func__, ret); + return ret; + } + return 0; } -- cgit v1.2.3