ASoC: msm/apq: Remove the dependency of AUX PCM TX to AUX PCM RX.
AUX PCM interface is a bi-direction interface which RX and TX paths
share the clock and sync word. In current design, it is assumed
when TX path is activated, RX path was enabled beforehand. So the
AUX PCM clock and GPIO pin configuration is only tied to AUX PCM RX
path. There is use case that only AUX PCM TX path is activated by
application so the AUX PCM clock and GPIOs are never configured
in this case which causes recording from AUX PCM TX failed to
capture any audio sample.
The solution is to update the clock and GPIO pin configuration to
both RX and TX path and then use an atomic reference counter to
prevent them configured twice.
CRs-Fixed: 397095
Signed-off-by: Kuirong Wang <kuirongw@codeaurora.org>
(cherry picked from commit ae395b024194bf6ae633a67dd1c2a5b3c7f1e019)
Conflicts:
sound/soc/msm/msm8974.c
Change-Id: If7f044de3cc4819e61fe66cd865755dceb5c45eb
Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
(cherry picked from commit eba5065dc6a84da68e5d9bcf6cb1934324698fec)
Signed-off-by: Sudhir Sharma <sudsha@codeaurora.org>
diff --git a/sound/soc/msm/apq8064-i2s.c b/sound/soc/msm/apq8064-i2s.c
index 162f39d..f57d686 100644
--- a/sound/soc/msm/apq8064-i2s.c
+++ b/sound/soc/msm/apq8064-i2s.c
@@ -208,6 +208,7 @@
static struct snd_soc_jack hs_jack;
static struct snd_soc_jack button_jack;
+static atomic_t auxpcm_rsc_ref;
static int apq8064_i2s_hs_detect_use_gpio = -1;
module_param(apq8064_i2s_hs_detect_use_gpio, int, 0444);
@@ -2095,8 +2096,10 @@
{
int ret = 0;
- pr_debug("%s(): substream = %s\n", __func__, substream->name);
- ret = msm_aux_pcm_get_gpios();
+ pr_debug("%s(): substream = %s, auxpcm_rsc_ref counter = %d\n",
+ __func__, substream->name, atomic_read(&auxpcm_rsc_ref));
+ if (atomic_inc_return(&auxpcm_rsc_ref) == 1)
+ ret = msm_aux_pcm_get_gpios();
if (ret < 0) {
pr_err("%s: Aux PCM GPIO request failed\n", __func__);
return -EINVAL;
@@ -2120,8 +2123,10 @@
static void msm_auxpcm_shutdown(struct snd_pcm_substream *substream)
{
- pr_debug("%s(): substream = %s\n", __func__, substream->name);
- msm_aux_pcm_free_gpios();
+ pr_debug("%s(): substream = %s, auxpcm_rsc_ref counter = %d\n",
+ __func__, substream->name, atomic_read(&auxpcm_rsc_ref));
+ if (atomic_dec_return(&auxpcm_rsc_ref) == 0)
+ msm_aux_pcm_free_gpios();
}
static void msm_shutdown(struct snd_pcm_substream *substream)
@@ -2710,6 +2715,7 @@
.no_pcm = 1,
.be_id = MSM_BACKEND_DAI_AUXPCM_TX,
.be_hw_params_fixup = msm_auxpcm_be_params_fixup,
+ .ops = &msm_auxpcm_be_ops,
},
};
@@ -2785,6 +2791,7 @@
mutex_init(&cdc_mclk_mutex);
atomic_set(&mi2s_rsc_ref, 0);
+ atomic_set(&auxpcm_rsc_ref, 0);
return ret;
}
diff --git a/sound/soc/msm/apq8064.c b/sound/soc/msm/apq8064.c
index ee789cc..37ff06c 100644
--- a/sound/soc/msm/apq8064.c
+++ b/sound/soc/msm/apq8064.c
@@ -103,6 +103,7 @@
static struct snd_soc_jack hs_jack;
static struct snd_soc_jack button_jack;
+static atomic_t auxpcm_rsc_ref;
static int apq8064_hs_detect_use_gpio = -1;
module_param(apq8064_hs_detect_use_gpio, int, 0444);
@@ -1526,8 +1527,10 @@
{
int ret = 0;
- pr_debug("%s(): substream = %s\n", __func__, substream->name);
- ret = msm_aux_pcm_get_gpios();
+ pr_debug("%s(): substream = %s, auxpcm_rsc_ref counter = %d\n",
+ __func__, substream->name, atomic_read(&auxpcm_rsc_ref));
+ if (atomic_inc_return(&auxpcm_rsc_ref) == 1)
+ ret = msm_aux_pcm_get_gpios();
if (ret < 0) {
pr_err("%s: Aux PCM GPIO request failed\n", __func__);
return -EINVAL;
@@ -1551,8 +1554,10 @@
static void msm_auxpcm_shutdown(struct snd_pcm_substream *substream)
{
- pr_debug("%s(): substream = %s\n", __func__, substream->name);
- msm_aux_pcm_free_gpios();
+ pr_debug("%s(): substream = %s, auxpcm_rsc_ref counter = %d\n",
+ __func__, substream->name, atomic_read(&auxpcm_rsc_ref));
+ if (atomic_dec_return(&auxpcm_rsc_ref) == 0)
+ msm_aux_pcm_free_gpios();
}
static void msm_shutdown(struct snd_pcm_substream *substream)
@@ -1949,6 +1954,7 @@
.no_pcm = 1,
.be_id = MSM_BACKEND_DAI_AUXPCM_TX,
.be_hw_params_fixup = msm_auxpcm_be_params_fixup,
+ .ops = &msm_auxpcm_be_ops,
},
{
.name = LPASS_BE_STUB_RX,
@@ -2139,6 +2145,7 @@
}
mutex_init(&cdc_mclk_mutex);
+ atomic_set(&auxpcm_rsc_ref, 0);
return ret;
}
diff --git a/sound/soc/msm/msm8930.c b/sound/soc/msm/msm8930.c
index a577b6a..5b57824 100644
--- a/sound/soc/msm/msm8930.c
+++ b/sound/soc/msm/msm8930.c
@@ -65,6 +65,7 @@
static struct snd_soc_jack hs_jack;
static struct snd_soc_jack button_jack;
+static atomic_t auxpcm_rsc_ref;
static int msm8930_enable_codec_ext_clk(
struct snd_soc_codec *codec, int enable,
@@ -825,8 +826,10 @@
{
int ret = 0;
- pr_debug("%s(): substream = %s\n", __func__, substream->name);
- ret = msm8930_aux_pcm_get_gpios();
+ pr_debug("%s(): substream = %s, auxpcm_rsc_ref counter = %d\n",
+ __func__, substream->name, atomic_read(&auxpcm_rsc_ref));
+ if (atomic_inc_return(&auxpcm_rsc_ref) == 1)
+ ret = msm8930_aux_pcm_get_gpios();
if (ret < 0) {
pr_err("%s: Aux PCM GPIO request failed\n", __func__);
return -EINVAL;
@@ -837,8 +840,10 @@
static void msm8930_auxpcm_shutdown(struct snd_pcm_substream *substream)
{
- pr_debug("%s(): substream = %s\n", __func__, substream->name);
- msm8930_aux_pcm_free_gpios();
+ pr_debug("%s(): substream = %s, auxpcm_rsc_ref counter = %d\n",
+ __func__, substream->name, atomic_read(&auxpcm_rsc_ref));
+ if (atomic_dec_return(&auxpcm_rsc_ref) == 0)
+ msm8930_aux_pcm_free_gpios();
}
static void msm8930_shutdown(struct snd_pcm_substream *substream)
@@ -1194,6 +1199,7 @@
.no_pcm = 1,
.be_id = MSM_BACKEND_DAI_AUXPCM_TX,
.be_hw_params_fixup = msm8930_auxpcm_be_params_fixup,
+ .ops = &msm8930_auxpcm_be_ops,
},
/* Incall Music BACK END DAI Link */
{
@@ -1301,6 +1307,7 @@
} else
msm8930_headset_gpios_configured = 1;
+ atomic_set(&auxpcm_rsc_ref, 0);
return ret;
}
diff --git a/sound/soc/msm/msm8960.c b/sound/soc/msm/msm8960.c
index 40e92e9..3260cd2 100644
--- a/sound/soc/msm/msm8960.c
+++ b/sound/soc/msm/msm8960.c
@@ -83,6 +83,7 @@
static struct snd_soc_jack hs_jack;
static struct snd_soc_jack button_jack;
+static atomic_t auxpcm_rsc_ref;
static bool hs_detect_use_gpio;
module_param(hs_detect_use_gpio, bool, 0444);
@@ -1133,8 +1134,11 @@
{
int ret = 0;
- pr_debug("%s(): substream = %s\n", __func__, substream->name);
- ret = msm8960_aux_pcm_get_gpios();
+ pr_debug("%s(): substream = %s, auxpcm_rsc_ref counter = %d\n",
+ __func__, substream->name, atomic_read(&auxpcm_rsc_ref));
+ if (atomic_inc_return(&auxpcm_rsc_ref) == 1)
+ ret = msm8960_aux_pcm_get_gpios();
+
if (ret < 0) {
pr_err("%s: Aux PCM GPIO request failed\n", __func__);
return -EINVAL;
@@ -1144,9 +1148,10 @@
static void msm8960_auxpcm_shutdown(struct snd_pcm_substream *substream)
{
-
- pr_debug("%s(): substream = %s\n", __func__, substream->name);
- msm8960_aux_pcm_free_gpios();
+ pr_debug("%s(): substream = %s, auxpcm_rsc_ref counter = %d\n",
+ __func__, substream->name, atomic_read(&auxpcm_rsc_ref));
+ if (atomic_dec_return(&auxpcm_rsc_ref) == 0)
+ msm8960_aux_pcm_free_gpios();
}
static void msm8960_shutdown(struct snd_pcm_substream *substream)
@@ -1482,6 +1487,7 @@
.no_pcm = 1,
.be_id = MSM_BACKEND_DAI_AUXPCM_TX,
.be_hw_params_fixup = msm8960_auxpcm_be_params_fixup,
+ .ops = &msm8960_auxpcm_be_ops,
},
/* Incall Music BACK END DAI Link */
{
@@ -1779,7 +1785,7 @@
}
mutex_init(&cdc_mclk_mutex);
-
+ atomic_set(&auxpcm_rsc_ref, 0);
return ret;
}
diff --git a/sound/soc/msm/msm8974.c b/sound/soc/msm/msm8974.c
index 2f0c2e3..68b4edf 100644
--- a/sound/soc/msm/msm8974.c
+++ b/sound/soc/msm/msm8974.c
@@ -82,6 +82,9 @@
static struct snd_soc_jack button_jack;
static struct mutex cdc_mclk_mutex;
+static struct q_clkdiv *codec_clk;
+static int clk_users;
+static atomic_t auxpcm_rsc_ref;
static void msm_enable_ext_spk_amp_gpio(u32 spk_amp_gpio)
{
@@ -583,8 +586,10 @@
{
int ret = 0;
- pr_debug("%s(): substream = %s\n", __func__, substream->name);
- ret = msm_aux_pcm_get_gpios();
+ pr_debug("%s(): substream = %s, auxpcm_rsc_ref counter = %d\n",
+ __func__, substream->name, atomic_read(&auxpcm_rsc_ref));
+ if (atomic_inc_return(&auxpcm_rsc_ref) == 1)
+ ret = msm_aux_pcm_get_gpios();
if (ret < 0) {
pr_err("%s: Aux PCM GPIO request failed\n", __func__);
return -EINVAL;
@@ -595,8 +600,10 @@
static void msm_auxpcm_shutdown(struct snd_pcm_substream *substream)
{
- pr_debug("%s(): substream = %s\n", __func__, substream->name);
- msm_aux_pcm_free_gpios();
+ pr_debug("%s(): substream = %s, auxpcm_rsc_ref counter = %d\n",
+ __func__, substream->name, atomic_read(&auxpcm_rsc_ref));
+ if (atomic_dec_return(&auxpcm_rsc_ref) == 0)
+ msm_aux_pcm_free_gpios();
}
static struct snd_soc_ops msm_auxpcm_be_ops = {
.startup = msm_auxpcm_startup,
@@ -908,6 +915,7 @@
.no_pcm = 1,
.be_id = MSM_BACKEND_DAI_AUXPCM_TX,
.be_hw_params_fixup = msm_auxpcm_be_params_fixup,
+ .ops = &msm_auxpcm_be_ops,
},
/* Backend DAI Links */
{
@@ -975,6 +983,12 @@
platform_device_put(msm_snd_device);
return ret;
}
+ mutex_init(&cdc_mclk_mutex);
+ atomic_set(&auxpcm_rsc_ref, 0);
+
+ return 0;
+err:
+ devm_kfree(&pdev->dev, pdata);
return ret;
}