Skip to content

Commit 4604183

Browse files
author
Fox Snowpatch
committed
1 parent a85c72f commit 4604183

6 files changed

Lines changed: 93 additions & 20 deletions

File tree

sound/soc/fsl/fsl_micfil.c

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,15 @@
3535
#define MICFIL_AUDIO_PLL2 1
3636
#define MICFIL_CLK_EXT3 2
3737

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+
3847
enum quality {
3948
QUALITY_HIGH,
4049
QUALITY_MEDIUM,
@@ -486,29 +495,12 @@ static int fsl_micfil_startup(struct snd_pcm_substream *substream,
486495
struct snd_soc_dai *dai)
487496
{
488497
struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
489-
unsigned int rates[MICFIL_NUM_RATES] = {8000, 11025, 16000, 22050, 32000, 44100, 48000};
490-
int i, j, k = 0;
491-
u64 clk_rate;
492498

493499
if (!micfil) {
494500
dev_err(dai->dev, "micfil dai priv_data not set\n");
495501
return -EINVAL;
496502
}
497503

498-
micfil->constraint_rates.list = micfil->constraint_rates_list;
499-
micfil->constraint_rates.count = 0;
500-
501-
for (j = 0; j < MICFIL_NUM_RATES; j++) {
502-
for (i = 0; i < MICFIL_CLK_SRC_NUM; i++) {
503-
clk_rate = clk_get_rate(micfil->clk_src[i]);
504-
if (clk_rate != 0 && do_div(clk_rate, rates[j]) == 0) {
505-
micfil->constraint_rates_list[k++] = rates[j];
506-
micfil->constraint_rates.count++;
507-
break;
508-
}
509-
}
510-
}
511-
512504
if (micfil->constraint_rates.count > 0)
513505
snd_pcm_hw_constraint_list(substream->runtime, 0,
514506
SNDRV_PCM_HW_PARAM_RATE,
@@ -1239,6 +1231,13 @@ static int fsl_micfil_probe(struct platform_device *pdev)
12391231
if (IS_ERR(micfil->clk_src[MICFIL_CLK_EXT3]))
12401232
micfil->clk_src[MICFIL_CLK_EXT3] = NULL;
12411233

1234+
fsl_asoc_constrain_rates(&micfil->constraint_rates,
1235+
&fsl_micfil_rate_constraints,
1236+
micfil->clk_src[MICFIL_AUDIO_PLL1],
1237+
micfil->clk_src[MICFIL_AUDIO_PLL2],
1238+
micfil->clk_src[MICFIL_CLK_EXT3],
1239+
micfil->constraint_rates_list);
1240+
12421241
/* init regmap */
12431242
regs = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
12441243
if (IS_ERR(regs))

sound/soc/fsl/fsl_sai.c

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -885,7 +885,7 @@ static int fsl_sai_startup(struct snd_pcm_substream *substream,
885885
sai->dma_params_rx.maxburst);
886886

887887
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);
889889

890890
return ret;
891891
}
@@ -1442,6 +1442,11 @@ static int fsl_sai_probe(struct platform_device *pdev)
14421442
fsl_asoc_get_pll_clocks(&pdev->dev, &sai->pll8k_clk,
14431443
&sai->pll11k_clk);
14441444

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);
1449+
14451450
/* Use Multi FIFO mode depending on the support from SDMA script */
14461451
ret = of_property_read_u32_array(np, "dmas", dmas, 4);
14471452
if (!sai->soc_data->use_edma && !ret && dmas[2] == IMX_DMATYPE_MULTI_SAI)

sound/soc/fsl/fsl_sai.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#include <linux/dma/imx-dma.h>
1010
#include <sound/dmaengine_pcm.h>
1111

12+
#define FAL_SAI_NUM_RATES 20
1213
#define FSL_SAI_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\
1314
SNDRV_PCM_FMTBIT_S20_3LE |\
1415
SNDRV_PCM_FMTBIT_S24_LE |\
@@ -309,6 +310,8 @@ struct fsl_sai {
309310
struct pinctrl *pinctrl;
310311
struct pinctrl_state *pins_state;
311312
struct sdma_peripheral_config audio_config[2];
313+
struct snd_pcm_hw_constraint_list constraint_rates;
314+
unsigned int constraint_rates_list[FAL_SAI_NUM_RATES];
312315
};
313316

314317
#define TX 1

sound/soc/fsl/fsl_utils.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,51 @@ void fsl_asoc_reparent_pll_clocks(struct device *dev, struct clk *clk,
152152
}
153153
EXPORT_SYMBOL(fsl_asoc_reparent_pll_clocks);
154154

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+
155200
MODULE_AUTHOR("Timur Tabi <timur@freescale.com>");
156201
MODULE_DESCRIPTION("Freescale ASoC utility code");
157202
MODULE_LICENSE("GPL v2");

sound/soc/fsl/fsl_utils.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,9 @@ void fsl_asoc_get_pll_clocks(struct device *dev, struct clk **pll8k_clk,
2626
void fsl_asoc_reparent_pll_clocks(struct device *dev, struct clk *clk,
2727
struct clk *pll8k_clk,
2828
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);
2934
#endif /* _FSL_UTILS_H */

sound/soc/fsl/fsl_xcvr.c

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include "imx-pcm.h"
2020

2121
#define FSL_XCVR_CAPDS_SIZE 256
22+
#define SPDIF_NUM_RATES 7
2223

2324
enum fsl_xcvr_pll_verison {
2425
PLL_MX8MP,
@@ -55,6 +56,8 @@ struct fsl_xcvr {
5556
u8 cap_ds[FSL_XCVR_CAPDS_SIZE];
5657
struct work_struct work_rst;
5758
spinlock_t lock; /* Protect hw_reset and trigger */
59+
struct snd_pcm_hw_constraint_list spdif_constr_rates;
60+
u32 spdif_constr_rates_list[SPDIF_NUM_RATES];
5861
};
5962

6063
static const struct fsl_xcvr_pll_conf {
@@ -585,8 +588,12 @@ static int fsl_xcvr_startup(struct snd_pcm_substream *substream,
585588
switch (xcvr->mode) {
586589
case FSL_XCVR_MODE_SPDIF:
587590
case FSL_XCVR_MODE_ARC:
588-
ret = fsl_xcvr_constr(substream, &fsl_xcvr_spdif_channels_constr,
589-
&fsl_xcvr_spdif_rates_constr);
591+
if (xcvr->soc_data->spdif_only && tx)
592+
ret = fsl_xcvr_constr(substream, &fsl_xcvr_spdif_channels_constr,
593+
&xcvr->spdif_constr_rates);
594+
else
595+
ret = fsl_xcvr_constr(substream, &fsl_xcvr_spdif_channels_constr,
596+
&fsl_xcvr_spdif_rates_constr);
590597
break;
591598
case FSL_XCVR_MODE_EARC:
592599
ret = fsl_xcvr_constr(substream, &fsl_xcvr_earc_channels_constr,
@@ -1405,6 +1412,15 @@ static int fsl_xcvr_probe(struct platform_device *pdev)
14051412
fsl_asoc_get_pll_clocks(dev, &xcvr->pll8k_clk,
14061413
&xcvr->pll11k_clk);
14071414

1415+
if (xcvr->soc_data->spdif_only) {
1416+
if (!(xcvr->pll8k_clk || xcvr->pll11k_clk))
1417+
xcvr->pll8k_clk = xcvr->phy_clk;
1418+
fsl_asoc_constrain_rates(&xcvr->spdif_constr_rates,
1419+
&fsl_xcvr_spdif_rates_constr,
1420+
xcvr->pll8k_clk, xcvr->pll11k_clk, NULL,
1421+
xcvr->spdif_constr_rates_list);
1422+
}
1423+
14081424
xcvr->ram_addr = devm_platform_ioremap_resource_byname(pdev, "ram");
14091425
if (IS_ERR(xcvr->ram_addr))
14101426
return PTR_ERR(xcvr->ram_addr);

0 commit comments

Comments
 (0)