hc
2024-01-03 2f7c68cb55ecb7331f2381deb497c27155f32faf
kernel/sound/soc/jz4740/jz4740-i2s.c
....@@ -59,7 +59,8 @@
5959 #define JZ_AIC_CTRL_MONO_TO_STEREO BIT(11)
6060 #define JZ_AIC_CTRL_SWITCH_ENDIANNESS BIT(10)
6161 #define JZ_AIC_CTRL_SIGNED_TO_UNSIGNED BIT(9)
62
-#define JZ_AIC_CTRL_FLUSH BIT(8)
62
+#define JZ_AIC_CTRL_TFLUSH BIT(8)
63
+#define JZ_AIC_CTRL_RFLUSH BIT(7)
6364 #define JZ_AIC_CTRL_ENABLE_ROR_INT BIT(6)
6465 #define JZ_AIC_CTRL_ENABLE_TUR_INT BIT(5)
6566 #define JZ_AIC_CTRL_ENABLE_RFS_INT BIT(4)
....@@ -94,6 +95,8 @@
9495 struct i2s_soc_info {
9596 enum jz47xx_i2s_version version;
9697 struct snd_soc_dai_driver *dai;
98
+
99
+ bool shared_fifo_flush;
97100 };
98101
99102 struct jz4740_i2s {
....@@ -122,19 +125,44 @@
122125 writel(value, i2s->base + reg);
123126 }
124127
128
+static inline void jz4740_i2s_set_bits(const struct jz4740_i2s *i2s,
129
+ unsigned int reg, uint32_t bits)
130
+{
131
+ uint32_t value = jz4740_i2s_read(i2s, reg);
132
+ value |= bits;
133
+ jz4740_i2s_write(i2s, reg, value);
134
+}
135
+
125136 static int jz4740_i2s_startup(struct snd_pcm_substream *substream,
126137 struct snd_soc_dai *dai)
127138 {
128139 struct jz4740_i2s *i2s = snd_soc_dai_get_drvdata(dai);
129
- uint32_t conf, ctrl;
140
+ uint32_t conf;
130141 int ret;
142
+
143
+ /*
144
+ * When we can flush FIFOs independently, only flush the FIFO
145
+ * that is starting up. We can do this when the DAI is active
146
+ * because it does not disturb other active substreams.
147
+ */
148
+ if (!i2s->soc_info->shared_fifo_flush) {
149
+ if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
150
+ jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_TFLUSH);
151
+ else
152
+ jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_RFLUSH);
153
+ }
131154
132155 if (snd_soc_dai_active(dai))
133156 return 0;
134157
135
- ctrl = jz4740_i2s_read(i2s, JZ_REG_AIC_CTRL);
136
- ctrl |= JZ_AIC_CTRL_FLUSH;
137
- jz4740_i2s_write(i2s, JZ_REG_AIC_CTRL, ctrl);
158
+ /*
159
+ * When there is a shared flush bit for both FIFOs, the TFLUSH
160
+ * bit flushes both FIFOs. Flushing while the DAI is active would
161
+ * cause FIFO underruns in other active substreams so we have to
162
+ * guard this behind the snd_soc_dai_active() check.
163
+ */
164
+ if (i2s->soc_info->shared_fifo_flush)
165
+ jz4740_i2s_set_bits(i2s, JZ_REG_AIC_CTRL, JZ_AIC_CTRL_TFLUSH);
138166
139167 ret = clk_prepare_enable(i2s->clk_i2s);
140168 if (ret)
....@@ -467,6 +495,7 @@
467495 static const struct i2s_soc_info jz4740_i2s_soc_info = {
468496 .version = JZ_I2S_JZ4740,
469497 .dai = &jz4740_i2s_dai,
498
+ .shared_fifo_flush = true,
470499 };
471500
472501 static const struct i2s_soc_info jz4760_i2s_soc_info = {