From ebfea67125767a779af63ae6de176709713c8826 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 26 Aug 2021 12:01:47 +0800 Subject: ASoC: rockchip: i2s: Add support for set bclk ratio This patch adds support for set bclk ratio from machine driver. Signed-off-by: Sugar Zhang Link: https://lore.kernel.org/r/1629950520-14190-1-git-send-email-sugar.zhang@rock-chips.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index c7dc3509bceb..c9d5c524af6c 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -49,6 +49,7 @@ struct rk_i2s_dev { bool rx_start; bool is_master_mode; const struct rk_i2s_pins *pins; + unsigned int bclk_ratio; }; static int i2s_runtime_suspend(struct device *dev) @@ -278,7 +279,7 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, if (i2s->is_master_mode) { mclk_rate = clk_get_rate(i2s->mclk); - bclk_rate = 2 * 32 * params_rate(params); + bclk_rate = i2s->bclk_ratio * params_rate(params); if (bclk_rate == 0 || mclk_rate % bclk_rate) return -EINVAL; @@ -413,6 +414,16 @@ static int rockchip_i2s_trigger(struct snd_pcm_substream *substream, return ret; } +static int rockchip_i2s_set_bclk_ratio(struct snd_soc_dai *dai, + unsigned int ratio) +{ + struct rk_i2s_dev *i2s = to_info(dai); + + i2s->bclk_ratio = ratio; + + return 0; +} + static int rockchip_i2s_set_sysclk(struct snd_soc_dai *cpu_dai, int clk_id, unsigned int freq, int dir) { @@ -441,6 +452,7 @@ static int rockchip_i2s_dai_probe(struct snd_soc_dai *dai) static const struct snd_soc_dai_ops rockchip_i2s_dai_ops = { .hw_params = rockchip_i2s_hw_params, + .set_bclk_ratio = rockchip_i2s_set_bclk_ratio, .set_sysclk = rockchip_i2s_set_sysclk, .set_fmt = rockchip_i2s_set_fmt, .trigger = rockchip_i2s_trigger, @@ -638,6 +650,8 @@ static int rockchip_i2s_probe(struct platform_device *pdev) i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; i2s->capture_dma_data.maxburst = 4; + i2s->bclk_ratio = 64; + dev_set_drvdata(&pdev->dev, i2s); pm_runtime_enable(&pdev->dev); -- cgit v1.2.3 From 6b76bcc004b046ea3c8eb66bbc6954f1d23cc2af Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 26 Aug 2021 12:01:48 +0800 Subject: ASoC: rockchip: i2s: Fixup clk div error MCLK maybe not precise as required because of PLL, but which still can be used and no side effect. so, using DIV_ROUND_CLOSEST instead div. e.g. set mclk to 11289600 Hz, but get 11289598 Hz. Signed-off-by: Sugar Zhang Link: https://lore.kernel.org/r/1629950520-14190-2-git-send-email-sugar.zhang@rock-chips.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index c9d5c524af6c..05fce2c61f1a 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -280,10 +280,10 @@ static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, if (i2s->is_master_mode) { mclk_rate = clk_get_rate(i2s->mclk); bclk_rate = i2s->bclk_ratio * params_rate(params); - if (bclk_rate == 0 || mclk_rate % bclk_rate) + if (!bclk_rate) return -EINVAL; - div_bclk = mclk_rate / bclk_rate; + div_bclk = DIV_ROUND_CLOSEST(mclk_rate, bclk_rate); div_lrck = bclk_rate / params_rate(params); regmap_update_bits(i2s->regmap, I2S_CKR, I2S_CKR_MDIV_MASK, -- cgit v1.2.3 From 7a2df53bc090a161713da057df7455b39f6cd00d Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 26 Aug 2021 12:01:49 +0800 Subject: ASoC: rockchip: i2s: Improve dma data transfer efficiency This patch changes dma data burst from 4 to 8 to improve data transfer efficiency. Signed-off-by: Sugar Zhang Link: https://lore.kernel.org/r/1629950520-14190-3-git-send-email-sugar.zhang@rock-chips.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 05fce2c61f1a..2e0047ddbc39 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -644,11 +644,11 @@ static int rockchip_i2s_probe(struct platform_device *pdev) i2s->playback_dma_data.addr = res->start + I2S_TXDR; i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - i2s->playback_dma_data.maxburst = 4; + i2s->playback_dma_data.maxburst = 8; i2s->capture_dma_data.addr = res->start + I2S_RXDR; i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - i2s->capture_dma_data.maxburst = 4; + i2s->capture_dma_data.maxburst = 8; i2s->bclk_ratio = 64; -- cgit v1.2.3 From 53ca9b9777b95cdd689181d7c547e38dc79adad0 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 26 Aug 2021 12:01:50 +0800 Subject: ASoC: rockchip: i2s: Fix regmap_ops hang API 'set_fmt' maybe called when PD is off, in the situation, any register access will hang the system. so, enable PD before r/w register. Signed-off-by: Sugar Zhang Link: https://lore.kernel.org/r/1629950520-14190-4-git-send-email-sugar.zhang@rock-chips.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 2e0047ddbc39..90877e867549 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -187,7 +187,9 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, { struct rk_i2s_dev *i2s = to_info(cpu_dai); unsigned int mask = 0, val = 0; + int ret = 0; + pm_runtime_get_sync(cpu_dai->dev); mask = I2S_CKR_MSS_MASK; switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) { case SND_SOC_DAIFMT_CBS_CFS: @@ -200,7 +202,8 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, i2s->is_master_mode = false; break; default: - return -EINVAL; + ret = -EINVAL; + goto err_pm_put; } regmap_update_bits(i2s->regmap, I2S_CKR, mask, val); @@ -214,7 +217,8 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, val = I2S_CKR_CKP_POS; break; default: - return -EINVAL; + ret = -EINVAL; + goto err_pm_put; } regmap_update_bits(i2s->regmap, I2S_CKR, mask, val); @@ -237,7 +241,8 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1); break; default: - return -EINVAL; + ret = -EINVAL; + goto err_pm_put; } regmap_update_bits(i2s->regmap, I2S_TXCR, mask, val); @@ -260,12 +265,16 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1); break; default: - return -EINVAL; + ret = -EINVAL; + goto err_pm_put; } regmap_update_bits(i2s->regmap, I2S_RXCR, mask, val); - return 0; +err_pm_put: + pm_runtime_put(cpu_dai->dev); + + return ret; } static int rockchip_i2s_hw_params(struct snd_pcm_substream *substream, -- cgit v1.2.3 From 296713a3609deaf4ad2c460ffe196c09084792e0 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 26 Aug 2021 12:02:35 +0800 Subject: ASoC: dt-bindings: rockchip: Document reset property for i2s This patch documents reset property for i2s. Signed-off-by: Sugar Zhang Reviewed-by: Rob Herring Link: https://lore.kernel.org/r/1629950562-14281-2-git-send-email-sugar.zhang@rock-chips.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/rockchip-i2s.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml b/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml index 245895b58a2f..9f9cc480209b 100644 --- a/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml @@ -61,6 +61,14 @@ properties: power-domains: maxItems: 1 + reset-names: + items: + - const: reset-m + - const: reset-h + + resets: + maxItems: 2 + rockchip,capture-channels: $ref: /schemas/types.yaml#/definitions/uint32 default: 2 -- cgit v1.2.3 From 1bf56843e664eef2525bdbfae6a561e98910f676 Mon Sep 17 00:00:00 2001 From: Xiaotan Luo Date: Thu, 26 Aug 2021 12:02:36 +0800 Subject: ASoC: rockchip: i2s: Fixup config for DAIFMT_DSP_A/B - DSP_A: PCM delay 1 bit mode, L data MSB after FRM LRC - DSP_B: PCM no delay mode, L data MSB during FRM LRC Signed-off-by: Xiaotan Luo Signed-off-by: Sugar Zhang Link: https://lore.kernel.org/r/1629950562-14281-3-git-send-email-sugar.zhang@rock-chips.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 90877e867549..ef9d1db4df48 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -234,12 +234,12 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_I2S: val = I2S_TXCR_IBM_NORMAL; break; - case SND_SOC_DAIFMT_DSP_A: /* PCM no delay mode */ - val = I2S_TXCR_TFS_PCM; - break; - case SND_SOC_DAIFMT_DSP_B: /* PCM delay 1 mode */ + case SND_SOC_DAIFMT_DSP_A: /* PCM delay 1 bit mode */ val = I2S_TXCR_TFS_PCM | I2S_TXCR_PBM_MODE(1); break; + case SND_SOC_DAIFMT_DSP_B: /* PCM no delay mode */ + val = I2S_TXCR_TFS_PCM; + break; default: ret = -EINVAL; goto err_pm_put; @@ -258,12 +258,12 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, case SND_SOC_DAIFMT_I2S: val = I2S_RXCR_IBM_NORMAL; break; - case SND_SOC_DAIFMT_DSP_A: /* PCM no delay mode */ - val = I2S_RXCR_TFS_PCM; - break; - case SND_SOC_DAIFMT_DSP_B: /* PCM delay 1 mode */ + case SND_SOC_DAIFMT_DSP_A: /* PCM delay 1 bit mode */ val = I2S_RXCR_TFS_PCM | I2S_RXCR_PBM_MODE(1); break; + case SND_SOC_DAIFMT_DSP_B: /* PCM no delay mode */ + val = I2S_RXCR_TFS_PCM; + break; default: ret = -EINVAL; goto err_pm_put; -- cgit v1.2.3 From 4455f26a551c86e31c7d27495903a11c3d660034 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 26 Aug 2021 12:02:37 +0800 Subject: ASoC: rockchip: i2s: Make playback/capture optional There are some controllers which support playback only or capture only. so, make it optional. and initial capability by 'dma-names' of DT. Signed-off-by: Sugar Zhang Link: https://lore.kernel.org/r/1629950562-14281-4-git-send-email-sugar.zhang@rock-chips.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 129 +++++++++++++++++++++++--------------- 1 file changed, 79 insertions(+), 50 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index ef9d1db4df48..f955a06fe194 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -40,6 +40,9 @@ struct rk_i2s_dev { struct regmap *regmap; struct regmap *grf; + bool has_capture; + bool has_playback; + /* * Used to indicate the tx/rx status. * I2S controller hopes to start the tx and rx together, @@ -453,8 +456,9 @@ static int rockchip_i2s_dai_probe(struct snd_soc_dai *dai) { struct rk_i2s_dev *i2s = snd_soc_dai_get_drvdata(dai); - dai->capture_dma_data = &i2s->capture_dma_data; - dai->playback_dma_data = &i2s->playback_dma_data; + snd_soc_dai_init_dma_data(dai, + i2s->has_playback ? &i2s->playback_dma_data : NULL, + i2s->has_capture ? &i2s->capture_dma_data : NULL); return 0; } @@ -469,28 +473,6 @@ static const struct snd_soc_dai_ops rockchip_i2s_dai_ops = { static struct snd_soc_dai_driver rockchip_i2s_dai = { .probe = rockchip_i2s_dai_probe, - .playback = { - .stream_name = "Playback", - .channels_min = 2, - .channels_max = 8, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = (SNDRV_PCM_FMTBIT_S8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S20_3LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE), - }, - .capture = { - .stream_name = "Capture", - .channels_min = 2, - .channels_max = 2, - .rates = SNDRV_PCM_RATE_8000_192000, - .formats = (SNDRV_PCM_FMTBIT_S8 | - SNDRV_PCM_FMTBIT_S16_LE | - SNDRV_PCM_FMTBIT_S20_3LE | - SNDRV_PCM_FMTBIT_S24_LE | - SNDRV_PCM_FMTBIT_S32_LE), - }, .ops = &rockchip_i2s_dai_ops, .symmetric_rate = 1, }; @@ -595,16 +577,84 @@ static const struct of_device_id rockchip_i2s_match[] __maybe_unused = { {}, }; +static int rockchip_i2s_init_dai(struct rk_i2s_dev *i2s, struct resource *res, + struct snd_soc_dai_driver **dp) +{ + struct device_node *node = i2s->dev->of_node; + struct snd_soc_dai_driver *dai; + struct property *dma_names; + const char *dma_name; + unsigned int val; + + of_property_for_each_string(node, "dma-names", dma_names, dma_name) { + if (!strcmp(dma_name, "tx")) + i2s->has_playback = true; + if (!strcmp(dma_name, "rx")) + i2s->has_capture = true; + } + + dai = devm_kmemdup(i2s->dev, &rockchip_i2s_dai, + sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + if (i2s->has_playback) { + dai->playback.stream_name = "Playback"; + dai->playback.channels_min = 2; + dai->playback.channels_max = 8; + dai->playback.rates = SNDRV_PCM_RATE_8000_192000; + dai->playback.formats = SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S20_3LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE; + + i2s->playback_dma_data.addr = res->start + I2S_TXDR; + i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + i2s->playback_dma_data.maxburst = 8; + + if (!of_property_read_u32(node, "rockchip,playback-channels", &val)) { + if (val >= 2 && val <= 8) + dai->playback.channels_max = val; + } + } + + if (i2s->has_capture) { + dai->capture.stream_name = "Capture"; + dai->capture.channels_min = 2; + dai->capture.channels_max = 8; + dai->capture.rates = SNDRV_PCM_RATE_8000_192000; + dai->capture.formats = SNDRV_PCM_FMTBIT_S8 | + SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S20_3LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE; + + i2s->capture_dma_data.addr = res->start + I2S_RXDR; + i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; + i2s->capture_dma_data.maxburst = 8; + + if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) { + if (val >= 2 && val <= 8) + dai->capture.channels_max = val; + } + } + + if (dp) + *dp = dai; + + return 0; +} + static int rockchip_i2s_probe(struct platform_device *pdev) { struct device_node *node = pdev->dev.of_node; const struct of_device_id *of_id; struct rk_i2s_dev *i2s; - struct snd_soc_dai_driver *soc_dai; + struct snd_soc_dai_driver *dai; struct resource *res; void __iomem *regs; int ret; - int val; i2s = devm_kzalloc(&pdev->dev, sizeof(*i2s), GFP_KERNEL); if (!i2s) @@ -651,14 +701,6 @@ static int rockchip_i2s_probe(struct platform_device *pdev) return PTR_ERR(i2s->regmap); } - i2s->playback_dma_data.addr = res->start + I2S_TXDR; - i2s->playback_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - i2s->playback_dma_data.maxburst = 8; - - i2s->capture_dma_data.addr = res->start + I2S_RXDR; - i2s->capture_dma_data.addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES; - i2s->capture_dma_data.maxburst = 8; - i2s->bclk_ratio = 64; dev_set_drvdata(&pdev->dev, i2s); @@ -670,26 +712,13 @@ static int rockchip_i2s_probe(struct platform_device *pdev) goto err_pm_disable; } - soc_dai = devm_kmemdup(&pdev->dev, &rockchip_i2s_dai, - sizeof(*soc_dai), GFP_KERNEL); - if (!soc_dai) { - ret = -ENOMEM; + ret = rockchip_i2s_init_dai(i2s, res, &dai); + if (ret) goto err_pm_disable; - } - - if (!of_property_read_u32(node, "rockchip,playback-channels", &val)) { - if (val >= 2 && val <= 8) - soc_dai->playback.channels_max = val; - } - - if (!of_property_read_u32(node, "rockchip,capture-channels", &val)) { - if (val >= 2 && val <= 8) - soc_dai->capture.channels_max = val; - } ret = devm_snd_soc_register_component(&pdev->dev, &rockchip_i2s_component, - soc_dai, 1); + dai, 1); if (ret) { dev_err(&pdev->dev, "Could not register DAI\n"); -- cgit v1.2.3 From f005dc6db136a477166dd86e983351fec9129cce Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 26 Aug 2021 12:02:38 +0800 Subject: ASoC: rockchip: i2s: Add compatible for more SoCs This patch adds more compatible strings for SoCs. Signed-off-by: Sugar Zhang Link: https://lore.kernel.org/r/1629950562-14281-5-git-send-email-sugar.zhang@rock-chips.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index f955a06fe194..7ee580642864 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -570,10 +570,20 @@ static const struct rk_i2s_pins rk3399_i2s_pins = { }; static const struct of_device_id rockchip_i2s_match[] __maybe_unused = { + { .compatible = "rockchip,px30-i2s", }, + { .compatible = "rockchip,rk1808-i2s", }, + { .compatible = "rockchip,rk3036-i2s", }, { .compatible = "rockchip,rk3066-i2s", }, + { .compatible = "rockchip,rk3128-i2s", }, { .compatible = "rockchip,rk3188-i2s", }, + { .compatible = "rockchip,rk3228-i2s", }, { .compatible = "rockchip,rk3288-i2s", }, + { .compatible = "rockchip,rk3308-i2s", }, + { .compatible = "rockchip,rk3328-i2s", }, + { .compatible = "rockchip,rk3366-i2s", }, + { .compatible = "rockchip,rk3368-i2s", }, { .compatible = "rockchip,rk3399-i2s", .data = &rk3399_i2s_pins }, + { .compatible = "rockchip,rv1126-i2s", }, {}, }; -- cgit v1.2.3 From d5ceed036f7cde29bf17173e9a9c8bbde0a70389 Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 26 Aug 2021 12:03:11 +0800 Subject: ASoC: dt-bindings: rockchip: Add compatible strings for more SoCs This patch adds compatible strings for more SoCs. Signed-off-by: Sugar Zhang Acked-by: Rob Herring Link: https://lore.kernel.org/r/1629950594-14345-1-git-send-email-sugar.zhang@rock-chips.com Signed-off-by: Mark Brown --- Documentation/devicetree/bindings/sound/rockchip-i2s.yaml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml b/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml index 9f9cc480209b..5ea16b8ef93f 100644 --- a/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml +++ b/Documentation/devicetree/bindings/sound/rockchip-i2s.yaml @@ -20,7 +20,9 @@ properties: - items: - enum: - rockchip,px30-i2s + - rockchip,rk1808-i2s - rockchip,rk3036-i2s + - rockchip,rk3128-i2s - rockchip,rk3188-i2s - rockchip,rk3228-i2s - rockchip,rk3288-i2s @@ -29,6 +31,7 @@ properties: - rockchip,rk3366-i2s - rockchip,rk3368-i2s - rockchip,rk3399-i2s + - rockchip,rv1126-i2s - const: rockchip,rk3066-i2s reg: -- cgit v1.2.3 From 917f07719b133093680ed57dd7b5bc30b6a5b45d Mon Sep 17 00:00:00 2001 From: Sugar Zhang Date: Thu, 26 Aug 2021 12:03:12 +0800 Subject: ASoC: rockchip: i2s: Add support for frame inversion This patch adds support for frame inversion. Signed-off-by: Sugar Zhang Link: https://lore.kernel.org/r/1629950594-14345-2-git-send-email-sugar.zhang@rock-chips.com Signed-off-by: Mark Brown --- sound/soc/rockchip/rockchip_i2s.c | 20 +++++++++++++++++--- sound/soc/rockchip/rockchip_i2s.h | 10 ++++++---- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/sound/soc/rockchip/rockchip_i2s.c b/sound/soc/rockchip/rockchip_i2s.c index 7ee580642864..53e0b4a1c7d2 100644 --- a/sound/soc/rockchip/rockchip_i2s.c +++ b/sound/soc/rockchip/rockchip_i2s.c @@ -211,13 +211,27 @@ static int rockchip_i2s_set_fmt(struct snd_soc_dai *cpu_dai, regmap_update_bits(i2s->regmap, I2S_CKR, mask, val); - mask = I2S_CKR_CKP_MASK; + mask = I2S_CKR_CKP_MASK | I2S_CKR_TLP_MASK | I2S_CKR_RLP_MASK; switch (fmt & SND_SOC_DAIFMT_INV_MASK) { case SND_SOC_DAIFMT_NB_NF: - val = I2S_CKR_CKP_NEG; + val = I2S_CKR_CKP_NORMAL | + I2S_CKR_TLP_NORMAL | + I2S_CKR_RLP_NORMAL; + break; + case SND_SOC_DAIFMT_NB_IF: + val = I2S_CKR_CKP_NORMAL | + I2S_CKR_TLP_INVERTED | + I2S_CKR_RLP_INVERTED; break; case SND_SOC_DAIFMT_IB_NF: - val = I2S_CKR_CKP_POS; + val = I2S_CKR_CKP_INVERTED | + I2S_CKR_TLP_NORMAL | + I2S_CKR_RLP_NORMAL; + break; + case SND_SOC_DAIFMT_IB_IF: + val = I2S_CKR_CKP_INVERTED | + I2S_CKR_TLP_INVERTED | + I2S_CKR_RLP_INVERTED; break; default: ret = -EINVAL; diff --git a/sound/soc/rockchip/rockchip_i2s.h b/sound/soc/rockchip/rockchip_i2s.h index fcaae24e40af..251851bf4f2c 100644 --- a/sound/soc/rockchip/rockchip_i2s.h +++ b/sound/soc/rockchip/rockchip_i2s.h @@ -88,15 +88,17 @@ #define I2S_CKR_MSS_SLAVE (1 << I2S_CKR_MSS_SHIFT) #define I2S_CKR_MSS_MASK (1 << I2S_CKR_MSS_SHIFT) #define I2S_CKR_CKP_SHIFT 26 -#define I2S_CKR_CKP_NEG (0 << I2S_CKR_CKP_SHIFT) -#define I2S_CKR_CKP_POS (1 << I2S_CKR_CKP_SHIFT) +#define I2S_CKR_CKP_NORMAL (0 << I2S_CKR_CKP_SHIFT) +#define I2S_CKR_CKP_INVERTED (1 << I2S_CKR_CKP_SHIFT) #define I2S_CKR_CKP_MASK (1 << I2S_CKR_CKP_SHIFT) #define I2S_CKR_RLP_SHIFT 25 #define I2S_CKR_RLP_NORMAL (0 << I2S_CKR_RLP_SHIFT) -#define I2S_CKR_RLP_OPPSITE (1 << I2S_CKR_RLP_SHIFT) +#define I2S_CKR_RLP_INVERTED (1 << I2S_CKR_RLP_SHIFT) +#define I2S_CKR_RLP_MASK (1 << I2S_CKR_RLP_SHIFT) #define I2S_CKR_TLP_SHIFT 24 #define I2S_CKR_TLP_NORMAL (0 << I2S_CKR_TLP_SHIFT) -#define I2S_CKR_TLP_OPPSITE (1 << I2S_CKR_TLP_SHIFT) +#define I2S_CKR_TLP_INVERTED (1 << I2S_CKR_TLP_SHIFT) +#define I2S_CKR_TLP_MASK (1 << I2S_CKR_TLP_SHIFT) #define I2S_CKR_MDIV_SHIFT 16 #define I2S_CKR_MDIV(x) ((x - 1) << I2S_CKR_MDIV_SHIFT) #define I2S_CKR_MDIV_MASK (0xff << I2S_CKR_MDIV_SHIFT) -- cgit v1.2.3