linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/11] ASoC: QCOM: Add support for SC7180 lpass variant
@ 2020-04-11  8:02 Ajit Pandey
  2020-04-11  8:02 ` [PATCH 01/11] Documentation: device-tree: sound: Update lpass-cpu driver binding Ajit Pandey
                   ` (10 more replies)
  0 siblings, 11 replies; 21+ messages in thread
From: Ajit Pandey @ 2020-04-11  8:02 UTC (permalink / raw)
  To: alsa-devel, broonie, devicetree, plai, bgoswami, srinivas.kandagatla
  Cc: linux-kernel, tiwai, Ajit Pandey

We've common ASoC cpu driver for QCOM LPASS soc varaints. This patch
chain add support for new variant SC7180 soc by doing the required
modification in existing common lpass-cpu driver. Below is a brief
summary of patch series:

PATCH 01 ... 04: Update lpass-cpu driver files to make it more generic
PATCH 05 ... 08: Add changes to support SC7180 specific configuration
PATCH 09 ... 11: Add new drivers and documentation for SC7180 soc lpass

Ajit Pandey (11):
  Documentation: device-tree: sound: Update lpass-cpu driver binding
  ASoC: qcom: lpass: Add struct lpass_dai to store dai clocks pointer
  ASoC: qcom: Add common array to initialize soc based core clocks
  ASoC: qcom: lpass-cpu: Make "ahbix-clk" an optional clock.
  ASoC: qcom: lpass: Add support for newer lpass version
  dt-bindings: sound: Add bindings related to lpass-cpu configuration
  Documentation: dt-bindings: sound: Add details for new dai properties
  ASoC: qcom : lpass: Add support to configure dai's connection mode
  device-tree: bindings: sound: lpass-cpu: Add new compatible soc
  ASoC: qcom: lpass-sc7180: Add platform driver for lpass audio
  ASoC: qcom: lpass-platform: Replace card->dev with component->dev

 .../devicetree/bindings/sound/qcom,lpass-cpu.txt   | 158 -------------
 .../devicetree/bindings/sound/qcom,lpass-cpu.yaml  | 159 +++++++++++++
 include/dt-bindings/sound/qcom,lpass.h             |  31 +++
 sound/soc/qcom/Kconfig                             |   5 +
 sound/soc/qcom/Makefile                            |   2 +
 sound/soc/qcom/lpass-apq8016.c                     |  39 ++-
 sound/soc/qcom/lpass-cpu.c                         | 263 ++++++++++++++-------
 sound/soc/qcom/lpass-lpaif-reg.h                   | 182 +++++++++++++-
 sound/soc/qcom/lpass-platform.c                    |  36 +--
 sound/soc/qcom/lpass-sc7180.c                      | 192 +++++++++++++++
 sound/soc/qcom/lpass.h                             |  40 +++-
 11 files changed, 808 insertions(+), 299 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt
 create mode 100644 Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
 create mode 100644 include/dt-bindings/sound/qcom,lpass.h
 create mode 100644 sound/soc/qcom/lpass-sc7180.c

-- 
1.9.1

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH 01/11] Documentation: device-tree: sound: Update lpass-cpu driver binding
  2020-04-11  8:02 [PATCH 00/11] ASoC: QCOM: Add support for SC7180 lpass variant Ajit Pandey
@ 2020-04-11  8:02 ` Ajit Pandey
  2020-04-16  7:53   ` Srinivas Kandagatla
  2020-04-11  8:02 ` [PATCH 02/11] ASoC: qcom: lpass: Add struct lpass_dai to store dai clocks pointer Ajit Pandey
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Ajit Pandey @ 2020-04-11  8:02 UTC (permalink / raw)
  To: alsa-devel, broonie, devicetree, plai, bgoswami, srinivas.kandagatla
  Cc: linux-kernel, tiwai, Ajit Pandey

Done the required cleanups to update lpass-cpu binding with newer
yaml formats.

Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
---
 .../devicetree/bindings/sound/qcom,lpass-cpu.txt   | 158 ---------------------
 .../devicetree/bindings/sound/qcom,lpass-cpu.yaml  | 103 ++++++++++++++
 2 files changed, 103 insertions(+), 158 deletions(-)
 delete mode 100644 Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt
 create mode 100644 Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml

diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt
deleted file mode 100644
index a49b878..00000000
--- a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt
+++ /dev/null
@@ -1,158 +0,0 @@
-* Qualcomm Technologies LPASS CPU DAI binding
-
-Low-Power Audio SubSystem (LPASS) consist of MI2S interfaces for audio data
-transfer on external codec. LPASS cpu driver is a common code to configure
-MI2S related CPU dai's across different version of LPASS architecture.
-
-- compatible:
-	Usage: required
-	Value type: <stringlist>
-	Definition: compatible string corresponds to lpass variants driver
-		    must be "qcom, lpass-cpu-sc7180" for sc7180 lpass
-		    must be "qcom,apq8016-lpass-cpu" for apq8016 lpass
-- reg:
-	Usage: required
-	Value type: <prop-encoded-array>
-	Definition: must specify the base address and size of the LPAIF CORE
-		    region of lpass variant.
-- reg-names:
-	Usage: required
-	Value type: <stringlist>
-	Definition: must be "lpass-lpaif"
-
-- iommus:
-        Usage: required for "qcom, lpass-cpu-sc7180" compatible string
-        Value type: <prop-encoded-array>
-        Definition: sid mask for lpaif memory region to apps_smmu
-                    must be <&apps_smmu 0x1020 0>
-
-- power-domains:
-	Usage: required for "qcom, lpass-cpu-sc7180" compatible string
-	Value type: <phandle>
-	Definition: reference to power-domains
-		    must be <&lpass_hm LPASS_CORE_HM_GDSCR>
-
-- clocks:
-        Usage: required
-	Value type: <phandle>
-	Definition: reference to the clocks that match clock-names
-
-- clock-names:
-	Usage: required
-	Value type: <stringlist>
-	Definition: The clocks needed depend on the compatible string:
-	qcom,lpass-cpu-apq8016:
-		must be "ahbix-clk", "mi2s-osr-clk", "mi2s-bit-clk0",
-		mi2s-bit-clk1", "mi2s-bit-clk2", "mi2s-bit-clk3",
-		"pcnoc-mport-clk", "pcnoc-sway-clk"
-	qcom, lpass-cpu-sc7180:
-		must be "noc", "audio-core", "mclk0", "sysnoc_mport",
-		"pri_ibit", "sec_ibit"
-
-- #sound-dai-cells
-	Usage: required
-	Value type: <u32>
-	Definition: Must be 1
-
-- interrupts:
-	Usage: required
-	Value type: <prop-encoded-array>
-	Definition: reference to the interrupts that match interrupt-names
-
-- interrupt-names:
-	Usage: required
-	Value type: <stringlist>
-	Definition: must be "lpass-irq-lpaif"
-
-- qcom,adsp:
-        Usage: optional
-        Value type: <phandle>
-	Definition: Phandle for the audio DSP node
-
-= MI2S DAIs (Digial Audio Interface)
-"dais" child node of the lpass node. It represents mi2s dais, each mi2s dai is
-subnode of "dais" representing board specific dai setup & required dai clocks.
-"dais" node should have following properties.
-
-- id:
-	Usage: required for mi2s interface
-	Value type: <u32>
-	Definition: Must be dai id defined in lpass bindings like MI2S_PRIMARY
-
-- qcom,bitclk-name:
-	Usage: required for mi2s interface
-	Value type: <stringlist>
-	Definition: bitclk name corresponds to MI2S of lpass version
-
-- qcom,mclk-name:
-        Usage: optional for mi2s interface
-        Value type: <stringlist>
-        Definition: external mclk name corresponds to MI2S of lpass version
-
-- qcom,osrclk-name:
-        Usage: optional for mi2s interface
-        Value type: <stringlist>
-        Definition: osrclk name corresponds to MI2S of lpass version
-
-- qcom,spkmode-mask:
-        Usage: optional for mi2s interface
-        Value type: <u32>
-        Definition: board specific property to change default spkmode mask
-                    of MI2S dai based on dataline connection on board.
-
-- qcom,micmode-mask:
-        Usage: optional for mi2s interface
-        Value type: <u32>
-        Definition: board specific property to change default micmode mask
-                    of MI2S dai based on dataline connection on board.
-
-- qcom,loopback-mask:
-        Usage: optional for mi2s interface
-        Value type: <u32>
-        Definition: board specific property to change default loopback mask
-                    of MI2S dai as per requirement.
-
-- qcom,wssrc-mask:
-        Usage: optional for mi2s interface
-        Value type: <u32>
-        Definition: board specific property to change default wssrc mask
-                    of MI2S dai based as per requirement.
-
-Example:
-
-lpass_cpu: lpass {
-	compatible = "qcom, lpass-cpu-sc7180";
-
-	reg = <0 0x62F00000 0 0x29000>;
-	reg-names = "lpass-lpaif";
-
-	iommus = <&apps_smmu 0x1020 0>;
-
-	power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>;
-
-	clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>,
-		 <&lpasscorecc LPASS_AUDIO_CORE_CORE_CLK>,
-		 <&lpasscorecc LPASS_AUDIO_CORE_EXT_MCLK0_CLK>,
-		 <&lpasscorecc LPASS_AUDIO_CORE_SYSNOC_MPORT_CORE_CLK>,
-		 <&lpasscorecc LPASS_AUDIO_CORE_LPAIF_PRI_IBIT_CLK>,
-		 <&lpasscorecc LPASS_AUDIO_CORE_LPAIF_SEC_IBIT_CLK>;
-
-	clock-names = "noc", "audio-core", "mclk0", "sysnoc_mport",
-		      "pri_ibit", "sec_ibit";
-
-	#sound-dai-cells = <1>;
-
-	interrupts = <0 160 IRQ_TYPE_LEVEL_HIGH>;
-	interrupt-names = "lpass-irq-lpaif";
-
-	prim-mi2s@0 {
-		id = <MI2S_PRIMARY>;
-		qcom,bitclk-name = "pri_ibit";
-		qcom,mclk-name = "mclk0";
-	};
-
-	sec-mi2s@1 {
-		id = <MI2S_SECONDARY>;
-		qcom,bitclk-name = "sec_ibit";
-	};
-};
diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
new file mode 100644
index 00000000..a87a406
--- /dev/null
+++ b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
@@ -0,0 +1,103 @@
+# SPDX-License-Identifier: GPL-2.0-only
+%YAML 1.2
+---
+$id: http://devicetree.org/schemas/sound/qcom,lpass-cpu.yaml#
+$schema: http://devicetree.org/meta-schemas/core.yaml#
+
+title: Qualcomm LPASS CPU dai driver bindings
+
+maintainers:
+  - Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
+  - Ajit Pandey <ajitp@codeaurora.org>
+
+description: |
+  Qualcomm SOC Low-Power Audio SubSystem (LPASS) that consist of MI2S interface
+  for audio data transfer on external codecs. LPASS cpu driver is a module to
+  configure Low-Power Audio Interface(LPAIF) core registers across different
+  IP versions.
+
+properties:
+  compatible:
+    enum:
+      - qcom,lpass-cpu
+      - qcom,apq8016-lpass-cpu
+
+  reg:
+    items:
+      - description: LPAIF core registers
+
+  reg-names:
+    items:
+      - const: lpass-lpaif
+
+  clocks:
+    items:
+      - description: AHBIX core clock for IPQ806X
+      - description: oscillator clock for MI2S external interfaces
+      - description: Bit clock for single MI2S dai in IPQ806X
+      - description: Bit clock for MI2S_PRIMARY dai interface
+      - description: Bit clock for MI2S_SECONDARY dai interface
+      - description: Bit clock for MI2S_TERTIARY dai interface
+      - description: Bit clock for MI2S_QUATERNARY dai interface
+      - description: NOC MPORT clock of LPASS core
+      - description: NOC SWAY clock of LPASS core
+
+  clock-names:
+    items:
+      - const: ahbix-clk
+      - const: mi2s-osr-clk
+      - const: mi2s-bit-clk
+      - const: mi2s-bit-clk0
+      - const: mi2s-bit-clk1
+      - const: mi2s-bit-clk2
+      - const: mi2s-bit-clk3
+      - const: pcnoc-mport-clk
+      - const: pcnoc-sway-clk
+
+  interrupts:
+    items:
+      - description: LPAIF DMA buffer interrupt
+
+  interrupt-names:
+    items:
+      - const: lpass-irq-lpaif
+
+  qcom,adsp:
+    maxItems: 1
+    description: Phandle for the audio DSP node
+
+  '#sound-dai-cells':
+    const: 1
+
+required:
+  - compatible
+  - reg
+  - reg-names
+  - clocks
+  - clock-names
+  - interrupts
+  - interrupt-names
+  - sound-dai-cells
+
+optional:
+  - qcom,adsp
+
+examples:
+  lpass@28100000 {
+	compatible = "qcom,lpass-cpu";
+	clocks = <&lcc AHBIX_CLK>,
+		 <&lcc MI2S_OSR_CLK>,
+		 <&lcc MI2S_BIT_CLK>;
+
+	clock-names = "ahbix-clk",
+		      "mi2s-osr-clk",
+		      "mi2s-bit-clk";
+
+	interrupts = <0 85 1>;
+	interrupt-names = "lpass-irq-lpaif";
+
+	reg = <0x28100000 0x10000>;
+	reg-names = "lpass-lpaif";
+	#sound-dai-cells = <1>;
+	qcom,adsp = <&adsp>;
+
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 02/11] ASoC: qcom: lpass: Add struct lpass_dai to store dai clocks pointer
  2020-04-11  8:02 [PATCH 00/11] ASoC: QCOM: Add support for SC7180 lpass variant Ajit Pandey
  2020-04-11  8:02 ` [PATCH 01/11] Documentation: device-tree: sound: Update lpass-cpu driver binding Ajit Pandey
@ 2020-04-11  8:02 ` Ajit Pandey
  2020-04-16  7:56   ` Srinivas Kandagatla
  2020-04-11  8:02 ` [PATCH 03/11] ASoC: qcom: Add common array to initialize soc based core clocks Ajit Pandey
                   ` (8 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Ajit Pandey @ 2020-04-11  8:02 UTC (permalink / raw)
  To: alsa-devel, broonie, devicetree, plai, bgoswami, srinivas.kandagatla
  Cc: linux-kernel, tiwai, Ajit Pandey

lpass_dai will store clocks related to respective dai's and it will
be initialized during probe based on variant clock names.

Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
---
 sound/soc/qcom/lpass-cpu.c | 89 ++++++++++++++++++++++++++--------------------
 sound/soc/qcom/lpass.h     | 18 +++++-----
 2 files changed, 61 insertions(+), 46 deletions(-)

diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
index dbce7e9..492f27b 100644
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -23,13 +23,15 @@ static int lpass_cpu_daiops_set_sysclk(struct snd_soc_dai *dai, int clk_id,
 		unsigned int freq, int dir)
 {
 	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
-	int ret;
-
-	ret = clk_set_rate(drvdata->mi2s_osr_clk[dai->driver->id], freq);
-	if (ret)
-		dev_err(dai->dev, "error setting mi2s osrclk to %u: %d\n",
-			freq, ret);
+	struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id];
+	int ret = 0;
 
+	if (dai_data->osr_clk != NULL) {
+		ret = clk_set_rate(dai_data->osr_clk, freq);
+		if (ret)
+			dev_err(dai->dev, "error setting mi2s osrclk to %u:%d\n",
+				freq, ret);
+	}
 	return ret;
 }
 
@@ -37,18 +39,22 @@ static int lpass_cpu_daiops_startup(struct snd_pcm_substream *substream,
 		struct snd_soc_dai *dai)
 {
 	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
+	struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id];
 	int ret;
 
-	ret = clk_prepare_enable(drvdata->mi2s_osr_clk[dai->driver->id]);
-	if (ret) {
-		dev_err(dai->dev, "error in enabling mi2s osr clk: %d\n", ret);
-		return ret;
+	if (dai_data->osr_clk != NULL) {
+		ret = clk_prepare_enable(dai_data->osr_clk);
+		if (ret) {
+			dev_err(dai->dev,
+				"error in enabling mi2s osr clk: %d\n", ret);
+			return ret;
+		}
 	}
 
-	ret = clk_prepare_enable(drvdata->mi2s_bit_clk[dai->driver->id]);
+	ret = clk_prepare_enable(dai_data->bit_clk);
 	if (ret) {
 		dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret);
-		clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]);
+		clk_disable_unprepare(dai_data->osr_clk);
 		return ret;
 	}
 
@@ -59,16 +65,18 @@ static void lpass_cpu_daiops_shutdown(struct snd_pcm_substream *substream,
 		struct snd_soc_dai *dai)
 {
 	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
+	struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id];
 
-	clk_disable_unprepare(drvdata->mi2s_bit_clk[dai->driver->id]);
+	clk_disable_unprepare(dai_data->bit_clk);
 
-	clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]);
+	clk_disable_unprepare(dai_data->osr_clk);
 }
 
 static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
 		struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
 {
 	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
+	struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id];
 	snd_pcm_format_t format = params_format(params);
 	unsigned int channels = params_channels(params);
 	unsigned int rate = params_rate(params);
@@ -163,8 +171,7 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
 		return ret;
 	}
 
-	ret = clk_set_rate(drvdata->mi2s_bit_clk[dai->driver->id],
-			   rate * bitwidth * 2);
+	ret = clk_set_rate(dai_data->bit_clk, rate * bitwidth * 2);
 	if (ret) {
 		dev_err(dai->dev, "error setting mi2s bitclk to %u: %d\n",
 			rate * bitwidth * 2, ret);
@@ -413,6 +420,25 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)
 	.cache_type = REGCACHE_FLAT,
 };
 
+static int lpass_init_dai_clocks(struct device *dev,
+			   struct lpass_data *drvdata)
+{
+	struct lpass_dai *dai;
+	struct lpass_variant *v = drvdata->variant;
+	int i;
+
+	for (i = 0; i < v->num_dai; i++) {
+
+		dai = drvdata->dai_priv[i];
+
+		dai->osr_clk = devm_clk_get_optional(dev,
+						     v->dai_osr_clk_names[i]);
+		dai->bit_clk = devm_clk_get(dev, v->dai_bit_clk_names[i]);
+	}
+
+	return 0;
+}
+
 int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
 {
 	struct lpass_data *drvdata;
@@ -421,7 +447,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
 	struct lpass_variant *variant;
 	struct device *dev = &pdev->dev;
 	const struct of_device_id *match;
-	int ret, i, dai_id;
+	int ret, i;
 
 	dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0);
 	if (dsp_of_node) {
@@ -467,28 +493,15 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
 		variant->init(pdev);
 
 	for (i = 0; i < variant->num_dai; i++) {
-		dai_id = variant->dai_driver[i].id;
-		drvdata->mi2s_osr_clk[dai_id] = devm_clk_get(&pdev->dev,
-					     variant->dai_osr_clk_names[i]);
-		if (IS_ERR(drvdata->mi2s_osr_clk[dai_id])) {
-			dev_warn(&pdev->dev,
-				"%s() error getting optional %s: %ld\n",
-				__func__,
-				variant->dai_osr_clk_names[i],
-				PTR_ERR(drvdata->mi2s_osr_clk[dai_id]));
-
-			drvdata->mi2s_osr_clk[dai_id] = NULL;
-		}
+		drvdata->dai_priv[i] = devm_kzalloc(dev,
+						sizeof(struct lpass_dai),
+						GFP_KERNEL);
+	}
 
-		drvdata->mi2s_bit_clk[dai_id] = devm_clk_get(&pdev->dev,
-						variant->dai_bit_clk_names[i]);
-		if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) {
-			dev_err(&pdev->dev,
-				"error getting %s: %ld\n",
-				variant->dai_bit_clk_names[i],
-				PTR_ERR(drvdata->mi2s_bit_clk[dai_id]));
-			return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]);
-		}
+	ret = lpass_init_dai_clocks(dev, drvdata);
+	if (ret) {
+		dev_err(&pdev->dev, "error intializing dai clock: %d\n", ret);
+		return ret;
 	}
 
 	drvdata->ahbix_clk = devm_clk_get(&pdev->dev, "ahbix-clk");
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
index 17113d3..b729686 100644
--- a/sound/soc/qcom/lpass.h
+++ b/sound/soc/qcom/lpass.h
@@ -13,9 +13,14 @@
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
 
-#define LPASS_AHBIX_CLOCK_FREQUENCY		131072000
-#define LPASS_MAX_MI2S_PORTS			(8)
-#define LPASS_MAX_DMA_CHANNELS			(8)
+#define LPASS_AHBIX_CLOCK_FREQUENCY            131072000
+#define LPASS_MAX_MI2S_PORTS                   (8)
+#define LPASS_MAX_DMA_CHANNELS                 (8)
+
+struct lpass_dai {
+	struct clk *osr_clk;
+	struct clk *bit_clk;
+};
 
 /* Both the CPU DAI and platform drivers will access this data */
 struct lpass_data {
@@ -23,11 +28,8 @@ struct lpass_data {
 	/* AHB-I/X bus clocks inside the low-power audio subsystem (LPASS) */
 	struct clk *ahbix_clk;
 
-	/* MI2S system clock */
-	struct clk *mi2s_osr_clk[LPASS_MAX_MI2S_PORTS];
-
-	/* MI2S bit clock (derived from system clock by a divider */
-	struct clk *mi2s_bit_clk[LPASS_MAX_MI2S_PORTS];
+	/* MI2S dai specific configuration */
+	struct lpass_dai *dai_priv[LPASS_MAX_MI2S_PORTS];
 
 	/* low-power audio interface (LPAIF) registers */
 	void __iomem *lpaif;
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 03/11] ASoC: qcom: Add common array to initialize soc based core clocks
  2020-04-11  8:02 [PATCH 00/11] ASoC: QCOM: Add support for SC7180 lpass variant Ajit Pandey
  2020-04-11  8:02 ` [PATCH 01/11] Documentation: device-tree: sound: Update lpass-cpu driver binding Ajit Pandey
  2020-04-11  8:02 ` [PATCH 02/11] ASoC: qcom: lpass: Add struct lpass_dai to store dai clocks pointer Ajit Pandey
@ 2020-04-11  8:02 ` Ajit Pandey
  2020-04-11  8:02 ` [PATCH 04/11] ASoC: qcom: lpass-cpu: Make "ahbix-clk" an optional clock Ajit Pandey
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Ajit Pandey @ 2020-04-11  8:02 UTC (permalink / raw)
  To: alsa-devel, broonie, devicetree, plai, bgoswami, srinivas.kandagatla
  Cc: linux-kernel, tiwai, Ajit Pandey

lpass variants have their own soc specific clocks that needs to be
enable for MI2S audio support. Added a common variable in drvdata to
initialize such clocks using bulk clk api. Such clock names is still
defined in variants specific data and needs to fetched during init.

Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
---
 sound/soc/qcom/lpass-apq8016.c | 39 ++++++++++++++++++---------------------
 sound/soc/qcom/lpass.h         | 10 +++++++---
 2 files changed, 25 insertions(+), 24 deletions(-)

diff --git a/sound/soc/qcom/lpass-apq8016.c b/sound/soc/qcom/lpass-apq8016.c
index 6575da5..cef4661 100644
--- a/sound/soc/qcom/lpass-apq8016.c
+++ b/sound/soc/qcom/lpass-apq8016.c
@@ -161,33 +161,26 @@ static int apq8016_lpass_free_dma_channel(struct lpass_data *drvdata, int chan)
 static int apq8016_lpass_init(struct platform_device *pdev)
 {
 	struct lpass_data *drvdata = platform_get_drvdata(pdev);
+	struct lpass_variant *variant = drvdata->variant;
 	struct device *dev = &pdev->dev;
-	int ret;
+	int ret, i;
 
-	drvdata->pcnoc_mport_clk = devm_clk_get(dev, "pcnoc-mport-clk");
-	if (IS_ERR(drvdata->pcnoc_mport_clk)) {
-		dev_err(&pdev->dev, "error getting pcnoc-mport-clk: %ld\n",
-			PTR_ERR(drvdata->pcnoc_mport_clk));
-		return PTR_ERR(drvdata->pcnoc_mport_clk);
-	}
+	drvdata->clks = devm_kcalloc(dev, variant->num_clks,
+				     sizeof(*drvdata->clks), GFP_KERNEL);
+	drvdata->num_clks = variant->num_clks;
+
+	for (i = 0; i < drvdata->num_clks; i++)
+		drvdata->clks[i].id = variant->clk_name[i];
 
-	ret = clk_prepare_enable(drvdata->pcnoc_mport_clk);
+	ret = devm_clk_bulk_get(dev, drvdata->num_clks, drvdata->clks);
 	if (ret) {
-		dev_err(&pdev->dev, "Error enabling pcnoc-mport-clk: %d\n",
-			ret);
+		dev_err(dev, "Failed to get clocks %d\n", ret);
 		return ret;
 	}
 
-	drvdata->pcnoc_sway_clk = devm_clk_get(dev, "pcnoc-sway-clk");
-	if (IS_ERR(drvdata->pcnoc_sway_clk)) {
-		dev_err(&pdev->dev, "error getting pcnoc-sway-clk: %ld\n",
-			PTR_ERR(drvdata->pcnoc_sway_clk));
-		return PTR_ERR(drvdata->pcnoc_sway_clk);
-	}
-
-	ret = clk_prepare_enable(drvdata->pcnoc_sway_clk);
+	ret = clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks);
 	if (ret) {
-		dev_err(&pdev->dev, "Error enabling pcnoc_sway_clk: %d\n", ret);
+		dev_err(dev, "ao8016 clk_enable failed\n");
 		return ret;
 	}
 
@@ -198,8 +191,7 @@ static int apq8016_lpass_exit(struct platform_device *pdev)
 {
 	struct lpass_data *drvdata = platform_get_drvdata(pdev);
 
-	clk_disable_unprepare(drvdata->pcnoc_mport_clk);
-	clk_disable_unprepare(drvdata->pcnoc_sway_clk);
+	clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks);
 
 	return 0;
 }
@@ -220,6 +212,11 @@ static int apq8016_lpass_exit(struct platform_device *pdev)
 	.wrdma_reg_stride	= 0x1000,
 	.wrdma_channel_start	= 5,
 	.wrdma_channels		= 2,
+	.clk_name		= (const char*[]) {
+				   "pcnoc-mport-clk",
+				   "pcnoc-sway-clk",
+				  },
+	.num_clks		= 2,
 	.dai_driver		= apq8016_lpass_cpu_dai_driver,
 	.num_dai		= ARRAY_SIZE(apq8016_lpass_cpu_dai_driver),
 	.dai_osr_clk_names	= (const char *[]) {
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
index b729686..279cd02 100644
--- a/sound/soc/qcom/lpass.h
+++ b/sound/soc/qcom/lpass.h
@@ -49,9 +49,9 @@ struct lpass_data {
 	/* used it for handling interrupt per dma channel */
 	struct snd_pcm_substream *substream[LPASS_MAX_DMA_CHANNELS];
 
-	/* 8016 specific */
-	struct clk *pcnoc_mport_clk;
-	struct clk *pcnoc_sway_clk;
+	/* SOC specific clock list */
+	struct clk_bulk_data *clks;
+	int num_clks;
 
 };
 
@@ -87,6 +87,10 @@ struct lpass_variant {
 	int num_dai;
 	const char * const *dai_osr_clk_names;
 	const char * const *dai_bit_clk_names;
+
+	/* SOC specific clocks configuration */
+	const char **clk_name;
+	int num_clks;
 };
 
 /* register the platform driver from the CPU DAI driver */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 04/11] ASoC: qcom: lpass-cpu: Make "ahbix-clk" an optional clock.
  2020-04-11  8:02 [PATCH 00/11] ASoC: QCOM: Add support for SC7180 lpass variant Ajit Pandey
                   ` (2 preceding siblings ...)
  2020-04-11  8:02 ` [PATCH 03/11] ASoC: qcom: Add common array to initialize soc based core clocks Ajit Pandey
@ 2020-04-11  8:02 ` Ajit Pandey
  2020-04-16  7:56   ` Srinivas Kandagatla
  2020-04-11  8:02 ` [PATCH 05/11] ASoC: qcom: lpass: Add support for newer lpass version Ajit Pandey
                   ` (6 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Ajit Pandey @ 2020-04-11  8:02 UTC (permalink / raw)
  To: alsa-devel, broonie, devicetree, plai, bgoswami, srinivas.kandagatla
  Cc: linux-kernel, tiwai, Ajit Pandey

AHB-I/X bus clocks inside LPASS coreis not a mandatory clocks for
newer lpass variants, hence make it an optional one.

Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
---
 sound/soc/qcom/lpass-cpu.c | 31 ++++++++++++++++++-------------
 1 file changed, 18 insertions(+), 13 deletions(-)

diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
index 492f27b..f177932 100644
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -504,26 +504,31 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
 		return ret;
 	}
 
-	drvdata->ahbix_clk = devm_clk_get(&pdev->dev, "ahbix-clk");
+	drvdata->ahbix_clk = devm_clk_get_optional(&pdev->dev, "ahbix-clk");
 	if (IS_ERR(drvdata->ahbix_clk)) {
 		dev_err(&pdev->dev, "error getting ahbix-clk: %ld\n",
 			PTR_ERR(drvdata->ahbix_clk));
 		return PTR_ERR(drvdata->ahbix_clk);
 	}
 
-	ret = clk_set_rate(drvdata->ahbix_clk, LPASS_AHBIX_CLOCK_FREQUENCY);
-	if (ret) {
-		dev_err(&pdev->dev, "error setting rate on ahbix_clk: %d\n",
-			ret);
-		return ret;
-	}
-	dev_dbg(&pdev->dev, "set ahbix_clk rate to %lu\n",
-		clk_get_rate(drvdata->ahbix_clk));
+	if (drvdata->ahbix_clk != NULL) {
+		ret = clk_set_rate(drvdata->ahbix_clk,
+				   LPASS_AHBIX_CLOCK_FREQUENCY);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"error setting rate on ahbix_clk: %d\n", ret);
+			return ret;
+		}
 
-	ret = clk_prepare_enable(drvdata->ahbix_clk);
-	if (ret) {
-		dev_err(&pdev->dev, "error enabling ahbix_clk: %d\n", ret);
-		return ret;
+		dev_dbg(&pdev->dev, "set ahbix_clk rate to %lu\n",
+			clk_get_rate(drvdata->ahbix_clk));
+
+		ret = clk_prepare_enable(drvdata->ahbix_clk);
+		if (ret) {
+			dev_err(&pdev->dev,
+				"error enabling ahbix_clk: %d\n", ret);
+			return ret;
+		}
 	}
 
 	ret = devm_snd_soc_register_component(&pdev->dev,
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 05/11] ASoC: qcom: lpass: Add support for newer lpass version
  2020-04-11  8:02 [PATCH 00/11] ASoC: QCOM: Add support for SC7180 lpass variant Ajit Pandey
                   ` (3 preceding siblings ...)
  2020-04-11  8:02 ` [PATCH 04/11] ASoC: qcom: lpass-cpu: Make "ahbix-clk" an optional clock Ajit Pandey
@ 2020-04-11  8:02 ` Ajit Pandey
  2020-04-16  7:56   ` Srinivas Kandagatla
  2020-04-11  8:02 ` [PATCH 06/11] dt-bindings: sound: Add bindings related to lpass-cpu configuration Ajit Pandey
                   ` (5 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Ajit Pandey @ 2020-04-11  8:02 UTC (permalink / raw)
  To: alsa-devel, broonie, devicetree, plai, bgoswami, srinivas.kandagatla
  Cc: linux-kernel, tiwai, Ajit Pandey

Few control registers bit offset of lpaif in newer lpass variants
are changed. Added "id" field in variant struct and changes macros
configuration of registers to calculate bit mask & offset based on
variant id.

Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
---
 sound/soc/qcom/lpass-cpu.c       |  77 +++++++++--------
 sound/soc/qcom/lpass-lpaif-reg.h | 182 ++++++++++++++++++++++++++++++++++++++-
 sound/soc/qcom/lpass-platform.c  |  31 +++----
 sound/soc/qcom/lpass.h           |   6 ++
 4 files changed, 241 insertions(+), 55 deletions(-)

diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
index f177932..006ba5a 100644
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -77,6 +77,7 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
 {
 	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
 	struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id];
+	struct lpass_variant *v = drvdata->variant;
 	snd_pcm_format_t format = params_format(params);
 	unsigned int channels = params_channels(params);
 	unsigned int rate = params_rate(params);
@@ -89,18 +90,18 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
 		return bitwidth;
 	}
 
-	regval = LPAIF_I2SCTL_LOOPBACK_DISABLE |
-			LPAIF_I2SCTL_WSSRC_INTERNAL;
+	regval = LPAIF_I2SCTL(v, LOOPBACK_DISABLE);
+	regval |= LPAIF_I2SCTL(v, WSSRC_INTERNAL);
 
 	switch (bitwidth) {
 	case 16:
-		regval |= LPAIF_I2SCTL_BITWIDTH_16;
+		regval |= LPAIF_I2SCTL(v, BITWIDTH_16);
 		break;
 	case 24:
-		regval |= LPAIF_I2SCTL_BITWIDTH_24;
+		regval |= LPAIF_I2SCTL(v, BITWIDTH_24);
 		break;
 	case 32:
-		regval |= LPAIF_I2SCTL_BITWIDTH_32;
+		regval |= LPAIF_I2SCTL(v, BITWIDTH_32);
 		break;
 	default:
 		dev_err(dai->dev, "invalid bitwidth given: %d\n", bitwidth);
@@ -110,24 +111,24 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
 		switch (channels) {
 		case 1:
-			regval |= LPAIF_I2SCTL_SPKMODE_SD0;
-			regval |= LPAIF_I2SCTL_SPKMONO_MONO;
+			regval |= LPAIF_I2SCTL(v, SPKMODE_SD0);
+			regval |= LPAIF_I2SCTL(v, SPKMONO_MONO);
 			break;
 		case 2:
-			regval |= LPAIF_I2SCTL_SPKMODE_SD0;
-			regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
+			regval |= LPAIF_I2SCTL(v, SPKMODE_SD0);
+			regval |= LPAIF_I2SCTL(v, SPKMONO_STEREO);
 			break;
 		case 4:
-			regval |= LPAIF_I2SCTL_SPKMODE_QUAD01;
-			regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
+			regval |= LPAIF_I2SCTL(v, SPKMODE_QUAD01);
+			regval |= LPAIF_I2SCTL(v, SPKMONO_STEREO);
 			break;
 		case 6:
-			regval |= LPAIF_I2SCTL_SPKMODE_6CH;
-			regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
+			regval |= LPAIF_I2SCTL(v, SPKMODE_6CH);
+			regval |= LPAIF_I2SCTL(v, SPKMONO_STEREO);
 			break;
 		case 8:
-			regval |= LPAIF_I2SCTL_SPKMODE_8CH;
-			regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
+			regval |= LPAIF_I2SCTL(v, SPKMODE_8CH);
+			regval |= LPAIF_I2SCTL(v, SPKMONO_STEREO);
 			break;
 		default:
 			dev_err(dai->dev, "invalid channels given: %u\n",
@@ -137,24 +138,24 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
 	} else {
 		switch (channels) {
 		case 1:
-			regval |= LPAIF_I2SCTL_MICMODE_SD0;
-			regval |= LPAIF_I2SCTL_MICMONO_MONO;
+			regval |= LPAIF_I2SCTL(v, MICMODE_SD0);
+			regval |= LPAIF_I2SCTL(v, MICMONO_MONO);
 			break;
 		case 2:
-			regval |= LPAIF_I2SCTL_MICMODE_SD0;
-			regval |= LPAIF_I2SCTL_MICMONO_STEREO;
+			regval |= LPAIF_I2SCTL(v, MICMODE_SD0);
+			regval |= LPAIF_I2SCTL(v, MICMONO_STEREO);
 			break;
 		case 4:
-			regval |= LPAIF_I2SCTL_MICMODE_QUAD01;
-			regval |= LPAIF_I2SCTL_MICMONO_STEREO;
+			regval |= LPAIF_I2SCTL(v, MICMODE_QUAD01);
+			regval |= LPAIF_I2SCTL(v, MICMONO_STEREO);
 			break;
 		case 6:
-			regval |= LPAIF_I2SCTL_MICMODE_6CH;
-			regval |= LPAIF_I2SCTL_MICMONO_STEREO;
+			regval |= LPAIF_I2SCTL(v, MICMODE_6CH);
+			regval |= LPAIF_I2SCTL(v, MICMONO_STEREO);
 			break;
 		case 8:
-			regval |= LPAIF_I2SCTL_MICMODE_8CH;
-			regval |= LPAIF_I2SCTL_MICMONO_STEREO;
+			regval |= LPAIF_I2SCTL(v, MICMODE_8CH);
+			regval |= LPAIF_I2SCTL(v, MICMONO_STEREO);
 			break;
 		default:
 			dev_err(dai->dev, "invalid channels given: %u\n",
@@ -200,15 +201,16 @@ static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream,
 		struct snd_soc_dai *dai)
 {
 	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
+	struct lpass_variant *v = drvdata->variant;
 	int ret;
 	unsigned int val, mask;
 
 	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-		val = LPAIF_I2SCTL_SPKEN_ENABLE;
-		mask = LPAIF_I2SCTL_SPKEN_MASK;
+		val = LPAIF_I2SCTL(v, SPKEN_ENABLE);
+		mask = LPAIF_I2SCTL(v, SPKEN_MASK);
 	} else  {
-		val = LPAIF_I2SCTL_MICEN_ENABLE;
-		mask = LPAIF_I2SCTL_MICEN_MASK;
+		val = LPAIF_I2SCTL(v, MICEN_ENABLE);
+		mask = LPAIF_I2SCTL(v, MICEN_MASK);
 	}
 
 	ret = regmap_update_bits(drvdata->lpaif_map,
@@ -224,6 +226,7 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
 		int cmd, struct snd_soc_dai *dai)
 {
 	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
+	struct lpass_variant *v = drvdata->variant;
 	int ret = -EINVAL;
 	unsigned int val, mask;
 
@@ -232,11 +235,11 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
 	case SNDRV_PCM_TRIGGER_RESUME:
 	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-			val = LPAIF_I2SCTL_SPKEN_ENABLE;
-			mask = LPAIF_I2SCTL_SPKEN_MASK;
+			val = LPAIF_I2SCTL(v, SPKEN_ENABLE);
+			mask = LPAIF_I2SCTL(v, SPKEN_MASK);
 		} else  {
-			val = LPAIF_I2SCTL_MICEN_ENABLE;
-			mask = LPAIF_I2SCTL_MICEN_MASK;
+			val = LPAIF_I2SCTL(v, MICEN_ENABLE);
+			mask = LPAIF_I2SCTL(v, MICEN_MASK);
 		}
 
 		ret = regmap_update_bits(drvdata->lpaif_map,
@@ -251,11 +254,11 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
 	case SNDRV_PCM_TRIGGER_SUSPEND:
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
-			val = LPAIF_I2SCTL_SPKEN_DISABLE;
-			mask = LPAIF_I2SCTL_SPKEN_MASK;
+			val = LPAIF_I2SCTL(v, SPKEN_DISABLE);
+			mask = LPAIF_I2SCTL(v, SPKEN_MASK);
 		} else  {
-			val = LPAIF_I2SCTL_MICEN_DISABLE;
-			mask = LPAIF_I2SCTL_MICEN_MASK;
+			val = LPAIF_I2SCTL(v, MICEN_DISABLE);
+			mask = LPAIF_I2SCTL(v, MICEN_MASK);
 		}
 
 		ret = regmap_update_bits(drvdata->lpaif_map,
diff --git a/sound/soc/qcom/lpass-lpaif-reg.h b/sound/soc/qcom/lpass-lpaif-reg.h
index 3d74ae1..4251aa6 100644
--- a/sound/soc/qcom/lpass-lpaif-reg.h
+++ b/sound/soc/qcom/lpass-lpaif-reg.h
@@ -17,11 +17,28 @@
 #define LPAIF_I2SCTL_LOOPBACK_DISABLE	(0 << LPAIF_I2SCTL_LOOPBACK_SHIFT)
 #define LPAIF_I2SCTL_LOOPBACK_ENABLE	(1 << LPAIF_I2SCTL_LOOPBACK_SHIFT)
 
+#define LPAIF_I2SCTL_LOOPBACK_MASK_V2	 0x20000
+#define LPAIF_I2SCTL_LOOPBACK_SHIFT_V2	 17
+#define LPAIF_I2SCTL_LOOPBACK_DISABLE_V2 (0 << LPAIF_I2SCTL_LOOPBACK_SHIFT_V2)
+#define LPAIF_I2SCTL_LOOPBACK_ENABLE_V2	 (1 << LPAIF_I2SCTL_LOOPBACK_SHIFT_V2)
+
 #define LPAIF_I2SCTL_SPKEN_MASK		0x4000
 #define LPAIF_I2SCTL_SPKEN_SHIFT	14
 #define LPAIF_I2SCTL_SPKEN_DISABLE	(0 << LPAIF_I2SCTL_SPKEN_SHIFT)
 #define LPAIF_I2SCTL_SPKEN_ENABLE	(1 << LPAIF_I2SCTL_SPKEN_SHIFT)
 
+#define LPAIF_I2SCTL_SPKEN_MASK_V2	0x10000
+#define LPAIF_I2SCTL_SPKEN_SHIFT_V2	16
+#define LPAIF_I2SCTL_SPKEN_DISABLE_V2	(0 << LPAIF_I2SCTL_SPKEN_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKEN_ENABLE_V2	(1 << LPAIF_I2SCTL_SPKEN_SHIFT_V2)
+
+#define __LPAIF_I2S_CTL(v, bit)  \
+	((v->id ==  LPASS_VARIANT_V2) ? \
+		LPAIF_I2SCTL_##bit##_V2 : \
+		LPAIF_I2SCTL_##bit)
+
+#define LPAIF_I2SCTL(v, bit)		__LPAIF_I2S_CTL(v, bit)
+
 #define LPAIF_I2SCTL_SPKMODE_MASK	0x3C00
 #define LPAIF_I2SCTL_SPKMODE_SHIFT	10
 #define LPAIF_I2SCTL_SPKMODE_NONE	(0 << LPAIF_I2SCTL_SPKMODE_SHIFT)
@@ -34,16 +51,49 @@
 #define LPAIF_I2SCTL_SPKMODE_6CH	(7 << LPAIF_I2SCTL_SPKMODE_SHIFT)
 #define LPAIF_I2SCTL_SPKMODE_8CH	(8 << LPAIF_I2SCTL_SPKMODE_SHIFT)
 
+#define LPAIF_I2SCTL_SPKMODE_MASK_V2	0xF800
+#define LPAIF_I2SCTL_SPKMODE_SHIFT_V2	11
+#define LPAIF_I2SCTL_SPKMODE_NONE_V2	(0 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_SD0_V2	(1 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_SD1_V2	(2 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_SD2_V2	(3 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_SD3_V2	(4 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_QUAD01_V2	(5 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_QUAD23_V2	(6 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_6CH_V2	(7 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_8CH_V2	(8 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_10CH_V2	(9 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_12CH_V2	(10 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_14CH_V2	(11 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_16CH_V2	(12 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_SD4_V2	(13 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_SD5_V2	(14 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_SD6_V2	(15 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_SD7_V2	(16 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_QUAD45_V2	(17 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_QUAD47_V2	(18 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMODE_8CH_2_V2	(19 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
+
 #define LPAIF_I2SCTL_SPKMONO_MASK	0x0200
 #define LPAIF_I2SCTL_SPKMONO_SHIFT	9
 #define LPAIF_I2SCTL_SPKMONO_STEREO	(0 << LPAIF_I2SCTL_SPKMONO_SHIFT)
 #define LPAIF_I2SCTL_SPKMONO_MONO	(1 << LPAIF_I2SCTL_SPKMONO_SHIFT)
 
+#define LPAIF_I2SCTL_SPKMONO_MASK_V2	0x0400
+#define LPAIF_I2SCTL_SPKMONO_SHIFT_V2	10
+#define LPAIF_I2SCTL_SPKMONO_STEREO_V2	(0 << LPAIF_I2SCTL_SPKMONO_SHIFT_V2)
+#define LPAIF_I2SCTL_SPKMONO_MONO_V2	(1 << LPAIF_I2SCTL_SPKMONO_SHIFT_V2)
+
 #define LPAIF_I2SCTL_MICEN_MASK		GENMASK(8, 8)
 #define LPAIF_I2SCTL_MICEN_SHIFT	8
 #define LPAIF_I2SCTL_MICEN_DISABLE	(0 << LPAIF_I2SCTL_MICEN_SHIFT)
 #define LPAIF_I2SCTL_MICEN_ENABLE	(1 << LPAIF_I2SCTL_MICEN_SHIFT)
 
+#define LPAIF_I2SCTL_MICEN_MASK_V2	0x0200
+#define LPAIF_I2SCTL_MICEN_SHIFT_V2	9
+#define LPAIF_I2SCTL_MICEN_DISABLE_V2	(0 << LPAIF_I2SCTL_MICEN_SHIFT_V2)
+#define LPAIF_I2SCTL_MICEN_ENABLE_V2	(1 << LPAIF_I2SCTL_MICEN_SHIFT_V2)
+
 #define LPAIF_I2SCTL_MICMODE_MASK	GENMASK(7, 4)
 #define LPAIF_I2SCTL_MICMODE_SHIFT	4
 #define LPAIF_I2SCTL_MICMODE_NONE	(0 << LPAIF_I2SCTL_MICMODE_SHIFT)
@@ -56,22 +106,61 @@
 #define LPAIF_I2SCTL_MICMODE_6CH	(7 << LPAIF_I2SCTL_MICMODE_SHIFT)
 #define LPAIF_I2SCTL_MICMODE_8CH	(8 << LPAIF_I2SCTL_MICMODE_SHIFT)
 
+#define LPAIF_I2SCTL_MICMODE_MASK_V2	GENMASK(8, 4)
+#define LPAIF_I2SCTL_MICMODE_SHIFT_V2	4
+#define LPAIF_I2SCTL_MICMODE_NONE_V2	(0 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_SD0_V2	(1 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_SD1_V2	(2 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_SD2_V2	(3 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_SD3_V2	(4 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_QUAD01_V2	(5 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_QUAD23_V2	(6 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_6CH_V2	(7 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_8CH_V2	(8 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_10CH_V2	(9 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_12CH_V2	(10 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_14CH_V2	(11 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_16CH_V2	(12 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_SD4_V2	(13 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_SD5_V2	(14 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_SD6_V2	(15 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_SD7_V2	(16 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_QUAD45_V2	(17 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_QUAD47_V2	(18 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMODE_8CH_2_V2	(19 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
+
 #define LPAIF_I2SCTL_MIMONO_MASK	GENMASK(3, 3)
 #define LPAIF_I2SCTL_MICMONO_SHIFT	3
 #define LPAIF_I2SCTL_MICMONO_STEREO	(0 << LPAIF_I2SCTL_MICMONO_SHIFT)
 #define LPAIF_I2SCTL_MICMONO_MONO	(1 << LPAIF_I2SCTL_MICMONO_SHIFT)
 
+#define LPAIF_I2SCTL_MICMONO_MASK_V2	GENMASK(3, 3)
+#define LPAIF_I2SCTL_MICMONO_SHIFT_V2	3
+#define LPAIF_I2SCTL_MICMONO_STEREO_V2	(0 << LPAIF_I2SCTL_MICMONO_SHIFT_V2)
+#define LPAIF_I2SCTL_MICMONO_MONO_V2	(1 << LPAIF_I2SCTL_MICMONO_SHIFT_V2)
+
 #define LPAIF_I2SCTL_WSSRC_MASK		0x0004
 #define LPAIF_I2SCTL_WSSRC_SHIFT	2
 #define LPAIF_I2SCTL_WSSRC_INTERNAL	(0 << LPAIF_I2SCTL_WSSRC_SHIFT)
 #define LPAIF_I2SCTL_WSSRC_EXTERNAL	(1 << LPAIF_I2SCTL_WSSRC_SHIFT)
 
+#define LPAIF_I2SCTL_WSSRC_MASK_V2	0x0004
+#define LPAIF_I2SCTL_WSSRC_SHIFT_V2	2
+#define LPAIF_I2SCTL_WSSRC_INTERNAL_V2	(0 << LPAIF_I2SCTL_WSSRC_SHIFT_V2)
+#define LPAIF_I2SCTL_WSSRC_EXTERNAL_V2	(1 << LPAIF_I2SCTL_WSSRC_SHIFT_V2)
+
 #define LPAIF_I2SCTL_BITWIDTH_MASK	0x0003
 #define LPAIF_I2SCTL_BITWIDTH_SHIFT	0
 #define LPAIF_I2SCTL_BITWIDTH_16	(0 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
 #define LPAIF_I2SCTL_BITWIDTH_24	(1 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
 #define LPAIF_I2SCTL_BITWIDTH_32	(2 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
 
+#define LPAIF_I2SCTL_BITWIDTH_MASK_V2	0x0003
+#define LPAIF_I2SCTL_BITWIDTH_SHIFT_V2	0
+#define LPAIF_I2SCTL_BITWIDTH_16_V2	(0 << LPAIF_I2SCTL_BITWIDTH_SHIFT_V2)
+#define LPAIF_I2SCTL_BITWIDTH_24_V2	(1 << LPAIF_I2SCTL_BITWIDTH_SHIFT_V2)
+#define LPAIF_I2SCTL_BITWIDTH_32_V2	(2 << LPAIF_I2SCTL_BITWIDTH_SHIFT_V2)
+
 /* LPAIF IRQ */
 #define LPAIF_IRQ_REG_ADDR(v, addr, port) \
 	(v->irq_reg_base + (addr) + v->irq_reg_stride * (port))
@@ -91,7 +180,6 @@
 #define LPAIF_IRQ_ALL(chan)		(7 << (LPAIF_IRQ_BITSTRIDE * (chan)))
 
 /* LPAIF DMA */
-
 #define LPAIF_RDMA_REG_ADDR(v, addr, chan) \
 	(v->rdma_reg_base + (addr) + v->rdma_reg_stride * (chan))
 
@@ -143,7 +231,7 @@
 
 #define LPAIF_DMACTL_AUDINTF_MASK	0x0F0
 #define LPAIF_DMACTL_AUDINTF_SHIFT	4
-#define LPAIF_DMACTL_AUDINTF(id)	(id << LPAIF_DMACTL_AUDINTF_SHIFT)
+#define LPAIF_DMACTL_AUDINTF(port)	(port << LPAIF_DMACTL_AUDINTF_SHIFT)
 
 #define LPAIF_DMACTL_FIFOWM_MASK	0x00E
 #define LPAIF_DMACTL_FIFOWM_SHIFT	1
@@ -158,11 +246,99 @@
 
 #define LPAIF_DMACTL_ENABLE_MASK	0x1
 #define LPAIF_DMACTL_ENABLE_SHIFT	0
-#define LPAIF_DMACTL_ENABLE_OFF	(0 << LPAIF_DMACTL_ENABLE_SHIFT)
+#define LPAIF_DMACTL_ENABLE_OFF		(0 << LPAIF_DMACTL_ENABLE_SHIFT)
 #define LPAIF_DMACTL_ENABLE_ON		(1 << LPAIF_DMACTL_ENABLE_SHIFT)
 
+#define LPAIF_IRQ_BITSTRIDE		3
+
+#define LPAIF_IRQ_PER(chan)		(1 << (LPAIF_IRQ_BITSTRIDE * (chan)))
+#define LPAIF_IRQ_XRUN(chan)		(2 << (LPAIF_IRQ_BITSTRIDE * (chan)))
+#define LPAIF_IRQ_ERR(chan)		(4 << (LPAIF_IRQ_BITSTRIDE * (chan)))
+
+#define LPAIF_IRQ_ALL(chan)		(7 << (LPAIF_IRQ_BITSTRIDE * (chan)))
+
 #define LPAIF_DMACTL_DYNCLK_MASK	BIT(12)
 #define LPAIF_DMACTL_DYNCLK_SHIFT	12
 #define LPAIF_DMACTL_DYNCLK_OFF	(0 << LPAIF_DMACTL_DYNCLK_SHIFT)
 #define LPAIF_DMACTL_DYNCLK_ON		(1 << LPAIF_DMACTL_DYNCLK_SHIFT)
+
+#define LPAIF_DMACTL_BURSTEN_MASK_V2	0x100000
+#define LPAIF_DMACTL_BURSTEN_SHIFT_V2	20
+#define LPAIF_DMACTL_BURSTEN_SINGLE_V2	(0 << LPAIF_DMACTL_BURSTEN_SHIFT_V2)
+#define LPAIF_DMACTL_BURSTEN_INCR4_V2	(1 << LPAIF_DMACTL_BURSTEN_SHIFT_V2)
+
+#define LPAIF_DMACTL_WPSCNT_MASK_V2	0xF0000
+#define LPAIF_DMACTL_WPSCNT_SHIFT_V2	16
+#define LPAIF_DMACTL_WPSCNT_ONE_V2	(0 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
+#define LPAIF_DMACTL_WPSCNT_TWO_V2	(1 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
+#define LPAIF_DMACTL_WPSCNT_THREE_V2	(2 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
+#define LPAIF_DMACTL_WPSCNT_FOUR_V2	(3 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
+#define LPAIF_DMACTL_WPSCNT_SIX_V2	(5 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
+#define LPAIF_DMACTL_WPSCNT_EIGHT_V2	(7 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
+#define LPAIF_DMACTL_WPSCNT_TEN_V2	(9 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
+#define LPAIF_DMACTL_WPSCNT_TWELVE_V2	(11 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
+#define LPAIF_DMACTL_WPSCNT_FOURTEEN_V2	(13 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
+#define LPAIF_DMACTL_WPSCNT_SIXTEEN_V2	(15 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
+
+#define LPAIF_DMACTL_AUDINTF_MASK_V2	0xF000
+#define LPAIF_DMACTL_AUDINTF_SHIFT_V2	12
+#define LPAIF_DMACTL_AUDINTF_V2(port)	(port << LPAIF_DMACTL_AUDINTF_SHIFT_V2)
+
+#define LPAIF_DMACTL_AUD_INTF(v, port)  \
+	((v->id ==  LPASS_VARIANT_V2) ? \
+		LPAIF_DMACTL_AUDINTF_V2(port) : \
+		LPAIF_DMACTL_AUDINTF(port))
+
+#define LPAIF_DMACTL_FIFOWM_MASK_V2	0x3E
+#define LPAIF_DMACTL_FIFOWM_SHIFT_V2	1
+#define LPAIF_DMACTL_FIFOWM_1_V2	(0 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_2_V2	(1 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_3_V2	(2 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_4_V2	(3 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_5_V2	(4 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_6_V2	(5 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_7_V2	(6 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_8_V2	(7 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_9_V2	(8 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_10_V2	(9 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_11_V2	(10 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_12_V2	(11 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_13_V2	(12 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_14_V2	(13 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_15_V2	(14 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_16_V2	(15 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_17_V2	(16 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_18_V2	(17 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_19_V2	(18 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_20_V2	(19 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_21_V2	(20 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_22_V2	(21 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_23_V2	(22 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_24_V2	(23 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_25_V2	(24 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_26_V2	(25 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_27_V2	(26 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_28_V2	(27 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_29_V2	(28 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_30_V2	(29 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_31_V2	(30 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+#define LPAIF_DMACTL_FIFOWM_32_V2	(31 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
+
+#define LPAIF_DMACTL_ENABLE_MASK_V2	0x1
+#define LPAIF_DMACTL_ENABLE_SHIFT_V2	0
+#define LPAIF_DMACTL_ENABLE_OFF_V2	(0 << LPAIF_DMACTL_ENABLE_SHIFT_V2)
+#define LPAIF_DMACTL_ENABLE_ON_V2	(1 << LPAIF_DMACTL_ENABLE_SHIFT_V2)
+
+#define LPAIF_DMACTL_DYNCLK_MASK_V2	BIT(21)
+#define LPAIF_DMACTL_DYNCLK_SHIFT_V2	21
+#define LPAIF_DMACTL_DYNCLK_OFF_V2	(0 << LPAIF_DMACTL_DYNCLK_SHIFT_V2)
+#define LPAIF_DMACTL_DYNCLK_ON_V2	(1 << LPAIF_DMACTL_DYNCLK_SHIFT_V2)
+
+#define __LPAIF_DMA_CTL(v, bit)  \
+	((v->id ==  LPASS_VARIANT_V2) ? \
+		LPAIF_DMACTL_##bit##_V2 : \
+		LPAIF_DMACTL_##bit)
+
+#define LPAIF_DMACTL(v, bit)		__LPAIF_DMA_CTL(v, bit)
+
 #endif /* __LPASS_LPAIF_REG_H__ */
diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c
index b05091c2..821599e 100644
--- a/sound/soc/qcom/lpass-platform.c
+++ b/sound/soc/qcom/lpass-platform.c
@@ -146,25 +146,26 @@ static int lpass_platform_pcmops_hw_params(struct snd_soc_component *component,
 		return bitwidth;
 	}
 
-	regval = LPAIF_DMACTL_BURSTEN_INCR4 |
-			LPAIF_DMACTL_AUDINTF(dma_port) |
-			LPAIF_DMACTL_FIFOWM_8;
+
+	regval = LPAIF_DMACTL(v, BURSTEN_INCR4);
+	regval |= LPAIF_DMACTL(v, FIFOWM_8);
+	regval |= LPAIF_DMACTL_AUD_INTF(v, dma_port);
 
 	switch (bitwidth) {
 	case 16:
 		switch (channels) {
 		case 1:
 		case 2:
-			regval |= LPAIF_DMACTL_WPSCNT_ONE;
+			regval |= LPAIF_DMACTL(v, WPSCNT_ONE);
 			break;
 		case 4:
-			regval |= LPAIF_DMACTL_WPSCNT_TWO;
+			regval |= LPAIF_DMACTL(v, WPSCNT_TWO);
 			break;
 		case 6:
-			regval |= LPAIF_DMACTL_WPSCNT_THREE;
+			regval |= LPAIF_DMACTL(v, WPSCNT_THREE);
 			break;
 		case 8:
-			regval |= LPAIF_DMACTL_WPSCNT_FOUR;
+			regval |= LPAIF_DMACTL(v, WPSCNT_FOUR);
 			break;
 		default:
 			dev_err(soc_runtime->dev,
@@ -177,19 +178,19 @@ static int lpass_platform_pcmops_hw_params(struct snd_soc_component *component,
 	case 32:
 		switch (channels) {
 		case 1:
-			regval |= LPAIF_DMACTL_WPSCNT_ONE;
+			regval |= LPAIF_DMACTL(v, WPSCNT_ONE);
 			break;
 		case 2:
-			regval |= LPAIF_DMACTL_WPSCNT_TWO;
+			regval |= LPAIF_DMACTL(v, WPSCNT_TWO);
 			break;
 		case 4:
-			regval |= LPAIF_DMACTL_WPSCNT_FOUR;
+			regval |= LPAIF_DMACTL(v, WPSCNT_FOUR);
 			break;
 		case 6:
-			regval |= LPAIF_DMACTL_WPSCNT_SIX;
+			regval |= LPAIF_DMACTL(v, WPSCNT_SIX);
 			break;
 		case 8:
-			regval |= LPAIF_DMACTL_WPSCNT_EIGHT;
+			regval |= LPAIF_DMACTL(v, WPSCNT_EIGHT);
 			break;
 		default:
 			dev_err(soc_runtime->dev,
@@ -277,7 +278,7 @@ static int lpass_platform_pcmops_prepare(struct snd_soc_component *component,
 
 	ret = regmap_update_bits(drvdata->lpaif_map,
 			LPAIF_DMACTL_REG(v, ch, dir),
-			LPAIF_DMACTL_ENABLE_MASK, LPAIF_DMACTL_ENABLE_ON);
+			LPAIF_DMACTL(v, ENABLE_MASK), LPAIF_DMACTL_ENABLE_ON);
 	if (ret) {
 		dev_err(soc_runtime->dev, "error writing to rdmactl reg: %d\n",
 			ret);
@@ -326,7 +327,7 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
 
 		ret = regmap_update_bits(drvdata->lpaif_map,
 				LPAIF_DMACTL_REG(v, ch, dir),
-				LPAIF_DMACTL_ENABLE_MASK,
+				LPAIF_DMACTL(v, ENABLE_MASK),
 				LPAIF_DMACTL_ENABLE_ON);
 		if (ret) {
 			dev_err(soc_runtime->dev,
@@ -339,7 +340,7 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
 	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
 		ret = regmap_update_bits(drvdata->lpaif_map,
 				LPAIF_DMACTL_REG(v, ch, dir),
-				LPAIF_DMACTL_ENABLE_MASK,
+				LPAIF_DMACTL(v, ENABLE_MASK),
 				LPAIF_DMACTL_ENABLE_OFF);
 		if (ret) {
 			dev_err(soc_runtime->dev,
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
index 279cd02..384f4b8 100644
--- a/sound/soc/qcom/lpass.h
+++ b/sound/soc/qcom/lpass.h
@@ -17,6 +17,9 @@
 #define LPASS_MAX_MI2S_PORTS                   (8)
 #define LPASS_MAX_DMA_CHANNELS                 (8)
 
+#define LPASS_VARIANT				0
+#define LPASS_VARIANT_V2			1
+
 struct lpass_dai {
 	struct clk *osr_clk;
 	struct clk *bit_clk;
@@ -91,6 +94,9 @@ struct lpass_variant {
 	/* SOC specific clocks configuration */
 	const char **clk_name;
 	int num_clks;
+
+	/* LPASS Version id */
+	int id;
 };
 
 /* register the platform driver from the CPU DAI driver */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 06/11] dt-bindings: sound: Add bindings related to lpass-cpu configuration
  2020-04-11  8:02 [PATCH 00/11] ASoC: QCOM: Add support for SC7180 lpass variant Ajit Pandey
                   ` (4 preceding siblings ...)
  2020-04-11  8:02 ` [PATCH 05/11] ASoC: qcom: lpass: Add support for newer lpass version Ajit Pandey
@ 2020-04-11  8:02 ` Ajit Pandey
  2020-04-11  8:02 ` [PATCH 07/11] Documentation: dt-bindings: sound: Add details for new dai properties Ajit Pandey
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Ajit Pandey @ 2020-04-11  8:02 UTC (permalink / raw)
  To: alsa-devel, broonie, devicetree, plai, bgoswami, srinivas.kandagatla
  Cc: linux-kernel, tiwai, Ajit Pandey

Add header defining dts properties related to lpass cpu MI2S dai's.

Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
---
 include/dt-bindings/sound/qcom,lpass.h | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 include/dt-bindings/sound/qcom,lpass.h

diff --git a/include/dt-bindings/sound/qcom,lpass.h b/include/dt-bindings/sound/qcom,lpass.h
new file mode 100644
index 00000000..4e6c6bc
--- /dev/null
+++ b/include/dt-bindings/sound/qcom,lpass.h
@@ -0,0 +1,31 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * lpass.h -- DT bindings properties related to LPASS MI2S dai's
+ */
+
+#ifndef _DT_BINDINGS_LPASS_H
+#define _DT_BINDINGS_LPASS_H
+
+/* MI2S dai id */
+#define MI2S_PRIMARY	0
+#define MI2S_SECONDARY	1
+#define MI2S_TERTIARY	2
+#define MI2S_QUATERNARY	3
+
+/* MI2S dai's data line mask */
+#define SD0		1
+#define SD1		2
+#define SD2		3
+#define SD3		4
+
+/*MI2S dai' loopback mask */
+#define DISABLE		0
+#define ENABLE		1
+
+/* MI2S dai's wssrc mask */
+#define INTERNAL	0
+#define EXTERNAL	1
+
+#endif /* __DT_BINDINGS_LPASS_H__ */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 07/11] Documentation: dt-bindings: sound: Add details for new dai properties
  2020-04-11  8:02 [PATCH 00/11] ASoC: QCOM: Add support for SC7180 lpass variant Ajit Pandey
                   ` (5 preceding siblings ...)
  2020-04-11  8:02 ` [PATCH 06/11] dt-bindings: sound: Add bindings related to lpass-cpu configuration Ajit Pandey
@ 2020-04-11  8:02 ` Ajit Pandey
  2020-04-16  7:56   ` Srinivas Kandagatla
  2020-04-11  8:02 ` [PATCH 08/11] ASoC: qcom : lpass: Add support to configure dai's connection mode Ajit Pandey
                   ` (3 subsequent siblings)
  10 siblings, 1 reply; 21+ messages in thread
From: Ajit Pandey @ 2020-04-11  8:02 UTC (permalink / raw)
  To: alsa-devel, broonie, devicetree, plai, bgoswami, srinivas.kandagatla
  Cc: linux-kernel, tiwai, Ajit Pandey

Add changes related to new sub node defining MI2S dai's properties. Such
properties needs to be configured via board specific dts files.

Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
---
 .../devicetree/bindings/sound/qcom,lpass-cpu.yaml  | 33 ++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
index a87a406..727ec03 100644
--- a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
@@ -16,6 +16,8 @@ description: |
   configure Low-Power Audio Interface(LPAIF) core registers across different
   IP versions.
 
+  See also dt-bindings/sound/qcom,lpass.h.
+
 properties:
   compatible:
     enum:
@@ -69,6 +71,30 @@ properties:
   '#sound-dai-cells':
     const: 1
 
+  dai-name:
+    - description: Each node represents an MI2S dai and conatins dai specific
+        properties that may change with board layout & dai connections.
+    - type: object
+    - properties:
+      id:
+        - description: dai id among one of value defined in header
+        - type: u32
+      qcom,spkmode-mask:
+        - description: mask defining data lines used for speaker
+        - type: u32
+      qcom,micmode-mask:
+        - description: mask defining data lines used for mic
+        - type: u32
+      qcom,wssrc-mask:
+        - description: mask defining word-select source internal/extrnal on dai
+        - type: u32
+      qcom,loopback-mask:
+        - description: mask defining loopback enable/disable on dai
+        - type: u32
+
+      required:
+        - id
+
 required:
   - compatible
   - reg
@@ -101,3 +127,10 @@ examples:
 	#sound-dai-cells = <1>;
 	qcom,adsp = <&adsp>;
 
+        prim-mi2s@0 {
+		id = <MI2S_PRIMARY>;
+		qcom,spkmode-mask = <SD1>;
+		qcom,micmode-mask = <SD0>;
+                qcom,wssrc-mask = <INTERNAL>;
+                qcom,loopback-mask = <DISABLE>;
+	};
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 08/11] ASoC: qcom : lpass: Add support to configure dai's connection mode
  2020-04-11  8:02 [PATCH 00/11] ASoC: QCOM: Add support for SC7180 lpass variant Ajit Pandey
                   ` (6 preceding siblings ...)
  2020-04-11  8:02 ` [PATCH 07/11] Documentation: dt-bindings: sound: Add details for new dai properties Ajit Pandey
@ 2020-04-11  8:02 ` Ajit Pandey
  2020-04-11  8:02 ` [PATCH 09/11] device-tree: bindings: sound: lpass-cpu: Add new compatible soc Ajit Pandey
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 21+ messages in thread
From: Ajit Pandey @ 2020-04-11  8:02 UTC (permalink / raw)
  To: alsa-devel, broonie, devicetree, plai, bgoswami, srinivas.kandagatla
  Cc: linux-kernel, tiwai, Ajit Pandey

Few dai configuration depends on board layout and use cases. Add new
variables in dai_data to configure dai modes based on values defined
in device tree configuration of board.

Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
---
 sound/soc/qcom/lpass-cpu.c | 70 ++++++++++++++++++++++++++++++++++++++++++++--
 sound/soc/qcom/lpass.h     |  6 ++++
 2 files changed, 74 insertions(+), 2 deletions(-)

diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
index 006ba5a..f96338f 100644
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -90,8 +90,9 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
 		return bitwidth;
 	}
 
-	regval = LPAIF_I2SCTL(v, LOOPBACK_DISABLE);
-	regval |= LPAIF_I2SCTL(v, WSSRC_INTERNAL);
+	/* default to Loopback disable & wssrc internal */
+	regval = dai_data->loopback << (LPAIF_I2SCTL(v, LOOPBACK_SHIFT));
+	regval |= dai_data->wssrc << (LPAIF_I2SCTL(v, WSSRC_SHIFT));
 
 	switch (bitwidth) {
 	case 16:
@@ -172,6 +173,28 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
 		return ret;
 	}
 
+	/* Overwrite spk & mic mode bits with device tree value if specified */
+	if (dai_data->spkmode != 0) {
+		regval = dai_data->spkmode << (LPAIF_I2SCTL(v, SPKMODE_SHIFT));
+		ret = regmap_update_bits(drvdata->lpaif_map,
+			LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id),
+			LPAIF_I2SCTL(v, SPKMODE_MASK), regval);
+		if (ret)
+			dev_err(dai->dev, "error writing to i2sctl reg: %d\n",
+				ret);
+	}
+
+
+	if (dai_data->micmode != 0) {
+		regval = dai_data->micmode << (LPAIF_I2SCTL(v, MICMODE_SHIFT));
+		ret = regmap_update_bits(drvdata->lpaif_map,
+			LPAIF_I2SCTL_REG(drvdata->variant, dai->driver->id),
+			LPAIF_I2SCTL(v, MICMODE_MASK), regval);
+		if (ret)
+			dev_err(dai->dev, "error writing to i2sctl reg: %d\n",
+				ret);
+	}
+
 	ret = clk_set_rate(dai_data->bit_clk, rate * bitwidth * 2);
 	if (ret) {
 		dev_err(dai->dev, "error setting mi2s bitclk to %u: %d\n",
@@ -423,6 +446,46 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)
 	.cache_type = REGCACHE_FLAT,
 };
 
+static void of_qcom_parse_dai_data(struct device *dev,
+				    struct lpass_data *drvdata)
+{
+	struct device_node *node;
+	struct lpass_dai *dai;
+	int ret;
+
+	for_each_child_of_node(dev->of_node, node) {
+		int id;
+
+		ret = of_property_read_u32(node, "id", &id);
+		if (ret || id < 0 || id >= LPASS_MAX_MI2S_PORTS) {
+			dev_err(dev, "valid dai id not found:%d\n", ret);
+			continue;
+		}
+
+		dai = drvdata->dai_priv[id];
+		switch (id) {
+		case MI2S_PRIMARY... MI2S_QUATERNARY:
+			 /* MI2S specific properties */
+			ret = of_property_read_u32(node, "qcom,spkmode-mask",
+						   &dai->spkmode);
+
+			ret = of_property_read_u32(node, "qcom,micmode-mask",
+						   &dai->micmode);
+
+			ret = of_property_read_u32(node, "qcom,wssrc-mask",
+						   &dai->wssrc);
+
+			ret = of_property_read_u32(node, "qcom,loopback-mask",
+						   &dai->loopback);
+
+			break;
+		default:
+			dev_err(dev, "valid dai not found:%d\n", id);
+			break;
+		}
+	}
+}
+
 static int lpass_init_dai_clocks(struct device *dev,
 			   struct lpass_data *drvdata)
 {
@@ -501,6 +564,9 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
 						GFP_KERNEL);
 	}
 
+	/* parse dai data from dts */
+	of_qcom_parse_dai_data(dev, drvdata);
+
 	ret = lpass_init_dai_clocks(dev, drvdata);
 	if (ret) {
 		dev_err(&pdev->dev, "error intializing dai clock: %d\n", ret);
diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
index 384f4b8..960ee97 100644
--- a/sound/soc/qcom/lpass.h
+++ b/sound/soc/qcom/lpass.h
@@ -12,6 +12,7 @@
 #include <linux/compiler.h>
 #include <linux/platform_device.h>
 #include <linux/regmap.h>
+#include <dt-bindings/sound/qcom,lpass.h>
 
 #define LPASS_AHBIX_CLOCK_FREQUENCY            131072000
 #define LPASS_MAX_MI2S_PORTS                   (8)
@@ -23,6 +24,11 @@
 struct lpass_dai {
 	struct clk *osr_clk;
 	struct clk *bit_clk;
+
+	uint32_t spkmode;
+	uint32_t micmode;
+	uint32_t wssrc;
+	uint32_t loopback;
 };
 
 /* Both the CPU DAI and platform drivers will access this data */
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 09/11] device-tree: bindings: sound: lpass-cpu: Add new compatible soc
  2020-04-11  8:02 [PATCH 00/11] ASoC: QCOM: Add support for SC7180 lpass variant Ajit Pandey
                   ` (7 preceding siblings ...)
  2020-04-11  8:02 ` [PATCH 08/11] ASoC: qcom : lpass: Add support to configure dai's connection mode Ajit Pandey
@ 2020-04-11  8:02 ` Ajit Pandey
  2020-04-11  8:02 ` [PATCH 10/11] ASoC: qcom: lpass-sc7180: Add platform driver for lpass audio Ajit Pandey
  2020-04-11  8:02 ` [PATCH 11/11] ASoC: qcom: lpass-platform: Replace card->dev with component->dev Ajit Pandey
  10 siblings, 0 replies; 21+ messages in thread
From: Ajit Pandey @ 2020-04-11  8:02 UTC (permalink / raw)
  To: alsa-devel, broonie, devicetree, plai, bgoswami, srinivas.kandagatla
  Cc: linux-kernel, tiwai, Ajit Pandey

SC7180 soc varaints of LPASS uses lpass-cpu node but required few extra
devictree configuration. Update bindings documents with sc7180 compatible
string specific dts properties.

Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
---
 .../devicetree/bindings/sound/qcom,lpass-cpu.yaml  | 25 +++++++++++++++++++++-
 1 file changed, 24 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
index 727ec03..84bd95c 100644
--- a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
+++ b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
@@ -23,6 +23,7 @@ properties:
     enum:
       - qcom,lpass-cpu
       - qcom,apq8016-lpass-cpu
+      - qcom,lpass-cpu-sc7180
 
   reg:
     items:
@@ -68,6 +69,14 @@ properties:
     maxItems: 1
     description: Phandle for the audio DSP node
 
+  iommus:
+    maxItems: 1
+    description: Phandle to apps_smmu node with sid mask
+
+  power-domains:
+    maxItems: 1
+    description: Phandle for power domain node
+
   '#sound-dai-cells':
     const: 1
 
@@ -108,6 +117,17 @@ required:
 optional:
   - qcom,adsp
 
+if:
+  properties:
+    compatible:
+      contains:
+        const: qcom,lpass-cpu-sc7180
+
+then:
+  required:
+    - iommus
+    - power-domains
+
 examples:
   lpass@28100000 {
 	compatible = "qcom,lpass-cpu";
@@ -120,7 +140,10 @@ examples:
 		      "mi2s-bit-clk";
 
 	interrupts = <0 85 1>;
-	interrupt-names = "lpass-irq-lpaif";
+        interrupt-names = "lpass-irq-lpaif";
+
+	iommus = <&apps_smmu 0x1020 0>;
+	power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>;
 
 	reg = <0x28100000 0x10000>;
 	reg-names = "lpass-lpaif";
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 10/11] ASoC: qcom: lpass-sc7180: Add platform driver for lpass audio
  2020-04-11  8:02 [PATCH 00/11] ASoC: QCOM: Add support for SC7180 lpass variant Ajit Pandey
                   ` (8 preceding siblings ...)
  2020-04-11  8:02 ` [PATCH 09/11] device-tree: bindings: sound: lpass-cpu: Add new compatible soc Ajit Pandey
@ 2020-04-11  8:02 ` Ajit Pandey
  2020-04-11  8:02 ` [PATCH 11/11] ASoC: qcom: lpass-platform: Replace card->dev with component->dev Ajit Pandey
  10 siblings, 0 replies; 21+ messages in thread
From: Ajit Pandey @ 2020-04-11  8:02 UTC (permalink / raw)
  To: alsa-devel, broonie, devicetree, plai, bgoswami, srinivas.kandagatla
  Cc: linux-kernel, tiwai, Ajit Pandey

Create a platform driver for configuring sc7180 lpass core I2S and
DMA configuration to support playback & capture to external codecs
connected over primary & secondary MI2S interfaces.

Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
---
 sound/soc/qcom/Kconfig        |   5 ++
 sound/soc/qcom/Makefile       |   2 +
 sound/soc/qcom/lpass-sc7180.c | 192 ++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 199 insertions(+)
 create mode 100644 sound/soc/qcom/lpass-sc7180.c

diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index 6008685..23fd9e6 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -24,6 +24,11 @@ config SND_SOC_LPASS_APQ8016
 	select SND_SOC_LPASS_CPU
 	select SND_SOC_LPASS_PLATFORM
 
+config SND_SOC_LPASS_SC7180
+	tristate
+	select SND_SOC_LPASS_CPU
+	select SND_SOC_LPASS_PLATFORM
+
 config SND_SOC_STORM
 	tristate "ASoC I2S support for Storm boards"
 	depends on SND_SOC_QCOM
diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile
index 41b2c7a..7972c94 100644
--- a/sound/soc/qcom/Makefile
+++ b/sound/soc/qcom/Makefile
@@ -4,11 +4,13 @@ snd-soc-lpass-cpu-objs := lpass-cpu.o
 snd-soc-lpass-platform-objs := lpass-platform.o
 snd-soc-lpass-ipq806x-objs := lpass-ipq806x.o
 snd-soc-lpass-apq8016-objs := lpass-apq8016.o
+snd-soc-lpass-sc7180-objs := lpass-sc7180.o
 
 obj-$(CONFIG_SND_SOC_LPASS_CPU) += snd-soc-lpass-cpu.o
 obj-$(CONFIG_SND_SOC_LPASS_PLATFORM) += snd-soc-lpass-platform.o
 obj-$(CONFIG_SND_SOC_LPASS_IPQ806X) += snd-soc-lpass-ipq806x.o
 obj-$(CONFIG_SND_SOC_LPASS_APQ8016) += snd-soc-lpass-apq8016.o
+obj-$(CONFIG_SND_SOC_LPASS_SC7180) += snd-soc-lpass-sc7180.o
 
 # Machine
 snd-soc-storm-objs := storm.o
diff --git a/sound/soc/qcom/lpass-sc7180.c b/sound/soc/qcom/lpass-sc7180.c
new file mode 100644
index 00000000..879f3a5
--- /dev/null
+++ b/sound/soc/qcom/lpass-sc7180.c
@@ -0,0 +1,192 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020, The Linux Foundation. All rights reserved.
+ *
+ * lpass-sc7180.c -- ALSA SoC platform-machine driver for QTi LPASS
+ */
+
+#include <linux/clk.h>
+#include <linux/device.h>
+#include <linux/err.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <sound/pcm.h>
+#include <sound/soc.h>
+
+#include "lpass-lpaif-reg.h"
+#include "lpass.h"
+
+static struct snd_soc_dai_driver sc7180_lpass_cpu_dai_driver[] = {
+	[MI2S_PRIMARY] = {
+		.id = MI2S_PRIMARY,
+		.name = "Primary MI2S",
+		.playback = {
+			.stream_name = "Primary Playback",
+			.formats	= SNDRV_PCM_FMTBIT_S16,
+			.rates = SNDRV_PCM_RATE_48000,
+			.rate_min	= 48000,
+			.rate_max	= 48000,
+			.channels_min	= 2,
+			.channels_max	= 2,
+		},
+		.capture = {
+			.stream_name = "Primary Capture",
+			.formats = SNDRV_PCM_FMTBIT_S16,
+			.rates = SNDRV_PCM_RATE_48000,
+			.rate_min	= 48000,
+			.rate_max	= 48000,
+			.channels_min	= 2,
+			.channels_max	= 2,
+		},
+		.probe	= &asoc_qcom_lpass_cpu_dai_probe,
+		.ops    = &asoc_qcom_lpass_cpu_dai_ops,
+	},
+
+	[MI2S_SECONDARY] = {
+		.id = MI2S_SECONDARY,
+		.name = "Secondary MI2S",
+		.playback = {
+			.stream_name = "Secondary Playback",
+			.formats	= SNDRV_PCM_FMTBIT_S16,
+			.rates = SNDRV_PCM_RATE_48000,
+			.rate_min	= 48000,
+			.rate_max	= 48000,
+			.channels_min	= 2,
+			.channels_max	= 2,
+		},
+		.probe	= &asoc_qcom_lpass_cpu_dai_probe,
+		.ops    = &asoc_qcom_lpass_cpu_dai_ops,
+	},
+};
+
+static int sc7180_lpass_alloc_dma_channel(struct lpass_data *drvdata,
+					   int direction)
+{
+	struct lpass_variant *v = drvdata->variant;
+	int chan = 0;
+
+	if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
+		chan = find_first_zero_bit(&drvdata->dma_ch_bit_map,
+					v->rdma_channels);
+
+		if (chan >= v->rdma_channels)
+			return -EBUSY;
+	} else {
+		chan = find_next_zero_bit(&drvdata->dma_ch_bit_map,
+					v->wrdma_channel_start +
+					v->wrdma_channels,
+					v->wrdma_channel_start);
+
+		if (chan >=  v->wrdma_channel_start + v->wrdma_channels)
+			return -EBUSY;
+	}
+
+	set_bit(chan, &drvdata->dma_ch_bit_map);
+
+	return chan;
+}
+
+static int sc7180_lpass_free_dma_channel(struct lpass_data *drvdata, int chan)
+{
+	clear_bit(chan, &drvdata->dma_ch_bit_map);
+
+	return 0;
+}
+
+static int sc7180_lpass_init(struct platform_device *pdev)
+{
+	struct lpass_data *drvdata = platform_get_drvdata(pdev);
+	struct lpass_variant *variant = drvdata->variant;
+	struct device *dev = &pdev->dev;
+	int ret, i;
+
+	drvdata->clks = devm_kcalloc(dev, variant->num_clks,
+				     sizeof(*drvdata->clks), GFP_KERNEL);
+	drvdata->num_clks = variant->num_clks;
+
+	for (i = 0; i < drvdata->num_clks; i++)
+		drvdata->clks[i].id = variant->clk_name[i];
+
+	ret = devm_clk_bulk_get(dev, drvdata->num_clks, drvdata->clks);
+	if (ret) {
+		dev_err(dev, "Failed to get clocks %d\n", ret);
+		return ret;
+	}
+
+	ret = clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks);
+	if (ret) {
+		dev_err(dev, "sc7180 clk_enable failed\n");
+		return ret;
+	}
+
+	return 0;
+}
+
+static int sc7180_lpass_exit(struct platform_device *pdev)
+{
+	struct lpass_data *drvdata = platform_get_drvdata(pdev);
+
+	clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks);
+
+	return 0;
+}
+
+static struct lpass_variant sc7180_data = {
+	.i2sctrl_reg_base	= 0x1000,
+	.i2sctrl_reg_stride	= 0x1000,
+	.i2s_ports		= 3,
+	.irq_reg_base		= 0x9000,
+	.irq_reg_stride		= 0x1000,
+	.irq_ports		= 3,
+	.rdma_reg_base		= 0xC000,
+	.rdma_reg_stride	= 0x1000,
+	.rdma_channels		= 5,
+	.dmactl_audif_start	= 1,
+	.wrdma_reg_base		= 0x18000,
+	.wrdma_reg_stride	= 0x1000,
+	.wrdma_channel_start	= 5,
+	.wrdma_channels		= 4,
+	.id			= LPASS_VARIANT_V2,
+	.clk_name		= (const char*[]) {
+				   "noc",
+				   "audio-core",
+				   "sysnoc_mport",
+				},
+	.num_clks		= 3,
+	.dai_driver		= sc7180_lpass_cpu_dai_driver,
+	.num_dai		= ARRAY_SIZE(sc7180_lpass_cpu_dai_driver),
+	.dai_osr_clk_names      = (const char *[]) {
+				   "mclk0",
+				   "null",
+				},
+	.dai_bit_clk_names      = (const char *[]) {
+				   "pri_ibit",
+				   "sec_ibit",
+				},
+	.init			= sc7180_lpass_init,
+	.exit			= sc7180_lpass_exit,
+	.alloc_dma_channel	= sc7180_lpass_alloc_dma_channel,
+	.free_dma_channel	= sc7180_lpass_free_dma_channel,
+
+};
+
+static const struct of_device_id sc7180_lpass_cpu_device_id[] = {
+	{.compatible = "qcom,lpass-cpu-sc7180", .data = &sc7180_data},
+	{}
+};
+
+static struct platform_driver sc7180_lpass_cpu_platform_driver = {
+	.driver = {
+		.name = "sc7180-lpass-cpu",
+		.of_match_table = of_match_ptr(sc7180_lpass_cpu_device_id),
+	},
+	.probe = asoc_qcom_lpass_cpu_platform_probe,
+	.remove = asoc_qcom_lpass_cpu_platform_probe,
+};
+
+module_platform_driver(sc7180_lpass_cpu_platform_driver);
+
+MODULE_DESCRIPTION("SC7180 LPASS CPU DRIVER");
+MODULE_LICENSE("GPL v2");
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 11/11] ASoC: qcom: lpass-platform: Replace card->dev with component->dev
  2020-04-11  8:02 [PATCH 00/11] ASoC: QCOM: Add support for SC7180 lpass variant Ajit Pandey
                   ` (9 preceding siblings ...)
  2020-04-11  8:02 ` [PATCH 10/11] ASoC: qcom: lpass-sc7180: Add platform driver for lpass audio Ajit Pandey
@ 2020-04-11  8:02 ` Ajit Pandey
  2020-04-16  7:56   ` Srinivas Kandagatla
  10 siblings, 1 reply; 21+ messages in thread
From: Ajit Pandey @ 2020-04-11  8:02 UTC (permalink / raw)
  To: alsa-devel, broonie, devicetree, plai, bgoswami, srinivas.kandagatla
  Cc: linux-kernel, tiwai, Ajit Pandey

We are allocating dma memory for component->dev but trying to mmap
such memory for substream->pcm->card->dev. Replace device argument
in mmap with component->dev to fix this.

Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
---
 sound/soc/qcom/lpass-platform.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c
index 821599e..9ab2dd5 100644
--- a/sound/soc/qcom/lpass-platform.c
+++ b/sound/soc/qcom/lpass-platform.c
@@ -401,9 +401,8 @@ static int lpass_platform_pcmops_mmap(struct snd_soc_component *component,
 {
 	struct snd_pcm_runtime *runtime = substream->runtime;
 
-	return dma_mmap_coherent(substream->pcm->card->dev, vma,
-			runtime->dma_area, runtime->dma_addr,
-			runtime->dma_bytes);
+	return dma_mmap_coherent(component->dev, vma, runtime->dma_area,
+				 runtime->dma_addr, runtime->dma_bytes);
 }
 
 static irqreturn_t lpass_dma_interrupt_handler(
-- 
1.9.1

^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 01/11] Documentation: device-tree: sound: Update lpass-cpu driver binding
  2020-04-11  8:02 ` [PATCH 01/11] Documentation: device-tree: sound: Update lpass-cpu driver binding Ajit Pandey
@ 2020-04-16  7:53   ` Srinivas Kandagatla
  2020-04-25 14:05     ` Ajit Pandey
  0 siblings, 1 reply; 21+ messages in thread
From: Srinivas Kandagatla @ 2020-04-16  7:53 UTC (permalink / raw)
  To: Ajit Pandey, alsa-devel, broonie, devicetree, plai, bgoswami
  Cc: linux-kernel, tiwai



On 11/04/2020 09:02, Ajit Pandey wrote:
> Done the required cleanups to update lpass-cpu binding with newer
> yaml formats.
> 
> Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>


> ---
>   .../devicetree/bindings/sound/qcom,lpass-cpu.txt   | 158 ---------------------
>   .../devicetree/bindings/sound/qcom,lpass-cpu.yaml  | 103 ++++++++++++++
>   2 files changed, 103 insertions(+), 158 deletions(-)
>   delete mode 100644 Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt
>   create mode 100644 Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
> 
> diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt
> deleted file mode 100644
> index a49b878..00000000
> --- a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt
> +++ /dev/null
> @@ -1,158 +0,0 @@
> -* Qualcomm Technologies LPASS CPU DAI binding
> -
> -Low-Power Audio SubSystem (LPASS) consist of MI2S interfaces for audio data
> -transfer on external codec. LPASS cpu driver is a common code to configure
> -MI2S related CPU dai's across different version of LPASS architecture.
> -
> -- compatible:
> -	Usage: required
> -	Value type: <stringlist>
> -	Definition: compatible string corresponds to lpass variants driver
> -		    must be "qcom, lpass-cpu-sc7180" for sc7180 lpass
This patch will not apply on mainline, looks like this was done on top 
of your local repo, please fix this!

Best thing would be rebase patches top of 
https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git/log/?h=for-next

Secondly, Split this patch into two,
1> converting in to yaml
2> adding new changes
so that it will be easy to see what exactly changed.

thanks,
srini

> -		    must be "qcom,apq8016-lpass-cpu" for apq8016 lpass
> -- reg:
> -	Usage: required
> -	Value type: <prop-encoded-array>
> -	Definition: must specify the base address and size of the LPAIF CORE
> -		    region of lpass variant.
> -- reg-names:
> -	Usage: required
> -	Value type: <stringlist>
> -	Definition: must be "lpass-lpaif"
> -
> -- iommus:
> -        Usage: required for "qcom, lpass-cpu-sc7180" compatible string
> -        Value type: <prop-encoded-array>
> -        Definition: sid mask for lpaif memory region to apps_smmu
> -                    must be <&apps_smmu 0x1020 0>
> -
> -- power-domains:
> -	Usage: required for "qcom, lpass-cpu-sc7180" compatible string
> -	Value type: <phandle>
> -	Definition: reference to power-domains
> -		    must be <&lpass_hm LPASS_CORE_HM_GDSCR>
> -
> -- clocks:
> -        Usage: required
> -	Value type: <phandle>
> -	Definition: reference to the clocks that match clock-names
> -
> -- clock-names:
> -	Usage: required
> -	Value type: <stringlist>
> -	Definition: The clocks needed depend on the compatible string:
> -	qcom,lpass-cpu-apq8016:
> -		must be "ahbix-clk", "mi2s-osr-clk", "mi2s-bit-clk0",
> -		mi2s-bit-clk1", "mi2s-bit-clk2", "mi2s-bit-clk3",
> -		"pcnoc-mport-clk", "pcnoc-sway-clk"
> -	qcom, lpass-cpu-sc7180:
> -		must be "noc", "audio-core", "mclk0", "sysnoc_mport",
> -		"pri_ibit", "sec_ibit"
> -
> -- #sound-dai-cells
> -	Usage: required
> -	Value type: <u32>
> -	Definition: Must be 1
> -
> -- interrupts:
> -	Usage: required
> -	Value type: <prop-encoded-array>
> -	Definition: reference to the interrupts that match interrupt-names
> -
> -- interrupt-names:
> -	Usage: required
> -	Value type: <stringlist>
> -	Definition: must be "lpass-irq-lpaif"
> -
> -- qcom,adsp:
> -        Usage: optional
> -        Value type: <phandle>
> -	Definition: Phandle for the audio DSP node
> -
> -= MI2S DAIs (Digial Audio Interface)
> -"dais" child node of the lpass node. It represents mi2s dais, each mi2s dai is
> -subnode of "dais" representing board specific dai setup & required dai clocks.
> -"dais" node should have following properties.
> -
> -- id:
> -	Usage: required for mi2s interface
> -	Value type: <u32>
> -	Definition: Must be dai id defined in lpass bindings like MI2S_PRIMARY
> -
> -- qcom,bitclk-name:
> -	Usage: required for mi2s interface
> -	Value type: <stringlist>
> -	Definition: bitclk name corresponds to MI2S of lpass version
> -
> -- qcom,mclk-name:
> -        Usage: optional for mi2s interface
> -        Value type: <stringlist>
> -        Definition: external mclk name corresponds to MI2S of lpass version
> -
> -- qcom,osrclk-name:
> -        Usage: optional for mi2s interface
> -        Value type: <stringlist>
> -        Definition: osrclk name corresponds to MI2S of lpass version
> -
> -- qcom,spkmode-mask:
> -        Usage: optional for mi2s interface
> -        Value type: <u32>
> -        Definition: board specific property to change default spkmode mask
> -                    of MI2S dai based on dataline connection on board.
> -
> -- qcom,micmode-mask:
> -        Usage: optional for mi2s interface
> -        Value type: <u32>
> -        Definition: board specific property to change default micmode mask
> -                    of MI2S dai based on dataline connection on board.
> -
> -- qcom,loopback-mask:
> -        Usage: optional for mi2s interface
> -        Value type: <u32>
> -        Definition: board specific property to change default loopback mask
> -                    of MI2S dai as per requirement.
> -
> -- qcom,wssrc-mask:
> -        Usage: optional for mi2s interface
> -        Value type: <u32>
> -        Definition: board specific property to change default wssrc mask
> -                    of MI2S dai based as per requirement.
> -
> -Example:
> -
> -lpass_cpu: lpass {
> -	compatible = "qcom, lpass-cpu-sc7180";
> -
> -	reg = <0 0x62F00000 0 0x29000>;
> -	reg-names = "lpass-lpaif";
> -
> -	iommus = <&apps_smmu 0x1020 0>;
> -
> -	power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>;
> -
> -	clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>,
> -		 <&lpasscorecc LPASS_AUDIO_CORE_CORE_CLK>,
> -		 <&lpasscorecc LPASS_AUDIO_CORE_EXT_MCLK0_CLK>,
> -		 <&lpasscorecc LPASS_AUDIO_CORE_SYSNOC_MPORT_CORE_CLK>,
> -		 <&lpasscorecc LPASS_AUDIO_CORE_LPAIF_PRI_IBIT_CLK>,
> -		 <&lpasscorecc LPASS_AUDIO_CORE_LPAIF_SEC_IBIT_CLK>;
> -
> -	clock-names = "noc", "audio-core", "mclk0", "sysnoc_mport",
> -		      "pri_ibit", "sec_ibit";
> -
> -	#sound-dai-cells = <1>;
> -
> -	interrupts = <0 160 IRQ_TYPE_LEVEL_HIGH>;
> -	interrupt-names = "lpass-irq-lpaif";
> -
> -	prim-mi2s@0 {
> -		id = <MI2S_PRIMARY>;
> -		qcom,bitclk-name = "pri_ibit";
> -		qcom,mclk-name = "mclk0";
> -	};
> -
> -	sec-mi2s@1 {
> -		id = <MI2S_SECONDARY>;
> -		qcom,bitclk-name = "sec_ibit";
> -	};
> -};
> diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
> new file mode 100644
> index 00000000..a87a406
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
> @@ -0,0 +1,103 @@
> +# SPDX-License-Identifier: GPL-2.0-only
> +%YAML 1.2
> +---
> +$id: http://devicetree.org/schemas/sound/qcom,lpass-cpu.yaml#
> +$schema: http://devicetree.org/meta-schemas/core.yaml#
> +
> +title: Qualcomm LPASS CPU dai driver bindings
> +
> +maintainers:
> +  - Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
> +  - Ajit Pandey <ajitp@codeaurora.org>
> +
> +description: |
> +  Qualcomm SOC Low-Power Audio SubSystem (LPASS) that consist of MI2S interface
> +  for audio data transfer on external codecs. LPASS cpu driver is a module to
> +  configure Low-Power Audio Interface(LPAIF) core registers across different
> +  IP versions.
> +
> +properties:
> +  compatible:
> +    enum:
> +      - qcom,lpass-cpu
> +      - qcom,apq8016-lpass-cpu
> +
> +  reg:
> +    items:
> +      - description: LPAIF core registers
> +
> +  reg-names:
> +    items:
> +      - const: lpass-lpaif
> +
> +  clocks:
> +    items:
> +      - description: AHBIX core clock for IPQ806X
> +      - description: oscillator clock for MI2S external interfaces
> +      - description: Bit clock for single MI2S dai in IPQ806X
> +      - description: Bit clock for MI2S_PRIMARY dai interface
> +      - description: Bit clock for MI2S_SECONDARY dai interface
> +      - description: Bit clock for MI2S_TERTIARY dai interface
> +      - description: Bit clock for MI2S_QUATERNARY dai interface
> +      - description: NOC MPORT clock of LPASS core
> +      - description: NOC SWAY clock of LPASS core
> +
> +  clock-names:
> +    items:
> +      - const: ahbix-clk
> +      - const: mi2s-osr-clk
> +      - const: mi2s-bit-clk
> +      - const: mi2s-bit-clk0
> +      - const: mi2s-bit-clk1
> +      - const: mi2s-bit-clk2
> +      - const: mi2s-bit-clk3
> +      - const: pcnoc-mport-clk
> +      - const: pcnoc-sway-clk
> +
> +  interrupts:
> +    items:
> +      - description: LPAIF DMA buffer interrupt
> +
> +  interrupt-names:
> +    items:
> +      - const: lpass-irq-lpaif
> +
> +  qcom,adsp:
> +    maxItems: 1
> +    description: Phandle for the audio DSP node
> +
> +  '#sound-dai-cells':
> +    const: 1
> +
> +required:
> +  - compatible
> +  - reg
> +  - reg-names
> +  - clocks
> +  - clock-names
> +  - interrupts
> +  - interrupt-names
> +  - sound-dai-cells
> +
> +optional:
> +  - qcom,adsp
> +
> +examples:
> +  lpass@28100000 {
> +	compatible = "qcom,lpass-cpu";
> +	clocks = <&lcc AHBIX_CLK>,
> +		 <&lcc MI2S_OSR_CLK>,
> +		 <&lcc MI2S_BIT_CLK>;
> +
> +	clock-names = "ahbix-clk",
> +		      "mi2s-osr-clk",
> +		      "mi2s-bit-clk";
> +
> +	interrupts = <0 85 1>;
> +	interrupt-names = "lpass-irq-lpaif";
> +
> +	reg = <0x28100000 0x10000>;
> +	reg-names = "lpass-lpaif";
> +	#sound-dai-cells = <1>;
> +	qcom,adsp = <&adsp>;
> +
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 11/11] ASoC: qcom: lpass-platform: Replace card->dev with component->dev
  2020-04-11  8:02 ` [PATCH 11/11] ASoC: qcom: lpass-platform: Replace card->dev with component->dev Ajit Pandey
@ 2020-04-16  7:56   ` Srinivas Kandagatla
  0 siblings, 0 replies; 21+ messages in thread
From: Srinivas Kandagatla @ 2020-04-16  7:56 UTC (permalink / raw)
  To: Ajit Pandey, alsa-devel, broonie, devicetree, plai, bgoswami
  Cc: linux-kernel, tiwai



On 11/04/2020 09:02, Ajit Pandey wrote:
> We are allocating dma memory for component->dev but trying to mmap
> such memory for substream->pcm->card->dev. Replace device argument
> in mmap with component->dev to fix this.
> 
> Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>

Probably a fixes tag here,

Fixes: c5c8635a0471("ASoC: qcom: Add LPASS platform driver")

Reviewed-by: Srinivas Kandagatla <srinivas.kandagatla@linaro.org>

> ---
>   sound/soc/qcom/lpass-platform.c | 5 ++---
>   1 file changed, 2 insertions(+), 3 deletions(-)
> 
> diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c
> index 821599e..9ab2dd5 100644
> --- a/sound/soc/qcom/lpass-platform.c
> +++ b/sound/soc/qcom/lpass-platform.c
> @@ -401,9 +401,8 @@ static int lpass_platform_pcmops_mmap(struct snd_soc_component *component,
>   {
>   	struct snd_pcm_runtime *runtime = substream->runtime;
>   
> -	return dma_mmap_coherent(substream->pcm->card->dev, vma,
> -			runtime->dma_area, runtime->dma_addr,
> -			runtime->dma_bytes);
> +	return dma_mmap_coherent(component->dev, vma, runtime->dma_area,
> +				 runtime->dma_addr, runtime->dma_bytes);
>   }
>   
>   static irqreturn_t lpass_dma_interrupt_handler(
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 02/11] ASoC: qcom: lpass: Add struct lpass_dai to store dai clocks pointer
  2020-04-11  8:02 ` [PATCH 02/11] ASoC: qcom: lpass: Add struct lpass_dai to store dai clocks pointer Ajit Pandey
@ 2020-04-16  7:56   ` Srinivas Kandagatla
  2020-04-25 14:11     ` Ajit Pandey
  0 siblings, 1 reply; 21+ messages in thread
From: Srinivas Kandagatla @ 2020-04-16  7:56 UTC (permalink / raw)
  To: Ajit Pandey, alsa-devel, broonie, devicetree, plai, bgoswami
  Cc: linux-kernel, tiwai



On 11/04/2020 09:02, Ajit Pandey wrote:
> lpass_dai will store clocks related to respective dai's and it will
> be initialized during probe based on variant clock names.
> 
> Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>

I dont understand why do we need this change? What is the advantage of 
doing this way vs the existing one?


--srini

> ---
>   sound/soc/qcom/lpass-cpu.c | 89 ++++++++++++++++++++++++++--------------------
>   sound/soc/qcom/lpass.h     | 18 +++++-----
>   2 files changed, 61 insertions(+), 46 deletions(-)
> 
> diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
> index dbce7e9..492f27b 100644
> --- a/sound/soc/qcom/lpass-cpu.c
> +++ b/sound/soc/qcom/lpass-cpu.c
> @@ -23,13 +23,15 @@ static int lpass_cpu_daiops_set_sysclk(struct snd_soc_dai *dai, int clk_id,
>   		unsigned int freq, int dir)
>   {
>   	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
> -	int ret;
> -
> -	ret = clk_set_rate(drvdata->mi2s_osr_clk[dai->driver->id], freq);
> -	if (ret)
> -		dev_err(dai->dev, "error setting mi2s osrclk to %u: %d\n",
> -			freq, ret);
> +	struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id];
> +	int ret = 0;
>   
> +	if (dai_data->osr_clk != NULL) {
> +		ret = clk_set_rate(dai_data->osr_clk, freq);
> +		if (ret)
> +			dev_err(dai->dev, "error setting mi2s osrclk to %u:%d\n",
> +				freq, ret);
> +	}
>   	return ret;
>   }
>   
> @@ -37,18 +39,22 @@ static int lpass_cpu_daiops_startup(struct snd_pcm_substream *substream,
>   		struct snd_soc_dai *dai)
>   {
>   	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
> +	struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id];
>   	int ret;
>   
> -	ret = clk_prepare_enable(drvdata->mi2s_osr_clk[dai->driver->id]);
> -	if (ret) {
> -		dev_err(dai->dev, "error in enabling mi2s osr clk: %d\n", ret);
> -		return ret;
> +	if (dai_data->osr_clk != NULL) {
> +		ret = clk_prepare_enable(dai_data->osr_clk);
> +		if (ret) {
> +			dev_err(dai->dev,
> +				"error in enabling mi2s osr clk: %d\n", ret);
> +			return ret;
> +		}
>   	}
>   
> -	ret = clk_prepare_enable(drvdata->mi2s_bit_clk[dai->driver->id]);
> +	ret = clk_prepare_enable(dai_data->bit_clk);
>   	if (ret) {
>   		dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", ret);
> -		clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]);
> +		clk_disable_unprepare(dai_data->osr_clk);
>   		return ret;
>   	}
>   
> @@ -59,16 +65,18 @@ static void lpass_cpu_daiops_shutdown(struct snd_pcm_substream *substream,
>   		struct snd_soc_dai *dai)
>   {
>   	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
> +	struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id];
>   
> -	clk_disable_unprepare(drvdata->mi2s_bit_clk[dai->driver->id]);
> +	clk_disable_unprepare(dai_data->bit_clk);
>   
> -	clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]);
> +	clk_disable_unprepare(dai_data->osr_clk);
>   }
>   
>   static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
>   		struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
>   {
>   	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
> +	struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id];
>   	snd_pcm_format_t format = params_format(params);
>   	unsigned int channels = params_channels(params);
>   	unsigned int rate = params_rate(params);
> @@ -163,8 +171,7 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
>   		return ret;
>   	}
>   
> -	ret = clk_set_rate(drvdata->mi2s_bit_clk[dai->driver->id],
> -			   rate * bitwidth * 2);
> +	ret = clk_set_rate(dai_data->bit_clk, rate * bitwidth * 2);
>   	if (ret) {
>   		dev_err(dai->dev, "error setting mi2s bitclk to %u: %d\n",
>   			rate * bitwidth * 2, ret);
> @@ -413,6 +420,25 @@ static bool lpass_cpu_regmap_volatile(struct device *dev, unsigned int reg)
>   	.cache_type = REGCACHE_FLAT,
>   };
>   
> +static int lpass_init_dai_clocks(struct device *dev,
> +			   struct lpass_data *drvdata)
> +{
> +	struct lpass_dai *dai;
> +	struct lpass_variant *v = drvdata->variant;
> +	int i;
> +
> +	for (i = 0; i < v->num_dai; i++) {
> +
> +		dai = drvdata->dai_priv[i];
> +
> +		dai->osr_clk = devm_clk_get_optional(dev,
> +						     v->dai_osr_clk_names[i]);
> +		dai->bit_clk = devm_clk_get(dev, v->dai_bit_clk_names[i]);
> +	}
> +
> +	return 0;
> +}
> +
>   int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
>   {
>   	struct lpass_data *drvdata;
> @@ -421,7 +447,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
>   	struct lpass_variant *variant;
>   	struct device *dev = &pdev->dev;
>   	const struct of_device_id *match;
> -	int ret, i, dai_id;
> +	int ret, i;
>   
>   	dsp_of_node = of_parse_phandle(pdev->dev.of_node, "qcom,adsp", 0);
>   	if (dsp_of_node) {
> @@ -467,28 +493,15 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
>   		variant->init(pdev);
>   
>   	for (i = 0; i < variant->num_dai; i++) {
> -		dai_id = variant->dai_driver[i].id;
> -		drvdata->mi2s_osr_clk[dai_id] = devm_clk_get(&pdev->dev,
> -					     variant->dai_osr_clk_names[i]);
> -		if (IS_ERR(drvdata->mi2s_osr_clk[dai_id])) {
> -			dev_warn(&pdev->dev,
> -				"%s() error getting optional %s: %ld\n",
> -				__func__,
> -				variant->dai_osr_clk_names[i],
> -				PTR_ERR(drvdata->mi2s_osr_clk[dai_id]));
> -
> -			drvdata->mi2s_osr_clk[dai_id] = NULL;
> -		}
> +		drvdata->dai_priv[i] = devm_kzalloc(dev,
> +						sizeof(struct lpass_dai),
> +						GFP_KERNEL);
> +	}
>   
> -		drvdata->mi2s_bit_clk[dai_id] = devm_clk_get(&pdev->dev,
> -						variant->dai_bit_clk_names[i]);
> -		if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) {
> -			dev_err(&pdev->dev,
> -				"error getting %s: %ld\n",
> -				variant->dai_bit_clk_names[i],
> -				PTR_ERR(drvdata->mi2s_bit_clk[dai_id]));
> -			return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]);
> -		}
> +	ret = lpass_init_dai_clocks(dev, drvdata);
> +	if (ret) {
> +		dev_err(&pdev->dev, "error intializing dai clock: %d\n", ret);
> +		return ret;
>   	}
>   
>   	drvdata->ahbix_clk = devm_clk_get(&pdev->dev, "ahbix-clk");
> diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
> index 17113d3..b729686 100644
> --- a/sound/soc/qcom/lpass.h
> +++ b/sound/soc/qcom/lpass.h
> @@ -13,9 +13,14 @@
>   #include <linux/platform_device.h>
>   #include <linux/regmap.h>
>   
> -#define LPASS_AHBIX_CLOCK_FREQUENCY		131072000
> -#define LPASS_MAX_MI2S_PORTS			(8)
> -#define LPASS_MAX_DMA_CHANNELS			(8)
> +#define LPASS_AHBIX_CLOCK_FREQUENCY            131072000
> +#define LPASS_MAX_MI2S_PORTS                   (8)
> +#define LPASS_MAX_DMA_CHANNELS                 (8)
> +
> +struct lpass_dai {
> +	struct clk *osr_clk;
> +	struct clk *bit_clk;
> +};
>   
>   /* Both the CPU DAI and platform drivers will access this data */
>   struct lpass_data {
> @@ -23,11 +28,8 @@ struct lpass_data {
>   	/* AHB-I/X bus clocks inside the low-power audio subsystem (LPASS) */
>   	struct clk *ahbix_clk;
>   
> -	/* MI2S system clock */
> -	struct clk *mi2s_osr_clk[LPASS_MAX_MI2S_PORTS];
> -
> -	/* MI2S bit clock (derived from system clock by a divider */
> -	struct clk *mi2s_bit_clk[LPASS_MAX_MI2S_PORTS];
> +	/* MI2S dai specific configuration */
> +	struct lpass_dai *dai_priv[LPASS_MAX_MI2S_PORTS];
>   
>   	/* low-power audio interface (LPAIF) registers */
>   	void __iomem *lpaif;
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 04/11] ASoC: qcom: lpass-cpu: Make "ahbix-clk" an optional clock.
  2020-04-11  8:02 ` [PATCH 04/11] ASoC: qcom: lpass-cpu: Make "ahbix-clk" an optional clock Ajit Pandey
@ 2020-04-16  7:56   ` Srinivas Kandagatla
  0 siblings, 0 replies; 21+ messages in thread
From: Srinivas Kandagatla @ 2020-04-16  7:56 UTC (permalink / raw)
  To: Ajit Pandey, alsa-devel, broonie, devicetree, plai, bgoswami
  Cc: linux-kernel, tiwai



On 11/04/2020 09:02, Ajit Pandey wrote:
> AHB-I/X bus clocks inside LPASS coreis not a mandatory clocks for
s/coreis/core is/
> newer lpass variants, hence make it an optional one.
> 

Can you add more detail on which version of IP would not have this clk.

> Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
> ---
>   sound/soc/qcom/lpass-cpu.c | 31 ++++++++++++++++++-------------
>   1 file changed, 18 insertions(+), 13 deletions(-)
> 
> diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
> index 492f27b..f177932 100644
> --- a/sound/soc/qcom/lpass-cpu.c
> +++ b/sound/soc/qcom/lpass-cpu.c
> @@ -504,26 +504,31 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
>   		return ret;
>   	}
>   
> -	drvdata->ahbix_clk = devm_clk_get(&pdev->dev, "ahbix-clk");
> +	drvdata->ahbix_clk = devm_clk_get_optional(&pdev->dev, "ahbix-clk");
>   	if (IS_ERR(drvdata->ahbix_clk)) {
>   		dev_err(&pdev->dev, "error getting ahbix-clk: %ld\n",
>   			PTR_ERR(drvdata->ahbix_clk));
>   		return PTR_ERR(drvdata->ahbix_clk);
>   	}
>   
> -	ret = clk_set_rate(drvdata->ahbix_clk, LPASS_AHBIX_CLOCK_FREQUENCY);
> -	if (ret) {
> -		dev_err(&pdev->dev, "error setting rate on ahbix_clk: %d\n",
> -			ret);
> -		return ret;
> -	}
> -	dev_dbg(&pdev->dev, "set ahbix_clk rate to %lu\n",
> -		clk_get_rate(drvdata->ahbix_clk));
> +	if (drvdata->ahbix_clk != NULL) {

No need for NULL checks here, clk apis already have checks.

--srini

> +		ret = clk_set_rate(drvdata->ahbix_clk,
> +				   LPASS_AHBIX_CLOCK_FREQUENCY);
> +		if (ret) {
> +			dev_err(&pdev->dev,
> +				"error setting rate on ahbix_clk: %d\n", ret);
> +			return ret;
> +		}
>   
> -	ret = clk_prepare_enable(drvdata->ahbix_clk);
> -	if (ret) {
> -		dev_err(&pdev->dev, "error enabling ahbix_clk: %d\n", ret);
> -		return ret;
> +		dev_dbg(&pdev->dev, "set ahbix_clk rate to %lu\n",
> +			clk_get_rate(drvdata->ahbix_clk));
> +
> +		ret = clk_prepare_enable(drvdata->ahbix_clk);
> +		if (ret) {
> +			dev_err(&pdev->dev,
> +				"error enabling ahbix_clk: %d\n", ret);
> +			return ret;
> +		}
>   	}
>   
>   	ret = devm_snd_soc_register_component(&pdev->dev,
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 05/11] ASoC: qcom: lpass: Add support for newer lpass version
  2020-04-11  8:02 ` [PATCH 05/11] ASoC: qcom: lpass: Add support for newer lpass version Ajit Pandey
@ 2020-04-16  7:56   ` Srinivas Kandagatla
  2020-04-25 14:14     ` Ajit Pandey
  0 siblings, 1 reply; 21+ messages in thread
From: Srinivas Kandagatla @ 2020-04-16  7:56 UTC (permalink / raw)
  To: Ajit Pandey, alsa-devel, broonie, devicetree, plai, bgoswami
  Cc: linux-kernel, tiwai



On 11/04/2020 09:02, Ajit Pandey wrote:
> Few control registers bit offset of lpaif in newer lpass variants
> are changed. Added "id" field in variant struct and changes macros
> configuration of registers to calculate bit mask & offset based on
> variant id.
> 

These fields are handled much nicely with regmap_field, you should 
consider using that. If not we will add overhead of check for every mask.


> Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
> ---
>   sound/soc/qcom/lpass-cpu.c       |  77 +++++++++--------
>   sound/soc/qcom/lpass-lpaif-reg.h | 182 ++++++++++++++++++++++++++++++++++++++-
>   sound/soc/qcom/lpass-platform.c  |  31 +++----
>   sound/soc/qcom/lpass.h           |   6 ++
>   4 files changed, 241 insertions(+), 55 deletions(-)
> 
> diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
> index f177932..006ba5a 100644
> --- a/sound/soc/qcom/lpass-cpu.c
> +++ b/sound/soc/qcom/lpass-cpu.c
> @@ -77,6 +77,7 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
>   {
>   	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
>   	struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id];
> +	struct lpass_variant *v = drvdata->variant;
>   	snd_pcm_format_t format = params_format(params);
>   	unsigned int channels = params_channels(params);
>   	unsigned int rate = params_rate(params);
> @@ -89,18 +90,18 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
>   		return bitwidth;
>   	}
>   
> -	regval = LPAIF_I2SCTL_LOOPBACK_DISABLE |
> -			LPAIF_I2SCTL_WSSRC_INTERNAL;
> +	regval = LPAIF_I2SCTL(v, LOOPBACK_DISABLE);
> +	regval |= LPAIF_I2SCTL(v, WSSRC_INTERNAL);
>   
>   	switch (bitwidth) {
>   	case 16:
> -		regval |= LPAIF_I2SCTL_BITWIDTH_16;
> +		regval |= LPAIF_I2SCTL(v, BITWIDTH_16);
>   		break;
>   	case 24:
> -		regval |= LPAIF_I2SCTL_BITWIDTH_24;
> +		regval |= LPAIF_I2SCTL(v, BITWIDTH_24);
>   		break;
>   	case 32:
> -		regval |= LPAIF_I2SCTL_BITWIDTH_32;
> +		regval |= LPAIF_I2SCTL(v, BITWIDTH_32);
>   		break;
>   	default:
>   		dev_err(dai->dev, "invalid bitwidth given: %d\n", bitwidth);
> @@ -110,24 +111,24 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
>   	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
>   		switch (channels) {
>   		case 1:
> -			regval |= LPAIF_I2SCTL_SPKMODE_SD0;
> -			regval |= LPAIF_I2SCTL_SPKMONO_MONO;
> +			regval |= LPAIF_I2SCTL(v, SPKMODE_SD0);
> +			regval |= LPAIF_I2SCTL(v, SPKMONO_MONO);
>   			break;
>   		case 2:
> -			regval |= LPAIF_I2SCTL_SPKMODE_SD0;
> -			regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
> +			regval |= LPAIF_I2SCTL(v, SPKMODE_SD0);
> +			regval |= LPAIF_I2SCTL(v, SPKMONO_STEREO);
>   			break;
>   		case 4:
> -			regval |= LPAIF_I2SCTL_SPKMODE_QUAD01;
> -			regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
> +			regval |= LPAIF_I2SCTL(v, SPKMODE_QUAD01);
> +			regval |= LPAIF_I2SCTL(v, SPKMONO_STEREO);
>   			break;
>   		case 6:
> -			regval |= LPAIF_I2SCTL_SPKMODE_6CH;
> -			regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
> +			regval |= LPAIF_I2SCTL(v, SPKMODE_6CH);
> +			regval |= LPAIF_I2SCTL(v, SPKMONO_STEREO);
>   			break;
>   		case 8:
> -			regval |= LPAIF_I2SCTL_SPKMODE_8CH;
> -			regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
> +			regval |= LPAIF_I2SCTL(v, SPKMODE_8CH);
> +			regval |= LPAIF_I2SCTL(v, SPKMONO_STEREO);
>   			break;
>   		default:
>   			dev_err(dai->dev, "invalid channels given: %u\n",
> @@ -137,24 +138,24 @@ static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream *substream,
>   	} else {
>   		switch (channels) {
>   		case 1:
> -			regval |= LPAIF_I2SCTL_MICMODE_SD0;
> -			regval |= LPAIF_I2SCTL_MICMONO_MONO;
> +			regval |= LPAIF_I2SCTL(v, MICMODE_SD0);
> +			regval |= LPAIF_I2SCTL(v, MICMONO_MONO);
>   			break;
>   		case 2:
> -			regval |= LPAIF_I2SCTL_MICMODE_SD0;
> -			regval |= LPAIF_I2SCTL_MICMONO_STEREO;
> +			regval |= LPAIF_I2SCTL(v, MICMODE_SD0);
> +			regval |= LPAIF_I2SCTL(v, MICMONO_STEREO);
>   			break;
>   		case 4:
> -			regval |= LPAIF_I2SCTL_MICMODE_QUAD01;
> -			regval |= LPAIF_I2SCTL_MICMONO_STEREO;
> +			regval |= LPAIF_I2SCTL(v, MICMODE_QUAD01);
> +			regval |= LPAIF_I2SCTL(v, MICMONO_STEREO);
>   			break;
>   		case 6:
> -			regval |= LPAIF_I2SCTL_MICMODE_6CH;
> -			regval |= LPAIF_I2SCTL_MICMONO_STEREO;
> +			regval |= LPAIF_I2SCTL(v, MICMODE_6CH);
> +			regval |= LPAIF_I2SCTL(v, MICMONO_STEREO);
>   			break;
>   		case 8:
> -			regval |= LPAIF_I2SCTL_MICMODE_8CH;
> -			regval |= LPAIF_I2SCTL_MICMONO_STEREO;
> +			regval |= LPAIF_I2SCTL(v, MICMODE_8CH);
> +			regval |= LPAIF_I2SCTL(v, MICMONO_STEREO);
>   			break;
>   		default:
>   			dev_err(dai->dev, "invalid channels given: %u\n",
> @@ -200,15 +201,16 @@ static int lpass_cpu_daiops_prepare(struct snd_pcm_substream *substream,
>   		struct snd_soc_dai *dai)
>   {
>   	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
> +	struct lpass_variant *v = drvdata->variant;
>   	int ret;
>   	unsigned int val, mask;
>   
>   	if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
> -		val = LPAIF_I2SCTL_SPKEN_ENABLE;
> -		mask = LPAIF_I2SCTL_SPKEN_MASK;
> +		val = LPAIF_I2SCTL(v, SPKEN_ENABLE);
> +		mask = LPAIF_I2SCTL(v, SPKEN_MASK);
>   	} else  {
> -		val = LPAIF_I2SCTL_MICEN_ENABLE;
> -		mask = LPAIF_I2SCTL_MICEN_MASK;
> +		val = LPAIF_I2SCTL(v, MICEN_ENABLE);
> +		mask = LPAIF_I2SCTL(v, MICEN_MASK);
>   	}
>   
>   	ret = regmap_update_bits(drvdata->lpaif_map,
> @@ -224,6 +226,7 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
>   		int cmd, struct snd_soc_dai *dai)
>   {
>   	struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
> +	struct lpass_variant *v = drvdata->variant;
>   	int ret = -EINVAL;
>   	unsigned int val, mask;
>   
> @@ -232,11 +235,11 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
>   	case SNDRV_PCM_TRIGGER_RESUME:
>   	case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
>   		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
> -			val = LPAIF_I2SCTL_SPKEN_ENABLE;
> -			mask = LPAIF_I2SCTL_SPKEN_MASK;
> +			val = LPAIF_I2SCTL(v, SPKEN_ENABLE);
> +			mask = LPAIF_I2SCTL(v, SPKEN_MASK);
>   		} else  {
> -			val = LPAIF_I2SCTL_MICEN_ENABLE;
> -			mask = LPAIF_I2SCTL_MICEN_MASK;
> +			val = LPAIF_I2SCTL(v, MICEN_ENABLE);
> +			mask = LPAIF_I2SCTL(v, MICEN_MASK);
>   		}
>   
>   		ret = regmap_update_bits(drvdata->lpaif_map,
> @@ -251,11 +254,11 @@ static int lpass_cpu_daiops_trigger(struct snd_pcm_substream *substream,
>   	case SNDRV_PCM_TRIGGER_SUSPEND:
>   	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
>   		if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
> -			val = LPAIF_I2SCTL_SPKEN_DISABLE;
> -			mask = LPAIF_I2SCTL_SPKEN_MASK;
> +			val = LPAIF_I2SCTL(v, SPKEN_DISABLE);
> +			mask = LPAIF_I2SCTL(v, SPKEN_MASK);
>   		} else  {
> -			val = LPAIF_I2SCTL_MICEN_DISABLE;
> -			mask = LPAIF_I2SCTL_MICEN_MASK;
> +			val = LPAIF_I2SCTL(v, MICEN_DISABLE);
> +			mask = LPAIF_I2SCTL(v, MICEN_MASK);
>   		}
>   
>   		ret = regmap_update_bits(drvdata->lpaif_map,
> diff --git a/sound/soc/qcom/lpass-lpaif-reg.h b/sound/soc/qcom/lpass-lpaif-reg.h
> index 3d74ae1..4251aa6 100644
> --- a/sound/soc/qcom/lpass-lpaif-reg.h
> +++ b/sound/soc/qcom/lpass-lpaif-reg.h
> @@ -17,11 +17,28 @@
>   #define LPAIF_I2SCTL_LOOPBACK_DISABLE	(0 << LPAIF_I2SCTL_LOOPBACK_SHIFT)
>   #define LPAIF_I2SCTL_LOOPBACK_ENABLE	(1 << LPAIF_I2SCTL_LOOPBACK_SHIFT)
>   
> +#define LPAIF_I2SCTL_LOOPBACK_MASK_V2	 0x20000
> +#define LPAIF_I2SCTL_LOOPBACK_SHIFT_V2	 17
> +#define LPAIF_I2SCTL_LOOPBACK_DISABLE_V2 (0 << LPAIF_I2SCTL_LOOPBACK_SHIFT_V2)
> +#define LPAIF_I2SCTL_LOOPBACK_ENABLE_V2	 (1 << LPAIF_I2SCTL_LOOPBACK_SHIFT_V2)
> +
>   #define LPAIF_I2SCTL_SPKEN_MASK		0x4000
>   #define LPAIF_I2SCTL_SPKEN_SHIFT	14
>   #define LPAIF_I2SCTL_SPKEN_DISABLE	(0 << LPAIF_I2SCTL_SPKEN_SHIFT)
>   #define LPAIF_I2SCTL_SPKEN_ENABLE	(1 << LPAIF_I2SCTL_SPKEN_SHIFT)
>   
> +#define LPAIF_I2SCTL_SPKEN_MASK_V2	0x10000
> +#define LPAIF_I2SCTL_SPKEN_SHIFT_V2	16
> +#define LPAIF_I2SCTL_SPKEN_DISABLE_V2	(0 << LPAIF_I2SCTL_SPKEN_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKEN_ENABLE_V2	(1 << LPAIF_I2SCTL_SPKEN_SHIFT_V2)
> +
> +#define __LPAIF_I2S_CTL(v, bit)  \
> +	((v->id ==  LPASS_VARIANT_V2) ? \
> +		LPAIF_I2SCTL_##bit##_V2 : \
> +		LPAIF_I2SCTL_##bit)
> +
> +#define LPAIF_I2SCTL(v, bit)		__LPAIF_I2S_CTL(v, bit)
> +
>   #define LPAIF_I2SCTL_SPKMODE_MASK	0x3C00
>   #define LPAIF_I2SCTL_SPKMODE_SHIFT	10
>   #define LPAIF_I2SCTL_SPKMODE_NONE	(0 << LPAIF_I2SCTL_SPKMODE_SHIFT)
> @@ -34,16 +51,49 @@
>   #define LPAIF_I2SCTL_SPKMODE_6CH	(7 << LPAIF_I2SCTL_SPKMODE_SHIFT)
>   #define LPAIF_I2SCTL_SPKMODE_8CH	(8 << LPAIF_I2SCTL_SPKMODE_SHIFT)
>   
> +#define LPAIF_I2SCTL_SPKMODE_MASK_V2	0xF800
> +#define LPAIF_I2SCTL_SPKMODE_SHIFT_V2	11
> +#define LPAIF_I2SCTL_SPKMODE_NONE_V2	(0 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_SD0_V2	(1 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_SD1_V2	(2 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_SD2_V2	(3 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_SD3_V2	(4 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_QUAD01_V2	(5 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_QUAD23_V2	(6 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_6CH_V2	(7 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_8CH_V2	(8 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_10CH_V2	(9 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_12CH_V2	(10 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_14CH_V2	(11 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_16CH_V2	(12 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_SD4_V2	(13 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_SD5_V2	(14 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_SD6_V2	(15 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_SD7_V2	(16 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_QUAD45_V2	(17 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_QUAD47_V2	(18 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMODE_8CH_2_V2	(19 << LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
> +
>   #define LPAIF_I2SCTL_SPKMONO_MASK	0x0200
>   #define LPAIF_I2SCTL_SPKMONO_SHIFT	9
>   #define LPAIF_I2SCTL_SPKMONO_STEREO	(0 << LPAIF_I2SCTL_SPKMONO_SHIFT)
>   #define LPAIF_I2SCTL_SPKMONO_MONO	(1 << LPAIF_I2SCTL_SPKMONO_SHIFT)
>   
> +#define LPAIF_I2SCTL_SPKMONO_MASK_V2	0x0400
> +#define LPAIF_I2SCTL_SPKMONO_SHIFT_V2	10
> +#define LPAIF_I2SCTL_SPKMONO_STEREO_V2	(0 << LPAIF_I2SCTL_SPKMONO_SHIFT_V2)
> +#define LPAIF_I2SCTL_SPKMONO_MONO_V2	(1 << LPAIF_I2SCTL_SPKMONO_SHIFT_V2)
> +
>   #define LPAIF_I2SCTL_MICEN_MASK		GENMASK(8, 8)
>   #define LPAIF_I2SCTL_MICEN_SHIFT	8
>   #define LPAIF_I2SCTL_MICEN_DISABLE	(0 << LPAIF_I2SCTL_MICEN_SHIFT)
>   #define LPAIF_I2SCTL_MICEN_ENABLE	(1 << LPAIF_I2SCTL_MICEN_SHIFT)
>   
> +#define LPAIF_I2SCTL_MICEN_MASK_V2	0x0200
> +#define LPAIF_I2SCTL_MICEN_SHIFT_V2	9
> +#define LPAIF_I2SCTL_MICEN_DISABLE_V2	(0 << LPAIF_I2SCTL_MICEN_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICEN_ENABLE_V2	(1 << LPAIF_I2SCTL_MICEN_SHIFT_V2)
> +
>   #define LPAIF_I2SCTL_MICMODE_MASK	GENMASK(7, 4)
>   #define LPAIF_I2SCTL_MICMODE_SHIFT	4
>   #define LPAIF_I2SCTL_MICMODE_NONE	(0 << LPAIF_I2SCTL_MICMODE_SHIFT)
> @@ -56,22 +106,61 @@
>   #define LPAIF_I2SCTL_MICMODE_6CH	(7 << LPAIF_I2SCTL_MICMODE_SHIFT)
>   #define LPAIF_I2SCTL_MICMODE_8CH	(8 << LPAIF_I2SCTL_MICMODE_SHIFT)
>   
> +#define LPAIF_I2SCTL_MICMODE_MASK_V2	GENMASK(8, 4)
> +#define LPAIF_I2SCTL_MICMODE_SHIFT_V2	4
> +#define LPAIF_I2SCTL_MICMODE_NONE_V2	(0 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_SD0_V2	(1 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_SD1_V2	(2 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_SD2_V2	(3 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_SD3_V2	(4 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_QUAD01_V2	(5 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_QUAD23_V2	(6 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_6CH_V2	(7 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_8CH_V2	(8 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_10CH_V2	(9 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_12CH_V2	(10 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_14CH_V2	(11 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_16CH_V2	(12 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_SD4_V2	(13 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_SD5_V2	(14 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_SD6_V2	(15 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_SD7_V2	(16 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_QUAD45_V2	(17 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_QUAD47_V2	(18 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMODE_8CH_2_V2	(19 << LPAIF_I2SCTL_MICMODE_SHIFT_V2)
> +
>   #define LPAIF_I2SCTL_MIMONO_MASK	GENMASK(3, 3)
>   #define LPAIF_I2SCTL_MICMONO_SHIFT	3
>   #define LPAIF_I2SCTL_MICMONO_STEREO	(0 << LPAIF_I2SCTL_MICMONO_SHIFT)
>   #define LPAIF_I2SCTL_MICMONO_MONO	(1 << LPAIF_I2SCTL_MICMONO_SHIFT)
>   
> +#define LPAIF_I2SCTL_MICMONO_MASK_V2	GENMASK(3, 3)
> +#define LPAIF_I2SCTL_MICMONO_SHIFT_V2	3
> +#define LPAIF_I2SCTL_MICMONO_STEREO_V2	(0 << LPAIF_I2SCTL_MICMONO_SHIFT_V2)
> +#define LPAIF_I2SCTL_MICMONO_MONO_V2	(1 << LPAIF_I2SCTL_MICMONO_SHIFT_V2)
> +
>   #define LPAIF_I2SCTL_WSSRC_MASK		0x0004
>   #define LPAIF_I2SCTL_WSSRC_SHIFT	2
>   #define LPAIF_I2SCTL_WSSRC_INTERNAL	(0 << LPAIF_I2SCTL_WSSRC_SHIFT)
>   #define LPAIF_I2SCTL_WSSRC_EXTERNAL	(1 << LPAIF_I2SCTL_WSSRC_SHIFT)
>   
> +#define LPAIF_I2SCTL_WSSRC_MASK_V2	0x0004
> +#define LPAIF_I2SCTL_WSSRC_SHIFT_V2	2
> +#define LPAIF_I2SCTL_WSSRC_INTERNAL_V2	(0 << LPAIF_I2SCTL_WSSRC_SHIFT_V2)
> +#define LPAIF_I2SCTL_WSSRC_EXTERNAL_V2	(1 << LPAIF_I2SCTL_WSSRC_SHIFT_V2)
> +
>   #define LPAIF_I2SCTL_BITWIDTH_MASK	0x0003
>   #define LPAIF_I2SCTL_BITWIDTH_SHIFT	0
>   #define LPAIF_I2SCTL_BITWIDTH_16	(0 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
>   #define LPAIF_I2SCTL_BITWIDTH_24	(1 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
>   #define LPAIF_I2SCTL_BITWIDTH_32	(2 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
>   
> +#define LPAIF_I2SCTL_BITWIDTH_MASK_V2	0x0003
> +#define LPAIF_I2SCTL_BITWIDTH_SHIFT_V2	0
> +#define LPAIF_I2SCTL_BITWIDTH_16_V2	(0 << LPAIF_I2SCTL_BITWIDTH_SHIFT_V2)
> +#define LPAIF_I2SCTL_BITWIDTH_24_V2	(1 << LPAIF_I2SCTL_BITWIDTH_SHIFT_V2)
> +#define LPAIF_I2SCTL_BITWIDTH_32_V2	(2 << LPAIF_I2SCTL_BITWIDTH_SHIFT_V2)
> +
>   /* LPAIF IRQ */
>   #define LPAIF_IRQ_REG_ADDR(v, addr, port) \
>   	(v->irq_reg_base + (addr) + v->irq_reg_stride * (port))
> @@ -91,7 +180,6 @@
>   #define LPAIF_IRQ_ALL(chan)		(7 << (LPAIF_IRQ_BITSTRIDE * (chan)))
>   
>   /* LPAIF DMA */
> -
>   #define LPAIF_RDMA_REG_ADDR(v, addr, chan) \
>   	(v->rdma_reg_base + (addr) + v->rdma_reg_stride * (chan))
>   
> @@ -143,7 +231,7 @@
>   
>   #define LPAIF_DMACTL_AUDINTF_MASK	0x0F0
>   #define LPAIF_DMACTL_AUDINTF_SHIFT	4
> -#define LPAIF_DMACTL_AUDINTF(id)	(id << LPAIF_DMACTL_AUDINTF_SHIFT)
> +#define LPAIF_DMACTL_AUDINTF(port)	(port << LPAIF_DMACTL_AUDINTF_SHIFT)
>   
>   #define LPAIF_DMACTL_FIFOWM_MASK	0x00E
>   #define LPAIF_DMACTL_FIFOWM_SHIFT	1
> @@ -158,11 +246,99 @@
>   
>   #define LPAIF_DMACTL_ENABLE_MASK	0x1
>   #define LPAIF_DMACTL_ENABLE_SHIFT	0
> -#define LPAIF_DMACTL_ENABLE_OFF	(0 << LPAIF_DMACTL_ENABLE_SHIFT)
> +#define LPAIF_DMACTL_ENABLE_OFF		(0 << LPAIF_DMACTL_ENABLE_SHIFT)
>   #define LPAIF_DMACTL_ENABLE_ON		(1 << LPAIF_DMACTL_ENABLE_SHIFT)
>   
> +#define LPAIF_IRQ_BITSTRIDE		3
> +
> +#define LPAIF_IRQ_PER(chan)		(1 << (LPAIF_IRQ_BITSTRIDE * (chan)))
> +#define LPAIF_IRQ_XRUN(chan)		(2 << (LPAIF_IRQ_BITSTRIDE * (chan)))
> +#define LPAIF_IRQ_ERR(chan)		(4 << (LPAIF_IRQ_BITSTRIDE * (chan)))
> +
> +#define LPAIF_IRQ_ALL(chan)		(7 << (LPAIF_IRQ_BITSTRIDE * (chan)))
> +
>   #define LPAIF_DMACTL_DYNCLK_MASK	BIT(12)
>   #define LPAIF_DMACTL_DYNCLK_SHIFT	12
>   #define LPAIF_DMACTL_DYNCLK_OFF	(0 << LPAIF_DMACTL_DYNCLK_SHIFT)
>   #define LPAIF_DMACTL_DYNCLK_ON		(1 << LPAIF_DMACTL_DYNCLK_SHIFT)
> +
> +#define LPAIF_DMACTL_BURSTEN_MASK_V2	0x100000
> +#define LPAIF_DMACTL_BURSTEN_SHIFT_V2	20
> +#define LPAIF_DMACTL_BURSTEN_SINGLE_V2	(0 << LPAIF_DMACTL_BURSTEN_SHIFT_V2)
> +#define LPAIF_DMACTL_BURSTEN_INCR4_V2	(1 << LPAIF_DMACTL_BURSTEN_SHIFT_V2)
> +
> +#define LPAIF_DMACTL_WPSCNT_MASK_V2	0xF0000
> +#define LPAIF_DMACTL_WPSCNT_SHIFT_V2	16
> +#define LPAIF_DMACTL_WPSCNT_ONE_V2	(0 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
> +#define LPAIF_DMACTL_WPSCNT_TWO_V2	(1 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
> +#define LPAIF_DMACTL_WPSCNT_THREE_V2	(2 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
> +#define LPAIF_DMACTL_WPSCNT_FOUR_V2	(3 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
> +#define LPAIF_DMACTL_WPSCNT_SIX_V2	(5 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
> +#define LPAIF_DMACTL_WPSCNT_EIGHT_V2	(7 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
> +#define LPAIF_DMACTL_WPSCNT_TEN_V2	(9 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
> +#define LPAIF_DMACTL_WPSCNT_TWELVE_V2	(11 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
> +#define LPAIF_DMACTL_WPSCNT_FOURTEEN_V2	(13 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
> +#define LPAIF_DMACTL_WPSCNT_SIXTEEN_V2	(15 << LPAIF_DMACTL_WPSCNT_SHIFT_V2)
> +
> +#define LPAIF_DMACTL_AUDINTF_MASK_V2	0xF000
> +#define LPAIF_DMACTL_AUDINTF_SHIFT_V2	12
> +#define LPAIF_DMACTL_AUDINTF_V2(port)	(port << LPAIF_DMACTL_AUDINTF_SHIFT_V2)
> +
> +#define LPAIF_DMACTL_AUD_INTF(v, port)  \
> +	((v->id ==  LPASS_VARIANT_V2) ? \
> +		LPAIF_DMACTL_AUDINTF_V2(port) : \
> +		LPAIF_DMACTL_AUDINTF(port))
> +
> +#define LPAIF_DMACTL_FIFOWM_MASK_V2	0x3E
> +#define LPAIF_DMACTL_FIFOWM_SHIFT_V2	1
> +#define LPAIF_DMACTL_FIFOWM_1_V2	(0 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_2_V2	(1 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_3_V2	(2 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_4_V2	(3 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_5_V2	(4 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_6_V2	(5 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_7_V2	(6 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_8_V2	(7 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_9_V2	(8 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_10_V2	(9 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_11_V2	(10 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_12_V2	(11 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_13_V2	(12 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_14_V2	(13 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_15_V2	(14 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_16_V2	(15 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_17_V2	(16 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_18_V2	(17 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_19_V2	(18 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_20_V2	(19 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_21_V2	(20 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_22_V2	(21 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_23_V2	(22 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_24_V2	(23 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_25_V2	(24 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_26_V2	(25 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_27_V2	(26 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_28_V2	(27 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_29_V2	(28 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_30_V2	(29 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_31_V2	(30 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +#define LPAIF_DMACTL_FIFOWM_32_V2	(31 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
> +
> +#define LPAIF_DMACTL_ENABLE_MASK_V2	0x1
> +#define LPAIF_DMACTL_ENABLE_SHIFT_V2	0
> +#define LPAIF_DMACTL_ENABLE_OFF_V2	(0 << LPAIF_DMACTL_ENABLE_SHIFT_V2)
> +#define LPAIF_DMACTL_ENABLE_ON_V2	(1 << LPAIF_DMACTL_ENABLE_SHIFT_V2)
> +
> +#define LPAIF_DMACTL_DYNCLK_MASK_V2	BIT(21)
> +#define LPAIF_DMACTL_DYNCLK_SHIFT_V2	21
> +#define LPAIF_DMACTL_DYNCLK_OFF_V2	(0 << LPAIF_DMACTL_DYNCLK_SHIFT_V2)
> +#define LPAIF_DMACTL_DYNCLK_ON_V2	(1 << LPAIF_DMACTL_DYNCLK_SHIFT_V2)
> +
> +#define __LPAIF_DMA_CTL(v, bit)  \
> +	((v->id ==  LPASS_VARIANT_V2) ? \
> +		LPAIF_DMACTL_##bit##_V2 : \
> +		LPAIF_DMACTL_##bit)
> +
> +#define LPAIF_DMACTL(v, bit)		__LPAIF_DMA_CTL(v, bit)
> +
>   #endif /* __LPASS_LPAIF_REG_H__ */
> diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platform.c
> index b05091c2..821599e 100644
> --- a/sound/soc/qcom/lpass-platform.c
> +++ b/sound/soc/qcom/lpass-platform.c
> @@ -146,25 +146,26 @@ static int lpass_platform_pcmops_hw_params(struct snd_soc_component *component,
>   		return bitwidth;
>   	}
>   
> -	regval = LPAIF_DMACTL_BURSTEN_INCR4 |
> -			LPAIF_DMACTL_AUDINTF(dma_port) |
> -			LPAIF_DMACTL_FIFOWM_8;
> +
> +	regval = LPAIF_DMACTL(v, BURSTEN_INCR4);
> +	regval |= LPAIF_DMACTL(v, FIFOWM_8);
> +	regval |= LPAIF_DMACTL_AUD_INTF(v, dma_port);
>   
>   	switch (bitwidth) {
>   	case 16:
>   		switch (channels) {
>   		case 1:
>   		case 2:
> -			regval |= LPAIF_DMACTL_WPSCNT_ONE;
> +			regval |= LPAIF_DMACTL(v, WPSCNT_ONE);
>   			break;
>   		case 4:
> -			regval |= LPAIF_DMACTL_WPSCNT_TWO;
> +			regval |= LPAIF_DMACTL(v, WPSCNT_TWO);
>   			break;
>   		case 6:
> -			regval |= LPAIF_DMACTL_WPSCNT_THREE;
> +			regval |= LPAIF_DMACTL(v, WPSCNT_THREE);
>   			break;
>   		case 8:
> -			regval |= LPAIF_DMACTL_WPSCNT_FOUR;
> +			regval |= LPAIF_DMACTL(v, WPSCNT_FOUR);
>   			break;
>   		default:
>   			dev_err(soc_runtime->dev,
> @@ -177,19 +178,19 @@ static int lpass_platform_pcmops_hw_params(struct snd_soc_component *component,
>   	case 32:
>   		switch (channels) {
>   		case 1:
> -			regval |= LPAIF_DMACTL_WPSCNT_ONE;
> +			regval |= LPAIF_DMACTL(v, WPSCNT_ONE);
>   			break;
>   		case 2:
> -			regval |= LPAIF_DMACTL_WPSCNT_TWO;
> +			regval |= LPAIF_DMACTL(v, WPSCNT_TWO);
>   			break;
>   		case 4:
> -			regval |= LPAIF_DMACTL_WPSCNT_FOUR;
> +			regval |= LPAIF_DMACTL(v, WPSCNT_FOUR);
>   			break;
>   		case 6:
> -			regval |= LPAIF_DMACTL_WPSCNT_SIX;
> +			regval |= LPAIF_DMACTL(v, WPSCNT_SIX);
>   			break;
>   		case 8:
> -			regval |= LPAIF_DMACTL_WPSCNT_EIGHT;
> +			regval |= LPAIF_DMACTL(v, WPSCNT_EIGHT);
>   			break;
>   		default:
>   			dev_err(soc_runtime->dev,
> @@ -277,7 +278,7 @@ static int lpass_platform_pcmops_prepare(struct snd_soc_component *component,
>   
>   	ret = regmap_update_bits(drvdata->lpaif_map,
>   			LPAIF_DMACTL_REG(v, ch, dir),
> -			LPAIF_DMACTL_ENABLE_MASK, LPAIF_DMACTL_ENABLE_ON);
> +			LPAIF_DMACTL(v, ENABLE_MASK), LPAIF_DMACTL_ENABLE_ON);
>   	if (ret) {
>   		dev_err(soc_runtime->dev, "error writing to rdmactl reg: %d\n",
>   			ret);
> @@ -326,7 +327,7 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
>   
>   		ret = regmap_update_bits(drvdata->lpaif_map,
>   				LPAIF_DMACTL_REG(v, ch, dir),
> -				LPAIF_DMACTL_ENABLE_MASK,
> +				LPAIF_DMACTL(v, ENABLE_MASK),
>   				LPAIF_DMACTL_ENABLE_ON);
>   		if (ret) {
>   			dev_err(soc_runtime->dev,
> @@ -339,7 +340,7 @@ static int lpass_platform_pcmops_trigger(struct snd_soc_component *component,
>   	case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
>   		ret = regmap_update_bits(drvdata->lpaif_map,
>   				LPAIF_DMACTL_REG(v, ch, dir),
> -				LPAIF_DMACTL_ENABLE_MASK,
> +				LPAIF_DMACTL(v, ENABLE_MASK),
>   				LPAIF_DMACTL_ENABLE_OFF);
>   		if (ret) {
>   			dev_err(soc_runtime->dev,
> diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
> index 279cd02..384f4b8 100644
> --- a/sound/soc/qcom/lpass.h
> +++ b/sound/soc/qcom/lpass.h
> @@ -17,6 +17,9 @@
>   #define LPASS_MAX_MI2S_PORTS                   (8)
>   #define LPASS_MAX_DMA_CHANNELS                 (8)
>   
> +#define LPASS_VARIANT				0
> +#define LPASS_VARIANT_V2			1
> +
>   struct lpass_dai {
>   	struct clk *osr_clk;
>   	struct clk *bit_clk;
> @@ -91,6 +94,9 @@ struct lpass_variant {
>   	/* SOC specific clocks configuration */
>   	const char **clk_name;
>   	int num_clks;
> +
> +	/* LPASS Version id */
> +	int id;

May be spelling this out like "version_id" would make it more readable.

thanks,
srini


>   };
>   
>   /* register the platform driver from the CPU DAI driver */
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 07/11] Documentation: dt-bindings: sound: Add details for new dai properties
  2020-04-11  8:02 ` [PATCH 07/11] Documentation: dt-bindings: sound: Add details for new dai properties Ajit Pandey
@ 2020-04-16  7:56   ` Srinivas Kandagatla
  0 siblings, 0 replies; 21+ messages in thread
From: Srinivas Kandagatla @ 2020-04-16  7:56 UTC (permalink / raw)
  To: Ajit Pandey, alsa-devel, broonie, devicetree, plai, bgoswami
  Cc: linux-kernel, tiwai, stephan



On 11/04/2020 09:02, Ajit Pandey wrote:
> Add changes related to new sub node defining MI2S dai's properties. Such
> properties needs to be configured via board specific dts files.
> 
+Adding Stephan Gerlhold

Have a look at https://www.spinics.net/lists/alsa-devel/msg107224.html 
patches from Stephan Gerlhold which has better version of specifying sd 
line mask and is inline with DSP based solution too.

--srini

> Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
> ---
>   .../devicetree/bindings/sound/qcom,lpass-cpu.yaml  | 33 ++++++++++++++++++++++
>   1 file changed, 33 insertions(+)
> 
> diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
> index a87a406..727ec03 100644
> --- a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
> +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
> @@ -16,6 +16,8 @@ description: |
>     configure Low-Power Audio Interface(LPAIF) core registers across different
>     IP versions.
>   
> +  See also dt-bindings/sound/qcom,lpass.h.
> +
>   properties:
>     compatible:
>       enum:
> @@ -69,6 +71,30 @@ properties:
>     '#sound-dai-cells':
>       const: 1
>   
> +  dai-name:
> +    - description: Each node represents an MI2S dai and conatins dai specific
> +        properties that may change with board layout & dai connections.
> +    - type: object
> +    - properties:
> +      id:
> +        - description: dai id among one of value defined in header
> +        - type: u32
> +      qcom,spkmode-mask:
> +        - description: mask defining data lines used for speaker
> +        - type: u32
> +      qcom,micmode-mask:
> +        - description: mask defining data lines used for mic
> +        - type: u32
> +      qcom,wssrc-mask:
> +        - description: mask defining word-select source internal/extrnal on dai
> +        - type: u32
> +      qcom,loopback-mask:
> +        - description: mask defining loopback enable/disable on dai
> +        - type: u32
> +
> +      required:
> +        - id
> +
>   required:
>     - compatible
>     - reg
> @@ -101,3 +127,10 @@ examples:
>   	#sound-dai-cells = <1>;
>   	qcom,adsp = <&adsp>;
>   
> +        prim-mi2s@0 {
> +		id = <MI2S_PRIMARY>;
> +		qcom,spkmode-mask = <SD1>;
> +		qcom,micmode-mask = <SD0>;
> +                qcom,wssrc-mask = <INTERNAL>;
> +                qcom,loopback-mask = <DISABLE>;
> +	};
> 

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 01/11] Documentation: device-tree: sound: Update lpass-cpu driver binding
  2020-04-16  7:53   ` Srinivas Kandagatla
@ 2020-04-25 14:05     ` Ajit Pandey
  0 siblings, 0 replies; 21+ messages in thread
From: Ajit Pandey @ 2020-04-25 14:05 UTC (permalink / raw)
  To: Srinivas Kandagatla, alsa-devel, broonie, devicetree, plai, bgoswami
  Cc: linux-kernel, tiwai

On 4/16/2020 1:23 PM, Srinivas Kandagatla wrote:
>
>
> On 11/04/2020 09:02, Ajit Pandey wrote:
>> Done the required cleanups to update lpass-cpu binding with newer
>> yaml formats.
>>
>> Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
>
>
>> ---
>>   .../devicetree/bindings/sound/qcom,lpass-cpu.txt   | 158 
>> ---------------------
>>   .../devicetree/bindings/sound/qcom,lpass-cpu.yaml  | 103 
>> ++++++++++++++
>>   2 files changed, 103 insertions(+), 158 deletions(-)
>>   delete mode 100644 
>> Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt
>>   create mode 100644 
>> Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
>>
>> diff --git 
>> a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt 
>> b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt
>> deleted file mode 100644
>> index a49b878..00000000
>> --- a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.txt
>> +++ /dev/null
>> @@ -1,158 +0,0 @@
>> -* Qualcomm Technologies LPASS CPU DAI binding
>> -
>> -Low-Power Audio SubSystem (LPASS) consist of MI2S interfaces for 
>> audio data
>> -transfer on external codec. LPASS cpu driver is a common code to 
>> configure
>> -MI2S related CPU dai's across different version of LPASS architecture.
>> -
>> -- compatible:
>> -    Usage: required
>> -    Value type: <stringlist>
>> -    Definition: compatible string corresponds to lpass variants driver
>> -            must be "qcom, lpass-cpu-sc7180" for sc7180 lpass
> This patch will not apply on mainline, looks like this was done on top 
> of your local repo, please fix this!
>
> Best thing would be rebase patches top of 
> https://git.kernel.org/pub/scm/linux/kernel/git/broonie/sound.git/log/?h=for-next
Sure I'll rebase on top of mentioned tip during v2 patch chain submission
>
> Secondly, Split this patch into two,
> 1> converting in to yaml
> 2> adding new changes
> so that it will be easy to see what exactly changed.
>
> thanks,
> srini
>
I've not added any newer properties here just changed it to yaml format only

Thanks & Regards

Ajit

>> -            must be "qcom,apq8016-lpass-cpu" for apq8016 lpass
>> -- reg:
>> -    Usage: required
>> -    Value type: <prop-encoded-array>
>> -    Definition: must specify the base address and size of the LPAIF 
>> CORE
>> -            region of lpass variant.
>> -- reg-names:
>> -    Usage: required
>> -    Value type: <stringlist>
>> -    Definition: must be "lpass-lpaif"
>> -
>> -- iommus:
>> -        Usage: required for "qcom, lpass-cpu-sc7180" compatible string
>> -        Value type: <prop-encoded-array>
>> -        Definition: sid mask for lpaif memory region to apps_smmu
>> -                    must be <&apps_smmu 0x1020 0>
>> -
>> -- power-domains:
>> -    Usage: required for "qcom, lpass-cpu-sc7180" compatible string
>> -    Value type: <phandle>
>> -    Definition: reference to power-domains
>> -            must be <&lpass_hm LPASS_CORE_HM_GDSCR>
>> -
>> -- clocks:
>> -        Usage: required
>> -    Value type: <phandle>
>> -    Definition: reference to the clocks that match clock-names
>> -
>> -- clock-names:
>> -    Usage: required
>> -    Value type: <stringlist>
>> -    Definition: The clocks needed depend on the compatible string:
>> -    qcom,lpass-cpu-apq8016:
>> -        must be "ahbix-clk", "mi2s-osr-clk", "mi2s-bit-clk0",
>> -        mi2s-bit-clk1", "mi2s-bit-clk2", "mi2s-bit-clk3",
>> -        "pcnoc-mport-clk", "pcnoc-sway-clk"
>> -    qcom, lpass-cpu-sc7180:
>> -        must be "noc", "audio-core", "mclk0", "sysnoc_mport",
>> -        "pri_ibit", "sec_ibit"
>> -
>> -- #sound-dai-cells
>> -    Usage: required
>> -    Value type: <u32>
>> -    Definition: Must be 1
>> -
>> -- interrupts:
>> -    Usage: required
>> -    Value type: <prop-encoded-array>
>> -    Definition: reference to the interrupts that match interrupt-names
>> -
>> -- interrupt-names:
>> -    Usage: required
>> -    Value type: <stringlist>
>> -    Definition: must be "lpass-irq-lpaif"
>> -
>> -- qcom,adsp:
>> -        Usage: optional
>> -        Value type: <phandle>
>> -    Definition: Phandle for the audio DSP node
>> -
>> -= MI2S DAIs (Digial Audio Interface)
>> -"dais" child node of the lpass node. It represents mi2s dais, each 
>> mi2s dai is
>> -subnode of "dais" representing board specific dai setup & required 
>> dai clocks.
>> -"dais" node should have following properties.
>> -
>> -- id:
>> -    Usage: required for mi2s interface
>> -    Value type: <u32>
>> -    Definition: Must be dai id defined in lpass bindings like 
>> MI2S_PRIMARY
>> -
>> -- qcom,bitclk-name:
>> -    Usage: required for mi2s interface
>> -    Value type: <stringlist>
>> -    Definition: bitclk name corresponds to MI2S of lpass version
>> -
>> -- qcom,mclk-name:
>> -        Usage: optional for mi2s interface
>> -        Value type: <stringlist>
>> -        Definition: external mclk name corresponds to MI2S of lpass 
>> version
>> -
>> -- qcom,osrclk-name:
>> -        Usage: optional for mi2s interface
>> -        Value type: <stringlist>
>> -        Definition: osrclk name corresponds to MI2S of lpass version
>> -
>> -- qcom,spkmode-mask:
>> -        Usage: optional for mi2s interface
>> -        Value type: <u32>
>> -        Definition: board specific property to change default 
>> spkmode mask
>> -                    of MI2S dai based on dataline connection on board.
>> -
>> -- qcom,micmode-mask:
>> -        Usage: optional for mi2s interface
>> -        Value type: <u32>
>> -        Definition: board specific property to change default 
>> micmode mask
>> -                    of MI2S dai based on dataline connection on board.
>> -
>> -- qcom,loopback-mask:
>> -        Usage: optional for mi2s interface
>> -        Value type: <u32>
>> -        Definition: board specific property to change default 
>> loopback mask
>> -                    of MI2S dai as per requirement.
>> -
>> -- qcom,wssrc-mask:
>> -        Usage: optional for mi2s interface
>> -        Value type: <u32>
>> -        Definition: board specific property to change default wssrc 
>> mask
>> -                    of MI2S dai based as per requirement.
>> -
>> -Example:
>> -
>> -lpass_cpu: lpass {
>> -    compatible = "qcom, lpass-cpu-sc7180";
>> -
>> -    reg = <0 0x62F00000 0 0x29000>;
>> -    reg-names = "lpass-lpaif";
>> -
>> -    iommus = <&apps_smmu 0x1020 0>;
>> -
>> -    power-domains = <&lpass_hm LPASS_CORE_HM_GDSCR>;
>> -
>> -    clocks = <&gcc GCC_LPASS_CFG_NOC_SWAY_CLK>,
>> -         <&lpasscorecc LPASS_AUDIO_CORE_CORE_CLK>,
>> -         <&lpasscorecc LPASS_AUDIO_CORE_EXT_MCLK0_CLK>,
>> -         <&lpasscorecc LPASS_AUDIO_CORE_SYSNOC_MPORT_CORE_CLK>,
>> -         <&lpasscorecc LPASS_AUDIO_CORE_LPAIF_PRI_IBIT_CLK>,
>> -         <&lpasscorecc LPASS_AUDIO_CORE_LPAIF_SEC_IBIT_CLK>;
>> -
>> -    clock-names = "noc", "audio-core", "mclk0", "sysnoc_mport",
>> -              "pri_ibit", "sec_ibit";
>> -
>> -    #sound-dai-cells = <1>;
>> -
>> -    interrupts = <0 160 IRQ_TYPE_LEVEL_HIGH>;
>> -    interrupt-names = "lpass-irq-lpaif";
>> -
>> -    prim-mi2s@0 {
>> -        id = <MI2S_PRIMARY>;
>> -        qcom,bitclk-name = "pri_ibit";
>> -        qcom,mclk-name = "mclk0";
>> -    };
>> -
>> -    sec-mi2s@1 {
>> -        id = <MI2S_SECONDARY>;
>> -        qcom,bitclk-name = "sec_ibit";
>> -    };
>> -};
>> diff --git 
>> a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml 
>> b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
>> new file mode 100644
>> index 00000000..a87a406
>> --- /dev/null
>> +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml
>> @@ -0,0 +1,103 @@
>> +# SPDX-License-Identifier: GPL-2.0-only
>> +%YAML 1.2
>> +---
>> +$id: http://devicetree.org/schemas/sound/qcom,lpass-cpu.yaml#
>> +$schema: http://devicetree.org/meta-schemas/core.yaml#
>> +
>> +title: Qualcomm LPASS CPU dai driver bindings
>> +
>> +maintainers:
>> +  - Srinivas Kandagatla <srinivas.kandagatla@linaro.org>
>> +  - Ajit Pandey <ajitp@codeaurora.org>
>> +
>> +description: |
>> +  Qualcomm SOC Low-Power Audio SubSystem (LPASS) that consist of 
>> MI2S interface
>> +  for audio data transfer on external codecs. LPASS cpu driver is a 
>> module to
>> +  configure Low-Power Audio Interface(LPAIF) core registers across 
>> different
>> +  IP versions.
>> +
>> +properties:
>> +  compatible:
>> +    enum:
>> +      - qcom,lpass-cpu
>> +      - qcom,apq8016-lpass-cpu
>> +
>> +  reg:
>> +    items:
>> +      - description: LPAIF core registers
>> +
>> +  reg-names:
>> +    items:
>> +      - const: lpass-lpaif
>> +
>> +  clocks:
>> +    items:
>> +      - description: AHBIX core clock for IPQ806X
>> +      - description: oscillator clock for MI2S external interfaces
>> +      - description: Bit clock for single MI2S dai in IPQ806X
>> +      - description: Bit clock for MI2S_PRIMARY dai interface
>> +      - description: Bit clock for MI2S_SECONDARY dai interface
>> +      - description: Bit clock for MI2S_TERTIARY dai interface
>> +      - description: Bit clock for MI2S_QUATERNARY dai interface
>> +      - description: NOC MPORT clock of LPASS core
>> +      - description: NOC SWAY clock of LPASS core
>> +
>> +  clock-names:
>> +    items:
>> +      - const: ahbix-clk
>> +      - const: mi2s-osr-clk
>> +      - const: mi2s-bit-clk
>> +      - const: mi2s-bit-clk0
>> +      - const: mi2s-bit-clk1
>> +      - const: mi2s-bit-clk2
>> +      - const: mi2s-bit-clk3
>> +      - const: pcnoc-mport-clk
>> +      - const: pcnoc-sway-clk
>> +
>> +  interrupts:
>> +    items:
>> +      - description: LPAIF DMA buffer interrupt
>> +
>> +  interrupt-names:
>> +    items:
>> +      - const: lpass-irq-lpaif
>> +
>> +  qcom,adsp:
>> +    maxItems: 1
>> +    description: Phandle for the audio DSP node
>> +
>> +  '#sound-dai-cells':
>> +    const: 1
>> +
>> +required:
>> +  - compatible
>> +  - reg
>> +  - reg-names
>> +  - clocks
>> +  - clock-names
>> +  - interrupts
>> +  - interrupt-names
>> +  - sound-dai-cells
>> +
>> +optional:
>> +  - qcom,adsp
>> +
>> +examples:
>> +  lpass@28100000 {
>> +    compatible = "qcom,lpass-cpu";
>> +    clocks = <&lcc AHBIX_CLK>,
>> +         <&lcc MI2S_OSR_CLK>,
>> +         <&lcc MI2S_BIT_CLK>;
>> +
>> +    clock-names = "ahbix-clk",
>> +              "mi2s-osr-clk",
>> +              "mi2s-bit-clk";
>> +
>> +    interrupts = <0 85 1>;
>> +    interrupt-names = "lpass-irq-lpaif";
>> +
>> +    reg = <0x28100000 0x10000>;
>> +    reg-names = "lpass-lpaif";
>> +    #sound-dai-cells = <1>;
>> +    qcom,adsp = <&adsp>;
>> +
>>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 02/11] ASoC: qcom: lpass: Add struct lpass_dai to store dai clocks pointer
  2020-04-16  7:56   ` Srinivas Kandagatla
@ 2020-04-25 14:11     ` Ajit Pandey
  0 siblings, 0 replies; 21+ messages in thread
From: Ajit Pandey @ 2020-04-25 14:11 UTC (permalink / raw)
  To: Srinivas Kandagatla, alsa-devel, broonie, devicetree, plai, bgoswami
  Cc: linux-kernel, tiwai

On 4/16/2020 1:26 PM, Srinivas Kandagatla wrote:
>
>
> On 11/04/2020 09:02, Ajit Pandey wrote:
>> lpass_dai will store clocks related to respective dai's and it will
>> be initialized during probe based on variant clock names.
>>
>> Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
>
> I dont understand why do we need this change? What is the advantage of 
> doing this way vs the existing one?
>
>
> --srini
>
> Actually I've kept this in chain to add dai modes properties later in 
> chain in this struct but with adoption of Stephen patch now , i guess 
> we don't have any significant advantage now. I'll probably drop this 
> patch during v2 submission.      --Ajit
>> ---
>>   sound/soc/qcom/lpass-cpu.c | 89 
>> ++++++++++++++++++++++++++--------------------
>>   sound/soc/qcom/lpass.h     | 18 +++++-----
>>   2 files changed, 61 insertions(+), 46 deletions(-)
>>
>> diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
>> index dbce7e9..492f27b 100644
>> --- a/sound/soc/qcom/lpass-cpu.c
>> +++ b/sound/soc/qcom/lpass-cpu.c
>> @@ -23,13 +23,15 @@ static int lpass_cpu_daiops_set_sysclk(struct 
>> snd_soc_dai *dai, int clk_id,
>>           unsigned int freq, int dir)
>>   {
>>       struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
>> -    int ret;
>> -
>> -    ret = clk_set_rate(drvdata->mi2s_osr_clk[dai->driver->id], freq);
>> -    if (ret)
>> -        dev_err(dai->dev, "error setting mi2s osrclk to %u: %d\n",
>> -            freq, ret);
>> +    struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id];
>> +    int ret = 0;
>>   +    if (dai_data->osr_clk != NULL) {
>> +        ret = clk_set_rate(dai_data->osr_clk, freq);
>> +        if (ret)
>> +            dev_err(dai->dev, "error setting mi2s osrclk to %u:%d\n",
>> +                freq, ret);
>> +    }
>>       return ret;
>>   }
>>   @@ -37,18 +39,22 @@ static int lpass_cpu_daiops_startup(struct 
>> snd_pcm_substream *substream,
>>           struct snd_soc_dai *dai)
>>   {
>>       struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
>> +    struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id];
>>       int ret;
>>   -    ret = clk_prepare_enable(drvdata->mi2s_osr_clk[dai->driver->id]);
>> -    if (ret) {
>> -        dev_err(dai->dev, "error in enabling mi2s osr clk: %d\n", ret);
>> -        return ret;
>> +    if (dai_data->osr_clk != NULL) {
>> +        ret = clk_prepare_enable(dai_data->osr_clk);
>> +        if (ret) {
>> +            dev_err(dai->dev,
>> +                "error in enabling mi2s osr clk: %d\n", ret);
>> +            return ret;
>> +        }
>>       }
>>   -    ret = clk_prepare_enable(drvdata->mi2s_bit_clk[dai->driver->id]);
>> +    ret = clk_prepare_enable(dai_data->bit_clk);
>>       if (ret) {
>>           dev_err(dai->dev, "error in enabling mi2s bit clk: %d\n", 
>> ret);
>> - clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]);
>> +        clk_disable_unprepare(dai_data->osr_clk);
>>           return ret;
>>       }
>>   @@ -59,16 +65,18 @@ static void lpass_cpu_daiops_shutdown(struct 
>> snd_pcm_substream *substream,
>>           struct snd_soc_dai *dai)
>>   {
>>       struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
>> +    struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id];
>>   - clk_disable_unprepare(drvdata->mi2s_bit_clk[dai->driver->id]);
>> +    clk_disable_unprepare(dai_data->bit_clk);
>>   - clk_disable_unprepare(drvdata->mi2s_osr_clk[dai->driver->id]);
>> +    clk_disable_unprepare(dai_data->osr_clk);
>>   }
>>     static int lpass_cpu_daiops_hw_params(struct snd_pcm_substream 
>> *substream,
>>           struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
>>   {
>>       struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
>> +    struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id];
>>       snd_pcm_format_t format = params_format(params);
>>       unsigned int channels = params_channels(params);
>>       unsigned int rate = params_rate(params);
>> @@ -163,8 +171,7 @@ static int lpass_cpu_daiops_hw_params(struct 
>> snd_pcm_substream *substream,
>>           return ret;
>>       }
>>   -    ret = clk_set_rate(drvdata->mi2s_bit_clk[dai->driver->id],
>> -               rate * bitwidth * 2);
>> +    ret = clk_set_rate(dai_data->bit_clk, rate * bitwidth * 2);
>>       if (ret) {
>>           dev_err(dai->dev, "error setting mi2s bitclk to %u: %d\n",
>>               rate * bitwidth * 2, ret);
>> @@ -413,6 +420,25 @@ static bool lpass_cpu_regmap_volatile(struct 
>> device *dev, unsigned int reg)
>>       .cache_type = REGCACHE_FLAT,
>>   };
>>   +static int lpass_init_dai_clocks(struct device *dev,
>> +               struct lpass_data *drvdata)
>> +{
>> +    struct lpass_dai *dai;
>> +    struct lpass_variant *v = drvdata->variant;
>> +    int i;
>> +
>> +    for (i = 0; i < v->num_dai; i++) {
>> +
>> +        dai = drvdata->dai_priv[i];
>> +
>> +        dai->osr_clk = devm_clk_get_optional(dev,
>> +                             v->dai_osr_clk_names[i]);
>> +        dai->bit_clk = devm_clk_get(dev, v->dai_bit_clk_names[i]);
>> +    }
>> +
>> +    return 0;
>> +}
>> +
>>   int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)
>>   {
>>       struct lpass_data *drvdata;
>> @@ -421,7 +447,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct 
>> platform_device *pdev)
>>       struct lpass_variant *variant;
>>       struct device *dev = &pdev->dev;
>>       const struct of_device_id *match;
>> -    int ret, i, dai_id;
>> +    int ret, i;
>>         dsp_of_node = of_parse_phandle(pdev->dev.of_node, 
>> "qcom,adsp", 0);
>>       if (dsp_of_node) {
>> @@ -467,28 +493,15 @@ int asoc_qcom_lpass_cpu_platform_probe(struct 
>> platform_device *pdev)
>>           variant->init(pdev);
>>         for (i = 0; i < variant->num_dai; i++) {
>> -        dai_id = variant->dai_driver[i].id;
>> -        drvdata->mi2s_osr_clk[dai_id] = devm_clk_get(&pdev->dev,
>> -                         variant->dai_osr_clk_names[i]);
>> -        if (IS_ERR(drvdata->mi2s_osr_clk[dai_id])) {
>> -            dev_warn(&pdev->dev,
>> -                "%s() error getting optional %s: %ld\n",
>> -                __func__,
>> -                variant->dai_osr_clk_names[i],
>> -                PTR_ERR(drvdata->mi2s_osr_clk[dai_id]));
>> -
>> -            drvdata->mi2s_osr_clk[dai_id] = NULL;
>> -        }
>> +        drvdata->dai_priv[i] = devm_kzalloc(dev,
>> +                        sizeof(struct lpass_dai),
>> +                        GFP_KERNEL);
>> +    }
>>   -        drvdata->mi2s_bit_clk[dai_id] = devm_clk_get(&pdev->dev,
>> -                        variant->dai_bit_clk_names[i]);
>> -        if (IS_ERR(drvdata->mi2s_bit_clk[dai_id])) {
>> -            dev_err(&pdev->dev,
>> -                "error getting %s: %ld\n",
>> -                variant->dai_bit_clk_names[i],
>> -                PTR_ERR(drvdata->mi2s_bit_clk[dai_id]));
>> -            return PTR_ERR(drvdata->mi2s_bit_clk[dai_id]);
>> -        }
>> +    ret = lpass_init_dai_clocks(dev, drvdata);
>> +    if (ret) {
>> +        dev_err(&pdev->dev, "error intializing dai clock: %d\n", ret);
>> +        return ret;
>>       }
>>         drvdata->ahbix_clk = devm_clk_get(&pdev->dev, "ahbix-clk");
>> diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
>> index 17113d3..b729686 100644
>> --- a/sound/soc/qcom/lpass.h
>> +++ b/sound/soc/qcom/lpass.h
>> @@ -13,9 +13,14 @@
>>   #include <linux/platform_device.h>
>>   #include <linux/regmap.h>
>>   -#define LPASS_AHBIX_CLOCK_FREQUENCY        131072000
>> -#define LPASS_MAX_MI2S_PORTS            (8)
>> -#define LPASS_MAX_DMA_CHANNELS            (8)
>> +#define LPASS_AHBIX_CLOCK_FREQUENCY            131072000
>> +#define LPASS_MAX_MI2S_PORTS                   (8)
>> +#define LPASS_MAX_DMA_CHANNELS                 (8)
>> +
>> +struct lpass_dai {
>> +    struct clk *osr_clk;
>> +    struct clk *bit_clk;
>> +};
>>     /* Both the CPU DAI and platform drivers will access this data */
>>   struct lpass_data {
>> @@ -23,11 +28,8 @@ struct lpass_data {
>>       /* AHB-I/X bus clocks inside the low-power audio subsystem 
>> (LPASS) */
>>       struct clk *ahbix_clk;
>>   -    /* MI2S system clock */
>> -    struct clk *mi2s_osr_clk[LPASS_MAX_MI2S_PORTS];
>> -
>> -    /* MI2S bit clock (derived from system clock by a divider */
>> -    struct clk *mi2s_bit_clk[LPASS_MAX_MI2S_PORTS];
>> +    /* MI2S dai specific configuration */
>> +    struct lpass_dai *dai_priv[LPASS_MAX_MI2S_PORTS];
>>         /* low-power audio interface (LPAIF) registers */
>>       void __iomem *lpaif;
>>

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 05/11] ASoC: qcom: lpass: Add support for newer lpass version
  2020-04-16  7:56   ` Srinivas Kandagatla
@ 2020-04-25 14:14     ` Ajit Pandey
  0 siblings, 0 replies; 21+ messages in thread
From: Ajit Pandey @ 2020-04-25 14:14 UTC (permalink / raw)
  To: Srinivas Kandagatla, alsa-devel, broonie, devicetree, plai, bgoswami
  Cc: linux-kernel, tiwai

On 4/16/2020 1:26 PM, Srinivas Kandagatla wrote:
>
>
> On 11/04/2020 09:02, Ajit Pandey wrote:
>> Few control registers bit offset of lpaif in newer lpass variants
>> are changed. Added "id" field in variant struct and changes macros
>> configuration of registers to calculate bit mask & offset based on
>> variant id.
>>
>
> These fields are handled much nicely with regmap_field, you should 
> consider using that. If not we will add overhead of check for every mask.

Sure i'll try  to add this support using regmap_field API's during v2 
patch chain

Thanks & Regards

Ajit

>
>
>> Signed-off-by: Ajit Pandey <ajitp@codeaurora.org>
>> ---
>>   sound/soc/qcom/lpass-cpu.c       |  77 +++++++++--------
>>   sound/soc/qcom/lpass-lpaif-reg.h | 182 
>> ++++++++++++++++++++++++++++++++++++++-
>>   sound/soc/qcom/lpass-platform.c  |  31 +++----
>>   sound/soc/qcom/lpass.h           |   6 ++
>>   4 files changed, 241 insertions(+), 55 deletions(-)
>>
>> diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
>> index f177932..006ba5a 100644
>> --- a/sound/soc/qcom/lpass-cpu.c
>> +++ b/sound/soc/qcom/lpass-cpu.c
>> @@ -77,6 +77,7 @@ static int lpass_cpu_daiops_hw_params(struct 
>> snd_pcm_substream *substream,
>>   {
>>       struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
>>       struct lpass_dai *dai_data = drvdata->dai_priv[dai->driver->id];
>> +    struct lpass_variant *v = drvdata->variant;
>>       snd_pcm_format_t format = params_format(params);
>>       unsigned int channels = params_channels(params);
>>       unsigned int rate = params_rate(params);
>> @@ -89,18 +90,18 @@ static int lpass_cpu_daiops_hw_params(struct 
>> snd_pcm_substream *substream,
>>           return bitwidth;
>>       }
>>   -    regval = LPAIF_I2SCTL_LOOPBACK_DISABLE |
>> -            LPAIF_I2SCTL_WSSRC_INTERNAL;
>> +    regval = LPAIF_I2SCTL(v, LOOPBACK_DISABLE);
>> +    regval |= LPAIF_I2SCTL(v, WSSRC_INTERNAL);
>>         switch (bitwidth) {
>>       case 16:
>> -        regval |= LPAIF_I2SCTL_BITWIDTH_16;
>> +        regval |= LPAIF_I2SCTL(v, BITWIDTH_16);
>>           break;
>>       case 24:
>> -        regval |= LPAIF_I2SCTL_BITWIDTH_24;
>> +        regval |= LPAIF_I2SCTL(v, BITWIDTH_24);
>>           break;
>>       case 32:
>> -        regval |= LPAIF_I2SCTL_BITWIDTH_32;
>> +        regval |= LPAIF_I2SCTL(v, BITWIDTH_32);
>>           break;
>>       default:
>>           dev_err(dai->dev, "invalid bitwidth given: %d\n", bitwidth);
>> @@ -110,24 +111,24 @@ static int lpass_cpu_daiops_hw_params(struct 
>> snd_pcm_substream *substream,
>>       if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
>>           switch (channels) {
>>           case 1:
>> -            regval |= LPAIF_I2SCTL_SPKMODE_SD0;
>> -            regval |= LPAIF_I2SCTL_SPKMONO_MONO;
>> +            regval |= LPAIF_I2SCTL(v, SPKMODE_SD0);
>> +            regval |= LPAIF_I2SCTL(v, SPKMONO_MONO);
>>               break;
>>           case 2:
>> -            regval |= LPAIF_I2SCTL_SPKMODE_SD0;
>> -            regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
>> +            regval |= LPAIF_I2SCTL(v, SPKMODE_SD0);
>> +            regval |= LPAIF_I2SCTL(v, SPKMONO_STEREO);
>>               break;
>>           case 4:
>> -            regval |= LPAIF_I2SCTL_SPKMODE_QUAD01;
>> -            regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
>> +            regval |= LPAIF_I2SCTL(v, SPKMODE_QUAD01);
>> +            regval |= LPAIF_I2SCTL(v, SPKMONO_STEREO);
>>               break;
>>           case 6:
>> -            regval |= LPAIF_I2SCTL_SPKMODE_6CH;
>> -            regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
>> +            regval |= LPAIF_I2SCTL(v, SPKMODE_6CH);
>> +            regval |= LPAIF_I2SCTL(v, SPKMONO_STEREO);
>>               break;
>>           case 8:
>> -            regval |= LPAIF_I2SCTL_SPKMODE_8CH;
>> -            regval |= LPAIF_I2SCTL_SPKMONO_STEREO;
>> +            regval |= LPAIF_I2SCTL(v, SPKMODE_8CH);
>> +            regval |= LPAIF_I2SCTL(v, SPKMONO_STEREO);
>>               break;
>>           default:
>>               dev_err(dai->dev, "invalid channels given: %u\n",
>> @@ -137,24 +138,24 @@ static int lpass_cpu_daiops_hw_params(struct 
>> snd_pcm_substream *substream,
>>       } else {
>>           switch (channels) {
>>           case 1:
>> -            regval |= LPAIF_I2SCTL_MICMODE_SD0;
>> -            regval |= LPAIF_I2SCTL_MICMONO_MONO;
>> +            regval |= LPAIF_I2SCTL(v, MICMODE_SD0);
>> +            regval |= LPAIF_I2SCTL(v, MICMONO_MONO);
>>               break;
>>           case 2:
>> -            regval |= LPAIF_I2SCTL_MICMODE_SD0;
>> -            regval |= LPAIF_I2SCTL_MICMONO_STEREO;
>> +            regval |= LPAIF_I2SCTL(v, MICMODE_SD0);
>> +            regval |= LPAIF_I2SCTL(v, MICMONO_STEREO);
>>               break;
>>           case 4:
>> -            regval |= LPAIF_I2SCTL_MICMODE_QUAD01;
>> -            regval |= LPAIF_I2SCTL_MICMONO_STEREO;
>> +            regval |= LPAIF_I2SCTL(v, MICMODE_QUAD01);
>> +            regval |= LPAIF_I2SCTL(v, MICMONO_STEREO);
>>               break;
>>           case 6:
>> -            regval |= LPAIF_I2SCTL_MICMODE_6CH;
>> -            regval |= LPAIF_I2SCTL_MICMONO_STEREO;
>> +            regval |= LPAIF_I2SCTL(v, MICMODE_6CH);
>> +            regval |= LPAIF_I2SCTL(v, MICMONO_STEREO);
>>               break;
>>           case 8:
>> -            regval |= LPAIF_I2SCTL_MICMODE_8CH;
>> -            regval |= LPAIF_I2SCTL_MICMONO_STEREO;
>> +            regval |= LPAIF_I2SCTL(v, MICMODE_8CH);
>> +            regval |= LPAIF_I2SCTL(v, MICMONO_STEREO);
>>               break;
>>           default:
>>               dev_err(dai->dev, "invalid channels given: %u\n",
>> @@ -200,15 +201,16 @@ static int lpass_cpu_daiops_prepare(struct 
>> snd_pcm_substream *substream,
>>           struct snd_soc_dai *dai)
>>   {
>>       struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
>> +    struct lpass_variant *v = drvdata->variant;
>>       int ret;
>>       unsigned int val, mask;
>>         if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
>> -        val = LPAIF_I2SCTL_SPKEN_ENABLE;
>> -        mask = LPAIF_I2SCTL_SPKEN_MASK;
>> +        val = LPAIF_I2SCTL(v, SPKEN_ENABLE);
>> +        mask = LPAIF_I2SCTL(v, SPKEN_MASK);
>>       } else  {
>> -        val = LPAIF_I2SCTL_MICEN_ENABLE;
>> -        mask = LPAIF_I2SCTL_MICEN_MASK;
>> +        val = LPAIF_I2SCTL(v, MICEN_ENABLE);
>> +        mask = LPAIF_I2SCTL(v, MICEN_MASK);
>>       }
>>         ret = regmap_update_bits(drvdata->lpaif_map,
>> @@ -224,6 +226,7 @@ static int lpass_cpu_daiops_trigger(struct 
>> snd_pcm_substream *substream,
>>           int cmd, struct snd_soc_dai *dai)
>>   {
>>       struct lpass_data *drvdata = snd_soc_dai_get_drvdata(dai);
>> +    struct lpass_variant *v = drvdata->variant;
>>       int ret = -EINVAL;
>>       unsigned int val, mask;
>>   @@ -232,11 +235,11 @@ static int lpass_cpu_daiops_trigger(struct 
>> snd_pcm_substream *substream,
>>       case SNDRV_PCM_TRIGGER_RESUME:
>>       case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
>>           if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
>> -            val = LPAIF_I2SCTL_SPKEN_ENABLE;
>> -            mask = LPAIF_I2SCTL_SPKEN_MASK;
>> +            val = LPAIF_I2SCTL(v, SPKEN_ENABLE);
>> +            mask = LPAIF_I2SCTL(v, SPKEN_MASK);
>>           } else  {
>> -            val = LPAIF_I2SCTL_MICEN_ENABLE;
>> -            mask = LPAIF_I2SCTL_MICEN_MASK;
>> +            val = LPAIF_I2SCTL(v, MICEN_ENABLE);
>> +            mask = LPAIF_I2SCTL(v, MICEN_MASK);
>>           }
>>             ret = regmap_update_bits(drvdata->lpaif_map,
>> @@ -251,11 +254,11 @@ static int lpass_cpu_daiops_trigger(struct 
>> snd_pcm_substream *substream,
>>       case SNDRV_PCM_TRIGGER_SUSPEND:
>>       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
>>           if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
>> -            val = LPAIF_I2SCTL_SPKEN_DISABLE;
>> -            mask = LPAIF_I2SCTL_SPKEN_MASK;
>> +            val = LPAIF_I2SCTL(v, SPKEN_DISABLE);
>> +            mask = LPAIF_I2SCTL(v, SPKEN_MASK);
>>           } else  {
>> -            val = LPAIF_I2SCTL_MICEN_DISABLE;
>> -            mask = LPAIF_I2SCTL_MICEN_MASK;
>> +            val = LPAIF_I2SCTL(v, MICEN_DISABLE);
>> +            mask = LPAIF_I2SCTL(v, MICEN_MASK);
>>           }
>>             ret = regmap_update_bits(drvdata->lpaif_map,
>> diff --git a/sound/soc/qcom/lpass-lpaif-reg.h 
>> b/sound/soc/qcom/lpass-lpaif-reg.h
>> index 3d74ae1..4251aa6 100644
>> --- a/sound/soc/qcom/lpass-lpaif-reg.h
>> +++ b/sound/soc/qcom/lpass-lpaif-reg.h
>> @@ -17,11 +17,28 @@
>>   #define LPAIF_I2SCTL_LOOPBACK_DISABLE    (0 << 
>> LPAIF_I2SCTL_LOOPBACK_SHIFT)
>>   #define LPAIF_I2SCTL_LOOPBACK_ENABLE    (1 << 
>> LPAIF_I2SCTL_LOOPBACK_SHIFT)
>>   +#define LPAIF_I2SCTL_LOOPBACK_MASK_V2     0x20000
>> +#define LPAIF_I2SCTL_LOOPBACK_SHIFT_V2     17
>> +#define LPAIF_I2SCTL_LOOPBACK_DISABLE_V2 (0 << 
>> LPAIF_I2SCTL_LOOPBACK_SHIFT_V2)
>> +#define LPAIF_I2SCTL_LOOPBACK_ENABLE_V2     (1 << 
>> LPAIF_I2SCTL_LOOPBACK_SHIFT_V2)
>> +
>>   #define LPAIF_I2SCTL_SPKEN_MASK        0x4000
>>   #define LPAIF_I2SCTL_SPKEN_SHIFT    14
>>   #define LPAIF_I2SCTL_SPKEN_DISABLE    (0 << LPAIF_I2SCTL_SPKEN_SHIFT)
>>   #define LPAIF_I2SCTL_SPKEN_ENABLE    (1 << LPAIF_I2SCTL_SPKEN_SHIFT)
>>   +#define LPAIF_I2SCTL_SPKEN_MASK_V2    0x10000
>> +#define LPAIF_I2SCTL_SPKEN_SHIFT_V2    16
>> +#define LPAIF_I2SCTL_SPKEN_DISABLE_V2    (0 << 
>> LPAIF_I2SCTL_SPKEN_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKEN_ENABLE_V2    (1 << 
>> LPAIF_I2SCTL_SPKEN_SHIFT_V2)
>> +
>> +#define __LPAIF_I2S_CTL(v, bit)  \
>> +    ((v->id ==  LPASS_VARIANT_V2) ? \
>> +        LPAIF_I2SCTL_##bit##_V2 : \
>> +        LPAIF_I2SCTL_##bit)
>> +
>> +#define LPAIF_I2SCTL(v, bit)        __LPAIF_I2S_CTL(v, bit)
>> +
>>   #define LPAIF_I2SCTL_SPKMODE_MASK    0x3C00
>>   #define LPAIF_I2SCTL_SPKMODE_SHIFT    10
>>   #define LPAIF_I2SCTL_SPKMODE_NONE    (0 << LPAIF_I2SCTL_SPKMODE_SHIFT)
>> @@ -34,16 +51,49 @@
>>   #define LPAIF_I2SCTL_SPKMODE_6CH    (7 << LPAIF_I2SCTL_SPKMODE_SHIFT)
>>   #define LPAIF_I2SCTL_SPKMODE_8CH    (8 << LPAIF_I2SCTL_SPKMODE_SHIFT)
>>   +#define LPAIF_I2SCTL_SPKMODE_MASK_V2    0xF800
>> +#define LPAIF_I2SCTL_SPKMODE_SHIFT_V2    11
>> +#define LPAIF_I2SCTL_SPKMODE_NONE_V2    (0 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_SD0_V2    (1 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_SD1_V2    (2 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_SD2_V2    (3 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_SD3_V2    (4 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_QUAD01_V2    (5 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_QUAD23_V2    (6 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_6CH_V2    (7 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_8CH_V2    (8 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_10CH_V2    (9 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_12CH_V2    (10 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_14CH_V2    (11 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_16CH_V2    (12 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_SD4_V2    (13 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_SD5_V2    (14 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_SD6_V2    (15 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_SD7_V2    (16 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_QUAD45_V2    (17 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_QUAD47_V2    (18 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMODE_8CH_2_V2    (19 << 
>> LPAIF_I2SCTL_SPKMODE_SHIFT_V2)
>> +
>>   #define LPAIF_I2SCTL_SPKMONO_MASK    0x0200
>>   #define LPAIF_I2SCTL_SPKMONO_SHIFT    9
>>   #define LPAIF_I2SCTL_SPKMONO_STEREO    (0 << 
>> LPAIF_I2SCTL_SPKMONO_SHIFT)
>>   #define LPAIF_I2SCTL_SPKMONO_MONO    (1 << LPAIF_I2SCTL_SPKMONO_SHIFT)
>>   +#define LPAIF_I2SCTL_SPKMONO_MASK_V2    0x0400
>> +#define LPAIF_I2SCTL_SPKMONO_SHIFT_V2    10
>> +#define LPAIF_I2SCTL_SPKMONO_STEREO_V2    (0 << 
>> LPAIF_I2SCTL_SPKMONO_SHIFT_V2)
>> +#define LPAIF_I2SCTL_SPKMONO_MONO_V2    (1 << 
>> LPAIF_I2SCTL_SPKMONO_SHIFT_V2)
>> +
>>   #define LPAIF_I2SCTL_MICEN_MASK        GENMASK(8, 8)
>>   #define LPAIF_I2SCTL_MICEN_SHIFT    8
>>   #define LPAIF_I2SCTL_MICEN_DISABLE    (0 << LPAIF_I2SCTL_MICEN_SHIFT)
>>   #define LPAIF_I2SCTL_MICEN_ENABLE    (1 << LPAIF_I2SCTL_MICEN_SHIFT)
>>   +#define LPAIF_I2SCTL_MICEN_MASK_V2    0x0200
>> +#define LPAIF_I2SCTL_MICEN_SHIFT_V2    9
>> +#define LPAIF_I2SCTL_MICEN_DISABLE_V2    (0 << 
>> LPAIF_I2SCTL_MICEN_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICEN_ENABLE_V2    (1 << 
>> LPAIF_I2SCTL_MICEN_SHIFT_V2)
>> +
>>   #define LPAIF_I2SCTL_MICMODE_MASK    GENMASK(7, 4)
>>   #define LPAIF_I2SCTL_MICMODE_SHIFT    4
>>   #define LPAIF_I2SCTL_MICMODE_NONE    (0 << LPAIF_I2SCTL_MICMODE_SHIFT)
>> @@ -56,22 +106,61 @@
>>   #define LPAIF_I2SCTL_MICMODE_6CH    (7 << LPAIF_I2SCTL_MICMODE_SHIFT)
>>   #define LPAIF_I2SCTL_MICMODE_8CH    (8 << LPAIF_I2SCTL_MICMODE_SHIFT)
>>   +#define LPAIF_I2SCTL_MICMODE_MASK_V2    GENMASK(8, 4)
>> +#define LPAIF_I2SCTL_MICMODE_SHIFT_V2    4
>> +#define LPAIF_I2SCTL_MICMODE_NONE_V2    (0 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_SD0_V2    (1 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_SD1_V2    (2 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_SD2_V2    (3 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_SD3_V2    (4 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_QUAD01_V2    (5 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_QUAD23_V2    (6 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_6CH_V2    (7 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_8CH_V2    (8 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_10CH_V2    (9 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_12CH_V2    (10 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_14CH_V2    (11 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_16CH_V2    (12 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_SD4_V2    (13 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_SD5_V2    (14 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_SD6_V2    (15 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_SD7_V2    (16 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_QUAD45_V2    (17 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_QUAD47_V2    (18 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMODE_8CH_2_V2    (19 << 
>> LPAIF_I2SCTL_MICMODE_SHIFT_V2)
>> +
>>   #define LPAIF_I2SCTL_MIMONO_MASK    GENMASK(3, 3)
>>   #define LPAIF_I2SCTL_MICMONO_SHIFT    3
>>   #define LPAIF_I2SCTL_MICMONO_STEREO    (0 << 
>> LPAIF_I2SCTL_MICMONO_SHIFT)
>>   #define LPAIF_I2SCTL_MICMONO_MONO    (1 << LPAIF_I2SCTL_MICMONO_SHIFT)
>>   +#define LPAIF_I2SCTL_MICMONO_MASK_V2    GENMASK(3, 3)
>> +#define LPAIF_I2SCTL_MICMONO_SHIFT_V2    3
>> +#define LPAIF_I2SCTL_MICMONO_STEREO_V2    (0 << 
>> LPAIF_I2SCTL_MICMONO_SHIFT_V2)
>> +#define LPAIF_I2SCTL_MICMONO_MONO_V2    (1 << 
>> LPAIF_I2SCTL_MICMONO_SHIFT_V2)
>> +
>>   #define LPAIF_I2SCTL_WSSRC_MASK        0x0004
>>   #define LPAIF_I2SCTL_WSSRC_SHIFT    2
>>   #define LPAIF_I2SCTL_WSSRC_INTERNAL    (0 << LPAIF_I2SCTL_WSSRC_SHIFT)
>>   #define LPAIF_I2SCTL_WSSRC_EXTERNAL    (1 << LPAIF_I2SCTL_WSSRC_SHIFT)
>>   +#define LPAIF_I2SCTL_WSSRC_MASK_V2    0x0004
>> +#define LPAIF_I2SCTL_WSSRC_SHIFT_V2    2
>> +#define LPAIF_I2SCTL_WSSRC_INTERNAL_V2    (0 << 
>> LPAIF_I2SCTL_WSSRC_SHIFT_V2)
>> +#define LPAIF_I2SCTL_WSSRC_EXTERNAL_V2    (1 << 
>> LPAIF_I2SCTL_WSSRC_SHIFT_V2)
>> +
>>   #define LPAIF_I2SCTL_BITWIDTH_MASK    0x0003
>>   #define LPAIF_I2SCTL_BITWIDTH_SHIFT    0
>>   #define LPAIF_I2SCTL_BITWIDTH_16    (0 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
>>   #define LPAIF_I2SCTL_BITWIDTH_24    (1 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
>>   #define LPAIF_I2SCTL_BITWIDTH_32    (2 << LPAIF_I2SCTL_BITWIDTH_SHIFT)
>>   +#define LPAIF_I2SCTL_BITWIDTH_MASK_V2    0x0003
>> +#define LPAIF_I2SCTL_BITWIDTH_SHIFT_V2    0
>> +#define LPAIF_I2SCTL_BITWIDTH_16_V2    (0 << 
>> LPAIF_I2SCTL_BITWIDTH_SHIFT_V2)
>> +#define LPAIF_I2SCTL_BITWIDTH_24_V2    (1 << 
>> LPAIF_I2SCTL_BITWIDTH_SHIFT_V2)
>> +#define LPAIF_I2SCTL_BITWIDTH_32_V2    (2 << 
>> LPAIF_I2SCTL_BITWIDTH_SHIFT_V2)
>> +
>>   /* LPAIF IRQ */
>>   #define LPAIF_IRQ_REG_ADDR(v, addr, port) \
>>       (v->irq_reg_base + (addr) + v->irq_reg_stride * (port))
>> @@ -91,7 +180,6 @@
>>   #define LPAIF_IRQ_ALL(chan)        (7 << (LPAIF_IRQ_BITSTRIDE * 
>> (chan)))
>>     /* LPAIF DMA */
>> -
>>   #define LPAIF_RDMA_REG_ADDR(v, addr, chan) \
>>       (v->rdma_reg_base + (addr) + v->rdma_reg_stride * (chan))
>>   @@ -143,7 +231,7 @@
>>     #define LPAIF_DMACTL_AUDINTF_MASK    0x0F0
>>   #define LPAIF_DMACTL_AUDINTF_SHIFT    4
>> -#define LPAIF_DMACTL_AUDINTF(id)    (id << LPAIF_DMACTL_AUDINTF_SHIFT)
>> +#define LPAIF_DMACTL_AUDINTF(port)    (port << 
>> LPAIF_DMACTL_AUDINTF_SHIFT)
>>     #define LPAIF_DMACTL_FIFOWM_MASK    0x00E
>>   #define LPAIF_DMACTL_FIFOWM_SHIFT    1
>> @@ -158,11 +246,99 @@
>>     #define LPAIF_DMACTL_ENABLE_MASK    0x1
>>   #define LPAIF_DMACTL_ENABLE_SHIFT    0
>> -#define LPAIF_DMACTL_ENABLE_OFF    (0 << LPAIF_DMACTL_ENABLE_SHIFT)
>> +#define LPAIF_DMACTL_ENABLE_OFF        (0 << LPAIF_DMACTL_ENABLE_SHIFT)
>>   #define LPAIF_DMACTL_ENABLE_ON        (1 << LPAIF_DMACTL_ENABLE_SHIFT)
>>   +#define LPAIF_IRQ_BITSTRIDE        3
>> +
>> +#define LPAIF_IRQ_PER(chan)        (1 << (LPAIF_IRQ_BITSTRIDE * 
>> (chan)))
>> +#define LPAIF_IRQ_XRUN(chan)        (2 << (LPAIF_IRQ_BITSTRIDE * 
>> (chan)))
>> +#define LPAIF_IRQ_ERR(chan)        (4 << (LPAIF_IRQ_BITSTRIDE * 
>> (chan)))
>> +
>> +#define LPAIF_IRQ_ALL(chan)        (7 << (LPAIF_IRQ_BITSTRIDE * 
>> (chan)))
>> +
>>   #define LPAIF_DMACTL_DYNCLK_MASK    BIT(12)
>>   #define LPAIF_DMACTL_DYNCLK_SHIFT    12
>>   #define LPAIF_DMACTL_DYNCLK_OFF    (0 << LPAIF_DMACTL_DYNCLK_SHIFT)
>>   #define LPAIF_DMACTL_DYNCLK_ON        (1 << LPAIF_DMACTL_DYNCLK_SHIFT)
>> +
>> +#define LPAIF_DMACTL_BURSTEN_MASK_V2    0x100000
>> +#define LPAIF_DMACTL_BURSTEN_SHIFT_V2    20
>> +#define LPAIF_DMACTL_BURSTEN_SINGLE_V2    (0 << 
>> LPAIF_DMACTL_BURSTEN_SHIFT_V2)
>> +#define LPAIF_DMACTL_BURSTEN_INCR4_V2    (1 << 
>> LPAIF_DMACTL_BURSTEN_SHIFT_V2)
>> +
>> +#define LPAIF_DMACTL_WPSCNT_MASK_V2    0xF0000
>> +#define LPAIF_DMACTL_WPSCNT_SHIFT_V2    16
>> +#define LPAIF_DMACTL_WPSCNT_ONE_V2    (0 << 
>> LPAIF_DMACTL_WPSCNT_SHIFT_V2)
>> +#define LPAIF_DMACTL_WPSCNT_TWO_V2    (1 << 
>> LPAIF_DMACTL_WPSCNT_SHIFT_V2)
>> +#define LPAIF_DMACTL_WPSCNT_THREE_V2    (2 << 
>> LPAIF_DMACTL_WPSCNT_SHIFT_V2)
>> +#define LPAIF_DMACTL_WPSCNT_FOUR_V2    (3 << 
>> LPAIF_DMACTL_WPSCNT_SHIFT_V2)
>> +#define LPAIF_DMACTL_WPSCNT_SIX_V2    (5 << 
>> LPAIF_DMACTL_WPSCNT_SHIFT_V2)
>> +#define LPAIF_DMACTL_WPSCNT_EIGHT_V2    (7 << 
>> LPAIF_DMACTL_WPSCNT_SHIFT_V2)
>> +#define LPAIF_DMACTL_WPSCNT_TEN_V2    (9 << 
>> LPAIF_DMACTL_WPSCNT_SHIFT_V2)
>> +#define LPAIF_DMACTL_WPSCNT_TWELVE_V2    (11 << 
>> LPAIF_DMACTL_WPSCNT_SHIFT_V2)
>> +#define LPAIF_DMACTL_WPSCNT_FOURTEEN_V2    (13 << 
>> LPAIF_DMACTL_WPSCNT_SHIFT_V2)
>> +#define LPAIF_DMACTL_WPSCNT_SIXTEEN_V2    (15 << 
>> LPAIF_DMACTL_WPSCNT_SHIFT_V2)
>> +
>> +#define LPAIF_DMACTL_AUDINTF_MASK_V2    0xF000
>> +#define LPAIF_DMACTL_AUDINTF_SHIFT_V2    12
>> +#define LPAIF_DMACTL_AUDINTF_V2(port)    (port << 
>> LPAIF_DMACTL_AUDINTF_SHIFT_V2)
>> +
>> +#define LPAIF_DMACTL_AUD_INTF(v, port)  \
>> +    ((v->id ==  LPASS_VARIANT_V2) ? \
>> +        LPAIF_DMACTL_AUDINTF_V2(port) : \
>> +        LPAIF_DMACTL_AUDINTF(port))
>> +
>> +#define LPAIF_DMACTL_FIFOWM_MASK_V2    0x3E
>> +#define LPAIF_DMACTL_FIFOWM_SHIFT_V2    1
>> +#define LPAIF_DMACTL_FIFOWM_1_V2    (0 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_2_V2    (1 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_3_V2    (2 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_4_V2    (3 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_5_V2    (4 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_6_V2    (5 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_7_V2    (6 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_8_V2    (7 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_9_V2    (8 << LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_10_V2    (9 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_11_V2    (10 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_12_V2    (11 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_13_V2    (12 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_14_V2    (13 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_15_V2    (14 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_16_V2    (15 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_17_V2    (16 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_18_V2    (17 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_19_V2    (18 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_20_V2    (19 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_21_V2    (20 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_22_V2    (21 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_23_V2    (22 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_24_V2    (23 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_25_V2    (24 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_26_V2    (25 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_27_V2    (26 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_28_V2    (27 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_29_V2    (28 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_30_V2    (29 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_31_V2    (30 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +#define LPAIF_DMACTL_FIFOWM_32_V2    (31 << 
>> LPAIF_DMACTL_FIFOWM_SHIFT_V2)
>> +
>> +#define LPAIF_DMACTL_ENABLE_MASK_V2    0x1
>> +#define LPAIF_DMACTL_ENABLE_SHIFT_V2    0
>> +#define LPAIF_DMACTL_ENABLE_OFF_V2    (0 << 
>> LPAIF_DMACTL_ENABLE_SHIFT_V2)
>> +#define LPAIF_DMACTL_ENABLE_ON_V2    (1 << 
>> LPAIF_DMACTL_ENABLE_SHIFT_V2)
>> +
>> +#define LPAIF_DMACTL_DYNCLK_MASK_V2    BIT(21)
>> +#define LPAIF_DMACTL_DYNCLK_SHIFT_V2    21
>> +#define LPAIF_DMACTL_DYNCLK_OFF_V2    (0 << 
>> LPAIF_DMACTL_DYNCLK_SHIFT_V2)
>> +#define LPAIF_DMACTL_DYNCLK_ON_V2    (1 << 
>> LPAIF_DMACTL_DYNCLK_SHIFT_V2)
>> +
>> +#define __LPAIF_DMA_CTL(v, bit)  \
>> +    ((v->id ==  LPASS_VARIANT_V2) ? \
>> +        LPAIF_DMACTL_##bit##_V2 : \
>> +        LPAIF_DMACTL_##bit)
>> +
>> +#define LPAIF_DMACTL(v, bit)        __LPAIF_DMA_CTL(v, bit)
>> +
>>   #endif /* __LPASS_LPAIF_REG_H__ */
>> diff --git a/sound/soc/qcom/lpass-platform.c 
>> b/sound/soc/qcom/lpass-platform.c
>> index b05091c2..821599e 100644
>> --- a/sound/soc/qcom/lpass-platform.c
>> +++ b/sound/soc/qcom/lpass-platform.c
>> @@ -146,25 +146,26 @@ static int 
>> lpass_platform_pcmops_hw_params(struct snd_soc_component *component,
>>           return bitwidth;
>>       }
>>   -    regval = LPAIF_DMACTL_BURSTEN_INCR4 |
>> -            LPAIF_DMACTL_AUDINTF(dma_port) |
>> -            LPAIF_DMACTL_FIFOWM_8;
>> +
>> +    regval = LPAIF_DMACTL(v, BURSTEN_INCR4);
>> +    regval |= LPAIF_DMACTL(v, FIFOWM_8);
>> +    regval |= LPAIF_DMACTL_AUD_INTF(v, dma_port);
>>         switch (bitwidth) {
>>       case 16:
>>           switch (channels) {
>>           case 1:
>>           case 2:
>> -            regval |= LPAIF_DMACTL_WPSCNT_ONE;
>> +            regval |= LPAIF_DMACTL(v, WPSCNT_ONE);
>>               break;
>>           case 4:
>> -            regval |= LPAIF_DMACTL_WPSCNT_TWO;
>> +            regval |= LPAIF_DMACTL(v, WPSCNT_TWO);
>>               break;
>>           case 6:
>> -            regval |= LPAIF_DMACTL_WPSCNT_THREE;
>> +            regval |= LPAIF_DMACTL(v, WPSCNT_THREE);
>>               break;
>>           case 8:
>> -            regval |= LPAIF_DMACTL_WPSCNT_FOUR;
>> +            regval |= LPAIF_DMACTL(v, WPSCNT_FOUR);
>>               break;
>>           default:
>>               dev_err(soc_runtime->dev,
>> @@ -177,19 +178,19 @@ static int 
>> lpass_platform_pcmops_hw_params(struct snd_soc_component *component,
>>       case 32:
>>           switch (channels) {
>>           case 1:
>> -            regval |= LPAIF_DMACTL_WPSCNT_ONE;
>> +            regval |= LPAIF_DMACTL(v, WPSCNT_ONE);
>>               break;
>>           case 2:
>> -            regval |= LPAIF_DMACTL_WPSCNT_TWO;
>> +            regval |= LPAIF_DMACTL(v, WPSCNT_TWO);
>>               break;
>>           case 4:
>> -            regval |= LPAIF_DMACTL_WPSCNT_FOUR;
>> +            regval |= LPAIF_DMACTL(v, WPSCNT_FOUR);
>>               break;
>>           case 6:
>> -            regval |= LPAIF_DMACTL_WPSCNT_SIX;
>> +            regval |= LPAIF_DMACTL(v, WPSCNT_SIX);
>>               break;
>>           case 8:
>> -            regval |= LPAIF_DMACTL_WPSCNT_EIGHT;
>> +            regval |= LPAIF_DMACTL(v, WPSCNT_EIGHT);
>>               break;
>>           default:
>>               dev_err(soc_runtime->dev,
>> @@ -277,7 +278,7 @@ static int lpass_platform_pcmops_prepare(struct 
>> snd_soc_component *component,
>>         ret = regmap_update_bits(drvdata->lpaif_map,
>>               LPAIF_DMACTL_REG(v, ch, dir),
>> -            LPAIF_DMACTL_ENABLE_MASK, LPAIF_DMACTL_ENABLE_ON);
>> +            LPAIF_DMACTL(v, ENABLE_MASK), LPAIF_DMACTL_ENABLE_ON);
>>       if (ret) {
>>           dev_err(soc_runtime->dev, "error writing to rdmactl reg: 
>> %d\n",
>>               ret);
>> @@ -326,7 +327,7 @@ static int lpass_platform_pcmops_trigger(struct 
>> snd_soc_component *component,
>>             ret = regmap_update_bits(drvdata->lpaif_map,
>>                   LPAIF_DMACTL_REG(v, ch, dir),
>> -                LPAIF_DMACTL_ENABLE_MASK,
>> +                LPAIF_DMACTL(v, ENABLE_MASK),
>>                   LPAIF_DMACTL_ENABLE_ON);
>>           if (ret) {
>>               dev_err(soc_runtime->dev,
>> @@ -339,7 +340,7 @@ static int lpass_platform_pcmops_trigger(struct 
>> snd_soc_component *component,
>>       case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
>>           ret = regmap_update_bits(drvdata->lpaif_map,
>>                   LPAIF_DMACTL_REG(v, ch, dir),
>> -                LPAIF_DMACTL_ENABLE_MASK,
>> +                LPAIF_DMACTL(v, ENABLE_MASK),
>>                   LPAIF_DMACTL_ENABLE_OFF);
>>           if (ret) {
>>               dev_err(soc_runtime->dev,
>> diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h
>> index 279cd02..384f4b8 100644
>> --- a/sound/soc/qcom/lpass.h
>> +++ b/sound/soc/qcom/lpass.h
>> @@ -17,6 +17,9 @@
>>   #define LPASS_MAX_MI2S_PORTS                   (8)
>>   #define LPASS_MAX_DMA_CHANNELS                 (8)
>>   +#define LPASS_VARIANT                0
>> +#define LPASS_VARIANT_V2            1
>> +
>>   struct lpass_dai {
>>       struct clk *osr_clk;
>>       struct clk *bit_clk;
>> @@ -91,6 +94,9 @@ struct lpass_variant {
>>       /* SOC specific clocks configuration */
>>       const char **clk_name;
>>       int num_clks;
>> +
>> +    /* LPASS Version id */
>> +    int id;
>
> May be spelling this out like "version_id" would make it more readable.
>
> thanks,
> srini
>
>
>>   };
>>     /* register the platform driver from the CPU DAI driver */
>>

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2020-04-25 14:14 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-04-11  8:02 [PATCH 00/11] ASoC: QCOM: Add support for SC7180 lpass variant Ajit Pandey
2020-04-11  8:02 ` [PATCH 01/11] Documentation: device-tree: sound: Update lpass-cpu driver binding Ajit Pandey
2020-04-16  7:53   ` Srinivas Kandagatla
2020-04-25 14:05     ` Ajit Pandey
2020-04-11  8:02 ` [PATCH 02/11] ASoC: qcom: lpass: Add struct lpass_dai to store dai clocks pointer Ajit Pandey
2020-04-16  7:56   ` Srinivas Kandagatla
2020-04-25 14:11     ` Ajit Pandey
2020-04-11  8:02 ` [PATCH 03/11] ASoC: qcom: Add common array to initialize soc based core clocks Ajit Pandey
2020-04-11  8:02 ` [PATCH 04/11] ASoC: qcom: lpass-cpu: Make "ahbix-clk" an optional clock Ajit Pandey
2020-04-16  7:56   ` Srinivas Kandagatla
2020-04-11  8:02 ` [PATCH 05/11] ASoC: qcom: lpass: Add support for newer lpass version Ajit Pandey
2020-04-16  7:56   ` Srinivas Kandagatla
2020-04-25 14:14     ` Ajit Pandey
2020-04-11  8:02 ` [PATCH 06/11] dt-bindings: sound: Add bindings related to lpass-cpu configuration Ajit Pandey
2020-04-11  8:02 ` [PATCH 07/11] Documentation: dt-bindings: sound: Add details for new dai properties Ajit Pandey
2020-04-16  7:56   ` Srinivas Kandagatla
2020-04-11  8:02 ` [PATCH 08/11] ASoC: qcom : lpass: Add support to configure dai's connection mode Ajit Pandey
2020-04-11  8:02 ` [PATCH 09/11] device-tree: bindings: sound: lpass-cpu: Add new compatible soc Ajit Pandey
2020-04-11  8:02 ` [PATCH 10/11] ASoC: qcom: lpass-sc7180: Add platform driver for lpass audio Ajit Pandey
2020-04-11  8:02 ` [PATCH 11/11] ASoC: qcom: lpass-platform: Replace card->dev with component->dev Ajit Pandey
2020-04-16  7:56   ` Srinivas Kandagatla

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).