Re: [PATCH v2 3/3] ASoC: fsl_easrc: Add EASRC ASoC CPU DAI and platform drivers

2020-02-25 Thread Nicolin Chen
On Wed, Feb 26, 2020 at 09:51:39AM +0800, Shengjiu Wang wrote:
> > > > > +static const struct regmap_config fsl_easrc_regmap_config = {
> > > > > + .readable_reg = fsl_easrc_readable_reg,
> > > > > + .volatile_reg = fsl_easrc_volatile_reg,
> > > > > + .writeable_reg = fsl_easrc_writeable_reg,
> > > >
> > > > Can we use regmap_range and regmap_access_table?
> > > >
> > >
> > > Can the regmap_range support discontinuous registers?  The
> > > reg_stride = 4.
> >
> > I think it does. Giving an example here:
> > https://github.com/torvalds/linux/blob/master/drivers/mfd/da9063-i2c.c
> 
> The register in this i2c driver are continuous,  from 0x00, 0x01, 0x02...
> 
> But our case is 0x00, 0x04, 0x08, does it work?

Ah...I see your point now. I am not very sure -- have only used
in I2C drivers. You can ignore if it doesn't likely work for us.


Re: [PATCH v2 3/3] ASoC: fsl_easrc: Add EASRC ASoC CPU DAI and platform drivers

2020-02-25 Thread Shengjiu Wang
On Tue, Feb 25, 2020 at 4:05 PM Nicolin Chen  wrote:
>
> On Mon, Feb 24, 2020 at 08:53:25AM +, S.j. Wang wrote:
> > Hi
> >
> > > >
> > > > Signed-off-by: Shengjiu Wang 
> > > > ---
> > > >  sound/soc/fsl/Kconfig   |   10 +
> > > >  sound/soc/fsl/Makefile  |2 +
> > > >  sound/soc/fsl/fsl_asrc_common.h |1 +
> > > >  sound/soc/fsl/fsl_easrc.c   | 2265 +++
> > > >  sound/soc/fsl/fsl_easrc.h   |  668 +
> > > >  sound/soc/fsl/fsl_easrc_dma.c   |  440 ++
> > >
> > > I see a 90% similarity between fsl_asrc_dma and fsl_easrc_dma files.
> > > Would it be possible reuse the existing code? Could share structures from
> > > my point of view, just like it reuses "enum asrc_pair_index", I know
> > > differentiating "pair" and "context" is a big point here though.
> > >
> > > A possible quick solution for that, off the top of my head, could be:
> > >
> > > 1) in fsl_asrc_common.h
> > >
> > > struct fsl_asrc {
> > > 
> > > };
> > >
> > > struct fsl_asrc_pair {
> > > 
> > > };
> > >
> > > 2) in fsl_easrc.h
> > >
> > > /* Renaming shared structures */
> > > #define fsl_easrc fsl_asrc
> > > #define fsl_easrc_context fsl_asrc_pair
> > >
> > > May be a good idea to see if others have some opinion too.
> > >
> >
> > We need to modify the fsl_asrc and fsl_asrc_pair, let them
> > To be used by both driver,  also we need to put the specific
> > Definition for each module to same struct, right?
>
> Yea. A merged structure if that doesn't look that bad. I see most
> of the fields in struct fsl_asrc are being reused by in fsl_easrc.
>
> > >
> > > > +static const struct regmap_config fsl_easrc_regmap_config = {
> > > > + .readable_reg = fsl_easrc_readable_reg,
> > > > + .volatile_reg = fsl_easrc_volatile_reg,
> > > > + .writeable_reg = fsl_easrc_writeable_reg,
> > >
> > > Can we use regmap_range and regmap_access_table?
> > >
> >
> > Can the regmap_range support discontinuous registers?  The
> > reg_stride = 4.
>
> I think it does. Giving an example here:
> https://github.com/torvalds/linux/blob/master/drivers/mfd/da9063-i2c.c

The register in this i2c driver are continuous,  from 0x00, 0x01, 0x02...

But our case is 0x00, 0x04, 0x08, does it work?

best regards
wang shengjiu


Re: [PATCH v2 3/3] ASoC: fsl_easrc: Add EASRC ASoC CPU DAI and platform drivers

2020-02-25 Thread Nicolin Chen
On Mon, Feb 24, 2020 at 08:53:25AM +, S.j. Wang wrote:
> Hi
> 
> > >
> > > Signed-off-by: Shengjiu Wang 
> > > ---
> > >  sound/soc/fsl/Kconfig   |   10 +
> > >  sound/soc/fsl/Makefile  |2 +
> > >  sound/soc/fsl/fsl_asrc_common.h |1 +
> > >  sound/soc/fsl/fsl_easrc.c   | 2265 +++
> > >  sound/soc/fsl/fsl_easrc.h   |  668 +
> > >  sound/soc/fsl/fsl_easrc_dma.c   |  440 ++
> > 
> > I see a 90% similarity between fsl_asrc_dma and fsl_easrc_dma files.
> > Would it be possible reuse the existing code? Could share structures from
> > my point of view, just like it reuses "enum asrc_pair_index", I know
> > differentiating "pair" and "context" is a big point here though.
> > 
> > A possible quick solution for that, off the top of my head, could be:
> > 
> > 1) in fsl_asrc_common.h
> > 
> > struct fsl_asrc {
> > 
> > };
> > 
> > struct fsl_asrc_pair {
> > 
> > };
> > 
> > 2) in fsl_easrc.h
> > 
> > /* Renaming shared structures */
> > #define fsl_easrc fsl_asrc
> > #define fsl_easrc_context fsl_asrc_pair
> > 
> > May be a good idea to see if others have some opinion too.
> > 
> 
> We need to modify the fsl_asrc and fsl_asrc_pair, let them
> To be used by both driver,  also we need to put the specific
> Definition for each module to same struct, right?

Yea. A merged structure if that doesn't look that bad. I see most
of the fields in struct fsl_asrc are being reused by in fsl_easrc.

> > 
> > > +static const struct regmap_config fsl_easrc_regmap_config = {
> > > + .readable_reg = fsl_easrc_readable_reg,
> > > + .volatile_reg = fsl_easrc_volatile_reg,
> > > + .writeable_reg = fsl_easrc_writeable_reg,
> > 
> > Can we use regmap_range and regmap_access_table?
> > 
> 
> Can the regmap_range support discontinuous registers?  The
> reg_stride = 4.

I think it does. Giving an example here:
https://github.com/torvalds/linux/blob/master/drivers/mfd/da9063-i2c.c


Re: [PATCH v2 3/3] ASoC: fsl_easrc: Add EASRC ASoC CPU DAI and platform drivers

2020-02-24 Thread S.j. Wang
Hi

> >
> > Signed-off-by: Shengjiu Wang 
> > ---
> >  sound/soc/fsl/Kconfig   |   10 +
> >  sound/soc/fsl/Makefile  |2 +
> >  sound/soc/fsl/fsl_asrc_common.h |1 +
> >  sound/soc/fsl/fsl_easrc.c   | 2265 +++
> >  sound/soc/fsl/fsl_easrc.h   |  668 +
> >  sound/soc/fsl/fsl_easrc_dma.c   |  440 ++
> 
> I see a 90% similarity between fsl_asrc_dma and fsl_easrc_dma files.
> Would it be possible reuse the existing code? Could share structures from
> my point of view, just like it reuses "enum asrc_pair_index", I know
> differentiating "pair" and "context" is a big point here though.
> 
> A possible quick solution for that, off the top of my head, could be:
> 
> 1) in fsl_asrc_common.h
> 
> struct fsl_asrc {
> 
> };
> 
> struct fsl_asrc_pair {
> 
> };
> 
> 2) in fsl_easrc.h
> 
> /* Renaming shared structures */
> #define fsl_easrc fsl_asrc
> #define fsl_easrc_context fsl_asrc_pair
> 
> May be a good idea to see if others have some opinion too.
> 

We need to modify the fsl_asrc and fsl_asrc_pair, let them
To be used by both driver,  also we need to put the specific
Definition for each module to same struct, right?

> 
> > +static const struct regmap_config fsl_easrc_regmap_config = {
> > + .readable_reg = fsl_easrc_readable_reg,
> > + .volatile_reg = fsl_easrc_volatile_reg,
> > + .writeable_reg = fsl_easrc_writeable_reg,
> 
> Can we use regmap_range and regmap_access_table?
> 

Can the regmap_range support discontinuous registers?  The
reg_stride = 4.

Best regards
Wang shengjiu



Re: [PATCH v2 3/3] ASoC: fsl_easrc: Add EASRC ASoC CPU DAI and platform drivers

2020-02-18 Thread Nicolin Chen
On Tue, Feb 18, 2020 at 02:39:37PM +0800, Shengjiu Wang wrote:
> EASRC (Enhanced Asynchronous Sample Rate Converter) is a new IP module
> found on i.MX8MN. It is different with old ASRC module.
> 
> The primary features for the EASRC are as follows:
> - 4 Contexts - groups of channels with an independent time base
> - Fully independent and concurrent context control
> - Simultaneous processing of up to 32 audio channels
> - Programmable filter charachteristics for each context
> - 32, 24, 20, and 16-bit fixed point audio sample support
> - 32-bit floating point audio sample support
> - 8kHz to 384kHz sample rate
> - 1/16 to 8x sample rate conversion ratio
> 
> Signed-off-by: Shengjiu Wang 
> ---
>  sound/soc/fsl/Kconfig   |   10 +
>  sound/soc/fsl/Makefile  |2 +
>  sound/soc/fsl/fsl_asrc_common.h |1 +
>  sound/soc/fsl/fsl_easrc.c   | 2265 +++
>  sound/soc/fsl/fsl_easrc.h   |  668 +
>  sound/soc/fsl/fsl_easrc_dma.c   |  440 ++

I see a 90% similarity between fsl_asrc_dma and fsl_easrc_dma files.
Would it be possible reuse the existing code? Could share structures
from my point of view, just like it reuses "enum asrc_pair_index", I
know differentiating "pair" and "context" is a big point here though.

A possible quick solution for that, off the top of my head, could be:

1) in fsl_asrc_common.h

struct fsl_asrc {

};

struct fsl_asrc_pair {

};

2) in fsl_easrc.h

/* Renaming shared structures */
#define fsl_easrc fsl_asrc
#define fsl_easrc_context fsl_asrc_pair

May be a good idea to see if others have some opinion too.

> diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
> new file mode 100644
> index ..6fe2953317f2
> --- /dev/null
> +++ b/sound/soc/fsl/fsl_easrc.c
> +
> +/* set_rs_ratio
> + *
> + * According to the resample taps, calculate the resample ratio
> + */
> +static int set_rs_ratio(struct fsl_easrc_context *ctx)

"fsl_easrc_" prefix? Would be nice to have a formula in the comments.

> +/* resets the pointer of the coeff memory pointers */
> +static int fsl_coeff_mem_ptr_reset(struct fsl_easrc *easrc,
> +unsigned int ctx_id, int mem_type)
> +{
> + /*  To reset the write pointer back to zero, the register field
> +  *  ASRC_CTX_CTRL_EXT1x[PF_COEFF_MEM_RST] can be toggled from
> +  *  0x0 to 0x1 to 0x0.
> +  */

Please use the style:
/*
 * xxx
 */

> +static int fsl_easrc_resampler_config(struct fsl_easrc *easrc)
> +{
> + for (i = 0; i < hdr->interp_scen; i++) {
> + if ((interp[i].num_taps - 1) ==
> + bits_taps_to_val(easrc->rs_num_taps)) {

Could do below to save some indentations from the rest of the routine:
+   if ((interp[i].num_taps - 1) !=
+   bits_taps_to_val(easrc->rs_num_taps))
+   continue;

> + arr = interp[i].coeff;
> + selected_interp = [i];
> + dev_dbg(dev, "Selected interp_filter: %u taps - %u 
> phases\n",
> + selected_interp->num_taps,
> + selected_interp->num_phases);
> + break;

> +/*
> + *  Scale filter coefficients (64 bits float)
> + *  For input float32 normalized range (1.0,-1.0) -> output int[16,24,32]:
> + *  scale it by multiplying filter coefficients by 2^31
> + *  For input int[16, 24, 32] -> output float32
> + *  scale it by multiplying filter coefficients by 2^-15, 2^-23, 2^-31
> + *  input:
> + *  easrc:  Structure pointer of fsl_easrc
> + *  infilter : Pointer to non-scaled input filter
> + *  shift:  The multiply factor
> + *  output:
> + *  outfilter: scaled filter
> + 
> */
> +static int NormalizedFilterForFloat32InIntOut(struct fsl_easrc *easrc,
> +   u64 *infilter,
> +   u64 *outfilter,
> +   int shift)

Coding style looks very different, at comments and function naming.

> +{
> + struct device *dev = >pdev->dev;
> + u64 coef = *infilter;
> + s64 exp  = (coef & 0x7ff0ll) >> 52;
> + u64 outcoef;
> +
> + /*
> +  * If exponent is zero (value == 0), or 7ff (value == NaNs)
> +  * dont touch the content
> +  */
> + if (((coef & 0x7ff0ll) == 0) ||
> + ((coef & 0x7ff0ll) == ((u64)0x7ff << 52))) {
> + *outfilter = coef;
> + } else {
> + if ((shift > 0 && (shift + exp) >= 2047) ||
> + (shift < 0 && (exp + shift) <= 0)) {
> + dev_err(dev, "coef 

[PATCH v2 3/3] ASoC: fsl_easrc: Add EASRC ASoC CPU DAI and platform drivers

2020-02-17 Thread Shengjiu Wang
EASRC (Enhanced Asynchronous Sample Rate Converter) is a new IP module
found on i.MX8MN. It is different with old ASRC module.

The primary features for the EASRC are as follows:
- 4 Contexts - groups of channels with an independent time base
- Fully independent and concurrent context control
- Simultaneous processing of up to 32 audio channels
- Programmable filter charachteristics for each context
- 32, 24, 20, and 16-bit fixed point audio sample support
- 32-bit floating point audio sample support
- 8kHz to 384kHz sample rate
- 1/16 to 8x sample rate conversion ratio

Signed-off-by: Shengjiu Wang 
---
 sound/soc/fsl/Kconfig   |   10 +
 sound/soc/fsl/Makefile  |2 +
 sound/soc/fsl/fsl_asrc_common.h |1 +
 sound/soc/fsl/fsl_easrc.c   | 2265 +++
 sound/soc/fsl/fsl_easrc.h   |  668 +
 sound/soc/fsl/fsl_easrc_dma.c   |  440 ++
 6 files changed, 3386 insertions(+)
 create mode 100644 sound/soc/fsl/fsl_easrc.c
 create mode 100644 sound/soc/fsl/fsl_easrc.h
 create mode 100644 sound/soc/fsl/fsl_easrc_dma.c

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 65e8cd4be930..21ba7642b5d0 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -84,6 +84,16 @@ config SND_SOC_FSL_MICFIL
  Say Y if you want to add Pulse Density Modulation microphone
  interface (MICFIL) support for NXP.
 
+config SND_SOC_FSL_EASRC
+   tristate "Enhanced Asynchronous Sample Rate Converter (EASRC) module 
support"
+   select REGMAP_MMIO
+   select SND_SOC_GENERIC_DMAENGINE_PCM
+   help
+ Say Y if you want to add Enhanced ASRC support for NXP. The ASRC is
+ a digital module that converts audio from a source sample rate to a
+ destination sample rate. It is a new design module compare with the
+ old ASRC.
+
 config SND_SOC_FSL_UTILS
tristate
 
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 8cde88c72d93..a5a2d08930f4 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -24,6 +24,7 @@ snd-soc-fsl-micfil-objs := fsl_micfil.o
 snd-soc-fsl-utils-objs := fsl_utils.o
 snd-soc-fsl-dma-objs := fsl_dma.o
 snd-soc-fsl-mqs-objs := fsl_mqs.o
+snd-soc-fsl-easrc-objs := fsl_easrc.o fsl_easrc_dma.o
 
 obj-$(CONFIG_SND_SOC_FSL_AUDMIX) += snd-soc-fsl-audmix.o
 obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o
@@ -35,6 +36,7 @@ obj-$(CONFIG_SND_SOC_FSL_ESAI) += snd-soc-fsl-esai.o
 obj-$(CONFIG_SND_SOC_FSL_MICFIL) += snd-soc-fsl-micfil.o
 obj-$(CONFIG_SND_SOC_FSL_UTILS) += snd-soc-fsl-utils.o
 obj-$(CONFIG_SND_SOC_FSL_MQS) += snd-soc-fsl-mqs.o
+obj-$(CONFIG_SND_SOC_FSL_EASRC) += snd-soc-fsl-easrc.o
 obj-$(CONFIG_SND_SOC_POWERPC_DMA) += snd-soc-fsl-dma.o
 
 # MPC5200 Platform Support
diff --git a/sound/soc/fsl/fsl_asrc_common.h b/sound/soc/fsl/fsl_asrc_common.h
index 8acc55778ff2..c2056b661f15 100644
--- a/sound/soc/fsl/fsl_asrc_common.h
+++ b/sound/soc/fsl/fsl_asrc_common.h
@@ -16,6 +16,7 @@ enum asrc_pair_index {
ASRC_PAIR_A = 0,
ASRC_PAIR_B = 1,
ASRC_PAIR_C = 2,
+   ASRC_PAIR_D = 3,
 };
 
 #endif /* _FSL_ASRC_COMMON_H */
diff --git a/sound/soc/fsl/fsl_easrc.c b/sound/soc/fsl/fsl_easrc.c
new file mode 100644
index ..6fe2953317f2
--- /dev/null
+++ b/sound/soc/fsl/fsl_easrc.c
@@ -0,0 +1,2265 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright 2019 NXP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fsl_easrc.h"
+#include "imx-pcm.h"
+
+#define FSL_EASRC_FORMATS   (SNDRV_PCM_FMTBIT_S16_LE | \
+SNDRV_PCM_FMTBIT_U16_LE | \
+SNDRV_PCM_FMTBIT_S24_LE | \
+SNDRV_PCM_FMTBIT_S24_3LE | \
+SNDRV_PCM_FMTBIT_U24_LE | \
+SNDRV_PCM_FMTBIT_U24_3LE | \
+SNDRV_PCM_FMTBIT_S32_LE | \
+SNDRV_PCM_FMTBIT_U32_LE | \
+SNDRV_PCM_FMTBIT_S20_3LE | \
+SNDRV_PCM_FMTBIT_U20_3LE | \
+SNDRV_PCM_FMTBIT_FLOAT_LE)
+
+static int fsl_easrc_iec958_put_bits(struct snd_kcontrol *kcontrol,
+struct snd_ctl_elem_value *ucontrol)
+{
+   struct snd_soc_component *comp = snd_kcontrol_chip(kcontrol);
+   struct fsl_easrc *easrc = snd_soc_component_get_drvdata(comp);
+   struct soc_mreg_control *mc =
+   (struct soc_mreg_control *)kcontrol->private_value;
+   unsigned int regval = ucontrol->value.integer.value[0];
+
+   easrc->bps_iec958[mc->regbase] = regval;
+
+   return 0;
+}
+
+static int