Re: [PATCH] ASoC: fsl_xcvr:Fix unbalanced pm_runtime_enable in fsl_xcvr_probe

2022-05-27 Thread Shengjiu Wang
On Thu, May 26, 2022 at 9:18 AM zhangqilong  wrote:

> Add missing pm_runtime_disable() when probe error out. It could
> avoid pm_runtime implementation complains when removing and probing
> again the driver.
>
> Fix:c590fa80b3928 ("ASoC: fsl_xcvr: register platform component before
> registering cpu dai")
> Signed-off-by: Zhang Qilong 
> ---
>  sound/soc/fsl/fsl_xcvr.c | 2 ++
>  1 file changed, 2 insertions(+)
>
> diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
> index d0556c79fdb1..907435efe121 100644
> --- a/sound/soc/fsl/fsl_xcvr.c
> +++ b/sound/soc/fsl/fsl_xcvr.c
> @@ -1228,6 +1228,7 @@ static int fsl_xcvr_probe(struct platform_device
> *pdev)
>  */
> ret = devm_snd_dmaengine_pcm_register(dev, NULL, 0);
> if (ret) {
> +   pm_runtime_disable(dev);
> dev_err(dev, "failed to pcm register\n");
> return ret;
> }
> @@ -1235,6 +1236,7 @@ static int fsl_xcvr_probe(struct platform_device
> *pdev)
> ret = devm_snd_soc_register_component(dev, _xcvr_comp,
>   _xcvr_dai, 1);
> if (ret) {
> +   pm_runtime_disable(dev);
> dev_err(dev, "failed to register component %s\n",
> fsl_xcvr_comp.name);
> }
>
> Could you please also help add remove() function and add
pm_runtime_disable()
in the remove()?
Thanks.

best regards
wang shengjiu


Re: [PATCH] ASoC: fsl_sai: fix incorrect mclk number in error message

2022-05-08 Thread Shengjiu Wang
On Sat, May 7, 2022 at 8:31 PM Pieterjan Camerlynck <
pieterjan.camerly...@gmail.com> wrote:

> In commit  ("ASoC: fsl_sai: add sai master mode support")
> the loop was changed to start iterating from 1 instead of 0. The error
> message however was not updated, reporting the wrong clock to the user.
>
> Signed-off-by: Pieterjan Camerlynck 
>

Acked-by: Shengjiu Wang 

Best Regards
Wang Shengjiu

> ---
>  sound/soc/fsl/fsl_sai.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
> index ffc24afb5a7a..f0602077b385 100644
> --- a/sound/soc/fsl/fsl_sai.c
> +++ b/sound/soc/fsl/fsl_sai.c
> @@ -1054,7 +1054,7 @@ static int fsl_sai_probe(struct platform_device
> *pdev)
> sai->mclk_clk[i] = devm_clk_get(>dev, tmp);
> if (IS_ERR(sai->mclk_clk[i])) {
> dev_err(>dev, "failed to get mclk%d clock:
> %ld\n",
> -   i + 1, PTR_ERR(sai->mclk_clk[i]));
> +   i, PTR_ERR(sai->mclk_clk[i]));
> sai->mclk_clk[i] = NULL;
> }
> }
> --
> 2.25.1
>
>


Re: [PATCH] ASoC: fsl: using pm_runtime_resume_and_get instead of pm_runtime_get_sync

2022-04-12 Thread Shengjiu Wang
On Tue, Apr 12, 2022 at 4:30 PM  wrote:

> From: Minghao Chi 
>
> Using pm_runtime_resume_and_get is more appropriate
> for simplifing code
>
> Reported-by: Zeal Robot 
> Signed-off-by: Minghao Chi 
>

Acked-by: Shengjiu Wang 

Best regards
Wang Shengjiu

> ---
>  sound/soc/fsl/fsl_esai.c | 6 ++
>  1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
> index ed444e8f1d6b..1a2bdf8e76f0 100644
> --- a/sound/soc/fsl/fsl_esai.c
> +++ b/sound/soc/fsl/fsl_esai.c
> @@ -1050,11 +1050,9 @@ static int fsl_esai_probe(struct platform_device
> *pdev)
> goto err_pm_disable;
> }
>
> -   ret = pm_runtime_get_sync(>dev);
> -   if (ret < 0) {
> -   pm_runtime_put_noidle(>dev);
> +   ret = pm_runtime_resume_and_get(>dev);
> +   if (ret < 0)
> goto err_pm_get_sync;
> -   }
>
> ret = fsl_esai_hw_init(esai_priv);
> if (ret)
> --
> 2.25.1
>
>


Re: [PATCH] ASoC: fsl_sai: fix 1:1 bclk:mclk ratio support

2022-04-06 Thread Shengjiu Wang
On Tue, Apr 5, 2022 at 11:58 PM Ahmad Fatoum 
wrote:

> Refactoring in commit a50b7926d015 ("ASoC: fsl_sai: implement 1:1
> bclk:mclk ratio support") led to the bypass never happening
> as (ratio = 1) was caught in the existing if (ratio & 1) continue;
> check. The correct check sequence instead is:
>
>  - skip all ratios lower than one and higher than 512
>  - skip all odd ratios except for 1:1
>  - skip 1:1 ratio if and only if !support_1_1_ratio
>
> And for all others, calculate the appropriate divider. Adjust the
> code to facilitate this.
>
> Fixes: a50b7926d015 ("ASoC: fsl_sai: implement 1:1 bclk:mclk ratio
> support")
> Signed-off-by: Ahmad Fatoum 
>

Acked-by: Shengjiu Wang 

Best regards
Wang shengjiu


> ---
>  sound/soc/fsl/fsl_sai.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
> index a992d51568cc..50c377f16097 100644
> --- a/sound/soc/fsl/fsl_sai.c
> +++ b/sound/soc/fsl/fsl_sai.c
> @@ -372,7 +372,7 @@ static int fsl_sai_set_bclk(struct snd_soc_dai *dai,
> bool tx, u32 freq)
> continue;
> if (ratio == 1 && !support_1_1_ratio)
> continue;
> -   else if (ratio & 1)
> +   if ((ratio & 1) && ratio > 1)
> continue;
>
> diff = abs((long)clk_rate - ratio * freq);
> --
> 2.30.2
>
>


Re: [PATCH v2] ASoC: fsl-asoc-card: Fix jack_event() always return 0

2022-03-21 Thread Shengjiu Wang
On Mon, Mar 21, 2022 at 2:58 PM Meng Tang  wrote:

> Today, hp_jack_event and mic_jack_event always return 0. However,
> snd_soc_dapm_disable_pin and snd_soc_dapm_enable_pin may return a
> non-zero value, this will cause the user who calling hp_jack_event
> and mic_jack_event don't know whether the operation was really
> successfully.
>
> Signed-off-by: Meng Tang 
>

Acked-by: Shengjiu Wang 

Best regards
Wang Shengjiu

> ---
>  sound/soc/fsl/fsl-asoc-card.c | 12 
>  1 file changed, 4 insertions(+), 8 deletions(-)
>
> diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
> index 370bc790c6ba..d9a0d4768c4d 100644
> --- a/sound/soc/fsl/fsl-asoc-card.c
> +++ b/sound/soc/fsl/fsl-asoc-card.c
> @@ -462,11 +462,9 @@ static int hp_jack_event(struct notifier_block *nb,
> unsigned long event,
>
> if (event & SND_JACK_HEADPHONE)
> /* Disable speaker if headphone is plugged in */
> -   snd_soc_dapm_disable_pin(dapm, "Ext Spk");
> +   return snd_soc_dapm_disable_pin(dapm, "Ext Spk");
> else
> -   snd_soc_dapm_enable_pin(dapm, "Ext Spk");
> -
> -   return 0;
> +   return snd_soc_dapm_enable_pin(dapm, "Ext Spk");
>  }
>
>  static struct notifier_block hp_jack_nb = {
> @@ -481,11 +479,9 @@ static int mic_jack_event(struct notifier_block *nb,
> unsigned long event,
>
> if (event & SND_JACK_MICROPHONE)
> /* Disable dmic if microphone is plugged in */
> -   snd_soc_dapm_disable_pin(dapm, "DMIC");
> +   return snd_soc_dapm_disable_pin(dapm, "DMIC");
> else
> -   snd_soc_dapm_enable_pin(dapm, "DMIC");
> -
> -   return 0;
> +   return snd_soc_dapm_enable_pin(dapm, "DMIC");
>  }
>
>  static struct notifier_block mic_jack_nb = {
> --
> 2.20.1
>
>
>
>


Re: [PATCH] ASoC: fsl-asoc-card: Fix jack_event() always return 0

2022-03-20 Thread Shengjiu Wang
Hi

On Fri, Mar 18, 2022 at 5:35 PM Meng Tang  wrote:

> Today, hp_jack_event and mic_jack_event always return 0. However,
> snd_soc_dapm_disable_pin and snd_soc_dapm_enable_pin may return a
> non-zero value, this will cause the user who calling hp_jack_event
> and mic_jack_event don't know whether the operation was really
> successfully.
>
> This patch corrects the behavior by properly returning 1 when the
> value gets updated.
>
> Signed-off-by: Meng Tang 
> ---
>  sound/soc/fsl/fsl-asoc-card.c | 16 ++--
>  1 file changed, 10 insertions(+), 6 deletions(-)
>
> diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
> index 370bc790c6ba..f2641c2cb047 100644
> --- a/sound/soc/fsl/fsl-asoc-card.c
> +++ b/sound/soc/fsl/fsl-asoc-card.c
> @@ -457,16 +457,18 @@ static int fsl_asoc_card_audmux_init(struct
> device_node *np,
>  static int hp_jack_event(struct notifier_block *nb, unsigned long event,
>  void *data)
>  {
> +   int ret;
> +
> struct snd_soc_jack *jack = (struct snd_soc_jack *)data;
> struct snd_soc_dapm_context *dapm = >card->dapm;

The "int ret" should be here.
The variables have order, the short one should be behind the long one.


>




> if (event & SND_JACK_HEADPHONE)
> /* Disable speaker if headphone is plugged in */
> -   snd_soc_dapm_disable_pin(dapm, "Ext Spk");
> +   ret = snd_soc_dapm_disable_pin(dapm, "Ext Spk");
> else
> -   snd_soc_dapm_enable_pin(dapm, "Ext Spk");
> +   ret = snd_soc_dapm_enable_pin(dapm, "Ext Spk");
>
> -   return 0;
> +   return ret;
>  }
>
>  static struct notifier_block hp_jack_nb = {
> @@ -476,16 +478,18 @@ static struct notifier_block hp_jack_nb = {
>  static int mic_jack_event(struct notifier_block *nb, unsigned long event,
>   void *data)
>  {
> +   int ret;
> +
> struct snd_soc_jack *jack = (struct snd_soc_jack *)data;
> struct snd_soc_dapm_context *dapm = >card->dapm;
>
ditto.

>
> if (event & SND_JACK_MICROPHONE)
> /* Disable dmic if microphone is plugged in */
> -   snd_soc_dapm_disable_pin(dapm, "DMIC");
> +   ret = snd_soc_dapm_disable_pin(dapm, "DMIC");
> else
> -   snd_soc_dapm_enable_pin(dapm, "DMIC");
> +   ret = snd_soc_dapm_enable_pin(dapm, "DMIC");
>
> -   return 0;
> +   return ret;
>  }
>
>  static struct notifier_block mic_jack_nb = {
> --
> 2.20.1
>
>
>
>


Re: [PATCH] sound: fsl: add missing put_device() call in imx_hdmi_probe()

2021-12-20 Thread Shengjiu Wang
On Thu, Dec 9, 2021 at 5:58 PM 王擎  wrote:
>
>
> >> From: Wang Qing 
> >>
> >> of_find_device_by_node() takes a reference to the embedded struct device
> >> which needs to be dropped when error return.
> >
> >...
> >
> >>data = devm_kzalloc(>dev, sizeof(*data), GFP_KERNEL);
> >>if (!data) {
> >> + put_device(_pdev->dev);
> >
> >If it's of_find_device_by_node() you need an of_node_put() since you're
> >dropping a reference on the OF node.
> >
>
> Label fail will drop a reference on the OF node.
> Also, put_device() is called later except this branch,
> we just need to add put_device() here.
>
I agree with you. But could you please add the info in this
commit that
the commit:
f670b274f7f6 ASoC: imx-hdmi: add put_device() after of_find_device_by_node()
is partially fixing the original issue, so we still need this fix.

Best regards
Wang Shengjiu


Re: [PATCH] ASoC:fsl_spdif:Remove superfluous error message around platform_get_irq()

2021-06-10 Thread Shengjiu Wang
On Thu, Jun 10, 2021 at 12:02 PM Zhongjun Tan  wrote:
>
> From: Tan Zhongjun 
>
> The platform_get_irq() prints error message telling that interrupt is
> missing, hence there is no need to duplicated that message.
>
> Signed-off-by: Tan Zhongjun 

Acked-by: Shengjiu Wang 

> ---
>  sound/soc/fsl/fsl_spdif.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
> index 2a76714eb8e6..29cefd459241 100644
> --- a/sound/soc/fsl/fsl_spdif.c
> +++ b/sound/soc/fsl/fsl_spdif.c
> @@ -1368,10 +1368,8 @@ static int fsl_spdif_probe(struct platform_device 
> *pdev)
>
> for (i = 0; i < spdif_priv->soc->interrupts; i++) {
> irq = platform_get_irq(pdev, i);
> -   if (irq < 0) {
> -   dev_err(>dev, "no irq for node %s\n", 
> pdev->name);
> +   if (irq < 0)
> return irq;
> -   }
>
> ret = devm_request_irq(>dev, irq, spdif_isr, 0,
>dev_name(>dev), spdif_priv);
> --
> 2.17.1
>


Re: [PATCH] ASoC:fsl_easrc:Remove superfluous error message around platform_get_irq()

2021-06-10 Thread Shengjiu Wang
On Thu, Jun 10, 2021 at 8:52 PM Zhongjun Tan  wrote:
>
> From: Tan Zhongjun 
>
> Clean up the check for irq.dev_err is superfluous as platform_get_irq()
> already prints an error.Remove curly braces to confirm to styling
> requirements.
>
> Signed-off-by: Tan Zhongjun 

Acked-by: Shengjiu Wang 

> ---
>  sound/soc/fsl/fsl_easrc.c | 4 +---
>  1 file changed, 1 insertion(+), 3 deletions(-)
>
> diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
> index b1765c7d3bcd..25747433916e 100644
> --- a/sound/soc/fsl/fsl_easrc.c
> +++ b/sound/soc/fsl/fsl_easrc.c
> @@ -1901,10 +1901,8 @@ static int fsl_easrc_probe(struct platform_device 
> *pdev)
> }
>
> irq = platform_get_irq(pdev, 0);
> -   if (irq < 0) {
> -   dev_err(dev, "no irq for node %pOF\n", np);
> +   if (irq < 0)
> return irq;
> -   }
>
> ret = devm_request_irq(>dev, irq, fsl_easrc_isr, 0,
>dev_name(dev), easrc);
> --
> 2.17.1
>
>


Re: [PATCH -next] ASoC: imx-rpmsg: fix platform_no_drv_owner.cocci warnings

2021-05-31 Thread Shengjiu Wang
On Thu, May 27, 2021 at 6:48 PM Zou Wei  wrote:
>
> ./sound/soc/fsl/imx-rpmsg.c:140:3-8: No need to set .owner here. The core 
> will do it.
>
>  Remove .owner field if calls are used which set it automatically
>
> Generated by: scripts/coccinelle/api/platform_no_drv_owner.cocci
>
> Reported-by: Hulk Robot 
> Signed-off-by: Zou Wei 

Acked-by: Shengjiu Wang 

> ---
>  sound/soc/fsl/imx-rpmsg.c | 1 -
>  1 file changed, 1 deletion(-)
>
> diff --git a/sound/soc/fsl/imx-rpmsg.c b/sound/soc/fsl/imx-rpmsg.c
> index 5a9a470..f0cae8c 100644
> --- a/sound/soc/fsl/imx-rpmsg.c
> +++ b/sound/soc/fsl/imx-rpmsg.c
> @@ -137,7 +137,6 @@ static int imx_rpmsg_probe(struct platform_device *pdev)
>  static struct platform_driver imx_rpmsg_driver = {
> .driver = {
> .name = "imx-audio-rpmsg",
> -   .owner = THIS_MODULE,
> .pm = _soc_pm_ops,
> },
> .probe = imx_rpmsg_probe,
> --
> 2.6.2
>


Re: [PATCH] ASoC: fsl-asoc-card: Set .owner attribute when registering card.

2021-05-31 Thread Shengjiu Wang
On Fri, May 28, 2021 at 12:35 AM Nicolas Cavallari
 wrote:
>
> Otherwise, when compiled as module, a WARN_ON is triggered:
>
> WARNING: CPU: 0 PID: 5 at sound/core/init.c:208 snd_card_new+0x310/0x39c [snd]
> [...]
> CPU: 0 PID: 5 Comm: kworker/0:0 Not tainted 5.10.39 #1
> Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
> Workqueue: events deferred_probe_work_func
> [] (unwind_backtrace) from [] (show_stack+0x10/0x14)
> [] (show_stack) from [] (dump_stack+0xdc/0x104)
> [] (dump_stack) from [] (__warn+0xd8/0x114)
> [] (__warn) from [] (warn_slowpath_fmt+0x5c/0xc4)
> [] (warn_slowpath_fmt) from [] (snd_card_new+0x310/0x39c 
> [snd])
> [] (snd_card_new [snd]) from [] 
> (snd_soc_bind_card+0x334/0x9c4 [snd_soc_core])
> [] (snd_soc_bind_card [snd_soc_core]) from [] 
> (devm_snd_soc_register_card+0x30/0x6c [snd_soc_core])
> [] (devm_snd_soc_register_card [snd_soc_core]) from [] 
> (fsl_asoc_card_probe+0x550/0xcc8 [snd_soc_fsl_asoc_card])
> [] (fsl_asoc_card_probe [snd_soc_fsl_asoc_card]) from [] 
> (platform_drv_probe+0x48/0x98)
> [...]
>
> Signed-off-by: Nicolas Cavallari 

Acked-by: Shengjiu Wang 

> ---
>  sound/soc/fsl/fsl-asoc-card.c | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
> index c62bfd1c3ac7..4f55b316cf0f 100644
> --- a/sound/soc/fsl/fsl-asoc-card.c
> +++ b/sound/soc/fsl/fsl-asoc-card.c
> @@ -744,6 +744,7 @@ static int fsl_asoc_card_probe(struct platform_device 
> *pdev)
> /* Initialize sound card */
> priv->pdev = pdev;
> priv->card.dev = >dev;
> +   priv->card.owner = THIS_MODULE;
> ret = snd_soc_of_parse_card_name(>card, "model");
> if (ret) {
> snprintf(priv->name, sizeof(priv->name), "%s-audio",
> --
> 2.32.0.rc0
>


Re: [PATCH 2/2] ASoC: dt-bindings: imx-akcodec: Add binding doc for akcodec machine driver

2021-05-08 Thread Shengjiu Wang
Hi

On Tue, May 4, 2021 at 1:01 AM Rob Herring  wrote:
>
> On Fri, Apr 23, 2021 at 01:51:47PM +0800, Shengjiu Wang wrote:
> > Imx-akcodec is a new added machine driver for supporting
> > ak4458/ak5558/ak5552/ak4497 codec on i.MX platforms.
> >
> > Signed-off-by: Shengjiu Wang 
> > ---
> >  .../bindings/sound/imx-audio-akcodec.yaml | 60 +++
> >  1 file changed, 60 insertions(+)
> >  create mode 100644 
> > Documentation/devicetree/bindings/sound/imx-audio-akcodec.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/sound/imx-audio-akcodec.yaml 
> > b/Documentation/devicetree/bindings/sound/imx-audio-akcodec.yaml
> > new file mode 100644
> > index ..7419bf7224e9
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/sound/imx-audio-akcodec.yaml
> > @@ -0,0 +1,60 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
> > +%YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/sound/imx-audio-akcodec.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: NXP i.MX audio complex with AK4458/AK5558/AK5552/AK4497 codec
>
> Looks like the existing fsl-asoc-card.txt? You should convert to schema
> and use that. Otherwise, my comments are based on this all being 'new'.

Ok, let's treat it as 'new'

>
> > +
> > +maintainers:
> > +  - Shengjiu Wang 
> > +
> > +properties:
> > +  compatible:
> > +enum:
> > +  - fsl,imx8mq-audio-ak4458
> > +  - fsl,imx8mq-audio-ak4497
> > +  - fsl,imx8mq-audio-ak5558
> > +  - fsl,imx-audio-ak4497
> > +  - fsl,imx-audio-ak4458
> > +  - fsl,imx-audio-ak5558
> > +  - fsl,imx-audio-ak5552
>
> I continue to not understand why audio bindings need the codec(s) in the
> compatible strings. Can't you look up the codec thru the audio-codec
> property?

I will try to remove the codecs type from the compatible string and check
the codec type in driver.

>
> > +
> > +  model:
> > +$ref: /schemas/types.yaml#/definitions/string
> > +description: User specified audio sound card name
> > +
> > +  audio-cpu:
> > +$ref: /schemas/types.yaml#/definitions/phandle
> > +description: The phandle of a CPU DAI controller
> > +
> > +  audio-codec:
> > +description: The phandle of Codec DAI controllers, there are two
> > + controllers maximum.
>
> We have the common 'sound-dai' property. See the simple-card.yaml
> binding.

ok, will use sound-dai.

>
> > +
> > +  audio-asrc:
> > +$ref: /schemas/types.yaml#/definitions/phandle
> > +description: The phandle of ASRC. It can be absent if there's no
> > + need to add ASRC support via DPCM.
>
> Needs a vendor prefix.

ok,  can be removed in the next version.

>
> > +
> > +  fsl,tdm:
> > +$ref: /schemas/types.yaml#/definitions/flag
> > +description: |
> > +  This is a boolean property. If present, the TDM mode is enabled.
>
> But this one seems like something that could or should be common.

Ok, I will use the common one in the next version.

>
> > +
> > +required:
> > +  - compatible
> > +  - model
> > +  - audio-cpu
> > +  - audio-codec
> > +
> > +additionalProperties: false
> > +
> > +examples:
> > +  - |
> > +sound-ak4458 {
> > +compatible = "fsl,imx-audio-ak4458";
> > +model = "ak4458-audio";
> > +audio-cpu = <>;
> > +audio-codec = <_1>, <_2>;
> > +};
> > --
> > 2.17.1
> >


Re: [PATCH] ASoC: fsl_xcvr: Remove unneeded semicolon

2021-05-05 Thread Shengjiu Wang
On Thu, May 6, 2021 at 10:26 AM Wan Jiabing  wrote:
>
> Fix the following coccicheck warning:
>
> ./sound/soc/fsl/fsl_xcvr.c:739:2-3: Unneeded semicolon
>
> Signed-off-by: Wan Jiabing 

Acked-by: Shengjiu Wang 

> ---
>  sound/soc/fsl/fsl_xcvr.c | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
> index 6cb558165848..df7c189d97dd 100644
> --- a/sound/soc/fsl/fsl_xcvr.c
> +++ b/sound/soc/fsl/fsl_xcvr.c
> @@ -736,7 +736,7 @@ static int fsl_xcvr_load_firmware(struct fsl_xcvr *xcvr)
> /* clean current page, including data memory */
> memset_io(xcvr->ram_addr, 0, size);
> }
> -   };
> +   }
>
>  err_firmware:
> release_firmware(fw);
> --
> 2.25.1
>


Re: [PATCH] ASoC: fsl_sai: Don't use devm_regmap_init_mmio_clk

2021-04-12 Thread Shengjiu Wang
On Sun, Apr 11, 2021 at 10:43 PM Guenter Roeck  wrote:
>
> On Fri, Mar 19, 2021 at 04:06:43PM +0800, Shengjiu Wang wrote:
> > When there is power domain bind with bus clock,
> >
> > The call flow:
> > devm_regmap_init_mmio_clk
> >- clk_prepare()
> >   - clk_pm_runtime_get()
> >
> > cause the power domain of clock always be enabled after
> > regmap_init(). which impact the power consumption.
> >
> > So use devm_regmap_init_mmio instead of
> > devm_regmap_init_mmio_clk, then explicitly enable clock when
> > using by pm_runtime_get(), if CONFIG_PM=n, then
> > fsl_sai_runtime_resume will be explicitly called.
> >
> > Signed-off-by: Shengjiu Wang 
> > Signed-off-by: Viorel Suman 
>
> This patch results in a crash when running mcimx6ul-evk in qemu.
> Reverting it fixes the problem.
>
> Crash and bisect logs attached.
>
> Guenter
>
> ---
> [   19.196778] 8<--- cut here ---
> [   19.197011] Unhandled fault: external abort on non-linefetch (0x808) at 
> 0xd1588000
> [   19.197135] pgd = (ptrval)
> [   19.197203] [d1588000] *pgd=824da811, *pte=0202c653, *ppte=0202c453
> [   19.197764] Internal error: : 808 [#1] SMP ARM
> [   19.197953] Modules linked in:
> [   19.198108] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 
> 5.12.0-rc6-next-20210409 #1
> [   19.198234] Hardware name: Freescale i.MX6 Ultralite (Device Tree)
> [   19.198354] PC is at regmap_mmio_write32le+0x24/0x2c
> [   19.198482] LR is at regmap_mmio_write32le+0x1c/0x2c
> [   19.198544] pc : []lr : []psr: 6093
> [   19.198611] sp : c20b5cf0  ip :   fp : c017a344
> [   19.198669] r10: c217c1b0  r9 : c20b4000  r8 : c26fcc00
> [   19.198729] r7 : 0100  r6 : c26ff580  r5 :   r4 : 0100
> [   19.198801] r3 : d1588000  r2 : 0100  r1 : d1588000  r0 : c26ff580
> [   19.198896] Flags: nZCv  IRQs off  FIQs on  Mode SVC_32  ISA ARM  Segment 
> none
> [   19.198982] Control: 10c5387d  Table: 826bc06a  DAC: 0051
> [   19.199060] Register r0 information: slab kmalloc-64 start c26ff580 
> pointer offset 0 size 64
> [   19.199421] Register r1 information: 0-page vmalloc region starting at 
> 0xd1588000 allocated at __devm_ioremap+0x90/0xa4
> [   19.199587] Register r2 information: non-paged memory
> [   19.199667] Register r3 information: 0-page vmalloc region starting at 
> 0xd1588000 allocated at __devm_ioremap+0x90/0xa4
> [   19.199774] Register r4 information: non-paged memory
> [   19.199832] Register r5 information: NULL pointer
> [   19.199888] Register r6 information: slab kmalloc-64 start c26ff580 
> pointer offset 0 size 64
> [   19.18] Register r7 information: non-paged memory
> [   19.200056] Register r8 information: slab kmalloc-1k start c26fcc00 
> pointer offset 0 size 1024
> [   19.200167] Register r9 information: non-slab/vmalloc memory
> [   19.200252] Register r10 information: slab kmalloc-1k start c217c000 
> pointer offset 432 size 1024
> [   19.200367] Register r11 information: non-slab/vmalloc memory
> [   19.200431] Register r12 information: NULL pointer
> [   19.200495] Process swapper/0 (pid: 1, stack limit = 0x(ptrval))
> [   19.200596] Stack: (0xc20b5cf0 to 0xc20b6000)
> [   19.200755] 5ce0: c26ff580  
> 0100 c0965f40
> [   19.200932] 5d00: c26fcc00   c095f3cc c20c c26fcc00 
>  0100
> [   19.201096] 5d20: c269b840  c20b4000 c217c1b0 c017a344 c0961130 
> 0080 c217c010
> [   19.201259] 5d40: c26ff5c0 c0d21354 c217c010 c0946e24  c0946e24 
> c217c114 c094a894
> [   19.201420] 5d60: c217c010 c0946e24 c2173810 c217c114 c2173914 c20b4000 
> c217c1b0 c094a930
> [   19.201582] 5d80: c217c010 c0946e24 c2173810 c094a468 c20c c20b4000 
> c094a6a0 6013
> [   19.201744] 5da0: 0002 cbdc8024 c217c114 5bdc6b72 6013 6013 
> c217c114 0004
> [   19.201906] 5dc0: 0002 cbdc8024 c20b4000 c269b880  c094a6b4 
> c269b840 c217c010
> [   19.202067] 5de0: c217c000 c0d2176c     
> c2176340 c21d5c00
> [   19.202228] 5e00:  6b6c636d 0033 5bdc6b72   
> c217c010 c18d47fc
> [   19.202389] 5e20: c1f70c20  c18d47fc   c093f540 
> c217c010 c1f70c1c
> [   19.202551] 5e40:  c1f70c20  c093cdec c217c010 c18d47fc 
> c18d47fc c20b4000
> [   19.202712] 5e60:  c166e854 c20af880 c093d0fc c217c010  
> c18d47fc c093d418
> [   19.202873] 5e80:  c18d47fc c217c010 c093d484  c18d47fc 
> c093d420 c093aefc
> [   19.203035] 5ea0: c26fe980 c20ae2b0 c214be94 5bdc6b72 c20ae2e4 c18d47fc 
> c26fe980 
> [   19.203196] 5ec0: c187b

Re: [PATCH] ASoC: imx-hdmi: no need to set .owner when using module_platform_driver

2021-02-18 Thread Shengjiu Wang
On Thu, Feb 11, 2021 at 5:21 PM Tian Tao  wrote:
>
> the module_platform_driver will call platform_driver_register.
> and It will set the .owner to THIS_MODULE
>
> Signed-off-by: Tian Tao 

Acked-by: Shengjiu Wang 


Re: [PATCH] ASoC: fsl: constify static snd_soc_dai_ops structs

2021-02-07 Thread Shengjiu Wang
On Sun, Feb 7, 2021 at 6:58 AM Rikard Falkeborn
 wrote:
>
> The only usage of these is to assign their address to the 'ops' field in
> the snd_soc_dai_driver struct, which is a pointer to const. Make them
> const to allow the compiler to put them in read-only memory.
>
> Signed-off-by: Rikard Falkeborn 

Acked-by: Shengjiu Wang 


Re: [PATCH 5/7] ASoC: imx-pcm-rpmsg: Add platform driver for audio base on rpmsg

2021-02-07 Thread Shengjiu Wang
On Fri, Feb 5, 2021 at 11:00 PM Mark Brown  wrote:
>
> On Fri, Feb 05, 2021 at 02:57:28PM +0800, Shengjiu Wang wrote:
>
> > + if (params_format(params) == SNDRV_PCM_FORMAT_S16_LE)
> > + msg->s_msg.param.format   = RPMSG_S16_LE;
> > + else if (params_format(params) == SNDRV_PCM_FORMAT_S24_LE)
>
> Again this should be a switch statement.
>
> > + if (params_channels(params) == 1)
> > + msg->s_msg.param.channels = RPMSG_CH_LEFT;
> > + else
> > + msg->s_msg.param.channels = RPMSG_CH_STEREO;
>
> Shouldn't this be reporting an error if the number of channels is more
> than 2?
>
> > + /*
> > +  * if the data in the buffer is less than one period
> > +  * send message immediately.
> > +  * if there is more than one period data, delay one
> > +  * period (timer) to send the message.
> > +  */
> > + if ((avail - writen_num * period_size) <= period_size) {
> > + imx_rpmsg_insert_workqueue(substream, msg, info);
> > + } else if (rpmsg->force_lpa && !timer_pending(timer)) {
> > + int time_msec;
> > +
> > + time_msec = (int)(runtime->period_size * 1000 / 
> > runtime->rate);
> > + mod_timer(timer, jiffies + 
> > msecs_to_jiffies(time_msec));
> > + }
>
> The comment here is at least confusing - why would we not send a full
> buffer immediately if we have one?  This sounds like it's the opposite
> way round to what we'd do if we were trying to cut down the number of
> messages.  It might help to say which buffer and where?
>
> > + /**
> > +  * Every work in the work queue, first we check if there
>
> /** comments are only for kerneldoc.

Thanks Mark, I will update them.

Best regards
wang shengjiu


Re: [PATCH 4/7] ASoC: imx-audio-rpmsg: Add rpmsg_driver for audio channel

2021-02-07 Thread Shengjiu Wang
On Fri, Feb 5, 2021 at 10:27 PM Mark Brown  wrote:
>
> On Fri, Feb 05, 2021 at 02:57:27PM +0800, Shengjiu Wang wrote:
>
> > + /* TYPE C is notification from M core */
> > + if (r_msg->header.type == MSG_TYPE_C) {
> > + if (r_msg->header.cmd == TX_PERIOD_DONE) {
>
> > + } else if (r_msg->header.cmd == RX_PERIOD_DONE) {
>
> A switch statement would be clearer and more extensible...
>
> > + /* TYPE B is response msg */
> > + if (r_msg->header.type == MSG_TYPE_B) {
> > + memcpy(>r_msg, r_msg, sizeof(struct rpmsg_r_msg));
> > + complete(>cmd_complete);
> > + }
>
> ...and make this flow clearer for example.  Do we need to warn on
> unknown messages?

Thanks for reviewing. I will update them.

Best regards
wang shengjiu


Re: [PATCH] ASoC: fsl_spdif: Utilize the defined parameter to clear code

2021-02-01 Thread Shengjiu Wang
On Thu, Jan 28, 2021 at 7:28 PM Tang Bin  wrote:
>
> Utilize the defined parameter 'dev' to make the code cleaner.
>
> Signed-off-by: Tang Bin 

Acked-by: Shengjiu Wang 


Re: [PATCH] ASoC: fsl_xcvr: remove unneeded semicolon

2021-02-01 Thread Shengjiu Wang
On Mon, Feb 1, 2021 at 4:08 PM Yang Li  wrote:
>
> Eliminate the following coccicheck warning:
> ./sound/soc/fsl/fsl_xcvr.c:739:2-3: Unneeded semicolon
>
> Reported-by: Abaci Robot 
> Signed-off-by: Yang Li 

Acked-by: Shengjiu Wang 


Re: [PATCH 2/2] ASoC: fsl: Add imx-hdmi machine driver

2020-12-02 Thread Shengjiu Wang
On Thu, Dec 3, 2020 at 4:23 AM Nicolin Chen  wrote:
>
> On Fri, Nov 27, 2020 at 01:30:21PM +0800, Shengjiu Wang wrote:
> > The driver is initially designed for sound card using HDMI
> > interface on i.MX platform. There is internal HDMI IP or
> > external HDMI modules connect with SAI or AUD2HTX interface.
> > It supports both transmitter and receiver devices.
> >
> > Signed-off-by: Shengjiu Wang 
> > ---
> >  sound/soc/fsl/Kconfig|  12 ++
> >  sound/soc/fsl/Makefile   |   2 +
> >  sound/soc/fsl/imx-hdmi.c | 235 +++
> >  3 files changed, 249 insertions(+)
> >  create mode 100644 sound/soc/fsl/imx-hdmi.c
>
> > diff --git a/sound/soc/fsl/imx-hdmi.c b/sound/soc/fsl/imx-hdmi.c
> > new file mode 100644
> > index ..ac164514b1b2
> > --- /dev/null
> > +++ b/sound/soc/fsl/imx-hdmi.c
>
> > +static int imx_hdmi_hw_params(struct snd_pcm_substream *substream,
> > +   struct snd_pcm_hw_params *params)
> > +{
> > + struct snd_soc_pcm_runtime *rtd = substream->private_data;
> > + struct imx_hdmi_data *data = snd_soc_card_get_drvdata(rtd->card);
> > + bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
> > + struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
> > + struct snd_soc_card *card = rtd->card;
> > + struct device *dev = card->dev;
> > + int ret;
> > +
> > + /* set cpu DAI configuration */
> > + ret = snd_soc_dai_set_sysclk(cpu_dai, data->cpu_priv.sysclk_id[tx],
> > +  8 * data->cpu_priv.slot_width * 
> > params_rate(params),
>
> Looks like fixed 2 slots being used, judging by the set_tdm_slot
> call below. Then...why "8 *"? Probably need a line of comments?

The master clock always 256 * rate, when slot_width=32.  so use
the 8 * slot_width.  will add comments.

>
> > +  tx ? SND_SOC_CLOCK_OUT : 
> > SND_SOC_CLOCK_IN);
> > + if (ret && ret != -ENOTSUPP) {
> > + dev_err(dev, "failed to set cpu sysclk: %d\n", ret);
> > + return ret;
> > + }
> > +
> > + ret = snd_soc_dai_set_tdm_slot(cpu_dai, 0, 0, 2, 
> > data->cpu_priv.slot_width);
>
> May have a local variable to cache slot_width.

ok.

>
> > +static int imx_hdmi_probe(struct platform_device *pdev)
>
> > + data->dai.name = "i.MX HDMI";
> > + data->dai.stream_name = "i.MX HDMI";
> > + data->dai.cpus->dai_name = dev_name(_pdev->dev);
> > + data->dai.platforms->of_node = cpu_np;
> > + data->dai.ops = _hdmi_ops;
> > + data->dai.playback_only = true;
> > + data->dai.capture_only = false;
> > + data->dai.init = imx_hdmi_init;
> > +
> > +
> > + if (of_property_read_bool(np, "hdmi-out")) {
> > + data->dai.playback_only = true;
> > + data->dai.capture_only = false;
> > + data->dai.codecs->dai_name = "i2s-hifi";
> > + data->dai.codecs->name = "hdmi-audio-codec.1";
> > + data->dai.dai_fmt = data->dai_fmt |
> > + SND_SOC_DAIFMT_NB_NF |
> > + SND_SOC_DAIFMT_CBS_CFS;
> > + }
> > +
> > + if (of_property_read_bool(np, "hdmi-in")) {
> > + data->dai.playback_only = false;
> > + data->dai.capture_only = true;
> > + data->dai.codecs->dai_name = "i2s-hifi";
> > + data->dai.codecs->name = "hdmi-audio-codec.2";
> > + data->dai.dai_fmt = data->dai_fmt |
> > + SND_SOC_DAIFMT_NB_NF |
> > + SND_SOC_DAIFMT_CBM_CFM;
> > + }
> > +
> > + if ((data->dai.playback_only && data->dai.capture_only) ||
> > + (!data->dai.playback_only && !data->dai.capture_only)) {
> > + dev_err(>dev, "Wrongly enable HDMI DAI link\n");
> > + goto fail;
> > + }
>
> Seems that this condition check can never be true, given that:
> 1. By default: playback_only=true && capture_only=false
> 2. Conditionally overwritten: playback_only=true && capture_only=false
> 3. Conditionally overwritten: playback_only=false && capture_only=true
>
> If I understand it correctly, probably should be something like:
> bool hdmi_out = of_property_read_bool(np, "hdmi-out");
> bool hdmi_in = of_property_read_bool(np, "hdmi-in");
>
> if ((hdmi_out && hdmi_in) || (!hdmi_out || !hdmi_in))
> // "Invalid HDMI DAI link"; goto fail;
>
> if (hdmi_out) {
> // ...
> } else if (hdmi_in) {
> // ...
> } else // No need of this line if two properties are exclusive
>

Good catch, will update it.

> > + data->card.num_links = 1;
> > + data->card.dai_link = >dai;
> > +
> > + platform_set_drvdata(pdev, >card);
>
> Why pass card pointer?

Seems it duplicates with dev_set_drvdata(card->dev, card);
in snd_soc_register_card.  will remove it.

best regards
wang shengjiu


[PATCH v2 3/3] ASoC: fsl-asoc-card: Support Headphone and Microphone Jack detection

2020-07-15 Thread Shengjiu Wang
Use asoc_simple_init_jack function from simple card to implement
the Headphone and Microphone detection.
Register notifier to disable Speaker when Headphone is plugged in
and enable Speaker when Headphone is unplugged.
Register notifier to disable Digital Microphone when Analog Microphone
is plugged in and enable DMIC when Analog Microphone is unplugged.

Signed-off-by: Shengjiu Wang 
Acked-by: Nicolin Chen 
---
 sound/soc/fsl/Kconfig |  1 +
 sound/soc/fsl/fsl-asoc-card.c | 77 ++-
 2 files changed, 76 insertions(+), 2 deletions(-)

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index ea7b4787a8af..1c4ca5ec8caf 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -315,6 +315,7 @@ config SND_SOC_FSL_ASOC_CARD
depends on OF && I2C
# enforce SND_SOC_FSL_ASOC_CARD=m if SND_AC97_CODEC=m:
depends on SND_AC97_CODEC || SND_AC97_CODEC=n
+   select SND_SIMPLE_CARD_UTILS
select SND_SOC_IMX_AUDMUX
select SND_SOC_IMX_PCM_DMA
select SND_SOC_FSL_ESAI
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index faac6ce9a82c..f0cde3ecb5b7 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -15,6 +15,8 @@
 #endif
 #include 
 #include 
+#include 
+#include 
 
 #include "fsl_esai.h"
 #include "fsl_sai.h"
@@ -65,6 +67,8 @@ struct cpu_priv {
 /**
  * struct fsl_asoc_card_priv - Freescale Generic ASOC card private data
  * @dai_link: DAI link structure including normal one and DPCM link
+ * @hp_jack: Headphone Jack structure
+ * @mic_jack: Microphone Jack structure
  * @pdev: platform device pointer
  * @codec_priv: CODEC private data
  * @cpu_priv: CPU private data
@@ -79,6 +83,8 @@ struct cpu_priv {
 
 struct fsl_asoc_card_priv {
struct snd_soc_dai_link dai_link[3];
+   struct asoc_simple_jack hp_jack;
+   struct asoc_simple_jack mic_jack;
struct platform_device *pdev;
struct codec_priv codec_priv;
struct cpu_priv cpu_priv;
@@ -445,6 +451,44 @@ static int fsl_asoc_card_audmux_init(struct device_node 
*np,
return 0;
 }
 
+static int hp_jack_event(struct notifier_block *nb, unsigned long event,
+void *data)
+{
+   struct snd_soc_jack *jack = (struct snd_soc_jack *)data;
+   struct snd_soc_dapm_context *dapm = >card->dapm;
+
+   if (event & SND_JACK_HEADPHONE)
+   /* Disable speaker if headphone is plugged in */
+   snd_soc_dapm_disable_pin(dapm, "Ext Spk");
+   else
+   snd_soc_dapm_enable_pin(dapm, "Ext Spk");
+
+   return 0;
+}
+
+static struct notifier_block hp_jack_nb = {
+   .notifier_call = hp_jack_event,
+};
+
+static int mic_jack_event(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+   struct snd_soc_jack *jack = (struct snd_soc_jack *)data;
+   struct snd_soc_dapm_context *dapm = >card->dapm;
+
+   if (event & SND_JACK_MICROPHONE)
+   /* Disable dmic if microphone is plugged in */
+   snd_soc_dapm_disable_pin(dapm, "DMIC");
+   else
+   snd_soc_dapm_enable_pin(dapm, "DMIC");
+
+   return 0;
+}
+
+static struct notifier_block mic_jack_nb = {
+   .notifier_call = mic_jack_event,
+};
+
 static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
 {
struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card);
@@ -745,8 +789,37 @@ static int fsl_asoc_card_probe(struct platform_device 
*pdev)
snd_soc_card_set_drvdata(>card, priv);
 
ret = devm_snd_soc_register_card(>dev, >card);
-   if (ret && ret != -EPROBE_DEFER)
-   dev_err(>dev, "snd_soc_register_card failed (%d)\n", ret);
+   if (ret) {
+   if (ret != -EPROBE_DEFER)
+   dev_err(>dev, "snd_soc_register_card failed 
(%d)\n", ret);
+   goto asrc_fail;
+   }
+
+   /*
+* Properties "hp-det-gpio" and "mic-det-gpio" are optional, and
+* asoc_simple_init_jack uses these properties for creating
+* Headphone Jack and Microphone Jack.
+*
+* The notifier is initialized in snd_soc_card_jack_new(), then
+* snd_soc_jack_notifier_register can be called.
+*/
+   if (of_property_read_bool(np, "hp-det-gpio")) {
+   ret = asoc_simple_init_jack(>card, >hp_jack,
+   1, NULL, "Headphone Jack");
+   if (ret)
+   goto asrc_fail;
+
+   snd_soc_jack_notifier_register(>hp_jack.jack, 
_jack_nb);
+   }
+
+   if (of_property_read_bool(np, "mic-det-gpio")) {
+   ret = asoc_simple_init_jack(>card, >mic_jack,
+ 

[PATCH v2 2/3] ASoC: bindings: fsl-asoc-card: Support hp-det-gpio and mic-det-gpio

2020-07-15 Thread Shengjiu Wang
Add headphone and microphone detection GPIO support.
These properties are optional.

Signed-off-by: Shengjiu Wang 
Acked-by: Nicolin Chen 
---
 Documentation/devicetree/bindings/sound/fsl-asoc-card.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt 
b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
index 133d7e14a4d0..8a6a3d0fda5e 100644
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
@@ -69,6 +69,9 @@ Optional properties:
coexisting in order to support the old bindings
of wm8962 and sgtl5000.
 
+  - hp-det-gpio: The GPIO that detect headphones are plugged in
+  - mic-det-gpio   : The GPIO that detect microphones are plugged in
+
 Optional unless SSI is selected as a CPU DAI:
 
   - mux-int-port   : The internal port of the i.MX audio muxer (AUDMUX)
-- 
2.27.0



[PATCH v2 1/3] ASoC: simple-card-utils: Support configure pin_name for asoc_simple_init_jack

2020-07-15 Thread Shengjiu Wang
Currently the pin_name is fixed in asoc_simple_init_jack, but some driver
may use a different pin_name. So add a new parameter in
asoc_simple_init_jack for configuring pin_name.

If this parameter is NULL, then the default pin_name is used.

Signed-off-by: Shengjiu Wang 
Acked-by: Nicolin Chen 
---
 include/sound/simple_card_utils.h | 6 +++---
 sound/soc/generic/simple-card-utils.c | 7 ---
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/include/sound/simple_card_utils.h 
b/include/sound/simple_card_utils.h
index bbdd1542d6f1..86a1e956991e 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -12,9 +12,9 @@
 #include 
 
 #define asoc_simple_init_hp(card, sjack, prefix) \
-   asoc_simple_init_jack(card, sjack, 1, prefix)
+   asoc_simple_init_jack(card, sjack, 1, prefix, NULL)
 #define asoc_simple_init_mic(card, sjack, prefix) \
-   asoc_simple_init_jack(card, sjack, 0, prefix)
+   asoc_simple_init_jack(card, sjack, 0, prefix, NULL)
 
 struct asoc_simple_dai {
const char *name;
@@ -131,7 +131,7 @@ int asoc_simple_parse_pin_switches(struct snd_soc_card 
*card,
 
 int asoc_simple_init_jack(struct snd_soc_card *card,
   struct asoc_simple_jack *sjack,
-  int is_hp, char *prefix);
+  int is_hp, char *prefix, char *pin);
 int asoc_simple_init_priv(struct asoc_simple_priv *priv,
   struct link_info *li);
 
diff --git a/sound/soc/generic/simple-card-utils.c 
b/sound/soc/generic/simple-card-utils.c
index 8c54dc6710fe..b408cb5ed644 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -540,7 +540,8 @@ EXPORT_SYMBOL_GPL(asoc_simple_parse_pin_switches);
 
 int asoc_simple_init_jack(struct snd_soc_card *card,
  struct asoc_simple_jack *sjack,
- int is_hp, char *prefix)
+ int is_hp, char *prefix,
+ char *pin)
 {
struct device *dev = card->dev;
enum of_gpio_flags flags;
@@ -557,12 +558,12 @@ int asoc_simple_init_jack(struct snd_soc_card *card,
 
if (is_hp) {
snprintf(prop, sizeof(prop), "%shp-det-gpio", prefix);
-   pin_name= "Headphones";
+   pin_name= pin ? pin : "Headphones";
gpio_name   = "Headphone detection";
mask= SND_JACK_HEADPHONE;
} else {
snprintf(prop, sizeof(prop), "%smic-det-gpio", prefix);
-   pin_name= "Mic Jack";
+   pin_name= pin ? pin : "Mic Jack";
gpio_name   = "Mic detection";
mask= SND_JACK_MICROPHONE;
}
-- 
2.27.0



[PATCH v2 0/3] ASoC: fsl-asoc-card: Support hp and mic detection

2020-07-15 Thread Shengjiu Wang
Support hp and mic detection.
Add a parameter for asoc_simple_init_jack.

Shengjiu Wang (3):
  ASoC: simple-card-utils: Support configure pin_name for
asoc_simple_init_jack
  ASoC: bindings: fsl-asoc-card: Support hp-det-gpio and mic-det-gpio
  ASoC: fsl-asoc-card: Support Headphone and Microphone Jack detection

changes in v2:
- Add more comments in third commit
- Add Acked-by Nicolin.

 .../bindings/sound/fsl-asoc-card.txt  |  3 +
 include/sound/simple_card_utils.h |  6 +-
 sound/soc/fsl/Kconfig |  1 +
 sound/soc/fsl/fsl-asoc-card.c | 77 ++-
 sound/soc/generic/simple-card-utils.c |  7 +-
 5 files changed, 86 insertions(+), 8 deletions(-)

-- 
2.27.0



Re: [PATCH 3/3] ASoC: fsl-asoc-card: Support Headphone and Microphone Jack detection

2020-07-14 Thread Shengjiu Wang
On Wed, Jul 15, 2020 at 5:16 AM Nicolin Chen  wrote:
>
> Hi Shengjiu,
>
> The whole series looks good to me. Just a couple of small
> questions inline:
>
> On Tue, Jul 14, 2020 at 05:05:36PM +0800, Shengjiu Wang wrote:
> > Use asoc_simple_init_jack function from simple card to implement
> > the Headphone and Microphone detection.
> > Register notifier to disable Speaker when Headphone is plugged in
> > and enable Speaker when Headphone is unplugged.
> > Register notifier to disable Digital Microphone when Analog Microphone
> > is plugged in and enable DMIC when Analog Microphone is unplugged.
> >
> > Signed-off-by: Shengjiu Wang 
> > ---
> >  sound/soc/fsl/Kconfig |  1 +
> >  sound/soc/fsl/fsl-asoc-card.c | 69 ++-
> >  2 files changed, 68 insertions(+), 2 deletions(-)
>
> >  static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
> >  {
> >   struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card);
> > @@ -745,8 +789,29 @@ static int fsl_asoc_card_probe(struct platform_device 
> > *pdev)
> >   snd_soc_card_set_drvdata(>card, priv);
> >
> >   ret = devm_snd_soc_register_card(>dev, >card);
> > - if (ret && ret != -EPROBE_DEFER)
> > - dev_err(>dev, "snd_soc_register_card failed (%d)\n", 
> > ret);
> > + if (ret) {
> > + if (ret != -EPROBE_DEFER)
> > + dev_err(>dev, "snd_soc_register_card failed 
> > (%d)\n", ret);
>
> I think we may move this EPROBE_DEFER to the asrc_fail label.

If we move this to asrc_fail label, then it will be hard to define the
error message.
There are many places that goto asrc_fail.

>
> > + goto asrc_fail;
> > + }
> > +
> > + if (of_property_read_bool(np, "hp-det-gpio")) {
>
> Could we move this check inside asoc_simple_init_jack? There's no
> problem with doing it here though, yet I got a bit confused by it
> as I thought it's a boolean type property, which would be against
> the DT bindings until I saw asoc_simple_init_jack() uses the same
> string to get the GPIO. Just it probably would be a bit tricky as
> we need it to be optional here.
>
> Otherwise, I think we may add a line of comments to indicate that
> the API would use the same string to get the GPIO.

In asoc_simple_init_jack, gpio_is_valid() will be invalid when there is
no "hp-det-gpio" property, and asoc_simple_init_jack will return 0.

The reason why I add a check here is mostly for
snd_soc_jack_notifier_register().
when there is no jack created, there will be a kernel dump.

or I can use this code:

-   if (of_property_read_bool(np, "hp-det-gpio")) {
-   ret = asoc_simple_init_jack(>card, >hp_jack,
-   1, NULL, "Headphone Jack");
-   if (ret)
-   goto asrc_fail;
+   ret = asoc_simple_init_jack(>card, >hp_jack,
+   1, NULL, "Headphone Jack");
+   if (ret)
+   goto asrc_fail;

+   if (priv->hp_jack.jack.jack)
snd_soc_jack_notifier_register(>hp_jack.jack,
_jack_nb);
-   }

what do you think?

best regards
wang shengjiu


[PATCH 3/3] ASoC: fsl-asoc-card: Support Headphone and Microphone Jack detection

2020-07-14 Thread Shengjiu Wang
Use asoc_simple_init_jack function from simple card to implement
the Headphone and Microphone detection.
Register notifier to disable Speaker when Headphone is plugged in
and enable Speaker when Headphone is unplugged.
Register notifier to disable Digital Microphone when Analog Microphone
is plugged in and enable DMIC when Analog Microphone is unplugged.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/Kconfig |  1 +
 sound/soc/fsl/fsl-asoc-card.c | 69 ++-
 2 files changed, 68 insertions(+), 2 deletions(-)

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index ea7b4787a8af..1c4ca5ec8caf 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -315,6 +315,7 @@ config SND_SOC_FSL_ASOC_CARD
depends on OF && I2C
# enforce SND_SOC_FSL_ASOC_CARD=m if SND_AC97_CODEC=m:
depends on SND_AC97_CODEC || SND_AC97_CODEC=n
+   select SND_SIMPLE_CARD_UTILS
select SND_SOC_IMX_AUDMUX
select SND_SOC_IMX_PCM_DMA
select SND_SOC_FSL_ESAI
diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index faac6ce9a82c..313058789ea9 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -15,6 +15,8 @@
 #endif
 #include 
 #include 
+#include 
+#include 
 
 #include "fsl_esai.h"
 #include "fsl_sai.h"
@@ -65,6 +67,8 @@ struct cpu_priv {
 /**
  * struct fsl_asoc_card_priv - Freescale Generic ASOC card private data
  * @dai_link: DAI link structure including normal one and DPCM link
+ * @hp_jack: Headphone Jack structure
+ * @mic_jack: Microphone Jack structure
  * @pdev: platform device pointer
  * @codec_priv: CODEC private data
  * @cpu_priv: CPU private data
@@ -79,6 +83,8 @@ struct cpu_priv {
 
 struct fsl_asoc_card_priv {
struct snd_soc_dai_link dai_link[3];
+   struct asoc_simple_jack hp_jack;
+   struct asoc_simple_jack mic_jack;
struct platform_device *pdev;
struct codec_priv codec_priv;
struct cpu_priv cpu_priv;
@@ -445,6 +451,44 @@ static int fsl_asoc_card_audmux_init(struct device_node 
*np,
return 0;
 }
 
+static int hp_jack_event(struct notifier_block *nb, unsigned long event,
+void *data)
+{
+   struct snd_soc_jack *jack = (struct snd_soc_jack *)data;
+   struct snd_soc_dapm_context *dapm = >card->dapm;
+
+   if (event & SND_JACK_HEADPHONE)
+   /* Disable speaker if headphone is plugged in */
+   snd_soc_dapm_disable_pin(dapm, "Ext Spk");
+   else
+   snd_soc_dapm_enable_pin(dapm, "Ext Spk");
+
+   return 0;
+}
+
+static struct notifier_block hp_jack_nb = {
+   .notifier_call = hp_jack_event,
+};
+
+static int mic_jack_event(struct notifier_block *nb, unsigned long event,
+ void *data)
+{
+   struct snd_soc_jack *jack = (struct snd_soc_jack *)data;
+   struct snd_soc_dapm_context *dapm = >card->dapm;
+
+   if (event & SND_JACK_MICROPHONE)
+   /* Disable dmic if microphone is plugged in */
+   snd_soc_dapm_disable_pin(dapm, "DMIC");
+   else
+   snd_soc_dapm_enable_pin(dapm, "DMIC");
+
+   return 0;
+}
+
+static struct notifier_block mic_jack_nb = {
+   .notifier_call = mic_jack_event,
+};
+
 static int fsl_asoc_card_late_probe(struct snd_soc_card *card)
 {
struct fsl_asoc_card_priv *priv = snd_soc_card_get_drvdata(card);
@@ -745,8 +789,29 @@ static int fsl_asoc_card_probe(struct platform_device 
*pdev)
snd_soc_card_set_drvdata(>card, priv);
 
ret = devm_snd_soc_register_card(>dev, >card);
-   if (ret && ret != -EPROBE_DEFER)
-   dev_err(>dev, "snd_soc_register_card failed (%d)\n", ret);
+   if (ret) {
+   if (ret != -EPROBE_DEFER)
+   dev_err(>dev, "snd_soc_register_card failed 
(%d)\n", ret);
+   goto asrc_fail;
+   }
+
+   if (of_property_read_bool(np, "hp-det-gpio")) {
+   ret = asoc_simple_init_jack(>card, >hp_jack,
+   1, NULL, "Headphone Jack");
+   if (ret)
+   goto asrc_fail;
+
+   snd_soc_jack_notifier_register(>hp_jack.jack, 
_jack_nb);
+   }
+
+   if (of_property_read_bool(np, "mic-det-gpio")) {
+   ret = asoc_simple_init_jack(>card, >mic_jack,
+   0, NULL, "Mic Jack");
+   if (ret)
+   goto asrc_fail;
+
+   snd_soc_jack_notifier_register(>mic_jack.jack, 
_jack_nb);
+   }
 
 asrc_fail:
of_node_put(asrc_np);
-- 
2.27.0



[PATCH 2/3] ASoC: bindings: fsl-asoc-card: Support hp-det-gpio and mic-det-gpio

2020-07-14 Thread Shengjiu Wang
Add headphone and microphone detection GPIO support.

Signed-off-by: Shengjiu Wang 
---
 Documentation/devicetree/bindings/sound/fsl-asoc-card.txt | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt 
b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
index 133d7e14a4d0..8a6a3d0fda5e 100644
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
@@ -69,6 +69,9 @@ Optional properties:
coexisting in order to support the old bindings
of wm8962 and sgtl5000.
 
+  - hp-det-gpio: The GPIO that detect headphones are plugged in
+  - mic-det-gpio   : The GPIO that detect microphones are plugged in
+
 Optional unless SSI is selected as a CPU DAI:
 
   - mux-int-port   : The internal port of the i.MX audio muxer (AUDMUX)
-- 
2.27.0



[PATCH 1/3] ASoC: simple-card-utils: Support configure pin_name for asoc_simple_init_jack

2020-07-14 Thread Shengjiu Wang
Currently the pin_name is fixed in asoc_simple_init_jack, but some driver
may use a different pin_name. So add a new parameter in
asoc_simple_init_jack for configuring pin_name.

If this parameter is NULL, then the default pin_name is used.

Signed-off-by: Shengjiu Wang 
---
 include/sound/simple_card_utils.h | 6 +++---
 sound/soc/generic/simple-card-utils.c | 7 ---
 2 files changed, 7 insertions(+), 6 deletions(-)

diff --git a/include/sound/simple_card_utils.h 
b/include/sound/simple_card_utils.h
index bbdd1542d6f1..86a1e956991e 100644
--- a/include/sound/simple_card_utils.h
+++ b/include/sound/simple_card_utils.h
@@ -12,9 +12,9 @@
 #include 
 
 #define asoc_simple_init_hp(card, sjack, prefix) \
-   asoc_simple_init_jack(card, sjack, 1, prefix)
+   asoc_simple_init_jack(card, sjack, 1, prefix, NULL)
 #define asoc_simple_init_mic(card, sjack, prefix) \
-   asoc_simple_init_jack(card, sjack, 0, prefix)
+   asoc_simple_init_jack(card, sjack, 0, prefix, NULL)
 
 struct asoc_simple_dai {
const char *name;
@@ -131,7 +131,7 @@ int asoc_simple_parse_pin_switches(struct snd_soc_card 
*card,
 
 int asoc_simple_init_jack(struct snd_soc_card *card,
   struct asoc_simple_jack *sjack,
-  int is_hp, char *prefix);
+  int is_hp, char *prefix, char *pin);
 int asoc_simple_init_priv(struct asoc_simple_priv *priv,
   struct link_info *li);
 
diff --git a/sound/soc/generic/simple-card-utils.c 
b/sound/soc/generic/simple-card-utils.c
index 8c54dc6710fe..b408cb5ed644 100644
--- a/sound/soc/generic/simple-card-utils.c
+++ b/sound/soc/generic/simple-card-utils.c
@@ -540,7 +540,8 @@ EXPORT_SYMBOL_GPL(asoc_simple_parse_pin_switches);
 
 int asoc_simple_init_jack(struct snd_soc_card *card,
  struct asoc_simple_jack *sjack,
- int is_hp, char *prefix)
+ int is_hp, char *prefix,
+ char *pin)
 {
struct device *dev = card->dev;
enum of_gpio_flags flags;
@@ -557,12 +558,12 @@ int asoc_simple_init_jack(struct snd_soc_card *card,
 
if (is_hp) {
snprintf(prop, sizeof(prop), "%shp-det-gpio", prefix);
-   pin_name= "Headphones";
+   pin_name= pin ? pin : "Headphones";
gpio_name   = "Headphone detection";
mask= SND_JACK_HEADPHONE;
} else {
snprintf(prop, sizeof(prop), "%smic-det-gpio", prefix);
-   pin_name= "Mic Jack";
+   pin_name= pin ? pin : "Mic Jack";
gpio_name   = "Mic detection";
mask= SND_JACK_MICROPHONE;
}
-- 
2.27.0



[PATCH 0/3] ASoC: fsl-asoc-card: Support hp and mic detection

2020-07-14 Thread Shengjiu Wang
Support hp and mic detection.
Add a parameter for asoc_simple_init_jack.

Shengjiu Wang (3):
  ASoC: simple-card-utils: Support configure pin_name for
asoc_simple_init_jack
  ASoC: bindings: fsl-asoc-card: Support hp-det-gpio and mic-det-gpio
  ASoC: fsl-asoc-card: Support Headphone and Microphone Jack detection

 .../bindings/sound/fsl-asoc-card.txt  |  3 +
 include/sound/simple_card_utils.h |  6 +-
 sound/soc/fsl/Kconfig |  1 +
 sound/soc/fsl/fsl-asoc-card.c | 69 ++-
 sound/soc/generic/simple-card-utils.c |  7 +-
 5 files changed, 78 insertions(+), 8 deletions(-)

-- 
2.27.0



[PATCH 2/2] ASoC: fsl_spdif: Add kctl for configuring TX validity bit

2020-07-07 Thread Shengjiu Wang
Add one kctl for configuring TX validity bit from user
space.

The type of this kctl is boolean:
on - Outgoing validity always set
off - Outgoing validity always clear

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_spdif.c | 47 +++
 1 file changed, 43 insertions(+), 4 deletions(-)

diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 576370dc6e70..37053e8f29d0 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -776,8 +776,8 @@ static int fsl_spdif_vbit_info(struct snd_kcontrol 
*kcontrol,
 }
 
 /* Get valid good bit from interrupt status register */
-static int fsl_spdif_vbit_get(struct snd_kcontrol *kcontrol,
-   struct snd_ctl_elem_value *ucontrol)
+static int fsl_spdif_rx_vbit_get(struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
 {
struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
@@ -791,6 +791,35 @@ static int fsl_spdif_vbit_get(struct snd_kcontrol 
*kcontrol,
return 0;
 }
 
+static int fsl_spdif_tx_vbit_get(struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+   struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+   struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
+   struct regmap *regmap = spdif_priv->regmap;
+   u32 val;
+
+   regmap_read(regmap, REG_SPDIF_SCR, );
+   val = (val & SCR_VAL_MASK) >> SCR_VAL_OFFSET;
+   val = 1 - val;
+   ucontrol->value.integer.value[0] = val;
+
+   return 0;
+}
+
+static int fsl_spdif_tx_vbit_put(struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+   struct snd_soc_dai *cpu_dai = snd_kcontrol_chip(kcontrol);
+   struct fsl_spdif_priv *spdif_priv = snd_soc_dai_get_drvdata(cpu_dai);
+   struct regmap *regmap = spdif_priv->regmap;
+   u32 val = (1 - ucontrol->value.integer.value[0]) << SCR_VAL_OFFSET;
+
+   regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_VAL_MASK, val);
+
+   return 0;
+}
+
 /* DPLL lock information */
 static int fsl_spdif_rxrate_info(struct snd_kcontrol *kcontrol,
struct snd_ctl_elem_info *uinfo)
@@ -948,11 +977,21 @@ static struct snd_kcontrol_new fsl_spdif_ctrls[] = {
/* Valid bit error controller */
{
.iface = SNDRV_CTL_ELEM_IFACE_PCM,
-   .name = "IEC958 V-Bit Errors",
+   .name = "IEC958 RX V-Bit Errors",
.access = SNDRV_CTL_ELEM_ACCESS_READ |
SNDRV_CTL_ELEM_ACCESS_VOLATILE,
.info = fsl_spdif_vbit_info,
-   .get = fsl_spdif_vbit_get,
+   .get = fsl_spdif_rx_vbit_get,
+   },
+   {
+   .iface = SNDRV_CTL_ELEM_IFACE_PCM,
+   .name = "IEC958 TX V-Bit",
+   .access = SNDRV_CTL_ELEM_ACCESS_READ |
+   SNDRV_CTL_ELEM_ACCESS_WRITE |
+   SNDRV_CTL_ELEM_ACCESS_VOLATILE,
+   .info = fsl_spdif_vbit_info,
+   .get = fsl_spdif_tx_vbit_get,
+   .put = fsl_spdif_tx_vbit_put,
},
/* DPLL lock info get controller */
{
-- 
2.21.0



[PATCH 0/2] ASoC: fsl_spdif: Clear the validity bit for TX

2020-07-07 Thread Shengjiu Wang
Clear the validity bit for TX
Add kctl for configuring TX validity bit

Shengjiu Wang (2):
  ASoC: fsl_spdif: Clear the validity bit for TX
  ASoC: fsl_spdif: Add kctl for configuring TX validity bit

 sound/soc/fsl/fsl_spdif.c | 51 ---
 1 file changed, 47 insertions(+), 4 deletions(-)

-- 
2.21.0



[PATCH 1/2] ASoC: fsl_spdif: Clear the validity bit for TX

2020-07-07 Thread Shengjiu Wang
In IEC958 spec, "The validity bit is logical "0" if the
information in the main data field is reliable, and it
is logical "1" if it is not".

The default value of "ValCtrl" is zero, which means
"Outgoing Validity always set", then all the data is not
reliable, then some spdif sink device will drop the data.

So set "ValCtrl" to 1, that is to clear "Outgoing Validity"
in default.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_spdif.c | 4 
 1 file changed, 4 insertions(+)

diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 9fb95c6ee7ba..576370dc6e70 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -985,6 +985,10 @@ static int fsl_spdif_dai_probe(struct snd_soc_dai *dai)
 
snd_soc_add_dai_controls(dai, fsl_spdif_ctrls, 
ARRAY_SIZE(fsl_spdif_ctrls));
 
+   /*Clear the val bit for Tx*/
+   regmap_update_bits(spdif_private->regmap, REG_SPDIF_SCR,
+  SCR_VAL_MASK, SCR_VAL_CLEAR);
+
return 0;
 }
 
-- 
2.21.0



Re: [PATCH] MAINTAINERS: Add Shengjiu to reviewer list of sound/soc/fsl

2020-07-06 Thread Shengjiu Wang
On Fri, Jul 3, 2020 at 3:33 AM Nicolin Chen  wrote:
>
> Add Shengjiu who's actively working on the latest fsl/nxp audio drivers.
>
> Signed-off-by: Nicolin Chen 
> Cc: Shengjiu Wang 
> ---
> To Shengjiu, please ack if you feel okay with this (your email address too).

Thanks Nicolin for nominating me as a reviewer.

I'd like to use my gmail address "shengjiu.w...@gmail.com".
with this then

Acked-by: Shengjiu Wang 

best regards
wang shengjiu

>
>  MAINTAINERS | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/MAINTAINERS b/MAINTAINERS
> index 496fd4eafb68..54aab083bb88 100644
> --- a/MAINTAINERS
> +++ b/MAINTAINERS
> @@ -6956,6 +6956,7 @@ M:Timur Tabi 
>  M: Nicolin Chen 
>  M: Xiubo Li 
>  R: Fabio Estevam 
> +R: Shengjiu Wang 
>  L: alsa-de...@alsa-project.org (moderated for non-subscribers)
>  L: linuxppc-dev@lists.ozlabs.org
>  S: Maintained
> --
> 2.17.1
>


[PATCH v3] ASoC: fsl_asrc: Add an option to select internal ratio mode

2020-06-30 Thread Shengjiu Wang
The ASRC not only supports ideal ratio mode, but also supports
internal ratio mode.

For internal rato mode, the rate of clock source should be divided
with no remainder by sample rate, otherwise there is sound
distortion.

Add function fsl_asrc_select_clk() to find proper clock source for
internal ratio mode, if the clock source is available then internal
ratio mode will be selected.

With change, the ideal ratio mode is not the only option for user.

Signed-off-by: Shengjiu Wang 
---
changes in v3
- convert fsl_asrc_select_clk to void type

changes in v2
- update according to Nicolin's comments

 sound/soc/fsl/fsl_asrc.c | 46 ++--
 1 file changed, 44 insertions(+), 2 deletions(-)

diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 95f6a9617b0b..462ce9f9ab48 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -582,11 +582,51 @@ static int fsl_asrc_dai_startup(struct snd_pcm_substream 
*substream,
SNDRV_PCM_HW_PARAM_RATE, _asrc_rate_constraints);
 }
 
+/* Select proper clock source for internal ratio mode */
+static void fsl_asrc_select_clk(struct fsl_asrc_priv *asrc_priv,
+   struct fsl_asrc_pair *pair,
+   int in_rate,
+   int out_rate)
+{
+   struct fsl_asrc_pair_priv *pair_priv = pair->private;
+   struct asrc_config *config = pair_priv->config;
+   int rate[2], select_clk[2]; /* Array size 2 means IN and OUT */
+   int clk_rate, clk_index;
+   int i = 0, j = 0;
+
+   rate[IN] = in_rate;
+   rate[OUT] = out_rate;
+
+   /* Select proper clock source for internal ratio mode */
+   for (j = 0; j < 2; j++) {
+   for (i = 0; i < ASRC_CLK_MAP_LEN; i++) {
+   clk_index = asrc_priv->clk_map[j][i];
+   clk_rate = 
clk_get_rate(asrc_priv->asrck_clk[clk_index]);
+   /* Only match a perfect clock source with no remainder 
*/
+   if (clk_rate != 0 && (clk_rate / rate[j]) <= 1024 &&
+   (clk_rate % rate[j]) == 0)
+   break;
+   }
+
+   select_clk[j] = i;
+   }
+
+   /* Switch to ideal ratio mode if there is no proper clock source */
+   if (select_clk[IN] == ASRC_CLK_MAP_LEN || select_clk[OUT] == 
ASRC_CLK_MAP_LEN) {
+   select_clk[IN] = INCLK_NONE;
+   select_clk[OUT] = OUTCLK_ASRCK1_CLK;
+   }
+
+   config->inclk = select_clk[IN];
+   config->outclk = select_clk[OUT];
+}
+
 static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
  struct snd_pcm_hw_params *params,
  struct snd_soc_dai *dai)
 {
struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
+   struct fsl_asrc_priv *asrc_priv = asrc->private;
struct snd_pcm_runtime *runtime = substream->runtime;
struct fsl_asrc_pair *pair = runtime->private_data;
struct fsl_asrc_pair_priv *pair_priv = pair->private;
@@ -605,8 +645,6 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream 
*substream,
 
config.pair = pair->index;
config.channel_num = channels;
-   config.inclk = INCLK_NONE;
-   config.outclk = OUTCLK_ASRCK1_CLK;
 
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
config.input_format   = params_format(params);
@@ -620,6 +658,10 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream 
*substream,
config.output_sample_rate = rate;
}
 
+   fsl_asrc_select_clk(asrc_priv, pair,
+   config.input_sample_rate,
+   config.output_sample_rate);
+
ret = fsl_asrc_config_pair(pair, false);
if (ret) {
dev_err(dai->dev, "fail to config asrc pair\n");
-- 
2.21.0



Re: [PATCH] ASoC: fsl_asrc: Add an option to select internal ratio mode

2020-06-30 Thread Shengjiu Wang
On Tue, Jun 30, 2020 at 8:38 PM Fabio Estevam  wrote:
>
> Hi Shengjiu,
>
> On Mon, Jun 29, 2020 at 11:10 AM Shengjiu Wang  wrote:
>
> > +/**
>
> "/**" notation may confuse 'make htmldocs". Since this is a single
> line comment you could do:
>
> /* Select proper clock source for internal ratio mode */
>
>
> > + * Select proper clock source for internal ratio mode
> > + */
> > +static int fsl_asrc_select_clk(struct fsl_asrc_priv *asrc_priv,
> > +  struct fsl_asrc_pair *pair,
> > +  int in_rate,
> > +  int out_rate)
> > +{
> > +   struct fsl_asrc_pair_priv *pair_priv = pair->private;
> > +   struct asrc_config *config = pair_priv->config;
> > +   int rate[2], select_clk[2]; /* Array size 2 means IN and OUT */
> > +   int clk_rate, clk_index;
> > +   int i = 0, j = 0;
> > +   bool clk_sel[2];
> > +
> > +   rate[0] = in_rate;
> > +   rate[1] = out_rate;
> > +
> > +   /* Select proper clock source for internal ratio mode */
> > +   for (j = 0; j < 2; j++) {
> > +   for (i = 0; i < ASRC_CLK_MAP_LEN; i++) {
> > +   clk_index = asrc_priv->clk_map[j][i];
> > +   clk_rate = 
> > clk_get_rate(asrc_priv->asrck_clk[clk_index]);
> > +   if (clk_rate != 0 && (clk_rate / rate[j]) <= 1024 &&
> > +   (clk_rate % rate[j]) == 0)
> > +   break;
> > +   }
> > +
> > +   if (i == ASRC_CLK_MAP_LEN) {
> > +   select_clk[j] = OUTCLK_ASRCK1_CLK;
> > +   clk_sel[j] = false;
> > +   } else {
> > +   select_clk[j] = i;
> > +   clk_sel[j] = true;
> > +   }
> > +   }
> > +
> > +   /* Switch to ideal ratio mode if there is no proper clock source */
> > +   if (!clk_sel[IN] || !clk_sel[OUT])
> > +   select_clk[IN] = INCLK_NONE;
> > +
> > +   config->inclk = select_clk[IN];
> > +   config->outclk = select_clk[OUT];
> > +
> > +   return 0;
>
> This new function always returns 0. Should it be converted to 'void'
> type instead?
>
> > +   ret = fsl_asrc_select_clk(asrc_priv, pair,
> > + config.input_sample_rate,
> > + config.output_sample_rate);
> > +   if (ret) {
> > +   dev_err(dai->dev, "fail to select clock\n");
>
> fsl_asrc_select_clk() does not return error, so you could skip the
> error checking.

ok, will update the patch

best regards
wang shengjiu


[PATCH v2] ASoC: fsl_asrc: Add an option to select internal ratio mode

2020-06-30 Thread Shengjiu Wang
The ASRC not only supports ideal ratio mode, but also supports
internal ratio mode.

For internal rato mode, the rate of clock source should be divided
with no remainder by sample rate, otherwise there is sound
distortion.

Add function fsl_asrc_select_clk() to find proper clock source for
internal ratio mode, if the clock source is available then internal
ratio mode will be selected.

With change, the ideal ratio mode is not the only option for user.

Signed-off-by: Shengjiu Wang 
---
changes in v2
- update according to Nicolin's comments

 sound/soc/fsl/fsl_asrc.c | 54 ++--
 1 file changed, 52 insertions(+), 2 deletions(-)

diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 95f6a9617b0b..4105ef2c4f99 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -582,11 +582,55 @@ static int fsl_asrc_dai_startup(struct snd_pcm_substream 
*substream,
SNDRV_PCM_HW_PARAM_RATE, _asrc_rate_constraints);
 }
 
+/**
+ * Select proper clock source for internal ratio mode
+ */
+static int fsl_asrc_select_clk(struct fsl_asrc_priv *asrc_priv,
+  struct fsl_asrc_pair *pair,
+  int in_rate,
+  int out_rate)
+{
+   struct fsl_asrc_pair_priv *pair_priv = pair->private;
+   struct asrc_config *config = pair_priv->config;
+   int rate[2], select_clk[2]; /* Array size 2 means IN and OUT */
+   int clk_rate, clk_index;
+   int i = 0, j = 0;
+
+   rate[0] = in_rate;
+   rate[1] = out_rate;
+
+   /* Select proper clock source for internal ratio mode */
+   for (j = 0; j < 2; j++) {
+   for (i = 0; i < ASRC_CLK_MAP_LEN; i++) {
+   clk_index = asrc_priv->clk_map[j][i];
+   clk_rate = 
clk_get_rate(asrc_priv->asrck_clk[clk_index]);
+   /* Only match a perfect clock source with no remainder 
*/
+   if (clk_rate != 0 && (clk_rate / rate[j]) <= 1024 &&
+   (clk_rate % rate[j]) == 0)
+   break;
+   }
+
+   select_clk[j] = i;
+   }
+
+   /* Switch to ideal ratio mode if there is no proper clock source */
+   if (select_clk[IN] == ASRC_CLK_MAP_LEN || select_clk[OUT] == 
ASRC_CLK_MAP_LEN) {
+   select_clk[IN] = INCLK_NONE;
+   select_clk[OUT] = OUTCLK_ASRCK1_CLK;
+   }
+
+   config->inclk = select_clk[IN];
+   config->outclk = select_clk[OUT];
+
+   return 0;
+}
+
 static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
  struct snd_pcm_hw_params *params,
  struct snd_soc_dai *dai)
 {
struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
+   struct fsl_asrc_priv *asrc_priv = asrc->private;
struct snd_pcm_runtime *runtime = substream->runtime;
struct fsl_asrc_pair *pair = runtime->private_data;
struct fsl_asrc_pair_priv *pair_priv = pair->private;
@@ -605,8 +649,6 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream 
*substream,
 
config.pair = pair->index;
config.channel_num = channels;
-   config.inclk = INCLK_NONE;
-   config.outclk = OUTCLK_ASRCK1_CLK;
 
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
config.input_format   = params_format(params);
@@ -620,6 +662,14 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream 
*substream,
config.output_sample_rate = rate;
}
 
+   ret = fsl_asrc_select_clk(asrc_priv, pair,
+ config.input_sample_rate,
+ config.output_sample_rate);
+   if (ret) {
+   dev_err(dai->dev, "fail to select clock\n");
+   return ret;
+   }
+
ret = fsl_asrc_config_pair(pair, false);
if (ret) {
dev_err(dai->dev, "fail to config asrc pair\n");
-- 
2.21.0



Re: [PATCH] ASoC: fsl_asrc: Add an option to select internal ratio mode

2020-06-29 Thread Shengjiu Wang
On Tue, Jun 30, 2020 at 4:09 AM Nicolin Chen  wrote:
>
> On Mon, Jun 29, 2020 at 09:58:35PM +0800, Shengjiu Wang wrote:
> > The ASRC not only supports ideal ratio mode, but also supports
> > internal ratio mode.
> >
> > For internal rato mode, the rate of clock source should be divided
> > with no remainder by sample rate, otherwise there is sound
> > distortion.
> >
> > Add function fsl_asrc_select_clk() to find proper clock source for
> > internal ratio mode, if the clock source is available then internal
> > ratio mode will be selected.
> >
> > With change, the ideal ratio mode is not the only option for user.
> >
> > Signed-off-by: Shengjiu Wang 
> > ---
>
> > +static int fsl_asrc_select_clk(struct fsl_asrc_priv *asrc_priv,
> > +struct fsl_asrc_pair *pair,
> > +int in_rate,
> > +int out_rate)
> > +{
> > + struct fsl_asrc_pair_priv *pair_priv = pair->private;
> > + struct asrc_config *config = pair_priv->config;
> > + int rate[2], select_clk[2]; /* Array size 2 means IN and OUT */
> > + int clk_rate, clk_index;
> > + int i = 0, j = 0;
> > + bool clk_sel[2];
> > +
> > + rate[0] = in_rate;
> > + rate[1] = out_rate;
> > +
> > + /* Select proper clock source for internal ratio mode */
> > + for (j = 0; j < 2; j++) {
> > + for (i = 0; i < ASRC_CLK_MAP_LEN; i++) {
> > + clk_index = asrc_priv->clk_map[j][i];
> > + clk_rate = 
> > clk_get_rate(asrc_priv->asrck_clk[clk_index]);
>
> +   /* Only match a perfect clock source with no 
> remainder */
>
> > + if (clk_rate != 0 && (clk_rate / rate[j]) <= 1024 &&
> > + (clk_rate % rate[j]) == 0)
> > + break;
> > + }
> > +
> > + if (i == ASRC_CLK_MAP_LEN) {
> > + select_clk[j] = OUTCLK_ASRCK1_CLK;
> > + clk_sel[j] = false;
> > + } else {
> > + select_clk[j] = i;
> > + clk_sel[j] = true;
> > + }
> > + }
> > +
> > + /* Switch to ideal ratio mode if there is no proper clock source */
> > + if (!clk_sel[IN] || !clk_sel[OUT])
> > + select_clk[IN] = INCLK_NONE;
>
> Could get rid of clk_set:
>
> for (j) {
> for (i) {
> if (match)
> break;
> }
>
> clk[j] = i;
> }
>
> if (clk[IN] == ASRC_CLK_MAP_LEN || clk[OUT] == ASRC_CLK_MAP_LEN)
>
> And it only overrides clk[IN] setting but leaving clk[OUT] to
> to the searching result. This means that clk[OUT] may be using
> a clock source other than OUTCLK_ASRCK1_CLK if sel[IN] happens
> to be false while sel[OUT] happens to be true. Not sure if it
> is intended...but I feel it would probably be safer to use the
> previous settings: INCLK_NONE + OUTCLK_ASRCK1_CLK?

ok, will update the patch.

best regards
wang shengjiu


[PATCH] ASoC: fsl_asrc: Add an option to select internal ratio mode

2020-06-29 Thread Shengjiu Wang
The ASRC not only supports ideal ratio mode, but also supports
internal ratio mode.

For internal rato mode, the rate of clock source should be divided
with no remainder by sample rate, otherwise there is sound
distortion.

Add function fsl_asrc_select_clk() to find proper clock source for
internal ratio mode, if the clock source is available then internal
ratio mode will be selected.

With change, the ideal ratio mode is not the only option for user.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_asrc.c | 58 ++--
 1 file changed, 56 insertions(+), 2 deletions(-)

diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 95f6a9617b0b..fcafc8ecb131 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -582,11 +582,59 @@ static int fsl_asrc_dai_startup(struct snd_pcm_substream 
*substream,
SNDRV_PCM_HW_PARAM_RATE, _asrc_rate_constraints);
 }
 
+/**
+ * Select proper clock source for internal ratio mode
+ */
+static int fsl_asrc_select_clk(struct fsl_asrc_priv *asrc_priv,
+  struct fsl_asrc_pair *pair,
+  int in_rate,
+  int out_rate)
+{
+   struct fsl_asrc_pair_priv *pair_priv = pair->private;
+   struct asrc_config *config = pair_priv->config;
+   int rate[2], select_clk[2]; /* Array size 2 means IN and OUT */
+   int clk_rate, clk_index;
+   int i = 0, j = 0;
+   bool clk_sel[2];
+
+   rate[0] = in_rate;
+   rate[1] = out_rate;
+
+   /* Select proper clock source for internal ratio mode */
+   for (j = 0; j < 2; j++) {
+   for (i = 0; i < ASRC_CLK_MAP_LEN; i++) {
+   clk_index = asrc_priv->clk_map[j][i];
+   clk_rate = 
clk_get_rate(asrc_priv->asrck_clk[clk_index]);
+   if (clk_rate != 0 && (clk_rate / rate[j]) <= 1024 &&
+   (clk_rate % rate[j]) == 0)
+   break;
+   }
+
+   if (i == ASRC_CLK_MAP_LEN) {
+   select_clk[j] = OUTCLK_ASRCK1_CLK;
+   clk_sel[j] = false;
+   } else {
+   select_clk[j] = i;
+   clk_sel[j] = true;
+   }
+   }
+
+   /* Switch to ideal ratio mode if there is no proper clock source */
+   if (!clk_sel[IN] || !clk_sel[OUT])
+   select_clk[IN] = INCLK_NONE;
+
+   config->inclk = select_clk[IN];
+   config->outclk = select_clk[OUT];
+
+   return 0;
+}
+
 static int fsl_asrc_dai_hw_params(struct snd_pcm_substream *substream,
  struct snd_pcm_hw_params *params,
  struct snd_soc_dai *dai)
 {
struct fsl_asrc *asrc = snd_soc_dai_get_drvdata(dai);
+   struct fsl_asrc_priv *asrc_priv = asrc->private;
struct snd_pcm_runtime *runtime = substream->runtime;
struct fsl_asrc_pair *pair = runtime->private_data;
struct fsl_asrc_pair_priv *pair_priv = pair->private;
@@ -605,8 +653,6 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream 
*substream,
 
config.pair = pair->index;
config.channel_num = channels;
-   config.inclk = INCLK_NONE;
-   config.outclk = OUTCLK_ASRCK1_CLK;
 
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
config.input_format   = params_format(params);
@@ -620,6 +666,14 @@ static int fsl_asrc_dai_hw_params(struct snd_pcm_substream 
*substream,
config.output_sample_rate = rate;
}
 
+   ret = fsl_asrc_select_clk(asrc_priv, pair,
+ config.input_sample_rate,
+ config.output_sample_rate);
+   if (ret) {
+   dev_err(dai->dev, "fail to select clock\n");
+   return ret;
+   }
+
ret = fsl_asrc_config_pair(pair, false);
if (ret) {
dev_err(dai->dev, "fail to config asrc pair\n");
-- 
2.21.0



[PATCH] ASoC: fsl_sai: Refine regcache usage with pm runtime

2020-06-29 Thread Shengjiu Wang
When there is dedicated power domain bound with device, after probing
the power will be disabled, then registers are not accessible in
fsl_sai_dai_probe(), so regcache only need to be enabled in end of
probe() and regcache_mark_dirty should be moved to pm runtime resume
callback function.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_sai.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c
index 9d436b0c5718..a22562f2df47 100644
--- a/sound/soc/fsl/fsl_sai.c
+++ b/sound/soc/fsl/fsl_sai.c
@@ -1016,6 +1016,7 @@ static int fsl_sai_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, sai);
 
pm_runtime_enable(>dev);
+   regcache_cache_only(sai->regmap, true);
 
ret = devm_snd_soc_register_component(>dev, _component,
_sai_dai, 1);
@@ -1107,7 +1108,6 @@ static int fsl_sai_runtime_suspend(struct device *dev)
clk_disable_unprepare(sai->bus_clk);
 
regcache_cache_only(sai->regmap, true);
-   regcache_mark_dirty(sai->regmap);
 
return 0;
 }
@@ -1137,6 +1137,7 @@ static int fsl_sai_runtime_resume(struct device *dev)
}
 
regcache_cache_only(sai->regmap, false);
+   regcache_mark_dirty(sai->regmap);
regmap_write(sai->regmap, FSL_SAI_TCSR(ofs), FSL_SAI_CSR_SR);
regmap_write(sai->regmap, FSL_SAI_RCSR(ofs), FSL_SAI_CSR_SR);
usleep_range(1000, 2000);
-- 
2.21.0



Re: [PATCH v2 1/2] ASoC: fsl_mqs: Don't check clock is NULL before calling clk API

2020-06-23 Thread Shengjiu Wang
On Tue, Jun 23, 2020 at 4:55 PM Markus Elfring  wrote:
>
> > clk_prepare_enable and clk_disable_unprepare check the input
> > clock parameter in the beginning of the function,
>
> These functions call further functions which perform null pointer checks.
>
>
> >   if the parameter
> > is NULL, clk_prepare_enable and clk_disable_unprepare will
> > return immediately.
>
> The interpretation of these function implementations seems to be reasonable.
> Would you like to achieve any improvements for the corresponding software 
> documentation?

Which document do you mean?

>
>
> > So Don't need to check input clock parameters before calling clk API.
>
> What do you find imperative in this wording?
>
> Another wording alternative:
>Thus omit extra null pointer checks before four function calls.
>
> Regards,
> Markus


Re: [PATCH v2 1/2] ASoC: fsl_mqs: Don't check clock is NULL before calling clk API

2020-06-23 Thread Shengjiu Wang
On Tue, Jun 23, 2020 at 3:38 PM Markus Elfring  wrote:
>
> > In-Reply-To: 
>
> I guess that it should be sufficient to specify such a field once
> for the header information.

seems it's caused by my "git format-patch" command, I will update
it, hope it is better next time.

>
>
> > Because clk_prepare_enable and clk_disable_unprepare should
> > check input clock parameter is NULL or not internally,
>
> I find this change description unclear.

clk_prepare_enable and clk_disable_unprepare check the input
clock parameter in the beginning of the function, if the parameter
is NULL, clk_prepare_enable and clk_disable_unprepare will
return immediately.

So Don't need to check input clock parameters before calling clk
API.

Do you think this commit message is better?

best regards
wang shengjiu


[PATCH 1/2] ASoC: fsl-asoc-card: Add WM8524 support

2020-06-23 Thread Shengjiu Wang
WM8524 only supports playback mode, and only works at
slave mode.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl-asoc-card.c | 10 ++
 1 file changed, 10 insertions(+)

diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index d0543a53764e..57ea1b072326 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -611,6 +611,15 @@ static int fsl_asoc_card_probe(struct platform_device 
*pdev)
priv->dai_link[2].dpcm_capture = 0;
priv->card.dapm_routes = audio_map_tx;
priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx);
+   } else if (of_device_is_compatible(np, "fsl,imx-audio-wm8524")) {
+   codec_dai_name = "wm8524-hifi";
+   priv->card.set_bias_level = NULL;
+   priv->dai_fmt |= SND_SOC_DAIFMT_CBS_CFS;
+   priv->dai_link[1].dpcm_capture = 0;
+   priv->dai_link[2].dpcm_capture = 0;
+   priv->cpu_priv.slot_width = 32;
+   priv->card.dapm_routes = audio_map_tx;
+   priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx);
} else {
dev_err(>dev, "unknown Device Tree compatible\n");
ret = -EINVAL;
@@ -760,6 +769,7 @@ static const struct of_device_id fsl_asoc_card_dt_ids[] = {
{ .compatible = "fsl,imx-audio-wm8962", },
{ .compatible = "fsl,imx-audio-wm8960", },
{ .compatible = "fsl,imx-audio-mqs", },
+   { .compatible = "fsl,imx-audio-wm8524", },
{}
 };
 MODULE_DEVICE_TABLE(of, fsl_asoc_card_dt_ids);
-- 
2.21.0



[PATCH 2/2] ASoC: bindings: fsl-asoc-card: Add compatible string for wm8524

2020-06-23 Thread Shengjiu Wang
In order to support wm8524 codec with fsl-asoc-card machine
driver, add compatible string "fsl,imx-audio-wm8524".

Signed-off-by: Shengjiu Wang 
---
 Documentation/devicetree/bindings/sound/fsl-asoc-card.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt 
b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
index ca9a3a43adfd..133d7e14a4d0 100644
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
@@ -36,6 +36,8 @@ The compatible list for this generic sound card currently:
 
  "fsl,imx-audio-mqs"
 
+ "fsl,imx-audio-wm8524"
+
 Required properties:
 
   - compatible : Contains one of entries in the compatible list.
-- 
2.21.0



[PATCH v2 2/2] ASoC: fsl_mqs: Fix unchecked return value for clk_prepare_enable

2020-06-23 Thread Shengjiu Wang
Fix unchecked return value for clk_prepare_enable, add error
handler in fsl_mqs_runtime_resume.

Fixes: 9e28f6532c61 ("ASoC: fsl_mqs: Add MQS component driver")
Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_mqs.c | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/sound/soc/fsl/fsl_mqs.c b/sound/soc/fsl/fsl_mqs.c
index b44b134390a3..69aeb0e71844 100644
--- a/sound/soc/fsl/fsl_mqs.c
+++ b/sound/soc/fsl/fsl_mqs.c
@@ -265,10 +265,20 @@ static int fsl_mqs_remove(struct platform_device *pdev)
 static int fsl_mqs_runtime_resume(struct device *dev)
 {
struct fsl_mqs *mqs_priv = dev_get_drvdata(dev);
+   int ret;
 
-   clk_prepare_enable(mqs_priv->ipg);
+   ret = clk_prepare_enable(mqs_priv->ipg);
+   if (ret) {
+   dev_err(dev, "failed to enable ipg clock\n");
+   return ret;
+   }
 
-   clk_prepare_enable(mqs_priv->mclk);
+   ret = clk_prepare_enable(mqs_priv->mclk);
+   if (ret) {
+   dev_err(dev, "failed to enable mclk clock\n");
+   clk_disable_unprepare(mqs_priv->ipg);
+   return ret;
+   }
 
if (mqs_priv->use_gpr)
regmap_write(mqs_priv->regmap, IOMUXC_GPR2,
-- 
2.21.0



[PATCH v2 1/2] ASoC: fsl_mqs: Don't check clock is NULL before calling clk API

2020-06-23 Thread Shengjiu Wang
Because clk_prepare_enable and clk_disable_unprepare should
check input clock parameter is NULL or not internally, then
we don't need to check them before calling the function.

Fixes: 9e28f6532c61 ("ASoC: fsl_mqs: Add MQS component driver")
Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_mqs.c | 13 -
 1 file changed, 4 insertions(+), 9 deletions(-)

diff --git a/sound/soc/fsl/fsl_mqs.c b/sound/soc/fsl/fsl_mqs.c
index 0c813a45bba7..b44b134390a3 100644
--- a/sound/soc/fsl/fsl_mqs.c
+++ b/sound/soc/fsl/fsl_mqs.c
@@ -266,11 +266,9 @@ static int fsl_mqs_runtime_resume(struct device *dev)
 {
struct fsl_mqs *mqs_priv = dev_get_drvdata(dev);
 
-   if (mqs_priv->ipg)
-   clk_prepare_enable(mqs_priv->ipg);
+   clk_prepare_enable(mqs_priv->ipg);
 
-   if (mqs_priv->mclk)
-   clk_prepare_enable(mqs_priv->mclk);
+   clk_prepare_enable(mqs_priv->mclk);
 
if (mqs_priv->use_gpr)
regmap_write(mqs_priv->regmap, IOMUXC_GPR2,
@@ -292,11 +290,8 @@ static int fsl_mqs_runtime_suspend(struct device *dev)
regmap_read(mqs_priv->regmap, REG_MQS_CTRL,
_priv->reg_mqs_ctrl);
 
-   if (mqs_priv->mclk)
-   clk_disable_unprepare(mqs_priv->mclk);
-
-   if (mqs_priv->ipg)
-   clk_disable_unprepare(mqs_priv->ipg);
+   clk_disable_unprepare(mqs_priv->mclk);
+   clk_disable_unprepare(mqs_priv->ipg);
 
return 0;
 }
-- 
2.21.0



[PATCH v2 0/2] Fix unchecked return value for clk_prepare_enable

2020-06-23 Thread Shengjiu Wang
First patch is to remove the check of clock pointer before calling
clk API.

Second patch is to fix the issue that the return value of
clk_prepare_enable is not checked.

changes in v2:
- split the patch to separate patches

Shengjiu Wang (2):
  ASoC: fsl_mqs: Don't check clock is NULL before calling clk API
  ASoC: fsl_mqs: Fix unchecked return value for clk_prepare_enable

 sound/soc/fsl/fsl_mqs.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

-- 
2.21.0



Re: [PATCH] ASoC: fsl_mqs: Fix unchecked return value for clk_prepare_enable

2020-06-22 Thread Shengjiu Wang
On Tue, Jun 23, 2020 at 12:08 AM Markus Elfring  wrote:
>
> > Fix unchecked return value for clk_prepare_enable.
> >
> > And because clk_prepare_enable and clk_disable_unprepare should
> > check input clock parameter is NULL or not, then we don't need
> > to check it before calling the function.
>
> I propose to split the adjustment of two function implementations
> into separate update steps for a small patch series.
> https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/process/submitting-patches.rst?id=625d3449788f85569096780592549d0340e9c0c7#n138
>
> I suggest to improve the change descriptions accordingly.

ok, will update the patches in v2.

best regards
wang shengjiu


[PATCH] ASoC: fsl_easrc: Fix uninitialized scalar variable in fsl_easrc_set_ctx_format

2020-06-22 Thread Shengjiu Wang
The "ret" in fsl_easrc_set_ctx_format is not initialized, then
the unknown value maybe returned by this function.

Fixes: 955ac624058f ("ASoC: fsl_easrc: Add EASRC ASoC CPU DAI drivers")
Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_easrc.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index 2f6b3d8bfcfc..03b3aef41d34 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -1132,7 +1132,7 @@ static int fsl_easrc_set_ctx_format(struct fsl_asrc_pair 
*ctx,
struct fsl_easrc_ctx_priv *ctx_priv = ctx->private;
struct fsl_easrc_data_fmt *in_fmt = _priv->in_params.fmt;
struct fsl_easrc_data_fmt *out_fmt = _priv->out_params.fmt;
-   int ret;
+   int ret = 0;
 
/* Get the bitfield values for input data format */
if (in_raw_format && out_raw_format) {
-- 
2.21.0



[PATCH] ASoC: fsl_mqs: Fix unchecked return value for clk_prepare_enable

2020-06-22 Thread Shengjiu Wang
Fix unchecked return value for clk_prepare_enable.

And because clk_prepare_enable and clk_disable_unprepare should
check input clock parameter is NULL or not, then we don't need
to check it before calling the function.

Fixes: 9e28f6532c61 ("ASoC: fsl_mqs: Add MQS component driver")
Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_mqs.c | 23 ++-
 1 file changed, 14 insertions(+), 9 deletions(-)

diff --git a/sound/soc/fsl/fsl_mqs.c b/sound/soc/fsl/fsl_mqs.c
index 0c813a45bba7..69aeb0e71844 100644
--- a/sound/soc/fsl/fsl_mqs.c
+++ b/sound/soc/fsl/fsl_mqs.c
@@ -265,12 +265,20 @@ static int fsl_mqs_remove(struct platform_device *pdev)
 static int fsl_mqs_runtime_resume(struct device *dev)
 {
struct fsl_mqs *mqs_priv = dev_get_drvdata(dev);
+   int ret;
 
-   if (mqs_priv->ipg)
-   clk_prepare_enable(mqs_priv->ipg);
+   ret = clk_prepare_enable(mqs_priv->ipg);
+   if (ret) {
+   dev_err(dev, "failed to enable ipg clock\n");
+   return ret;
+   }
 
-   if (mqs_priv->mclk)
-   clk_prepare_enable(mqs_priv->mclk);
+   ret = clk_prepare_enable(mqs_priv->mclk);
+   if (ret) {
+   dev_err(dev, "failed to enable mclk clock\n");
+   clk_disable_unprepare(mqs_priv->ipg);
+   return ret;
+   }
 
if (mqs_priv->use_gpr)
regmap_write(mqs_priv->regmap, IOMUXC_GPR2,
@@ -292,11 +300,8 @@ static int fsl_mqs_runtime_suspend(struct device *dev)
regmap_read(mqs_priv->regmap, REG_MQS_CTRL,
_priv->reg_mqs_ctrl);
 
-   if (mqs_priv->mclk)
-   clk_disable_unprepare(mqs_priv->mclk);
-
-   if (mqs_priv->ipg)
-   clk_disable_unprepare(mqs_priv->ipg);
+   clk_disable_unprepare(mqs_priv->mclk);
+   clk_disable_unprepare(mqs_priv->ipg);
 
return 0;
 }
-- 
2.21.0



[PATCH v2] ASoC: fsl_spdif: Add pm runtime function

2020-06-19 Thread Shengjiu Wang
Add pm runtime support and move clock handling there.
Close the clocks at suspend to reduce the power consumption.

fsl_spdif_suspend is replaced by pm_runtime_force_suspend.
fsl_spdif_resume is replaced by pm_runtime_force_resume.

Signed-off-by: Shengjiu Wang 
Acked-by: Nicolin Chen 
---
changes in v2
- remove goto in startup()
- remove goto disable_spba_clk
- Add Acked-by: Nicolin Chen

 sound/soc/fsl/fsl_spdif.c | 117 ++
 1 file changed, 67 insertions(+), 50 deletions(-)

diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 5bc0e4729341..5b2689ae63d4 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -495,29 +496,14 @@ static int fsl_spdif_startup(struct snd_pcm_substream 
*substream,
struct platform_device *pdev = spdif_priv->pdev;
struct regmap *regmap = spdif_priv->regmap;
u32 scr, mask;
-   int i;
int ret;
 
/* Reset module and interrupts only for first initialization */
if (!snd_soc_dai_active(cpu_dai)) {
-   ret = clk_prepare_enable(spdif_priv->coreclk);
-   if (ret) {
-   dev_err(>dev, "failed to enable core clock\n");
-   return ret;
-   }
-
-   if (!IS_ERR(spdif_priv->spbaclk)) {
-   ret = clk_prepare_enable(spdif_priv->spbaclk);
-   if (ret) {
-   dev_err(>dev, "failed to enable spba 
clock\n");
-   goto err_spbaclk;
-   }
-   }
-
ret = spdif_softreset(spdif_priv);
if (ret) {
dev_err(>dev, "failed to soft reset\n");
-   goto err;
+   return ret;
}
 
/* Disable all the interrupts */
@@ -531,18 +517,10 @@ static int fsl_spdif_startup(struct snd_pcm_substream 
*substream,
mask = SCR_TXFIFO_AUTOSYNC_MASK | SCR_TXFIFO_CTRL_MASK |
SCR_TXSEL_MASK | SCR_USRC_SEL_MASK |
SCR_TXFIFO_FSEL_MASK;
-   for (i = 0; i < SPDIF_TXRATE_MAX; i++) {
-   ret = clk_prepare_enable(spdif_priv->txclk[i]);
-   if (ret)
-   goto disable_txclk;
-   }
} else {
scr = SCR_RXFIFO_FSEL_IF8 | SCR_RXFIFO_AUTOSYNC;
mask = SCR_RXFIFO_FSEL_MASK | SCR_RXFIFO_AUTOSYNC_MASK|
SCR_RXFIFO_CTL_MASK | SCR_RXFIFO_OFF_MASK;
-   ret = clk_prepare_enable(spdif_priv->rxclk);
-   if (ret)
-   goto err;
}
regmap_update_bits(regmap, REG_SPDIF_SCR, mask, scr);
 
@@ -550,17 +528,6 @@ static int fsl_spdif_startup(struct snd_pcm_substream 
*substream,
regmap_update_bits(regmap, REG_SPDIF_SCR, SCR_LOW_POWER, 0);
 
return 0;
-
-disable_txclk:
-   for (i--; i >= 0; i--)
-   clk_disable_unprepare(spdif_priv->txclk[i]);
-err:
-   if (!IS_ERR(spdif_priv->spbaclk))
-   clk_disable_unprepare(spdif_priv->spbaclk);
-err_spbaclk:
-   clk_disable_unprepare(spdif_priv->coreclk);
-
-   return ret;
 }
 
 static void fsl_spdif_shutdown(struct snd_pcm_substream *substream,
@@ -569,20 +536,17 @@ static void fsl_spdif_shutdown(struct snd_pcm_substream 
*substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct fsl_spdif_priv *spdif_priv = 
snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
struct regmap *regmap = spdif_priv->regmap;
-   u32 scr, mask, i;
+   u32 scr, mask;
 
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
scr = 0;
mask = SCR_TXFIFO_AUTOSYNC_MASK | SCR_TXFIFO_CTRL_MASK |
SCR_TXSEL_MASK | SCR_USRC_SEL_MASK |
SCR_TXFIFO_FSEL_MASK;
-   for (i = 0; i < SPDIF_TXRATE_MAX; i++)
-   clk_disable_unprepare(spdif_priv->txclk[i]);
} else {
scr = SCR_RXFIFO_OFF | SCR_RXFIFO_CTL_ZERO;
mask = SCR_RXFIFO_FSEL_MASK | SCR_RXFIFO_AUTOSYNC_MASK|
SCR_RXFIFO_CTL_MASK | SCR_RXFIFO_OFF_MASK;
-   clk_disable_unprepare(spdif_priv->rxclk);
}
regmap_update_bits(regmap, REG_SPDIF_SCR, mask, scr);
 
@@ -591,9 +555,6 @@ static void fsl_spdif_shutdown(struct snd_pcm_substream 
*substream,
spdif_intr_status_clear(spdif_priv);
regmap_update_bits(regmap, REG_SPDIF_SCR,
SCR_LOW_POWER, SCR_LOW_POWER);
-   if (!IS_ERR(spdif_priv->spbaclk))
-   cl

Re: [PATCH] ASoC: fsl_spdif: Add pm runtime function

2020-06-19 Thread Shengjiu Wang
On Fri, Jun 19, 2020 at 1:51 PM Nicolin Chen  wrote:
>
> On Thu, Jun 18, 2020 at 07:55:34PM +0800, Shengjiu Wang wrote:
> > Add pm runtime support and move clock handling there.
> > Close the clocks at suspend to reduce the power consumption.
> >
> > fsl_spdif_suspend is replaced by pm_runtime_force_suspend.
> > fsl_spdif_resume is replaced by pm_runtime_force_resume.
> >
> > Signed-off-by: Shengjiu Wang 
>
> LGTM, yet some nits, please add my ack after fixing:
>
> Acked-by: Nicolin Chen 
>
> > @@ -495,25 +496,10 @@ static int fsl_spdif_startup(struct snd_pcm_substream 
> > *substream,
>
> >
> > -disable_txclk:
> > - for (i--; i >= 0; i--)
> > - clk_disable_unprepare(spdif_priv->txclk[i]);
> >  err:
> > - if (!IS_ERR(spdif_priv->spbaclk))
> > - clk_disable_unprepare(spdif_priv->spbaclk);
> > -err_spbaclk:
> > - clk_disable_unprepare(spdif_priv->coreclk);
> > -
> >   return ret;
>
> Only "return ret;" remains now. We could clean the goto away.
>
> > -static int fsl_spdif_resume(struct device *dev)
> > +static int fsl_spdif_runtime_resume(struct device *dev)
>
> > +disable_rx_clk:
> > + clk_disable_unprepare(spdif_priv->rxclk);
> > +disable_tx_clk:
> > +disable_spba_clk:
>
> Why have two duplicated ones? Could probably drop the 2nd one.

seems can drop one, will send an update.

best regards
wang shengjiu


[PATCH] ASoC: fsl_spdif: Add pm runtime function

2020-06-18 Thread Shengjiu Wang
Add pm runtime support and move clock handling there.
Close the clocks at suspend to reduce the power consumption.

fsl_spdif_suspend is replaced by pm_runtime_force_suspend.
fsl_spdif_resume is replaced by pm_runtime_force_resume.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_spdif.c | 113 ++
 1 file changed, 67 insertions(+), 46 deletions(-)

diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 5bc0e4729341..46719fd2f1ec 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -16,6 +16,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -495,25 +496,10 @@ static int fsl_spdif_startup(struct snd_pcm_substream 
*substream,
struct platform_device *pdev = spdif_priv->pdev;
struct regmap *regmap = spdif_priv->regmap;
u32 scr, mask;
-   int i;
int ret;
 
/* Reset module and interrupts only for first initialization */
if (!snd_soc_dai_active(cpu_dai)) {
-   ret = clk_prepare_enable(spdif_priv->coreclk);
-   if (ret) {
-   dev_err(>dev, "failed to enable core clock\n");
-   return ret;
-   }
-
-   if (!IS_ERR(spdif_priv->spbaclk)) {
-   ret = clk_prepare_enable(spdif_priv->spbaclk);
-   if (ret) {
-   dev_err(>dev, "failed to enable spba 
clock\n");
-   goto err_spbaclk;
-   }
-   }
-
ret = spdif_softreset(spdif_priv);
if (ret) {
dev_err(>dev, "failed to soft reset\n");
@@ -531,18 +517,10 @@ static int fsl_spdif_startup(struct snd_pcm_substream 
*substream,
mask = SCR_TXFIFO_AUTOSYNC_MASK | SCR_TXFIFO_CTRL_MASK |
SCR_TXSEL_MASK | SCR_USRC_SEL_MASK |
SCR_TXFIFO_FSEL_MASK;
-   for (i = 0; i < SPDIF_TXRATE_MAX; i++) {
-   ret = clk_prepare_enable(spdif_priv->txclk[i]);
-   if (ret)
-   goto disable_txclk;
-   }
} else {
scr = SCR_RXFIFO_FSEL_IF8 | SCR_RXFIFO_AUTOSYNC;
mask = SCR_RXFIFO_FSEL_MASK | SCR_RXFIFO_AUTOSYNC_MASK|
SCR_RXFIFO_CTL_MASK | SCR_RXFIFO_OFF_MASK;
-   ret = clk_prepare_enable(spdif_priv->rxclk);
-   if (ret)
-   goto err;
}
regmap_update_bits(regmap, REG_SPDIF_SCR, mask, scr);
 
@@ -551,15 +529,7 @@ static int fsl_spdif_startup(struct snd_pcm_substream 
*substream,
 
return 0;
 
-disable_txclk:
-   for (i--; i >= 0; i--)
-   clk_disable_unprepare(spdif_priv->txclk[i]);
 err:
-   if (!IS_ERR(spdif_priv->spbaclk))
-   clk_disable_unprepare(spdif_priv->spbaclk);
-err_spbaclk:
-   clk_disable_unprepare(spdif_priv->coreclk);
-
return ret;
 }
 
@@ -569,20 +539,17 @@ static void fsl_spdif_shutdown(struct snd_pcm_substream 
*substream,
struct snd_soc_pcm_runtime *rtd = substream->private_data;
struct fsl_spdif_priv *spdif_priv = 
snd_soc_dai_get_drvdata(asoc_rtd_to_cpu(rtd, 0));
struct regmap *regmap = spdif_priv->regmap;
-   u32 scr, mask, i;
+   u32 scr, mask;
 
if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
scr = 0;
mask = SCR_TXFIFO_AUTOSYNC_MASK | SCR_TXFIFO_CTRL_MASK |
SCR_TXSEL_MASK | SCR_USRC_SEL_MASK |
SCR_TXFIFO_FSEL_MASK;
-   for (i = 0; i < SPDIF_TXRATE_MAX; i++)
-   clk_disable_unprepare(spdif_priv->txclk[i]);
} else {
scr = SCR_RXFIFO_OFF | SCR_RXFIFO_CTL_ZERO;
mask = SCR_RXFIFO_FSEL_MASK | SCR_RXFIFO_AUTOSYNC_MASK|
SCR_RXFIFO_CTL_MASK | SCR_RXFIFO_OFF_MASK;
-   clk_disable_unprepare(spdif_priv->rxclk);
}
regmap_update_bits(regmap, REG_SPDIF_SCR, mask, scr);
 
@@ -591,9 +558,6 @@ static void fsl_spdif_shutdown(struct snd_pcm_substream 
*substream,
spdif_intr_status_clear(spdif_priv);
regmap_update_bits(regmap, REG_SPDIF_SCR,
SCR_LOW_POWER, SCR_LOW_POWER);
-   if (!IS_ERR(spdif_priv->spbaclk))
-   clk_disable_unprepare(spdif_priv->spbaclk);
-   clk_disable_unprepare(spdif_priv->coreclk);
}
 }
 
@@ -1350,6 +1314,8 @@ static int fsl_spdif_probe(struct platform_device *pdev)
 
/* Register with ASoC */
dev_set_drvdata(>dev, spdif_priv);
+   pm_runtime_enable(>dev);
+   regcache_cache_only(spdif_priv->regmap, true);
 
ret = devm_snd_

[PATCH v3 2/2] ASoC: fsl_spdif: Add support for imx6sx platform

2020-06-17 Thread Shengjiu Wang
The one difference on imx6sx platform is that the root clock
is shared with ASRC module, so we add a new flags
"shared_root_clock" which means the root clock is not independent,
then we will not do the clk_set_rate and clk_round_rate to avoid
impact ASRC module usage.

As add a new flags, we include the soc specific data struct.

Signed-off-by: Shengjiu Wang 
Reviewed-by: Nicolin Chen 
---
changes in v3
- refine some comments
- add Reviewed-by: Nicolin Chen

changes in v2
- use shared_root_clk instead ind_root_clk.
- add fsl_spdif_can_set_clk_rate function.

 sound/soc/fsl/fsl_spdif.c | 50 +++
 1 file changed, 45 insertions(+), 5 deletions(-)

diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 1b2e516f9162..5bc0e4729341 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -42,6 +42,18 @@ static u8 srpc_dpll_locked[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 
0xa, 0xb };
 
 #define DEFAULT_RXCLK_SRC  1
 
+/**
+ * struct fsl_spdif_soc_data: soc specific data
+ *
+ * @imx: for imx platform
+ * @shared_root_clock: flag of sharing a clock source with others;
+ * so the driver shouldn't set root clock rate
+ */
+struct fsl_spdif_soc_data {
+   bool imx;
+   bool shared_root_clock;
+};
+
 /*
  * SPDIF control structure
  * Defines channel status, subcode and Q sub
@@ -89,6 +101,7 @@ struct spdif_mixer_control {
  * @dma_params_rx: DMA parameters for receive channel
  */
 struct fsl_spdif_priv {
+   const struct fsl_spdif_soc_data *soc;
struct spdif_mixer_control fsl_spdif_control;
struct snd_soc_dai_driver cpu_dai_drv;
struct platform_device *pdev;
@@ -110,6 +123,27 @@ struct fsl_spdif_priv {
u32 regcache_srpc;
 };
 
+static struct fsl_spdif_soc_data fsl_spdif_vf610 = {
+   .imx = false,
+   .shared_root_clock = false,
+};
+
+static struct fsl_spdif_soc_data fsl_spdif_imx35 = {
+   .imx = true,
+   .shared_root_clock = false,
+};
+
+static struct fsl_spdif_soc_data fsl_spdif_imx6sx = {
+   .imx = true,
+   .shared_root_clock = true,
+};
+
+/* Check if clk is a root clock that does not share clock source with others */
+static inline bool fsl_spdif_can_set_clk_rate(struct fsl_spdif_priv *spdif, 
int clk)
+{
+   return (clk == STC_TXCLK_SPDIF_ROOT) && !spdif->soc->shared_root_clock;
+}
+
 /* DPLL locked and lock loss interrupt handler */
 static void spdif_irq_dpll_lock(struct fsl_spdif_priv *spdif_priv)
 {
@@ -420,8 +454,7 @@ static int spdif_set_sample_rate(struct snd_pcm_substream 
*substream,
 
sysclk_df = spdif_priv->sysclk_df[rate];
 
-   /* Don't mess up the clocks from other modules */
-   if (clk != STC_TXCLK_SPDIF_ROOT)
+   if (!fsl_spdif_can_set_clk_rate(spdif_priv, clk))
goto clk_set_bypass;
 
/* The S/PDIF block needs a clock of 64 * fs * txclk_df */
@@ -1186,7 +1219,7 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv 
*spdif_priv,
continue;
 
ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index,
-i == STC_TXCLK_SPDIF_ROOT);
+
fsl_spdif_can_set_clk_rate(spdif_priv, i));
if (savesub == ret)
continue;
 
@@ -1230,6 +1263,12 @@ static int fsl_spdif_probe(struct platform_device *pdev)
 
spdif_priv->pdev = pdev;
 
+   spdif_priv->soc = of_device_get_match_data(>dev);
+   if (!spdif_priv->soc) {
+   dev_err(>dev, "failed to get soc data\n");
+   return -ENODEV;
+   }
+
/* Initialize this copy of the CPU DAI driver structure */
memcpy(_priv->cpu_dai_drv, _spdif_dai, sizeof(fsl_spdif_dai));
spdif_priv->cpu_dai_drv.name = dev_name(>dev);
@@ -1359,8 +1398,9 @@ static const struct dev_pm_ops fsl_spdif_pm = {
 };
 
 static const struct of_device_id fsl_spdif_dt_ids[] = {
-   { .compatible = "fsl,imx35-spdif", },
-   { .compatible = "fsl,vf610-spdif", },
+   { .compatible = "fsl,imx35-spdif", .data = _spdif_imx35, },
+   { .compatible = "fsl,vf610-spdif", .data = _spdif_vf610, },
+   { .compatible = "fsl,imx6sx-spdif", .data = _spdif_imx6sx, },
{}
 };
 MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids);
-- 
2.21.0



[PATCH v3 1/2] ASoC: bindings: fsl_spdif: Add new compatible string for imx6sx

2020-06-17 Thread Shengjiu Wang
Add new compatible string "fsl,imx6sx-spdif" in the binding document.
And add compatible string "fsl,vf610-spdif" which was missed before.

Signed-off-by: Shengjiu Wang 
---
 Documentation/devicetree/bindings/sound/fsl,spdif.txt | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl,spdif.txt 
b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
index 8b324f82a782..e1365b0ee1e9 100644
--- a/Documentation/devicetree/bindings/sound/fsl,spdif.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
@@ -6,7 +6,11 @@ a fibre cable.
 
 Required properties:
 
-  - compatible : Compatible list, must contain "fsl,imx35-spdif".
+  - compatible : Compatible list, should contain one of the following
+ compatibles:
+ "fsl,imx35-spdif",
+ "fsl,vf610-spdif",
+ "fsl,imx6sx-spdif",
 
   - reg: Offset and length of the register set for the 
device.
 
-- 
2.21.0



Re: [PATCH v2 2/2] ASoC: fsl_spdif: Add support for imx6sx platform

2020-06-17 Thread Shengjiu Wang
On Wed, Jun 17, 2020 at 2:27 PM Nicolin Chen  wrote:
>
> On Wed, Jun 17, 2020 at 12:30:17PM +0800, Shengjiu Wang wrote:
> > The one difference on imx6sx platform is that the root clock
> > is shared with ASRC module, so we add a new flags
> > "shared_root_clock" which means the root clock is independent,
>
> "shared" means "not independent", against "independent" ;)
>
> > then we will not do the clk_set_rate and clk_round_rate to avoid
> > impact ASRC module usage.
> >
> > As add a new flags, we include the soc specific data struct.
> >
> > Signed-off-by: Shengjiu Wang 
>
> Can add this once fixing the remaining comments:
>
> Reviewed-by: Nicolin Chen 
>
> > +static inline bool fsl_spdif_can_set_clk_rate(struct fsl_spdif_priv *spdif,
> > +   int clk)
>
> Can actually merge into single line as kernel has 100-character
> limit now, though 80-char is still preferable for a good coding
> style. But I think this one wouldn't be too bad at all.
>
> > @@ -421,7 +456,7 @@ static int spdif_set_sample_rate(struct 
> > snd_pcm_substream *substream,
> >   sysclk_df = spdif_priv->sysclk_df[rate];
> >
> >   /* Don't mess up the clocks from other modules */
>
> We can drop this comments now as it's out-of-date and the name of
> the new helper function is straightforward enough.
>

ok, will send v3.

best regards
wang shengjiu


[PATCH v2 2/2] ASoC: fsl-asoc-card: Add MQS support

2020-06-16 Thread Shengjiu Wang
The MQS codec isn't an i2c device, so use of_find_device_by_node
to get platform device pointer.

Because MQS only support playback, then add a new audio map.

And there maybe "model" property or no "audio-routing" property in
devicetree, so add some enhancement for these two property.

Signed-off-by: Shengjiu Wang 
---
changes in v2
- update according Nicolin's comments.

 sound/soc/fsl/fsl-asoc-card.c | 78 +--
 1 file changed, 57 insertions(+), 21 deletions(-)

diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 00be73900888..d0543a53764e 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -119,6 +119,13 @@ static const struct snd_soc_dapm_route audio_map_ac97[] = {
{"ASRC-Capture",  NULL, "AC97 Capture"},
 };
 
+static const struct snd_soc_dapm_route audio_map_tx[] = {
+   /* 1st half -- Normal DAPM routes */
+   {"Playback",  NULL, "CPU-Playback"},
+   /* 2nd half -- ASRC DAPM routes */
+   {"CPU-Playback",  NULL, "ASRC-Playback"},
+};
+
 /* Add all possible widgets into here without being redundant */
 static const struct snd_soc_dapm_widget fsl_asoc_card_dapm_widgets[] = {
SND_SOC_DAPM_LINE("Line Out Jack", NULL),
@@ -485,8 +492,9 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
struct platform_device *asrc_pdev = NULL;
struct platform_device *cpu_pdev;
struct fsl_asoc_card_priv *priv;
-   struct i2c_client *codec_dev;
+   struct device *codec_dev = NULL;
const char *codec_dai_name;
+   const char *codec_dev_name;
u32 width;
int ret;
 
@@ -512,10 +520,23 @@ static int fsl_asoc_card_probe(struct platform_device 
*pdev)
}
 
codec_np = of_parse_phandle(np, "audio-codec", 0);
-   if (codec_np)
-   codec_dev = of_find_i2c_device_by_node(codec_np);
-   else
-   codec_dev = NULL;
+   if (codec_np) {
+   struct platform_device *codec_pdev;
+   struct i2c_client *codec_i2c;
+
+   codec_i2c = of_find_i2c_device_by_node(codec_np);
+   if (codec_i2c) {
+   codec_dev = _i2c->dev;
+   codec_dev_name = codec_i2c->name;
+   }
+   if (!codec_dev) {
+   codec_pdev = of_find_device_by_node(codec_np);
+   if (codec_pdev) {
+   codec_dev = _pdev->dev;
+   codec_dev_name = codec_pdev->name;
+   }
+   }
+   }
 
asrc_np = of_parse_phandle(np, "audio-asrc", 0);
if (asrc_np)
@@ -523,7 +544,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 
/* Get the MCLK rate only, and leave it controlled by CODEC drivers */
if (codec_dev) {
-   struct clk *codec_clk = clk_get(_dev->dev, NULL);
+   struct clk *codec_clk = clk_get(codec_dev, NULL);
 
if (!IS_ERR(codec_clk)) {
priv->codec_priv.mclk_freq = clk_get_rate(codec_clk);
@@ -538,6 +559,11 @@ static int fsl_asoc_card_probe(struct platform_device 
*pdev)
/* Assign a default DAI format, and allow each card to overwrite it */
priv->dai_fmt = DAI_FMT_BASE;
 
+   memcpy(priv->dai_link, fsl_asoc_card_dai,
+  sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link));
+
+   priv->card.dapm_routes = audio_map;
+   priv->card.num_dapm_routes = ARRAY_SIZE(audio_map);
/* Diversify the card configurations */
if (of_device_is_compatible(np, "fsl,imx-audio-cs42888")) {
codec_dai_name = "cs42888";
@@ -573,6 +599,18 @@ static int fsl_asoc_card_probe(struct platform_device 
*pdev)
codec_dai_name = "ac97-hifi";
priv->card.set_bias_level = NULL;
priv->dai_fmt = SND_SOC_DAIFMT_AC97;
+   priv->card.dapm_routes = audio_map_ac97;
+   priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_ac97);
+   } else if (of_device_is_compatible(np, "fsl,imx-audio-mqs")) {
+   codec_dai_name = "fsl-mqs-dai";
+   priv->card.set_bias_level = NULL;
+   priv->dai_fmt = SND_SOC_DAIFMT_LEFT_J |
+   SND_SOC_DAIFMT_CBS_CFS |
+   SND_SOC_DAIFMT_NB_NF;
+   priv->dai_link[1].dpcm_capture = 0;
+   priv->dai_link[2].dpcm_capture = 0;
+   priv->card.dapm_routes = audio_map_tx;
+   priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx);
} else {
dev_err(>dev, "unknown Device Tree compatible\n");

[PATCH v2 1/2] ASoC: bindings: fsl-asoc-card: Add compatible string for MQS

2020-06-16 Thread Shengjiu Wang
Add compatible string "fsl,imx-audio-mqs" for MQS, and move
"audio-routing" property to be optional for MQS doesn't need
such property.

Signed-off-by: Shengjiu Wang 
---
changes in v2
- Move "audio-routing" to optional.

 .../devicetree/bindings/sound/fsl-asoc-card.txt  | 12 +++-
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt 
b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
index c60a5732d29c..ca9a3a43adfd 100644
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
@@ -34,6 +34,8 @@ The compatible list for this generic sound card currently:
 
  "fsl,imx-audio-wm8960"
 
+ "fsl,imx-audio-mqs"
+
 Required properties:
 
   - compatible : Contains one of entries in the compatible list.
@@ -44,6 +46,11 @@ Required properties:
 
   - audio-codec: The phandle of an audio codec
 
+Optional properties:
+
+  - audio-asrc : The phandle of ASRC. It can be absent if there's no
+ need to add ASRC support via DPCM.
+
   - audio-routing  : A list of the connections between audio components.
  Each entry is a pair of strings, the first being the
  connection's sink, the second being the connection's
@@ -60,11 +67,6 @@ Required properties:
coexisting in order to support the old bindings
of wm8962 and sgtl5000.
 
-Optional properties:
-
-  - audio-asrc : The phandle of ASRC. It can be absent if there's no
- need to add ASRC support via DPCM.
-
 Optional unless SSI is selected as a CPU DAI:
 
   - mux-int-port   : The internal port of the i.MX audio muxer (AUDMUX)
-- 
2.21.0



[PATCH v2 2/2] ASoC: fsl_spdif: Add support for imx6sx platform

2020-06-16 Thread Shengjiu Wang
The one difference on imx6sx platform is that the root clock
is shared with ASRC module, so we add a new flags
"shared_root_clock" which means the root clock is independent,
then we will not do the clk_set_rate and clk_round_rate to avoid
impact ASRC module usage.

As add a new flags, we include the soc specific data struct.

Signed-off-by: Shengjiu Wang 
---
changes in v2
- use shared_root_clk instead ind_root_clk.
- add fsl_spdif_can_set_clk_rate function.

 sound/soc/fsl/fsl_spdif.c | 50 +++
 1 file changed, 46 insertions(+), 4 deletions(-)

diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 1b2e516f9162..8dc1959d0463 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -42,6 +42,18 @@ static u8 srpc_dpll_locked[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 
0xa, 0xb };
 
 #define DEFAULT_RXCLK_SRC  1
 
+/**
+ * struct fsl_spdif_soc_data: soc specific data
+ *
+ * @imx: for imx platform
+ * @shared_root_clock: flag of sharing a clock source with others;
+ * so the driver shouldn't set root clock rate
+ */
+struct fsl_spdif_soc_data {
+   bool imx;
+   bool shared_root_clock;
+};
+
 /*
  * SPDIF control structure
  * Defines channel status, subcode and Q sub
@@ -89,6 +101,7 @@ struct spdif_mixer_control {
  * @dma_params_rx: DMA parameters for receive channel
  */
 struct fsl_spdif_priv {
+   const struct fsl_spdif_soc_data *soc;
struct spdif_mixer_control fsl_spdif_control;
struct snd_soc_dai_driver cpu_dai_drv;
struct platform_device *pdev;
@@ -110,6 +123,28 @@ struct fsl_spdif_priv {
u32 regcache_srpc;
 };
 
+static struct fsl_spdif_soc_data fsl_spdif_vf610 = {
+   .imx = false,
+   .shared_root_clock = false,
+};
+
+static struct fsl_spdif_soc_data fsl_spdif_imx35 = {
+   .imx = true,
+   .shared_root_clock = false,
+};
+
+static struct fsl_spdif_soc_data fsl_spdif_imx6sx = {
+   .imx = true,
+   .shared_root_clock = true,
+};
+
+/* Check if clk is a root clock that does not share clock source with others */
+static inline bool fsl_spdif_can_set_clk_rate(struct fsl_spdif_priv *spdif,
+ int clk)
+{
+   return (clk == STC_TXCLK_SPDIF_ROOT) && !spdif->soc->shared_root_clock;
+}
+
 /* DPLL locked and lock loss interrupt handler */
 static void spdif_irq_dpll_lock(struct fsl_spdif_priv *spdif_priv)
 {
@@ -421,7 +456,7 @@ static int spdif_set_sample_rate(struct snd_pcm_substream 
*substream,
sysclk_df = spdif_priv->sysclk_df[rate];
 
/* Don't mess up the clocks from other modules */
-   if (clk != STC_TXCLK_SPDIF_ROOT)
+   if (!fsl_spdif_can_set_clk_rate(spdif_priv, clk))
goto clk_set_bypass;
 
/* The S/PDIF block needs a clock of 64 * fs * txclk_df */
@@ -1186,7 +1221,7 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv 
*spdif_priv,
continue;
 
ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index,
-i == STC_TXCLK_SPDIF_ROOT);
+
fsl_spdif_can_set_clk_rate(spdif_priv, i));
if (savesub == ret)
continue;
 
@@ -1230,6 +1265,12 @@ static int fsl_spdif_probe(struct platform_device *pdev)
 
spdif_priv->pdev = pdev;
 
+   spdif_priv->soc = of_device_get_match_data(>dev);
+   if (!spdif_priv->soc) {
+   dev_err(>dev, "failed to get soc data\n");
+   return -ENODEV;
+   }
+
/* Initialize this copy of the CPU DAI driver structure */
memcpy(_priv->cpu_dai_drv, _spdif_dai, sizeof(fsl_spdif_dai));
spdif_priv->cpu_dai_drv.name = dev_name(>dev);
@@ -1359,8 +1400,9 @@ static const struct dev_pm_ops fsl_spdif_pm = {
 };
 
 static const struct of_device_id fsl_spdif_dt_ids[] = {
-   { .compatible = "fsl,imx35-spdif", },
-   { .compatible = "fsl,vf610-spdif", },
+   { .compatible = "fsl,imx35-spdif", .data = _spdif_imx35, },
+   { .compatible = "fsl,vf610-spdif", .data = _spdif_vf610, },
+   { .compatible = "fsl,imx6sx-spdif", .data = _spdif_imx6sx, },
{}
 };
 MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids);
-- 
2.21.0



[PATCH v2 1/2] ASoC: bindings: fsl_spdif: Add new compatible string for imx6sx

2020-06-16 Thread Shengjiu Wang
Add new compatible string "fsl,imx6sx-spdif" in the binding document.
And add compatible string "fsl,vf610-spdif" which was missed before.

Signed-off-by: Shengjiu Wang 
---
 Documentation/devicetree/bindings/sound/fsl,spdif.txt | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl,spdif.txt 
b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
index 8b324f82a782..e1365b0ee1e9 100644
--- a/Documentation/devicetree/bindings/sound/fsl,spdif.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
@@ -6,7 +6,11 @@ a fibre cable.
 
 Required properties:
 
-  - compatible : Compatible list, must contain "fsl,imx35-spdif".
+  - compatible : Compatible list, should contain one of the following
+ compatibles:
+ "fsl,imx35-spdif",
+ "fsl,vf610-spdif",
+ "fsl,imx6sx-spdif",
 
   - reg: Offset and length of the register set for the 
device.
 
-- 
2.21.0



Re: [PATCH 2/2] ASoC: fsl_spdif: Add support for imx6sx platform

2020-06-16 Thread Shengjiu Wang
On Wed, Jun 17, 2020 at 7:30 AM Nicolin Chen  wrote:
>
> On Tue, Jun 16, 2020 at 02:42:41PM +0800, Shengjiu Wang wrote:
> > The one difference on imx6sx platform is that the root clock
> > is shared with ASRC module, so we add a new flags "ind_root_clk"
> > which means the root clock is independent, then we will not
> > do the clk_set_rate and clk_round_rate to avoid impact ASRC
> > module usage.
> >
> > As add a new flags, we include the soc specific data struct.
> >
> > Signed-off-by: Shengjiu Wang 
> > ---
> >  sound/soc/fsl/fsl_spdif.c | 43 +++
> >  1 file changed, 39 insertions(+), 4 deletions(-)
> >
> > diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
> > index 1b2e516f9162..00e06803d32f 100644
> > --- a/sound/soc/fsl/fsl_spdif.c
> > +++ b/sound/soc/fsl/fsl_spdif.c
> > @@ -42,6 +42,17 @@ static u8 srpc_dpll_locked[] = { 0x0, 0x1, 0x2, 0x3, 
> > 0x4, 0xa, 0xb };
> >
> >  #define DEFAULT_RXCLK_SRC1
> >
> > +/**
> > + * struct fsl_spdif_soc_data: soc specific data
> > + *
> > + * @imx: for imx platform
> > + * @ind_root_clk: flag for round clk rate
> > + */
> > +struct fsl_spdif_soc_data {
> > + bool imx;
> > + bool ind_root_clk;
>
> "ind" doesn't look very straightforward; maybe "shared_root_clock"?
>
> And for its comments:
> * @shared_root_clock: flag of sharing a clock source with others;
> * so the driver shouldn't set root clock rate
>
> > +};
> > +
> >  /*
> >   * SPDIF control structure
> >   * Defines channel status, subcode and Q sub
> > @@ -93,6 +104,7 @@ struct fsl_spdif_priv {
> >   struct snd_soc_dai_driver cpu_dai_drv;
> >   struct platform_device *pdev;
> >   struct regmap *regmap;
> > + const struct fsl_spdif_soc_data *soc;
>
> Looks better if we move it to the top of the list :)
>
> > @@ -421,7 +448,7 @@ static int spdif_set_sample_rate(struct 
> > snd_pcm_substream *substream,
> >   sysclk_df = spdif_priv->sysclk_df[rate];
> >
> >   /* Don't mess up the clocks from other modules */
> > - if (clk != STC_TXCLK_SPDIF_ROOT)
> > + if (clk != STC_TXCLK_SPDIF_ROOT || !spdif_priv->soc->ind_root_clk)
> >   goto clk_set_bypass;
> >
> >   /* The S/PDIF block needs a clock of 64 * fs * txclk_df */
> > @@ -1186,7 +1213,8 @@ static int fsl_spdif_probe_txclk(struct 
> > fsl_spdif_priv *spdif_priv,
> >   continue;
> >
> >   ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index,
> > -  i == STC_TXCLK_SPDIF_ROOT);
> > +  i == STC_TXCLK_SPDIF_ROOT &&
> > +  spdif_priv->soc->ind_root_clk);
>
> Having more than one place that checks the condition, we can add:
>
> /* Check if clk is a root clock that does not share clock source with others 
> */
> static inline bool fsl_spdif_can_set_clk_rate(struct fsl_spdif_priv *spdif, 
> int clk)
> {
> return (clk == STC_TXCLK_SPDIF_ROOT) && 
> !spdif->soc->shared_root_clock;
> }

will update them in v2

best regards
wang shengjiu


Re: [PATCH 2/2] ASoC: fsl-asoc-card: Add MQS support

2020-06-16 Thread Shengjiu Wang
On Wed, Jun 17, 2020 at 8:50 AM Nicolin Chen  wrote:
>
> On Tue, Jun 16, 2020 at 03:30:37PM +0800, Shengjiu Wang wrote:
> > The MQS codec isn't an i2c device, so add a new platform device for it.
> >
> > MQS only support playback, so add a new audio map.
> >
> > Add there maybe "model" property or no "audio-routing" property insertions
>
> "Add" => "And"
>
> > devicetree, so add some enhancement for these two property.
> >
> > Signed-off-by: Shengjiu Wang 
> > ---
> >  sound/soc/fsl/fsl-asoc-card.c | 70 ++-
> >  1 file changed, 52 insertions(+), 18 deletions(-)
> >
> > diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
> > index 00be73900888..2ac8cb9ddd10 100644
> > --- a/sound/soc/fsl/fsl-asoc-card.c
> > +++ b/sound/soc/fsl/fsl-asoc-card.c
>
> > @@ -482,6 +489,7 @@ static int fsl_asoc_card_probe(struct platform_device 
> > *pdev)
> >  {
> >   struct device_node *cpu_np, *codec_np, *asrc_np;
> >   struct device_node *np = pdev->dev.of_node;
> > + struct platform_device *codec_pdev = NULL; /* used for non i2c 
> > device*/
>
> Having both codec_pdev and codec_dev duplicates things. Actually
> only a couple of places really need "codec_dev" -- most of them
> need codec_dev->dev pointer instead. So we could have a cleanup:
>
> -   struct i2c_client *codec_dev;
> +   struct device *codec_dev = NULL;
>
> > @@ -512,10 +520,13 @@ static int fsl_asoc_card_probe(struct platform_device 
> > *pdev)
> >   }
> >
> >   codec_np = of_parse_phandle(np, "audio-codec", 0);
> > - if (codec_np)
> > + if (codec_np) {
> >   codec_dev = of_find_i2c_device_by_node(codec_np);
> > - else
> > + if (!codec_dev)
> > + codec_pdev = of_find_device_by_node(codec_np);
> > + } else {
> >   codec_dev = NULL;
> > + }
>
> Here can have something like (feel free to simplify):
>
> if (codec_np) {
> struct platform_device *codec_pdev;
> struct i2c_client *codec_i2c;
>
> codec_i2c = of_find_i2c_device_by_node(codec_np);
> if (codec_i2c)
> codec_dev = _i2c->dev;
>
> if (!codec_dev) {
> codec_pdev = of_find_device_by_node(codec_np);
> codec_dev = _pdev->dev;
> }
> }
> >   asrc_np = of_parse_phandle(np, "audio-asrc", 0);
> >   if (asrc_np)
> > @@ -525,6 +536,13 @@ static int fsl_asoc_card_probe(struct platform_device 
> > *pdev)
> >   if (codec_dev) {
> >   struct clk *codec_clk = clk_get(_dev->dev, NULL);
>
> Then here:
>
> -   struct clk *codec_clk = clk_get(_dev->dev, NULL);
> +   struct clk *codec_clk = clk_get(codec_dev, NULL);
>
> > @@ -538,6 +556,11 @@ static int fsl_asoc_card_probe(struct platform_device 
> > *pdev)
> >   /* Assign a default DAI format, and allow each card to overwrite it */
> >   priv->dai_fmt = DAI_FMT_BASE;
> >
> > + memcpy(priv->dai_link, fsl_asoc_card_dai,
> > +sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link));
>
> > @@ -573,13 +596,25 @@ static int fsl_asoc_card_probe(struct platform_device 
> > *pdev)
> >   codec_dai_name = "ac97-hifi";
> >   priv->card.set_bias_level = NULL;
> >   priv->dai_fmt = SND_SOC_DAIFMT_AC97;
> > + priv->card.dapm_routes = audio_map_ac97;
> > + priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_ac97);
> > + } else if (of_device_is_compatible(np, "fsl,imx-audio-mqs")) {
> > + codec_dai_name = "fsl-mqs-dai";
> > + priv->card.set_bias_level = NULL;
> > + priv->dai_fmt = SND_SOC_DAIFMT_LEFT_J |
> > + SND_SOC_DAIFMT_CBS_CFS |
> > + SND_SOC_DAIFMT_NB_NF;
> > + priv->dai_link[1].dpcm_playback = 1;
> > + priv->dai_link[2].dpcm_playback = 1;
>
> dpcm_playback = 1? That's the default value in fsl_asoc_card_dai.

ah,  should be dpcm_capture = 0.

>
> > @@ -601,19 +636,18 @@ static int fsl_asoc_card_probe(struct platform_device 
> > *pdev)
> >   priv->cpu_priv.sysclk_id[0] = FSL_SAI_CLK_MAST1;
> >   }
> >
>

[PATCH 2/2] ASoC: fsl-asoc-card: Add MQS support

2020-06-16 Thread Shengjiu Wang
The MQS codec isn't an i2c device, so add a new platform device for it.

MQS only support playback, so add a new audio map.

Add there maybe "model" property or no "audio-routing" property in
devicetree, so add some enhancement for these two property.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl-asoc-card.c | 70 ++-
 1 file changed, 52 insertions(+), 18 deletions(-)

diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index 00be73900888..2ac8cb9ddd10 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -119,6 +119,13 @@ static const struct snd_soc_dapm_route audio_map_ac97[] = {
{"ASRC-Capture",  NULL, "AC97 Capture"},
 };
 
+static const struct snd_soc_dapm_route audio_map_tx[] = {
+   /* 1st half -- Normal DAPM routes */
+   {"Playback",  NULL, "CPU-Playback"},
+   /* 2nd half -- ASRC DAPM routes */
+   {"CPU-Playback",  NULL, "ASRC-Playback"},
+};
+
 /* Add all possible widgets into here without being redundant */
 static const struct snd_soc_dapm_widget fsl_asoc_card_dapm_widgets[] = {
SND_SOC_DAPM_LINE("Line Out Jack", NULL),
@@ -482,6 +489,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 {
struct device_node *cpu_np, *codec_np, *asrc_np;
struct device_node *np = pdev->dev.of_node;
+   struct platform_device *codec_pdev = NULL; /* used for non i2c device*/
struct platform_device *asrc_pdev = NULL;
struct platform_device *cpu_pdev;
struct fsl_asoc_card_priv *priv;
@@ -512,10 +520,13 @@ static int fsl_asoc_card_probe(struct platform_device 
*pdev)
}
 
codec_np = of_parse_phandle(np, "audio-codec", 0);
-   if (codec_np)
+   if (codec_np) {
codec_dev = of_find_i2c_device_by_node(codec_np);
-   else
+   if (!codec_dev)
+   codec_pdev = of_find_device_by_node(codec_np);
+   } else {
codec_dev = NULL;
+   }
 
asrc_np = of_parse_phandle(np, "audio-asrc", 0);
if (asrc_np)
@@ -525,6 +536,13 @@ static int fsl_asoc_card_probe(struct platform_device 
*pdev)
if (codec_dev) {
struct clk *codec_clk = clk_get(_dev->dev, NULL);
 
+   if (!IS_ERR(codec_clk)) {
+   priv->codec_priv.mclk_freq = clk_get_rate(codec_clk);
+   clk_put(codec_clk);
+   }
+   } else if (codec_pdev) {
+   struct clk *codec_clk = clk_get(_pdev->dev, NULL);
+
if (!IS_ERR(codec_clk)) {
priv->codec_priv.mclk_freq = clk_get_rate(codec_clk);
clk_put(codec_clk);
@@ -538,6 +556,11 @@ static int fsl_asoc_card_probe(struct platform_device 
*pdev)
/* Assign a default DAI format, and allow each card to overwrite it */
priv->dai_fmt = DAI_FMT_BASE;
 
+   memcpy(priv->dai_link, fsl_asoc_card_dai,
+  sizeof(struct snd_soc_dai_link) * ARRAY_SIZE(priv->dai_link));
+
+   priv->card.dapm_routes = audio_map;
+   priv->card.num_dapm_routes = ARRAY_SIZE(audio_map);
/* Diversify the card configurations */
if (of_device_is_compatible(np, "fsl,imx-audio-cs42888")) {
codec_dai_name = "cs42888";
@@ -573,13 +596,25 @@ static int fsl_asoc_card_probe(struct platform_device 
*pdev)
codec_dai_name = "ac97-hifi";
priv->card.set_bias_level = NULL;
priv->dai_fmt = SND_SOC_DAIFMT_AC97;
+   priv->card.dapm_routes = audio_map_ac97;
+   priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_ac97);
+   } else if (of_device_is_compatible(np, "fsl,imx-audio-mqs")) {
+   codec_dai_name = "fsl-mqs-dai";
+   priv->card.set_bias_level = NULL;
+   priv->dai_fmt = SND_SOC_DAIFMT_LEFT_J |
+   SND_SOC_DAIFMT_CBS_CFS |
+   SND_SOC_DAIFMT_NB_NF;
+   priv->dai_link[1].dpcm_playback = 1;
+   priv->dai_link[2].dpcm_playback = 1;
+   priv->card.dapm_routes = audio_map_tx;
+   priv->card.num_dapm_routes = ARRAY_SIZE(audio_map_tx);
} else {
dev_err(>dev, "unknown Device Tree compatible\n");
ret = -EINVAL;
goto asrc_fail;
}
 
-   if (!fsl_asoc_card_is_ac97(priv) && !codec_dev) {
+   if (!fsl_asoc_card_is_ac97(priv) && !codec_dev && !codec_pdev) {
dev_err(>dev, "failed to find codec device\n");
ret = -EPROBE_DEFER;
goto asrc_fail;
@@ -601,19 +636,18 @@ static int fsl_aso

[PATCH 1/2] ASoC: bindings: fsl-asoc-card: Add compatible string for MQS

2020-06-16 Thread Shengjiu Wang
Add compatible string "fsl,imx-audio-mqs" for MQS

Signed-off-by: Shengjiu Wang 
---
 Documentation/devicetree/bindings/sound/fsl-asoc-card.txt | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt 
b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
index c60a5732d29c..6417c5dffa9a 100644
--- a/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
+++ b/Documentation/devicetree/bindings/sound/fsl-asoc-card.txt
@@ -34,6 +34,8 @@ The compatible list for this generic sound card currently:
 
  "fsl,imx-audio-wm8960"
 
+ "fsl,imx-audio-mqs"
+
 Required properties:
 
   - compatible : Contains one of entries in the compatible list.
-- 
2.21.0



[PATCH 2/2] ASoC: fsl_spdif: Add support for imx6sx platform

2020-06-16 Thread Shengjiu Wang
The one difference on imx6sx platform is that the root clock
is shared with ASRC module, so we add a new flags "ind_root_clk"
which means the root clock is independent, then we will not
do the clk_set_rate and clk_round_rate to avoid impact ASRC
module usage.

As add a new flags, we include the soc specific data struct.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_spdif.c | 43 +++
 1 file changed, 39 insertions(+), 4 deletions(-)

diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index 1b2e516f9162..00e06803d32f 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -42,6 +42,17 @@ static u8 srpc_dpll_locked[] = { 0x0, 0x1, 0x2, 0x3, 0x4, 
0xa, 0xb };
 
 #define DEFAULT_RXCLK_SRC  1
 
+/**
+ * struct fsl_spdif_soc_data: soc specific data
+ *
+ * @imx: for imx platform
+ * @ind_root_clk: flag for round clk rate
+ */
+struct fsl_spdif_soc_data {
+   bool imx;
+   bool ind_root_clk;
+};
+
 /*
  * SPDIF control structure
  * Defines channel status, subcode and Q sub
@@ -93,6 +104,7 @@ struct fsl_spdif_priv {
struct snd_soc_dai_driver cpu_dai_drv;
struct platform_device *pdev;
struct regmap *regmap;
+   const struct fsl_spdif_soc_data *soc;
bool dpll_locked;
u32 txrate[SPDIF_TXRATE_MAX];
u8 txclk_df[SPDIF_TXRATE_MAX];
@@ -110,6 +122,21 @@ struct fsl_spdif_priv {
u32 regcache_srpc;
 };
 
+static struct fsl_spdif_soc_data fsl_spdif_vf610 = {
+   .imx = false,
+   .ind_root_clk = true,
+};
+
+static struct fsl_spdif_soc_data fsl_spdif_imx35 = {
+   .imx = true,
+   .ind_root_clk = true,
+};
+
+static struct fsl_spdif_soc_data fsl_spdif_imx6sx = {
+   .imx = true,
+   .ind_root_clk = false,
+};
+
 /* DPLL locked and lock loss interrupt handler */
 static void spdif_irq_dpll_lock(struct fsl_spdif_priv *spdif_priv)
 {
@@ -421,7 +448,7 @@ static int spdif_set_sample_rate(struct snd_pcm_substream 
*substream,
sysclk_df = spdif_priv->sysclk_df[rate];
 
/* Don't mess up the clocks from other modules */
-   if (clk != STC_TXCLK_SPDIF_ROOT)
+   if (clk != STC_TXCLK_SPDIF_ROOT || !spdif_priv->soc->ind_root_clk)
goto clk_set_bypass;
 
/* The S/PDIF block needs a clock of 64 * fs * txclk_df */
@@ -1186,7 +1213,8 @@ static int fsl_spdif_probe_txclk(struct fsl_spdif_priv 
*spdif_priv,
continue;
 
ret = fsl_spdif_txclk_caldiv(spdif_priv, clk, savesub, index,
-i == STC_TXCLK_SPDIF_ROOT);
+i == STC_TXCLK_SPDIF_ROOT &&
+spdif_priv->soc->ind_root_clk);
if (savesub == ret)
continue;
 
@@ -1230,6 +1258,12 @@ static int fsl_spdif_probe(struct platform_device *pdev)
 
spdif_priv->pdev = pdev;
 
+   spdif_priv->soc = of_device_get_match_data(>dev);
+   if (!spdif_priv->soc) {
+   dev_err(>dev, "failed to get soc data\n");
+   return -ENODEV;
+   }
+
/* Initialize this copy of the CPU DAI driver structure */
memcpy(_priv->cpu_dai_drv, _spdif_dai, sizeof(fsl_spdif_dai));
spdif_priv->cpu_dai_drv.name = dev_name(>dev);
@@ -1359,8 +1393,9 @@ static const struct dev_pm_ops fsl_spdif_pm = {
 };
 
 static const struct of_device_id fsl_spdif_dt_ids[] = {
-   { .compatible = "fsl,imx35-spdif", },
-   { .compatible = "fsl,vf610-spdif", },
+   { .compatible = "fsl,imx35-spdif", .data = _spdif_imx35, },
+   { .compatible = "fsl,vf610-spdif", .data = _spdif_vf610, },
+   { .compatible = "fsl,imx6sx-spdif", .data = _spdif_imx6sx, },
{}
 };
 MODULE_DEVICE_TABLE(of, fsl_spdif_dt_ids);
-- 
2.21.0



[PATCH 1/2] ASoC: bindings: fsl_spdif: Add new compatible string for imx6sx

2020-06-16 Thread Shengjiu Wang
Add new compatible string "fsl,imx6sx-spdif" in the binding document.
And add compatible string "fsl,vf610-spdif" which was missed before.

Signed-off-by: Shengjiu Wang 
---
 Documentation/devicetree/bindings/sound/fsl,spdif.txt | 6 +-
 1 file changed, 5 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/fsl,spdif.txt 
b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
index 8b324f82a782..e1365b0ee1e9 100644
--- a/Documentation/devicetree/bindings/sound/fsl,spdif.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,spdif.txt
@@ -6,7 +6,11 @@ a fibre cable.
 
 Required properties:
 
-  - compatible : Compatible list, must contain "fsl,imx35-spdif".
+  - compatible : Compatible list, should contain one of the following
+ compatibles:
+ "fsl,imx35-spdif",
+ "fsl,vf610-spdif",
+ "fsl,imx6sx-spdif",
 
   - reg: Offset and length of the register set for the 
device.
 
-- 
2.21.0



[PATCH v3] ASoC: fsl_ssi: Fix bclk calculation for mono channel

2020-06-15 Thread Shengjiu Wang
For mono channel, SSI will switch to Normal mode.

In Normal mode and Network mode, the Word Length Control bits
control the word length divider in clock generator, which is
different with I2S Master mode (the word length is fixed to
32bit), it should be the value of params_width(hw_params).

The condition "slots == 2" is not good for I2S Master mode,
because for Network mode and Normal mode, the slots can also
be 2. Then we need to use (ssi->i2s_net & SSI_SCR_I2S_MODE_MASK)
to check if it is I2S Master mode.

So we refine the formula for mono channel, otherwise there
will be sound issue for S24_LE.

Fixes: b0a7043d5c2c ("ASoC: fsl_ssi: Caculate bit clock rate using slot number 
and width")
Signed-off-by: Shengjiu Wang 
---
changes in v3
- update according to Nicolin's comments

changes in v2
- refine patch for Network mode and Normal mode.

 sound/soc/fsl/fsl_ssi.c | 13 +
 1 file changed, 9 insertions(+), 4 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index bad89b0d129e..1a2fa7f18142 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -678,8 +678,9 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
*substream,
struct regmap *regs = ssi->regs;
u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
unsigned long clkrate, baudrate, tmprate;
-   unsigned int slots = params_channels(hw_params);
-   unsigned int slot_width = 32;
+   unsigned int channels = params_channels(hw_params);
+   unsigned int slot_width = params_width(hw_params);
+   unsigned int slots = 2;
u64 sub, savesub = 10;
unsigned int freq;
bool baudclk_is_used;
@@ -688,10 +689,14 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
*substream,
/* Override slots and slot_width if being specifically set... */
if (ssi->slots)
slots = ssi->slots;
-   /* ...but keep 32 bits if slots is 2 -- I2S Master mode */
-   if (ssi->slot_width && slots != 2)
+   if (ssi->slot_width)
slot_width = ssi->slot_width;
 
+   /* ...but force 32 bits for stereo audio using I2S Master Mode */
+   if (channels == 2 &&
+   (ssi->i2s_net & SSI_SCR_I2S_MODE_MASK) == SSI_SCR_I2S_MODE_MASTER)
+   slot_width = 32;
+
/* Generate bit clock based on the slot number and slot width */
freq = slots * slot_width * params_rate(hw_params);
 
-- 
2.21.0



Re: [PATCH v2] ASoC: fsl_ssi: Fix bclk calculation for mono channel

2020-06-15 Thread Shengjiu Wang
On Tue, Jun 16, 2020 at 9:59 AM Nicolin Chen  wrote:
>
> On Tue, Jun 16, 2020 at 09:48:39AM +0800, Shengjiu Wang wrote:
> > On Tue, Jun 16, 2020 at 7:11 AM Nicolin Chen  wrote:
> > >
> > > On Mon, Jun 15, 2020 at 01:56:18PM +0800, Shengjiu Wang wrote:
> > > > For mono channel, SSI will switch to Normal mode.
> > > >
> > > > In Normal mode and Network mode, the Word Length Control bits
> > > > control the word length divider in clock generator, which is
> > > > different with I2S Master mode (the word length is fixed to
> > > > 32bit), it should be the value of params_width(hw_params).
> > > >
> > > > The condition "slots == 2" is not good for I2S Master mode,
> > > > because for Network mode and Normal mode, the slots can also
> > > > be 2. Then we need to use (ssi->i2s_net & SSI_SCR_I2S_MODE_MASK)
> > > > to check if it is I2S Master mode.
> > >
> > > The fsl_ssi_set_bclk is only called when fsl_ssi_is_i2s_master,
> > > though I agree that that line of comments sounds confusing now.
> >
> > Actually I think fsl_ssi_is_i2s_master is not accurate, it just checks
> > the Master mode,  but didn't check the I2S mode.
> >
> > >
> > > > So we refine the famula for mono channel, otherwise there
> > >
> > > famula => formula?
> > >
> > > > will be sound issue for S24_LE.
> > > >
> > > > Fixes: b0a7043d5c2c ("ASoC: fsl_ssi: Caculate bit clock rate using slot 
> > > > number and width")
> > > > Signed-off-by: Shengjiu Wang 
> > > > ---
> > > > changes in v2
> > > > - refine patch for Network mode and Normal mode.
> > > >
> > > >  sound/soc/fsl/fsl_ssi.c | 15 +++
> > > >  1 file changed, 11 insertions(+), 4 deletions(-)
> > > >
> > > > diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
> > > > index bad89b0d129e..cbf67d132fda 100644
> > > > --- a/sound/soc/fsl/fsl_ssi.c
> > > > +++ b/sound/soc/fsl/fsl_ssi.c
> > > > @@ -678,7 +678,8 @@ static int fsl_ssi_set_bclk(struct 
> > > > snd_pcm_substream *substream,
> > > >   struct regmap *regs = ssi->regs;
> > > >   u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
> > > >   unsigned long clkrate, baudrate, tmprate;
> > > > - unsigned int slots = params_channels(hw_params);
> > > > + unsigned int channels = params_channels(hw_params);
> > > > + unsigned int slots;
> > > >   unsigned int slot_width = 32;
> > > >   u64 sub, savesub = 10;
> > > >   unsigned int freq;
> > > > @@ -688,9 +689,15 @@ static int fsl_ssi_set_bclk(struct 
> > > > snd_pcm_substream *substream,
> > > >   /* Override slots and slot_width if being specifically set... */
> > > >   if (ssi->slots)
> > > >   slots = ssi->slots;
> > > > - /* ...but keep 32 bits if slots is 2 -- I2S Master mode */
> > > > - if (ssi->slot_width && slots != 2)
> > > > - slot_width = ssi->slot_width;
> > > > + else
> > > > + /* Apply two slots for mono channel, because DC = 2 */
> > > > + slots = (channels == 1) ? 2 : channels;
> > > > +
> > > > + /* ...but keep 32 bits if I2S Master mode */
> > > > + if ((ssi->i2s_net & SSI_SCR_I2S_MODE_MASK) != 
> > > > SSI_SCR_I2S_MODE_MASTER ||
> > > > + channels == 1)
> > > > + slot_width = ssi->slot_width ? ssi->slot_width :
> > >
> > > This looks very complicated...can you review and try mine?
> > > (Basically, take 32-bit out of default but force it later)
> > >
> > > @@ -678,8 +678,9 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
> > > *substream,
> > > struct regmap *regs = ssi->regs;
> > > u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
> > > unsigned long clkrate, baudrate, tmprate;
> > > -   unsigned int slots = params_channels(hw_params);
> > > -   unsigned int slot_width = 32;
> > > +   unsigned int channels = params_channels(hw_params);
> > > +   unsigned int slot_width = params_width(hw_params);
> > > +   unsigned int slots = 2;
> > > u64 sub, savesub = 1

Re: [PATCH v2] ASoC: fsl_ssi: Fix bclk calculation for mono channel

2020-06-15 Thread Shengjiu Wang
On Tue, Jun 16, 2020 at 7:11 AM Nicolin Chen  wrote:
>
> On Mon, Jun 15, 2020 at 01:56:18PM +0800, Shengjiu Wang wrote:
> > For mono channel, SSI will switch to Normal mode.
> >
> > In Normal mode and Network mode, the Word Length Control bits
> > control the word length divider in clock generator, which is
> > different with I2S Master mode (the word length is fixed to
> > 32bit), it should be the value of params_width(hw_params).
> >
> > The condition "slots == 2" is not good for I2S Master mode,
> > because for Network mode and Normal mode, the slots can also
> > be 2. Then we need to use (ssi->i2s_net & SSI_SCR_I2S_MODE_MASK)
> > to check if it is I2S Master mode.
>
> The fsl_ssi_set_bclk is only called when fsl_ssi_is_i2s_master,
> though I agree that that line of comments sounds confusing now.

Actually I think fsl_ssi_is_i2s_master is not accurate, it just checks
the Master mode,  but didn't check the I2S mode.

>
> > So we refine the famula for mono channel, otherwise there
>
> famula => formula?
>
> > will be sound issue for S24_LE.
> >
> > Fixes: b0a7043d5c2c ("ASoC: fsl_ssi: Caculate bit clock rate using slot 
> > number and width")
> > Signed-off-by: Shengjiu Wang 
> > ---
> > changes in v2
> > - refine patch for Network mode and Normal mode.
> >
> >  sound/soc/fsl/fsl_ssi.c | 15 +++
> >  1 file changed, 11 insertions(+), 4 deletions(-)
> >
> > diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
> > index bad89b0d129e..cbf67d132fda 100644
> > --- a/sound/soc/fsl/fsl_ssi.c
> > +++ b/sound/soc/fsl/fsl_ssi.c
> > @@ -678,7 +678,8 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
> > *substream,
> >   struct regmap *regs = ssi->regs;
> >   u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
> >   unsigned long clkrate, baudrate, tmprate;
> > - unsigned int slots = params_channels(hw_params);
> > + unsigned int channels = params_channels(hw_params);
> > + unsigned int slots;
> >   unsigned int slot_width = 32;
> >   u64 sub, savesub = 10;
> >   unsigned int freq;
> > @@ -688,9 +689,15 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
> > *substream,
> >   /* Override slots and slot_width if being specifically set... */
> >   if (ssi->slots)
> >   slots = ssi->slots;
> > - /* ...but keep 32 bits if slots is 2 -- I2S Master mode */
> > - if (ssi->slot_width && slots != 2)
> > - slot_width = ssi->slot_width;
> > + else
> > + /* Apply two slots for mono channel, because DC = 2 */
> > + slots = (channels == 1) ? 2 : channels;
> > +
> > + /* ...but keep 32 bits if I2S Master mode */
> > + if ((ssi->i2s_net & SSI_SCR_I2S_MODE_MASK) != SSI_SCR_I2S_MODE_MASTER 
> > ||
> > + channels == 1)
> > + slot_width = ssi->slot_width ? ssi->slot_width :
>
> This looks very complicated...can you review and try mine?
> (Basically, take 32-bit out of default but force it later)
>
> @@ -678,8 +678,9 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
> *substream,
> struct regmap *regs = ssi->regs;
> u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
> unsigned long clkrate, baudrate, tmprate;
> -   unsigned int slots = params_channels(hw_params);
> -   unsigned int slot_width = 32;
> +   unsigned int channels = params_channels(hw_params);
> +   unsigned int slot_width = params_width(hw_params);
> +   unsigned int slots = 2;
> u64 sub, savesub = 10;
> unsigned int freq;
> bool baudclk_is_used;
> @@ -688,10 +689,16 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
> *substream,
> /* Override slots and slot_width if being specifically set... */
> if (ssi->slots)
> slots = ssi->slots;
> -   /* ...but keep 32 bits if slots is 2 -- I2S Master mode */
> -   if (ssi->slot_width && slots != 2)
> +   if (ssi->slot_width)
> slot_width = ssi->slot_width;
>
> +   /*
> +* ...but force 32 bits for stereo audio. Note that mono audio is also
> +* sent in 2 slots via NORMAL mode, so check both slots and channels.
> +*/
> +   if (slots == 2 && channels == 2)
> +   slot_width = 32;

slots ==2 && channels ==2 does not mean the I2S Master mode.
For LEFT_J, it is also slots =2 & channels = 2, then the slot_width
should be params_width(hw_params).
and DSP_A/B also supports stereo.


[PATCH v2] ASoC: fsl_ssi: Fix bclk calculation for mono channel

2020-06-15 Thread Shengjiu Wang
For mono channel, SSI will switch to Normal mode.

In Normal mode and Network mode, the Word Length Control bits
control the word length divider in clock generator, which is
different with I2S Master mode (the word length is fixed to
32bit), it should be the value of params_width(hw_params).

The condition "slots == 2" is not good for I2S Master mode,
because for Network mode and Normal mode, the slots can also
be 2. Then we need to use (ssi->i2s_net & SSI_SCR_I2S_MODE_MASK)
to check if it is I2S Master mode.

So we refine the famula for mono channel, otherwise there
will be sound issue for S24_LE.

Fixes: b0a7043d5c2c ("ASoC: fsl_ssi: Caculate bit clock rate using slot number 
and width")
Signed-off-by: Shengjiu Wang 
---
changes in v2
- refine patch for Network mode and Normal mode.

 sound/soc/fsl/fsl_ssi.c | 15 +++
 1 file changed, 11 insertions(+), 4 deletions(-)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index bad89b0d129e..cbf67d132fda 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -678,7 +678,8 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
*substream,
struct regmap *regs = ssi->regs;
u32 pm = 999, div2, psr, stccr, mask, afreq, factor, i;
unsigned long clkrate, baudrate, tmprate;
-   unsigned int slots = params_channels(hw_params);
+   unsigned int channels = params_channels(hw_params);
+   unsigned int slots;
unsigned int slot_width = 32;
u64 sub, savesub = 10;
unsigned int freq;
@@ -688,9 +689,15 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
*substream,
/* Override slots and slot_width if being specifically set... */
if (ssi->slots)
slots = ssi->slots;
-   /* ...but keep 32 bits if slots is 2 -- I2S Master mode */
-   if (ssi->slot_width && slots != 2)
-   slot_width = ssi->slot_width;
+   else
+   /* Apply two slots for mono channel, because DC = 2 */
+   slots = (channels == 1) ? 2 : channels;
+
+   /* ...but keep 32 bits if I2S Master mode */
+   if ((ssi->i2s_net & SSI_SCR_I2S_MODE_MASK) != SSI_SCR_I2S_MODE_MASTER ||
+   channels == 1)
+   slot_width = ssi->slot_width ? ssi->slot_width :
+params_width(hw_params);
 
/* Generate bit clock based on the slot number and slot width */
freq = slots * slot_width * params_rate(hw_params);
-- 
2.21.0



[RFC PATCH v3 4/4] ASoC: fsl_asrc_dma: Fix data copying speed issue with EDMA

2020-06-12 Thread Shengjiu Wang
With EDMA, there is two dma channels can be used for dev_to_dev,
one is from ASRC, one is from another peripheral (ESAI or SAI).

If we select the dma channel of ASRC, there is an issue for ideal
ratio case, the speed of copy data is faster than sample
frequency, because ASRC output data is very fast in ideal ratio
mode.

So it is reasonable to use the dma channel of Back-End peripheral.
then copying speed of DMA is controlled by data consumption
speed in the peripheral FIFO,

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_asrc_common.h |  2 ++
 sound/soc/fsl/fsl_asrc_dma.c| 26 +++---
 2 files changed, 17 insertions(+), 11 deletions(-)

diff --git a/sound/soc/fsl/fsl_asrc_common.h b/sound/soc/fsl/fsl_asrc_common.h
index 77665b15c8db..7e1c13ca37f1 100644
--- a/sound/soc/fsl/fsl_asrc_common.h
+++ b/sound/soc/fsl/fsl_asrc_common.h
@@ -32,6 +32,7 @@ enum asrc_pair_index {
  * @dma_chan: inputer and output DMA channels
  * @dma_data: private dma data
  * @pos: hardware pointer position
+ * @req_dma_chan: flag to release dev_to_dev chan
  * @private: pair private area
  */
 struct fsl_asrc_pair {
@@ -45,6 +46,7 @@ struct fsl_asrc_pair {
struct dma_chan *dma_chan[2];
struct imx_dma_data dma_data;
unsigned int pos;
+   bool req_dma_chan;
 
void *private;
 };
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
index d88e6343e0a2..5f01a58f422a 100644
--- a/sound/soc/fsl/fsl_asrc_dma.c
+++ b/sound/soc/fsl/fsl_asrc_dma.c
@@ -233,11 +233,11 @@ static int fsl_asrc_dma_hw_params(struct 
snd_soc_component *component,
 
pair->dma_chan[dir] =
dma_request_channel(mask, filter, >dma_data);
+   pair->req_dma_chan = true;
} else {
-   if (!be_chan)
-   dma_release_channel(tmp_chan);
-   pair->dma_chan[dir] =
-   asrc->get_dma_channel(pair, dir);
+   pair->dma_chan[dir] = tmp_chan;
+   /* Do not flag to release if we are reusing the Back-End one */
+   pair->req_dma_chan = !be_chan;
}
 
if (!pair->dma_chan[dir]) {
@@ -276,7 +276,8 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component 
*component,
ret = dmaengine_slave_config(pair->dma_chan[dir], _be);
if (ret) {
dev_err(dev, "failed to config DMA channel for Back-End\n");
-   dma_release_channel(pair->dma_chan[dir]);
+   if (pair->req_dma_chan)
+   dma_release_channel(pair->dma_chan[dir]);
return ret;
}
 
@@ -288,19 +289,22 @@ static int fsl_asrc_dma_hw_params(struct 
snd_soc_component *component,
 static int fsl_asrc_dma_hw_free(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
 {
+   bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
struct snd_pcm_runtime *runtime = substream->runtime;
struct fsl_asrc_pair *pair = runtime->private_data;
+   u8 dir = tx ? OUT : IN;
 
snd_pcm_set_runtime_buffer(substream, NULL);
 
-   if (pair->dma_chan[IN])
-   dma_release_channel(pair->dma_chan[IN]);
+   if (pair->dma_chan[!dir])
+   dma_release_channel(pair->dma_chan[!dir]);
 
-   if (pair->dma_chan[OUT])
-   dma_release_channel(pair->dma_chan[OUT]);
+   /* release dev_to_dev chan if we aren't reusing the Back-End one */
+   if (pair->dma_chan[dir] && pair->req_dma_chan)
+   dma_release_channel(pair->dma_chan[dir]);
 
-   pair->dma_chan[IN] = NULL;
-   pair->dma_chan[OUT] = NULL;
+   pair->dma_chan[!dir] = NULL;
+   pair->dma_chan[dir] = NULL;
 
return 0;
 }
-- 
2.21.0



[RFC PATCH v3 3/4] ASoC: fsl_asrc_dma: Reuse the dma channel if available in Back-End

2020-06-12 Thread Shengjiu Wang
The dma channel has been requested by Back-End cpu dai driver already.
If fsl_asrc_dma requests dma chan with same dma:tx symlink, then
there will be below warning with SDMA.

[   48.174236] fsl-esai-dai 2024000.esai: Cannot create DMA dma:tx symlink

So if we can reuse the dma channel of Back-End, then the issue can be
fixed.

In order to get the dma channel which is already requested in Back-End.
we use the exported two functions (snd_soc_lookup_component_nolocked
and soc_component_to_pcm). If we can get the dma channel, then reuse it,
if can't, then request a new one.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_asrc_dma.c | 25 -
 1 file changed, 20 insertions(+), 5 deletions(-)

diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
index d6a3fc5f87e5..d88e6343e0a2 100644
--- a/sound/soc/fsl/fsl_asrc_dma.c
+++ b/sound/soc/fsl/fsl_asrc_dma.c
@@ -135,6 +135,8 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component 
*component,
struct snd_dmaengine_dai_dma_data *dma_params_be = NULL;
struct snd_pcm_runtime *runtime = substream->runtime;
struct fsl_asrc_pair *pair = runtime->private_data;
+   struct dma_chan *tmp_chan = NULL, *be_chan = NULL;
+   struct snd_soc_component *component_be = NULL;
struct fsl_asrc *asrc = pair->asrc;
struct dma_slave_config config_fe, config_be;
enum asrc_pair_index index = pair->index;
@@ -142,7 +144,6 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component 
*component,
int stream = substream->stream;
struct imx_dma_data *tmp_data;
struct snd_soc_dpcm *dpcm;
-   struct dma_chan *tmp_chan;
struct device *dev_be;
u8 dir = tx ? OUT : IN;
dma_cap_mask_t mask;
@@ -197,18 +198,30 @@ static int fsl_asrc_dma_hw_params(struct 
snd_soc_component *component,
dma_cap_set(DMA_SLAVE, mask);
dma_cap_set(DMA_CYCLIC, mask);
 
+   /*
+* The Back-End device might have already requested a DMA channel,
+* so try to reuse it first, and then request a new one upon NULL.
+*/
+   component_be = snd_soc_lookup_component_nolocked(dev_be, 
SND_DMAENGINE_PCM_DRV_NAME);
+   if (component_be) {
+   be_chan = 
soc_component_to_pcm(component_be)->chan[substream->stream];
+   tmp_chan = be_chan;
+   }
+   if (!tmp_chan)
+   tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx");
+
/*
 * An EDMA DEV_TO_DEV channel is fixed and bound with DMA event of each
 * peripheral, unlike SDMA channel that is allocated dynamically. So no
-* need to configure dma_request and dma_request2, but get dma_chan via
-* dma_request_slave_channel directly with dma name of Front-End device
+* need to configure dma_request and dma_request2, but get dma_chan of
+* Back-End device directly via dma_request_slave_channel.
 */
if (!asrc->use_edma) {
/* Get DMA request of Back-End */
-   tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx");
tmp_data = tmp_chan->private;
pair->dma_data.dma_request = tmp_data->dma_request;
-   dma_release_channel(tmp_chan);
+   if (!be_chan)
+   dma_release_channel(tmp_chan);
 
/* Get DMA request of Front-End */
tmp_chan = asrc->get_dma_channel(pair, dir);
@@ -221,6 +234,8 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component 
*component,
pair->dma_chan[dir] =
dma_request_channel(mask, filter, >dma_data);
} else {
+   if (!be_chan)
+   dma_release_channel(tmp_chan);
pair->dma_chan[dir] =
asrc->get_dma_channel(pair, dir);
}
-- 
2.21.0



[RFC PATCH v3 2/4] ASoC: dmaengine_pcm: export soc_component_to_pcm

2020-06-12 Thread Shengjiu Wang
In DPCM case, Front-End needs to get the dma chan which has
been requested by Back-End and reuse it.

Signed-off-by: Shengjiu Wang 
---
 include/sound/dmaengine_pcm.h | 11 +++
 sound/soc/soc-generic-dmaengine-pcm.c | 12 
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h
index b65220685920..8c5e38180fb0 100644
--- a/include/sound/dmaengine_pcm.h
+++ b/include/sound/dmaengine_pcm.h
@@ -161,4 +161,15 @@ int snd_dmaengine_pcm_prepare_slave_config(struct 
snd_pcm_substream *substream,
 
 #define SND_DMAENGINE_PCM_DRV_NAME "snd_dmaengine_pcm"
 
+struct dmaengine_pcm {
+   struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
+   const struct snd_dmaengine_pcm_config *config;
+   struct snd_soc_component component;
+   unsigned int flags;
+};
+
+static inline struct dmaengine_pcm *soc_component_to_pcm(struct 
snd_soc_component *p)
+{
+   return container_of(p, struct dmaengine_pcm, component);
+}
 #endif
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c 
b/sound/soc/soc-generic-dmaengine-pcm.c
index f728309a0833..80a4e71f2d95 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -21,18 +21,6 @@
  */
 #define SND_DMAENGINE_PCM_FLAG_NO_RESIDUE BIT(31)
 
-struct dmaengine_pcm {
-   struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
-   const struct snd_dmaengine_pcm_config *config;
-   struct snd_soc_component component;
-   unsigned int flags;
-};
-
-static struct dmaengine_pcm *soc_component_to_pcm(struct snd_soc_component *p)
-{
-   return container_of(p, struct dmaengine_pcm, component);
-}
-
 static struct device *dmaengine_dma_dev(struct dmaengine_pcm *pcm,
struct snd_pcm_substream *substream)
 {
-- 
2.21.0



[RFC PATCH v3 1/4] ASoC: soc-card: export snd_soc_lookup_component_nolocked

2020-06-12 Thread Shengjiu Wang
snd_soc_lookup_component_nolocked can be used for the DPCM case
that Front-End needs to get the unused platform component but
added by Back-End cpu dai driver.

If the component is gotten, then we can get the dma chan created
by Back-End component and reused it in Front-End.

Signed-off-by: Shengjiu Wang 
---
 include/sound/soc.h  | 2 ++
 sound/soc/soc-core.c | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 74868436ac79..565612a8d690 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -444,6 +444,8 @@ int devm_snd_soc_register_component(struct device *dev,
 const struct snd_soc_component_driver 
*component_driver,
 struct snd_soc_dai_driver *dai_drv, int num_dai);
 void snd_soc_unregister_component(struct device *dev);
+struct snd_soc_component *snd_soc_lookup_component_nolocked(struct device *dev,
+   const char 
*driver_name);
 struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
   const char *driver_name);
 
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index b07eca2c6ccc..d4c73e86d058 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -310,7 +310,7 @@ struct snd_soc_component *snd_soc_rtdcom_lookup(struct 
snd_soc_pcm_runtime *rtd,
 }
 EXPORT_SYMBOL_GPL(snd_soc_rtdcom_lookup);
 
-static struct snd_soc_component
+struct snd_soc_component
 *snd_soc_lookup_component_nolocked(struct device *dev, const char *driver_name)
 {
struct snd_soc_component *component;
@@ -329,6 +329,7 @@ static struct snd_soc_component
 
return found_component;
 }
+EXPORT_SYMBOL_GPL(snd_soc_lookup_component_nolocked);
 
 struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
   const char *driver_name)
-- 
2.21.0



[RFC PATCH v3 0/4] Reuse the dma channel if available in Back-End

2020-06-12 Thread Shengjiu Wang
Reuse the dma channel if available in Back-End

Shengjiu Wang (4):
  ASoC: soc-card: export snd_soc_lookup_component_nolocked
  ASoC: dmaengine_pcm: export soc_component_to_pcm
  ASoC: fsl_asrc_dma: Reuse the dma channel if available in Back-End
  ASoC: fsl_asrc_dma: Fix data copying speed issue with EDMA

changes in v3:
- update according to Nicolin's comments
- split previous 0003 patch to two patches

changes in v2:
- update according to Mark's comments and split the patch

 include/sound/dmaengine_pcm.h | 11 +++
 include/sound/soc.h   |  2 ++
 sound/soc/fsl/fsl_asrc_common.h   |  2 ++
 sound/soc/fsl/fsl_asrc_dma.c  | 47 +++
 sound/soc/soc-core.c  |  3 +-
 sound/soc/soc-generic-dmaengine-pcm.c | 12 ---
 6 files changed, 50 insertions(+), 27 deletions(-)

-- 
2.21.0



Re: [RFC PATCH v2 3/3] ASoC: fsl_asrc_dma: Reuse the dma channel if available in Back-End

2020-06-11 Thread Shengjiu Wang
On Fri, Jun 12, 2020 at 8:33 AM Nicolin Chen  wrote:
>
> On Wed, Jun 10, 2020 at 06:05:49PM +0800, Shengjiu Wang wrote:
> > The dma channel has been requested by Back-End cpu dai driver already.
> > If fsl_asrc_dma requests dma chan with same dma:tx symlink, then
> > there will be below warning with SDMA.
> >
> > [   48.174236] fsl-esai-dai 2024000.esai: Cannot create DMA dma:tx symlink
> >
> > or with EDMA the request operation will fail for EDMA channel
> > can only be requested once.
> >
> > So If we can reuse the dma channel of Back-End, then the issue can be
> > fixed.
> >
> > In order to get the dma channel which is already requested in Back-End.
> > we use the exported two functions (snd_soc_lookup_component_nolocked
> > and soc_component_to_pcm). If we can get the dma channel, then reuse it,
> > if can't, then request a new one.
> >
> > Signed-off-by: Shengjiu Wang 
> > ---
> >  sound/soc/fsl/fsl_asrc_common.h |  2 ++
> >  sound/soc/fsl/fsl_asrc_dma.c| 52 +
> >  2 files changed, 42 insertions(+), 12 deletions(-)
>
> > diff --git a/sound/soc/fsl/fsl_asrc_common.h 
> > b/sound/soc/fsl/fsl_asrc_common.h
> > index 77665b15c8db..09512bc79b80 100644
> > --- a/sound/soc/fsl/fsl_asrc_common.h
> > +++ b/sound/soc/fsl/fsl_asrc_common.h
> > @@ -32,6 +32,7 @@ enum asrc_pair_index {
> >   * @dma_chan: inputer and output DMA channels
> >   * @dma_data: private dma data
> >   * @pos: hardware pointer position
> > + * @req_dma_chan_dev_to_dev: flag for release dev_to_dev chan
>
> Since we only have dma_request call for back-end only:
> + * @req_dma_chan: flag to release back-end dma chan

I prefer to use the description "flag to release dev_to_dev chan"
because we won't release the dma chan of the back-end. if the chan
is from the back-end, it is owned by the back-end component.

>
> > diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
> > index d6a3fc5f87e5..5ecb77d466d3 100644
> > --- a/sound/soc/fsl/fsl_asrc_dma.c
> > +++ b/sound/soc/fsl/fsl_asrc_dma.c
> > @@ -160,6 +161,9 @@ static int fsl_asrc_dma_hw_params(struct 
> > snd_soc_component *component,
> >   substream_be = snd_soc_dpcm_get_substream(be, stream);
> >   dma_params_be = snd_soc_dai_get_dma_data(dai, substream_be);
> >   dev_be = dai->dev;
> > + component_be = snd_soc_lookup_component_nolocked(dev_be, 
> > SND_DMAENGINE_PCM_DRV_NAME);
> > + if (component_be)
> > + tmp_chan = 
> > soc_component_to_pcm(component_be)->chan[substream->stream];
>
> Should we use substream_be->stream or just substream->stream?

substream_be->stream should be better.

>
> And would be better to add these lines right before we really use
> tmp_chan because there's still some distance till it reaches that
> point. And would be better to have a line of comments too.

ok.

>
> > @@ -205,10 +209,14 @@ static int fsl_asrc_dma_hw_params(struct 
> > snd_soc_component *component,
> >*/
> >   if (!asrc->use_edma) {
> >   /* Get DMA request of Back-End */
> > - tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : 
> > "rx");
> > + if (!tmp_chan) {
> > + tmp_chan_new = dma_request_slave_channel(dev_be, tx ? 
> > "tx" : "rx");
> > + tmp_chan = tmp_chan_new;
>
> This is a bit confusing...though I finally got it :)
> So probably better to have a line of comments.

ok.

>
> > @@ -220,9 +228,26 @@ static int fsl_asrc_dma_hw_params(struct 
> > snd_soc_component *component,
> >
> >   pair->dma_chan[dir] =
> >   dma_request_channel(mask, filter, >dma_data);
> > + pair->req_dma_chan_dev_to_dev = true;
> >   } else {
> > - pair->dma_chan[dir] =
> > - asrc->get_dma_channel(pair, dir);
> > + /*
> > +  * With EDMA, there is two dma channels can be used for p2p,
> > +  * one is from ASRC, one is from another peripheral
> > +  * (ESAI or SAI). Previously we select the dma channel of 
> > ASRC,
> > +  * but find an issue for ideal ratio case, there is no control
> > +  * for data copy speed, the speed is faster than sample
> > +  * frequency.
> > +  *
> > +  * So we switch to use dma channel of peripheral 

[RFC PATCH v2 3/3] ASoC: fsl_asrc_dma: Reuse the dma channel if available in Back-End

2020-06-10 Thread Shengjiu Wang
The dma channel has been requested by Back-End cpu dai driver already.
If fsl_asrc_dma requests dma chan with same dma:tx symlink, then
there will be below warning with SDMA.

[   48.174236] fsl-esai-dai 2024000.esai: Cannot create DMA dma:tx symlink

or with EDMA the request operation will fail for EDMA channel
can only be requested once.

So If we can reuse the dma channel of Back-End, then the issue can be
fixed.

In order to get the dma channel which is already requested in Back-End.
we use the exported two functions (snd_soc_lookup_component_nolocked
and soc_component_to_pcm). If we can get the dma channel, then reuse it,
if can't, then request a new one.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_asrc_common.h |  2 ++
 sound/soc/fsl/fsl_asrc_dma.c| 52 +
 2 files changed, 42 insertions(+), 12 deletions(-)

diff --git a/sound/soc/fsl/fsl_asrc_common.h b/sound/soc/fsl/fsl_asrc_common.h
index 77665b15c8db..09512bc79b80 100644
--- a/sound/soc/fsl/fsl_asrc_common.h
+++ b/sound/soc/fsl/fsl_asrc_common.h
@@ -32,6 +32,7 @@ enum asrc_pair_index {
  * @dma_chan: inputer and output DMA channels
  * @dma_data: private dma data
  * @pos: hardware pointer position
+ * @req_dma_chan_dev_to_dev: flag for release dev_to_dev chan
  * @private: pair private area
  */
 struct fsl_asrc_pair {
@@ -45,6 +46,7 @@ struct fsl_asrc_pair {
struct dma_chan *dma_chan[2];
struct imx_dma_data dma_data;
unsigned int pos;
+   bool req_dma_chan_dev_to_dev;
 
void *private;
 };
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
index d6a3fc5f87e5..5ecb77d466d3 100644
--- a/sound/soc/fsl/fsl_asrc_dma.c
+++ b/sound/soc/fsl/fsl_asrc_dma.c
@@ -133,6 +133,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component 
*component,
bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
struct snd_dmaengine_dai_dma_data *dma_params_fe = NULL;
struct snd_dmaengine_dai_dma_data *dma_params_be = NULL;
+   struct dma_chan *tmp_chan = NULL, *tmp_chan_new = NULL;
struct snd_pcm_runtime *runtime = substream->runtime;
struct fsl_asrc_pair *pair = runtime->private_data;
struct fsl_asrc *asrc = pair->asrc;
@@ -142,7 +143,6 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component 
*component,
int stream = substream->stream;
struct imx_dma_data *tmp_data;
struct snd_soc_dpcm *dpcm;
-   struct dma_chan *tmp_chan;
struct device *dev_be;
u8 dir = tx ? OUT : IN;
dma_cap_mask_t mask;
@@ -152,6 +152,7 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component 
*component,
for_each_dpcm_be(rtd, stream, dpcm) {
struct snd_soc_pcm_runtime *be = dpcm->be;
struct snd_pcm_substream *substream_be;
+   struct snd_soc_component *component_be;
struct snd_soc_dai *dai = asoc_rtd_to_cpu(be, 0);
 
if (dpcm->fe != rtd)
@@ -160,6 +161,9 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component 
*component,
substream_be = snd_soc_dpcm_get_substream(be, stream);
dma_params_be = snd_soc_dai_get_dma_data(dai, substream_be);
dev_be = dai->dev;
+   component_be = snd_soc_lookup_component_nolocked(dev_be, 
SND_DMAENGINE_PCM_DRV_NAME);
+   if (component_be)
+   tmp_chan = 
soc_component_to_pcm(component_be)->chan[substream->stream];
break;
}
 
@@ -205,10 +209,14 @@ static int fsl_asrc_dma_hw_params(struct 
snd_soc_component *component,
 */
if (!asrc->use_edma) {
/* Get DMA request of Back-End */
-   tmp_chan = dma_request_slave_channel(dev_be, tx ? "tx" : "rx");
+   if (!tmp_chan) {
+   tmp_chan_new = dma_request_slave_channel(dev_be, tx ? 
"tx" : "rx");
+   tmp_chan = tmp_chan_new;
+   }
tmp_data = tmp_chan->private;
pair->dma_data.dma_request = tmp_data->dma_request;
-   dma_release_channel(tmp_chan);
+   if (tmp_chan_new)
+   dma_release_channel(tmp_chan_new);
 
/* Get DMA request of Front-End */
tmp_chan = asrc->get_dma_channel(pair, dir);
@@ -220,9 +228,26 @@ static int fsl_asrc_dma_hw_params(struct snd_soc_component 
*component,
 
pair->dma_chan[dir] =
dma_request_channel(mask, filter, >dma_data);
+   pair->req_dma_chan_dev_to_dev = true;
} else {
-   pair->dma_chan[dir] =
-   asrc->get_dma_channel(pair, dir);
+   /*
+* With EDMA, there is two dma channels can be used for p2p,
+* one is from ASRC, one is fr

[RFC PATCH v2 2/3] ASoC: dmaengine_pcm: export soc_component_to_pcm

2020-06-10 Thread Shengjiu Wang
In DPCM case, Front-End needs to get the dma chan which has
been requested by Back-End and reuse it.

Signed-off-by: Shengjiu Wang 
---
 include/sound/dmaengine_pcm.h | 11 +++
 sound/soc/soc-generic-dmaengine-pcm.c | 12 
 2 files changed, 11 insertions(+), 12 deletions(-)

diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h
index b65220685920..8c5e38180fb0 100644
--- a/include/sound/dmaengine_pcm.h
+++ b/include/sound/dmaengine_pcm.h
@@ -161,4 +161,15 @@ int snd_dmaengine_pcm_prepare_slave_config(struct 
snd_pcm_substream *substream,
 
 #define SND_DMAENGINE_PCM_DRV_NAME "snd_dmaengine_pcm"
 
+struct dmaengine_pcm {
+   struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
+   const struct snd_dmaengine_pcm_config *config;
+   struct snd_soc_component component;
+   unsigned int flags;
+};
+
+static inline struct dmaengine_pcm *soc_component_to_pcm(struct 
snd_soc_component *p)
+{
+   return container_of(p, struct dmaengine_pcm, component);
+}
 #endif
diff --git a/sound/soc/soc-generic-dmaengine-pcm.c 
b/sound/soc/soc-generic-dmaengine-pcm.c
index f728309a0833..80a4e71f2d95 100644
--- a/sound/soc/soc-generic-dmaengine-pcm.c
+++ b/sound/soc/soc-generic-dmaengine-pcm.c
@@ -21,18 +21,6 @@
  */
 #define SND_DMAENGINE_PCM_FLAG_NO_RESIDUE BIT(31)
 
-struct dmaengine_pcm {
-   struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
-   const struct snd_dmaengine_pcm_config *config;
-   struct snd_soc_component component;
-   unsigned int flags;
-};
-
-static struct dmaengine_pcm *soc_component_to_pcm(struct snd_soc_component *p)
-{
-   return container_of(p, struct dmaengine_pcm, component);
-}
-
 static struct device *dmaengine_dma_dev(struct dmaengine_pcm *pcm,
struct snd_pcm_substream *substream)
 {
-- 
2.21.0



[RFC PATCH v2 0/3] ASoC: fsl_asrc_dma: Reuse the dma channel if available in Back-End

2020-06-10 Thread Shengjiu Wang
Reuse the dma channel if available in Back-End

Shengjiu Wang (3):
  ASoC: soc-card: export snd_soc_lookup_component_nolocked
  ASoC: dmaengine_pcm: export soc_component_to_pcm
  ASoC: fsl_asrc_dma: Reuse the dma channel if available in Back-End

changes in v2:
- update according to Mark's comments and split the patch


 include/sound/dmaengine_pcm.h | 11 ++
 include/sound/soc.h   |  2 ++
 sound/soc/fsl/fsl_asrc_common.h   |  2 ++
 sound/soc/fsl/fsl_asrc_dma.c  | 52 ---
 sound/soc/soc-core.c  |  3 +-
 sound/soc/soc-generic-dmaengine-pcm.c | 12 ---
 6 files changed, 57 insertions(+), 25 deletions(-)

-- 
2.21.0



[RFC PATCH v2 1/3] ASoC: soc-card: export snd_soc_lookup_component_nolocked

2020-06-10 Thread Shengjiu Wang
snd_soc_lookup_component_nolocked can be used for the DPCM case
that Front-End needs to get the unused platform component but
added by Back-End cpu dai driver.

If the component is gotten, then we can get the dma chan created
by Back-End component and reused it in Front-End.

Signed-off-by: Shengjiu Wang 
---
 include/sound/soc.h  | 2 ++
 sound/soc/soc-core.c | 3 ++-
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/include/sound/soc.h b/include/sound/soc.h
index 74868436ac79..565612a8d690 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -444,6 +444,8 @@ int devm_snd_soc_register_component(struct device *dev,
 const struct snd_soc_component_driver 
*component_driver,
 struct snd_soc_dai_driver *dai_drv, int num_dai);
 void snd_soc_unregister_component(struct device *dev);
+struct snd_soc_component *snd_soc_lookup_component_nolocked(struct device *dev,
+   const char 
*driver_name);
 struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
   const char *driver_name);
 
diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c
index b07eca2c6ccc..d4c73e86d058 100644
--- a/sound/soc/soc-core.c
+++ b/sound/soc/soc-core.c
@@ -310,7 +310,7 @@ struct snd_soc_component *snd_soc_rtdcom_lookup(struct 
snd_soc_pcm_runtime *rtd,
 }
 EXPORT_SYMBOL_GPL(snd_soc_rtdcom_lookup);
 
-static struct snd_soc_component
+struct snd_soc_component
 *snd_soc_lookup_component_nolocked(struct device *dev, const char *driver_name)
 {
struct snd_soc_component *component;
@@ -329,6 +329,7 @@ static struct snd_soc_component
 
return found_component;
 }
+EXPORT_SYMBOL_GPL(snd_soc_lookup_component_nolocked);
 
 struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
   const char *driver_name)
-- 
2.21.0



[PATCH] ASoC: fsl_ssi: Fix bclk calculation for mono channel

2020-06-09 Thread Shengjiu Wang
For mono channel, ssi will switch to normal mode. In normal
mode, the Word Length Control bits control the word length
divider in clock generator, which is different with I2S master
mode, the word length is fixed to 32bit.

So we refine the famula for mono channel, otherwise there
will be sound issue for S24_LE.

Fixes: b0a7043d5c2c ("ASoC: fsl_ssi: Caculate bit clock rate using slot number 
and width")
Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_ssi.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/sound/soc/fsl/fsl_ssi.c b/sound/soc/fsl/fsl_ssi.c
index bad89b0d129e..e347776590f7 100644
--- a/sound/soc/fsl/fsl_ssi.c
+++ b/sound/soc/fsl/fsl_ssi.c
@@ -695,6 +695,11 @@ static int fsl_ssi_set_bclk(struct snd_pcm_substream 
*substream,
/* Generate bit clock based on the slot number and slot width */
freq = slots * slot_width * params_rate(hw_params);
 
+   /* The slot_width is not fixed to 32 for normal mode */
+   if (params_channels(hw_params) == 1)
+   freq = (slots <= 1 ? 2 : slots) * params_width(hw_params) *
+  params_rate(hw_params);
+
/* Don't apply it to any non-baudclk circumstance */
if (IS_ERR(ssi->baudclk))
return -EINVAL;
-- 
2.21.0



[RFC PATCH] ASoC: fsl_asrc_dma: Fix warning "Cannot create DMA dma:tx symlink"

2020-06-08 Thread Shengjiu Wang
The issue log is:

[   48.021506] CPU: 0 PID: 664 Comm: aplay Not tainted 
5.7.0-rc1-13120-g12b434cbbea0 #343
[   48.031063] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
[   48.037638] [] (unwind_backtrace) from [] 
(show_stack+0x10/0x14)
[   48.045413] [] (show_stack) from [] 
(dump_stack+0xe4/0x118)
[   48.052757] [] (dump_stack) from [] 
(sysfs_warn_dup+0x50/0x64)
[   48.060357] [] (sysfs_warn_dup) from [] 
(sysfs_do_create_link_sd+0xc8/0xd4)
[   48.069086] [] (sysfs_do_create_link_sd) from [] 
(dma_request_chan+0xb0/0x210)
[   48.078068] [] (dma_request_chan) from [] 
(dma_request_slave_channel+0x8/0x14)
[   48.087060] [] (dma_request_slave_channel) from [] 
(fsl_asrc_dma_hw_params+0x1dc/0x434)
[   48.096831] [] (fsl_asrc_dma_hw_params) from [] 
(soc_pcm_hw_params+0x4b0/0x650)
[   48.105903] [] (soc_pcm_hw_params) from [] 
(dpcm_fe_dai_hw_params+0x70/0xe4)
[   48.114715] [] (dpcm_fe_dai_hw_params) from [] 
(snd_pcm_hw_params+0x158/0x418)
[   48.123701] [] (snd_pcm_hw_params) from [] 
(snd_pcm_ioctl+0x734/0x183c)
[   48.132079] [] (snd_pcm_ioctl) from [] 
(ksys_ioctl+0x2ac/0xb98)
[   48.139765] [] (ksys_ioctl) from [] 
(ret_fast_syscall+0x0/0x28)
[   48.147440] Exception stack(0xed3c5fa8 to 0xed3c5ff0)
[   48.152515] 5fa0:   bec28670 00e92870 0004 c25c4111 
bec28670 0002000f
[   48.160716] 5fc0: bec28670 00e92870 00e92820 0036 bb80  
0002c2f8 0003
[   48.168913] 5fe0: b6f4d3fc bec2853c b6ee7655 b6e22cf8
[   48.174236] fsl-esai-dai 2024000.esai: Cannot create DMA dma:tx symlink

The dma channel is already requested by Back-End cpu dai driver,
if fsl_asrc_dma requests dma chan with same dma:tx symlink, then
this warning comes out.

The warning is added by
commit 71723a96b8b1 ("dmaengine: Create symlinks between DMA channels and 
slaves")
commit bad83565eafe ("dmaengine: Cleanups for the slave <-> channel symlink 
support")

As the dma channel is requested by Back-End, we need to reuse the channel
and avoid to request a new one, then the issue can be fixed.

In order to get the dma channel which is already requested in Back-End.
we export two functions (snd_soc_lookup_component_nolocked and
soc_component_to_pcm), if we can get the dma channel, then reuse it.
if can't, then request a new one.

Signed-off-by: Shengjiu Wang 
---
 include/sound/dmaengine_pcm.h | 11 ++
 include/sound/soc.h   |  2 ++
 sound/soc/fsl/fsl_asrc_common.h   |  2 ++
 sound/soc/fsl/fsl_asrc_dma.c  | 49 +--
 sound/soc/soc-core.c  |  3 +-
 sound/soc/soc-generic-dmaengine-pcm.c | 12 ---
 6 files changed, 55 insertions(+), 24 deletions(-)

diff --git a/include/sound/dmaengine_pcm.h b/include/sound/dmaengine_pcm.h
index b65220685920..8c5e38180fb0 100644
--- a/include/sound/dmaengine_pcm.h
+++ b/include/sound/dmaengine_pcm.h
@@ -161,4 +161,15 @@ int snd_dmaengine_pcm_prepare_slave_config(struct 
snd_pcm_substream *substream,
 
 #define SND_DMAENGINE_PCM_DRV_NAME "snd_dmaengine_pcm"
 
+struct dmaengine_pcm {
+   struct dma_chan *chan[SNDRV_PCM_STREAM_LAST + 1];
+   const struct snd_dmaengine_pcm_config *config;
+   struct snd_soc_component component;
+   unsigned int flags;
+};
+
+static inline struct dmaengine_pcm *soc_component_to_pcm(struct 
snd_soc_component *p)
+{
+   return container_of(p, struct dmaengine_pcm, component);
+}
 #endif
diff --git a/include/sound/soc.h b/include/sound/soc.h
index 74868436ac79..565612a8d690 100644
--- a/include/sound/soc.h
+++ b/include/sound/soc.h
@@ -444,6 +444,8 @@ int devm_snd_soc_register_component(struct device *dev,
 const struct snd_soc_component_driver 
*component_driver,
 struct snd_soc_dai_driver *dai_drv, int num_dai);
 void snd_soc_unregister_component(struct device *dev);
+struct snd_soc_component *snd_soc_lookup_component_nolocked(struct device *dev,
+   const char 
*driver_name);
 struct snd_soc_component *snd_soc_lookup_component(struct device *dev,
   const char *driver_name);
 
diff --git a/sound/soc/fsl/fsl_asrc_common.h b/sound/soc/fsl/fsl_asrc_common.h
index 77665b15c8db..09512bc79b80 100644
--- a/sound/soc/fsl/fsl_asrc_common.h
+++ b/sound/soc/fsl/fsl_asrc_common.h
@@ -32,6 +32,7 @@ enum asrc_pair_index {
  * @dma_chan: inputer and output DMA channels
  * @dma_data: private dma data
  * @pos: hardware pointer position
+ * @req_dma_chan_dev_to_dev: flag for release dev_to_dev chan
  * @private: pair private area
  */
 struct fsl_asrc_pair {
@@ -45,6 +46,7 @@ struct fsl_asrc_pair {
struct dma_chan *dma_chan[2];
struct imx_dma_data dma_data;
unsigned int pos;
+   bool req_dma_chan_dev_to_dev;
 
void *private;
 };
diff --git a/sound/soc/fsl/fsl_asrc_dma.c b/sound/soc/fsl/fsl_asrc_dma.c
index d6a3fc5f87e5..3ad

[PATCH] ASoC: fsl-asoc-card: Defer probe when fail to find codec device

2020-06-04 Thread Shengjiu Wang
Defer probe when fail to find codec device, because the codec
device maybe probed later than machine driver.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl-asoc-card.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/fsl/fsl-asoc-card.c b/sound/soc/fsl/fsl-asoc-card.c
index cf4feb835743..00be73900888 100644
--- a/sound/soc/fsl/fsl-asoc-card.c
+++ b/sound/soc/fsl/fsl-asoc-card.c
@@ -581,7 +581,7 @@ static int fsl_asoc_card_probe(struct platform_device *pdev)
 
if (!fsl_asoc_card_is_ac97(priv) && !codec_dev) {
dev_err(>dev, "failed to find codec device\n");
-   ret = -EINVAL;
+   ret = -EPROBE_DEFER;
goto asrc_fail;
}
 
-- 
2.21.0



[PATCH 3/3] ASoC: fsl_easrc: Fix "Function parameter not described" warnings

2020-06-02 Thread Shengjiu Wang
Obtained with:
$ make W=1

sound/soc/fsl/fsl_easrc.c:403: warning: Function parameter or member 'easrc' 
not described in 'fsl_easrc_normalize_filter'
sound/soc/fsl/fsl_easrc.c:403: warning: Function parameter or member 'infilter' 
not described in 'fsl_easrc_normalize_filter'
sound/soc/fsl/fsl_easrc.c:403: warning: Function parameter or member 
'outfilter' not described in 'fsl_easrc_normalize_filter'
sound/soc/fsl/fsl_easrc.c:403: warning: Function parameter or member 'shift' 
not described in 'fsl_easrc_normalize_filter'

Fixes: 955ac624058f ("ASoC: fsl_easrc: Add EASRC ASoC CPU DAI drivers")
Signed-off-by: Shengjiu Wang 
Reported-by: kbuild test robot 
---
 sound/soc/fsl/fsl_easrc.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index 7d8bf9d47842..2f6b3d8bfcfc 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -389,11 +389,11 @@ static int fsl_easrc_resampler_config(struct fsl_asrc 
*easrc)
  *  For input int[16, 24, 32] -> output float32
  *  scale it by multiplying filter coefficients by 2^-15, 2^-23, 2^-31
  *  input:
- *  asrc:  Structure pointer of fsl_asrc
- *  infilter : Pointer to non-scaled input filter
- *  shift:  The multiply factor
+ *  @easrc:  Structure pointer of fsl_asrc
+ *  @infilter : Pointer to non-scaled input filter
+ *  @shift:  The multiply factor
  *  output:
- *  outfilter: scaled filter
+ *  @outfilter: scaled filter
  */
 static int fsl_easrc_normalize_filter(struct fsl_asrc *easrc,
  u64 *infilter,
-- 
2.21.0



[PATCH 2/3] ASoC: fsl_easrc: Fix -Wunused-but-set-variable

2020-06-02 Thread Shengjiu Wang
Obtained with:
$ make W=1

sound/soc/fsl/fsl_easrc.c: In function 'fsl_easrc_set_rs_ratio':
sound/soc/fsl/fsl_easrc.c:182:15: warning: variable 'int_bits' set but not used 
[-Wunused-but-set-variable]
  unsigned int int_bits;
   ^
sound/soc/fsl/fsl_easrc.c: In function 'fsl_easrc_set_ctx_organziation':
sound/soc/fsl/fsl_easrc.c:1204:17: warning: variable 'dev' set but not used 
[-Wunused-but-set-variable]
  struct device *dev;
 ^
sound/soc/fsl/fsl_easrc.c: In function 'fsl_easrc_release_context':
sound/soc/fsl/fsl_easrc.c:1294:17: warning: variable 'dev' set but not used 
[-Wunused-but-set-variable]
  struct device *dev;
 ^
Fixes: 955ac624058f ("ASoC: fsl_easrc: Add EASRC ASoC CPU DAI drivers")
Signed-off-by: Shengjiu Wang 
Reported-by: kbuild test robot 
---
 sound/soc/fsl/fsl_easrc.c | 11 +++
 1 file changed, 3 insertions(+), 8 deletions(-)

diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index f227308a50e2..7d8bf9d47842 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -179,22 +179,21 @@ static int fsl_easrc_set_rs_ratio(struct fsl_asrc_pair 
*ctx)
struct fsl_easrc_ctx_priv *ctx_priv = ctx->private;
unsigned int in_rate = ctx_priv->in_params.norm_rate;
unsigned int out_rate = ctx_priv->out_params.norm_rate;
-   unsigned int int_bits;
unsigned int frac_bits;
u64 val;
u32 *r;
 
switch (easrc_priv->rs_num_taps) {
case EASRC_RS_32_TAPS:
-   int_bits = 5;
+   /* integer bits = 5; */
frac_bits = 39;
break;
case EASRC_RS_64_TAPS:
-   int_bits = 6;
+   /* integer bits = 6; */
frac_bits = 38;
break;
case EASRC_RS_128_TAPS:
-   int_bits = 7;
+   /* integer bits = 7; */
frac_bits = 37;
break;
default:
@@ -1201,7 +1200,6 @@ static int fsl_easrc_set_ctx_format(struct fsl_asrc_pair 
*ctx,
 static int fsl_easrc_set_ctx_organziation(struct fsl_asrc_pair *ctx)
 {
struct fsl_easrc_ctx_priv *ctx_priv;
-   struct device *dev;
struct fsl_asrc *easrc;
 
if (!ctx)
@@ -1209,7 +1207,6 @@ static int fsl_easrc_set_ctx_organziation(struct 
fsl_asrc_pair *ctx)
 
easrc = ctx->asrc;
ctx_priv = ctx->private;
-   dev = >pdev->dev;
 
/* input interleaving parameters */
regmap_update_bits(easrc->regmap, REG_EASRC_CIA(ctx->index),
@@ -1291,13 +1288,11 @@ static void fsl_easrc_release_context(struct 
fsl_asrc_pair *ctx)
 {
unsigned long lock_flags;
struct fsl_asrc *easrc;
-   struct device *dev;
 
if (!ctx)
return;
 
easrc = ctx->asrc;
-   dev = >pdev->dev;
 
spin_lock_irqsave(>lock, lock_flags);
 
-- 
2.21.0



[PATCH 0/3] ASoC: fsl_easrc: Fix several warnings

2020-06-02 Thread Shengjiu Wang
Fix several warnings with "make W=1"

Shengjiu Wang (3):
  ASoC: fsl_easrc: Fix -Wmissing-prototypes warning
  ASoC: fsl_easrc: Fix -Wunused-but-set-variable
  ASoC: fsl_easrc: Fix "Function parameter not described" warnings

 sound/soc/fsl/fsl_easrc.c | 42 +--
 1 file changed, 18 insertions(+), 24 deletions(-)

-- 
2.21.0



[PATCH 1/3] ASoC: fsl_easrc: Fix -Wmissing-prototypes warning

2020-06-02 Thread Shengjiu Wang
Obtained with:
$ make W=1

sound/soc/fsl/fsl_easrc.c:967:5: warning: no previous prototype for function 
'fsl_easrc_config_context' [-Wmissing-prototypes]
int fsl_easrc_config_context(struct fsl_asrc *easrc, unsigned int ctx_id)
^
sound/soc/fsl/fsl_easrc.c:967:1: note: declare 'static' if the function is not 
intended to be used outside of this translation unit
int fsl_easrc_config_context(struct fsl_asrc *easrc, unsigned int ctx_id)
^
static
sound/soc/fsl/fsl_easrc.c:1128:5: warning: no previous prototype for function 
'fsl_easrc_set_ctx_format' [-Wmissing-prototypes]
int fsl_easrc_set_ctx_format(struct fsl_asrc_pair *ctx,
^
sound/soc/fsl/fsl_easrc.c:1128:1: note: declare 'static' if the function is not 
intended to be used outside of this translation unit
int fsl_easrc_set_ctx_format(struct fsl_asrc_pair *ctx,
^
static
sound/soc/fsl/fsl_easrc.c:1201:5: warning: no previous prototype for function 
'fsl_easrc_set_ctx_organziation' [-Wmissing-prototypes]
int fsl_easrc_set_ctx_organziation(struct fsl_asrc_pair *ctx)
^
sound/soc/fsl/fsl_easrc.c:1201:1: note: declare 'static' if the function is not 
intended to be used outside of this translation unit
int fsl_easrc_set_ctx_organziation(struct fsl_asrc_pair *ctx)
^
static
sound/soc/fsl/fsl_easrc.c:1245:5: warning: no previous prototype for function 
'fsl_easrc_request_context' [-Wmissing-prototypes]
int fsl_easrc_request_context(int channels, struct fsl_asrc_pair *ctx)
^
sound/soc/fsl/fsl_easrc.c:1245:1: note: declare 'static' if the function is not 
intended to be used outside of this translation unit
int fsl_easrc_request_context(int channels, struct fsl_asrc_pair *ctx)
^
static
sound/soc/fsl/fsl_easrc.c:1290:6: warning: no previous prototype for function 
'fsl_easrc_release_context' [-Wmissing-prototypes]
void fsl_easrc_release_context(struct fsl_asrc_pair *ctx)
 ^
sound/soc/fsl/fsl_easrc.c:1290:1: note: declare 'static' if the function is not 
intended to be used outside of this translation unit
void fsl_easrc_release_context(struct fsl_asrc_pair *ctx)
^
static
sound/soc/fsl/fsl_easrc.c:1317:5: warning: no previous prototype for function 
'fsl_easrc_start_context' [-Wmissing-prototypes]
int fsl_easrc_start_context(struct fsl_asrc_pair *ctx)
^
sound/soc/fsl/fsl_easrc.c:1317:1: note: declare 'static' if the function is not 
intended to be used outside of this translation unit
int fsl_easrc_start_context(struct fsl_asrc_pair *ctx)
^
static
sound/soc/fsl/fsl_easrc.c:1335:5: warning: no previous prototype for function 
'fsl_easrc_stop_context' [-Wmissing-prototypes]
int fsl_easrc_stop_context(struct fsl_asrc_pair *ctx)
^
sound/soc/fsl/fsl_easrc.c:1335:1: note: declare 'static' if the function is not 
intended to be used outside of this translation unit
int fsl_easrc_stop_context(struct fsl_asrc_pair *ctx)
^
static
sound/soc/fsl/fsl_easrc.c:1382:18: warning: no previous prototype for function 
'fsl_easrc_get_dma_channel' [-Wmissing-prototypes]
struct dma_chan *fsl_easrc_get_dma_channel(struct fsl_asrc_pair *ctx,
 ^
sound/soc/fsl/fsl_easrc.c:1382:1: note: declare 'static' if the function is not 
intended to be used outside of this translation unit
struct dma_chan *fsl_easrc_get_dma_channel(struct fsl_asrc_pair *ctx,
^
static

Fixes: 955ac624058f ("ASoC: fsl_easrc: Add EASRC ASoC CPU DAI drivers")
Signed-off-by: Shengjiu Wang 
Reported-by: kbuild test robot 
---
 sound/soc/fsl/fsl_easrc.c | 23 +++
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
index c6b5eb2d2af7..f227308a50e2 100644
--- a/sound/soc/fsl/fsl_easrc.c
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -964,7 +964,7 @@ static int fsl_easrc_release_slot(struct fsl_asrc *easrc, 
unsigned int ctx_id)
  *
  * Configure the register relate with context.
  */
-int fsl_easrc_config_context(struct fsl_asrc *easrc, unsigned int ctx_id)
+static int fsl_easrc_config_context(struct fsl_asrc *easrc, unsigned int 
ctx_id)
 {
struct fsl_easrc_ctx_priv *ctx_priv;
struct fsl_asrc_pair *ctx;
@@ -1125,9 +1125,9 @@ static int fsl_easrc_process_format(struct fsl_asrc_pair 
*ctx,
return 0;
 }
 
-int fsl_easrc_set_ctx_format(struct fsl_asrc_pair *ctx,
-snd_pcm_format_t *in_raw_format,
-snd_pcm_format_t *out_raw_format)
+static int fsl_easrc_set_ctx_format(struct fsl_asrc_pair *ctx,
+   snd_pcm_format_t *in_raw_format,
+   snd_pcm_format_t *out_raw_format)
 {
struct fsl_asrc *easrc = ctx->asrc;
struct fsl_easrc_ctx_priv *ctx_priv = ctx->private;
@@ -1198,7 +1198,7 @@ int fsl_easrc_set_ctx_format(struct fsl_asrc_pair *ctx,
  * to conform with this format. Interleaving parameters are accessed
  * through the ASRC_CTRL_IN_ACCESSa and ASRC_CTRL_OUT_ACCESSa registers
  */
-int fsl_easrc_set_ctx_organziation(struct fsl_asrc_pair *

[PATCH] ASoC: fsl_asrc: Fix -Wmissing-prototypes warning

2020-05-25 Thread Shengjiu Wang
From: shengjiu wang 

COMPILER_INSTALL_PATH=$HOME/0day COMPILER=clang make.cross ARCH=x86_64

sound/soc/fsl/fsl_asrc.c:557:18: warning: no previous prototype for function 
'fsl_asrc_get_dma_channel' [-Wmissing-prototypes]
struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair, bool dir)
 ^
sound/soc/fsl/fsl_asrc.c:557:1: note: declare 'static' if the function is not 
intended to be used outside of this translation unit
struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair, bool dir)
^
static

Fixes: be7bd03f0201 ("ASoC: fsl_asrc: Move common definition to 
fsl_asrc_common")
Reported-by: kbuild test robot 
Signed-off-by: shengjiu wang 
---
 sound/soc/fsl/fsl_asrc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 7e2d598ffb81..d79d2c7f8d36 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -554,7 +554,8 @@ static void fsl_asrc_stop_pair(struct fsl_asrc_pair *pair)
 /**
  * Get DMA channel according to the pair and direction.
  */
-struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair, bool dir)
+static struct dma_chan *fsl_asrc_get_dma_channel(struct fsl_asrc_pair *pair,
+bool dir)
 {
struct fsl_asrc *asrc = pair->asrc;
enum asrc_pair_index index = pair->index;
@@ -564,7 +565,6 @@ struct dma_chan *fsl_asrc_get_dma_channel(struct 
fsl_asrc_pair *pair, bool dir)
 
return dma_request_slave_channel(>pdev->dev, name);
 }
-EXPORT_SYMBOL_GPL(fsl_asrc_get_dma_channel);
 
 static int fsl_asrc_dai_startup(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
-- 
2.21.0



Re: [PATCH] ASoC: fsl_asrc: Merge suspend/resume function to runtime_suspend/resume

2020-05-25 Thread Shengjiu Wang
On Mon, May 25, 2020 at 1:12 PM Nicolin Chen  wrote:
>
> On Fri, May 22, 2020 at 05:57:24PM +0800, Shengjiu Wang wrote:
> > With dedicated power domain for asrc, power can be disabled after
> > probe and pm runtime suspend, then the value of all registers need to
> > be restored in pm runtime resume. So we can merge suspend/resume function
> > to runtime_suspend/resume function and enable regcache only in end of
> > probe.
> >
> > Signed-off-by: Shengjiu Wang 
> > ---
> >  sound/soc/fsl/fsl_asrc.c | 70 
> >  1 file changed, 27 insertions(+), 43 deletions(-)
> >
> > diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
> > index 432936039de4..3ebbe15ac378 100644
> > --- a/sound/soc/fsl/fsl_asrc.c
> > +++ b/sound/soc/fsl/fsl_asrc.c
> > @@ -1100,6 +1100,7 @@ static int fsl_asrc_probe(struct platform_device 
> > *pdev)
> >   platform_set_drvdata(pdev, asrc);
> >   pm_runtime_enable(>dev);
> >   spin_lock_init(>lock);
> > + regcache_cache_only(asrc->regmap, true);
> >
> >   ret = devm_snd_soc_register_component(>dev, _asrc_component,
> > _asrc_dai, 1);
> > @@ -1117,6 +1118,7 @@ static int fsl_asrc_runtime_resume(struct device *dev)
> >   struct fsl_asrc *asrc = dev_get_drvdata(dev);
> >   struct fsl_asrc_priv *asrc_priv = asrc->private;
> >   int i, ret;
> > + u32 asrctr;
> >
> >   ret = clk_prepare_enable(asrc->mem_clk);
> >   if (ret)
> > @@ -1135,6 +1137,24 @@ static int fsl_asrc_runtime_resume(struct device 
> > *dev)
> >   goto disable_asrck_clk;
> >   }
> >
> > + /* Stop all pairs provisionally */
> > + regmap_read(asrc->regmap, REG_ASRCTR, );
> > + regmap_update_bits(asrc->regmap, REG_ASRCTR,
> > +ASRCTR_ASRCEi_ALL_MASK, 0);
> > +
> > + /* Restore all registers */
> > + regcache_cache_only(asrc->regmap, false);
> > + regcache_mark_dirty(asrc->regmap);
>
>
> I see you doing regcache_mark_dirty() in the resume() now,
> being different from previously doing in suspend()?
>
> Thanks
> Nic

Which is for probe -> runtime_resume case.
After probe, the power may be disabled, so move mark_dirtry
to runtime_resume, then regcache can re-write all the registers.

best regards
wang shengjiu

>
>
> > + regcache_sync(asrc->regmap);
> > +
> > + regmap_update_bits(asrc->regmap, REG_ASRCFG,
> > +ASRCFG_NDPRi_ALL_MASK | ASRCFG_POSTMODi_ALL_MASK |
> > +ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg);
> > +
> > + /* Restart enabled pairs */
> > + regmap_update_bits(asrc->regmap, REG_ASRCTR,
> > +ASRCTR_ASRCEi_ALL_MASK, asrctr);
> > +
> >   return 0;
> >
> >  disable_asrck_clk:
> > @@ -1155,6 +1175,11 @@ static int fsl_asrc_runtime_suspend(struct device 
> > *dev)
> >   struct fsl_asrc_priv *asrc_priv = asrc->private;
> >   int i;
> >
> > + regmap_read(asrc->regmap, REG_ASRCFG,
> > + _priv->regcache_cfg);
> > +
> > + regcache_cache_only(asrc->regmap, true);
> > +
> >   for (i = 0; i < ASRC_CLK_MAX_NUM; i++)
> >   clk_disable_unprepare(asrc_priv->asrck_clk[i]);
> >   if (!IS_ERR(asrc->spba_clk))
> > @@ -1166,51 +1191,10 @@ static int fsl_asrc_runtime_suspend(struct device 
> > *dev)
> >  }
> >  #endif /* CONFIG_PM */
> >
> > -#ifdef CONFIG_PM_SLEEP
> > -static int fsl_asrc_suspend(struct device *dev)
> > -{
> > - struct fsl_asrc *asrc = dev_get_drvdata(dev);
> > - struct fsl_asrc_priv *asrc_priv = asrc->private;
> > -
> > - regmap_read(asrc->regmap, REG_ASRCFG,
> > - _priv->regcache_cfg);
> > -
> > - regcache_cache_only(asrc->regmap, true);
> > - regcache_mark_dirty(asrc->regmap);
> > -
> > - return 0;
> > -}
> > -
> > -static int fsl_asrc_resume(struct device *dev)
> > -{
> > - struct fsl_asrc *asrc = dev_get_drvdata(dev);
> > - struct fsl_asrc_priv *asrc_priv = asrc->private;
> > - u32 asrctr;
> > -
> > - /* Stop all pairs provisionally */
> > - regmap_read(asrc->regmap, REG_ASRCTR, );
> > - regmap_update_bits(asrc->regmap, REG_ASRCTR,
> > -ASRCTR_ASRCEi_ALL_MASK, 0);
&g

[PATCH] ASoC: fsl_asrc: Merge suspend/resume function to runtime_suspend/resume

2020-05-22 Thread Shengjiu Wang
With dedicated power domain for asrc, power can be disabled after
probe and pm runtime suspend, then the value of all registers need to
be restored in pm runtime resume. So we can merge suspend/resume function
to runtime_suspend/resume function and enable regcache only in end of
probe.

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/fsl_asrc.c | 70 
 1 file changed, 27 insertions(+), 43 deletions(-)

diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 432936039de4..3ebbe15ac378 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -1100,6 +1100,7 @@ static int fsl_asrc_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, asrc);
pm_runtime_enable(>dev);
spin_lock_init(>lock);
+   regcache_cache_only(asrc->regmap, true);
 
ret = devm_snd_soc_register_component(>dev, _asrc_component,
  _asrc_dai, 1);
@@ -1117,6 +1118,7 @@ static int fsl_asrc_runtime_resume(struct device *dev)
struct fsl_asrc *asrc = dev_get_drvdata(dev);
struct fsl_asrc_priv *asrc_priv = asrc->private;
int i, ret;
+   u32 asrctr;
 
ret = clk_prepare_enable(asrc->mem_clk);
if (ret)
@@ -1135,6 +1137,24 @@ static int fsl_asrc_runtime_resume(struct device *dev)
goto disable_asrck_clk;
}
 
+   /* Stop all pairs provisionally */
+   regmap_read(asrc->regmap, REG_ASRCTR, );
+   regmap_update_bits(asrc->regmap, REG_ASRCTR,
+  ASRCTR_ASRCEi_ALL_MASK, 0);
+
+   /* Restore all registers */
+   regcache_cache_only(asrc->regmap, false);
+   regcache_mark_dirty(asrc->regmap);
+   regcache_sync(asrc->regmap);
+
+   regmap_update_bits(asrc->regmap, REG_ASRCFG,
+  ASRCFG_NDPRi_ALL_MASK | ASRCFG_POSTMODi_ALL_MASK |
+  ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg);
+
+   /* Restart enabled pairs */
+   regmap_update_bits(asrc->regmap, REG_ASRCTR,
+  ASRCTR_ASRCEi_ALL_MASK, asrctr);
+
return 0;
 
 disable_asrck_clk:
@@ -1155,6 +1175,11 @@ static int fsl_asrc_runtime_suspend(struct device *dev)
struct fsl_asrc_priv *asrc_priv = asrc->private;
int i;
 
+   regmap_read(asrc->regmap, REG_ASRCFG,
+   _priv->regcache_cfg);
+
+   regcache_cache_only(asrc->regmap, true);
+
for (i = 0; i < ASRC_CLK_MAX_NUM; i++)
clk_disable_unprepare(asrc_priv->asrck_clk[i]);
if (!IS_ERR(asrc->spba_clk))
@@ -1166,51 +1191,10 @@ static int fsl_asrc_runtime_suspend(struct device *dev)
 }
 #endif /* CONFIG_PM */
 
-#ifdef CONFIG_PM_SLEEP
-static int fsl_asrc_suspend(struct device *dev)
-{
-   struct fsl_asrc *asrc = dev_get_drvdata(dev);
-   struct fsl_asrc_priv *asrc_priv = asrc->private;
-
-   regmap_read(asrc->regmap, REG_ASRCFG,
-   _priv->regcache_cfg);
-
-   regcache_cache_only(asrc->regmap, true);
-   regcache_mark_dirty(asrc->regmap);
-
-   return 0;
-}
-
-static int fsl_asrc_resume(struct device *dev)
-{
-   struct fsl_asrc *asrc = dev_get_drvdata(dev);
-   struct fsl_asrc_priv *asrc_priv = asrc->private;
-   u32 asrctr;
-
-   /* Stop all pairs provisionally */
-   regmap_read(asrc->regmap, REG_ASRCTR, );
-   regmap_update_bits(asrc->regmap, REG_ASRCTR,
-  ASRCTR_ASRCEi_ALL_MASK, 0);
-
-   /* Restore all registers */
-   regcache_cache_only(asrc->regmap, false);
-   regcache_sync(asrc->regmap);
-
-   regmap_update_bits(asrc->regmap, REG_ASRCFG,
-  ASRCFG_NDPRi_ALL_MASK | ASRCFG_POSTMODi_ALL_MASK |
-  ASRCFG_PREMODi_ALL_MASK, asrc_priv->regcache_cfg);
-
-   /* Restart enabled pairs */
-   regmap_update_bits(asrc->regmap, REG_ASRCTR,
-  ASRCTR_ASRCEi_ALL_MASK, asrctr);
-
-   return 0;
-}
-#endif /* CONFIG_PM_SLEEP */
-
 static const struct dev_pm_ops fsl_asrc_pm = {
SET_RUNTIME_PM_OPS(fsl_asrc_runtime_suspend, fsl_asrc_runtime_resume, 
NULL)
-   SET_SYSTEM_SLEEP_PM_OPS(fsl_asrc_suspend, fsl_asrc_resume)
+   SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
+   pm_runtime_force_resume)
 };
 
 static const struct fsl_asrc_soc_data fsl_asrc_imx35_data = {
-- 
2.21.0



Re: [PATCH] ASoC: fsl: imx-pcm-dma: Don't request dma channel in probe

2020-05-21 Thread Shengjiu Wang
On Wed, May 20, 2020 at 8:38 PM Mark Brown  wrote:
>
> On Wed, May 20, 2020 at 07:22:19PM +0800, Shengjiu Wang wrote:
>
> > I see some driver also request dma channel in open() or hw_params().
> > how can they avoid the defer probe issue?
> > for example:
> > sound/arm/pxa2xx-pcm-lib.c
> > sound/soc/sprd/sprd-pcm-dma.c
>
> Other drivers having problems means those drivers should be fixed, not
> that we should copy the problems.  In the case of the PXA driver that's
> very old code which predates deferred probe by I'd guess a decade.

Thanks.

For the FE-BE case, do you have any suggestion for how fix it?

With DMA1->ASRC->DMA2->ESAI case, the DMA1->ASRC->DMA2
is in FE,  ESAI is in BE.  When ESAI drvier probe,  DMA3 channel is
created with ESAI's "dma:tx" (DMA3 channel
is not used in this FE-BE case).When FE-BE startup, DMA2
channel is created, it needs the ESAI's "dma:tx", so the warning
comes out.

best regards
wang shengjiu


Re: [PATCH] ASoC: fsl: imx-pcm-dma: Don't request dma channel in probe

2020-05-20 Thread Shengjiu Wang
Hi

On Wed, May 20, 2020 at 5:42 PM Lucas Stach  wrote:
>
> Am Mittwoch, den 20.05.2020, 16:20 +0800 schrieb Shengjiu Wang:
> > Hi
> >
> > On Tue, May 19, 2020 at 6:04 PM Lucas Stach  wrote:
> > > Am Dienstag, den 19.05.2020, 17:41 +0800 schrieb Shengjiu Wang:
> > > > There are two requirements that we need to move the request
> > > > of dma channel from probe to open.
> > >
> > > How do you handle -EPROBE_DEFER return code from the channel request if
> > > you don't do it in probe?
> >
> > I use the dma_request_slave_channel or dma_request_channel instead
> > of dmaengine_pcm_request_chan_of. so there should be not -EPROBE_DEFER
> > return code.
>
> This is a pretty weak argument. The dmaengine device might probe after
> you try to get the channel. Using a function to request the channel
> that doesn't allow you to handle probe deferral is IMHO a bug and
> should be fixed, instead of building even more assumptions on top of
> it.
>

I see some driver also request dma channel in open() or hw_params().
how can they avoid the defer probe issue?
for example:
sound/arm/pxa2xx-pcm-lib.c
sound/soc/sprd/sprd-pcm-dma.c

> > > > - When dma device binds with power-domains, the power will
> > > > be enabled when we request dma channel. If the request of dma
> > > > channel happen on probe, then the power-domains will be always
> > > > enabled after kernel boot up,  which is not good for power
> > > > saving,  so we need to move the request of dma channel to .open();
> > >
> > > This is certainly something which could be fixed in the dmaengine
> > > driver.
> >
> > Dma driver always call the pm_runtime_get_sync in
> > device_alloc_chan_resources, the device_alloc_chan_resources is
> > called when channel is requested. so power is enabled on channel
> > request.
>
> So why can't you fix the dmaengine driver to do that RPM call at a
> later time when the channel is actually going to be used? This will
> allow further power savings with other slave devices than the audio
> PCM.
>
> Regards,
> Lucas
>

It seems the best place for calling pm_runtime_get_sync is the
device_alloc_chan_resources, and calling pm_runtime_put_sync
in the .device_free_chan_resources

For the slave_sg mode, the .device_prep_slave_sg and
.device_issue_pending  will be called many times after
.device_alloc_chan_resources. so it is not good to call
pm_runtime_get_sync in .device_prep_slave_sg or
.device_issue_pending

best regards
wang shengjiu


Re: [PATCH] ASoC: fsl: imx-pcm-dma: Don't request dma channel in probe

2020-05-20 Thread Shengjiu Wang
Hi

On Tue, May 19, 2020 at 6:04 PM Lucas Stach  wrote:
>
> Am Dienstag, den 19.05.2020, 17:41 +0800 schrieb Shengjiu Wang:
> > There are two requirements that we need to move the request
> > of dma channel from probe to open.
>
> How do you handle -EPROBE_DEFER return code from the channel request if
> you don't do it in probe?

I use the dma_request_slave_channel or dma_request_channel instead
of dmaengine_pcm_request_chan_of. so there should be not -EPROBE_DEFER
return code.

>
> > - When dma device binds with power-domains, the power will
> > be enabled when we request dma channel. If the request of dma
> > channel happen on probe, then the power-domains will be always
> > enabled after kernel boot up,  which is not good for power
> > saving,  so we need to move the request of dma channel to .open();
>
> This is certainly something which could be fixed in the dmaengine
> driver.

Dma driver always call the pm_runtime_get_sync in
device_alloc_chan_resources, the device_alloc_chan_resources is
called when channel is requested. so power is enabled on channel
request.

>
> > - With FE-BE case, if the dma channel is requested in probe,
> > then there will be below issue, which is caused by that the
> > dma channel will be requested duplicately
>
> Why is this requested a second time? Is this just some missing cleanup
> on a deferred probe path?

Not relate with deferred probe.  With DMA1->ASRC->DMA2->ESAI case,
the DMA1->ASRC->DMA2 is in FE,  ESAI is in BE.  When ESAI drvier
probe,  DMA3 channel is created with ESAI's "dma:tx" (DMA3 channel
is not used in this FE-BE case).When FE-BE startup, DMA2
channel is created, it needs the ESAI's "dma:tx", so below warning
comes out.

>
> Regards,
> Lucas
>
> > [  638.906268] sysfs: cannot create duplicate filename 
> > '/devices/soc0/soc/200.bus/200.spba-bus/2024000.esai/dma:tx'
> > [  638.919061] CPU: 1 PID: 673 Comm: aplay Not tainted 
> > 5.7.0-rc1-12956-gfc64b2585593 #287
> > [  638.927113] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
> > [  638.933690] [] (unwind_backtrace) from [] 
> > (show_stack+0x10/0x14)
> > [  638.941464] [] (show_stack) from [] 
> > (dump_stack+0xe4/0x118)
> > [  638.948808] [] (dump_stack) from [] 
> > (sysfs_warn_dup+0x50/0x64)
> > [  638.956406] [] (sysfs_warn_dup) from [] 
> > (sysfs_do_create_link_sd+0xc8/0xd4)
> > [  638.965134] [] (sysfs_do_create_link_sd) from [] 
> > (dma_request_chan+0xb0/0x210)
> > [  638.974120] [] (dma_request_chan) from [] 
> > (dma_request_slave_channel+0x8/0x14)
> > [  638.983111] [] (dma_request_slave_channel) from [] 
> > (fsl_asrc_dma_hw_params+0x1e0/0x438)
> > [  638.992881] [] (fsl_asrc_dma_hw_params) from [] 
> > (soc_pcm_hw_params+0x4a0/0x6a8)
> > [  639.001952] [] (soc_pcm_hw_params) from [] 
> > (dpcm_fe_dai_hw_params+0x70/0xe4)
> > [  639.010765] [] (dpcm_fe_dai_hw_params) from [] 
> > (snd_pcm_hw_params+0x158/0x418)
> > [  639.019750] [] (snd_pcm_hw_params) from [] 
> > (snd_pcm_ioctl+0x734/0x183c)
> > [  639.028129] [] (snd_pcm_ioctl) from [] 
> > (ksys_ioctl+0x2ac/0xb98)
> > [  639.035812] [] (ksys_ioctl) from [] 
> > (ret_fast_syscall+0x0/0x28)
> > [  639.043490] Exception stack(0xec529fa8 to 0xec529ff0)
> > [  639.048565] 9fa0:       bee84650 01321870 0004 c25c4111 
> > bee84650 0002000f
> > [  639.056766] 9fc0: bee84650 01321870 01321820 0036 1f40  
> > 0002c2f8 0003
> > [  639.064964] 9fe0: b6f483fc bee8451c b6ee2655 b6e1dcf8
> > [  639.070339] fsl-esai-dai 2024000.esai: Cannot create DMA dma:tx symlink
> >
> > Signed-off-by: Shengjiu Wang 
> > ---
> >  sound/soc/fsl/imx-pcm-dma.c | 173 +---
> >  1 file changed, 159 insertions(+), 14 deletions(-)
> >
> > diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
> > index 04a9bc749016..dae53b384df4 100644
> > --- a/sound/soc/fsl/imx-pcm-dma.c
> > +++ b/sound/soc/fsl/imx-pcm-dma.c
> > @@ -11,6 +11,7 @@
> >  #include 
> >  #include 
> >  #include 
> > +#include 
> >
> >  #include 
> >  #include 
> > @@ -29,24 +30,168 @@ static bool filter(struct dma_chan *chan, void *param)
> >   return true;
> >  }
> >
> > -static const struct snd_dmaengine_pcm_config imx_dmaengine_pcm_config = {
> > - .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
> > - .compat_filter_fn = filter,
> > -};
> > +static int imx_pcm_hw_params(struct snd_soc_component *component,
> > +   

[PATCH] ASoC: fsl: imx-pcm-dma: Don't request dma channel in probe

2020-05-19 Thread Shengjiu Wang
There are two requirements that we need to move the request
of dma channel from probe to open.

- When dma device binds with power-domains, the power will
be enabled when we request dma channel. If the request of dma
channel happen on probe, then the power-domains will be always
enabled after kernel boot up,  which is not good for power
saving,  so we need to move the request of dma channel to .open();

- With FE-BE case, if the dma channel is requested in probe,
then there will be below issue, which is caused by that the
dma channel will be requested duplicately

[  638.906268] sysfs: cannot create duplicate filename 
'/devices/soc0/soc/200.bus/200.spba-bus/2024000.esai/dma:tx'
[  638.919061] CPU: 1 PID: 673 Comm: aplay Not tainted 
5.7.0-rc1-12956-gfc64b2585593 #287
[  638.927113] Hardware name: Freescale i.MX6 Quad/DualLite (Device Tree)
[  638.933690] [] (unwind_backtrace) from [] 
(show_stack+0x10/0x14)
[  638.941464] [] (show_stack) from [] 
(dump_stack+0xe4/0x118)
[  638.948808] [] (dump_stack) from [] 
(sysfs_warn_dup+0x50/0x64)
[  638.956406] [] (sysfs_warn_dup) from [] 
(sysfs_do_create_link_sd+0xc8/0xd4)
[  638.965134] [] (sysfs_do_create_link_sd) from [] 
(dma_request_chan+0xb0/0x210)
[  638.974120] [] (dma_request_chan) from [] 
(dma_request_slave_channel+0x8/0x14)
[  638.983111] [] (dma_request_slave_channel) from [] 
(fsl_asrc_dma_hw_params+0x1e0/0x438)
[  638.992881] [] (fsl_asrc_dma_hw_params) from [] 
(soc_pcm_hw_params+0x4a0/0x6a8)
[  639.001952] [] (soc_pcm_hw_params) from [] 
(dpcm_fe_dai_hw_params+0x70/0xe4)
[  639.010765] [] (dpcm_fe_dai_hw_params) from [] 
(snd_pcm_hw_params+0x158/0x418)
[  639.019750] [] (snd_pcm_hw_params) from [] 
(snd_pcm_ioctl+0x734/0x183c)
[  639.028129] [] (snd_pcm_ioctl) from [] 
(ksys_ioctl+0x2ac/0xb98)
[  639.035812] [] (ksys_ioctl) from [] 
(ret_fast_syscall+0x0/0x28)
[  639.043490] Exception stack(0xec529fa8 to 0xec529ff0)
[  639.048565] 9fa0:   bee84650 01321870 0004 c25c4111 
bee84650 0002000f
[  639.056766] 9fc0: bee84650 01321870 01321820 0036 1f40  
0002c2f8 0003
[  639.064964] 9fe0: b6f483fc bee8451c b6ee2655 b6e1dcf8
[  639.070339] fsl-esai-dai 2024000.esai: Cannot create DMA dma:tx symlink

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/imx-pcm-dma.c | 173 +---
 1 file changed, 159 insertions(+), 14 deletions(-)

diff --git a/sound/soc/fsl/imx-pcm-dma.c b/sound/soc/fsl/imx-pcm-dma.c
index 04a9bc749016..dae53b384df4 100644
--- a/sound/soc/fsl/imx-pcm-dma.c
+++ b/sound/soc/fsl/imx-pcm-dma.c
@@ -11,6 +11,7 @@
 #include 
 #include 
 #include 
+#include 
 
 #include 
 #include 
@@ -29,24 +30,168 @@ static bool filter(struct dma_chan *chan, void *param)
return true;
 }
 
-static const struct snd_dmaengine_pcm_config imx_dmaengine_pcm_config = {
-   .prepare_slave_config = snd_dmaengine_pcm_prepare_slave_config,
-   .compat_filter_fn = filter,
-};
+static int imx_pcm_hw_params(struct snd_soc_component *component,
+struct snd_pcm_substream *substream,
+struct snd_pcm_hw_params *params)
+{
+   struct snd_pcm_runtime *runtime = substream->runtime;
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct snd_soc_dai *cpu_dai = asoc_rtd_to_cpu(rtd, 0);
+   struct snd_dmaengine_dai_dma_data *dma_data;
+   struct dma_slave_config config;
+   struct dma_chan *chan;
+   int ret = 0;
 
-int imx_pcm_dma_init(struct platform_device *pdev, size_t size)
+   snd_pcm_set_runtime_buffer(substream, >dma_buffer);
+   runtime->dma_bytes = params_buffer_bytes(params);
+
+   chan = snd_dmaengine_pcm_get_chan(substream);
+   if (!chan)
+   return -EINVAL;
+
+   ret = snd_hwparams_to_dma_slave_config(substream, params, );
+   if (ret)
+   return ret;
+
+   dma_data = snd_soc_dai_get_dma_data(cpu_dai, substream);
+   if (!dma_data)
+   return -EINVAL;
+
+   snd_dmaengine_pcm_set_config_from_dai_data(substream,
+  dma_data,
+  );
+   return dmaengine_slave_config(chan, );
+}
+
+static int imx_pcm_hw_free(struct snd_soc_component *component,
+  struct snd_pcm_substream *substream)
 {
-   struct snd_dmaengine_pcm_config *config;
+   snd_pcm_set_runtime_buffer(substream, NULL);
+   return 0;
+}
+
+static snd_pcm_uframes_t imx_pcm_pointer(struct snd_soc_component *component,
+struct snd_pcm_substream *substream)
+{
+   return snd_dmaengine_pcm_pointer(substream);
+}
+
+static int imx_pcm_trigger(struct snd_soc_component *component,
+  struct snd_pcm_substream *substream, int cmd)
+{
+   return snd_dmaengine_pcm_trigger(substream, cmd);
+}
+
+static int imx_pcm_open(struct snd_soc_componen

[PATCH v2 2/2] ASoC: fsl_esai: Add new compatible string for imx8qm

2020-05-15 Thread Shengjiu Wang
Add new compatible string "fsl,imx8qm-esai" in the binding document.

Signed-off-by: Shengjiu Wang 
Acked-by: Rob Herring 
---
 Documentation/devicetree/bindings/sound/fsl,esai.txt | 1 +
 1 file changed, 1 insertion(+)

diff --git a/Documentation/devicetree/bindings/sound/fsl,esai.txt 
b/Documentation/devicetree/bindings/sound/fsl,esai.txt
index 0e6e2166f76c..0a2480aeecf0 100644
--- a/Documentation/devicetree/bindings/sound/fsl,esai.txt
+++ b/Documentation/devicetree/bindings/sound/fsl,esai.txt
@@ -12,6 +12,7 @@ Required properties:
  "fsl,imx35-esai",
  "fsl,vf610-esai",
  "fsl,imx6ull-esai",
+ "fsl,imx8qm-esai",
 
   - reg: Offset and length of the register set for the 
device.
 
-- 
2.21.0



[PATCH v2 0/2] ASoC: fsl_esai: Add support for imx8qm

2020-05-15 Thread Shengjiu Wang
Add support for imx8qm.

Shengjiu Wang (2):
  ASoC: fsl_esai: introduce SoC specific data
  ASoC: fsl_esai: Add new compatible string for imx8qm

Changes in v2
- drop the 0002 patch in v1, the dma relate limitation should
  be done in dma driver, or define a new DMA API for it.


 .../devicetree/bindings/sound/fsl,esai.txt|  1 +
 sound/soc/fsl/fsl_esai.c  | 46 +++
 2 files changed, 38 insertions(+), 9 deletions(-)

-- 
2.21.0



[PATCH v2 1/2] ASoC: fsl_esai: introduce SoC specific data

2020-05-15 Thread Shengjiu Wang
Introduce a SoC specific data structure which contains the
differences between the different SoCs.
This makes it easier to support more differences without having
to introduce a new if/else each time.

Signed-off-by: Shengjiu Wang 
Acked-by: Nicolin Chen 
---
 sound/soc/fsl/fsl_esai.c | 46 
 1 file changed, 37 insertions(+), 9 deletions(-)

diff --git a/sound/soc/fsl/fsl_esai.c b/sound/soc/fsl/fsl_esai.c
index 84290be778f0..bac65ba7fbad 100644
--- a/sound/soc/fsl/fsl_esai.c
+++ b/sound/soc/fsl/fsl_esai.c
@@ -21,6 +21,17 @@
SNDRV_PCM_FMTBIT_S20_3LE | \
SNDRV_PCM_FMTBIT_S24_LE)
 
+/**
+ * fsl_esai_soc_data: soc specific data
+ *
+ * @imx: for imx platform
+ * @reset_at_xrun: flags for enable reset operaton
+ */
+struct fsl_esai_soc_data {
+   bool imx;
+   bool reset_at_xrun;
+};
+
 /**
  * fsl_esai: ESAI private data
  *
@@ -33,6 +44,7 @@
  * @fsysclk: system clock source to derive HCK, SCK and FS
  * @spbaclk: SPBA clock (optional, depending on SoC design)
  * @task: tasklet to handle the reset operation
+ * @soc: soc specific data
  * @lock: spin lock between hw_reset() and trigger()
  * @fifo_depth: depth of tx/rx FIFO
  * @slot_width: width of each DAI slot
@@ -44,7 +56,6 @@
  * @sck_div: if using PSR/PM dividers for SCKx clock
  * @slave_mode: if fully using DAI slave mode
  * @synchronous: if using tx/rx synchronous mode
- * @reset_at_xrun: flags for enable reset operaton
  * @name: driver name
  */
 struct fsl_esai {
@@ -57,6 +68,7 @@ struct fsl_esai {
struct clk *fsysclk;
struct clk *spbaclk;
struct tasklet_struct task;
+   const struct fsl_esai_soc_data *soc;
spinlock_t lock; /* Protect hw_reset and trigger */
u32 fifo_depth;
u32 slot_width;
@@ -70,10 +82,24 @@ struct fsl_esai {
bool sck_div[2];
bool slave_mode;
bool synchronous;
-   bool reset_at_xrun;
char name[32];
 };
 
+static struct fsl_esai_soc_data fsl_esai_vf610 = {
+   .imx = false,
+   .reset_at_xrun = true,
+};
+
+static struct fsl_esai_soc_data fsl_esai_imx35 = {
+   .imx = true,
+   .reset_at_xrun = true,
+};
+
+static struct fsl_esai_soc_data fsl_esai_imx6ull = {
+   .imx = true,
+   .reset_at_xrun = false,
+};
+
 static irqreturn_t esai_isr(int irq, void *devid)
 {
struct fsl_esai *esai_priv = (struct fsl_esai *)devid;
@@ -85,7 +111,7 @@ static irqreturn_t esai_isr(int irq, void *devid)
regmap_read(esai_priv->regmap, REG_ESAI_SAISR, );
 
if ((saisr & (ESAI_SAISR_TUE | ESAI_SAISR_ROE)) &&
-   esai_priv->reset_at_xrun) {
+   esai_priv->soc->reset_at_xrun) {
dev_dbg(>dev, "reset module for xrun\n");
regmap_update_bits(esai_priv->regmap, REG_ESAI_TCR,
   ESAI_xCR_xEIE_MASK, 0);
@@ -936,9 +962,11 @@ static int fsl_esai_probe(struct platform_device *pdev)
esai_priv->pdev = pdev;
snprintf(esai_priv->name, sizeof(esai_priv->name), "%pOFn", np);
 
-   if (of_device_is_compatible(np, "fsl,vf610-esai") ||
-   of_device_is_compatible(np, "fsl,imx35-esai"))
-   esai_priv->reset_at_xrun = true;
+   esai_priv->soc = of_device_get_match_data(>dev);
+   if (!esai_priv->soc) {
+   dev_err(>dev, "failed to get soc data\n");
+   return -ENODEV;
+   }
 
/* Get the addresses and IRQ */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
@@ -1063,9 +1091,9 @@ static int fsl_esai_remove(struct platform_device *pdev)
 }
 
 static const struct of_device_id fsl_esai_dt_ids[] = {
-   { .compatible = "fsl,imx35-esai", },
-   { .compatible = "fsl,vf610-esai", },
-   { .compatible = "fsl,imx6ull-esai", },
+   { .compatible = "fsl,imx35-esai", .data = _esai_imx35 },
+   { .compatible = "fsl,vf610-esai", .data = _esai_vf610 },
+   { .compatible = "fsl,imx6ull-esai", .data = _esai_imx6ull },
{}
 };
 MODULE_DEVICE_TABLE(of, fsl_esai_dt_ids);
-- 
2.21.0



Re: [PATCH 2/3] ASoC: fsl_esai: Add support for imx8qm

2020-05-15 Thread Shengjiu Wang
On Tue, May 12, 2020 at 8:38 PM Mark Brown  wrote:
>
> On Tue, May 12, 2020 at 10:48:41AM +0800, Shengjiu Wang wrote:
> > On Wed, May 6, 2020 at 10:33 AM Shengjiu Wang  
> > wrote:
> > > On Fri, May 1, 2020 at 6:23 PM Mark Brown  wrote:
>
> > > > > EDMA requires the period size to be multiple of maxburst. Otherwise
> > > > > the remaining bytes are not transferred and thus noise is produced.
>
> > > > If this constraint comes from the DMA controller then normally you'd
> > > > expect the DMA controller integration to be enforcing this - is there no
> > > > information in the DMA API that lets us know that this constraint is
> > > > there?
>
> > > No, I can't find one API for this.
> > > Do you have a recommendation?
>
> > could you please recommend which DMA API can I use?
>
> Not off-hand, you'd probably need to extend the API to export the
> information.

Thanks.  I will think about if I can find a better solution.
And I will drop this change and send v2 of this patch-set.


[PATCH] ASoC: fsl_asrc: Set ASR76K and ASR56K based on processing clock

2020-05-12 Thread Shengjiu Wang
The processing clock is different for platforms, so it is better
to set ASR76K and ASR56K based on processing clock, rather than
hard coding the value for them.

Signed-off-by: Shengjiu Wang 
Signed-off-by: Mihai Serban 
---
 sound/soc/fsl/fsl_asrc.c | 15 ++-
 1 file changed, 10 insertions(+), 5 deletions(-)

diff --git a/sound/soc/fsl/fsl_asrc.c b/sound/soc/fsl/fsl_asrc.c
index 067a54ab554f..ca926915068f 100644
--- a/sound/soc/fsl/fsl_asrc.c
+++ b/sound/soc/fsl/fsl_asrc.c
@@ -858,6 +858,8 @@ static const struct regmap_config fsl_asrc_regmap_config = {
  */
 static int fsl_asrc_init(struct fsl_asrc *asrc)
 {
+   unsigned long ipg_rate;
+
/* Halt ASRC internal FP when input FIFO needs data for pair A, B, C */
regmap_write(asrc->regmap, REG_ASRCTR, ASRCTR_ASRCEN);
 
@@ -875,11 +877,14 @@ static int fsl_asrc_init(struct fsl_asrc *asrc)
regmap_update_bits(asrc->regmap, REG_ASRTFR1,
   ASRTFR1_TF_BASE_MASK, ASRTFR1_TF_BASE(0xfc));
 
-   /* Set the processing clock for 76KHz to 133M */
-   regmap_write(asrc->regmap, REG_ASR76K, 0x06D6);
-
-   /* Set the processing clock for 56KHz to 133M */
-   return regmap_write(asrc->regmap, REG_ASR56K, 0x0947);
+   /*
+* Set the period of the 76KHz and 56KHz sampling clocks based on
+* the ASRC processing clock.
+* On iMX6, ipg_clk = 133MHz, REG_ASR76K = 0x06D6, REG_ASR56K = 0x0947
+*/
+   ipg_rate = clk_get_rate(asrc->ipg_clk);
+   regmap_write(asrc->regmap, REG_ASR76K, ipg_rate / 76000);
+   return regmap_write(asrc->regmap, REG_ASR56K, ipg_rate / 56000);
 }
 
 /**
-- 
2.21.0



Re: [PATCH 2/3] ASoC: fsl_esai: Add support for imx8qm

2020-05-11 Thread Shengjiu Wang
Hi Mark, Nicolin

On Wed, May 6, 2020 at 10:33 AM Shengjiu Wang  wrote:
>
> Hi
>
> On Fri, May 1, 2020 at 6:23 PM Mark Brown  wrote:
> >
> > On Fri, May 01, 2020 at 04:12:05PM +0800, Shengjiu Wang wrote:
> > > The difference for esai on imx8qm is that DMA device is EDMA.
> > >
> > > EDMA requires the period size to be multiple of maxburst. Otherwise
> > > the remaining bytes are not transferred and thus noise is produced.
> >
> > If this constraint comes from the DMA controller then normally you'd
> > expect the DMA controller integration to be enforcing this - is there no
> > information in the DMA API that lets us know that this constraint is
> > there?
>
> No, I can't find one API for this.
> Do you have a recommendation?
>
could you please recommend which DMA API can I use?

best regards
wang shengjiu


  1   2   3   4   >