hc
2023-11-06 e3e12f52b214121840b44c91de5b3e5af5d3eb84
kernel/sound/soc/rockchip/rockchip_pdm.c
....@@ -207,22 +207,35 @@
207207 return snd_soc_dai_get_drvdata(dai);
208208 }
209209
210
-static void rockchip_pdm_drop_fifo(struct rk_pdm_dev *pdm)
211
-{
212
- int cnt, val, i;
213
-
214
- /* drop the dirty data */
215
- regmap_read(pdm->regmap, PDM_FIFO_CTRL, &cnt);
216
- for (i = 0; i < PDM_FIFO_CNT(cnt); i++)
217
- regmap_read(pdm->regmap, PDM_RXFIFO_DATA, &val);
218
-}
219
-
220210 static void rockchip_pdm_rxctrl(struct rk_pdm_dev *pdm, int on)
221211 {
212
+ unsigned long flags;
213
+
222214 if (on) {
223
- rockchip_pdm_drop_fifo(pdm);
215
+ /* The PDM device need to delete some unused data
216
+ * since the pdm of various manufacturers can not
217
+ * be stable quickly. This is done by commit "ASoC:
218
+ * rockchip: pdm: Fix pop noise in the beginning".
219
+ *
220
+ * But we do not know how many data we delete, this
221
+ * cause channel disorder. For example, we record
222
+ * two channel 24-bit sound, then delete some starting
223
+ * data. Because the deleted starting data is uncertain,
224
+ * the next data may be left or right channel and cause
225
+ * channel disorder.
226
+ *
227
+ * Luckily, we can use the PDM_RX_CLR to fix this.
228
+ * Use the PDM_RX_CLR to clear fifo written data and
229
+ * address, but can not clear the read data and address.
230
+ * In initial state, the read data and address are zero.
231
+ */
232
+ local_irq_save(flags);
233
+ regmap_update_bits(pdm->regmap, PDM_SYSCONFIG,
234
+ PDM_RX_CLR_MASK,
235
+ PDM_RX_CLR_WR);
224236 regmap_update_bits(pdm->regmap, PDM_DMA_CTRL,
225237 PDM_DMA_RD_MSK, PDM_DMA_RD_EN);
238
+ local_irq_restore(flags);
226239 } else {
227240 regmap_update_bits(pdm->regmap, PDM_DMA_CTRL,
228241 PDM_DMA_RD_MSK, PDM_DMA_RD_DIS);
....@@ -976,8 +989,10 @@
976989 if (ret != 0 && ret != -ENOENT)
977990 goto err_suspend;
978991
979
- if (of_property_read_bool(node, "rockchip,no-dmaengine"))
992
+ if (of_property_read_bool(node, "rockchip,no-dmaengine")) {
993
+ dev_info(&pdev->dev, "Used for Multi-DAI\n");
980994 return 0;
995
+ }
981996
982997 ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0);
983998 if (ret) {