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.

Add function to constrain rates

Merge series from Chancel Liu <chancel.liu@nxp.com>:

Platforms like i.MX93/91 only have one audio PLL. Some sample rates are
not supported. If the PLL source is used for 8kHz series rates, then
11kHz series rates can't be supported. Add common function to constrain
rates according to different clock sources.

In ASoC drivers switch to this new function.

+93 -20
+16 -17
sound/soc/fsl/fsl_micfil.c
··· 35 35 #define MICFIL_AUDIO_PLL2 1 36 36 #define MICFIL_CLK_EXT3 2 37 37 38 + static const unsigned int fsl_micfil_rates[] = { 39 + 8000, 11025, 16000, 22050, 32000, 44100, 48000, 40 + }; 41 + 42 + static const struct snd_pcm_hw_constraint_list fsl_micfil_rate_constraints = { 43 + .count = ARRAY_SIZE(fsl_micfil_rates), 44 + .list = fsl_micfil_rates, 45 + }; 46 + 38 47 enum quality { 39 48 QUALITY_HIGH, 40 49 QUALITY_MEDIUM, ··· 495 486 struct snd_soc_dai *dai) 496 487 { 497 488 struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai); 498 - unsigned int rates[MICFIL_NUM_RATES] = {8000, 11025, 16000, 22050, 32000, 44100, 48000}; 499 - int i, j, k = 0; 500 - u64 clk_rate; 501 489 502 490 if (!micfil) { 503 491 dev_err(dai->dev, "micfil dai priv_data not set\n"); 504 492 return -EINVAL; 505 - } 506 - 507 - micfil->constraint_rates.list = micfil->constraint_rates_list; 508 - micfil->constraint_rates.count = 0; 509 - 510 - for (j = 0; j < MICFIL_NUM_RATES; j++) { 511 - for (i = 0; i < MICFIL_CLK_SRC_NUM; i++) { 512 - clk_rate = clk_get_rate(micfil->clk_src[i]); 513 - if (clk_rate != 0 && do_div(clk_rate, rates[j]) == 0) { 514 - micfil->constraint_rates_list[k++] = rates[j]; 515 - micfil->constraint_rates.count++; 516 - break; 517 - } 518 - } 519 493 } 520 494 521 495 if (micfil->constraint_rates.count > 0) ··· 1230 1238 micfil->clk_src[MICFIL_CLK_EXT3] = devm_clk_get(&pdev->dev, "clkext3"); 1231 1239 if (IS_ERR(micfil->clk_src[MICFIL_CLK_EXT3])) 1232 1240 micfil->clk_src[MICFIL_CLK_EXT3] = NULL; 1241 + 1242 + fsl_asoc_constrain_rates(&micfil->constraint_rates, 1243 + &fsl_micfil_rate_constraints, 1244 + micfil->clk_src[MICFIL_AUDIO_PLL1], 1245 + micfil->clk_src[MICFIL_AUDIO_PLL2], 1246 + micfil->clk_src[MICFIL_CLK_EXT3], 1247 + micfil->constraint_rates_list); 1233 1248 1234 1249 /* init regmap */ 1235 1250 regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+6 -1
sound/soc/fsl/fsl_sai.c
··· 885 885 sai->dma_params_rx.maxburst); 886 886 887 887 ret = snd_pcm_hw_constraint_list(substream->runtime, 0, 888 - SNDRV_PCM_HW_PARAM_RATE, &fsl_sai_rate_constraints); 888 + SNDRV_PCM_HW_PARAM_RATE, &sai->constraint_rates); 889 889 890 890 return ret; 891 891 } ··· 1441 1441 1442 1442 fsl_asoc_get_pll_clocks(&pdev->dev, &sai->pll8k_clk, 1443 1443 &sai->pll11k_clk); 1444 + 1445 + fsl_asoc_constrain_rates(&sai->constraint_rates, 1446 + &fsl_sai_rate_constraints, 1447 + sai->pll8k_clk, sai->pll11k_clk, NULL, 1448 + sai->constraint_rates_list); 1444 1449 1445 1450 /* Use Multi FIFO mode depending on the support from SDMA script */ 1446 1451 ret = of_property_read_u32_array(np, "dmas", dmas, 4);
+3
sound/soc/fsl/fsl_sai.h
··· 9 9 #include <linux/dma/imx-dma.h> 10 10 #include <sound/dmaengine_pcm.h> 11 11 12 + #define FAL_SAI_NUM_RATES 20 12 13 #define FSL_SAI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ 13 14 SNDRV_PCM_FMTBIT_S20_3LE |\ 14 15 SNDRV_PCM_FMTBIT_S24_LE |\ ··· 310 309 struct pinctrl *pinctrl; 311 310 struct pinctrl_state *pins_state; 312 311 struct sdma_peripheral_config audio_config[2]; 312 + struct snd_pcm_hw_constraint_list constraint_rates; 313 + unsigned int constraint_rates_list[FAL_SAI_NUM_RATES]; 313 314 }; 314 315 315 316 #define TX 1
+45
sound/soc/fsl/fsl_utils.c
··· 152 152 } 153 153 EXPORT_SYMBOL(fsl_asoc_reparent_pll_clocks); 154 154 155 + /** 156 + * fsl_asoc_constrain_rates - constrain rates according to clocks 157 + * 158 + * @target_constr: target constraint 159 + * @original_constr: original constraint 160 + * @pll8k_clk: PLL clock pointer for 8kHz 161 + * @pll11k_clk: PLL clock pointer for 11kHz 162 + * @ext_clk: External clock pointer 163 + * @target_rates: target rates array 164 + * 165 + * This function constrain rates according to clocks 166 + */ 167 + void fsl_asoc_constrain_rates(struct snd_pcm_hw_constraint_list *target_constr, 168 + const struct snd_pcm_hw_constraint_list *original_constr, 169 + struct clk *pll8k_clk, struct clk *pll11k_clk, 170 + struct clk *ext_clk, int *target_rates) 171 + { 172 + int i, j, k = 0; 173 + u64 clk_rate[3]; 174 + 175 + *target_constr = *original_constr; 176 + if (pll8k_clk || pll11k_clk || ext_clk) { 177 + target_constr->list = target_rates; 178 + target_constr->count = 0; 179 + for (i = 0; i < original_constr->count; i++) { 180 + clk_rate[0] = clk_get_rate(pll8k_clk); 181 + clk_rate[1] = clk_get_rate(pll11k_clk); 182 + clk_rate[2] = clk_get_rate(ext_clk); 183 + for (j = 0; j < 3; j++) { 184 + if (clk_rate[j] != 0 && 185 + do_div(clk_rate[j], original_constr->list[i]) == 0) { 186 + target_rates[k++] = original_constr->list[i]; 187 + target_constr->count++; 188 + break; 189 + } 190 + } 191 + } 192 + 193 + /* protection for if there is no proper rate found*/ 194 + if (!target_constr->count) 195 + *target_constr = *original_constr; 196 + } 197 + } 198 + EXPORT_SYMBOL(fsl_asoc_constrain_rates); 199 + 155 200 MODULE_AUTHOR("Timur Tabi <timur@freescale.com>"); 156 201 MODULE_DESCRIPTION("Freescale ASoC utility code"); 157 202 MODULE_LICENSE("GPL v2");
+5
sound/soc/fsl/fsl_utils.h
··· 26 26 void fsl_asoc_reparent_pll_clocks(struct device *dev, struct clk *clk, 27 27 struct clk *pll8k_clk, 28 28 struct clk *pll11k_clk, u64 ratio); 29 + 30 + void fsl_asoc_constrain_rates(struct snd_pcm_hw_constraint_list *target_constr, 31 + const struct snd_pcm_hw_constraint_list *original_constr, 32 + struct clk *pll8k_clk, struct clk *pll11k_clk, 33 + struct clk *ext_clk, int *target_rates); 29 34 #endif /* _FSL_UTILS_H */
+18 -2
sound/soc/fsl/fsl_xcvr.c
··· 19 19 #include "imx-pcm.h" 20 20 21 21 #define FSL_XCVR_CAPDS_SIZE 256 22 + #define SPDIF_NUM_RATES 7 22 23 23 24 enum fsl_xcvr_pll_verison { 24 25 PLL_MX8MP, ··· 58 57 u8 cap_ds[FSL_XCVR_CAPDS_SIZE]; 59 58 struct work_struct work_rst; 60 59 spinlock_t lock; /* Protect hw_reset and trigger */ 60 + struct snd_pcm_hw_constraint_list spdif_constr_rates; 61 + u32 spdif_constr_rates_list[SPDIF_NUM_RATES]; 61 62 }; 62 63 63 64 static const struct fsl_xcvr_pll_conf { ··· 643 640 switch (xcvr->mode) { 644 641 case FSL_XCVR_MODE_SPDIF: 645 642 case FSL_XCVR_MODE_ARC: 646 - ret = fsl_xcvr_constr(substream, &fsl_xcvr_spdif_channels_constr, 647 - &fsl_xcvr_spdif_rates_constr); 643 + if (xcvr->soc_data->spdif_only && tx) 644 + ret = fsl_xcvr_constr(substream, &fsl_xcvr_spdif_channels_constr, 645 + &xcvr->spdif_constr_rates); 646 + else 647 + ret = fsl_xcvr_constr(substream, &fsl_xcvr_spdif_channels_constr, 648 + &fsl_xcvr_spdif_rates_constr); 648 649 break; 649 650 case FSL_XCVR_MODE_EARC: 650 651 ret = fsl_xcvr_constr(substream, &fsl_xcvr_earc_channels_constr, ··· 1552 1545 1553 1546 fsl_asoc_get_pll_clocks(dev, &xcvr->pll8k_clk, 1554 1547 &xcvr->pll11k_clk); 1548 + 1549 + if (xcvr->soc_data->spdif_only) { 1550 + if (!(xcvr->pll8k_clk || xcvr->pll11k_clk)) 1551 + xcvr->pll8k_clk = xcvr->phy_clk; 1552 + fsl_asoc_constrain_rates(&xcvr->spdif_constr_rates, 1553 + &fsl_xcvr_spdif_rates_constr, 1554 + xcvr->pll8k_clk, xcvr->pll11k_clk, NULL, 1555 + xcvr->spdif_constr_rates_list); 1556 + } 1555 1557 1556 1558 xcvr->ram_addr = devm_platform_ioremap_resource_byname(pdev, "ram"); 1557 1559 if (IS_ERR(xcvr->ram_addr))