|
@@ -10,6 +10,7 @@
|
|
|
#include <linux/time.h>
|
|
|
#include <linux/math64.h>
|
|
|
#include <linux/wait.h>
|
|
|
+#include <linux/mutex.h>
|
|
|
#include <linux/platform_device.h>
|
|
|
#include <linux/slab.h>
|
|
|
#include <sound/core.h>
|
|
@@ -106,6 +107,7 @@ struct msm_compr_pdata {
|
|
|
struct msm_compr_ch_map *ch_map[MSM_FRONTEND_DAI_MAX];
|
|
|
bool is_in_use[MSM_FRONTEND_DAI_MAX];
|
|
|
struct msm_pcm_channel_mixer *chmixer_pspd[MSM_FRONTEND_DAI_MM_SIZE];
|
|
|
+ struct mutex lock;
|
|
|
};
|
|
|
|
|
|
struct msm_compr_audio {
|
|
@@ -1941,6 +1943,7 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream)
|
|
|
}
|
|
|
spin_unlock_irqrestore(&prtd->lock, flags);
|
|
|
|
|
|
+ mutex_lock(&pdata->lock);
|
|
|
pdata->cstream[soc_prtd->dai_link->id] = NULL;
|
|
|
if (cstream->direction == SND_COMPRESS_PLAYBACK) {
|
|
|
msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->id,
|
|
@@ -1962,6 +1965,7 @@ static int msm_compr_playback_free(struct snd_compr_stream *cstream)
|
|
|
pdata->is_in_use[soc_prtd->dai_link->id] = false;
|
|
|
kfree(prtd);
|
|
|
runtime->private_data = NULL;
|
|
|
+ mutex_unlock(&pdata->lock);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -2018,6 +2022,7 @@ static int msm_compr_capture_free(struct snd_compr_stream *cstream)
|
|
|
}
|
|
|
spin_unlock_irqrestore(&prtd->lock, flags);
|
|
|
|
|
|
+ mutex_lock(&pdata->lock);
|
|
|
pdata->cstream[soc_prtd->dai_link->id] = NULL;
|
|
|
msm_pcm_routing_dereg_phy_stream(soc_prtd->dai_link->id,
|
|
|
SNDRV_PCM_STREAM_CAPTURE);
|
|
@@ -2028,6 +2033,7 @@ static int msm_compr_capture_free(struct snd_compr_stream *cstream)
|
|
|
|
|
|
kfree(prtd);
|
|
|
runtime->private_data = NULL;
|
|
|
+ mutex_unlock(&pdata->lock);
|
|
|
|
|
|
return 0;
|
|
|
}
|
|
@@ -3406,6 +3412,7 @@ static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol,
|
|
|
struct snd_compr_stream *cstream = NULL;
|
|
|
struct msm_compr_audio *prtd = NULL;
|
|
|
long *values = &(ucontrol->value.integer.value[0]);
|
|
|
+ int ret = 0;
|
|
|
int effects_module;
|
|
|
|
|
|
pr_debug("%s\n", __func__);
|
|
@@ -3414,21 +3421,25 @@ static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol,
|
|
|
__func__, fe_id);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
+
|
|
|
+ mutex_lock(&pdata->lock);
|
|
|
cstream = pdata->cstream[fe_id];
|
|
|
audio_effects = pdata->audio_effects[fe_id];
|
|
|
if (!cstream || !audio_effects) {
|
|
|
pr_err("%s: stream or effects inactive\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto done;
|
|
|
}
|
|
|
prtd = cstream->runtime->private_data;
|
|
|
if (!prtd) {
|
|
|
pr_err("%s: cannot set audio effects\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto done;
|
|
|
}
|
|
|
if (prtd->compr_passthr != LEGACY_PCM) {
|
|
|
pr_debug("%s: No effects for compr_type[%d]\n",
|
|
|
__func__, prtd->compr_passthr);
|
|
|
- return 0;
|
|
|
+ goto done;
|
|
|
}
|
|
|
pr_debug("%s: Effects supported for compr_type[%d]\n",
|
|
|
__func__, prtd->compr_passthr);
|
|
@@ -3489,9 +3500,11 @@ static int msm_compr_audio_effects_config_put(struct snd_kcontrol *kcontrol,
|
|
|
break;
|
|
|
default:
|
|
|
pr_err("%s Invalid effects config module\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
+ ret = -EINVAL;
|
|
|
}
|
|
|
- return 0;
|
|
|
+done:
|
|
|
+ mutex_unlock(&pdata->lock);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol,
|
|
@@ -3503,6 +3516,7 @@ static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol,
|
|
|
snd_soc_component_get_drvdata(comp);
|
|
|
struct msm_compr_audio_effects *audio_effects = NULL;
|
|
|
struct snd_compr_stream *cstream = NULL;
|
|
|
+ int ret = 0;
|
|
|
struct msm_compr_audio *prtd = NULL;
|
|
|
|
|
|
pr_debug("%s\n", __func__);
|
|
@@ -3511,19 +3525,23 @@ static int msm_compr_audio_effects_config_get(struct snd_kcontrol *kcontrol,
|
|
|
__func__, fe_id);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
+
|
|
|
+ mutex_lock(&pdata->lock);
|
|
|
cstream = pdata->cstream[fe_id];
|
|
|
audio_effects = pdata->audio_effects[fe_id];
|
|
|
if (!cstream || !audio_effects) {
|
|
|
pr_debug("%s: stream or effects inactive\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto done;
|
|
|
}
|
|
|
prtd = cstream->runtime->private_data;
|
|
|
if (!prtd) {
|
|
|
pr_err("%s: cannot set audio effects\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
+ ret = -EINVAL;
|
|
|
}
|
|
|
-
|
|
|
- return 0;
|
|
|
+done:
|
|
|
+ mutex_unlock(&pdata->lock);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol,
|
|
@@ -3536,6 +3554,7 @@ static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol,
|
|
|
struct msm_compr_audio_effects *audio_effects = NULL;
|
|
|
struct snd_compr_stream *cstream = NULL;
|
|
|
struct msm_compr_audio *prtd = NULL;
|
|
|
+ int ret = 0;
|
|
|
long *values = &(ucontrol->value.integer.value[0]);
|
|
|
|
|
|
if (fe_id >= MSM_FRONTEND_DAI_MAX) {
|
|
@@ -3543,28 +3562,37 @@ static int msm_compr_query_audio_effect_put(struct snd_kcontrol *kcontrol,
|
|
|
__func__, fe_id);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
+
|
|
|
+ mutex_lock(&pdata->lock);
|
|
|
+
|
|
|
cstream = pdata->cstream[fe_id];
|
|
|
audio_effects = pdata->audio_effects[fe_id];
|
|
|
if (!cstream || !audio_effects) {
|
|
|
pr_err("%s: stream or effects inactive\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto done;
|
|
|
}
|
|
|
prtd = cstream->runtime->private_data;
|
|
|
if (!prtd) {
|
|
|
pr_err("%s: cannot set audio effects\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto done;
|
|
|
}
|
|
|
if (prtd->compr_passthr != LEGACY_PCM) {
|
|
|
pr_err("%s: No effects for compr_type[%d]\n",
|
|
|
__func__, prtd->compr_passthr);
|
|
|
- return -EPERM;
|
|
|
+ ret = -EPERM;
|
|
|
+ goto done;
|
|
|
}
|
|
|
audio_effects->query.mod_id = (u32)*values++;
|
|
|
audio_effects->query.parm_id = (u32)*values++;
|
|
|
audio_effects->query.size = (u32)*values++;
|
|
|
audio_effects->query.offset = (u32)*values++;
|
|
|
audio_effects->query.device = (u32)*values++;
|
|
|
- return 0;
|
|
|
+
|
|
|
+done:
|
|
|
+ mutex_unlock(&pdata->lock);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol,
|
|
@@ -3577,6 +3605,7 @@ static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol,
|
|
|
struct msm_compr_audio_effects *audio_effects = NULL;
|
|
|
struct snd_compr_stream *cstream = NULL;
|
|
|
struct msm_compr_audio *prtd = NULL;
|
|
|
+ int ret = 0;
|
|
|
long *values = &(ucontrol->value.integer.value[0]);
|
|
|
|
|
|
if (fe_id >= MSM_FRONTEND_DAI_MAX) {
|
|
@@ -3584,23 +3613,29 @@ static int msm_compr_query_audio_effect_get(struct snd_kcontrol *kcontrol,
|
|
|
__func__, fe_id);
|
|
|
return -EINVAL;
|
|
|
}
|
|
|
+
|
|
|
+ mutex_lock(&pdata->lock);
|
|
|
cstream = pdata->cstream[fe_id];
|
|
|
audio_effects = pdata->audio_effects[fe_id];
|
|
|
if (!cstream || !audio_effects) {
|
|
|
pr_debug("%s: stream or effects inactive\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto done;
|
|
|
}
|
|
|
prtd = cstream->runtime->private_data;
|
|
|
if (!prtd) {
|
|
|
pr_err("%s: cannot set audio effects\n", __func__);
|
|
|
- return -EINVAL;
|
|
|
+ ret = -EINVAL;
|
|
|
+ goto done;
|
|
|
}
|
|
|
values[0] = (long)audio_effects->query.mod_id;
|
|
|
values[1] = (long)audio_effects->query.parm_id;
|
|
|
values[2] = (long)audio_effects->query.size;
|
|
|
values[3] = (long)audio_effects->query.offset;
|
|
|
values[4] = (long)audio_effects->query.device;
|
|
|
- return 0;
|
|
|
+done:
|
|
|
+ mutex_unlock(&pdata->lock);
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
static int msm_compr_send_dec_params(struct snd_compr_stream *cstream,
|
|
@@ -3686,6 +3721,7 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol,
|
|
|
goto end;
|
|
|
}
|
|
|
|
|
|
+ mutex_lock(&pdata->lock);
|
|
|
switch (prtd->codec) {
|
|
|
case FORMAT_MP3:
|
|
|
case FORMAT_MPEG4_AAC:
|
|
@@ -3737,6 +3773,7 @@ static int msm_compr_dec_params_put(struct snd_kcontrol *kcontrol,
|
|
|
}
|
|
|
end:
|
|
|
pr_debug("%s: ret %d\n", __func__, rc);
|
|
|
+ mutex_unlock(&pdata->lock);
|
|
|
return rc;
|
|
|
}
|
|
|
|
|
@@ -3956,6 +3993,7 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
|
+ mutex_lock(&pdata->lock);
|
|
|
if (prtd->audio_client == NULL) {
|
|
|
pr_err("%s: audio_client is null\n", __func__);
|
|
|
ret = -EINVAL;
|
|
@@ -3984,6 +4022,7 @@ static int msm_compr_adsp_stream_cmd_put(struct snd_kcontrol *kcontrol,
|
|
|
pr_err("%s: failed to send stream event cmd, err = %d\n",
|
|
|
__func__, ret);
|
|
|
done:
|
|
|
+ mutex_unlock(&pdata->lock);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -4020,6 +4059,7 @@ static int msm_compr_ion_fd_map_put(struct snd_kcontrol *kcontrol,
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
|
+ mutex_lock(&pdata->lock);
|
|
|
if (prtd->audio_client == NULL) {
|
|
|
pr_err("%s: audio_client is null\n", __func__);
|
|
|
ret = -EINVAL;
|
|
@@ -4031,6 +4071,7 @@ static int msm_compr_ion_fd_map_put(struct snd_kcontrol *kcontrol,
|
|
|
if (ret < 0)
|
|
|
pr_err("%s: failed to register ion fd\n", __func__);
|
|
|
done:
|
|
|
+ mutex_unlock(&pdata->lock);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -4053,6 +4094,7 @@ static int msm_compr_rtic_event_ack_put(struct snd_kcontrol *kcontrol,
|
|
|
goto done;
|
|
|
}
|
|
|
|
|
|
+ mutex_lock(&pdata->lock);
|
|
|
cstream = pdata->cstream[fe_id];
|
|
|
if (cstream == NULL) {
|
|
|
pr_err("%s cstream is null\n", __func__);
|
|
@@ -4090,6 +4132,7 @@ static int msm_compr_rtic_event_ack_put(struct snd_kcontrol *kcontrol,
|
|
|
pr_err("%s: failed to send rtic event ack, err = %d\n",
|
|
|
__func__, ret);
|
|
|
done:
|
|
|
+ mutex_unlock(&pdata->lock);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
@@ -5469,6 +5512,7 @@ static int msm_compr_dev_probe(struct platform_device *pdev)
|
|
|
kzalloc(sizeof(*pdata), GFP_KERNEL);
|
|
|
if (!pdata)
|
|
|
return -ENOMEM;
|
|
|
+ mutex_init(&pdata->lock);
|
|
|
dev_set_drvdata(&pdev->dev, pdata);
|
|
|
|
|
|
return snd_soc_register_component(&pdev->dev,
|
|
@@ -5485,6 +5529,7 @@ static int msm_compr_remove(struct platform_device *pdev)
|
|
|
for (i = 0; i < MSM_FRONTEND_DAI_MM_SIZE; i++)
|
|
|
kfree(pdata->chmixer_pspd[i]);
|
|
|
}
|
|
|
+ mutex_destroy(&pdata->lock);
|
|
|
kfree(pdata);
|
|
|
|
|
|
snd_soc_unregister_component(&pdev->dev);
|