Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

ASoC: fsl_micfil: fix and improvement

Merge series from Shengjiu Wang <shengjiu.wang@nxp.com>:

Fix the usage of regmap_write_bits().
Move mclk clock enablement to late stage.
Enable the micfil error interrupt.

+39 -10
+39 -10
sound/soc/fsl/fsl_micfil.c
··· 58 58 int vad_detected; 59 59 struct fsl_micfil_verid verid; 60 60 struct fsl_micfil_param param; 61 + bool mclk_flag; /* mclk enable flag */ 61 62 }; 62 63 63 64 struct fsl_micfil_soc_data { ··· 651 650 652 651 /* Enable the module */ 653 652 ret = regmap_set_bits(micfil->regmap, REG_MICFIL_CTRL1, 654 - MICFIL_CTRL1_PDMIEN); 653 + MICFIL_CTRL1_PDMIEN | MICFIL_CTRL1_ERREN); 655 654 if (ret) 656 655 return ret; 657 656 ··· 667 666 668 667 /* Disable the module */ 669 668 ret = regmap_clear_bits(micfil->regmap, REG_MICFIL_CTRL1, 670 - MICFIL_CTRL1_PDMIEN); 669 + MICFIL_CTRL1_PDMIEN | MICFIL_CTRL1_ERREN); 671 670 if (ret) 672 671 return ret; 673 672 ··· 694 693 clk = micfil->mclk; 695 694 696 695 /* Disable clock first, for it was enabled by pm_runtime */ 697 - clk_disable_unprepare(clk); 698 696 fsl_asoc_reparent_pll_clocks(dev, clk, micfil->pll8k_clk, 699 697 micfil->pll11k_clk, ratio); 700 698 ret = clk_prepare_enable(clk); ··· 730 730 if (ret) 731 731 return ret; 732 732 733 + micfil->mclk_flag = true; 734 + 733 735 ret = clk_set_rate(micfil->mclk, rate * clk_div * osr * 8); 734 736 if (ret) 735 737 return ret; ··· 762 760 micfil->dma_params_rx.maxburst = channels * MICFIL_DMA_MAXBURST_RX; 763 761 if (micfil->soc->use_edma) 764 762 micfil->dma_params_rx.maxburst = channels; 763 + 764 + return 0; 765 + } 766 + 767 + static int fsl_micfil_hw_free(struct snd_pcm_substream *substream, 768 + struct snd_soc_dai *dai) 769 + { 770 + struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai); 771 + 772 + clk_disable_unprepare(micfil->mclk); 773 + micfil->mclk_flag = false; 765 774 766 775 return 0; 767 776 } ··· 819 806 .startup = fsl_micfil_startup, 820 807 .trigger = fsl_micfil_trigger, 821 808 .hw_params = fsl_micfil_hw_params, 809 + .hw_free = fsl_micfil_hw_free, 822 810 }; 823 811 824 812 static struct snd_soc_dai_driver fsl_micfil_dai = { ··· 940 926 { 941 927 switch (reg) { 942 928 case REG_MICFIL_STAT: 929 + case REG_MICFIL_FIFO_STAT: 943 930 case REG_MICFIL_DATACH0: 944 931 case REG_MICFIL_DATACH1: 945 932 case REG_MICFIL_DATACH2: ··· 949 934 case REG_MICFIL_DATACH5: 950 935 case REG_MICFIL_DATACH6: 951 936 case REG_MICFIL_DATACH7: 937 + case REG_MICFIL_OUT_STAT: 952 938 case REG_MICFIL_VERID: 953 939 case REG_MICFIL_PARAM: 954 940 case REG_MICFIL_VAD0_STAT: ··· 1004 988 regmap_write_bits(micfil->regmap, 1005 989 REG_MICFIL_STAT, 1006 990 MICFIL_STAT_CHXF(i), 1007 - 1); 991 + MICFIL_STAT_CHXF(i)); 1008 992 } 1009 993 1010 994 for (i = 0; i < MICFIL_FIFO_NUM; i++) { ··· 1026 1010 { 1027 1011 struct fsl_micfil *micfil = (struct fsl_micfil *)devid; 1028 1012 struct platform_device *pdev = micfil->pdev; 1013 + u32 fifo_stat_reg; 1014 + u32 out_stat_reg; 1029 1015 u32 stat_reg; 1030 1016 1031 1017 regmap_read(micfil->regmap, REG_MICFIL_STAT, &stat_reg); ··· 1041 1023 if (stat_reg & MICFIL_STAT_LOWFREQF) { 1042 1024 dev_dbg(&pdev->dev, "isr: ipg_clk_app is too low\n"); 1043 1025 regmap_write_bits(micfil->regmap, REG_MICFIL_STAT, 1044 - MICFIL_STAT_LOWFREQF, 1); 1026 + MICFIL_STAT_LOWFREQF, MICFIL_STAT_LOWFREQF); 1045 1027 } 1028 + 1029 + regmap_read(micfil->regmap, REG_MICFIL_FIFO_STAT, &fifo_stat_reg); 1030 + regmap_write_bits(micfil->regmap, REG_MICFIL_FIFO_STAT, 1031 + fifo_stat_reg, fifo_stat_reg); 1032 + 1033 + regmap_read(micfil->regmap, REG_MICFIL_OUT_STAT, &out_stat_reg); 1034 + regmap_write_bits(micfil->regmap, REG_MICFIL_OUT_STAT, 1035 + out_stat_reg, out_stat_reg); 1046 1036 1047 1037 return IRQ_HANDLED; 1048 1038 } ··· 1305 1279 1306 1280 regcache_cache_only(micfil->regmap, true); 1307 1281 1308 - clk_disable_unprepare(micfil->mclk); 1282 + if (micfil->mclk_flag) 1283 + clk_disable_unprepare(micfil->mclk); 1309 1284 clk_disable_unprepare(micfil->busclk); 1310 1285 1311 1286 return 0; ··· 1321 1294 if (ret < 0) 1322 1295 return ret; 1323 1296 1324 - ret = clk_prepare_enable(micfil->mclk); 1325 - if (ret < 0) { 1326 - clk_disable_unprepare(micfil->busclk); 1327 - return ret; 1297 + if (micfil->mclk_flag) { 1298 + ret = clk_prepare_enable(micfil->mclk); 1299 + if (ret < 0) { 1300 + clk_disable_unprepare(micfil->busclk); 1301 + return ret; 1302 + } 1328 1303 } 1329 1304 1330 1305 regcache_cache_only(micfil->regmap, false);