.. | .. |
---|
207 | 207 | return snd_soc_dai_get_drvdata(dai); |
---|
208 | 208 | } |
---|
209 | 209 | |
---|
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 | | - |
---|
220 | 210 | static void rockchip_pdm_rxctrl(struct rk_pdm_dev *pdm, int on) |
---|
221 | 211 | { |
---|
| 212 | + unsigned long flags; |
---|
| 213 | + |
---|
222 | 214 | 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); |
---|
224 | 236 | regmap_update_bits(pdm->regmap, PDM_DMA_CTRL, |
---|
225 | 237 | PDM_DMA_RD_MSK, PDM_DMA_RD_EN); |
---|
| 238 | + local_irq_restore(flags); |
---|
226 | 239 | } else { |
---|
227 | 240 | regmap_update_bits(pdm->regmap, PDM_DMA_CTRL, |
---|
228 | 241 | PDM_DMA_RD_MSK, PDM_DMA_RD_DIS); |
---|
.. | .. |
---|
976 | 989 | if (ret != 0 && ret != -ENOENT) |
---|
977 | 990 | goto err_suspend; |
---|
978 | 991 | |
---|
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"); |
---|
980 | 994 | return 0; |
---|
| 995 | + } |
---|
981 | 996 | |
---|
982 | 997 | ret = devm_snd_dmaengine_pcm_register(&pdev->dev, NULL, 0); |
---|
983 | 998 | if (ret) { |
---|