summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKuninori Morimoto <kuninori.morimoto.gx@renesas.com>2025-09-25 05:17:34 +0000
committerMark Brown <broonie@kernel.org>2025-09-25 17:43:28 +0100
commitdc7473e6372ee36ff232af10c910ee3a8bad6447 (patch)
tree51706a3bbbb90989d9e09fc6e68bb945b4c650a7
parent25aa058b5c83a3c455a2a288bb3295c0b234f093 (diff)
ASoC: renesas: msiof: setup both (Playback/Capture) in the same time
SITMDRn / SIRMDRn and some other registers should not be updated during working even though it was not related the target direction (for example, do TX settings during RX is working), otherwise it cause a FSERR. Setup both direction (Playback/Capture) in the same time. Signed-off-by: Kuninori Morimoto <kuninori.morimoto.gx@renesas.com> Tested-by: Yusuke Goda <yusuke.goda.sx@renesas.com> Link: https://patch.msgid.link/877bxnyutt.wl-kuninori.morimoto.gx@renesas.com Signed-off-by: Mark Brown <broonie@kernel.org>
-rw-r--r--sound/soc/renesas/rcar/msiof.c70
1 files changed, 41 insertions, 29 deletions
diff --git a/sound/soc/renesas/rcar/msiof.c b/sound/soc/renesas/rcar/msiof.c
index 5b59d4bcd67e..df664800bf60 100644
--- a/sound/soc/renesas/rcar/msiof.c
+++ b/sound/soc/renesas/rcar/msiof.c
@@ -36,6 +36,16 @@
* We need to use SW reset (= reset_control_xxx()) instead of TXRST/RXRST.
*/
+/*
+ * [NOTE-BOTH-SETTING]
+ *
+ * SITMDRn / SIRMDRn and some other registers should not be updated during working even though it
+ * was not related the target direction (for example, do TX settings during RX is working),
+ * otherwise it cause a FSERR.
+ *
+ * Setup both direction (Playback/Capture) in the same time.
+ */
+
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_dma.h>
@@ -165,39 +175,40 @@ static int msiof_hw_start(struct snd_soc_component *component,
/* Start DMAC */
snd_dmaengine_pcm_trigger(substream, cmd);
+ /*
+ * setup both direction (Playback/Capture) in the same time.
+ * see
+ * above [NOTE-BOTH-SETTING]
+ */
+
/* SITMDRx */
- if (is_play) {
- val = SITMDR1_PCON |
- FIELD_PREP(SIMDR1_SYNCMD, SIMDR1_SYNCMD_LR) |
- SIMDR1_SYNCAC | SIMDR1_XXSTP;
- if (msiof_flag_has(priv, MSIOF_FLAGS_NEED_DELAY))
- val |= FIELD_PREP(SIMDR1_DTDL, 1);
-
- msiof_write(priv, SITMDR1, val);
-
- val = FIELD_PREP(SIMDR2_BITLEN1, width - 1);
- msiof_write(priv, SITMDR2, val | FIELD_PREP(SIMDR2_GRP, 1));
- msiof_write(priv, SITMDR3, val);
- }
+ val = SITMDR1_PCON | SIMDR1_SYNCAC | SIMDR1_XXSTP |
+ FIELD_PREP(SIMDR1_SYNCMD, SIMDR1_SYNCMD_LR);
+ if (msiof_flag_has(priv, MSIOF_FLAGS_NEED_DELAY))
+ val |= FIELD_PREP(SIMDR1_DTDL, 1);
+
+ msiof_write(priv, SITMDR1, val);
+
+ val = FIELD_PREP(SIMDR2_BITLEN1, width - 1);
+ msiof_write(priv, SITMDR2, val | FIELD_PREP(SIMDR2_GRP, 1));
+ msiof_write(priv, SITMDR3, val);
+
/* SIRMDRx */
- else {
- val = FIELD_PREP(SIMDR1_SYNCMD, SIMDR1_SYNCMD_LR) |
- SIMDR1_SYNCAC;
- if (msiof_flag_has(priv, MSIOF_FLAGS_NEED_DELAY))
- val |= FIELD_PREP(SIMDR1_DTDL, 1);
+ val = SIMDR1_SYNCAC |
+ FIELD_PREP(SIMDR1_SYNCMD, SIMDR1_SYNCMD_LR);
+ if (msiof_flag_has(priv, MSIOF_FLAGS_NEED_DELAY))
+ val |= FIELD_PREP(SIMDR1_DTDL, 1);
- msiof_write(priv, SIRMDR1, val);
+ msiof_write(priv, SIRMDR1, val);
- val = FIELD_PREP(SIMDR2_BITLEN1, width - 1);
- msiof_write(priv, SIRMDR2, val | FIELD_PREP(SIMDR2_GRP, 1));
- msiof_write(priv, SIRMDR3, val);
- }
+ val = FIELD_PREP(SIMDR2_BITLEN1, width - 1);
+ msiof_write(priv, SIRMDR2, val | FIELD_PREP(SIMDR2_GRP, 1));
+ msiof_write(priv, SIRMDR3, val);
/* SIFCTR */
- if (is_play)
- msiof_update(priv, SIFCTR, SIFCTR_TFWM, FIELD_PREP(SIFCTR_TFWM, SIFCTR_TFWM_1));
- else
- msiof_update(priv, SIFCTR, SIFCTR_RFWM, FIELD_PREP(SIFCTR_RFWM, SIFCTR_RFWM_1));
+ msiof_write(priv, SIFCTR,
+ FIELD_PREP(SIFCTR_TFWM, SIFCTR_TFWM_1) |
+ FIELD_PREP(SIFCTR_RFWM, SIFCTR_RFWM_1));
/* SIIER */
if (is_play)
@@ -214,10 +225,11 @@ static int msiof_hw_start(struct snd_soc_component *component,
msiof_update(priv, SISTR, val, val);
/* SICTR */
+ val = SICTR_TEDG | SICTR_REDG;
if (is_play)
- val = SICTR_TXE | SICTR_TEDG;
+ val |= SICTR_TXE;
else
- val = SICTR_RXE | SICTR_REDG;
+ val |= SICTR_RXE;
msiof_update_and_wait(priv, SICTR, val, val, val);
return 0;