diff options
author | Viorel Suman <viorel.suman@nxp.com> | 2018-06-06 13:36:20 +0300 |
---|---|---|
committer | Dong Aisheng <aisheng.dong@nxp.com> | 2019-11-25 15:54:00 +0800 |
commit | 06131f164d73f623ce745023bf9207f1690556c0 (patch) | |
tree | 7ddba4d3d84d1aeddc84cb83f3a9e1c0084b2431 | |
parent | f22894516873a00f4dbadc30bb30bce745d99eab (diff) |
MLK-18534-1: ASoC: fsl: sai: introduce 1:1 bclk:mclk ratio support
Since IP version 3.01 (845s) SAI has support for 1:1
bclk:mclk ratio.
Signed-off-by: Viorel Suman <viorel.suman@nxp.com>
-rw-r--r-- | sound/soc/fsl/fsl_sai.c | 69 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_sai.h | 2 |
2 files changed, 36 insertions, 35 deletions
diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c index 37c32183f79c..10dda41249d2 100644 --- a/sound/soc/fsl/fsl_sai.c +++ b/sound/soc/fsl/fsl_sai.c @@ -471,7 +471,8 @@ static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) struct fsl_sai *sai = snd_soc_dai_get_drvdata(dai); unsigned char offset = sai->soc->reg_offset; unsigned long clk_rate; - u32 savediv = 0, ratio, savesub = freq; + unsigned int reg = 0; + u32 ratio, savesub = freq, saveratio = 0, savediv = 0; u32 id; int ret = 0; @@ -479,6 +480,8 @@ static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) if (sai->slave_mode[tx]) return 0; + fsl_sai_check_ver(dai); + for (id = 0; id < FSL_SAI_MCLK_MAX; id++) { clk_rate = clk_get_rate(sai->mclk_clk[id]); if (!clk_rate) @@ -499,22 +502,21 @@ static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) "ratio %d for freq %dHz based on clock %ldHz\n", ratio, freq, clk_rate); - if (ratio % 2 == 0 && ratio >= 2 && ratio <= 512) - ratio /= 2; - else - continue; + if ((ratio % 2 == 0 && ratio >= 2 && ratio <= 512) || + (ratio == 1 && sai->verid.id >= FSL_SAI_VERID_0301)) { - if (ret < savesub) { - savediv = ratio; - sai->mclk_id[tx] = id; - savesub = ret; - } + if (ret < savesub) { + saveratio = ratio; + sai->mclk_id[tx] = id; + savesub = ret; + } - if (ret == 0) - break; + if (ret == 0) + break; + } } - if (savediv == 0) { + if (saveratio == 0) { dev_err(dai->dev, "failed to derive required %cx rate: %d\n", tx ? 'T' : 'R', freq); return -EINVAL; @@ -530,33 +532,32 @@ static int fsl_sai_set_bclk(struct snd_soc_dai *dai, bool tx, u32 freq) * 4) For Tx and Rx are both Synchronous with another SAI, we just * ignore it. */ - if ((sai->synchronous[TX] && !sai->synchronous[RX]) || - (!tx && !sai->synchronous[RX])) { - regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset), - FSL_SAI_CR2_MSEL_MASK, - FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); - regmap_update_bits(sai->regmap, FSL_SAI_RCR2(offset), - FSL_SAI_CR2_DIV_MASK, savediv - 1); - } else if ((sai->synchronous[RX] && !sai->synchronous[TX]) || - (tx && !sai->synchronous[TX])) { - regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset), - FSL_SAI_CR2_MSEL_MASK, - FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); - regmap_update_bits(sai->regmap, FSL_SAI_TCR2(offset), - FSL_SAI_CR2_DIV_MASK, savediv - 1); + if ((!tx || sai->synchronous[TX]) && !sai->synchronous[RX]) + reg = FSL_SAI_RCR2(offset); + else if ((tx || sai->synchronous[RX]) && !sai->synchronous[TX]) + reg = FSL_SAI_TCR2(offset); + + if (reg) { + regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_MSEL_MASK, + FSL_SAI_CR2_MSEL(sai->mclk_id[tx])); + + savediv = (saveratio == 1 ? 0 : (saveratio >> 1) - 1); + regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_DIV_MASK, savediv); + + if (sai->verid.id >= FSL_SAI_VERID_0301) { + regmap_update_bits(sai->regmap, reg, FSL_SAI_CR2_BYP, + (saveratio == 1 ? FSL_SAI_CR2_BYP : 0)); + } } - fsl_sai_check_ver(dai); - switch (sai->verid.id) { - case FSL_SAI_VERID_0301: + if (sai->verid.id >= FSL_SAI_VERID_0301) { /* SAI is in master mode at this point, so enable MCLK */ regmap_update_bits(sai->regmap, FSL_SAI_MCTL, - FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN); - break; + FSL_SAI_MCTL_MCLK_EN, FSL_SAI_MCTL_MCLK_EN); } - dev_dbg(dai->dev, "best fit: clock id=%d, div=%d, deviation =%d\n", - sai->mclk_id[tx], savediv, savesub); + dev_dbg(dai->dev, "best fit: clock id=%d, ratio=%d, deviation=%d\n", + sai->mclk_id[tx], saveratio, savesub); return 0; } diff --git a/sound/soc/fsl/fsl_sai.h b/sound/soc/fsl/fsl_sai.h index b3286f3491dc..d5f8383b5824 100644 --- a/sound/soc/fsl/fsl_sai.h +++ b/sound/soc/fsl/fsl_sai.h @@ -122,7 +122,7 @@ #define FSL_SAI_CR2_MSEL(ID) ((ID) << 26) #define FSL_SAI_CR2_BCP BIT(25) #define FSL_SAI_CR2_BCD_MSTR BIT(24) -#define FSL_SAI_CR2_BCBP BIT(23) /* BCLK bypass */ +#define FSL_SAI_CR2_BYP BIT(23) /* BCLK bypass */ #define FSL_SAI_CR2_DIV_MASK 0xff /* SAI Transmit and Receive Configuration 3 Register */ |