From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001 From: Cezary Rojewski Date: Tue, 4 Dec 2018 05:21:48 +0100 Subject: [PATCH] ASoC: tdf8532: Account for critical sections. This patch adds locking for crucial sections within tdf8532 codec driver to improve latency between messages sent to and received from codec. Change-Id: I4931f759e57f31fb46220f7fc4dacddce884a8e1 Signed-off-by: Cezary Rojewski Tracked-On: OAM-72724 Reviewed-by: Lewandowski, Gustaw --- sound/soc/codecs/tdf8532.c | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/sound/soc/codecs/tdf8532.c b/sound/soc/codecs/tdf8532.c index 02e63f9..da820c5 100644 --- a/sound/soc/codecs/tdf8532.c +++ b/sound/soc/codecs/tdf8532.c @@ -21,8 +21,11 @@ #include #include #include +#include #include "tdf8532.h" +static DEFINE_MUTEX(tdf8532_lock); + static int __tdf8532_build_pkt(struct tdf8532_priv *dev_data, va_list valist, u8 *payload) { @@ -212,24 +215,28 @@ static int tdf8532_start_play(struct tdf8532_priv *tdf8532) { int ret; + mutex_lock(&tdf8532_lock); ret = tdf8532_amp_write(tdf8532, SET_CLK_STATE, CLK_CONNECT); if (ret < 0) - return ret; + goto out; ret = tdf8532_amp_write(tdf8532, SET_CHNL_ENABLE, CHNL_MASK(tdf8532->channels)); + if (ret < 0) + goto out; - if (ret >= 0) - ret = tdf8532_wait_state(tdf8532, STATE_PLAY, ACK_TIMEOUT); + ret = tdf8532_wait_state(tdf8532, STATE_PLAY, ACK_TIMEOUT); +out: + mutex_unlock(&tdf8532_lock); return ret; } - static int tdf8532_stop_play(struct tdf8532_priv *tdf8532) { int ret; + mutex_lock(&tdf8532_lock); ret = tdf8532_amp_write(tdf8532, SET_CHNL_DISABLE, CHNL_MASK(tdf8532->channels)); if (ret < 0) @@ -246,10 +253,10 @@ static int tdf8532_stop_play(struct tdf8532_priv *tdf8532) ret = tdf8532_wait_state(tdf8532, STATE_IDLE, ACK_TIMEOUT); out: + mutex_unlock(&tdf8532_lock); return ret; } - static int tdf8532_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_dai *dai) { @@ -257,7 +264,8 @@ static int tdf8532_dai_trigger(struct snd_pcm_substream *substream, int cmd, struct snd_soc_component *component = dai->component; struct tdf8532_priv *tdf8532 = snd_soc_component_get_drvdata(component); - dev_dbg(component->dev, "%s: cmd = %d\n", __func__, cmd); + dev_dbg(component->dev, "%s: cmd: %d, stream dir: %d\n", __func__, cmd, + substream->stream); switch (cmd) { case SNDRV_PCM_TRIGGER_START: @@ -281,15 +289,15 @@ static int tdf8532_mute(struct snd_soc_dai *dai, int mute) { struct snd_soc_component *component = dai->component; struct tdf8532_priv *tdf8532 = snd_soc_component_get_drvdata(component); + int ret; - dev_dbg(component->dev, "%s\n", __func__); + dev_dbg(component->dev, "%s: mute: %d\n", __func__, mute); - if (mute) - return tdf8532_amp_write(tdf8532, SET_CHNL_MUTE, - CHNL_MASK(CHNL_MAX)); - else - return tdf8532_amp_write(tdf8532, SET_CHNL_UNMUTE, + mutex_lock(&tdf8532_lock); + ret = tdf8532_amp_write(tdf8532, mute ? SET_CHNL_MUTE : SET_CHNL_UNMUTE, CHNL_MASK(CHNL_MAX)); + mutex_unlock(&tdf8532_lock); + return ret; } static const struct snd_soc_dai_ops tdf8532_dai_ops = { -- https://clearlinux.org