Re: [PATCH v10 5/7] ASoC: qcom: Add support for lpass hdmi driver

2020-10-07 Thread Srinivasa Rao Mandadapu

Thanks for review comments Srinivas!!!

On 10/7/2020 2:00 AM, Srinivas Kandagatla wrote:

On 05/10/2020 05:48, Srinivasa Rao Mandadapu wrote:

From: V Sujith Kumar Reddy 

Upadate lpass cpu and platform driver to support audio over dp.
Also add lpass-hdmi.c and lpass-hdmi.h.

Signed-off-by: V Sujith Kumar Reddy 
Signed-off-by: Srinivasa Rao 
---
  sound/soc/qcom/Kconfig   |   5 +
  sound/soc/qcom/Makefile  |   2 +
  sound/soc/qcom/lpass-apq8016.c   |   4 +-
  sound/soc/qcom/lpass-cpu.c   |  51 -
  sound/soc/qcom/lpass-hdmi.c  | 468 
+++

  sound/soc/qcom/lpass-hdmi.h  | 106 +
  sound/soc/qcom/lpass-ipq806x.c   |   4 +-
  sound/soc/qcom/lpass-lpaif-reg.h |  52 -
  sound/soc/qcom/lpass-platform.c  | 391 
++--

  sound/soc/qcom/lpass.h   | 113 +-
  10 files changed, 1097 insertions(+), 99 deletions(-)
  create mode 100644 sound/soc/qcom/lpass-hdmi.c
  create mode 100644 sound/soc/qcom/lpass-hdmi.h


...


diff --git a/sound/soc/qcom/lpass-hdmi.c b/sound/soc/qcom/lpass-hdmi.c
new file mode 100644
index 000..ee737f0
--- /dev/null
+++ b/sound/soc/qcom/lpass-hdmi.c
@@ -0,0 +1,468 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ *
+ * lpass-hdmi.c -- ALSA SoC HDMI-CPU DAI driver for QTi LPASS HDMI
+ */
+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "lpass-lpaif-reg.h"
+#include "lpass.h"
+


[

+#define QCOM_REGMAP_FIELD_ALLOC(d, m, f, mf)    \
+    do { \
+    mf = devm_regmap_field_alloc(d, m, f); \
+    if (IS_ERR(mf))    \
+    return -EINVAL; \
+    } while (0)
+
+

]
should go into lpass.h


okay!. will move to lpass.h

[

+int lpass_hdmi_init_bitfields(struct device *dev, struct regmap *map)
+{
+    struct lpass_data *drvdata = dev_get_drvdata(dev);
+    struct lpass_variant *v = drvdata->variant;
+    unsigned int i;
+    struct lpass_hdmi_tx_ctl *tx_ctl;
+    struct regmap_field *legacy_en;
+    struct lpass_vbit_ctrl *vbit_ctl;
+    struct regmap_field *tx_parity;
+    struct lpass_dp_metadata_ctl *meta_ctl;
+    struct lpass_sstream_ctl *sstream_ctl;
+    struct regmap_field *ch_msb;
+    struct regmap_field *ch_lsb;
+    struct lpass_hdmitx_dmactl *tx_dmactl;
+    int rval;
+
+    tx_ctl = devm_kzalloc(dev, sizeof(*tx_ctl), GFP_KERNEL);
+    if (!tx_ctl)
+    return -ENOMEM;
+
+    QCOM_REGMAP_FIELD_ALLOC(dev, map, v->soft_reset, 
tx_ctl->soft_reset);
+    QCOM_REGMAP_FIELD_ALLOC(dev, map, v->force_reset, 
tx_ctl->force_reset);

+    drvdata->tx_ctl = tx_ctl;
+
+    QCOM_REGMAP_FIELD_ALLOC(dev, map, v->legacy_en, legacy_en);
+    drvdata->hdmitx_legacy_en = legacy_en;
+
+    vbit_ctl = devm_kzalloc(dev, sizeof(*vbit_ctl), GFP_KERNEL);
+    if (!vbit_ctl)
+    return -ENOMEM;
+
+    QCOM_REGMAP_FIELD_ALLOC(dev, map, v->replace_vbit, 
vbit_ctl->replace_vbit);
+    QCOM_REGMAP_FIELD_ALLOC(dev, map, v->vbit_stream, 
vbit_ctl->vbit_stream);

+    drvdata->vbit_ctl = vbit_ctl;
+
+
+    QCOM_REGMAP_FIELD_ALLOC(dev, map, v->calc_en, tx_parity);
+    drvdata->hdmitx_parity_calc_en = tx_parity;
+
+    meta_ctl = devm_kzalloc(dev, sizeof(*meta_ctl), GFP_KERNEL);
+    if (!meta_ctl)
+    return -ENOMEM;
+
+    rval = devm_regmap_field_bulk_alloc(dev, map, _ctl->mute, 
>mute, 7);

+    if (rval)
+    return rval;
+    drvdata->meta_ctl = meta_ctl;
+
+    sstream_ctl = devm_kzalloc(dev, sizeof(*sstream_ctl), GFP_KERNEL);
+    if (!sstream_ctl)
+    return -ENOMEM;
+
+    rval = devm_regmap_field_bulk_alloc(dev, map, 
_ctl->sstream_en, >sstream_en, 9);

+    if (rval)
+    return rval;
+
+    drvdata->sstream_ctl = sstream_ctl;
+
+    for (i = 0; i < LPASS_MAX_HDMI_DMA_CHANNELS; i++) {
+    QCOM_REGMAP_FIELD_ALLOC(dev, map, v->msb_bits, ch_msb);
+    drvdata->hdmitx_ch_msb[i] = ch_msb;
+
+    QCOM_REGMAP_FIELD_ALLOC(dev, map, v->lsb_bits, ch_lsb);
+    drvdata->hdmitx_ch_lsb[i] = ch_lsb;
+
+    tx_dmactl = devm_kzalloc(dev, sizeof(*tx_dmactl), GFP_KERNEL);
+    if (!tx_dmactl)
+    return -ENOMEM;
+
+    QCOM_REGMAP_FIELD_ALLOC(dev, map, v->use_hw_chs, 
tx_dmactl->use_hw_chs);
+    QCOM_REGMAP_FIELD_ALLOC(dev, map, v->use_hw_usr, 
tx_dmactl->use_hw_usr);
+    QCOM_REGMAP_FIELD_ALLOC(dev, map, v->hw_chs_sel, 
tx_dmactl->hw_chs_sel);
+    QCOM_REGMAP_FIELD_ALLOC(dev, map, v->hw_usr_sel, 
tx_dmactl->hw_usr_sel);

+    drvdata->hdmi_tx_dmactl[i] = tx_dmactl;
+    }
+    return 0;
+}


]
This should go into lpass-cpu.c


Okay!. Will move to lpass-cpu.c



+EXPORT_SYMBOL(lpass_hdmi_init_bitfields);



+
+static int lpass_hdmi_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);
+    snd_pcm_format_t format = params_format(params);
+    

Re: [PATCH v10 5/7] ASoC: qcom: Add support for lpass hdmi driver

2020-10-06 Thread Srinivas Kandagatla

On 05/10/2020 05:48, Srinivasa Rao Mandadapu wrote:

From: V Sujith Kumar Reddy 

Upadate lpass cpu and platform driver to support audio over dp.
Also add lpass-hdmi.c and lpass-hdmi.h.

Signed-off-by: V Sujith Kumar Reddy 
Signed-off-by: Srinivasa Rao 
---
  sound/soc/qcom/Kconfig   |   5 +
  sound/soc/qcom/Makefile  |   2 +
  sound/soc/qcom/lpass-apq8016.c   |   4 +-
  sound/soc/qcom/lpass-cpu.c   |  51 -
  sound/soc/qcom/lpass-hdmi.c  | 468 +++
  sound/soc/qcom/lpass-hdmi.h  | 106 +
  sound/soc/qcom/lpass-ipq806x.c   |   4 +-
  sound/soc/qcom/lpass-lpaif-reg.h |  52 -
  sound/soc/qcom/lpass-platform.c  | 391 ++--
  sound/soc/qcom/lpass.h   | 113 +-
  10 files changed, 1097 insertions(+), 99 deletions(-)
  create mode 100644 sound/soc/qcom/lpass-hdmi.c
  create mode 100644 sound/soc/qcom/lpass-hdmi.h


...


diff --git a/sound/soc/qcom/lpass-hdmi.c b/sound/soc/qcom/lpass-hdmi.c
new file mode 100644
index 000..ee737f0
--- /dev/null
+++ b/sound/soc/qcom/lpass-hdmi.c
@@ -0,0 +1,468 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (c) 2020 The Linux Foundation. All rights reserved.
+ *
+ * lpass-hdmi.c -- ALSA SoC HDMI-CPU DAI driver for QTi LPASS HDMI
+ */
+
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+#include "lpass-lpaif-reg.h"
+#include "lpass.h"
+


[

+#define QCOM_REGMAP_FIELD_ALLOC(d, m, f, mf)\
+   do { \
+   mf = devm_regmap_field_alloc(d, m, f); \
+   if (IS_ERR(mf))\
+   return -EINVAL; \
+   } while (0)
+
+

]
should go into lpass.h

[

+int lpass_hdmi_init_bitfields(struct device *dev, struct regmap *map)
+{
+   struct lpass_data *drvdata = dev_get_drvdata(dev);
+   struct lpass_variant *v = drvdata->variant;
+   unsigned int i;
+   struct lpass_hdmi_tx_ctl *tx_ctl;
+   struct regmap_field *legacy_en;
+   struct lpass_vbit_ctrl *vbit_ctl;
+   struct regmap_field *tx_parity;
+   struct lpass_dp_metadata_ctl *meta_ctl;
+   struct lpass_sstream_ctl *sstream_ctl;
+   struct regmap_field *ch_msb;
+   struct regmap_field *ch_lsb;
+   struct lpass_hdmitx_dmactl *tx_dmactl;
+   int rval;
+
+   tx_ctl = devm_kzalloc(dev, sizeof(*tx_ctl), GFP_KERNEL);
+   if (!tx_ctl)
+   return -ENOMEM;
+
+   QCOM_REGMAP_FIELD_ALLOC(dev, map, v->soft_reset, tx_ctl->soft_reset);
+   QCOM_REGMAP_FIELD_ALLOC(dev, map, v->force_reset, tx_ctl->force_reset);
+   drvdata->tx_ctl = tx_ctl;
+
+   QCOM_REGMAP_FIELD_ALLOC(dev, map, v->legacy_en, legacy_en);
+   drvdata->hdmitx_legacy_en = legacy_en;
+
+   vbit_ctl = devm_kzalloc(dev, sizeof(*vbit_ctl), GFP_KERNEL);
+   if (!vbit_ctl)
+   return -ENOMEM;
+
+   QCOM_REGMAP_FIELD_ALLOC(dev, map, v->replace_vbit, 
vbit_ctl->replace_vbit);
+   QCOM_REGMAP_FIELD_ALLOC(dev, map, v->vbit_stream, 
vbit_ctl->vbit_stream);
+   drvdata->vbit_ctl = vbit_ctl;
+
+
+   QCOM_REGMAP_FIELD_ALLOC(dev, map, v->calc_en, tx_parity);
+   drvdata->hdmitx_parity_calc_en = tx_parity;
+
+   meta_ctl = devm_kzalloc(dev, sizeof(*meta_ctl), GFP_KERNEL);
+   if (!meta_ctl)
+   return -ENOMEM;
+
+   rval = devm_regmap_field_bulk_alloc(dev, map, _ctl->mute, 
>mute, 7);
+   if (rval)
+   return rval;
+   drvdata->meta_ctl = meta_ctl;
+
+   sstream_ctl = devm_kzalloc(dev, sizeof(*sstream_ctl), GFP_KERNEL);
+   if (!sstream_ctl)
+   return -ENOMEM;
+
+   rval = devm_regmap_field_bulk_alloc(dev, map, _ctl->sstream_en, 
>sstream_en, 9);
+   if (rval)
+   return rval;
+
+   drvdata->sstream_ctl = sstream_ctl;
+
+   for (i = 0; i < LPASS_MAX_HDMI_DMA_CHANNELS; i++) {
+   QCOM_REGMAP_FIELD_ALLOC(dev, map, v->msb_bits, ch_msb);
+   drvdata->hdmitx_ch_msb[i] = ch_msb;
+
+   QCOM_REGMAP_FIELD_ALLOC(dev, map, v->lsb_bits, ch_lsb);
+   drvdata->hdmitx_ch_lsb[i] = ch_lsb;
+
+   tx_dmactl = devm_kzalloc(dev, sizeof(*tx_dmactl), GFP_KERNEL);
+   if (!tx_dmactl)
+   return -ENOMEM;
+
+   QCOM_REGMAP_FIELD_ALLOC(dev, map, v->use_hw_chs, 
tx_dmactl->use_hw_chs);
+   QCOM_REGMAP_FIELD_ALLOC(dev, map, v->use_hw_usr, 
tx_dmactl->use_hw_usr);
+   QCOM_REGMAP_FIELD_ALLOC(dev, map, v->hw_chs_sel, 
tx_dmactl->hw_chs_sel);
+   QCOM_REGMAP_FIELD_ALLOC(dev, map, v->hw_usr_sel, 
tx_dmactl->hw_usr_sel);
+   drvdata->hdmi_tx_dmactl[i] = tx_dmactl;
+   }
+   return 0;
+}


]
This should go into lpass-cpu.c



+EXPORT_SYMBOL(lpass_hdmi_init_bitfields);



+
+static int lpass_hdmi_daiops_hw_params(struct snd_pcm_substream *substream,
+   struct snd_pcm_hw_params *params, struct snd_soc_dai *dai)
+{
+  

[PATCH v10 5/7] ASoC: qcom: Add support for lpass hdmi driver

2020-10-04 Thread Srinivasa Rao Mandadapu
From: V Sujith Kumar Reddy 

Upadate lpass cpu and platform driver to support audio over dp.
Also add lpass-hdmi.c and lpass-hdmi.h.

Signed-off-by: V Sujith Kumar Reddy 
Signed-off-by: Srinivasa Rao 
---
 sound/soc/qcom/Kconfig   |   5 +
 sound/soc/qcom/Makefile  |   2 +
 sound/soc/qcom/lpass-apq8016.c   |   4 +-
 sound/soc/qcom/lpass-cpu.c   |  51 -
 sound/soc/qcom/lpass-hdmi.c  | 468 +++
 sound/soc/qcom/lpass-hdmi.h  | 106 +
 sound/soc/qcom/lpass-ipq806x.c   |   4 +-
 sound/soc/qcom/lpass-lpaif-reg.h |  52 -
 sound/soc/qcom/lpass-platform.c  | 391 ++--
 sound/soc/qcom/lpass.h   | 113 +-
 10 files changed, 1097 insertions(+), 99 deletions(-)
 create mode 100644 sound/soc/qcom/lpass-hdmi.c
 create mode 100644 sound/soc/qcom/lpass-hdmi.h

diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig
index a7ef626..28e775f 100644
--- a/sound/soc/qcom/Kconfig
+++ b/sound/soc/qcom/Kconfig
@@ -12,6 +12,10 @@ config SND_SOC_LPASS_CPU
tristate
select REGMAP_MMIO
 
+config SND_SOC_LPASS_HDMI
+   tristate
+   select REGMAP_MMIO
+
 config SND_SOC_LPASS_PLATFORM
tristate
select REGMAP_MMIO
@@ -30,6 +34,7 @@ config SND_SOC_LPASS_SC7180
tristate
select SND_SOC_LPASS_CPU
select SND_SOC_LPASS_PLATFORM
+   select SND_SOC_LPASS_HDMI
 
 config SND_SOC_STORM
tristate "ASoC I2S support for Storm boards"
diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile
index 7972c94..0bd90d7 100644
--- a/sound/soc/qcom/Makefile
+++ b/sound/soc/qcom/Makefile
@@ -1,12 +1,14 @@
 # SPDX-License-Identifier: GPL-2.0
 # Platform
 snd-soc-lpass-cpu-objs := lpass-cpu.o
+snd-soc-lpass-hdmi-objs := lpass-hdmi.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_HDMI) += snd-soc-lpass-hdmi.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
diff --git a/sound/soc/qcom/lpass-apq8016.c b/sound/soc/qcom/lpass-apq8016.c
index 5c8ae22..0aedb3a 100644
--- a/sound/soc/qcom/lpass-apq8016.c
+++ b/sound/soc/qcom/lpass-apq8016.c
@@ -125,7 +125,7 @@ static struct snd_soc_dai_driver 
apq8016_lpass_cpu_dai_driver[] = {
 };
 
 static int apq8016_lpass_alloc_dma_channel(struct lpass_data *drvdata,
-  int direction)
+  int direction, unsigned int dai_id)
 {
struct lpass_variant *v = drvdata->variant;
int chan = 0;
@@ -151,7 +151,7 @@ static int apq8016_lpass_alloc_dma_channel(struct 
lpass_data *drvdata,
return chan;
 }
 
-static int apq8016_lpass_free_dma_channel(struct lpass_data *drvdata, int chan)
+static int apq8016_lpass_free_dma_channel(struct lpass_data *drvdata, int 
chan, unsigned int dai_id)
 {
clear_bit(chan, >dma_ch_bit_map);
 
diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c
index 12950d2..b6d243e 100644
--- a/sound/soc/qcom/lpass-cpu.c
+++ b/sound/soc/qcom/lpass-cpu.c
@@ -535,13 +535,17 @@ static void of_lpass_cpu_parse_dai_data(struct device 
*dev,
dev_err(dev, "valid dai id not found: %d\n", ret);
continue;
}
-
-   data->mi2s_playback_sd_mode[id] =
-   of_lpass_cpu_parse_sd_lines(dev, node,
-   "qcom,playback-sd-lines");
-   data->mi2s_capture_sd_mode[id] =
-   of_lpass_cpu_parse_sd_lines(dev, node,
+   if (id == LPASS_DP_RX) {
+   data->hdmi_port_enable = 1;
+   dev_err(dev, "HDMI Port is enabled: %d\n", id);
+   } else {
+   data->mi2s_playback_sd_mode[id] =
+   of_lpass_cpu_parse_sd_lines(dev, node,
+   
"qcom,playback-sd-lines");
+   data->mi2s_capture_sd_mode[id] =
+   of_lpass_cpu_parse_sd_lines(dev, node,
"qcom,capture-sd-lines");
+   }
}
 }
 
@@ -596,6 +600,27 @@ int asoc_qcom_lpass_cpu_platform_probe(struct 
platform_device *pdev)
return PTR_ERR(drvdata->lpaif_map);
}
 
+   if (drvdata->hdmi_port_enable) {
+   res = platform_get_resource_byname(pdev, IORESOURCE_MEM, 
"lpass-hdmiif");
+
+   drvdata->hdmiif = devm_ioremap_resource(dev, res);
+   if (IS_ERR((void const __force *)drvdata->hdmiif)) {
+