RE: [PATCH] ASoC: fsl_sai: remove reset code from dai_probe

2021-03-16 Thread Viorel Suman
> On Tue, Mar 16, 2021 at 05:27:06PM +0800, Shengjiu Wang wrote:
> > From: Viorel Suman 
> >
> > SAI software reset is done in runtime resume, there is no need to do
> > it in fsl_sai_dai_probe.
> 
> People can disable runtime PM in their configurations - do you not still need 
> a
> reset on probe in case there's no runtime PM?  It'd probably make sense to
> factor the rest code out itno a function though.

Hi Mark, Shengjiu,

To me it makes sense to manage the clocks and reset from the same place.
Currently we have the clocks management moved completely into runtime PM
fsl_sai_runtime_resume and fsl_sai_runtime_suspend callbacks. 

/Viorel



[PATCH] ASoC: fsl_xcvr: fix potential resource leak

2020-11-24 Thread Viorel Suman (OSS)
From: Viorel Suman 

"fw" variable must be relased before return.

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/fsl_xcvr.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
index 2a28810d0e29..3d58c88ea603 100644
--- a/sound/soc/fsl/fsl_xcvr.c
+++ b/sound/soc/fsl/fsl_xcvr.c
@@ -706,6 +706,7 @@ static int fsl_xcvr_load_firmware(struct fsl_xcvr *xcvr)
/* RAM is 20KiB = 16KiB code + 4KiB data => max 10 pages 2KiB each */
if (rem > 16384) {
dev_err(dev, "FW size %d is bigger than 16KiB.\n", rem);
+   release_firmware(fw);
return -ENOMEM;
}
 
-- 
2.26.2



RE: [RFC PATCH] ASoC: ak4458: use reset control instead of reset gpio

2020-11-19 Thread Viorel Suman
Hi Peter,

> DTS is supposed to look as follows:
> >
> > / {
> > ak4458_reset: gpio-reset {
> >compatible = "gpio-reset";
> >reset-gpios = < 4 GPIO_ACTIVE_LOW>;
> >#reset-cells = <0>;
> >initially-in-reset;
> 
> I can not find anything resembling to this in next-20201119.
> Where is the implementation and documentation for this gpio-reset?

The board schematics is not publicly available; some info may be seen in DTS 
files below:
https://source.codeaurora.org/external/imx/linux-imx/tree/arch/arm64/boot/dts/freescale/imx8mm-evk.dts?h=imx_5.4.24_2.1.0
https://source.codeaurora.org/external/imx/linux-imx/tree/arch/arm64/boot/dts/freescale/imx8mm-ab2.dts?h=imx_5.4.24_2.1.0
https://source.codeaurora.org/external/imx/linux-imx/tree/arch/arm64/boot/dts/freescale/imx8mp-ab2.dts?h=imx_5.4.24_2.1.0

In examples above the GPIO is handled by machine driver - wrong approach given 
that
it requires machine driver being probed before codec driver.

> > -   ak4458->reset_gpiod = devm_gpiod_get_optional(ak4458->dev,
> "reset",
> > - GPIOD_OUT_LOW);
> > -   if (IS_ERR(ak4458->reset_gpiod))
> > -   return PTR_ERR(ak4458->reset_gpiod);
> > +   ak4458->reset = devm_reset_control_get_optional_shared(ak4458-
> >dev, NULL);
> > +   if (IS_ERR(ak4458->reset))
> > +   return PTR_ERR(ak4458->reset);
> 
> The binding documentation must be updated and you must support the gpio
> way as well.

Sure, make sense.

> When I had this discussion around using the reset framework for shared
> enable and/or reset pins it was suggested that _if_ such a driver makes
> sense then it should internally handle (by using magic strings) the fallback
> and work with pre-reset binding.

Thanks, would appreciate if you point me to the discussion you had.

Viorel


RE: [RFC PATCH] ASoC: ak4458: use reset control instead of reset gpio

2020-11-19 Thread Viorel Suman
> On Tue, Nov 17, 2020 at 06:17:36PM +0000, Viorel Suman wrote:
> > > On Tue, Nov 17, 2020 at 12:20:36AM +0200, Viorel Suman (OSS) wrote:
> 
> > > One thing I'm not clear on is if there's some way to ensure that we
> > > don't have different instances of the device resetting each other without
> them noticing?
> > > Shouldn't be an issue in practice for the use here.
> 
> > The way to ensure that we don't have different instances of the device
> > resetting each other is to rely on the way the "shared" reset is handled by
> reset API:
> > ==
> > +   ak4458->reset = devm_reset_control_get_optional_shared(ak4458-
> >dev, NULL);
> > +   if (IS_ERR(ak4458->reset))
> > +   return PTR_ERR(ak4458->reset);
> > ==
> 
> Flip side of that then, how do we know when a reset has actually happened?

I don't see how this can be achieved - I'd imagine some "shared" reset
framework notification mechanism calling back all "listeners" in the moment
the assert/deassert actually happened, there is no such mechanism currently
implemented.

In this specific case the GPIO purpose is to just to power on/off all codecs.
In my view with this approach it's enough to know that all codecs will be
powered on the first _deassert_ call and will be powered off on the last
_assert_ call.

/Viorel 


RE: [RFC PATCH] ASoC: ak4458: use reset control instead of reset gpio

2020-11-17 Thread Viorel Suman
> On Tue, Nov 17, 2020 at 12:20:36AM +0200, Viorel Suman (OSS) wrote:
> 
> >  static void ak4458_power_off(struct ak4458_priv *ak4458)  {
> > -   if (ak4458->reset_gpiod) {
> > -   gpiod_set_value_cansleep(ak4458->reset_gpiod, 0);
> > -   usleep_range(1000, 2000);
> > +   if (ak4458->reset) {
> > +   reset_control_assert(ak4458->reset);
> > +   msleep(20);
> 
> We should really leave the support for doing this via GPIO in place for 
> backwards
> compatibility I think, we could mark it as deprecated in the binding document.
> Otherwise this makes sense to me and solves a real problem we have with the
> handling of resets so we should look into doing this for new bindings.
> 
> One thing I'm not clear on is if there's some way to ensure that we don't have
> different instances of the device resetting each other without them noticing?
> Shouldn't be an issue in practice for the use here.

The way to ensure that we don't have different instances of the device 
resetting each
other is to rely on the way the "shared" reset is handled by reset API: 
==
+   ak4458->reset = devm_reset_control_get_optional_shared(ak4458->dev, 
NULL);
+   if (IS_ERR(ak4458->reset))
+   return PTR_ERR(ak4458->reset);
==

/Viorel


[RFC PATCH] ASoC: ak4458: use reset control instead of reset gpio

2020-11-16 Thread Viorel Suman (OSS)
From: Viorel Suman 

Using GPIO API seems not a way to go for the case
when the same reset GPIO is used to control several codecs.
For a such case we can use the "gpio-reset" driver
and the "shared" reset API to manage the reset GPIO -
to deassert the reset when the first codec is powered up
and assert it when there is no codec in use.
DTS is supposed to look as follows:

/ {
ak4458_reset: gpio-reset {
   compatible = "gpio-reset";
   reset-gpios = < 4 GPIO_ACTIVE_LOW>;
   #reset-cells = <0>;
   initially-in-reset;
};
};

 {
pca6416: gpio@20 {
   compatible = "ti,tca6416";
   reg = <0x20>;
   gpio-controller;
   #gpio-cells = <2>;
};

ak4458_1: ak4458@10 {
   compatible = "asahi-kasei,ak4458";
   reg = <0x10>;
   resets = <_reset>;
};

ak4458_2: ak4458@11 {
   compatible = "asahi-kasei,ak4458";
   reg = <0x11>;
   resets = <_reset>;
};

ak4458_3: ak4458@12 {
   compatible = "asahi-kasei,ak4458";
   reg = <0x12>;
   resets = <_reset>;
};
};

Signed-off-by: Viorel Suman 
---
 sound/soc/codecs/ak4458.c | 23 +++
 1 file changed, 11 insertions(+), 12 deletions(-)

diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c
index 1010c9ee2e83..f27727cb1382 100644
--- a/sound/soc/codecs/ak4458.c
+++ b/sound/soc/codecs/ak4458.c
@@ -13,6 +13,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -45,7 +46,7 @@ struct ak4458_priv {
const struct ak4458_drvdata *drvdata;
struct device *dev;
struct regmap *regmap;
-   struct gpio_desc *reset_gpiod;
+   struct reset_control *reset;
struct gpio_desc *mute_gpiod;
int digfil; /* SSLOW, SD, SLOW bits */
int fs; /* sampling rate */
@@ -597,17 +598,17 @@ static struct snd_soc_dai_driver ak4497_dai = {
 
 static void ak4458_power_off(struct ak4458_priv *ak4458)
 {
-   if (ak4458->reset_gpiod) {
-   gpiod_set_value_cansleep(ak4458->reset_gpiod, 0);
-   usleep_range(1000, 2000);
+   if (ak4458->reset) {
+   reset_control_assert(ak4458->reset);
+   msleep(20);
}
 }
 
 static void ak4458_power_on(struct ak4458_priv *ak4458)
 {
-   if (ak4458->reset_gpiod) {
-   gpiod_set_value_cansleep(ak4458->reset_gpiod, 1);
-   usleep_range(1000, 2000);
+   if (ak4458->reset) {
+   reset_control_deassert(ak4458->reset);
+   msleep(20);
}
 }
 
@@ -685,7 +686,6 @@ static int __maybe_unused ak4458_runtime_resume(struct 
device *dev)
if (ak4458->mute_gpiod)
gpiod_set_value_cansleep(ak4458->mute_gpiod, 1);
 
-   ak4458_power_off(ak4458);
ak4458_power_on(ak4458);
 
regcache_cache_only(ak4458->regmap, false);
@@ -771,10 +771,9 @@ static int ak4458_i2c_probe(struct i2c_client *i2c)
 
ak4458->drvdata = of_device_get_match_data(>dev);
 
-   ak4458->reset_gpiod = devm_gpiod_get_optional(ak4458->dev, "reset",
- GPIOD_OUT_LOW);
-   if (IS_ERR(ak4458->reset_gpiod))
-   return PTR_ERR(ak4458->reset_gpiod);
+   ak4458->reset = devm_reset_control_get_optional_shared(ak4458->dev, 
NULL);
+   if (IS_ERR(ak4458->reset))
+   return PTR_ERR(ak4458->reset);
 
ak4458->mute_gpiod = devm_gpiod_get_optional(ak4458->dev, "mute",
 GPIOD_OUT_LOW);
-- 
2.26.2



[PATCH] ASoC: fsl_xcvr: fix break condition

2020-11-02 Thread Viorel Suman (OSS)
From: Viorel Suman 

The break condition copied by mistake as same
as loop condition in the previous version, but must
be the opposite. So fix it.

Signed-off-by: Viorel Suman 
---
 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 c055179e6d11..2a28810d0e29 100644
--- a/sound/soc/fsl/fsl_xcvr.c
+++ b/sound/soc/fsl/fsl_xcvr.c
@@ -247,7 +247,7 @@ static int fsl_xcvr_ai_write(struct fsl_xcvr *xcvr, u8 reg, 
u32 data, bool phy)
regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_TOG, idx);
 
ret = regmap_read_poll_timeout(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL, val,
-  (val & idx) != ((val & tidx) >> 1),
+  (val & idx) == ((val & tidx) >> 1),
   10, 1);
if (ret)
dev_err(dev, "AI timeout: failed to set %s reg 0x%02x=0x%08x\n",
-- 
2.26.2



[PATCH v4 0/2] DAI driver for new XCVR IP

2020-10-13 Thread Viorel Suman (OSS)
From: Viorel Suman 

DAI driver for new XCVR IP found in i.MX8MP.

Viorel Suman (2):
  ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver
  ASoC: dt-bindings: fsl_xcvr: Add document for XCVR

Changes since v1:
 - improved 6- and 12-ch layout comment
 - used regmap polling function, improved
   clocks handling in runtime_resume
 - added FW size check in FW load function,
   improved IRQ handler, removed dummy IRQ handlers
 - fixed yaml file

Changes since v2:
 - used devm_reset_control_get_exclusive instead of of_reset_control_get
 - moved reset_control_assert into runtime_suspend

Changes since v3:
 - removed "firmware-name" DTS property from both documentation and
   source code by porting it into SoC specific 'compatible' data structure.

 .../devicetree/bindings/sound/fsl,xcvr.yaml   |  104 ++
 sound/soc/fsl/Kconfig |   10 +
 sound/soc/fsl/Makefile|2 +
 sound/soc/fsl/fsl_xcvr.c  | 1359 +
 sound/soc/fsl/fsl_xcvr.h  |  266 
 5 files changed, 1741 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
 create mode 100644 sound/soc/fsl/fsl_xcvr.c
 create mode 100644 sound/soc/fsl/fsl_xcvr.h

-- 
2.26.2



[PATCH v4 2/2] ASoC: dt-bindings: fsl_xcvr: Add document for XCVR

2020-10-13 Thread Viorel Suman (OSS)
From: Viorel Suman 

XCVR (Audio Transceiver) is a new IP module found on i.MX8MP.

Signed-off-by: Viorel Suman 
---
 .../devicetree/bindings/sound/fsl,xcvr.yaml   | 104 ++
 1 file changed, 104 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,xcvr.yaml

diff --git a/Documentation/devicetree/bindings/sound/fsl,xcvr.yaml 
b/Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
new file mode 100644
index ..223b8ea693dc
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
@@ -0,0 +1,104 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/fsl,xcvr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP Audio Transceiver (XCVR) Controller
+
+maintainers:
+  - Viorel Suman 
+
+description: |
+  NXP XCVR (Audio Transceiver) is a on-chip functional module
+  that allows CPU to receive and transmit digital audio via
+  HDMI2.1 eARC, HDMI1.4 ARC and SPDIF.
+
+properties:
+  $nodename:
+pattern: "^xcvr@.*"
+
+  compatible:
+enum:
+  - fsl,imx8mp-xcvr
+
+  reg:
+items:
+  - description: 20K RAM for code and data
+  - description: registers space
+  - description: RX FIFO address
+  - description: TX FIFO address
+
+  reg-names:
+items:
+  - const: ram
+  - const: regs
+  - const: rxfifo
+  - const: txfifo
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: Peripheral clock
+  - description: PHY clock
+  - description: SPBA clock
+  - description: PLL clock
+
+  clock-names:
+items:
+  - const: ipg
+  - const: phy
+  - const: spba
+  - const: pll_ipg
+
+  dmas:
+items:
+  - description: DMA controller phandle and request line for RX
+  - description: DMA controller phandle and request line for TX
+
+  dma-names:
+items:
+  - const: rx
+  - const: tx
+
+  resets:
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - clocks
+  - clock-names
+  - dmas
+  - dma-names
+  - resets
+
+additionalProperties: false
+
+examples:
+  - |
+#include 
+#include 
+#include 
+
+xcvr: xcvr@30cc {
+   compatible = "fsl,imx8mp-xcvr";
+   reg = <0x30cc 0x800>,
+ <0x30cc0800 0x400>,
+ <0x30cc0c00 0x080>,
+ <0x30cc0e00 0x080>;
+   reg-names = "ram", "regs", "rxfifo", "txfifo";
+   interrupts = <0x0 128 IRQ_TYPE_LEVEL_HIGH>;
+   clocks = <_clk IMX8MP_CLK_AUDIOMIX_EARC_IPG>,
+<_clk IMX8MP_CLK_AUDIOMIX_EARC_PHY>,
+<_clk IMX8MP_CLK_AUDIOMIX_SPBA2_ROOT>,
+<_clk IMX8MP_CLK_AUDIOMIX_AUDPLL_ROOT>;
+   clock-names = "ipg", "phy", "spba", "pll_ipg";
+   dmas = < 30 2 0>, < 31 2 0>;
+   dma-names = "rx", "tx";
+   resets = <_reset 0>;
+};
-- 
2.26.2



[PATCH v4 1/2] ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver

2020-10-13 Thread Viorel Suman (OSS)
From: Viorel Suman 

XCVR (Audio Transceiver) is a on-chip functional module found
on i.MX8MP. It support HDMI2.1 eARC, HDMI1.4 ARC and SPDIF.

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/Kconfig|   10 +
 sound/soc/fsl/Makefile   |2 +
 sound/soc/fsl/fsl_xcvr.c | 1359 ++
 sound/soc/fsl/fsl_xcvr.h |  266 
 4 files changed, 1637 insertions(+)
 create mode 100644 sound/soc/fsl/fsl_xcvr.c
 create mode 100644 sound/soc/fsl/fsl_xcvr.h

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 3f76ff71ea47..d04b64d32dc1 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -95,6 +95,16 @@ config SND_SOC_FSL_EASRC
  destination sample rate. It is a new design module compare with the
  old ASRC.
 
+config SND_SOC_FSL_XCVR
+   tristate "NXP Audio Transceiver (XCVR) module support"
+   select REGMAP_MMIO
+   select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
+   select SND_SOC_GENERIC_DMAENGINE_PCM
+   help
+ Say Y if you want to add Audio Transceiver (XCVR) support for NXP
+ iMX CPUs. XCVR is a digital module that supports HDMI2.1 eARC,
+ HDMI1.4 ARC and SPDIF.
+
 config SND_SOC_FSL_UTILS
tristate
 
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index b835eebf8825..1d2231f9cc47 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -25,6 +25,7 @@ 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
+snd-soc-fsl-xcvr-objs := fsl_xcvr.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
@@ -38,6 +39,7 @@ 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
+obj-$(CONFIG_SND_SOC_FSL_XCVR) += snd-soc-fsl-xcvr.o
 
 # MPC5200 Platform Support
 obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o
diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
new file mode 100644
index ..c055179e6d11
--- /dev/null
+++ b/sound/soc/fsl/fsl_xcvr.c
@@ -0,0 +1,1359 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright 2019 NXP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fsl_xcvr.h"
+#include "imx-pcm.h"
+
+#define FSL_XCVR_CAPDS_SIZE256
+
+struct fsl_xcvr_soc_data {
+   const char *fw_name;
+};
+
+struct fsl_xcvr {
+   const struct fsl_xcvr_soc_data *soc_data;
+   struct platform_device *pdev;
+   struct regmap *regmap;
+   struct clk *ipg_clk;
+   struct clk *pll_ipg_clk;
+   struct clk *phy_clk;
+   struct clk *spba_clk;
+   struct reset_control *reset;
+   u8 streams;
+   u32 mode;
+   u32 arc_mode;
+   void __iomem *ram_addr;
+   struct snd_dmaengine_dai_dma_data dma_prms_rx;
+   struct snd_dmaengine_dai_dma_data dma_prms_tx;
+   struct snd_aes_iec958 rx_iec958;
+   struct snd_aes_iec958 tx_iec958;
+   u8 cap_ds[FSL_XCVR_CAPDS_SIZE];
+};
+
+static const struct fsl_xcvr_pll_conf {
+   u8 mfi;   /* min=0x18, max=0x38 */
+   u32 mfn;  /* signed int, 2's compl., min=0x3FFF, max=0x0001 */
+   u32 mfd;  /* unsigned int */
+   u32 fout; /* Fout = Fref*(MFI + MFN/MFD), Fref is 24MHz */
+} fsl_xcvr_pll_cfg[] = {
+   { .mfi = 54, .mfn = 1,  .mfd = 6,   .fout = 13, }, /* 1.3 GHz */
+   { .mfi = 32, .mfn = 96, .mfd = 125, .fout = 786432000, },  /* 8000 Hz */
+   { .mfi = 30, .mfn = 66, .mfd = 625, .fout = 722534400, },  /* 11025 Hz 
*/
+   { .mfi = 29, .mfn = 1,  .mfd = 6,   .fout = 7, },  /* 700 MHz */
+};
+
+/*
+ * HDMI2.1 spec defines 6- and 12-channels layout for one bit audio
+ * stream. Todo: to check how this case can be considered below
+ */
+static const u32 fsl_xcvr_earc_channels[] = { 1, 2, 8, 16, 32, };
+static const struct snd_pcm_hw_constraint_list fsl_xcvr_earc_channels_constr = 
{
+   .count = ARRAY_SIZE(fsl_xcvr_earc_channels),
+   .list = fsl_xcvr_earc_channels,
+};
+
+static const u32 fsl_xcvr_earc_rates[] = {
+   32000, 44100, 48000, 64000, 88200, 96000,
+   128000, 176400, 192000, 256000, 352800, 384000,
+   512000, 705600, 768000, 1024000, 1411200, 1536000,
+};
+static const struct snd_pcm_hw_constraint_list fsl_xcvr_earc_rates_constr = {
+   .count = ARRAY_SIZE(fsl_xcvr_earc_rates),
+   .list = fsl_xcvr_earc_rates,
+};
+
+static const u32 fsl_xcvr_spdif_channels[] = { 2, };
+static const struct snd_pcm_hw_constraint_list fsl_xcvr_spdif_channels_constr 
= {
+   .count = ARRAY_SIZE(fsl_xcvr_spdif_channels),
+   .list = fsl_xcvr_spdif_channels,
+};
+
+static const u32 fsl_xcvr_spdif_rates[] = {
+   32000, 44100, 48000

RE: [PATCH v3 2/2] ASoC: dt-bindings: fsl_xcvr: Add document for XCVR

2020-10-13 Thread Viorel Suman (OSS)
Hi Rob,

Thank you for review, fixed in V4.

/Viorel

> -Original Message-
> From: Rob Herring [mailto:r...@kernel.org]
> Sent: Tuesday, October 6, 2020 9:35 PM
> To: Viorel Suman (OSS) 
> Cc: Liam Girdwood ; Mark Brown
> ; Jaroslav Kysela ; Takashi Iwai
> ; Timur Tabi ; Nicolin Chen
> ; Xiubo Li ; Fabio Estevam
> ; Shengjiu Wang ; Philipp
> Zabel ; Cosmin-Gabriel Samoila
> ; Viorel Suman ; Matthias
> Schiffer ; alsa-de...@alsa-project.org;
> devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; linuxppc-
> d...@lists.ozlabs.org; dl-linux-imx ; Viorel Suman
> 
> Subject: Re: [PATCH v3 2/2] ASoC: dt-bindings: fsl_xcvr: Add document for XCVR
> 
> On Tue, Sep 29, 2020 at 12:19:27PM +0300, Viorel Suman (OSS) wrote:
> > From: Viorel Suman 
> >
> > XCVR (Audio Transceiver) is a new IP module found on i.MX8MP.
> >
> > Signed-off-by: Viorel Suman 
> > ---
> >  .../devicetree/bindings/sound/fsl,xcvr.yaml| 103
> +
> >  1 file changed, 103 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
> >
> > diff --git a/Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
> > b/Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
> > new file mode 100644
> > index ..8abab2d
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
> > @@ -0,0 +1,103 @@
> > +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) %YAML 1.2
> > +---
> > +$id: http://devicetree.org/schemas/sound/fsl,xcvr.yaml#
> > +$schema: http://devicetree.org/meta-schemas/core.yaml#
> > +
> > +title: NXP Audio Transceiver (XCVR) Controller
> > +
> > +maintainers:
> > +  - Viorel Suman 
> > +
> > +properties:
> > +  $nodename:
> > +pattern: "^xcvr@.*"
> > +
> > +  compatible:
> > +const: fsl,imx8mp-xcvr
> > +
> > +  reg:
> > +items:
> > +  - description: 20K RAM for code and data
> > +  - description: registers space
> > +  - description: RX FIFO address
> > +  - description: TX FIFO address
> > +
> > +  reg-names:
> > +items:
> > +  - const: ram
> > +  - const: regs
> > +  - const: rxfifo
> > +  - const: txfifo
> > +
> > +  interrupts:
> > +maxItems: 1
> > +
> > +  clocks:
> > +items:
> > +  - description: Peripheral clock
> > +  - description: PHY clock
> > +  - description: SPBA clock
> > +  - description: PLL clock
> > +
> > +  clock-names:
> > +items:
> > +  - const: ipg
> > +  - const: phy
> > +  - const: spba
> > +  - const: pll_ipg
> > +
> > +  dmas:
> > +maxItems: 2
> > +
> > +  dma-names:
> > +items:
> > +  - const: rx
> > +  - const: tx
> > +
> > +  firmware-name:
> > +$ref: /schemas/types.yaml#/definitions/string
> > +const: imx/xcvr/xcvr-imx8mp.bin
> > +description: |
> > +  Should contain the name of the default firmware image
> > +  file located on the firmware search path
> 
> We generally only have this if the name/path can't be fixed (per
> compatible) in the driver. Given you only have 1 possible value, that doesn't
> seem to be the case here.
> 
> > +
> > +  resets:
> > +maxItems: 1
> > +
> > +required:
> > +  - compatible
> > +  - reg
> > +  - reg-names
> > +  - interrupts
> > +  - clocks
> > +  - clock-names
> > +  - dmas
> > +  - dma-names
> > +  - firmware-name
> > +  - resets
> 
> additionalProperties: false
> 
> > +
> > +examples:
> > +  - |
> > +#include 
> > +#include 
> > +#include 
> > +
> > +xcvr: xcvr@30cc {
> > +   compatible = "fsl,imx8mp-xcvr";
> > +   reg = <0x30cc 0x800>,
> > + <0x30cc0800 0x400>,
> > + <0x30cc0c00 0x080>,
> > + <0x30cc0e00 0x080>;
> > +   reg-names = "ram", "regs", "rxfifo", "txfifo";
> > +   interrupts = <0x0 128 IRQ_TYPE_LEVEL_HIGH>;
> > +   clocks = <_clk IMX8MP_CLK_AUDIOMIX_EARC_IPG>,
> > +<_clk IMX8MP_CLK_AUDIOMIX_EARC_PHY>,
> > +<_clk IMX8MP_CLK_AUDIOMIX_SPBA2_ROOT>,
> > +<_clk IMX8MP_CLK_AUDIOMIX_AUDPLL_ROOT>;
> > +   clock-names = "ipg", "phy", "spba", "pll_ipg";
> > +   dmas = < 30 2 0>, < 31 2 0>;
> > +   dma-names = "rx", "tx";
> > +   firmware-name = "imx/xcvr/xcvr-imx8mp.bin";
> > +   resets = <_reset 0>;
> > +};
> > --
> > 2.7.4
> >


RE: [PATCH v2 1/2] ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver

2020-09-29 Thread Viorel Suman (OSS)
Hi Philipp,

Thank you for your review, please check my comments inline.

/Viorel

> -Original Message-
> From: Philipp Zabel [mailto:p...@pengutronix.de]
> Sent: Tuesday, September 22, 2020 3:09 PM
> To: Viorel Suman (OSS) 
> Cc: Liam Girdwood ; Mark Brown
> ; Rob Herring ; Jaroslav Kysela
> ; Takashi Iwai ; Timur Tabi
> ; Nicolin Chen ; Xiubo Li
> ; Fabio Estevam ; Shengjiu
> Wang ; Viorel Suman ;
> Matthias Schiffer ; Cosmin-Gabriel
> Samoila ; alsa-de...@alsa-project.org;
> devicet...@vger.kernel.org; linux-kernel@vger.kernel.org; linuxppc-
> d...@lists.ozlabs.org; dl-linux-imx ; Viorel Suman
> 
> Subject: Re: [PATCH v2 1/2] ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver
> 
> On Mon, Sep 21, 2020 at 10:08:11PM +0300, Viorel Suman (OSS) wrote:
> > From: Viorel Suman 
> >
> > XCVR (Audio Transceiver) is a on-chip functional module found on
> > i.MX8MP. It support HDMI2.1 eARC, HDMI1.4 ARC and SPDIF.
> >
> > Signed-off-by: Viorel Suman 
> > ---
> >  sound/soc/fsl/Kconfig|   10 +
> >  sound/soc/fsl/Makefile   |2 +
> >  sound/soc/fsl/fsl_xcvr.c | 1343
> > ++
> >  sound/soc/fsl/fsl_xcvr.h |  266 +
> >  4 files changed, 1621 insertions(+)
> >  create mode 100644 sound/soc/fsl/fsl_xcvr.c  create mode 100644
> > sound/soc/fsl/fsl_xcvr.h
> >
> > diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig index
> > 3f76ff7..d04b64d 100644
> > --- a/sound/soc/fsl/Kconfig
> > +++ b/sound/soc/fsl/Kconfig
> > @@ -95,6 +95,16 @@ config SND_SOC_FSL_EASRC
> >   destination sample rate. It is a new design module compare with the
> >   old ASRC.
> >
> > +config SND_SOC_FSL_XCVR
> > +   tristate "NXP Audio Transceiver (XCVR) module support"
> > +   select REGMAP_MMIO
> > +   select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
> > +   select SND_SOC_GENERIC_DMAENGINE_PCM
> > +   help
> > + Say Y if you want to add Audio Transceiver (XCVR) support for NXP
> > + iMX CPUs. XCVR is a digital module that supports HDMI2.1 eARC,
> > + HDMI1.4 ARC and SPDIF.
> > +
> >  config SND_SOC_FSL_UTILS
> > tristate
> >
> > diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile index
> > b835eeb..1d2231f 100644
> > --- a/sound/soc/fsl/Makefile
> > +++ b/sound/soc/fsl/Makefile
> > @@ -25,6 +25,7 @@ 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
> > +snd-soc-fsl-xcvr-objs := fsl_xcvr.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 @@
> > -38,6 +39,7 @@ 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
> > +obj-$(CONFIG_SND_SOC_FSL_XCVR) += snd-soc-fsl-xcvr.o
> >
> >  # MPC5200 Platform Support
> >  obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o diff --git
> > a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c new file mode
> > 100644 index ..7391bca
> > --- /dev/null
> > +++ b/sound/soc/fsl/fsl_xcvr.c
> > @@ -0,0 +1,1343 @@
> [...]
> > +static int fsl_xcvr_probe(struct platform_device *pdev) {
> > +   struct device *dev = >dev;
> > +   struct device_node *np = dev->of_node;
> > +   const struct of_device_id *of_id;
> > +   struct fsl_xcvr *xcvr;
> > +   struct resource *ram_res, *regs_res, *rx_res, *tx_res;
> > +   void __iomem *regs;
> > +   int ret, irq;
> > +
> > +   of_id = of_match_device(fsl_xcvr_dt_ids, dev);
> > +   if (!of_id)
> > +   return -EINVAL;
> > +
> > +   xcvr = devm_kzalloc(dev, sizeof(*xcvr), GFP_KERNEL);
> > +   if (!xcvr)
> > +   return -ENOMEM;
> > +
> > +   xcvr->pdev = pdev;
> > +   xcvr->ipg_clk = devm_clk_get(dev, "ipg");
> > +   if (IS_ERR(xcvr->ipg_clk)) {
> > +   dev_err(dev, "failed to get ipg clock\n");
> > +   return PTR_ERR(xcvr->ipg_clk);
> > +   }
> > +
> > +   xcvr->phy_clk = devm_clk_get(dev, "phy");
> > +   if (IS_ERR(xcvr->phy_clk)) {
> > +   dev_err(dev, "failed to get phy clock\n");
> > +   return PTR_ERR(xcvr->phy_clk);
> > +   }
> > +
> > +   xcvr->spba_clk = devm_clk_get(dev, "spba");

[PATCH v3 0/2] DAI driver for new XCVR IP

2020-09-29 Thread Viorel Suman (OSS)
From: Viorel Suman 

DAI driver for new XCVR IP found in i.MX8MP.

Viorel Suman (2):
  ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver
  ASoC: dt-bindings: fsl_xcvr: Add document for XCVR

Changes since v1:
 - improved 6- and 12-ch layout comment
 - used regmap polling function, improved
   clocks handling in runtime_resume
 - added FW size check in FW load function,
   improved IRQ handler, removed dummy IRQ handlers
 - fixed yaml file

Changes since v2:
 - used devm_reset_control_get_exclusive instead of of_reset_control_get
 - moved reset_control_assert into runtime_suspend

 .../devicetree/bindings/sound/fsl,xcvr.yaml|  103 ++
 sound/soc/fsl/Kconfig  |   10 +
 sound/soc/fsl/Makefile |2 +
 sound/soc/fsl/fsl_xcvr.c   | 1356 
 sound/soc/fsl/fsl_xcvr.h   |  266 
 5 files changed, 1737 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
 create mode 100644 sound/soc/fsl/fsl_xcvr.c
 create mode 100644 sound/soc/fsl/fsl_xcvr.h

-- 
2.7.4



[PATCH v3 1/2] ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver

2020-09-29 Thread Viorel Suman (OSS)
From: Viorel Suman 

XCVR (Audio Transceiver) is a on-chip functional module found
on i.MX8MP. It support HDMI2.1 eARC, HDMI1.4 ARC and SPDIF.

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/Kconfig|   10 +
 sound/soc/fsl/Makefile   |2 +
 sound/soc/fsl/fsl_xcvr.c | 1356 ++
 sound/soc/fsl/fsl_xcvr.h |  266 +
 4 files changed, 1634 insertions(+)
 create mode 100644 sound/soc/fsl/fsl_xcvr.c
 create mode 100644 sound/soc/fsl/fsl_xcvr.h

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 3f76ff7..d04b64d 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -95,6 +95,16 @@ config SND_SOC_FSL_EASRC
  destination sample rate. It is a new design module compare with the
  old ASRC.
 
+config SND_SOC_FSL_XCVR
+   tristate "NXP Audio Transceiver (XCVR) module support"
+   select REGMAP_MMIO
+   select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
+   select SND_SOC_GENERIC_DMAENGINE_PCM
+   help
+ Say Y if you want to add Audio Transceiver (XCVR) support for NXP
+ iMX CPUs. XCVR is a digital module that supports HDMI2.1 eARC,
+ HDMI1.4 ARC and SPDIF.
+
 config SND_SOC_FSL_UTILS
tristate
 
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index b835eeb..1d2231f 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -25,6 +25,7 @@ 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
+snd-soc-fsl-xcvr-objs := fsl_xcvr.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
@@ -38,6 +39,7 @@ 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
+obj-$(CONFIG_SND_SOC_FSL_XCVR) += snd-soc-fsl-xcvr.o
 
 # MPC5200 Platform Support
 obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o
diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
new file mode 100644
index ..148bf48
--- /dev/null
+++ b/sound/soc/fsl/fsl_xcvr.c
@@ -0,0 +1,1356 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright 2019 NXP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fsl_xcvr.h"
+#include "imx-pcm.h"
+
+#define FSL_XCVR_CAPDS_SIZE256
+
+struct fsl_xcvr {
+   struct platform_device *pdev;
+   struct regmap *regmap;
+   struct clk *ipg_clk;
+   struct clk *pll_ipg_clk;
+   struct clk *phy_clk;
+   struct clk *spba_clk;
+   struct reset_control *reset;
+   const char *fw_name;
+   u8 streams;
+   u32 mode;
+   u32 arc_mode;
+   void __iomem *ram_addr;
+   struct snd_dmaengine_dai_dma_data dma_prms_rx;
+   struct snd_dmaengine_dai_dma_data dma_prms_tx;
+   struct snd_aes_iec958 rx_iec958;
+   struct snd_aes_iec958 tx_iec958;
+   u8 cap_ds[FSL_XCVR_CAPDS_SIZE];
+};
+
+static const struct fsl_xcvr_pll_conf {
+   u8 mfi;   /* min=0x18, max=0x38 */
+   u32 mfn;  /* signed int, 2's compl., min=0x3FFF, max=0x0001 */
+   u32 mfd;  /* unsigned int */
+   u32 fout; /* Fout = Fref*(MFI + MFN/MFD), Fref is 24MHz */
+} fsl_xcvr_pll_cfg[] = {
+   { .mfi = 54, .mfn = 1,  .mfd = 6,   .fout = 13, }, /* 1.3 GHz */
+   { .mfi = 32, .mfn = 96, .mfd = 125, .fout = 786432000, },  /* 8000 Hz */
+   { .mfi = 30, .mfn = 66, .mfd = 625, .fout = 722534400, },  /* 11025 Hz 
*/
+   { .mfi = 29, .mfn = 1,  .mfd = 6,   .fout = 7, },  /* 700 MHz */
+};
+
+/*
+ * HDMI2.1 spec defines 6- and 12-channels layout for one bit audio
+ * stream. Todo: to check how this case can be considered below
+ */
+static const u32 fsl_xcvr_earc_channels[] = { 1, 2, 8, 16, 32, };
+static const struct snd_pcm_hw_constraint_list fsl_xcvr_earc_channels_constr = 
{
+   .count = ARRAY_SIZE(fsl_xcvr_earc_channels),
+   .list = fsl_xcvr_earc_channels,
+};
+
+static const u32 fsl_xcvr_earc_rates[] = {
+   32000, 44100, 48000, 64000, 88200, 96000,
+   128000, 176400, 192000, 256000, 352800, 384000,
+   512000, 705600, 768000, 1024000, 1411200, 1536000,
+};
+static const struct snd_pcm_hw_constraint_list fsl_xcvr_earc_rates_constr = {
+   .count = ARRAY_SIZE(fsl_xcvr_earc_rates),
+   .list = fsl_xcvr_earc_rates,
+};
+
+static const u32 fsl_xcvr_spdif_channels[] = { 2, };
+static const struct snd_pcm_hw_constraint_list fsl_xcvr_spdif_channels_constr 
= {
+   .count = ARRAY_SIZE(fsl_xcvr_spdif_channels),
+   .list = fsl_xcvr_spdif_channels,
+};
+
+static const u32 fsl_xcvr_spdif_rates[] = {
+   32000, 44100, 48000, 88200, 96000, 176400, 192000,
+};
+static const struct snd_pcm_hw_constraint_list fsl_xcvr_spdif_r

[PATCH v3 2/2] ASoC: dt-bindings: fsl_xcvr: Add document for XCVR

2020-09-29 Thread Viorel Suman (OSS)
From: Viorel Suman 

XCVR (Audio Transceiver) is a new IP module found on i.MX8MP.

Signed-off-by: Viorel Suman 
---
 .../devicetree/bindings/sound/fsl,xcvr.yaml| 103 +
 1 file changed, 103 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,xcvr.yaml

diff --git a/Documentation/devicetree/bindings/sound/fsl,xcvr.yaml 
b/Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
new file mode 100644
index ..8abab2d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/fsl,xcvr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP Audio Transceiver (XCVR) Controller
+
+maintainers:
+  - Viorel Suman 
+
+properties:
+  $nodename:
+pattern: "^xcvr@.*"
+
+  compatible:
+const: fsl,imx8mp-xcvr
+
+  reg:
+items:
+  - description: 20K RAM for code and data
+  - description: registers space
+  - description: RX FIFO address
+  - description: TX FIFO address
+
+  reg-names:
+items:
+  - const: ram
+  - const: regs
+  - const: rxfifo
+  - const: txfifo
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: Peripheral clock
+  - description: PHY clock
+  - description: SPBA clock
+  - description: PLL clock
+
+  clock-names:
+items:
+  - const: ipg
+  - const: phy
+  - const: spba
+  - const: pll_ipg
+
+  dmas:
+maxItems: 2
+
+  dma-names:
+items:
+  - const: rx
+  - const: tx
+
+  firmware-name:
+$ref: /schemas/types.yaml#/definitions/string
+const: imx/xcvr/xcvr-imx8mp.bin
+description: |
+  Should contain the name of the default firmware image
+  file located on the firmware search path
+
+  resets:
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - clocks
+  - clock-names
+  - dmas
+  - dma-names
+  - firmware-name
+  - resets
+
+examples:
+  - |
+#include 
+#include 
+#include 
+
+xcvr: xcvr@30cc {
+   compatible = "fsl,imx8mp-xcvr";
+   reg = <0x30cc 0x800>,
+ <0x30cc0800 0x400>,
+ <0x30cc0c00 0x080>,
+ <0x30cc0e00 0x080>;
+   reg-names = "ram", "regs", "rxfifo", "txfifo";
+   interrupts = <0x0 128 IRQ_TYPE_LEVEL_HIGH>;
+   clocks = <_clk IMX8MP_CLK_AUDIOMIX_EARC_IPG>,
+<_clk IMX8MP_CLK_AUDIOMIX_EARC_PHY>,
+<_clk IMX8MP_CLK_AUDIOMIX_SPBA2_ROOT>,
+<_clk IMX8MP_CLK_AUDIOMIX_AUDPLL_ROOT>;
+   clock-names = "ipg", "phy", "spba", "pll_ipg";
+   dmas = < 30 2 0>, < 31 2 0>;
+   dma-names = "rx", "tx";
+   firmware-name = "imx/xcvr/xcvr-imx8mp.bin";
+   resets = <_reset 0>;
+};
-- 
2.7.4



[PATCH v2 1/2] ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver

2020-09-21 Thread Viorel Suman (OSS)
From: Viorel Suman 

XCVR (Audio Transceiver) is a on-chip functional module found
on i.MX8MP. It support HDMI2.1 eARC, HDMI1.4 ARC and SPDIF.

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/Kconfig|   10 +
 sound/soc/fsl/Makefile   |2 +
 sound/soc/fsl/fsl_xcvr.c | 1343 ++
 sound/soc/fsl/fsl_xcvr.h |  266 +
 4 files changed, 1621 insertions(+)
 create mode 100644 sound/soc/fsl/fsl_xcvr.c
 create mode 100644 sound/soc/fsl/fsl_xcvr.h

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 3f76ff7..d04b64d 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -95,6 +95,16 @@ config SND_SOC_FSL_EASRC
  destination sample rate. It is a new design module compare with the
  old ASRC.
 
+config SND_SOC_FSL_XCVR
+   tristate "NXP Audio Transceiver (XCVR) module support"
+   select REGMAP_MMIO
+   select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
+   select SND_SOC_GENERIC_DMAENGINE_PCM
+   help
+ Say Y if you want to add Audio Transceiver (XCVR) support for NXP
+ iMX CPUs. XCVR is a digital module that supports HDMI2.1 eARC,
+ HDMI1.4 ARC and SPDIF.
+
 config SND_SOC_FSL_UTILS
tristate
 
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index b835eeb..1d2231f 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -25,6 +25,7 @@ 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
+snd-soc-fsl-xcvr-objs := fsl_xcvr.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
@@ -38,6 +39,7 @@ 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
+obj-$(CONFIG_SND_SOC_FSL_XCVR) += snd-soc-fsl-xcvr.o
 
 # MPC5200 Platform Support
 obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o
diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
new file mode 100644
index ..7391bca
--- /dev/null
+++ b/sound/soc/fsl/fsl_xcvr.c
@@ -0,0 +1,1343 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright 2019 NXP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fsl_xcvr.h"
+#include "imx-pcm.h"
+
+#define FSL_XCVR_CAPDS_SIZE256
+
+struct fsl_xcvr {
+   struct platform_device *pdev;
+   struct regmap *regmap;
+   struct clk *ipg_clk;
+   struct clk *pll_ipg_clk;
+   struct clk *phy_clk;
+   struct clk *spba_clk;
+   struct reset_control *reset;
+   const char *fw_name;
+   u8 streams;
+   u32 mode;
+   u32 arc_mode;
+   void __iomem *ram_addr;
+   struct snd_dmaengine_dai_dma_data dma_prms_rx;
+   struct snd_dmaengine_dai_dma_data dma_prms_tx;
+   struct snd_aes_iec958 rx_iec958;
+   struct snd_aes_iec958 tx_iec958;
+   u8 cap_ds[FSL_XCVR_CAPDS_SIZE];
+};
+
+static const struct fsl_xcvr_pll_conf {
+   u8 mfi;   /* min=0x18, max=0x38 */
+   u32 mfn;  /* signed int, 2's compl., min=0x3FFF, max=0x0001 */
+   u32 mfd;  /* unsigned int */
+   u32 fout; /* Fout = Fref*(MFI + MFN/MFD), Fref is 24MHz */
+} fsl_xcvr_pll_cfg[] = {
+   { .mfi = 54, .mfn = 1,  .mfd = 6,   .fout = 13, }, /* 1.3 GHz */
+   { .mfi = 32, .mfn = 96, .mfd = 125, .fout = 786432000, },  /* 8000 Hz */
+   { .mfi = 30, .mfn = 66, .mfd = 625, .fout = 722534400, },  /* 11025 Hz 
*/
+   { .mfi = 29, .mfn = 1,  .mfd = 6,   .fout = 7, },  /* 700 MHz */
+};
+
+/*
+ * HDMI2.1 spec defines 6- and 12-channels layout for one bit audio
+ * stream. Todo: to check how this case can be considered below
+ */
+static const u32 fsl_xcvr_earc_channels[] = { 1, 2, 8, 16, 32, };
+static const struct snd_pcm_hw_constraint_list fsl_xcvr_earc_channels_constr = 
{
+   .count = ARRAY_SIZE(fsl_xcvr_earc_channels),
+   .list = fsl_xcvr_earc_channels,
+};
+
+static const u32 fsl_xcvr_earc_rates[] = {
+   32000, 44100, 48000, 64000, 88200, 96000,
+   128000, 176400, 192000, 256000, 352800, 384000,
+   512000, 705600, 768000, 1024000, 1411200, 1536000,
+};
+static const struct snd_pcm_hw_constraint_list fsl_xcvr_earc_rates_constr = {
+   .count = ARRAY_SIZE(fsl_xcvr_earc_rates),
+   .list = fsl_xcvr_earc_rates,
+};
+
+static const u32 fsl_xcvr_spdif_channels[] = { 2, };
+static const struct snd_pcm_hw_constraint_list fsl_xcvr_spdif_channels_constr 
= {
+   .count = ARRAY_SIZE(fsl_xcvr_spdif_channels),
+   .list = fsl_xcvr_spdif_channels,
+};
+
+static const u32 fsl_xcvr_spdif_rates[] = {
+   32000, 44100, 48000, 88200, 96000, 176400, 192000,
+};
+static const struct snd_pcm_hw_constraint_list fsl_xcvr_spdif_r

[PATCH v2 2/2] ASoC: dt-bindings: fsl_xcvr: Add document for XCVR

2020-09-21 Thread Viorel Suman (OSS)
From: Viorel Suman 

XCVR (Audio Transceiver) is a new IP module found on i.MX8MP.

Signed-off-by: Viorel Suman 
---
 .../devicetree/bindings/sound/fsl,xcvr.yaml| 103 +
 1 file changed, 103 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,xcvr.yaml

diff --git a/Documentation/devicetree/bindings/sound/fsl,xcvr.yaml 
b/Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
new file mode 100644
index ..8abab2d
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/fsl,xcvr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP Audio Transceiver (XCVR) Controller
+
+maintainers:
+  - Viorel Suman 
+
+properties:
+  $nodename:
+pattern: "^xcvr@.*"
+
+  compatible:
+const: fsl,imx8mp-xcvr
+
+  reg:
+items:
+  - description: 20K RAM for code and data
+  - description: registers space
+  - description: RX FIFO address
+  - description: TX FIFO address
+
+  reg-names:
+items:
+  - const: ram
+  - const: regs
+  - const: rxfifo
+  - const: txfifo
+
+  interrupts:
+maxItems: 1
+
+  clocks:
+items:
+  - description: Peripheral clock
+  - description: PHY clock
+  - description: SPBA clock
+  - description: PLL clock
+
+  clock-names:
+items:
+  - const: ipg
+  - const: phy
+  - const: spba
+  - const: pll_ipg
+
+  dmas:
+maxItems: 2
+
+  dma-names:
+items:
+  - const: rx
+  - const: tx
+
+  firmware-name:
+$ref: /schemas/types.yaml#/definitions/string
+const: imx/xcvr/xcvr-imx8mp.bin
+description: |
+  Should contain the name of the default firmware image
+  file located on the firmware search path
+
+  resets:
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - clocks
+  - clock-names
+  - dmas
+  - dma-names
+  - firmware-name
+  - resets
+
+examples:
+  - |
+#include 
+#include 
+#include 
+
+xcvr: xcvr@30cc {
+   compatible = "fsl,imx8mp-xcvr";
+   reg = <0x30cc 0x800>,
+ <0x30cc0800 0x400>,
+ <0x30cc0c00 0x080>,
+ <0x30cc0e00 0x080>;
+   reg-names = "ram", "regs", "rxfifo", "txfifo";
+   interrupts = <0x0 128 IRQ_TYPE_LEVEL_HIGH>;
+   clocks = <_clk IMX8MP_CLK_AUDIOMIX_EARC_IPG>,
+<_clk IMX8MP_CLK_AUDIOMIX_EARC_PHY>,
+<_clk IMX8MP_CLK_AUDIOMIX_SPBA2_ROOT>,
+<_clk IMX8MP_CLK_AUDIOMIX_AUDPLL_ROOT>;
+   clock-names = "ipg", "phy", "spba", "pll_ipg";
+   dmas = < 30 2 0>, < 31 2 0>;
+   dma-names = "rx", "tx";
+   firmware-name = "imx/xcvr/xcvr-imx8mp.bin";
+   resets = <_reset 0>;
+};
-- 
2.7.4



[PATCH v2 0/2] DAI driver for new XCVR IP

2020-09-21 Thread Viorel Suman (OSS)
From: Viorel Suman 

DAI driver for new XCVR IP found in i.MX8MP.

Viorel Suman (2):
  ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver
  ASoC: dt-bindings: fsl_xcvr: Add document for XCVR

Changes since v1:
 - improved 6- and 12-ch layout comment
 - used regmap polling function, improved
   clocks handling in runtime_resume
 - added FW size check in FW load function,
   improved IRQ handler, removed dummy IRQ handlers
 - fixed yaml file

 .../devicetree/bindings/sound/fsl,xcvr.yaml|  103 ++
 sound/soc/fsl/Kconfig  |   10 +
 sound/soc/fsl/Makefile |2 +
 sound/soc/fsl/fsl_xcvr.c   | 1343 
 sound/soc/fsl/fsl_xcvr.h   |  266 
 5 files changed, 1724 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
 create mode 100644 sound/soc/fsl/fsl_xcvr.c
 create mode 100644 sound/soc/fsl/fsl_xcvr.h

-- 
2.7.4



RE: [PATCH 1/2] ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver

2020-09-18 Thread Viorel Suman (OSS)
> On Fri, Sep 18, 2020 at 03:02:39PM +0000, Viorel Suman (OSS) wrote:
> 
> Please fix your mail client to word wrap within paragraphs at something
> substantially less than 80 columns.  Doing this makes your messages much 
> easier
> to read and reply to.
> 

My bad, will do.

> > > > +   regmap_read(regmap, FSL_XCVR_EXT_ISR, );
> > > > +   regmap_write(regmap, FSL_XCVR_EXT_ISR_CLR, isr);
> 
> > > This will unconditionally clear any interrupts, even those we don't
> > > understand - it might be better to only clear bits that are
> > > supported so the IRQ core can complain if there's something unexpected
> showing up.
> 
> > The ARM core registers itself in "fsl_xcvr_prepare" (the code below) just 
> > for a
> subset of all supported interrupts:
> > =
> > ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0,
> >  FSL_XCVR_IRQ_EARC_ALL,
> FSL_XCVR_IRQ_EARC_ALL); =
> > FSL_XCVR_IRQ_EARC_ALL - this mask represents all the interrupts we are
> > interested in and we handle in interrupt handler, But this is just a subset 
> > of all
> interrupts the M0+ core is able to assert. Not very intuitive, I think I need 
> to
> reword it somehow.
> 
> That's not the issue, the issue is that if we get into the ISR we just ack 
> all the bits
> that are flagged by the hardware regardless of if we actually handled them.  
> This
> won't work if there are ever systems that share the interrupt and it works
> against safety/debugging features that the interrupt has in case something 
> goes
> wrong and we get spurious interrupts.
> 

Thank you for explanation, will fix it in next version.

> > > > +   if (isr & FSL_XCVR_IRQ_FIFO_UOFL_ERR)
> > > > +   dev_dbg(dev, "RX/TX FIFO full/empty\n");
> 
> > > Should this be dev_err()?
> 
> > The interrupt may be asserted right before DMA starts to fill the TX FIFO 
> > if I
> recall correctly.
> > I've added it just to debug the IP behavior, will check and change it to 
> > err it in
> next version if it is the case.
> 
> If it does come up normally then a comment or something to explain why this
> happens normally would probably be good.

Sure, ok.


RE: [PATCH 1/2] ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver

2020-09-18 Thread Viorel Suman (OSS)
Hi Mark,

Thank you for your review.
 
> On Wed, Sep 16, 2020 at 12:17:55PM +0300, Viorel Suman (OSS) wrote:
> > +static int fsl_xcvr_load_firmware(struct fsl_xcvr *xcvr) {
> > +   struct device *dev = >pdev->dev;
> > +   const struct firmware *fw;
> > +   int ret = 0, rem, off, out, page = 0, size = FSL_XCVR_REG_OFFSET;
> > +   u32 mask, val;
> > +
> > +   ret = request_firmware(, xcvr->fw_name, dev);
> > +   if (ret) {
> > +   dev_err(dev, "failed to request firmware.\n");
> > +   return ret;
> > +   }
> > +
> > +   rem = fw->size;
> 
> It would be good to see some explicit validation of the image size, at least
> printing an error message if the image is bigger than can be loaded.  The code
> should be safe in that it won't overflow the device region it's writing to 
> but it
> feels like it'd be better to tell people if we spot a problem rather than 
> just silently
> truncating the file.

Make sense, will improve this part in the next version.

> > +static irqreturn_t irq0_isr(int irq, void *devid) {
> > +   struct fsl_xcvr *xcvr = (struct fsl_xcvr *)devid;
> > +   struct device *dev = >pdev->dev;
> > +   struct regmap *regmap = xcvr->regmap;
> > +   void __iomem *reg_ctrl, *reg_buff;
> > +   u32 isr, val, i;
> > +
> > +   regmap_read(regmap, FSL_XCVR_EXT_ISR, );
> > +   regmap_write(regmap, FSL_XCVR_EXT_ISR_CLR, isr);
> 
> This will unconditionally clear any interrupts, even those we don't 
> understand - it
> might be better to only clear bits that are supported so the IRQ core can
> complain if there's something unexpected showing up.

The ARM core registers itself in "fsl_xcvr_prepare" (the code below) just for a 
subset of all supported interrupts: 
=
ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_IER0,
 FSL_XCVR_IRQ_EARC_ALL, FSL_XCVR_IRQ_EARC_ALL);
=
FSL_XCVR_IRQ_EARC_ALL - this mask represents all the interrupts we are 
interested in and we handle in interrupt handler,
But this is just a subset of all interrupts the M0+ core is able to assert. Not 
very intuitive, I think I need to reword it somehow.

> > +   if (isr & FSL_XCVR_IRQ_FIFO_UOFL_ERR)
> > +   dev_dbg(dev, "RX/TX FIFO full/empty\n");
> 
> Should this be dev_err()?

The interrupt may be asserted right before DMA starts to fill the TX FIFO if I 
recall correctly.
I've added it just to debug the IP behavior, will check and change it to err it 
in next version if it is the case.

> > +static irqreturn_t irq1_isr(int irq, void *devid) {
> > +   struct fsl_xcvr *xcvr = (struct fsl_xcvr *)devid;
> > +   struct device *dev = >pdev->dev;
> > +
> > +   dev_dbg(dev, "irq[1]: %d\n", irq);
> > +
> > +   return IRQ_HANDLED;
> > +}
> 
> Is there any value in even requesting this and irq2 given the lack of 
> meaningful
> handling?

No, will remove it in v2.

Thank you,
Viorel



RE: [PATCH 1/2] ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver

2020-09-18 Thread Viorel Suman (OSS)
Hi Nicolin,

Thank you for your review.

> > +static const u32 fsl_xcvr_earc_channels[] = { 1, 2, 8, 16, 32, }; /*
> > +one bit 6, 12 ? */
> 
> What's the meaning of the comments?

Just a thought noted as comment. HDMI2.1 spec defines 6- and 12-channels layout 
when
one bit audio stream is transmitted - I was wandering how can this be enforced. 
Is a @todo like of comment.

> 
> > +static const int fsl_xcvr_phy_arc_cfg[] = {
> > +   FSL_XCVR_PHY_CTRL_ARC_MODE_SE_EN,
> FSL_XCVR_PHY_CTRL_ARC_MODE_CM_EN,
> > +};
> 
> Nit: better be u32 vs. int?

Yes, will fix it in v2.

> 
> > +/** phy: true => phy, false => pll */ static int
> > +fsl_xcvr_ai_write(struct fsl_xcvr *xcvr, u8 reg, u32 data, bool phy)
> > +{
> > +   u32 val, idx, tidx;
> > +
> > +   idx  = BIT(phy ? 26 : 24);
> > +   tidx = BIT(phy ? 27 : 25);
> > +
> > +   regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_CLR, 0xFF);
> > +   regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_SET, reg);
> > +   regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_WDATA, data);
> > +   regmap_write(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL_TOG, idx);
> > +
> > +   do {
> > +   regmap_read(xcvr->regmap, FSL_XCVR_PHY_AI_CTRL, );
> > +   } while ((val & idx) != ((val & tidx) >> 1));
> 
> Might regmap_read_poll_timeout() be better? And it seems to poll intentionally
> with no sleep nor timeout -- would be nice to have a line of comments to 
> explain
> why.

No particular reason to do it with no sleep or timeout here, will check and fix 
it in v2.

> 
> > > +static int fsl_xcvr_runtime_resume(struct device *dev)
> > +{
> > +   struct fsl_xcvr *xcvr = dev_get_drvdata(dev);
> > +   int ret;
> > +
> > +   ret = clk_prepare_enable(xcvr->ipg_clk);
> > +   if (ret) {
> > +   dev_err(dev, "failed to start IPG clock.\n");
> > +   return ret;
> > +   }
> > +
> > +   ret = clk_prepare_enable(xcvr->pll_ipg_clk);
> > +   if (ret) {
> > +   dev_err(dev, "failed to start PLL IPG clock.\n");
> 
> Should it disable ipg_clk?

Yes, thank you, will fix in v2.

> 
> > +   return ret;
> > +   }
> > +
> > +   ret = clk_prepare_enable(xcvr->phy_clk);
> > +   if (ret) {
> > +   dev_err(dev, "failed to start PHY clock: %d\n", ret);
> > +   clk_disable_unprepare(xcvr->ipg_clk);
> 
> Should it disable pll_ipg_clk?

Yes, will fix in v2.

> 
> > +   return ret;
> > +   }
> > +
> > +   ret = clk_prepare_enable(xcvr->spba_clk);
> > +   if (ret) {
> > +   dev_err(dev, "failed to start SPBA clock.\n");
> > +   clk_disable_unprepare(xcvr->phy_clk);
> > +   clk_disable_unprepare(xcvr->ipg_clk);
> 
> Ditto

Ok.

> 
> > +   return ret;
> > +   }
> > +
> > +   regcache_cache_only(xcvr->regmap, false);
> > +   regcache_mark_dirty(xcvr->regmap);
> > +   ret = regcache_sync(xcvr->regmap);
> > +
> > +   if (ret) {
> > +   dev_err(dev, "failed to sync regcache.\n");
> > +   return ret;
> 
> What about those clocks? Probably better to have some error-out labels at the
> end of the function?

Make sense, will fix in v2.

> 
> > +   }
> > +
> > +   reset_control_assert(xcvr->reset);
> > +   reset_control_deassert(xcvr->reset);
> > +
> > +   ret = fsl_xcvr_load_firmware(xcvr);
> > +   if (ret) {
> > +   dev_err(dev, "failed to load firmware.\n");
> > +   return ret;
> 
> Ditto
> 
> > +   }
> > +
> > +   /* Release M0+ reset */
> > +   ret = regmap_update_bits(xcvr->regmap, FSL_XCVR_EXT_CTRL,
> > +FSL_XCVR_EXT_CTRL_CORE_RESET, 0);
> > +   if (ret < 0) {
> > +   dev_err(dev, "M0+ core release failed: %d\n", ret);
> > +   return ret;
> 
> Ditto
> 
> > +   }
> > +   mdelay(50);
> 
> Any reason to use mdelay over msleep for a 50ms wait? May add a line of
> comments if mdelay is a must?

No particular reason, will fix it in v2.

Thank you,
Viorel



[PATCH 2/2] ASoC: dt-bindings: fsl_xcvr: Add document for XCVR

2020-09-16 Thread Viorel Suman (OSS)
From: Viorel Suman 

XCVR (Audio Transceiver) is a new IP module found on i.MX8MP.

Signed-off-by: Viorel Suman 
---
 .../devicetree/bindings/sound/fsl,xcvr.yaml| 104 +
 1 file changed, 104 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,xcvr.yaml

diff --git a/Documentation/devicetree/bindings/sound/fsl,xcvr.yaml 
b/Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
new file mode 100644
index ..d4bb792
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
@@ -0,0 +1,104 @@
+# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause)
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/fsl,xcvr.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: NXP Audio Transceiver (XCVR) Controller
+
+maintainers:
+  - Viorel Suman 
+
+properties:
+  $nodename:
+pattern: "^xcvr@.*"
+
+  compatible:
+const: fsl,imx8mp-xcvr
+
+  reg:
+items:
+  - description: 20K RAM for code and data
+  - description: registers space
+  - description: RX FIFO address
+  - description: TX FIFO address
+
+  reg-names:
+items:
+  - const: ram
+  - const: regs
+  - const: rxfifo
+  - const: txfifo
+
+  interrupts:
+maxItems: 3
+
+  clocks:
+items:
+  - description: Peripheral clock
+  - description: PHY clock
+  - description: SPBA clock
+  - description: PLL clock
+
+  clock-names:
+items:
+  - const: ipg
+  - const: phy
+  - const: spba
+  - const: pll_ipg
+
+  dmas:
+maxItems: 2
+
+  dma-names:
+items:
+  - const: rx
+  - const: tx
+
+  firmware-name:
+$ref: /schemas/types.yaml#/definitions/string
+const: imx/xcvr/xcvr-imx8mp.bin
+description: |
+  Should contain the name of the default firmware image
+  file located on the firmware search path
+
+  resets:
+maxItems: 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - interrupts
+  - clocks
+  - clock-names
+  - dmas
+  - dma-names
+  - firmware-name
+  - resets
+
+examples:
+  - |
+#include 
+#include 
+
+xcvr: xcvr@30cc {
+   compatible = "fsl,imx8mp-xcvr";
+   reg = <0x30cc 0x800>,
+ <0x30cc0800 0x400>,
+ <0x30cc0c00 0x080>,
+ <0x30cc0e00 0x080>;
+   reg-names = "ram", "regs", "rxfifo", "txfifo";
+   interrupts = , /* XCVR IRQ 0 */
+, /* XCVR IRQ 1 */
+; /* XCVR PHY - SPDIF 
wakeup IRQ */
+   clocks = <_clk IMX8MP_CLK_AUDIOMIX_EARC_IPG>,
+<_clk IMX8MP_CLK_AUDIOMIX_EARC_PHY>,
+<_clk IMX8MP_CLK_AUDIOMIX_SPBA2_ROOT>,
+<_clk IMX8MP_CLK_AUDIOMIX_AUDPLL_ROOT>;
+   clock-names = "ipg", "phy", "spba", "pll_ipg";
+   dmas = < 30 2 0>, < 31 2 0>;
+   dma-names = "rx", "tx";
+   firmware-name = "imx/xcvr/xcvr-imx8mp.bin";
+   resets = <_reset 0>;
+};
-- 
2.7.4



[PATCH 1/2] ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver

2020-09-16 Thread Viorel Suman (OSS)
From: Viorel Suman 

XCVR (Audio Transceiver) is a on-chip functional module found
on i.MX8MP. It support HDMI2.1 eARC, HDMI1.4 ARC and SPDIF.

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/Kconfig|   10 +
 sound/soc/fsl/Makefile   |2 +
 sound/soc/fsl/fsl_xcvr.c | 1352 ++
 sound/soc/fsl/fsl_xcvr.h |  266 +
 4 files changed, 1630 insertions(+)
 create mode 100644 sound/soc/fsl/fsl_xcvr.c
 create mode 100644 sound/soc/fsl/fsl_xcvr.h

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 3f76ff7..d04b64d 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -95,6 +95,16 @@ config SND_SOC_FSL_EASRC
  destination sample rate. It is a new design module compare with the
  old ASRC.
 
+config SND_SOC_FSL_XCVR
+   tristate "NXP Audio Transceiver (XCVR) module support"
+   select REGMAP_MMIO
+   select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
+   select SND_SOC_GENERIC_DMAENGINE_PCM
+   help
+ Say Y if you want to add Audio Transceiver (XCVR) support for NXP
+ iMX CPUs. XCVR is a digital module that supports HDMI2.1 eARC,
+ HDMI1.4 ARC and SPDIF.
+
 config SND_SOC_FSL_UTILS
tristate
 
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index b835eeb..1d2231f 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -25,6 +25,7 @@ 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
+snd-soc-fsl-xcvr-objs := fsl_xcvr.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
@@ -38,6 +39,7 @@ 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
+obj-$(CONFIG_SND_SOC_FSL_XCVR) += snd-soc-fsl-xcvr.o
 
 # MPC5200 Platform Support
 obj-$(CONFIG_SND_MPC52xx_DMA) += mpc5200_dma.o
diff --git a/sound/soc/fsl/fsl_xcvr.c b/sound/soc/fsl/fsl_xcvr.c
new file mode 100644
index ..2e66f22
--- /dev/null
+++ b/sound/soc/fsl/fsl_xcvr.c
@@ -0,0 +1,1352 @@
+// SPDX-License-Identifier: GPL-2.0
+// Copyright 2019 NXP
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fsl_xcvr.h"
+#include "imx-pcm.h"
+
+#define FSL_XCVR_CAPDS_SIZE256
+
+struct fsl_xcvr {
+   struct platform_device *pdev;
+   struct regmap *regmap;
+   struct clk *ipg_clk;
+   struct clk *pll_ipg_clk;
+   struct clk *phy_clk;
+   struct clk *spba_clk;
+   struct reset_control *reset;
+   const char *fw_name;
+   u8 streams;
+   u32 mode;
+   u32 arc_mode;
+   void __iomem *ram_addr;
+   struct snd_dmaengine_dai_dma_data dma_prms_rx;
+   struct snd_dmaengine_dai_dma_data dma_prms_tx;
+   struct snd_aes_iec958 rx_iec958;
+   struct snd_aes_iec958 tx_iec958;
+   u8 cap_ds[FSL_XCVR_CAPDS_SIZE];
+};
+
+static const struct fsl_xcvr_pll_conf {
+   u8 mfi;   /* min=0x18, max=0x38 */
+   u32 mfn;  /* signed int, 2's compl., min=0x3FFF, max=0x0001 */
+   u32 mfd;  /* unsigned int */
+   u32 fout; /* Fout = Fref*(MFI + MFN/MFD), Fref is 24MHz */
+} fsl_xcvr_pll_cfg[] = {
+   { .mfi = 54, .mfn = 1,  .mfd = 6,   .fout = 13, }, /* 1.3 GHz */
+   { .mfi = 32, .mfn = 96, .mfd = 125, .fout = 786432000, },  /* 8000 Hz */
+   { .mfi = 30, .mfn = 66, .mfd = 625, .fout = 722534400, },  /* 11025 Hz 
*/
+   { .mfi = 29, .mfn = 1,  .mfd = 6,   .fout = 7, },  /* 700 MHz */
+};
+
+static const u32 fsl_xcvr_earc_channels[] = { 1, 2, 8, 16, 32, }; /* one bit 
6, 12 ? */
+static const struct snd_pcm_hw_constraint_list fsl_xcvr_earc_channels_constr = 
{
+   .count = ARRAY_SIZE(fsl_xcvr_earc_channels),
+   .list = fsl_xcvr_earc_channels,
+};
+
+static const u32 fsl_xcvr_earc_rates[] = {
+   32000, 44100, 48000, 64000, 88200, 96000,
+   128000, 176400, 192000, 256000, 352800, 384000,
+   512000, 705600, 768000, 1024000, 1411200, 1536000,
+};
+static const struct snd_pcm_hw_constraint_list fsl_xcvr_earc_rates_constr = {
+   .count = ARRAY_SIZE(fsl_xcvr_earc_rates),
+   .list = fsl_xcvr_earc_rates,
+};
+
+static const u32 fsl_xcvr_spdif_channels[] = { 2, };
+static const struct snd_pcm_hw_constraint_list fsl_xcvr_spdif_channels_constr 
= {
+   .count = ARRAY_SIZE(fsl_xcvr_spdif_channels),
+   .list = fsl_xcvr_spdif_channels,
+};
+
+static const u32 fsl_xcvr_spdif_rates[] = {
+   32000, 44100, 48000, 88200, 96000, 176400, 192000,
+};
+static const struct snd_pcm_hw_constraint_list fsl_xcvr_spdif_rates_constr = {
+   .count = ARRAY_SIZE(fsl_xcvr_spdif_rates),
+   .list = fsl_xcvr_spdif_rates,
+};
+
+static in

[PATCH 0/2] DAI driver for new XCVR IP

2020-09-16 Thread Viorel Suman (OSS)
From: Viorel Suman 

DAI driver for new XCVR IP found in i.MX8MP.

Viorel Suman (2):
  ASoC: fsl_xcvr: Add XCVR ASoC CPU DAI driver
  ASoC: dt-bindings: fsl_xcvr: Add document for XCVR

 .../devicetree/bindings/sound/fsl,xcvr.yaml|  104 ++
 sound/soc/fsl/Kconfig  |   10 +
 sound/soc/fsl/Makefile |2 +
 sound/soc/fsl/fsl_xcvr.c   | 1352 
 sound/soc/fsl/fsl_xcvr.h   |  266 
 5 files changed, 1734 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,xcvr.yaml
 create mode 100644 sound/soc/fsl/fsl_xcvr.c
 create mode 100644 sound/soc/fsl/fsl_xcvr.h

-- 
2.7.4



[PATCH] ASoC: fsl_audmix: make clock and output src write only

2020-09-14 Thread Viorel Suman (OSS)
From: Viorel Suman 

"alsactl -f state.conf store/restore" sequence fails because setting
"mixing clock source" and "output source" requires active TDM clock
being started for configuration propagation. Make these two controls
write only so that their values are not stored at "alsactl store".

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/fsl_audmix.c | 16 
 1 file changed, 12 insertions(+), 4 deletions(-)

diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c
index a447baf..7ad5925 100644
--- a/sound/soc/fsl/fsl_audmix.c
+++ b/sound/soc/fsl/fsl_audmix.c
@@ -199,10 +199,18 @@ static int fsl_audmix_put_out_src(struct snd_kcontrol 
*kcontrol,
 
 static const struct snd_kcontrol_new fsl_audmix_snd_controls[] = {
/* FSL_AUDMIX_CTR controls */
-   SOC_ENUM_EXT("Mixing Clock Source", fsl_audmix_enum[0],
-snd_soc_get_enum_double, fsl_audmix_put_mix_clk_src),
-   SOC_ENUM_EXT("Output Source", fsl_audmix_enum[1],
-snd_soc_get_enum_double, fsl_audmix_put_out_src),
+   {   .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+   .name = "Mixing Clock Source",
+   .info = snd_soc_info_enum_double,
+   .access = SNDRV_CTL_ELEM_ACCESS_WRITE,
+   .put = fsl_audmix_put_mix_clk_src,
+   .private_value = (unsigned long)_audmix_enum[0] },
+   {   .iface = SNDRV_CTL_ELEM_IFACE_MIXER,
+   .name = "Output Source",
+   .info = snd_soc_info_enum_double,
+   .access = SNDRV_CTL_ELEM_ACCESS_WRITE,
+   .put = fsl_audmix_put_out_src,
+   .private_value = (unsigned long)_audmix_enum[1] },
SOC_ENUM("Output Width", fsl_audmix_enum[2]),
SOC_ENUM("Frame Rate Diff Error", fsl_audmix_enum[3]),
SOC_ENUM("Clock Freq Diff Error", fsl_audmix_enum[4]),
-- 
2.7.4



Re: [alsa-devel] [PATCH] ASoC: AK4458: add regulator for ak4458

2019-05-16 Thread Viorel Suman
On Jo, 2019-05-16 at 10:14 -0300, Fabio Estevam wrote:
> On Thu, May 16, 2019 at 10:02 AM Viorel Suman  wrote:
> 
> > 
> > +   for (i = 0; i < ARRAY_SIZE(ak4458->supplies); i++)
> > +   ak4458->supplies[i].supply = ak4458_supply_names[i];
> > +
> > +   ret = devm_regulator_bulk_get(ak4458->dev, 
> > ARRAY_SIZE(ak4458->supplies),
> > + ak4458->supplies);
> > +   if (ret != 0) {
> > +   dev_err(ak4458->dev, "Failed to request supplies: %d\n", 
> > ret);
> > +   return ret;
> This would break existing users that do not pass the regulators in device 
> tree.
> 
> Ok, in this case there is no ak4458 user in any dts, so that would not
> be an issue.
> 
> Please update the dt-bindings with the regulator entries.

Thanks, will send in V2.

/Viorel

[PATCH] ASoC: AK4458: add regulator for ak4458

2019-05-16 Thread Viorel Suman
From: Shengjiu Wang 

Add regulator for ak4458.

Signed-off-by: Shengjiu Wang 
Signed-off-by: Viorel Suman 
---
 sound/soc/codecs/ak4458.c | 27 ++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c
index 7156215..06dcf13 100644
--- a/sound/soc/codecs/ak4458.c
+++ b/sound/soc/codecs/ak4458.c
@@ -12,6 +12,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -21,6 +22,12 @@
 
 #include "ak4458.h"
 
+#define AK4458_NUM_SUPPLIES 2
+static const char *ak4458_supply_names[AK4458_NUM_SUPPLIES] = {
+   "DVDD",
+   "AVDD",
+};
+
 struct ak4458_drvdata {
struct snd_soc_dai_driver *dai_drv;
const struct snd_soc_component_driver *comp_drv;
@@ -37,6 +44,7 @@ struct ak4458_priv {
int fmt;
int slots;
int slot_width;
+   struct regulator_bulk_data supplies[AK4458_NUM_SUPPLIES];
 };
 
 static const struct reg_default ak4458_reg_defaults[] = {
@@ -666,7 +674,7 @@ static int ak4458_i2c_probe(struct i2c_client *i2c)
 {
struct ak4458_priv *ak4458;
const struct ak4458_drvdata *drvdata;
-   int ret;
+   int ret, i;
 
ak4458 = devm_kzalloc(>dev, sizeof(*ak4458), GFP_KERNEL);
if (!ak4458)
@@ -691,6 +699,23 @@ static int ak4458_i2c_probe(struct i2c_client *i2c)
if (IS_ERR(ak4458->mute_gpiod))
return PTR_ERR(ak4458->mute_gpiod);
 
+   for (i = 0; i < ARRAY_SIZE(ak4458->supplies); i++)
+   ak4458->supplies[i].supply = ak4458_supply_names[i];
+
+   ret = devm_regulator_bulk_get(ak4458->dev, ARRAY_SIZE(ak4458->supplies),
+ ak4458->supplies);
+   if (ret != 0) {
+   dev_err(ak4458->dev, "Failed to request supplies: %d\n", ret);
+   return ret;
+   }
+
+   ret = regulator_bulk_enable(ARRAY_SIZE(ak4458->supplies),
+   ak4458->supplies);
+   if (ret != 0) {
+   dev_err(ak4458->dev, "Failed to enable supplies: %d\n", ret);
+   return ret;
+   }
+
ret = devm_snd_soc_register_component(ak4458->dev, drvdata->comp_drv,
  drvdata->dai_drv, 1);
if (ret < 0) {
-- 
2.7.4



[PATCH V2 2/2] ASoC: ak4458: add return value for ak4458_probe

2019-05-13 Thread Viorel Suman
AK4458 is probed successfully even if AK4458 is not present - this
is caused by probe function returning no error on i2c access failure.
Return an error on probe if i2c access has failed.

Signed-off-by: Shengjiu Wang 
Signed-off-by: Viorel Suman 
---
 sound/soc/codecs/ak4458.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c
index baf990a..7156215 100644
--- a/sound/soc/codecs/ak4458.c
+++ b/sound/soc/codecs/ak4458.c
@@ -539,9 +539,10 @@ static void ak4458_power_on(struct ak4458_priv *ak4458)
}
 }
 
-static void ak4458_init(struct snd_soc_component *component)
+static int ak4458_init(struct snd_soc_component *component)
 {
struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+   int ret;
 
/* External Mute ON */
if (ak4458->mute_gpiod)
@@ -549,21 +550,21 @@ static void ak4458_init(struct snd_soc_component 
*component)
 
ak4458_power_on(ak4458);
 
-   snd_soc_component_update_bits(component, AK4458_00_CONTROL1,
+   ret = snd_soc_component_update_bits(component, AK4458_00_CONTROL1,
0x80, 0x80);   /* ACKS bit = 1; 1000 */
+   if (ret < 0)
+   return ret;
 
-   ak4458_rstn_control(component, 1);
+   return ak4458_rstn_control(component, 1);
 }
 
 static int ak4458_probe(struct snd_soc_component *component)
 {
struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
 
-   ak4458_init(component);
-
ak4458->fs = 48000;
 
-   return 0;
+   return ak4458_init(component);
 }
 
 static void ak4458_remove(struct snd_soc_component *component)
-- 
2.7.4



[PATCH V2 0/2] ASoC: ak4458: fail on probe if codec is not present

2019-05-13 Thread Viorel Suman
AK4458 is probed successfully even if AK4458 is not present - this
is caused by probe function returning no error on i2c access failure.
The patchset fixes this.

Changes since V1:
  Conditional statement rewritten as suggested by Mark.

Viorel Suman (2):
  ASoC: ak4458: rstn_control - return a non-zero on error only
  ASoC: ak4458: add return value for ak4458_probe

 sound/soc/codecs/ak4458.c | 18 +++---
 1 file changed, 11 insertions(+), 7 deletions(-)

-- 
2.7.4



[PATCH V2 1/2] ASoC: ak4458: rstn_control - return a non-zero on error only

2019-05-13 Thread Viorel Suman
snd_soc_component_update_bits() may return 1 if operation
was successful and the value of the register changed.
Return a non-zero in ak4458_rstn_control for an error only.

Signed-off-by: Shengjiu Wang 
Signed-off-by: Viorel Suman 
---
 sound/soc/codecs/ak4458.c | 5 -
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c
index eab7c76..baf990a 100644
--- a/sound/soc/codecs/ak4458.c
+++ b/sound/soc/codecs/ak4458.c
@@ -304,7 +304,10 @@ static int ak4458_rstn_control(struct snd_soc_component 
*component, int bit)
  AK4458_00_CONTROL1,
  AK4458_RSTN_MASK,
  0x0);
-   return ret;
+   if (ret < 0)
+   return ret;
+
+   return 0;
 }
 
 static int ak4458_hw_params(struct snd_pcm_substream *substream,
-- 
2.7.4



[PATCH 0/2] ASoC: ak4458: fail on probe if codec is not present

2019-05-09 Thread Viorel Suman
AK4458 is probed successfully even if AK4458 is not present - this
is caused by probe function returning no error on i2c access failure.
The patchset fixes this.

Viorel Suman (2):
  ASoC: ak4458: rstn_control - return a non-zero on error only
  ASoC: ak4458: add return value for ak4458_probe

 sound/soc/codecs/ak4458.c | 16 +---
 1 file changed, 9 insertions(+), 7 deletions(-)

-- 
2.7.4



[PATCH 2/2] ASoC: ak4458: add return value for ak4458_probe

2019-05-09 Thread Viorel Suman
AK4458 is probed successfully even if AK4458 is not present - this
is caused by probe function returning no error on i2c access failure.
Return an error on probe if i2c access has failed.

Signed-off-by: Shengjiu Wang 
Signed-off-by: Viorel Suman 
---
 sound/soc/codecs/ak4458.c | 13 +++--
 1 file changed, 7 insertions(+), 6 deletions(-)

diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c
index 4795e32..d192774353 100644
--- a/sound/soc/codecs/ak4458.c
+++ b/sound/soc/codecs/ak4458.c
@@ -537,9 +537,10 @@ static void ak4458_power_on(struct ak4458_priv *ak4458)
}
 }
 
-static void ak4458_init(struct snd_soc_component *component)
+static int ak4458_init(struct snd_soc_component *component)
 {
struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
+   int ret;
 
/* External Mute ON */
if (ak4458->mute_gpiod)
@@ -547,21 +548,21 @@ static void ak4458_init(struct snd_soc_component 
*component)
 
ak4458_power_on(ak4458);
 
-   snd_soc_component_update_bits(component, AK4458_00_CONTROL1,
+   ret = snd_soc_component_update_bits(component, AK4458_00_CONTROL1,
0x80, 0x80);   /* ACKS bit = 1; 1000 */
+   if (ret < 0)
+   return ret;
 
-   ak4458_rstn_control(component, 1);
+   return ak4458_rstn_control(component, 1);
 }
 
 static int ak4458_probe(struct snd_soc_component *component)
 {
struct ak4458_priv *ak4458 = snd_soc_component_get_drvdata(component);
 
-   ak4458_init(component);
-
ak4458->fs = 48000;
 
-   return 0;
+   return ak4458_init(component);
 }
 
 static void ak4458_remove(struct snd_soc_component *component)
-- 
2.7.4



[PATCH 1/2] ASoC: ak4458: rstn_control - return a non-zero on error only

2019-05-09 Thread Viorel Suman
snd_soc_component_update_bits() may return 1 if operation
was successful and the value of the register changed.
Return a non-zero in ak4458_rstn_control for an error only.

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

diff --git a/sound/soc/codecs/ak4458.c b/sound/soc/codecs/ak4458.c
index eab7c76..4795e32 100644
--- a/sound/soc/codecs/ak4458.c
+++ b/sound/soc/codecs/ak4458.c
@@ -304,7 +304,8 @@ static int ak4458_rstn_control(struct snd_soc_component 
*component, int bit)
  AK4458_00_CONTROL1,
  AK4458_RSTN_MASK,
  0x0);
-   return ret;
+   /* Return a negative error code only. */
+   return (ret < 0 ? ret : 0);
 }
 
 static int ak4458_hw_params(struct snd_pcm_substream *substream,
-- 
2.7.4



[PATCH v4 4/4] ASoC: fsl_audmix: cache pdev->dev pointer

2019-04-10 Thread Viorel Suman
There should be no trouble to understand dev = pdev->dev.
This can save some space to have more print info or save
some wrapped lines.

Signed-off-by: Viorel Suman 
Suggested-by: Nicolin Chen 
---
 sound/soc/fsl/fsl_audmix.c | 27 +--
 1 file changed, 13 insertions(+), 14 deletions(-)

diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c
index dc802d5..3897a54 100644
--- a/sound/soc/fsl/fsl_audmix.c
+++ b/sound/soc/fsl/fsl_audmix.c
@@ -456,6 +456,7 @@ MODULE_DEVICE_TABLE(of, fsl_audmix_ids);
 
 static int fsl_audmix_probe(struct platform_device *pdev)
 {
+   struct device *dev = >dev;
struct fsl_audmix *priv;
struct resource *res;
const char *mdrv;
@@ -463,52 +464,50 @@ static int fsl_audmix_probe(struct platform_device *pdev)
void __iomem *regs;
int ret;
 
-   of_id = of_match_device(fsl_audmix_ids, >dev);
+   of_id = of_match_device(fsl_audmix_ids, dev);
if (!of_id || !of_id->data)
return -EINVAL;
 
mdrv = of_id->data;
 
-   priv = devm_kzalloc(>dev, sizeof(*priv), GFP_KERNEL);
+   priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
 
/* Get the addresses */
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-   regs = devm_ioremap_resource(>dev, res);
+   regs = devm_ioremap_resource(dev, res);
if (IS_ERR(regs))
return PTR_ERR(regs);
 
-   priv->regmap = devm_regmap_init_mmio_clk(>dev, "ipg", regs,
+   priv->regmap = devm_regmap_init_mmio_clk(dev, "ipg", regs,
 _audmix_regmap_config);
if (IS_ERR(priv->regmap)) {
-   dev_err(>dev, "failed to init regmap\n");
+   dev_err(dev, "failed to init regmap\n");
return PTR_ERR(priv->regmap);
}
 
-   priv->ipg_clk = devm_clk_get(>dev, "ipg");
+   priv->ipg_clk = devm_clk_get(dev, "ipg");
if (IS_ERR(priv->ipg_clk)) {
-   dev_err(>dev, "failed to get ipg clock\n");
+   dev_err(dev, "failed to get ipg clock\n");
return PTR_ERR(priv->ipg_clk);
}
 
platform_set_drvdata(pdev, priv);
-   pm_runtime_enable(>dev);
+   pm_runtime_enable(dev);
 
-   ret = devm_snd_soc_register_component(>dev, _audmix_component,
+   ret = devm_snd_soc_register_component(dev, _audmix_component,
  fsl_audmix_dai,
  ARRAY_SIZE(fsl_audmix_dai));
if (ret) {
-   dev_err(>dev, "failed to register ASoC DAI\n");
+   dev_err(dev, "failed to register ASoC DAI\n");
return ret;
}
 
-   priv->pdev = platform_device_register_data(>dev, mdrv, 0, NULL,
-  0);
+   priv->pdev = platform_device_register_data(dev, mdrv, 0, NULL, 0);
if (IS_ERR(priv->pdev)) {
ret = PTR_ERR(priv->pdev);
-   dev_err(>dev, "failed to register platform %s: %d\n",
-   mdrv, ret);
+   dev_err(dev, "failed to register platform %s: %d\n", mdrv, ret);
}
 
return ret;
-- 
2.7.4



[PATCH v4 1/4] ASoC: fsl_audmix: remove "model" attribute

2019-04-10 Thread Viorel Suman
Use "of_device_id.data" to specify the machine driver
instead of "model" DTS attribute.

Signed-off-by: Viorel Suman 
Acked-by: Nicolin Chen 
---
 sound/soc/fsl/fsl_audmix.c | 43 +++
 1 file changed, 23 insertions(+), 20 deletions(-)

diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c
index dabde03..dc802d5 100644
--- a/sound/soc/fsl/fsl_audmix.c
+++ b/sound/soc/fsl/fsl_audmix.c
@@ -445,13 +445,29 @@ static const struct regmap_config 
fsl_audmix_regmap_config = {
.cache_type = REGCACHE_FLAT,
 };
 
+static const struct of_device_id fsl_audmix_ids[] = {
+   {
+   .compatible = "fsl,imx8qm-audmix",
+   .data = "imx-audmix",
+   },
+   { /* sentinel */ }
+};
+MODULE_DEVICE_TABLE(of, fsl_audmix_ids);
+
 static int fsl_audmix_probe(struct platform_device *pdev)
 {
struct fsl_audmix *priv;
struct resource *res;
+   const char *mdrv;
+   const struct of_device_id *of_id;
void __iomem *regs;
int ret;
-   const char *sprop;
+
+   of_id = of_match_device(fsl_audmix_ids, >dev);
+   if (!of_id || !of_id->data)
+   return -EINVAL;
+
+   mdrv = of_id->data;
 
priv = devm_kzalloc(>dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -487,19 +503,12 @@ static int fsl_audmix_probe(struct platform_device *pdev)
return ret;
}
 
-   sprop = of_get_property(pdev->dev.of_node, "model", NULL);
-   if (sprop) {
-   priv->pdev = platform_device_register_data(>dev, sprop, 0,
-  NULL, 0);
-   if (IS_ERR(priv->pdev)) {
-   ret = PTR_ERR(priv->pdev);
-   dev_err(>dev,
-   "failed to register platform %s: %d\n", sprop,
-ret);
-   }
-   } else {
-   dev_err(>dev, "[model] attribute missing.\n");
-   ret = -EINVAL;
+   priv->pdev = platform_device_register_data(>dev, mdrv, 0, NULL,
+  0);
+   if (IS_ERR(priv->pdev)) {
+   ret = PTR_ERR(priv->pdev);
+   dev_err(>dev, "failed to register platform %s: %d\n",
+   mdrv, ret);
}
 
return ret;
@@ -553,12 +562,6 @@ static const struct dev_pm_ops fsl_audmix_pm = {
pm_runtime_force_resume)
 };
 
-static const struct of_device_id fsl_audmix_ids[] = {
-   { .compatible = "fsl,imx8qm-audmix", },
-   { /* sentinel */ }
-};
-MODULE_DEVICE_TABLE(of, fsl_audmix_ids);
-
 static struct platform_driver fsl_audmix_driver = {
.probe = fsl_audmix_probe,
.remove = fsl_audmix_remove,
-- 
2.7.4



[PATCH v4 0/4] ASoC: fsl: audmix: remove "model" attribute and fix ref leaks

2019-04-10 Thread Viorel Suman
The latest audmix patch-set (v5) had the "model" attribute removed as
requested by Nicolin Chen, but looks like (v4) version of DAI driver
reached "for-next" branch - fix this by removing "model" attribute.
Asside of this fix object reference leaks in machine probe reported by
Julia Lawall.

Viorel Suman (4):
  ASoC: fsl_audmix: remove "model" attribute
  ASoC: fsl_audmix: remove "model" attribute from DT document
  ASoC: imx-audmix: fix object reference leaks in probe
  ASoC: fsl_audmix: cache pdev->dev pointer

Changes since V1:
  a) Removed "model" attribute from dt-bindings documentation
  b) Adressed Daniel's comments

Changes since V2:
  a) Cache pdev->dev pointer in fsl_audmix probe as suggested by Nicolin

Changes since V3:
  a) Use subject lines matching the style for the subsystem.

 .../devicetree/bindings/sound/fsl,audmix.txt   |  4 --
 sound/soc/fsl/fsl_audmix.c | 60 +++---
 sound/soc/fsl/imx-audmix.c |  4 ++
 3 files changed, 35 insertions(+), 33 deletions(-)

-- 
2.7.4



Re: [EXT] Re: [PATCH v3 2/4] dt-bindings: fsl,audmix: remove "model" attribute

2019-04-10 Thread Viorel Suman
Hi Mark,

On Mi, 2019-04-10 at 11:39 +0100, Mark Brown wrote:
> On Wed, Apr 10, 2019 at 10:37:30AM +0000, Viorel Suman wrote:
> > 
> > Remove "model" attribute.
> > 
> > Signed-off-by: Viorel Suman 
> > Acked-by: Nicolin Chen 
> Please use subject lines matching the style for the subsystem.  This
> makes it easier for people to identify relevant patches.

Sure, thank you, do I have to send V4 with subject fixed ?

[PATCH RESEND v5 3/3] ASoC: fsl: Add Audio Mixer machine driver

2019-03-04 Thread Viorel Suman
This patch implements Audio Mixer machine driver for NXP iMX8 SOCs.
It connects together Audio Mixer and related SAI instances.

Signed-off-by: Viorel Suman 
Acked-by: Nicolin Chen 
---
 sound/soc/fsl/Kconfig  |   9 ++
 sound/soc/fsl/Makefile |   2 +
 sound/soc/fsl/imx-audmix.c | 327 +
 3 files changed, 338 insertions(+)
 create mode 100644 sound/soc/fsl/imx-audmix.c

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 0af2e056..d87c842 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -303,6 +303,15 @@ config SND_SOC_FSL_ASOC_CARD
 CS4271, CS4272 and SGTL5000.
 Say Y if you want to add support for Freescale Generic ASoC Sound Card.
 
+config SND_SOC_IMX_AUDMIX
+   tristate "SoC Audio support for i.MX boards with AUDMIX"
+   select SND_SOC_FSL_AUDMIX
+   select SND_SOC_FSL_SAI
+   help
+ SoC Audio support for i.MX boards with Audio Mixer
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ an Audio Mixer.
+
 endif # SND_IMX_SOC
 
 endmenu
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 4172d5a..c0dd044 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -62,6 +62,7 @@ snd-soc-imx-es8328-objs := imx-es8328.o
 snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
 snd-soc-imx-spdif-objs := imx-spdif.o
 snd-soc-imx-mc13783-objs := imx-mc13783.o
+snd-soc-imx-audmix-objs := imx-audmix.o
 
 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
 obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
@@ -71,3 +72,4 @@ obj-$(CONFIG_SND_SOC_IMX_ES8328) += snd-soc-imx-es8328.o
 obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
 obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
 obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
+obj-$(CONFIG_SND_SOC_IMX_AUDMIX) += snd-soc-imx-audmix.o
diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c
new file mode 100644
index 000..72e37ca
--- /dev/null
+++ b/sound/soc/fsl/imx-audmix.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2017 NXP
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "fsl_sai.h"
+#include "fsl_audmix.h"
+
+struct imx_audmix {
+   struct platform_device *pdev;
+   struct snd_soc_card card;
+   struct platform_device *audmix_pdev;
+   struct platform_device *out_pdev;
+   struct clk *cpu_mclk;
+   int num_dai;
+   struct snd_soc_dai_link *dai;
+   int num_dai_conf;
+   struct snd_soc_codec_conf *dai_conf;
+   int num_dapm_routes;
+   struct snd_soc_dapm_route *dapm_routes;
+};
+
+static const u32 imx_audmix_rates[] = {
+   8000, 12000, 16000, 24000, 32000, 48000, 64000, 96000,
+};
+
+static const struct snd_pcm_hw_constraint_list imx_audmix_rate_constraints = {
+   .count = ARRAY_SIZE(imx_audmix_rates),
+   .list = imx_audmix_rates,
+};
+
+static int imx_audmix_fe_startup(struct snd_pcm_substream *substream)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct imx_audmix *priv = snd_soc_card_get_drvdata(rtd->card);
+   struct snd_pcm_runtime *runtime = substream->runtime;
+   struct device *dev = rtd->card->dev;
+   unsigned long clk_rate = clk_get_rate(priv->cpu_mclk);
+   int ret;
+
+   if (clk_rate % 24576000 == 0) {
+   ret = snd_pcm_hw_constraint_list(runtime, 0,
+SNDRV_PCM_HW_PARAM_RATE,
+_audmix_rate_constraints);
+   if (ret < 0)
+   return ret;
+   } else {
+   dev_warn(dev, "mclk may be not supported %lu\n", clk_rate);
+   }
+
+   ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS,
+  1, 8);
+   if (ret < 0)
+   return ret;
+
+   return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
+   FSL_AUDMIX_FORMATS);
+}
+
+static int imx_audmix_fe_hw_params(struct snd_pcm_substream *substream,
+  struct snd_pcm_hw_params *params)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct device *dev = rtd->card->dev;
+   bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+   unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF;
+   u32 channels = params_channels(params);
+   int ret, dir;
+
+   /* For

[PATCH RESEND v5 2/3] ASoC: add fsl_audmix DT binding documentation

2019-03-04 Thread Viorel Suman
Add the DT binding documentation for NXP Audio Mixer
CPU DAI driver.

Signed-off-by: Viorel Suman 
Acked-by: Nicolin Chen 
Acked-by: Rob Herring 
---
 .../devicetree/bindings/sound/fsl,audmix.txt   | 50 ++
 1 file changed, 50 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,audmix.txt

diff --git a/Documentation/devicetree/bindings/sound/fsl,audmix.txt 
b/Documentation/devicetree/bindings/sound/fsl,audmix.txt
new file mode 100644
index 000..840b7e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,audmix.txt
@@ -0,0 +1,50 @@
+NXP Audio Mixer (AUDMIX).
+
+The Audio Mixer is a on-chip functional module that allows mixing of two
+audio streams into a single audio stream. Audio Mixer has two input serial
+audio interfaces. These are driven by two Synchronous Audio interface
+modules (SAI). Each input serial interface carries 8 audio channels in its
+frame in TDM manner. Mixer mixes audio samples of corresponding channels
+from two interfaces into a single sample. Before mixing, audio samples of
+two inputs can be attenuated based on configuration. The output of the
+Audio Mixer is also a serial audio interface. Like input interfaces it has
+the same TDM frame format. This output is used to drive the serial DAC TDM
+interface of audio codec and also sent to the external pins along with the
+receive path of normal audio SAI module for readback by the CPU.
+
+The output of Audio Mixer can be selected from any of the three streams
+ - serial audio input 1
+ - serial audio input 2
+ - mixed audio
+
+Mixing operation is independent of audio sample rate but the two audio
+input streams must have same audio sample rate with same number of channels
+in TDM frame to be eligible for mixing.
+
+Device driver required properties:
+=
+  - compatible : Compatible list, contains "fsl,imx8qm-audmix"
+
+  - reg: Offset and length of the register set for the 
device.
+
+  - clocks : Must contain an entry for each entry in clock-names.
+
+  - clock-names: Must include the "ipg" for register access.
+
+  - power-domains  : Must contain the phandle to AUDMIX power domain node
+
+  - dais   : Must contain a list of phandles to AUDMIX connected
+ DAIs. The current implementation requires two phandles
+ to SAI interfaces to be provided, the first SAI in the
+ list being used to route the AUDMIX output.
+
+Device driver configuration example:
+==
+  audmix: audmix@5984 {
+compatible = "fsl,imx8qm-audmix";
+reg = <0x0 0x5984 0x0 0x1>;
+clocks = < IMX8QXP_AUD_AUDMIX_IPG>;
+clock-names = "ipg";
+power-domains = <_audmix>;
+dais = <>, <>;
+  };
-- 
2.7.4



[PATCH RESEND v5 1/3] ASoC: fsl: Add Audio Mixer CPU DAI driver

2019-03-04 Thread Viorel Suman
This patch implements Audio Mixer CPU DAI driver for NXP iMX8 SOCs.
The Audio Mixer is a on-chip functional module that allows mixing of
two audio streams into a single audio stream.

Audio Mixer datasheet is available here:
https://www.nxp.com/docs/en/reference-manual/IMX8DQXPRM.pdf

Signed-off-by: Viorel Suman 
Acked-by: Nicolin Chen 
---
 sound/soc/fsl/Kconfig  |   7 +
 sound/soc/fsl/Makefile |   3 +
 sound/soc/fsl/fsl_audmix.c | 578 +
 sound/soc/fsl/fsl_audmix.h | 102 
 4 files changed, 690 insertions(+)
 create mode 100644 sound/soc/fsl/fsl_audmix.c
 create mode 100644 sound/soc/fsl/fsl_audmix.h

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 7b1d997..0af2e056 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -24,6 +24,13 @@ config SND_SOC_FSL_SAI
  This option is only useful for out-of-tree drivers since
  in-tree drivers select it automatically.
 
+config SND_SOC_FSL_AUDMIX
+   tristate "Audio Mixer (AUDMIX) module support"
+   select REGMAP_MMIO
+   help
+ Say Y if you want to add Audio Mixer (AUDMIX)
+ support for the NXP iMX CPUs.
+
 config SND_SOC_FSL_SSI
tristate "Synchronous Serial Interface module (SSI) support"
select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 3c0ff31..4172d5a 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -12,6 +12,7 @@ snd-soc-p1022-rdk-objs := p1022_rdk.o
 obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
 
 # Freescale SSI/DMA/SAI/SPDIF Support
+snd-soc-fsl-audmix-objs := fsl_audmix.o
 snd-soc-fsl-asoc-card-objs := fsl-asoc-card.o
 snd-soc-fsl-asrc-objs := fsl_asrc.o fsl_asrc_dma.o
 snd-soc-fsl-sai-objs := fsl_sai.o
@@ -22,6 +23,8 @@ snd-soc-fsl-esai-objs := fsl_esai.o
 snd-soc-fsl-micfil-objs := fsl_micfil.o
 snd-soc-fsl-utils-objs := fsl_utils.o
 snd-soc-fsl-dma-objs := fsl_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
 obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc.o
 obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c
new file mode 100644
index 000..07b72a3
--- /dev/null
+++ b/sound/soc/fsl/fsl_audmix.c
@@ -0,0 +1,578 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NXP AUDMIX ALSA SoC Digital Audio Interface (DAI) driver
+ *
+ * Copyright 2017 NXP
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fsl_audmix.h"
+
+#define SOC_ENUM_SINGLE_S(xreg, xshift, xtexts) \
+   SOC_ENUM_SINGLE(xreg, xshift, ARRAY_SIZE(xtexts), xtexts)
+
+static const char
+   *tdm_sel[] = { "TDM1", "TDM2", },
+   *mode_sel[] = { "Disabled", "TDM1", "TDM2", "Mixed", },
+   *width_sel[] = { "16b", "18b", "20b", "24b", "32b", },
+   *endis_sel[] = { "Disabled", "Enabled", },
+   *updn_sel[] = { "Downward", "Upward", },
+   *mask_sel[] = { "Unmask", "Mask", };
+
+static const struct soc_enum fsl_audmix_enum[] = {
+/* FSL_AUDMIX_CTR enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MIXCLK_SHIFT, tdm_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_OUTSRC_SHIFT, mode_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_OUTWIDTH_SHIFT, width_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MASKRTDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MASKCKDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_SYNCMODE_SHIFT, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_SYNCSRC_SHIFT, tdm_sel),
+/* FSL_AUDMIX_ATCR0 enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR0, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR0, 1, updn_sel),
+/* FSL_AUDMIX_ATCR1 enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR1, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR1, 1, updn_sel),
+};
+
+struct fsl_audmix_state {
+   u8 tdms;
+   u8 clk;
+   char msg[64];
+};
+
+static const struct fsl_audmix_state prms[4][4] = {{
+   /* DIS->DIS, do nothing */
+   { .tdms = 0, .clk = 0, .msg = "" },
+   /* DIS->TDM1*/
+   { .tdms = 1, .clk = 1, .msg = "DIS->TDM1: TDM1 not started!\n" },
+   /* DIS->TDM2*/
+   { .tdms = 2, .clk = 2, .msg = "DIS->TDM2: TDM2 not started!\n" },
+   /* DIS->MIX */
+   { .tdms = 3, .clk = 0, .msg = "DIS->MIX: Please start both TDMs!\n" }
+}, {   /* TDM1->DIS */
+   { .tdms = 1, .clk = 0, .msg = "TDM1->DIS: TDM1 not started!\n" },
+   /* TDM1->TDM1, do nothing */
+   { .tdms = 0, .clk = 0, .msg = "" },
+   /* TDM1->TDM2 */
+   { 

[PATCH RESEND v5 0/3] Add NXP AUDMIX device and machine drivers

2019-03-04 Thread Viorel Suman
The patchset adds NXP Audio Mixer (AUDMIX) device and machine
drivers and related DT bindings documentation.

Changes since V4:
1. Removed "model" attribute from device driver DT bindings documentation
   as suggested by Nicolin.

Changes since V3:
1. Removed machine driver DT bindings documentation.
2. Trigger machine driver probe from device driver as suggested by Nicolin.

Changes since V2:
1. Moved "dais" node from machine driver DTS node to device driver DTS node
  as suggested by Rob.

Changes since V1:
1. Original patch split into distinct patches for the device driver and
  DT binding documentation.
2. Replaced AMIX with AUDMIX in both code and file names as it looks more
  RM-compliant.
3. Removed polarity control from CPU DAI driver as suggested by Nicolin.
4. Added machine driver and related DT binding documentation.

Viorel Suman (3):
  ASoC: fsl: Add Audio Mixer CPU DAI driver
  ASoC: add fsl_audmix DT binding documentation
  ASoC: fsl: Add Audio Mixer machine driver

 .../devicetree/bindings/sound/fsl,audmix.txt   |  50 ++
 sound/soc/fsl/Kconfig  |  16 +
 sound/soc/fsl/Makefile |   5 +
 sound/soc/fsl/fsl_audmix.c | 578 +
 sound/soc/fsl/fsl_audmix.h | 102 
 sound/soc/fsl/imx-audmix.c | 327 
 6 files changed, 1078 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,audmix.txt
 create mode 100644 sound/soc/fsl/fsl_audmix.c
 create mode 100644 sound/soc/fsl/fsl_audmix.h
 create mode 100644 sound/soc/fsl/imx-audmix.c

-- 
2.7.4



[PATCH] ASoC: fsl_spdif: fix sysclk_df type

2019-02-18 Thread Viorel Suman
According to RM SPDIF STC SYSCLK_DF field is 9-bit wide, values
being in 0..511 range. Use a proper type to handle sysclk_df.

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/fsl_spdif.c | 10 ++
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/sound/soc/fsl/fsl_spdif.c b/sound/soc/fsl/fsl_spdif.c
index a26686e..4842e6d 100644
--- a/sound/soc/fsl/fsl_spdif.c
+++ b/sound/soc/fsl/fsl_spdif.c
@@ -96,7 +96,7 @@ struct fsl_spdif_priv {
bool dpll_locked;
u32 txrate[SPDIF_TXRATE_MAX];
u8 txclk_df[SPDIF_TXRATE_MAX];
-   u8 sysclk_df[SPDIF_TXRATE_MAX];
+   u16 sysclk_df[SPDIF_TXRATE_MAX];
u8 txclk_src[SPDIF_TXRATE_MAX];
u8 rxclk_src;
struct clk *txclk[SPDIF_TXRATE_MAX];
@@ -376,7 +376,8 @@ static int spdif_set_sample_rate(struct snd_pcm_substream 
*substream,
struct platform_device *pdev = spdif_priv->pdev;
unsigned long csfs = 0;
u32 stc, mask, rate;
-   u8 clk, txclk_df, sysclk_df;
+   u16 sysclk_df;
+   u8 clk, txclk_df;
int ret;
 
switch (sample_rate) {
@@ -1109,8 +1110,9 @@ static u32 fsl_spdif_txclk_caldiv(struct fsl_spdif_priv 
*spdif_priv,
static const u32 rate[] = { 32000, 44100, 48000, 96000, 192000 };
bool is_sysclk = clk_is_match(clk, spdif_priv->sysclk);
u64 rate_ideal, rate_actual, sub;
-   u32 sysclk_dfmin, sysclk_dfmax;
-   u32 txclk_df, sysclk_df, arate;
+   u32 arate;
+   u16 sysclk_dfmin, sysclk_dfmax, sysclk_df;
+   u8 txclk_df;
 
/* The sysclk has an extra divisor [2, 512] */
sysclk_dfmin = is_sysclk ? 2 : 1;
-- 
2.7.4



[PATCH] ASoC: fsl_spdif: fix TXCLK_DF mask

2019-02-18 Thread Viorel Suman
According to RM SPDIF TXCLK_DF mask is 7-bit wide.

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/fsl_spdif.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/sound/soc/fsl/fsl_spdif.h b/sound/soc/fsl/fsl_spdif.h
index 7666dab..e6c61e0 100644
--- a/sound/soc/fsl/fsl_spdif.h
+++ b/sound/soc/fsl/fsl_spdif.h
@@ -152,7 +152,7 @@ enum spdif_gainsel {
 #define STC_TXCLK_ALL_EN_MASK  (1 << STC_TXCLK_ALL_EN_OFFSET)
 #define STC_TXCLK_ALL_EN   (1 << STC_TXCLK_ALL_EN_OFFSET)
 #define STC_TXCLK_DF_OFFSET0
-#define STC_TXCLK_DF_MASK  (0x7ff << STC_TXCLK_DF_OFFSET)
+#define STC_TXCLK_DF_MASK  (0x7f << STC_TXCLK_DF_OFFSET)
 #define STC_TXCLK_DF(x)x) - 1) << STC_TXCLK_DF_OFFSET) & 
STC_TXCLK_DF_MASK)
 #define STC_TXCLK_SRC_MAX  8
 
-- 
2.7.4



[PATCH v5 1/3] ASoC: fsl: Add Audio Mixer CPU DAI driver

2019-02-15 Thread Viorel Suman
This patch implements Audio Mixer CPU DAI driver for NXP iMX8 SOCs.
The Audio Mixer is a on-chip functional module that allows mixing of
two audio streams into a single audio stream.

Audio Mixer datasheet is available here:
https://www.nxp.com/docs/en/reference-manual/IMX8DQXPRM.pdf

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/Kconfig  |   7 +
 sound/soc/fsl/Makefile |   3 +
 sound/soc/fsl/fsl_audmix.c | 578 +
 sound/soc/fsl/fsl_audmix.h | 102 
 4 files changed, 690 insertions(+)
 create mode 100644 sound/soc/fsl/fsl_audmix.c
 create mode 100644 sound/soc/fsl/fsl_audmix.h

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 7b1d997..0af2e056 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -24,6 +24,13 @@ config SND_SOC_FSL_SAI
  This option is only useful for out-of-tree drivers since
  in-tree drivers select it automatically.
 
+config SND_SOC_FSL_AUDMIX
+   tristate "Audio Mixer (AUDMIX) module support"
+   select REGMAP_MMIO
+   help
+ Say Y if you want to add Audio Mixer (AUDMIX)
+ support for the NXP iMX CPUs.
+
 config SND_SOC_FSL_SSI
tristate "Synchronous Serial Interface module (SSI) support"
select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 3c0ff31..4172d5a 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -12,6 +12,7 @@ snd-soc-p1022-rdk-objs := p1022_rdk.o
 obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
 
 # Freescale SSI/DMA/SAI/SPDIF Support
+snd-soc-fsl-audmix-objs := fsl_audmix.o
 snd-soc-fsl-asoc-card-objs := fsl-asoc-card.o
 snd-soc-fsl-asrc-objs := fsl_asrc.o fsl_asrc_dma.o
 snd-soc-fsl-sai-objs := fsl_sai.o
@@ -22,6 +23,8 @@ snd-soc-fsl-esai-objs := fsl_esai.o
 snd-soc-fsl-micfil-objs := fsl_micfil.o
 snd-soc-fsl-utils-objs := fsl_utils.o
 snd-soc-fsl-dma-objs := fsl_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
 obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc.o
 obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c
new file mode 100644
index 000..07b72a3
--- /dev/null
+++ b/sound/soc/fsl/fsl_audmix.c
@@ -0,0 +1,578 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NXP AUDMIX ALSA SoC Digital Audio Interface (DAI) driver
+ *
+ * Copyright 2017 NXP
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fsl_audmix.h"
+
+#define SOC_ENUM_SINGLE_S(xreg, xshift, xtexts) \
+   SOC_ENUM_SINGLE(xreg, xshift, ARRAY_SIZE(xtexts), xtexts)
+
+static const char
+   *tdm_sel[] = { "TDM1", "TDM2", },
+   *mode_sel[] = { "Disabled", "TDM1", "TDM2", "Mixed", },
+   *width_sel[] = { "16b", "18b", "20b", "24b", "32b", },
+   *endis_sel[] = { "Disabled", "Enabled", },
+   *updn_sel[] = { "Downward", "Upward", },
+   *mask_sel[] = { "Unmask", "Mask", };
+
+static const struct soc_enum fsl_audmix_enum[] = {
+/* FSL_AUDMIX_CTR enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MIXCLK_SHIFT, tdm_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_OUTSRC_SHIFT, mode_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_OUTWIDTH_SHIFT, width_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MASKRTDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MASKCKDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_SYNCMODE_SHIFT, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_SYNCSRC_SHIFT, tdm_sel),
+/* FSL_AUDMIX_ATCR0 enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR0, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR0, 1, updn_sel),
+/* FSL_AUDMIX_ATCR1 enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR1, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR1, 1, updn_sel),
+};
+
+struct fsl_audmix_state {
+   u8 tdms;
+   u8 clk;
+   char msg[64];
+};
+
+static const struct fsl_audmix_state prms[4][4] = {{
+   /* DIS->DIS, do nothing */
+   { .tdms = 0, .clk = 0, .msg = "" },
+   /* DIS->TDM1*/
+   { .tdms = 1, .clk = 1, .msg = "DIS->TDM1: TDM1 not started!\n" },
+   /* DIS->TDM2*/
+   { .tdms = 2, .clk = 2, .msg = "DIS->TDM2: TDM2 not started!\n" },
+   /* DIS->MIX */
+   { .tdms = 3, .clk = 0, .msg = "DIS->MIX: Please start both TDMs!\n" }
+}, {   /* TDM1->DIS */
+   { .tdms = 1, .clk = 0, .msg = "TDM1->DIS: TDM1 not started!\n" },
+   /* TDM1->TDM1, do nothing */
+   { .tdms = 0, .clk = 0, .msg = "" },
+   /* TDM1->TDM2 */
+   { .tdms = 3, .clk = 2, .msg = &

[PATCH v5 2/3] ASoC: add fsl_audmix DT binding documentation

2019-02-15 Thread Viorel Suman
Add the DT binding documentation for NXP Audio Mixer
CPU DAI driver.

Signed-off-by: Viorel Suman 
---
 .../devicetree/bindings/sound/fsl,audmix.txt   | 50 ++
 1 file changed, 50 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,audmix.txt

diff --git a/Documentation/devicetree/bindings/sound/fsl,audmix.txt 
b/Documentation/devicetree/bindings/sound/fsl,audmix.txt
new file mode 100644
index 000..840b7e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,audmix.txt
@@ -0,0 +1,50 @@
+NXP Audio Mixer (AUDMIX).
+
+The Audio Mixer is a on-chip functional module that allows mixing of two
+audio streams into a single audio stream. Audio Mixer has two input serial
+audio interfaces. These are driven by two Synchronous Audio interface
+modules (SAI). Each input serial interface carries 8 audio channels in its
+frame in TDM manner. Mixer mixes audio samples of corresponding channels
+from two interfaces into a single sample. Before mixing, audio samples of
+two inputs can be attenuated based on configuration. The output of the
+Audio Mixer is also a serial audio interface. Like input interfaces it has
+the same TDM frame format. This output is used to drive the serial DAC TDM
+interface of audio codec and also sent to the external pins along with the
+receive path of normal audio SAI module for readback by the CPU.
+
+The output of Audio Mixer can be selected from any of the three streams
+ - serial audio input 1
+ - serial audio input 2
+ - mixed audio
+
+Mixing operation is independent of audio sample rate but the two audio
+input streams must have same audio sample rate with same number of channels
+in TDM frame to be eligible for mixing.
+
+Device driver required properties:
+=
+  - compatible : Compatible list, contains "fsl,imx8qm-audmix"
+
+  - reg: Offset and length of the register set for the 
device.
+
+  - clocks : Must contain an entry for each entry in clock-names.
+
+  - clock-names: Must include the "ipg" for register access.
+
+  - power-domains  : Must contain the phandle to AUDMIX power domain node
+
+  - dais   : Must contain a list of phandles to AUDMIX connected
+ DAIs. The current implementation requires two phandles
+ to SAI interfaces to be provided, the first SAI in the
+ list being used to route the AUDMIX output.
+
+Device driver configuration example:
+==
+  audmix: audmix@5984 {
+compatible = "fsl,imx8qm-audmix";
+reg = <0x0 0x5984 0x0 0x1>;
+clocks = < IMX8QXP_AUD_AUDMIX_IPG>;
+clock-names = "ipg";
+power-domains = <_audmix>;
+dais = <>, <>;
+  };
-- 
2.7.4



[PATCH v5 3/3] ASoC: fsl: Add Audio Mixer machine driver

2019-02-15 Thread Viorel Suman
This patch implements Audio Mixer machine driver for NXP iMX8 SOCs.
It connects together Audio Mixer and related SAI instances.

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/Kconfig  |   9 ++
 sound/soc/fsl/Makefile |   2 +
 sound/soc/fsl/imx-audmix.c | 327 +
 3 files changed, 338 insertions(+)
 create mode 100644 sound/soc/fsl/imx-audmix.c

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 0af2e056..d87c842 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -303,6 +303,15 @@ config SND_SOC_FSL_ASOC_CARD
 CS4271, CS4272 and SGTL5000.
 Say Y if you want to add support for Freescale Generic ASoC Sound Card.
 
+config SND_SOC_IMX_AUDMIX
+   tristate "SoC Audio support for i.MX boards with AUDMIX"
+   select SND_SOC_FSL_AUDMIX
+   select SND_SOC_FSL_SAI
+   help
+ SoC Audio support for i.MX boards with Audio Mixer
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ an Audio Mixer.
+
 endif # SND_IMX_SOC
 
 endmenu
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 4172d5a..c0dd044 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -62,6 +62,7 @@ snd-soc-imx-es8328-objs := imx-es8328.o
 snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
 snd-soc-imx-spdif-objs := imx-spdif.o
 snd-soc-imx-mc13783-objs := imx-mc13783.o
+snd-soc-imx-audmix-objs := imx-audmix.o
 
 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
 obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
@@ -71,3 +72,4 @@ obj-$(CONFIG_SND_SOC_IMX_ES8328) += snd-soc-imx-es8328.o
 obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
 obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
 obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
+obj-$(CONFIG_SND_SOC_IMX_AUDMIX) += snd-soc-imx-audmix.o
diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c
new file mode 100644
index 000..72e37ca
--- /dev/null
+++ b/sound/soc/fsl/imx-audmix.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2017 NXP
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "fsl_sai.h"
+#include "fsl_audmix.h"
+
+struct imx_audmix {
+   struct platform_device *pdev;
+   struct snd_soc_card card;
+   struct platform_device *audmix_pdev;
+   struct platform_device *out_pdev;
+   struct clk *cpu_mclk;
+   int num_dai;
+   struct snd_soc_dai_link *dai;
+   int num_dai_conf;
+   struct snd_soc_codec_conf *dai_conf;
+   int num_dapm_routes;
+   struct snd_soc_dapm_route *dapm_routes;
+};
+
+static const u32 imx_audmix_rates[] = {
+   8000, 12000, 16000, 24000, 32000, 48000, 64000, 96000,
+};
+
+static const struct snd_pcm_hw_constraint_list imx_audmix_rate_constraints = {
+   .count = ARRAY_SIZE(imx_audmix_rates),
+   .list = imx_audmix_rates,
+};
+
+static int imx_audmix_fe_startup(struct snd_pcm_substream *substream)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct imx_audmix *priv = snd_soc_card_get_drvdata(rtd->card);
+   struct snd_pcm_runtime *runtime = substream->runtime;
+   struct device *dev = rtd->card->dev;
+   unsigned long clk_rate = clk_get_rate(priv->cpu_mclk);
+   int ret;
+
+   if (clk_rate % 24576000 == 0) {
+   ret = snd_pcm_hw_constraint_list(runtime, 0,
+SNDRV_PCM_HW_PARAM_RATE,
+_audmix_rate_constraints);
+   if (ret < 0)
+   return ret;
+   } else {
+   dev_warn(dev, "mclk may be not supported %lu\n", clk_rate);
+   }
+
+   ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS,
+  1, 8);
+   if (ret < 0)
+   return ret;
+
+   return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
+   FSL_AUDMIX_FORMATS);
+}
+
+static int imx_audmix_fe_hw_params(struct snd_pcm_substream *substream,
+  struct snd_pcm_hw_params *params)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct device *dev = rtd->card->dev;
+   bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+   unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF;
+   u32 channels = params_channels(params);
+   int ret, dir;
+
+   /* For playback the AUDMIX is s

[PATCH v5 0/3] Add NXP AUDMIX device and machine drivers

2019-02-15 Thread Viorel Suman
The patchset adds NXP Audio Mixer (AUDMIX) device and machine
drivers and related DT bindings documentation.

Changes since V4:
1. Removed "model" attribute from device driver DT bindings documentation
   as suggested by Nicolin.

Changes since V3:
1. Removed machine driver DT bindings documentation.
2. Trigger machine driver probe from device driver as suggested by Nicolin.

Changes since V2:
1. Moved "dais" node from machine driver DTS node to device driver DTS node
  as suggested by Rob.

Changes since V1:
1. Original patch split into distinct patches for the device driver and
  DT binding documentation.
2. Replaced AMIX with AUDMIX in both code and file names as it looks more
  RM-compliant.
3. Removed polarity control from CPU DAI driver as suggested by Nicolin.
4. Added machine driver and related DT binding documentation.

Viorel Suman (3):
  ASoC: fsl: Add Audio Mixer CPU DAI driver
  ASoC: add fsl_audmix DT binding documentation
  ASoC: fsl: Add Audio Mixer machine driver

 .../devicetree/bindings/sound/fsl,audmix.txt   |  50 ++
 sound/soc/fsl/Kconfig  |  16 +
 sound/soc/fsl/Makefile |   5 +
 sound/soc/fsl/fsl_audmix.c | 578 +
 sound/soc/fsl/fsl_audmix.h | 102 
 sound/soc/fsl/imx-audmix.c | 327 
 6 files changed, 1078 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,audmix.txt
 create mode 100644 sound/soc/fsl/fsl_audmix.c
 create mode 100644 sound/soc/fsl/fsl_audmix.h
 create mode 100644 sound/soc/fsl/imx-audmix.c

-- 
2.7.4



Re: [PATCH v3 0/4] Add NXP AUDMIX device and machine drivers

2019-01-22 Thread Viorel Suman
Hi Rob,

On Lu, 2019-01-21 at 09:23 -0600, Rob Herring wrote:
> On Fri, Jan 18, 2019 at 11:46:42AM -0800, Nicolin Chen wrote:
> > 
> > On Fri, Jan 18, 2019 at 01:16:24PM +0000, Viorel Suman wrote:
> > > 
> > > > 
> > > > > 
> > > > > 1. Moved "dais" node from machine driver DTS node to device
> > > > > driver
> > > > > DTS node
> > > > >   as suggested by Rob.
> > > > That was not what I suggested. You still have a virtual node
> > > > which
> > > > looks to me to be unnecessary.
> > > To me removing virtual node implies that AUDMIX machine driver
> > > (imx-
> > > audmix.c + virtual node) shall be removed and machine driver code
> > > merged into device driver (fsl_audmix.c + device node) - please
> > > let me
> > > know if my understanding is wrong.
> > We could use a non-DT configuration right? From the driver logic,
> > DT just registers a device corresponding to the machine driver so
> > that it can probe(). We could register one in fsl_audmix instead.
> > Please refer to how fsl_ssi registers the sound card device. The
> > machine driver can get audmix_np from the parent device pointer,
> > and I think that's all you need.
> Yes.

Thank you, sent V4 which implements the approach suggested by Nicolin.

> 
> > 
> > Or maybe someone else would provide a better way. But it'd work.
> Or the machine driver could create the audmix device. That probably 
> makes less sense, but either way there doesn't have to be a 1-1 
> correspondence of DT nodes and (platform) devices.
> 
> I'm not an ASoC expert, but why can't the machine driver just control
> the audmix directly (with DAIs as separate drivers)? Is the audmix
> ever going to a be a component for a different machine driver?
> 
> Rob

Currently I'm not aware of any information with regard to if audmix is
ever going to work with other DAIs than SAI. Howerver from audmix IP
block integration perspective the only requirement is that the input
DAI must be connected to audmix over I2S bus, possible DAI options are
SAI, ESAI, etc - I think the approach to mix both device and machine
drivers into a single entity is not the best way to go.

/Viorel

Re: [PATCH v3 0/4] Add NXP AUDMIX device and machine drivers

2019-01-22 Thread Viorel Suman
Hi Nicolin,

On Vi, 2019-01-18 at 11:46 -0800, Nicolin Chen wrote:
> On Fri, Jan 18, 2019 at 01:16:24PM +0000, Viorel Suman wrote:
> > 
> > > 
> > > > 
> > > > 1. Moved "dais" node from machine driver DTS node to device
> > > > driver
> > > > DTS node
> > > >   as suggested by Rob.
> > > That was not what I suggested. You still have a virtual node
> > > which
> > > looks to me to be unnecessary.
> > To me removing virtual node implies that AUDMIX machine driver
> > (imx-
> > audmix.c + virtual node) shall be removed and machine driver code
> > merged into device driver (fsl_audmix.c + device node) - please let
> > me
> > know if my understanding is wrong.
> We could use a non-DT configuration right? From the driver logic,
> DT just registers a device corresponding to the machine driver so
> that it can probe(). We could register one in fsl_audmix instead.
> Please refer to how fsl_ssi registers the sound card device. The
> machine driver can get audmix_np from the parent device pointer,
> and I think that's all you need.
> 
> Or maybe someone else would provide a better way. But it'd work.

Sent V4 - it implements the approach you suggested. Thank you for the
hint, works well indeed.

Regards,
Viorel



[PATCH v4 0/3] Add NXP AUDMIX device and machine drivers

2019-01-22 Thread Viorel Suman
The patchset adds NXP Audio Mixer (AUDMIX) device and machine
drivers and related DT bindings documentation.

Changes since V3:
1. Removed machine driver DT bindings documentation.
2. Trigger machine driver probe from device driver as suggested by Nicolin.

Changes since V2:
1. Moved "dais" node from machine driver DTS node to device driver DTS node
  as suggested by Rob.

Changes since V1:
1. Original patch split into distinct patches for the device driver and
  DT binding documentation.
2. Replaced AMIX with AUDMIX in both code and file names as it looks more
  RM-compliant.
3. Removed polarity control from CPU DAI driver as suggested by Nicolin.
4. Added machine driver and related DT binding documentation.

Viorel Suman (3):
  ASoC: fsl: Add Audio Mixer CPU DAI driver
  ASoC: add fsl_audmix DT binding documentation
  ASoC: fsl: Add Audio Mixer machine driver

 .../devicetree/bindings/sound/fsl,audmix.txt   |  54 ++
 sound/soc/fsl/Kconfig  |  16 +
 sound/soc/fsl/Makefile |   5 +
 sound/soc/fsl/fsl_audmix.c | 576 +
 sound/soc/fsl/fsl_audmix.h | 102 
 sound/soc/fsl/imx-audmix.c | 327 
 6 files changed, 1080 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,audmix.txt
 create mode 100644 sound/soc/fsl/fsl_audmix.c
 create mode 100644 sound/soc/fsl/fsl_audmix.h
 create mode 100644 sound/soc/fsl/imx-audmix.c

-- 
2.7.4



[PATCH v4 1/3] ASoC: fsl: Add Audio Mixer CPU DAI driver

2019-01-22 Thread Viorel Suman
This patch implements Audio Mixer CPU DAI driver for NXP iMX8 SOCs.
The Audio Mixer is a on-chip functional module that allows mixing of
two audio streams into a single audio stream.

Audio Mixer datasheet is available here:
https://www.nxp.com/docs/en/reference-manual/IMX8DQXPRM.pdf

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/Kconfig  |   7 +
 sound/soc/fsl/Makefile |   3 +
 sound/soc/fsl/fsl_audmix.c | 576 +
 sound/soc/fsl/fsl_audmix.h | 102 
 4 files changed, 688 insertions(+)
 create mode 100644 sound/soc/fsl/fsl_audmix.c
 create mode 100644 sound/soc/fsl/fsl_audmix.h

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 7b1d997..0af2e056 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -24,6 +24,13 @@ config SND_SOC_FSL_SAI
  This option is only useful for out-of-tree drivers since
  in-tree drivers select it automatically.
 
+config SND_SOC_FSL_AUDMIX
+   tristate "Audio Mixer (AUDMIX) module support"
+   select REGMAP_MMIO
+   help
+ Say Y if you want to add Audio Mixer (AUDMIX)
+ support for the NXP iMX CPUs.
+
 config SND_SOC_FSL_SSI
tristate "Synchronous Serial Interface module (SSI) support"
select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 3c0ff31..4172d5a 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -12,6 +12,7 @@ snd-soc-p1022-rdk-objs := p1022_rdk.o
 obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
 
 # Freescale SSI/DMA/SAI/SPDIF Support
+snd-soc-fsl-audmix-objs := fsl_audmix.o
 snd-soc-fsl-asoc-card-objs := fsl-asoc-card.o
 snd-soc-fsl-asrc-objs := fsl_asrc.o fsl_asrc_dma.o
 snd-soc-fsl-sai-objs := fsl_sai.o
@@ -22,6 +23,8 @@ snd-soc-fsl-esai-objs := fsl_esai.o
 snd-soc-fsl-micfil-objs := fsl_micfil.o
 snd-soc-fsl-utils-objs := fsl_utils.o
 snd-soc-fsl-dma-objs := fsl_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
 obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc.o
 obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c
new file mode 100644
index 000..3356cb6
--- /dev/null
+++ b/sound/soc/fsl/fsl_audmix.c
@@ -0,0 +1,576 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NXP AUDMIX ALSA SoC Digital Audio Interface (DAI) driver
+ *
+ * Copyright 2017 NXP
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fsl_audmix.h"
+
+#define SOC_ENUM_SINGLE_S(xreg, xshift, xtexts) \
+   SOC_ENUM_SINGLE(xreg, xshift, ARRAY_SIZE(xtexts), xtexts)
+
+static const char
+   *tdm_sel[] = { "TDM1", "TDM2", },
+   *mode_sel[] = { "Disabled", "TDM1", "TDM2", "Mixed", },
+   *width_sel[] = { "16b", "18b", "20b", "24b", "32b", },
+   *endis_sel[] = { "Disabled", "Enabled", },
+   *updn_sel[] = { "Downward", "Upward", },
+   *mask_sel[] = { "Unmask", "Mask", };
+
+static const struct soc_enum fsl_audmix_enum[] = {
+/* FSL_AUDMIX_CTR enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MIXCLK_SHIFT, tdm_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_OUTSRC_SHIFT, mode_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_OUTWIDTH_SHIFT, width_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MASKRTDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MASKCKDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_SYNCMODE_SHIFT, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_SYNCSRC_SHIFT, tdm_sel),
+/* FSL_AUDMIX_ATCR0 enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR0, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR0, 1, updn_sel),
+/* FSL_AUDMIX_ATCR1 enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR1, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR1, 1, updn_sel),
+};
+
+struct fsl_audmix_state {
+   u8 tdms;
+   u8 clk;
+   char msg[64];
+};
+
+static const struct fsl_audmix_state prms[4][4] = {{
+   /* DIS->DIS, do nothing */
+   { .tdms = 0, .clk = 0, .msg = "" },
+   /* DIS->TDM1*/
+   { .tdms = 1, .clk = 1, .msg = "DIS->TDM1: TDM1 not started!\n" },
+   /* DIS->TDM2*/
+   { .tdms = 2, .clk = 2, .msg = "DIS->TDM2: TDM2 not started!\n" },
+   /* DIS->MIX */
+   { .tdms = 3, .clk = 0, .msg = "DIS->MIX: Please start both TDMs!\n" }
+}, {   /* TDM1->DIS */
+   { .tdms = 1, .clk = 0, .msg = "TDM1->DIS: TDM1 not started!\n" },
+   /* TDM1->TDM1, do nothing */
+   { .tdms = 0, .clk = 0, .msg = "" },
+   /* TDM1->TDM2 */
+   { .tdms = 3, .clk = 2, .msg = &

[PATCH v4 2/3] ASoC: add fsl_audmix DT binding documentation

2019-01-22 Thread Viorel Suman
Add the DT binding documentation for NXP Audio Mixer
CPU DAI driver.

Signed-off-by: Viorel Suman 
---
 .../devicetree/bindings/sound/fsl,audmix.txt   | 54 ++
 1 file changed, 54 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,audmix.txt

diff --git a/Documentation/devicetree/bindings/sound/fsl,audmix.txt 
b/Documentation/devicetree/bindings/sound/fsl,audmix.txt
new file mode 100644
index 000..45f807e
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,audmix.txt
@@ -0,0 +1,54 @@
+NXP Audio Mixer (AUDMIX).
+
+The Audio Mixer is a on-chip functional module that allows mixing of two
+audio streams into a single audio stream. Audio Mixer has two input serial
+audio interfaces. These are driven by two Synchronous Audio interface
+modules (SAI). Each input serial interface carries 8 audio channels in its
+frame in TDM manner. Mixer mixes audio samples of corresponding channels
+from two interfaces into a single sample. Before mixing, audio samples of
+two inputs can be attenuated based on configuration. The output of the
+Audio Mixer is also a serial audio interface. Like input interfaces it has
+the same TDM frame format. This output is used to drive the serial DAC TDM
+interface of audio codec and also sent to the external pins along with the
+receive path of normal audio SAI module for readback by the CPU.
+
+The output of Audio Mixer can be selected from any of the three streams
+ - serial audio input 1
+ - serial audio input 2
+ - mixed audio
+
+Mixing operation is independent of audio sample rate but the two audio
+input streams must have same audio sample rate with same number of channels
+in TDM frame to be eligible for mixing.
+
+Device driver required properties:
+=
+  - compatible : Compatible list, contains "fsl,imx8qm-audmix"
+
+  - reg: Offset and length of the register set for the 
device.
+
+  - clocks : Must contain an entry for each entry in clock-names.
+
+  - clock-names: Must include the "ipg" for register access.
+
+  - power-domains  : Must contain the phandle to AUDMIX power domain node
+
+  - dais   : Must contain a list of phandles to AUDMIX connected
+ DAIs. The current implementation requires two phandles
+ to SAI interfaces to be provided, the first SAI in the
+ list being used to route the AUDMIX output.
+
+  - model  : Must contain machine driver name which will configure
+ and instantiate the appropriate audio card.
+
+Device driver configuration example:
+==
+  audmix: audmix@5984 {
+compatible = "fsl,imx8qm-audmix";
+reg = <0x0 0x5984 0x0 0x1>;
+clocks = < IMX8QXP_AUD_AUDMIX_IPG>;
+clock-names = "ipg";
+power-domains = <_audmix>;
+dais = <>, <>;
+model = "imx-audmix";
+  };
-- 
2.7.4



[PATCH v4 3/3] ASoC: fsl: Add Audio Mixer machine driver

2019-01-22 Thread Viorel Suman
This patch implements Audio Mixer machine driver for NXP iMX8 SOCs.
It connects together Audio Mixer and related SAI instances.

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/Kconfig  |   9 ++
 sound/soc/fsl/Makefile |   2 +
 sound/soc/fsl/imx-audmix.c | 327 +
 3 files changed, 338 insertions(+)
 create mode 100644 sound/soc/fsl/imx-audmix.c

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 0af2e056..d87c842 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -303,6 +303,15 @@ config SND_SOC_FSL_ASOC_CARD
 CS4271, CS4272 and SGTL5000.
 Say Y if you want to add support for Freescale Generic ASoC Sound Card.
 
+config SND_SOC_IMX_AUDMIX
+   tristate "SoC Audio support for i.MX boards with AUDMIX"
+   select SND_SOC_FSL_AUDMIX
+   select SND_SOC_FSL_SAI
+   help
+ SoC Audio support for i.MX boards with Audio Mixer
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ an Audio Mixer.
+
 endif # SND_IMX_SOC
 
 endmenu
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 4172d5a..c0dd044 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -62,6 +62,7 @@ snd-soc-imx-es8328-objs := imx-es8328.o
 snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
 snd-soc-imx-spdif-objs := imx-spdif.o
 snd-soc-imx-mc13783-objs := imx-mc13783.o
+snd-soc-imx-audmix-objs := imx-audmix.o
 
 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
 obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
@@ -71,3 +72,4 @@ obj-$(CONFIG_SND_SOC_IMX_ES8328) += snd-soc-imx-es8328.o
 obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
 obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
 obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
+obj-$(CONFIG_SND_SOC_IMX_AUDMIX) += snd-soc-imx-audmix.o
diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c
new file mode 100644
index 000..72e37ca
--- /dev/null
+++ b/sound/soc/fsl/imx-audmix.c
@@ -0,0 +1,327 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2017 NXP
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "fsl_sai.h"
+#include "fsl_audmix.h"
+
+struct imx_audmix {
+   struct platform_device *pdev;
+   struct snd_soc_card card;
+   struct platform_device *audmix_pdev;
+   struct platform_device *out_pdev;
+   struct clk *cpu_mclk;
+   int num_dai;
+   struct snd_soc_dai_link *dai;
+   int num_dai_conf;
+   struct snd_soc_codec_conf *dai_conf;
+   int num_dapm_routes;
+   struct snd_soc_dapm_route *dapm_routes;
+};
+
+static const u32 imx_audmix_rates[] = {
+   8000, 12000, 16000, 24000, 32000, 48000, 64000, 96000,
+};
+
+static const struct snd_pcm_hw_constraint_list imx_audmix_rate_constraints = {
+   .count = ARRAY_SIZE(imx_audmix_rates),
+   .list = imx_audmix_rates,
+};
+
+static int imx_audmix_fe_startup(struct snd_pcm_substream *substream)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct imx_audmix *priv = snd_soc_card_get_drvdata(rtd->card);
+   struct snd_pcm_runtime *runtime = substream->runtime;
+   struct device *dev = rtd->card->dev;
+   unsigned long clk_rate = clk_get_rate(priv->cpu_mclk);
+   int ret;
+
+   if (clk_rate % 24576000 == 0) {
+   ret = snd_pcm_hw_constraint_list(runtime, 0,
+SNDRV_PCM_HW_PARAM_RATE,
+_audmix_rate_constraints);
+   if (ret < 0)
+   return ret;
+   } else {
+   dev_warn(dev, "mclk may be not supported %lu\n", clk_rate);
+   }
+
+   ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS,
+  1, 8);
+   if (ret < 0)
+   return ret;
+
+   return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
+   FSL_AUDMIX_FORMATS);
+}
+
+static int imx_audmix_fe_hw_params(struct snd_pcm_substream *substream,
+  struct snd_pcm_hw_params *params)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct device *dev = rtd->card->dev;
+   bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+   unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF;
+   u32 channels = params_channels(params);
+   int ret, dir;
+
+   /* For playback the AUDMIX is s

Re: [PATCH v3 0/4] Add NXP AUDMIX device and machine drivers

2019-01-18 Thread Viorel Suman
Hi Rob, Nicolin, All,

On Jo, 2019-01-17 at 10:18 -0600, Rob Herring wrote:
> On Thu, Jan 17, 2019 at 12:46:25PM +0000, Viorel Suman wrote:
> > 
> > The patchset adds NXP Audio Mixer (AUDMIX) device and machine
> > drivers and related DT bindings documentation.
> > 
> > Changes since V2:
> > 1. Moved "dais" node from machine driver DTS node to device driver
> > DTS node
> >   as suggested by Rob.
> That was not what I suggested. You still have a virtual node which
> looks to me to be unnecessary.

To me removing virtual node implies that AUDMIX machine driver (imx-
audmix.c + virtual node) shall be removed and machine driver code
merged into device driver (fsl_audmix.c + device node) - please let me
know if my understanding is wrong.

The implication is that this makes AUDMIX device driver bounded to a
particular DAI type of interface - SAI. The original intention is to
keep AUDMIX device driver DAI-agnostic.

Indeed, currently the connection between AUDMIX and SAI IP blocks in
i.MX8QM and i.MX8QXP is fixed inside the SoC, but on other platforms we
may expect AUDMIX to be connected inside the SoC to other IP blocks -
to ESAI interface for instance.

At this moment it's a bit difficult for me to evaluate how critical is
to keep the device driver DAI-agnostic, so if you think it's better to
go now with a SAI bounded AUDMIX device driver - please confirm, I'll
merge machine driver code into device driver.

Thank you,
Viorel

> 
> > 
> > 
> > Changes since V1:
> > 1. Original patch split into distinct patches for the device driver
> > and
> >   DT binding documentation.
> > 2. Replaced AMIX with AUDMIX in both code and file names as it
> > looks more
> >   RM-compliant.
> > 3. Removed polarity control from CPU DAI driver as suggested by
> > Nicolin.
> > 4. Added machine driver and related DT binding documentation.
> > 
> > Viorel Suman (4):
> >   ASoC: fsl: Add Audio Mixer CPU DAI driver
> >   ASoC: add fsl_audmix DT binding documentation
> >   ASoC: fsl: Add Audio Mixer machine driver
> >   ASoC: add imx-audmix DT binding documentation
> > 
> >  .../devicetree/bindings/sound/fsl,audmix.txt   |  50 ++
> >  .../devicetree/bindings/sound/imx-audmix.txt   |  18 +
> >  sound/soc/fsl/Kconfig  |  16 +
> >  sound/soc/fsl/Makefile |   5 +
> >  sound/soc/fsl/fsl_audmix.c | 551
> > +
> >  sound/soc/fsl/fsl_audmix.h | 102 
> >  sound/soc/fsl/imx-audmix.c | 334
> > +
> >  7 files changed, 1076 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/sound/fsl,audmix.txt
> >  create mode 100644 Documentation/devicetree/bindings/sound/imx-
> > audmix.txt
> >  create mode 100644 sound/soc/fsl/fsl_audmix.c
> >  create mode 100644 sound/soc/fsl/fsl_audmix.h
> >  create mode 100644 sound/soc/fsl/imx-audmix.c
> > 

[PATCH v3 4/4] ASoC: add imx-audmix DT binding documentation

2019-01-17 Thread Viorel Suman
Add the DT binding documentation for Audio Mixer
machine driver.

Signed-off-by: Viorel Suman 
---
 Documentation/devicetree/bindings/sound/imx-audmix.txt | 18 ++
 1 file changed, 18 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/imx-audmix.txt

diff --git a/Documentation/devicetree/bindings/sound/imx-audmix.txt 
b/Documentation/devicetree/bindings/sound/imx-audmix.txt
new file mode 100644
index 000..c840ed5
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audmix.txt
@@ -0,0 +1,18 @@
+NXP Audio Mixer (AUDMIX) machine driver.
+
+Required properties:
+===
+  - compatible : Compatible list, contains "fsl,imx-audmix"
+
+  - model  : Short audio card description.
+
+  - audmix-controller  : Must contain the phandle to the AUDMIX device node.
+
+Machine driver configuration example:
+
+  sound-audmix-sai {
+compatible = "fsl,imx-audmix";
+model = "audmix-sai";
+audmix-controller = <>;
+  };
+
-- 
2.7.4



[PATCH v3 3/4] ASoC: fsl: Add Audio Mixer machine driver

2019-01-17 Thread Viorel Suman
This patch implements Audio Mixer machine driver for NXP iMX8 SOCs.
It connects together Audio Mixer and related SAI instances.

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/Kconfig  |   9 ++
 sound/soc/fsl/Makefile |   2 +
 sound/soc/fsl/imx-audmix.c | 334 +
 3 files changed, 345 insertions(+)
 create mode 100644 sound/soc/fsl/imx-audmix.c

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 0af2e056..d87c842 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -303,6 +303,15 @@ config SND_SOC_FSL_ASOC_CARD
 CS4271, CS4272 and SGTL5000.
 Say Y if you want to add support for Freescale Generic ASoC Sound Card.
 
+config SND_SOC_IMX_AUDMIX
+   tristate "SoC Audio support for i.MX boards with AUDMIX"
+   select SND_SOC_FSL_AUDMIX
+   select SND_SOC_FSL_SAI
+   help
+ SoC Audio support for i.MX boards with Audio Mixer
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ an Audio Mixer.
+
 endif # SND_IMX_SOC
 
 endmenu
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 4172d5a..c0dd044 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -62,6 +62,7 @@ snd-soc-imx-es8328-objs := imx-es8328.o
 snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
 snd-soc-imx-spdif-objs := imx-spdif.o
 snd-soc-imx-mc13783-objs := imx-mc13783.o
+snd-soc-imx-audmix-objs := imx-audmix.o
 
 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
 obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
@@ -71,3 +72,4 @@ obj-$(CONFIG_SND_SOC_IMX_ES8328) += snd-soc-imx-es8328.o
 obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
 obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
 obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
+obj-$(CONFIG_SND_SOC_IMX_AUDMIX) += snd-soc-imx-audmix.o
diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c
new file mode 100644
index 000..30396e4
--- /dev/null
+++ b/sound/soc/fsl/imx-audmix.c
@@ -0,0 +1,334 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2017 NXP
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "fsl_sai.h"
+#include "fsl_audmix.h"
+
+struct imx_audmix {
+   struct platform_device *pdev;
+   struct snd_soc_card card;
+   struct platform_device *audmix_pdev;
+   struct platform_device *out_pdev;
+   struct clk *cpu_mclk;
+   int num_dai;
+   struct snd_soc_dai_link *dai;
+   int num_dai_conf;
+   struct snd_soc_codec_conf *dai_conf;
+   int num_dapm_routes;
+   struct snd_soc_dapm_route *dapm_routes;
+};
+
+static const u32 imx_audmix_rates[] = {
+   8000, 12000, 16000, 24000, 32000, 48000, 64000, 96000,
+};
+
+static const struct snd_pcm_hw_constraint_list imx_audmix_rate_constraints = {
+   .count = ARRAY_SIZE(imx_audmix_rates),
+   .list = imx_audmix_rates,
+};
+
+static int imx_audmix_fe_startup(struct snd_pcm_substream *substream)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct imx_audmix *priv = snd_soc_card_get_drvdata(rtd->card);
+   struct snd_pcm_runtime *runtime = substream->runtime;
+   struct device *dev = rtd->card->dev;
+   unsigned long clk_rate = clk_get_rate(priv->cpu_mclk);
+   int ret;
+
+   if (clk_rate % 24576000 == 0) {
+   ret = snd_pcm_hw_constraint_list(runtime, 0,
+SNDRV_PCM_HW_PARAM_RATE,
+_audmix_rate_constraints);
+   if (ret < 0)
+   return ret;
+   } else {
+   dev_warn(dev, "mclk may be not supported %lu\n", clk_rate);
+   }
+
+   ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS,
+  1, 8);
+   if (ret < 0)
+   return ret;
+
+   return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
+   FSL_AUDMIX_FORMATS);
+}
+
+static int imx_audmix_fe_hw_params(struct snd_pcm_substream *substream,
+  struct snd_pcm_hw_params *params)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct device *dev = rtd->card->dev;
+   bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+   unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF;
+   u32 channels = params_channels(params);
+   int ret, dir;
+
+   /* For playback the AUDMIX is s

[PATCH v3 0/4] Add NXP AUDMIX device and machine drivers

2019-01-17 Thread Viorel Suman
The patchset adds NXP Audio Mixer (AUDMIX) device and machine
drivers and related DT bindings documentation.

Changes since V2:
1. Moved "dais" node from machine driver DTS node to device driver DTS node
  as suggested by Rob.

Changes since V1:
1. Original patch split into distinct patches for the device driver and
  DT binding documentation.
2. Replaced AMIX with AUDMIX in both code and file names as it looks more
  RM-compliant.
3. Removed polarity control from CPU DAI driver as suggested by Nicolin.
4. Added machine driver and related DT binding documentation.

Viorel Suman (4):
  ASoC: fsl: Add Audio Mixer CPU DAI driver
  ASoC: add fsl_audmix DT binding documentation
  ASoC: fsl: Add Audio Mixer machine driver
  ASoC: add imx-audmix DT binding documentation

 .../devicetree/bindings/sound/fsl,audmix.txt   |  50 ++
 .../devicetree/bindings/sound/imx-audmix.txt   |  18 +
 sound/soc/fsl/Kconfig  |  16 +
 sound/soc/fsl/Makefile |   5 +
 sound/soc/fsl/fsl_audmix.c | 551 +
 sound/soc/fsl/fsl_audmix.h | 102 
 sound/soc/fsl/imx-audmix.c | 334 +
 7 files changed, 1076 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,audmix.txt
 create mode 100644 Documentation/devicetree/bindings/sound/imx-audmix.txt
 create mode 100644 sound/soc/fsl/fsl_audmix.c
 create mode 100644 sound/soc/fsl/fsl_audmix.h
 create mode 100644 sound/soc/fsl/imx-audmix.c

-- 
2.7.4



[PATCH v3 1/4] ASoC: fsl: Add Audio Mixer CPU DAI driver

2019-01-17 Thread Viorel Suman
This patch implements Audio Mixer CPU DAI driver for NXP iMX8 SOCs.
The Audio Mixer is a on-chip functional module that allows mixing of
two audio streams into a single audio stream.

Audio Mixer datasheet is available here:
https://www.nxp.com/docs/en/reference-manual/IMX8DQXPRM.pdf

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/Kconfig  |   7 +
 sound/soc/fsl/Makefile |   3 +
 sound/soc/fsl/fsl_audmix.c | 551 +
 sound/soc/fsl/fsl_audmix.h | 102 +
 4 files changed, 663 insertions(+)
 create mode 100644 sound/soc/fsl/fsl_audmix.c
 create mode 100644 sound/soc/fsl/fsl_audmix.h

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 7b1d997..0af2e056 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -24,6 +24,13 @@ config SND_SOC_FSL_SAI
  This option is only useful for out-of-tree drivers since
  in-tree drivers select it automatically.
 
+config SND_SOC_FSL_AUDMIX
+   tristate "Audio Mixer (AUDMIX) module support"
+   select REGMAP_MMIO
+   help
+ Say Y if you want to add Audio Mixer (AUDMIX)
+ support for the NXP iMX CPUs.
+
 config SND_SOC_FSL_SSI
tristate "Synchronous Serial Interface module (SSI) support"
select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 3c0ff31..4172d5a 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -12,6 +12,7 @@ snd-soc-p1022-rdk-objs := p1022_rdk.o
 obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
 
 # Freescale SSI/DMA/SAI/SPDIF Support
+snd-soc-fsl-audmix-objs := fsl_audmix.o
 snd-soc-fsl-asoc-card-objs := fsl-asoc-card.o
 snd-soc-fsl-asrc-objs := fsl_asrc.o fsl_asrc_dma.o
 snd-soc-fsl-sai-objs := fsl_sai.o
@@ -22,6 +23,8 @@ snd-soc-fsl-esai-objs := fsl_esai.o
 snd-soc-fsl-micfil-objs := fsl_micfil.o
 snd-soc-fsl-utils-objs := fsl_utils.o
 snd-soc-fsl-dma-objs := fsl_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
 obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc.o
 obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c
new file mode 100644
index 000..f1267e5
--- /dev/null
+++ b/sound/soc/fsl/fsl_audmix.c
@@ -0,0 +1,551 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NXP AUDMIX ALSA SoC Digital Audio Interface (DAI) driver
+ *
+ * Copyright 2017 NXP
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fsl_audmix.h"
+
+#define SOC_ENUM_SINGLE_S(xreg, xshift, xtexts) \
+   SOC_ENUM_SINGLE(xreg, xshift, ARRAY_SIZE(xtexts), xtexts)
+
+static const char
+   *tdm_sel[] = { "TDM1", "TDM2", },
+   *mode_sel[] = { "Disabled", "TDM1", "TDM2", "Mixed", },
+   *width_sel[] = { "16b", "18b", "20b", "24b", "32b", },
+   *endis_sel[] = { "Disabled", "Enabled", },
+   *updn_sel[] = { "Downward", "Upward", },
+   *mask_sel[] = { "Unmask", "Mask", };
+
+static const struct soc_enum fsl_audmix_enum[] = {
+/* FSL_AUDMIX_CTR enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MIXCLK_SHIFT, tdm_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_OUTSRC_SHIFT, mode_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_OUTWIDTH_SHIFT, width_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MASKRTDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MASKCKDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_SYNCMODE_SHIFT, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_SYNCSRC_SHIFT, tdm_sel),
+/* FSL_AUDMIX_ATCR0 enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR0, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR0, 1, updn_sel),
+/* FSL_AUDMIX_ATCR1 enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR1, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR1, 1, updn_sel),
+};
+
+struct fsl_audmix_state {
+   u8 tdms;
+   u8 clk;
+   char msg[64];
+};
+
+static const struct fsl_audmix_state prms[4][4] = {{
+   /* DIS->DIS, do nothing */
+   { .tdms = 0, .clk = 0, .msg = "" },
+   /* DIS->TDM1*/
+   { .tdms = 1, .clk = 1, .msg = "DIS->TDM1: TDM1 not started!\n" },
+   /* DIS->TDM2*/
+   { .tdms = 2, .clk = 2, .msg = "DIS->TDM2: TDM2 not started!\n" },
+   /* DIS->MIX */
+   { .tdms = 3, .clk = 0, .msg = "DIS->MIX: Please start both TDMs!\n" }
+}, {   /* TDM1->DIS */
+   { .tdms = 1, .clk = 0, .msg = "TDM1->DIS: TDM1 not started!\n" },
+   /* TDM1->TDM1, do nothing */
+   { .tdms = 0, .clk = 0, .msg = "" },
+   /* TDM1->TDM2 */
+   { .tdms = 3, .clk = 2, .m

[PATCH v3 2/4] ASoC: add fsl_audmix DT binding documentation

2019-01-17 Thread Viorel Suman
Add the DT binding documentation for NXP Audio Mixer
CPU DAI driver.

Signed-off-by: Viorel Suman 
---
 .../devicetree/bindings/sound/fsl,audmix.txt   | 50 ++
 1 file changed, 50 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,audmix.txt

diff --git a/Documentation/devicetree/bindings/sound/fsl,audmix.txt 
b/Documentation/devicetree/bindings/sound/fsl,audmix.txt
new file mode 100644
index 000..840b7e0
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,audmix.txt
@@ -0,0 +1,50 @@
+NXP Audio Mixer (AUDMIX).
+
+The Audio Mixer is a on-chip functional module that allows mixing of two
+audio streams into a single audio stream. Audio Mixer has two input serial
+audio interfaces. These are driven by two Synchronous Audio interface
+modules (SAI). Each input serial interface carries 8 audio channels in its
+frame in TDM manner. Mixer mixes audio samples of corresponding channels
+from two interfaces into a single sample. Before mixing, audio samples of
+two inputs can be attenuated based on configuration. The output of the
+Audio Mixer is also a serial audio interface. Like input interfaces it has
+the same TDM frame format. This output is used to drive the serial DAC TDM
+interface of audio codec and also sent to the external pins along with the
+receive path of normal audio SAI module for readback by the CPU.
+
+The output of Audio Mixer can be selected from any of the three streams
+ - serial audio input 1
+ - serial audio input 2
+ - mixed audio
+
+Mixing operation is independent of audio sample rate but the two audio
+input streams must have same audio sample rate with same number of channels
+in TDM frame to be eligible for mixing.
+
+Device driver required properties:
+=
+  - compatible : Compatible list, contains "fsl,imx8qm-audmix"
+
+  - reg: Offset and length of the register set for the 
device.
+
+  - clocks : Must contain an entry for each entry in clock-names.
+
+  - clock-names: Must include the "ipg" for register access.
+
+  - power-domains  : Must contain the phandle to AUDMIX power domain node
+
+  - dais   : Must contain a list of phandles to AUDMIX connected
+ DAIs. The current implementation requires two phandles
+ to SAI interfaces to be provided, the first SAI in the
+ list being used to route the AUDMIX output.
+
+Device driver configuration example:
+==
+  audmix: audmix@5984 {
+compatible = "fsl,imx8qm-audmix";
+reg = <0x0 0x5984 0x0 0x1>;
+clocks = < IMX8QXP_AUD_AUDMIX_IPG>;
+clock-names = "ipg";
+power-domains = <_audmix>;
+dais = <>, <>;
+  };
-- 
2.7.4



[PATCH v2 4/4] ASoC: add imx-audmix DT binding documentation

2019-01-08 Thread Viorel Suman
Add the DT binding documentation for Audio Mixer
machine driver.

Signed-off-by: Viorel Suman 
---
 .../devicetree/bindings/sound/imx-audmix.txt   | 24 ++
 1 file changed, 24 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/imx-audmix.txt

diff --git a/Documentation/devicetree/bindings/sound/imx-audmix.txt 
b/Documentation/devicetree/bindings/sound/imx-audmix.txt
new file mode 100644
index 000..6ac1230
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/imx-audmix.txt
@@ -0,0 +1,24 @@
+NXP Audio Mixer (AUDMIX) machine driver.
+
+Required properties:
+===
+  - compatible : Compatible list, contains "fsl,imx-audmix"
+
+  - model  : Short audio card description.
+
+  - dais   : Must contain a list of phandles to AUDMIX connected
+ DAIs. The current implementation requires two phandles
+ to SAI interfaces to be provided, the first SAI in the
+ list being used to route the AUDMIX output.
+
+  - audmix-controller  : Must contain the phandle to the AUDMIX device node.
+
+Machine driver configuration example:
+
+  sound-audmix-sai {
+compatible = "fsl,imx-audmix";
+model = "audmix-sai";
+dais = <>, <>;
+audmix-controller = <>;
+  };
+
-- 
2.7.4



[PATCH v2 3/4] ASoC: fsl: Add Audio Mixer machine driver

2019-01-08 Thread Viorel Suman
This patch implements Audio Mixer machine driver for NXP iMX8 SOCs.
It connects together Audio Mixer and related SAI instances.

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/Kconfig  |   9 ++
 sound/soc/fsl/Makefile |   2 +
 sound/soc/fsl/imx-audmix.c | 333 +
 3 files changed, 344 insertions(+)
 create mode 100644 sound/soc/fsl/imx-audmix.c

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 0af2e056..d87c842 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -303,6 +303,15 @@ config SND_SOC_FSL_ASOC_CARD
 CS4271, CS4272 and SGTL5000.
 Say Y if you want to add support for Freescale Generic ASoC Sound Card.
 
+config SND_SOC_IMX_AUDMIX
+   tristate "SoC Audio support for i.MX boards with AUDMIX"
+   select SND_SOC_FSL_AUDMIX
+   select SND_SOC_FSL_SAI
+   help
+ SoC Audio support for i.MX boards with Audio Mixer
+ Say Y if you want to add support for SoC audio on an i.MX board with
+ an Audio Mixer.
+
 endif # SND_IMX_SOC
 
 endmenu
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 4172d5a..c0dd044 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -62,6 +62,7 @@ snd-soc-imx-es8328-objs := imx-es8328.o
 snd-soc-imx-sgtl5000-objs := imx-sgtl5000.o
 snd-soc-imx-spdif-objs := imx-spdif.o
 snd-soc-imx-mc13783-objs := imx-mc13783.o
+snd-soc-imx-audmix-objs := imx-audmix.o
 
 obj-$(CONFIG_SND_SOC_EUKREA_TLV320) += snd-soc-eukrea-tlv320.o
 obj-$(CONFIG_SND_SOC_PHYCORE_AC97) += snd-soc-phycore-ac97.o
@@ -71,3 +72,4 @@ obj-$(CONFIG_SND_SOC_IMX_ES8328) += snd-soc-imx-es8328.o
 obj-$(CONFIG_SND_SOC_IMX_SGTL5000) += snd-soc-imx-sgtl5000.o
 obj-$(CONFIG_SND_SOC_IMX_SPDIF) += snd-soc-imx-spdif.o
 obj-$(CONFIG_SND_SOC_IMX_MC13783) += snd-soc-imx-mc13783.o
+obj-$(CONFIG_SND_SOC_IMX_AUDMIX) += snd-soc-imx-audmix.o
diff --git a/sound/soc/fsl/imx-audmix.c b/sound/soc/fsl/imx-audmix.c
new file mode 100644
index 000..30cce52
--- /dev/null
+++ b/sound/soc/fsl/imx-audmix.c
@@ -0,0 +1,333 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright 2017 NXP
+ *
+ * The code contained herein is licensed under the GNU General Public
+ * License. You may obtain a copy of the GNU General Public License
+ * Version 2 or later at the following locations:
+ *
+ * http://www.opensource.org/licenses/gpl-license.html
+ * http://www.gnu.org/copyleft/gpl.html
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "fsl_sai.h"
+#include "fsl_audmix.h"
+
+struct imx_audmix {
+   struct platform_device *pdev;
+   struct snd_soc_card card;
+   struct platform_device *audmix_pdev;
+   struct platform_device *out_pdev;
+   struct clk *cpu_mclk;
+   int num_dai;
+   struct snd_soc_dai_link *dai;
+   int num_dai_conf;
+   struct snd_soc_codec_conf *dai_conf;
+   int num_dapm_routes;
+   struct snd_soc_dapm_route *dapm_routes;
+};
+
+static const u32 imx_audmix_rates[] = {
+   8000, 12000, 16000, 24000, 32000, 48000, 64000, 96000,
+};
+
+static const struct snd_pcm_hw_constraint_list imx_audmix_rate_constraints = {
+   .count = ARRAY_SIZE(imx_audmix_rates),
+   .list = imx_audmix_rates,
+};
+
+static int imx_audmix_fe_startup(struct snd_pcm_substream *substream)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct imx_audmix *priv = snd_soc_card_get_drvdata(rtd->card);
+   struct snd_pcm_runtime *runtime = substream->runtime;
+   struct device *dev = rtd->card->dev;
+   unsigned long clk_rate = clk_get_rate(priv->cpu_mclk);
+   int ret;
+
+   if (clk_rate % 24576000 == 0) {
+   ret = snd_pcm_hw_constraint_list(runtime, 0,
+SNDRV_PCM_HW_PARAM_RATE,
+_audmix_rate_constraints);
+   if (ret < 0)
+   return ret;
+   } else {
+   dev_warn(dev, "mclk may be not supported %lu\n", clk_rate);
+   }
+
+   ret = snd_pcm_hw_constraint_minmax(runtime, SNDRV_PCM_HW_PARAM_CHANNELS,
+  1, 8);
+   if (ret < 0)
+   return ret;
+
+   return snd_pcm_hw_constraint_mask64(runtime, SNDRV_PCM_HW_PARAM_FORMAT,
+   FSL_AUDMIX_FORMATS);
+}
+
+static int imx_audmix_fe_hw_params(struct snd_pcm_substream *substream,
+  struct snd_pcm_hw_params *params)
+{
+   struct snd_soc_pcm_runtime *rtd = substream->private_data;
+   struct device *dev = rtd->card->dev;
+   bool tx = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+   unsigned int fmt = SND_SOC_DAIFMT_DSP_A | SND_SOC_DAIFMT_NB_NF;
+   u32 channels = params_channels(params);
+   int ret, dir;
+
+   /* For playback the AUDMIX is s

[PATCH v2 2/4] ASoC: add fsl_audmix DT binding documentation

2019-01-08 Thread Viorel Suman
Add the DT binding documentation for NXP Audio Mixer
CPU DAI driver.

Signed-off-by: Viorel Suman 
---
 .../devicetree/bindings/sound/fsl,audmix.txt   | 44 ++
 1 file changed, 44 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,audmix.txt

diff --git a/Documentation/devicetree/bindings/sound/fsl,audmix.txt 
b/Documentation/devicetree/bindings/sound/fsl,audmix.txt
new file mode 100644
index 000..512d39b
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,audmix.txt
@@ -0,0 +1,44 @@
+NXP Audio Mixer (AUDMIX).
+
+The Audio Mixer is a on-chip functional module that allows mixing of two
+audio streams into a single audio stream. Audio Mixer has two input serial
+audio interfaces. These are driven by two Synchronous Audio interface
+modules (SAI). Each input serial interface carries 8 audio channels in its
+frame in TDM manner. Mixer mixes audio samples of corresponding channels
+from two interfaces into a single sample. Before mixing, audio samples of
+two inputs can be attenuated based on configuration. The output of the
+Audio Mixer is also a serial audio interface. Like input interfaces it has
+the same TDM frame format. This output is used to drive the serial DAC TDM
+interface of audio codec and also sent to the external pins along with the
+receive path of normal audio SAI module for readback by the CPU.
+
+The output of Audio Mixer can be selected from any of the three streams
+ - serial audio input 1
+ - serial audio input 2
+ - mixed audio
+
+Mixing operation is independent of audio sample rate but the two audio
+input streams must have same audio sample rate with same number of channels
+in TDM frame to be eligible for mixing.
+
+Device driver required properties:
+=
+  - compatible : Compatible list, contains "fsl,imx8qm-audmix"
+
+  - reg: Offset and length of the register set for the 
device.
+
+  - clocks : Must contain an entry for each entry in clock-names.
+
+  - clock-names: Must include the "ipg" for register access.
+
+  - power-domains  : Must contain the phandle to AUDMIX power domain node
+
+Device driver configuration example:
+==
+  audmix: audmix@5984 {
+compatible = "fsl,imx8qm-audmix";
+reg = <0x0 0x5984 0x0 0x1>;
+clocks = < IMX8QXP_AUD_AUDMIX_IPG>;
+clock-names = "ipg";
+power-domains = <_audmix>;
+  };
-- 
2.7.4



[PATCH v2 1/4] ASoC: fsl: Add Audio Mixer CPU DAI driver

2019-01-08 Thread Viorel Suman
This patch implements Audio Mixer CPU DAI driver for NXP iMX8 SOCs.
The Audio Mixer is a on-chip functional module that allows mixing of
two audio streams into a single audio stream.

Audio Mixer datasheet is available here:
https://www.nxp.com/docs/en/reference-manual/IMX8DQXPRM.pdf

Signed-off-by: Viorel Suman 
---
 sound/soc/fsl/Kconfig  |   7 +
 sound/soc/fsl/Makefile |   3 +
 sound/soc/fsl/fsl_audmix.c | 551 +
 sound/soc/fsl/fsl_audmix.h | 102 +
 4 files changed, 663 insertions(+)
 create mode 100644 sound/soc/fsl/fsl_audmix.c
 create mode 100644 sound/soc/fsl/fsl_audmix.h

diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 7b1d997..0af2e056 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -24,6 +24,13 @@ config SND_SOC_FSL_SAI
  This option is only useful for out-of-tree drivers since
  in-tree drivers select it automatically.
 
+config SND_SOC_FSL_AUDMIX
+   tristate "Audio Mixer (AUDMIX) module support"
+   select REGMAP_MMIO
+   help
+ Say Y if you want to add Audio Mixer (AUDMIX)
+ support for the NXP iMX CPUs.
+
 config SND_SOC_FSL_SSI
tristate "Synchronous Serial Interface module (SSI) support"
select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index 3c0ff31..4172d5a 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -12,6 +12,7 @@ snd-soc-p1022-rdk-objs := p1022_rdk.o
 obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
 
 # Freescale SSI/DMA/SAI/SPDIF Support
+snd-soc-fsl-audmix-objs := fsl_audmix.o
 snd-soc-fsl-asoc-card-objs := fsl-asoc-card.o
 snd-soc-fsl-asrc-objs := fsl_asrc.o fsl_asrc_dma.o
 snd-soc-fsl-sai-objs := fsl_sai.o
@@ -22,6 +23,8 @@ snd-soc-fsl-esai-objs := fsl_esai.o
 snd-soc-fsl-micfil-objs := fsl_micfil.o
 snd-soc-fsl-utils-objs := fsl_utils.o
 snd-soc-fsl-dma-objs := fsl_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
 obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc.o
 obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
diff --git a/sound/soc/fsl/fsl_audmix.c b/sound/soc/fsl/fsl_audmix.c
new file mode 100644
index 000..f1267e5
--- /dev/null
+++ b/sound/soc/fsl/fsl_audmix.c
@@ -0,0 +1,551 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NXP AUDMIX ALSA SoC Digital Audio Interface (DAI) driver
+ *
+ * Copyright 2017 NXP
+ */
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include "fsl_audmix.h"
+
+#define SOC_ENUM_SINGLE_S(xreg, xshift, xtexts) \
+   SOC_ENUM_SINGLE(xreg, xshift, ARRAY_SIZE(xtexts), xtexts)
+
+static const char
+   *tdm_sel[] = { "TDM1", "TDM2", },
+   *mode_sel[] = { "Disabled", "TDM1", "TDM2", "Mixed", },
+   *width_sel[] = { "16b", "18b", "20b", "24b", "32b", },
+   *endis_sel[] = { "Disabled", "Enabled", },
+   *updn_sel[] = { "Downward", "Upward", },
+   *mask_sel[] = { "Unmask", "Mask", };
+
+static const struct soc_enum fsl_audmix_enum[] = {
+/* FSL_AUDMIX_CTR enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MIXCLK_SHIFT, tdm_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_OUTSRC_SHIFT, mode_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_OUTWIDTH_SHIFT, width_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MASKRTDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_MASKCKDF_SHIFT, mask_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_SYNCMODE_SHIFT, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_CTR, FSL_AUDMIX_CTR_SYNCSRC_SHIFT, tdm_sel),
+/* FSL_AUDMIX_ATCR0 enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR0, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR0, 1, updn_sel),
+/* FSL_AUDMIX_ATCR1 enums */
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR1, 0, endis_sel),
+SOC_ENUM_SINGLE_S(FSL_AUDMIX_ATCR1, 1, updn_sel),
+};
+
+struct fsl_audmix_state {
+   u8 tdms;
+   u8 clk;
+   char msg[64];
+};
+
+static const struct fsl_audmix_state prms[4][4] = {{
+   /* DIS->DIS, do nothing */
+   { .tdms = 0, .clk = 0, .msg = "" },
+   /* DIS->TDM1*/
+   { .tdms = 1, .clk = 1, .msg = "DIS->TDM1: TDM1 not started!\n" },
+   /* DIS->TDM2*/
+   { .tdms = 2, .clk = 2, .msg = "DIS->TDM2: TDM2 not started!\n" },
+   /* DIS->MIX */
+   { .tdms = 3, .clk = 0, .msg = "DIS->MIX: Please start both TDMs!\n" }
+}, {   /* TDM1->DIS */
+   { .tdms = 1, .clk = 0, .msg = "TDM1->DIS: TDM1 not started!\n" },
+   /* TDM1->TDM1, do nothing */
+   { .tdms = 0, .clk = 0, .msg = "" },
+   /* TDM1->TDM2 */
+   { .tdms = 3, .clk = 2, .m

[PATCH v2 0/4] Add NXP AUDMIX device and machine drivers

2019-01-08 Thread Viorel Suman
The patchset adds NXP Audio Mixer (AUDMIX) device and machine
drivers and related DT bindings documentation.

Changes since V1:
1. Original patch split into distinct patches for the device driver and
  DT binding documentation.
2. Replaced AMIX with AUDMIX in both code and file names as it looks more
  RM-compliant.
3. Removed polarity control from CPU DAI driver as suggested by Nicolin.
4. Added machine driver and related DT binding documentation.

Viorel Suman (4):
  ASoC: fsl: Add Audio Mixer CPU DAI driver
  ASoC: add fsl_audmix DT binding documentation
  ASoC: fsl: Add Audio Mixer machine driver
  ASoC: add imx-audmix DT binding documentation

 .../devicetree/bindings/sound/fsl,audmix.txt   |  44 ++
 .../devicetree/bindings/sound/imx-audmix.txt   |  24 +
 sound/soc/fsl/Kconfig  |  16 +
 sound/soc/fsl/Makefile |   5 +
 sound/soc/fsl/fsl_audmix.c | 551 +
 sound/soc/fsl/fsl_audmix.h | 101 
 sound/soc/fsl/imx-audmix.c | 328 
 7 files changed, 1069 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,audmix.txt
 create mode 100644 Documentation/devicetree/bindings/sound/imx-audmix.txt
 create mode 100644 sound/soc/fsl/fsl_audmix.c
 create mode 100644 sound/soc/fsl/fsl_audmix.h
 create mode 100644 sound/soc/fsl/imx-audmix.c

-- 
2.7.4



Re: [RFC PATCH] ASoC: fsl: Add Audio Mixer CPU DAI driver

2019-01-04 Thread Viorel Suman
Hi Nicolin,

On Jo, 2019-01-03 at 12:03 -0800, Nicolin Chen wrote:
> Hi,
> 
> On Thu, Jan 03, 2019 at 03:56:46PM +0000, Viorel Suman wrote:
> > 
> > > 
> > > > 
> > > >  sound/soc/fsl/fsl_amix.c   | 554
> > > > +
> > > >  sound/soc/fsl/fsl_amix.h   | 101 
> > > I aimn't against the naming here, but it seems to be AUDMIX in
> > > RM?
> > > 
> > > Would it be better to align with that? It's your decision though.
> > To me "AUDMIX" sounds more like some RTL high level integration
> > module,
> > I would prefer to keep it as it is if there is no strong reason to 
> > rename it.
> We had AUDMUX, so "AUDMIX" doesn't sound bad to me at all. The only
> reason that we are discussing this is because RM uses more "AUDMIX"s
> over "amix"s. I'd have chosen AUDMIX if I were you, yet not strongly
> as I said. And it looks like Rob is asking you to use AUDMIX in DT
> binding doc.

Ok, I'll change in the next version the compatible string to "audmix"
as Rob requested.

> 
> > 
> > > 
> > > > 
> > > > +Device driver configuration example:
> > > > +==
> > > > +  amix: amix@5984 {
> > > > +compatible = "fsl,imx8qm-amix";
> > > > +reg = <0x0 0x5984 0x0 0x1>;
> > > > +clocks = < IMX8QXP_AUD_AMIX_IPG>;
> > > > +clock-names = "ipg";
> > > > +power-domains = <_amix>;
> > > > +  };
> > > From the description of DT and RM, I don't see how it connects to
> > > SAIs.
> > > 
> > > Are they fixed to SAI0 and SAI1 in imx8qm? Wondering if it'd be
> > > better to have such information in the doc.
> > Please check chapter "16.1.2.2 Audio Mixer" in RM: it has two
> > dedicated
> > SAI interfaces, SAI4 and SAI5. Audio Mixer operates on bit clock of
> > one
> > of these interfaces.
> OK. I am actually more wondering how you connect it with SAI on
> the software level: for imx8qm, SAI4/5 are used, but later SoCs
> might use other SAI blocks. So it might be necessary to indicate
> the connections in DT.

See below.

> 
> > 
> > > 
> > > > 
> > > > +static int fsl_amix_dai_set_fmt(struct snd_soc_dai *dai,
> > > > unsigned
> > > > int fmt)
> > > > +{
> > > > +   /* For playback the AMIX is slave, and for record is
> > > > master
> > > > */
> > > > +   switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
> > > > +   case SND_SOC_DAIFMT_CBM_CFM:
> > > > +   case SND_SOC_DAIFMT_CBS_CFS:
> > > So it's used either for playback or capture only, not both at
> > > same
> > > time?
> > From IP functional perspective AMIX capture is the result of AMIX
> > playback - AMIX output represents the resulting mixed audio stream
> > routed to SAI4 RX signals (bit & frame clocks and data). So once we
> > have playback on either SAI4 or SAI5 (or both) - we can capture the
> > AMIX output on SAI4.
> Ah, it sounds like a looping block then, receiving bclk from SAI4
> -- slave, and routing the bclk back to SAI4 -- master; SAI4 works
> at ASYNC mode?

Right. And yes, SAI4 works in ASYNC mode.

> 
> > 
> > I guess it would be nice to send the machine driver as part of this
> > patchset also - it defines two input SAI interfaces as frontends
> > and
> > AMIX - as backend. Userspace sees only two SAI interfaces exposed,
> > both
> > of them having playback enabled, and only SAI4 having capture
> > enabled.
> DPCM? So you are having the links in the sound DT nodes, i.e. the
> machine driver?

The machine driver DT configuration looks like:

sound-amix-sai {
  compatible = "fsl,imx-audio-amix";
  model = "amix-audio-sai";
  dais = <>, <>;
  amix-controller = <>;
};

The number of elements in "dais" array is at least two elements, DAPM
routes are generated dynamically in machine driver at probe as function
of number of SAI instances, the capture is enabled only for the first
SAI instance in the list.

> 
> Thanks
> Nicolin

Regards,
Viorel

RE: [RFC PATCH] ASoC: fsl: Add Audio Mixer CPU DAI driver

2019-01-03 Thread Viorel Suman
> -Original Message-
> From: Rob Herring [mailto:robh...@kernel.org]
> Sent: Thursday, January 3, 2019 8:26 PM
> To: Viorel Suman 
> Cc: nicoleots...@gmail.com; dl-linux-imx ; linux-
> ker...@vger.kernel.org; linuxppc-...@lists.ozlabs.org; ti...@kernel.org;
> devicet...@vger.kernel.org; xiubo@gmail.com; Fabio Estevam
> ; broo...@kernel.org; mark.rutl...@arm.com;
> ti...@suse.com; lgirdw...@gmail.com; Daniel Baluta
> ; pe...@perex.cz; alsa-de...@alsa-project.org
> Subject: Re: [RFC PATCH] ASoC: fsl: Add Audio Mixer CPU DAI driver
> 
> On Thu, Jan 3, 2019 at 9:59 AM Viorel Suman  wrote:
> >
> > Hi Nicolin,
> >
> > Thank you for your feedback, same here - just back from vacation.
> >
> > On Jo, 2018-12-27 at 01:24 +0800, Nicolin Chen wrote:
> > > Hi Viorel,
> > >
> > > Sorry for the late response, having been on a long vacation.
> > >
> > > The code looks pretty clean. Just some small concerns/questions
> > > below.
> > >
> > > On Wed, Dec 19, 2018 at 12:30 AM Viorel Suman 
> > > wrote:
> > > >
> > > >
> > > > This patch implements Audio Mixer CPU DAI driver for NXP iMX8 SOCs.
> > > > The Audio Mixer is a on-chip functional module that allows mixing
> > > > of two audio streams into a single audio stream.
> > > >
> > > > Audio Mixer datasheet is available here:
> > > > https://www.nxp.com/docs/en/reference-manual/IMX8DQXPRM.pdf
> > > >
> > > > Signed-off-by: Viorel Suman 
> > > > ---
> > > >  .../devicetree/bindings/sound/fsl,amix.txt |  45 ++
> > > >  sound/soc/fsl/Kconfig  |   7 +
> > > >  sound/soc/fsl/Makefile |   3 +
> > > >  sound/soc/fsl/fsl_amix.c   | 554
> > > > +
> > > >  sound/soc/fsl/fsl_amix.h   | 101 
> > > I aimn't against the naming here, but it seems to be AUDMIX in RM?
> > >
> > > Would it be better to align with that? It's your decision though.
> >
> > To me "AUDMIX" sounds more like some RTL high level integration
> > module, I would prefer to keep it as it is if there is no strong
> > reason to rename it.
> 
> At least for compatible string names, matching what's in the RM or RTL is more
> appropriate. Where does "AMIX" come from?
> 
> Rob

There are places in RM where Audio Mixer is referred as "AMIX":
1. Page 33, "Table 2-6. Audio DMA Memory Map"
2. Page 259, "LPCG_AMIX_REGS"
3. Page 6816, "Table 16-1. ADMA Subsystem Modules"

/Viorel


Re: [RFC PATCH] ASoC: fsl: Add Audio Mixer CPU DAI driver

2019-01-03 Thread Viorel Suman
Hi Nicolin,

Thank you for your feedback, same here - just back from vacation.

On Jo, 2018-12-27 at 01:24 +0800, Nicolin Chen wrote:
> Hi Viorel,
> 
> Sorry for the late response, having been on a long vacation.
> 
> The code looks pretty clean. Just some small concerns/questions
> below.
> 
> On Wed, Dec 19, 2018 at 12:30 AM Viorel Suman 
> wrote:
> > 
> > 
> > This patch implements Audio Mixer CPU DAI driver for NXP iMX8 SOCs.
> > The Audio Mixer is a on-chip functional module that allows mixing
> > of
> > two audio streams into a single audio stream.
> > 
> > Audio Mixer datasheet is available here:
> > https://www.nxp.com/docs/en/reference-manual/IMX8DQXPRM.pdf
> > 
> > Signed-off-by: Viorel Suman 
> > ---
> >  .../devicetree/bindings/sound/fsl,amix.txt |  45 ++
> >  sound/soc/fsl/Kconfig  |   7 +
> >  sound/soc/fsl/Makefile |   3 +
> >  sound/soc/fsl/fsl_amix.c   | 554
> > +
> >  sound/soc/fsl/fsl_amix.h   | 101 
> I aimn't against the naming here, but it seems to be AUDMIX in RM?
> 
> Would it be better to align with that? It's your decision though.

To me "AUDMIX" sounds more like some RTL high level integration module,
I would prefer to keep it as it is if there is no strong reason to 
rename it.

> 
> > 
> > diff --git a/Documentation/devicetree/bindings/sound/fsl,amix.txt
> > b/Documentation/devicetree/bindings/sound/fsl,amix.txt
> > +=
> > +  - compatible : Compatible list, contains "fsl,imx8qm-
> > amix"
> > +
> > +  - reg: Offset and length of the register
> > set for the device.
> > +
> > +  - clocks : Must contain an entry for each entry in
> > clock-names.
> > +
> > +  - clock-names: Must include the "ipg" for
> > register access.
> > +
> > +  - power-domains  : Must contain the phandle to the AMIX
> > power domain node
> > +
> > +Device driver configuration example:
> > +==
> > +  amix: amix@5984 {
> > +compatible = "fsl,imx8qm-amix";
> > +reg = <0x0 0x5984 0x0 0x1>;
> > +clocks = < IMX8QXP_AUD_AMIX_IPG>;
> > +clock-names = "ipg";
> > +power-domains = <_amix>;
> > +  };
> From the description of DT and RM, I don't see how it connects to
> SAIs.
> 
> Are they fixed to SAI0 and SAI1 in imx8qm? Wondering if it'd be
> better to have such information in the doc.

Please check chapter "16.1.2.2 Audio Mixer" in RM: it has two dedicated
SAI interfaces, SAI4 and SAI5. Audio Mixer operates on bit clock of one
of these interfaces.

> 
> > 
> > diff --git a/sound/soc/fsl/fsl_amix.c b/sound/soc/fsl/fsl_amix.c
> +static const char
> + *width_sel[] = { "16b", "18b", "20b", "24b", "32b", },
> + *pol_sel[] = { "Positive edge", "Negative edge", },
> [...]
> +static const struct soc_enum fsl_amix_enum[] = {
> +/* FSL_AMIX_CTR enums */
> [...]
> +SOC_ENUM_SINGLE_S(FSL_AMIX_CTR, FSL_AMIX_CTR_OUTWIDTH_SHIFT,
> width_sel),
> +SOC_ENUM_SINGLE_S(FSL_AMIX_CTR, FSL_AMIX_CTR_OUTCKPOL_SHIFT,
> pol_sel),
> 
> Should we handle the width in hw_param()?

The width of AMIX output (mixed) stream may be different than the width
of the input streams, the assumption is that the user may want to
control it from userspace.

> 
> Why do we change pol here? It feels like against set_fmt().

You're right, will remove it in the next version.

> 
> > 
> > +static int fsl_amix_dai_set_fmt(struct snd_soc_dai *dai, unsigned
> > int fmt)
> > +{
> > +   /* For playback the AMIX is slave, and for record is master
> > */
> > +   switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
> > +   case SND_SOC_DAIFMT_CBM_CFM:
> > +   case SND_SOC_DAIFMT_CBS_CFS:
> So it's used either for playback or capture only, not both at same
> time?

From IP functional perspective AMIX capture is the result of AMIX
playback - AMIX output represents the resulting mixed audio stream
routed to SAI4 RX signals (bit & frame clocks and data). So once we
have playback on either SAI4 or SAI5 (or both) - we can capture the
AMIX output on SAI4.

I guess it would be nice to send the machine driver as part of this
patchset also - it defines two input SAI interfaces as frontends and
AMIX - as backend. Userspace sees only two SAI interfaces exposed, both
of them having playback enabled, and only SAI4 having capture enabled.

> 
> Thanks
> Nicolin

Thank you,
Viorel


Re: [RFC PATCH] ASoC: fsl: Add Audio Mixer CPU DAI driver

2019-01-03 Thread Viorel Suman
Hi Rob,

On Vi, 2018-12-28 at 17:32 -0600, Rob Herring wrote:
> On Tue, Dec 18, 2018 at 04:30:01PM +0000, Viorel Suman wrote:
> > 
> > This patch implements Audio Mixer CPU DAI driver for NXP iMX8 SOCs.
> > The Audio Mixer is a on-chip functional module that allows mixing
> > of
> > two audio streams into a single audio stream.
> > 
> > Audio Mixer datasheet is available here:
> > https://www.nxp.com/docs/en/reference-manual/IMX8DQXPRM.pdf
> > 
> > Signed-off-by: Viorel Suman 
> > ---
> >  .../devicetree/bindings/sound/fsl,amix.txt |  45 ++
> This should be a separate patch.

Ok, thank you, will split this into several patches.

> 
> > 
> >  sound/soc/fsl/Kconfig  |   7 +
> >  sound/soc/fsl/Makefile |   3 +
> >  sound/soc/fsl/fsl_amix.c   | 554
> > +
> >  sound/soc/fsl/fsl_amix.h   | 101 
> >  5 files changed, 710 insertions(+)
> >  create mode 100644
> > Documentation/devicetree/bindings/sound/fsl,amix.txt
> >  create mode 100644 sound/soc/fsl/fsl_amix.c
> >  create mode 100644 sound/soc/fsl/fsl_amix.h
> > 
> > diff --git a/Documentation/devicetree/bindings/sound/fsl,amix.txt
> > b/Documentation/devicetree/bindings/sound/fsl,amix.txt
> > new file mode 100644
> > index 000..049144f
> > --- /dev/null
> > +++ b/Documentation/devicetree/bindings/sound/fsl,amix.txt
> > @@ -0,0 +1,45 @@
> > +NXP Audio Mixer (AMIX).
> > +
> > +The Audio Mixer is a on-chip functional module that allows mixing
> > of two
> > +audio streams into a single audio stream. Audio Mixer has two
> > input serial
> > +audio interfaces. These are driven by two Synchronous Audio
> > interface
> > +modules (SAI). Each input serial interface carries 8 audio
> > channels in its
> > +frame in TDM manner. Mixer mixes audio samples of corresponding
> > channels
> > +from two interfaces into a single sample. Before mixing, audio
> > samples of
> > +two inputs can be attenuated based on configuration. The output of
> > the
> > +Audio Mixer is also a serial audio interface. Like input
> > interfaces it has
> > +the same TDM frame format. This output is used to drive the serial
> > DAC TDM
> > +interface of audio codec and also sent to the external pins along
> > with the
> > +receive path of normal audio SAI module for readback by the CPU.
> > +
> > +The output of Audio mixer can be selected from any of the three
> > streams
> > + - serial audio input 1
> > + - serial audio input 2
> > + - Mixed audio
> > +
> > +Mixing operation is independent of audio sample rate but the two
> > audio
> > +input streams must have same audio sample rate with same number of
> > channels
> > +in TDM frame to be eligible for mixing.
> > +
> > +Device driver required properties:
> > +=
> > +  - compatible : Compatible list, contains
> > "fsl,imx8qm-amix"
> > +
> > +  - reg: Offset and length of the register
> > set for the device.
> > +
> > +  - clocks : Must contain an entry for each entry
> > in clock-names.
> > +
> > +  - clock-names: Must include the "ipg" for
> > register access.
> Humm, no audio related clocks?

Right, no audio related clocks - Audio Mixer operates on the clocks
supplied by input Synchronous Audio Interfaces.

>  
> 
> > 
> > +
> > +  - power-domains  : Must contain the phandle to the AMIX
> > power domain node
> > +
> > +Device driver configuration example:
> > +==
> > +  amix: amix@5984 {
> > +compatible = "fsl,imx8qm-amix";
> > +reg = <0x0 0x5984 0x0 0x1>;
> > +clocks = < IMX8QXP_AUD_AMIX_IPG>;
> > +clock-names = "ipg";
> > +power-domains = <_amix>;
> > +  };
> > +

Regards,
Viorel


[RFC PATCH] ASoC: fsl: Add Audio Mixer CPU DAI driver

2018-12-18 Thread Viorel Suman
This patch implements Audio Mixer CPU DAI driver for NXP iMX8 SOCs.
The Audio Mixer is a on-chip functional module that allows mixing of
two audio streams into a single audio stream.

Audio Mixer datasheet is available here:
https://www.nxp.com/docs/en/reference-manual/IMX8DQXPRM.pdf

Signed-off-by: Viorel Suman 
---
 .../devicetree/bindings/sound/fsl,amix.txt |  45 ++
 sound/soc/fsl/Kconfig  |   7 +
 sound/soc/fsl/Makefile |   3 +
 sound/soc/fsl/fsl_amix.c   | 554 +
 sound/soc/fsl/fsl_amix.h   | 101 
 5 files changed, 710 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/sound/fsl,amix.txt
 create mode 100644 sound/soc/fsl/fsl_amix.c
 create mode 100644 sound/soc/fsl/fsl_amix.h

diff --git a/Documentation/devicetree/bindings/sound/fsl,amix.txt 
b/Documentation/devicetree/bindings/sound/fsl,amix.txt
new file mode 100644
index 000..049144f
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/fsl,amix.txt
@@ -0,0 +1,45 @@
+NXP Audio Mixer (AMIX).
+
+The Audio Mixer is a on-chip functional module that allows mixing of two
+audio streams into a single audio stream. Audio Mixer has two input serial
+audio interfaces. These are driven by two Synchronous Audio interface
+modules (SAI). Each input serial interface carries 8 audio channels in its
+frame in TDM manner. Mixer mixes audio samples of corresponding channels
+from two interfaces into a single sample. Before mixing, audio samples of
+two inputs can be attenuated based on configuration. The output of the
+Audio Mixer is also a serial audio interface. Like input interfaces it has
+the same TDM frame format. This output is used to drive the serial DAC TDM
+interface of audio codec and also sent to the external pins along with the
+receive path of normal audio SAI module for readback by the CPU.
+
+The output of Audio mixer can be selected from any of the three streams
+ - serial audio input 1
+ - serial audio input 2
+ - Mixed audio
+
+Mixing operation is independent of audio sample rate but the two audio
+input streams must have same audio sample rate with same number of channels
+in TDM frame to be eligible for mixing.
+
+Device driver required properties:
+=
+  - compatible : Compatible list, contains "fsl,imx8qm-amix"
+
+  - reg: Offset and length of the register set for the 
device.
+
+  - clocks : Must contain an entry for each entry in clock-names.
+
+  - clock-names: Must include the "ipg" for register access.
+
+  - power-domains  : Must contain the phandle to the AMIX power domain node
+
+Device driver configuration example:
+==
+  amix: amix@5984 {
+compatible = "fsl,imx8qm-amix";
+reg = <0x0 0x5984 0x0 0x1>;
+clocks = < IMX8QXP_AUD_AMIX_IPG>;
+clock-names = "ipg";
+power-domains = <_amix>;
+  };
+
diff --git a/sound/soc/fsl/Kconfig b/sound/soc/fsl/Kconfig
index 2e75b5bc..0b08eb2 100644
--- a/sound/soc/fsl/Kconfig
+++ b/sound/soc/fsl/Kconfig
@@ -24,6 +24,13 @@ config SND_SOC_FSL_SAI
  This option is only useful for out-of-tree drivers since
  in-tree drivers select it automatically.
 
+config SND_SOC_FSL_AMIX
+   tristate "Audio Mixer (AMIX) module support"
+   select REGMAP_MMIO
+   help
+ Say Y if you want to add Audio Mixer (AMIX)
+ support for the NXP iMX CPUs.
+
 config SND_SOC_FSL_SSI
tristate "Synchronous Serial Interface module (SSI) support"
select SND_SOC_IMX_PCM_DMA if SND_IMX_SOC != n
diff --git a/sound/soc/fsl/Makefile b/sound/soc/fsl/Makefile
index de94fa0..3263634 100644
--- a/sound/soc/fsl/Makefile
+++ b/sound/soc/fsl/Makefile
@@ -12,6 +12,7 @@ snd-soc-p1022-rdk-objs := p1022_rdk.o
 obj-$(CONFIG_SND_SOC_P1022_RDK) += snd-soc-p1022-rdk.o
 
 # Freescale SSI/DMA/SAI/SPDIF Support
+snd-soc-fsl-amix-objs := fsl_amix.o
 snd-soc-fsl-asoc-card-objs := fsl-asoc-card.o
 snd-soc-fsl-asrc-objs := fsl_asrc.o fsl_asrc_dma.o
 snd-soc-fsl-sai-objs := fsl_sai.o
@@ -21,6 +22,8 @@ snd-soc-fsl-spdif-objs := fsl_spdif.o
 snd-soc-fsl-esai-objs := fsl_esai.o
 snd-soc-fsl-utils-objs := fsl_utils.o
 snd-soc-fsl-dma-objs := fsl_dma.o
+
+obj-$(CONFIG_SND_SOC_FSL_AMIX) += snd-soc-fsl-amix.o
 obj-$(CONFIG_SND_SOC_FSL_ASOC_CARD) += snd-soc-fsl-asoc-card.o
 obj-$(CONFIG_SND_SOC_FSL_ASRC) += snd-soc-fsl-asrc.o
 obj-$(CONFIG_SND_SOC_FSL_SAI) += snd-soc-fsl-sai.o
diff --git a/sound/soc/fsl/fsl_amix.c b/sound/soc/fsl/fsl_amix.c
new file mode 100644
index 000..d752029
--- /dev/null
+++ b/sound/soc/fsl/fsl_amix.c
@@ -0,0 +1,554 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * NXP AMIX ALSA SoC Digital Audio Interface (DAI) driver
+ *
+ * Copyright 2017 NXP
+ */
+
+#include 
+#include 
+#include 
+#includ

[PATCH v2] iio: inv_mpu6050: Clear timestamps fifo while resetting hardware fifo

2015-02-18 Thread Viorel Suman
A hardware fifo reset always imply an invalidation of the
existing timestamps, so we'll clear timestamps fifo on
successfull hardware fifo reset.

Signed-off-by: Viorel Suman 
---
  v2: Addressed Jonathan's comment regarding the subject prefix.

 drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c 
b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
index 0cd306a..ba27e27 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
@@ -24,6 +24,16 @@
 #include 
 #include "inv_mpu_iio.h"
 
+static void inv_clear_kfifo(struct inv_mpu6050_state *st)
+{
+   unsigned long flags;
+
+   /* take the spin lock sem to avoid interrupt kick in */
+   spin_lock_irqsave(>time_stamp_lock, flags);
+   kfifo_reset(>timestamps);
+   spin_unlock_irqrestore(>time_stamp_lock, flags);
+}
+
 int inv_reset_fifo(struct iio_dev *indio_dev)
 {
int result;
@@ -50,6 +60,10 @@ int inv_reset_fifo(struct iio_dev *indio_dev)
INV_MPU6050_BIT_FIFO_RST);
if (result)
goto reset_fifo_fail;
+
+   /* clear timestamps fifo */
+   inv_clear_kfifo(st);
+
/* enable interrupt */
if (st->chip_config.accl_fifo_enable ||
st->chip_config.gyro_fifo_enable) {
@@ -83,16 +97,6 @@ reset_fifo_fail:
return result;
 }
 
-static void inv_clear_kfifo(struct inv_mpu6050_state *st)
-{
-   unsigned long flags;
-
-   /* take the spin lock sem to avoid interrupt kick in */
-   spin_lock_irqsave(>time_stamp_lock, flags);
-   kfifo_reset(>timestamps);
-   spin_unlock_irqrestore(>time_stamp_lock, flags);
-}
-
 /**
  * inv_mpu6050_irq_handler() - Cache a timestamp at each data ready interrupt.
  */
@@ -184,7 +188,6 @@ end_session:
 flush_fifo:
/* Flush HW and SW FIFOs. */
inv_reset_fifo(indio_dev);
-   inv_clear_kfifo(st);
mutex_unlock(_dev->mlock);
iio_trigger_notify_done(indio_dev->trig);
 
-- 
2.3.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH v2] iio: inv_mpu6050: Clear timestamps fifo while resetting hardware fifo

2015-02-18 Thread Viorel Suman
A hardware fifo reset always imply an invalidation of the
existing timestamps, so we'll clear timestamps fifo on
successfull hardware fifo reset.

Signed-off-by: Viorel Suman viorel.su...@gmail.com
---
  v2: Addressed Jonathan's comment regarding the subject prefix.

 drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c | 25 ++---
 1 file changed, 14 insertions(+), 11 deletions(-)

diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c 
b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
index 0cd306a..ba27e27 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_ring.c
@@ -24,6 +24,16 @@
 #include linux/poll.h
 #include inv_mpu_iio.h
 
+static void inv_clear_kfifo(struct inv_mpu6050_state *st)
+{
+   unsigned long flags;
+
+   /* take the spin lock sem to avoid interrupt kick in */
+   spin_lock_irqsave(st-time_stamp_lock, flags);
+   kfifo_reset(st-timestamps);
+   spin_unlock_irqrestore(st-time_stamp_lock, flags);
+}
+
 int inv_reset_fifo(struct iio_dev *indio_dev)
 {
int result;
@@ -50,6 +60,10 @@ int inv_reset_fifo(struct iio_dev *indio_dev)
INV_MPU6050_BIT_FIFO_RST);
if (result)
goto reset_fifo_fail;
+
+   /* clear timestamps fifo */
+   inv_clear_kfifo(st);
+
/* enable interrupt */
if (st-chip_config.accl_fifo_enable ||
st-chip_config.gyro_fifo_enable) {
@@ -83,16 +97,6 @@ reset_fifo_fail:
return result;
 }
 
-static void inv_clear_kfifo(struct inv_mpu6050_state *st)
-{
-   unsigned long flags;
-
-   /* take the spin lock sem to avoid interrupt kick in */
-   spin_lock_irqsave(st-time_stamp_lock, flags);
-   kfifo_reset(st-timestamps);
-   spin_unlock_irqrestore(st-time_stamp_lock, flags);
-}
-
 /**
  * inv_mpu6050_irq_handler() - Cache a timestamp at each data ready interrupt.
  */
@@ -184,7 +188,6 @@ end_session:
 flush_fifo:
/* Flush HW and SW FIFOs. */
inv_reset_fifo(indio_dev);
-   inv_clear_kfifo(st);
mutex_unlock(indio_dev-mlock);
iio_trigger_notify_done(indio_dev-trig);
 
-- 
2.3.0

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] Clear timestamp kfifo on trigger enabling

2015-02-16 Thread Viorel Suman
The timestamp kfifo must be cleared once the
hardware fifo is reset, thus are removed
timestamps related to unprocessed events from
hardware fifo - see "inv_mpu6050_read_fifo"
method implementation.

Signed-off-by: Viorel Suman 
---
 drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c | 28 +++
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c 
b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
index 926fcce..b617920 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
@@ -42,57 +42,61 @@ static void inv_scan_query(struct iio_dev *indio_dev)
 static int inv_mpu6050_set_enable(struct iio_dev *indio_dev, bool enable)
 {
struct inv_mpu6050_state *st = iio_priv(indio_dev);
-   int result;
+   int result = 0;
 
+   mutex_lock(_dev->mlock);
if (enable) {
result = inv_mpu6050_set_power_itg(st, true);
if (result)
-   return result;
+   goto write_error;
inv_scan_query(indio_dev);
if (st->chip_config.gyro_fifo_enable) {
result = inv_mpu6050_switch_engine(st, true,
INV_MPU6050_BIT_PWR_GYRO_STBY);
if (result)
-   return result;
+   goto write_error;
}
if (st->chip_config.accl_fifo_enable) {
result = inv_mpu6050_switch_engine(st, true,
INV_MPU6050_BIT_PWR_ACCL_STBY);
if (result)
-   return result;
+   goto write_error;
}
+   inv_clear_kfifo(st);
result = inv_reset_fifo(indio_dev);
if (result)
-   return result;
+   goto write_error;
} else {
result = inv_mpu6050_write_reg(st, st->reg->fifo_en, 0);
if (result)
-   return result;
+   goto write_error;
 
result = inv_mpu6050_write_reg(st, st->reg->int_enable, 0);
if (result)
-   return result;
+   goto write_error;
 
result = inv_mpu6050_write_reg(st, st->reg->user_ctrl, 0);
if (result)
-   return result;
+   goto write_error;
 
result = inv_mpu6050_switch_engine(st, false,
INV_MPU6050_BIT_PWR_GYRO_STBY);
if (result)
-   return result;
+   goto write_error;
 
result = inv_mpu6050_switch_engine(st, false,
INV_MPU6050_BIT_PWR_ACCL_STBY);
if (result)
-   return result;
+   goto write_error;
result = inv_mpu6050_set_power_itg(st, false);
if (result)
-   return result;
+   goto write_error;
}
st->chip_config.enable = enable;
+write_error:
+   mutex_unlock(_dev->mlock);
 
-   return 0;
+   return result;
 }
 
 /**
-- 
2.3.0

--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/


[PATCH] Clear timestamp kfifo on trigger enabling

2015-02-16 Thread Viorel Suman
The timestamp kfifo must be cleared once the
hardware fifo is reset, thus are removed
timestamps related to unprocessed events from
hardware fifo - see inv_mpu6050_read_fifo
method implementation.

Signed-off-by: Viorel Suman viorel.su...@gmail.com
---
 drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c | 28 +++
 1 file changed, 16 insertions(+), 12 deletions(-)

diff --git a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c 
b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
index 926fcce..b617920 100644
--- a/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
+++ b/drivers/iio/imu/inv_mpu6050/inv_mpu_trigger.c
@@ -42,57 +42,61 @@ static void inv_scan_query(struct iio_dev *indio_dev)
 static int inv_mpu6050_set_enable(struct iio_dev *indio_dev, bool enable)
 {
struct inv_mpu6050_state *st = iio_priv(indio_dev);
-   int result;
+   int result = 0;
 
+   mutex_lock(indio_dev-mlock);
if (enable) {
result = inv_mpu6050_set_power_itg(st, true);
if (result)
-   return result;
+   goto write_error;
inv_scan_query(indio_dev);
if (st-chip_config.gyro_fifo_enable) {
result = inv_mpu6050_switch_engine(st, true,
INV_MPU6050_BIT_PWR_GYRO_STBY);
if (result)
-   return result;
+   goto write_error;
}
if (st-chip_config.accl_fifo_enable) {
result = inv_mpu6050_switch_engine(st, true,
INV_MPU6050_BIT_PWR_ACCL_STBY);
if (result)
-   return result;
+   goto write_error;
}
+   inv_clear_kfifo(st);
result = inv_reset_fifo(indio_dev);
if (result)
-   return result;
+   goto write_error;
} else {
result = inv_mpu6050_write_reg(st, st-reg-fifo_en, 0);
if (result)
-   return result;
+   goto write_error;
 
result = inv_mpu6050_write_reg(st, st-reg-int_enable, 0);
if (result)
-   return result;
+   goto write_error;
 
result = inv_mpu6050_write_reg(st, st-reg-user_ctrl, 0);
if (result)
-   return result;
+   goto write_error;
 
result = inv_mpu6050_switch_engine(st, false,
INV_MPU6050_BIT_PWR_GYRO_STBY);
if (result)
-   return result;
+   goto write_error;
 
result = inv_mpu6050_switch_engine(st, false,
INV_MPU6050_BIT_PWR_ACCL_STBY);
if (result)
-   return result;
+   goto write_error;
result = inv_mpu6050_set_power_itg(st, false);
if (result)
-   return result;
+   goto write_error;
}
st-chip_config.enable = enable;
+write_error:
+   mutex_unlock(indio_dev-mlock);
 
-   return 0;
+   return result;
 }
 
 /**
-- 
2.3.0

--
To unsubscribe from this list: send the line unsubscribe linux-kernel in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/