| .. | .. |
|---|
| 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) { |
|---|