Qualcomm's lpass-hdmi ASoC driver to support audio over dp port
Subsystems (5)
v7 cover Qualcomm's lpass-hdmi ASoC driver to support audio over dp port
These patches are to support audio over DP port on Qualcomm's SC7180 LPASS Asoc. It includes machine driver, cpu driver, platform driver updates for HDMI path support, device tree documention, lpass variant structure optimization and configuration changes.
These patches depends on the DP patch series
https://patchwork.kernel.org/project/dri-devel/list/?series=332029
https://lore.kernel.org/patchwork/project/lkml/list/?series=464856
changes since V6:
-- Removed compile time define flag, which used for enabling
HDMI code, based on corresponding config param is included.
-- Updated reg map alloc API with reg map bulk API.
-- Removed unnecessary line splits
changes since V5:
-- Removed unused struct regmap *map in lpass_platform_alloc_hdmidmactl_fields. -- DMA alloc and free API signature change in lpass-apq8016.c, lpass-ipq806x.c -- Keeping API "irqreturn_t lpass_platform_hdmiif_irq" under ifdef macro
Changes Since v4:
-- Updated with single compatible node for both I2S and HDMI.
Changes Since v3:
-- Removed id in lpass variant structure and used snd_soc_dai_driver id.
Changes Since v2:
-- Audio buffer size(i.e. LPASS_PLATFORM_BUFFER_SIZE) in lpass-platform.c increased.
Changes Since v1:
-- Commit messages are updated
-- Addressed Rob Herring review comments
V Sujith Kumar Reddy (6):
ASoC: Add sc7180-lpass binding header hdmi define
ASoC: dt-bindings: Add dt binding for lpass hdmi Asoc:qcom:lpass-cpu:Update dts property read API
Asoc: qcom: lpass:Update lpaif_dmactl members order
ASoC: qcom: Add support for lpass hdmi driver
ASoC: qcom: sc7180: Add support for audio over DP
.../devicetree/bindings/sound/qcom,lpass-cpu.yaml | 74 +++- include/dt-bindings/sound/sc7180-lpass.h | 1 + sound/soc/qcom/Kconfig | 17 + sound/soc/qcom/Makefile | 2 + sound/soc/qcom/lpass-apq8016.c | 4 +- sound/soc/qcom/lpass-cpu.c | 55 ++- sound/soc/qcom/lpass-hdmi.c | 470 +++++++++++++++++++++ sound/soc/qcom/lpass-hdmi.h | 122 ++++++ sound/soc/qcom/lpass-ipq806x.c | 4 +- sound/soc/qcom/lpass-lpaif-reg.h | 52 ++- sound/soc/qcom/lpass-platform.c | 421 ++++++++++++++---- sound/soc/qcom/lpass-sc7180.c | 116 ++++- sound/soc/qcom/lpass.h | 119 +++++- 13 files changed, 1301 insertions(+), 156 deletions(-) create mode 100644 sound/soc/qcom/lpass-hdmi.c create mode 100644 sound/soc/qcom/lpass-hdmi.h
Signature · 2 lines
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
PATCH v7 1/6 ASoC: Add sc7180-lpass binding header hdmi define
From: V Sujith Kumar Reddy <[email protected]>
Add header defining hdmi dai-id for SC7180 lpass soc in dt bindings.
--- include/dt-bindings/sound/sc7180-lpass.h | 1 + 1 file changed, 1 insertion(+)
include/dt-bindings/sound/sc7180-lpass.h +1 -0
@@ -4,6 +4,7 @@#define MI2S_PRIMARY 0#define MI2S_SECONDARY 1 +#define LPASS_DP_RX 2#define LPASS_MCLK0 0
Signature · 2 lines
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
PATCH v7 2/6 ASoC: dt-bindings: Add dt binding for lpass hdmi
In reply to Srinivasa Rao MandadapuFrom: V Sujith Kumar Reddy <[email protected]>
Adds bindings for lpass hdmi interface
which can support audio path over dp.
--- .../devicetree/bindings/sound/qcom,lpass-cpu.yaml | 74 +++++++++++++++------- 1 file changed, 52 insertions(+), 22 deletions(-)
Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml +52 -22
@@ -24,9 +24,10 @@ properties: - qcom,sc7180-lpass-cpu reg: - maxItems: 1 + maxItems: 2 description: LPAIF core registers - + reg-names: + maxItems: 2 clocks: minItems: 3 maxItems: 6
@@ -36,15 +37,16 @@ properties: maxItems: 6 interrupts: - maxItems: 1 + maxItems: 2 description: LPAIF DMA buffer interrupt - + interrupt-names: + maxItems: 2 qcom,adsp: $ref: /schemas/types.yaml#/definitions/phandle description: Phandle for the audio DSP node iommus: - maxItems: 1 + maxItems: 2 description: Phandle to apps_smmu node with sid mask power-domains:
@@ -60,10 +62,12 @@ properties: const: 0 patternProperties: - "(^mi2s-[0-9a-f]$|mi2s)": + "^dai-link@[0-9a-f]$": type: object - description: Required properties for each DAI - + description: | + LPASS CPU dai node for each I2S device. Bindings of each node + depends on the specific driver providing the functionality and + properties. properties: reg: maxItems: 1
@@ -85,9 +89,11 @@ patternProperties: required: - compatible - reg + - reg-names - clocks - clock-names - interrupts + - interrupt-names - '#sound-dai-cells' additionalProperties: false
@@ -134,13 +140,32 @@ allOf: then: properties: clock-names: - items: - - const: pcnoc-sway-clk - - const: audio-core - - const: mclk0 - - const: pcnoc-mport-clk - - const: mi2s-bit-clk0 - - const: mi2s-bit-clk1 + oneOf: + - items: #for I2S + - const: pcnoc-sway-clk + - const: audio-core + - const: mclk0 + - const: pcnoc-mport-clk + - const: mi2s-bit-clk0 + - const: mi2s-bit-clk1 + - items: #for HDMI + - const: pcnoc-sway-clk + - const: audio-core + - const: pcnoc-mport-clk + reg-names: + anyOf: + - items: #for I2S + - const: lpass-lpaif + - items: #for I2S and HDMI + - const: lpass-hdmiif + - const: lpass-lpaif + interrupt-names: + anyOf: + - items: #for I2S + - const: lpass-irq-lpaif + - items: #for I2S and HDMI + - const: lpass-irq-lpaif + - const: lpass-irq-hdmi required: - iommus - power-domains
@@ -152,12 +177,15 @@ examples: soc { #address-cells = <2>; #size-cells = <2>; - lpass@62f00000 { + lpass@62d80000 { compatible = "qcom,sc7180-lpass-cpu"; - reg = <0 0x62f00000 0 0x29000>; - - iommus = <&apps_smmu 0x1020 0>; + reg = <0 0x62d87000 0 0x68000>, + <0 0x62f00000 0 0x29000>; + reg-names = "lpass-hdmiif", + "lpass-lpaif"; + iommus = <&apps_smmu 0x1020 0>, + <&apps_smmu 0x1032 0>; power-domains = <&lpass_hm 0>; clocks = <&gcc 131>,
@@ -171,14 +199,16 @@ examples: "mclk0", "pcnoc-mport-clk", "mi2s-bit-clk0", "mi2s-bit-clk1"; - interrupts = <0 160 1>; - + interrupts = <0 160 1>, + <0 268 1>; + interrupt-names = "lpass-irq-lpaif", + "lpass-irq-hdmi"; #sound-dai-cells = <1>; #address-cells = <1>; #size-cells = <0>; /* Optional to set different MI2S SD lines */ - mi2s-primary@0 { + dai-link@0 { reg = <MI2S_PRIMARY>; qcom,playback-sd-lines = <1>; qcom,capture-sd-lines = <0>;
Signature · 2 lines
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
PATCH v7 3/6 Asoc:qcom:lpass-cpu:Update dts property read API
In reply to Srinivasa Rao MandadapuFrom: V Sujith Kumar Reddy <[email protected]>
Update dts property read API call with platform get property by name, as it make code more readable and avoid conflicts when array of properties to be used.
--- sound/soc/qcom/lpass-cpu.c | 2 +- sound/soc/qcom/lpass-platform.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)
sound/soc/qcom/lpass-cpu.c +1 -1
@@ -575,7 +575,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)of_lpass_cpu_parse_dai_data (dev, drvdata); - res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"lpass-lpaif" ); drvdata->lpaif =devm_ioremap_resource (dev, res);if (IS_ERR ((void const __force *)drvdata->lpaif)) {
sound/soc/qcom/lpass-platform.c +1 -1
@@ -621,7 +621,7 @@ int asoc_qcom_lpass_platform_register(struct platform_device *pdev)struct lpass_variant *v = drvdata->variant;int ret; - drvdata->lpaif_irq =platform_get_irq (pdev,0 ); + drvdata->lpaif_irq =platform_get_irq_byname (pdev,"lpass-irq-lpaif" );if (drvdata->lpaif_irq <0 )return -ENODEV ;
Signature · 2 lines
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH v7 3/6] Asoc:qcom:lpass-cpu:Update dts property read API
Quoted 8 lines · Srinivasa Rao Mandadapu
From: V Sujith Kumar Reddy <[email protected]>
Update dts property read API call with platform get property by name, as it make code more readable and avoid conflicts when array of properties to be used.
Signed-off-by V Sujith Kumar Reddy <[email protected]>Signed-off-by Srinivasa Rao <[email protected]>
Quoted 32 lines
--- sound/soc/qcom/lpass-cpu.c | 2 +- sound/soc/qcom/lpass-platform.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-)sound/soc/qcom/lpass-cpu.c +1
-1@@ -575,7 +575,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)of_lpass_cpu_parse_dai_data (dev, drvdata); - res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); + res =platform_get_resource_byname (pdev,IORESOURCE_MEM ,"lpass-lpaif" ); drvdata->lpaif =devm_ioremap_resource (dev, res);if (IS_ERR ((void const __force *)drvdata->lpaif)) {sound/soc/qcom/lpass-platform.c +1
-1@@ -621,7 +621,7 @@ int asoc_qcom_lpass_platform_register(struct platform_device *pdev)struct lpass_variant *v = drvdata->variant;int ret; - drvdata->lpaif_irq =platform_get_irq (pdev,0 ); + drvdata->lpaif_irq =platform_get_irq_byname (pdev,"lpass-irq-lpaif" );if (drvdata->lpaif_irq <0 )return -ENODEV ;
PATCH v7 4/6 Asoc: qcom: lpass:Update lpaif_dmactl members order
In reply to Srinivasa Rao MandadapuFrom: V Sujith Kumar Reddy <[email protected]>
Update the lpaif_dmactl struct members order to match HDMI reg map members sequence. Separate Interface reg map as it is used for I2S control but not for HDMI control, to make use of bulk API, which makes code more readable.
--- sound/soc/qcom/lpass-platform.c | 8 ++++---- sound/soc/qcom/lpass.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-)
sound/soc/qcom/lpass-platform.c +4 -4
@@ -71,13 +71,13 @@ static int lpass_platform_alloc_dmactl_fields(struct device *dev, rd_dmactl = drvdata->rd_dmactl; wr_dmactl = drvdata->wr_dmactl; - rval =devm_regmap_field_bulk_alloc (dev, map, &rd_dmactl->bursten, - &v->rdma_bursten,6 ); + rval =devm_regmap_field_bulk_alloc (dev, map, &rd_dmactl->intf, + &v->rdma_intf,6 );if (rval)return rval; -return devm_regmap_field_bulk_alloc (dev, map, &wr_dmactl->bursten, - &v->wrdma_bursten,6 ); +return devm_regmap_field_bulk_alloc (dev, map, &wr_dmactl->intf, + &v->wrdma_intf,6 ); } static int lpass_platform_pcmops_open(struct snd_soc_component *component,
sound/soc/qcom/lpass.h +3 -3
@@ -31,9 +31,9 @@ struct lpaif_i2sctl {struct lpaif_dmactl { +struct regmap_field *intf;struct regmap_field *bursten;struct regmap_field *wpscnt; -struct regmap_field *intf;struct regmap_field *fifowm;struct regmap_field *enable;struct regmap_field *dyncclk;
@@ -110,17 +110,17 @@ struct lpass_variant {struct reg_field bitwidth;/* RD_DMA Register fields */ +struct reg_field rdma_intf;struct reg_field rdma_bursten;struct reg_field rdma_wpscnt; -struct reg_field rdma_intf;struct reg_field rdma_fifowm;struct reg_field rdma_enable;struct reg_field rdma_dyncclk;/* WR_DMA Register fields */ +struct reg_field wrdma_intf;struct reg_field wrdma_bursten;struct reg_field wrdma_wpscnt; -struct reg_field wrdma_intf;struct reg_field wrdma_fifowm;struct reg_field wrdma_enable;struct reg_field wrdma_dyncclk;
Signature · 2 lines
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH v7 4/6] Asoc: qcom: lpass:Update lpaif_dmactl members order
Quoted 9 lines · Srinivasa Rao Mandadapu
From: V Sujith Kumar Reddy <[email protected]>
Update the
lpaif_dmactlstruct members order to match HDMI reg map members sequence. Separate Interface reg map as it is used for I2S control but not for HDMI control, to make use of bulk API, which makes code more readable.Signed-off-by V Sujith Kumar Reddy <[email protected]>Signed-off-by Srinivasa Rao Mandadapu <[email protected]>
Quoted 63 lines
--- sound/soc/qcom/lpass-platform.c | 8 ++++---- sound/soc/qcom/lpass.h | 6 +++--- 2 files changed, 7 insertions(+), 7 deletions(-)sound/soc/qcom/lpass-platform.c +4
-4@@ -71,13 +71,13 @@ static int lpass_platform_alloc_dmactl_fields(struct device *dev, rd_dmactl = drvdata->rd_dmactl; wr_dmactl = drvdata->wr_dmactl; - rval =devm_regmap_field_bulk_alloc (dev, map, &rd_dmactl->bursten, - &v->rdma_bursten,6 ); + rval =devm_regmap_field_bulk_alloc (dev, map, &rd_dmactl->intf, + &v->rdma_intf,6 );if (rval)return rval; -return devm_regmap_field_bulk_alloc (dev, map, &wr_dmactl->bursten, - &v->wrdma_bursten,6 ); +return devm_regmap_field_bulk_alloc (dev, map, &wr_dmactl->intf, + &v->wrdma_intf,6 ); } static int lpass_platform_pcmops_open(struct snd_soc_component *component,sound/soc/qcom/lpass.h +3
-3@@ -31,9 +31,9 @@ struct lpaif_i2sctl {struct lpaif_dmactl { +struct regmap_field *intf;struct regmap_field *bursten;struct regmap_field *wpscnt; -struct regmap_field *intf;struct regmap_field *fifowm;struct regmap_field *enable;struct regmap_field *dyncclk;@@ -110,17 +110,17 @@ struct lpass_variant {struct reg_field bitwidth;/* RD_DMA Register fields */ +struct reg_field rdma_intf;struct reg_field rdma_bursten;struct reg_field rdma_wpscnt; -struct reg_field rdma_intf;struct reg_field rdma_fifowm;struct reg_field rdma_enable;struct reg_field rdma_dyncclk;/* WR_DMA Register fields */ +struct reg_field wrdma_intf;struct reg_field wrdma_bursten;struct reg_field wrdma_wpscnt; -struct reg_field wrdma_intf;struct reg_field wrdma_fifowm;struct reg_field wrdma_enable;struct reg_field wrdma_dyncclk;
PATCH v7 5/6 ASoC: qcom: Add support for lpass hdmi driver
In reply to Srinivasa Rao MandadapuFrom: V Sujith Kumar Reddy <[email protected]>
Upadate lpass cpu and platform driver to support audio over dp. Also add lpass-hdmi.c and lpass-hdmi.h.
--- sound/soc/qcom/Kconfig | 17 ++ sound/soc/qcom/Makefile | 2 + sound/soc/qcom/lpass-apq8016.c | 4 +- sound/soc/qcom/lpass-cpu.c | 53 ++++- sound/soc/qcom/lpass-hdmi.c | 470 +++++++++++++++++++++++++++++++++++++++ sound/soc/qcom/lpass-hdmi.h | 122 ++++++++++ sound/soc/qcom/lpass-ipq806x.c | 4 +- sound/soc/qcom/lpass-lpaif-reg.h | 52 ++++- sound/soc/qcom/lpass-platform.c | 411 +++++++++++++++++++++++++++------- sound/soc/qcom/lpass.h | 113 +++++++++- 10 files changed, 1137 insertions(+), 111 deletions(-) create mode 100644 sound/soc/qcom/lpass-hdmi.c create mode 100644 sound/soc/qcom/lpass-hdmi.h
sound/soc/qcom/Kconfig +17 -0
@@ -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"
@@ -120,4 +125,16 @@ config SND_SOC_SDM845 SDM845 SoC-based systems. Say Y if you want to use audio device on this SoCs. +config SND_SOC_SC7180 + tristate "SoC Machine driver for SC7180 boards" + depends on I2C + select SND_SOC_QCOM_COMMON + select SND_SOC_LPASS_SC7180 + select SND_SOC_MAX98357A + select SND_SOC_RT5682_I2C + help + To add support for audio on Qualcomm Technologies Inc. + SC7180 SoC-based systems. + Say Y if you want to use audio device on this SoCs. + endif #SND_SOC_QCOM
sound/soc/qcom/Makefile +2 -0
@@ -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
sound/soc/qcom/lpass-apq8016.c +2 -2
@@ -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, &drvdata->dma_ch_bit_map);
sound/soc/qcom/lpass-cpu.c +43 -10
86 lines not on this page · raw message
sound/soc/qcom/lpass-hdmi.c new file +470 -0
470 lines not on this page · raw message
sound/soc/qcom/lpass-hdmi.h new file +122 -0
122 lines not on this page · raw message
sound/soc/qcom/lpass-ipq806x.c +2 -2
@@ -96,7 +96,7 @@ static int ipq806x_lpass_exit(struct platform_device *pdev)return 0 ; } -static int ipq806x_lpass_alloc_dma_channel (struct lpass_data *drvdata,int dir) +static int ipq806x_lpass_alloc_dma_channel (struct lpass_data *drvdata,int dir,unsigned int dai_id) {if (dir ==SNDRV_PCM_STREAM_PLAYBACK )return IPQ806X_LPAIF_RDMA_CHAN_MI2S ;
@@ -104,7 +104,7 @@ static int ipq806x_lpass_alloc_dma_channel(struct lpass_data *drvdata, int dir)return -EINVAL ; } -static int ipq806x_lpass_free_dma_channel (struct lpass_data *drvdata,int chan) +static int ipq806x_lpass_free_dma_channel (struct lpass_data *drvdata,int chan,unsigned int dai_id) {return 0 ; }
sound/soc/qcom/lpass-lpaif-reg.h +40 -12
78 lines not on this page · raw message
sound/soc/qcom/lpass-platform.c +333 -78
669 lines not on this page · raw message
sound/soc/qcom/lpass.h +106 -7
188 lines not on this page · raw message
Signature · 2 lines
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
Re: [PATCH v7 5/6] ASoC: qcom: Add support for lpass hdmi driver
Quoted 5 lines · Srinivasa Rao Mandadapu
From: V Sujith Kumar Reddy <[email protected]>
Upadate lpass cpu and platform driver to support audio over dp. Also add
lpass-hdmi.candlpass-hdmi.h.
Thanks for doing the rework this patch looks much better now!
However I have few comments below!
Quoted 41 lines
Signed-off-by V Sujith Kumar Reddy <[email protected]>Signed-off-by Srinivasa Rao <[email protected]>--- sound/soc/qcom/Kconfig | 17 ++ sound/soc/qcom/Makefile | 2 + sound/soc/qcom/lpass-apq8016.c | 4 +- sound/soc/qcom/lpass-cpu.c | 53 ++++- sound/soc/qcom/lpass-hdmi.c | 470 +++++++++++++++++++++++++++++++++++++++ sound/soc/qcom/lpass-hdmi.h | 122 ++++++++++ sound/soc/qcom/lpass-ipq806x.c | 4 +- sound/soc/qcom/lpass-lpaif-reg.h | 52 ++++- sound/soc/qcom/lpass-platform.c | 411 +++++++++++++++++++++++++++------- sound/soc/qcom/lpass.h | 113 +++++++++- 10 files changed, 1137 insertions(+), 111 deletions(-)create mode 100644
sound/soc/qcom/lpass-hdmi.c
create mode 100644sound/soc/qcom/lpass-hdmi.hsound/soc/qcom/Kconfig +5
-0@@ -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"
sound/soc/qcom/Kconfig config SND_SOC_SDM845 · line 127
Quoted 3 lines
sound/soc/qcom/Kconfig +0
-0@@ -120,4 +125,16 @@ config SND_SOC_SDM845 SDM845 SoC-based systems. Say Y if you want to use audio device on this SoCs.
<<<<<<
Quoted 12 lines
sound/soc/qcom/Kconfig +12
-0+config SND_SOC_SC7180 + tristate "SoC Machine driver for SC7180 boards" + depends on I2C + select SND_SOC_QCOM_COMMON + select SND_SOC_LPASS_SC7180 + select SND_SOC_MAX98357A + select SND_SOC_RT5682_I2C + help + To add support for audio on Qualcomm Technologies Inc. + SC7180 SoC-based systems. + Say Y if you want to use audio device on this SoCs. +
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Does this change belong to this patch!
Quoted 71 lines
endif #SND_SOC_QCOM
sound/soc/qcom/Makefile +2
-0@@ -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.osound/soc/qcom/lpass-apq8016.c +2
-2@@ -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, &drvdata->dma_ch_bit_map);sound/soc/qcom/lpass-cpu.c +10
-6@@ -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" ); + } } }
sound/soc/qcom/lpass-cpu.c int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) · line 596
Quoted 5 lines
sound/soc/qcom/lpass-cpu.c +1
-1@@ -589,13 +593,34 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) variant->wrdma_channel_start); drvdata->lpaif_map =devm_regmap_init_mmio (dev, drvdata->lpaif, - &lpass_cpu_regmap_config); + &lpass_cpu_regmap_config);
Looks like unnecessary change!
Quoted 75 lines
sound/soc/qcom/lpass-cpu.c +32
-3if (IS_ERR (drvdata->lpaif_map)) {dev_err (dev,"error initializing regmap: %ld\n" ,PTR_ERR (drvdata->lpaif_map));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)) { +dev_err (dev,"error mapping reg resource: %ld\n" , +PTR_ERR ((void const __force *)drvdata->hdmiif)); +return PTR_ERR ((void const __force *)drvdata->hdmiif); + } + + lpass_hdmi_regmap_config.max_register =LPAIF_HDMI_RDMAPER_REG (variant, + variant->hdmi_rdma_channels); + drvdata->hdmiif_map =devm_regmap_init_mmio (dev, drvdata->hdmiif, + &lpass_hdmi_regmap_config); +if (IS_ERR (drvdata->hdmiif_map)) { +dev_err (dev,"error initializing regmap: %ld\n" , +PTR_ERR (drvdata->hdmiif_map)); +return PTR_ERR (drvdata->hdmiif_map); + } + } +if (variant->init) { ret = variant->init (pdev);if (ret) {@@ -606,6 +631,9 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)for (i =0 ; i < variant->num_dai; i++) { dai_id = variant->dai_driver[i].id; +if (dai_id ==LPASS_DP_RX ) +continue ; + drvdata->mi2s_osr_clk[dai_id] =devm_clk_get (dev, variant->dai_osr_clk_names[i]);if (IS_ERR (drvdata->mi2s_osr_clk[dai_id])) {@@ -636,11 +664,16 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)/* Initialize bitfields for dai I2SCTL register */ ret =lpass_cpu_init_i2sctl_bitfields (dev, drvdata->i2sctl, drvdata->lpaif_map); -if (ret) { +if (ret)dev_err (dev,"error init i2sctl field: %d\n" , ret); -return ret; - } +if (drvdata->hdmi_port_enable) { + ret =lpass_hdmi_init_bitfields (dev, drvdata->hdmiif_map); +if (ret) { +dev_err (dev,"%s error hdmi init failed\n" , __func__); +return ret; + } + } ret = devm_snd_soc_register_component(dev, &lpass_cpu_comp_driver, variant->dai_driver,sound/soc/qcom/lpass-hdmi.c new file +9
-0@@ -0,0 +1,470 @@ +// 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 <linux/kernel.h>
sound/soc/qcom/lpass-hdmi.c line 19
Quoted 10 lines
sound/soc/qcom/lpass-hdmi.c new file +10
-0+#include <linux/module.h> +#include <sound/pcm_params.h> +#include <linux/regmap.h> +#include <sound/soc.h> +#include <sound/soc-dai.h> +#include <dt-bindings/sound/sc7180-lpass.h> +#include "lpass-lpaif-reg.h" +#include "lpass.h" + +#define QCOM_REGMAP_FILED_ALLOC (d, m, f, mf) \
s/QCOM_REGMAP_FILED_ALLOC/QCOM_REGMAP_FIELD_ALLOC
Quoted 11 lines
sound/soc/qcom/lpass-hdmi.c new file +11
-0+do { \ + mf =devm_regmap_field_alloc (d, m, f); \ +if (IS_ERR (mf)) \ +return -EINVAL ; \ + } while (0) + + +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;
sound/soc/qcom/lpass-hdmi.c line 40
Quoted 10 lines
sound/soc/qcom/lpass-hdmi.c new file +10
-0+unsigned int i; +struct lpass_hdmi_tx_ctl *tx_ctl; +struct lpass_hdmitx_legacy *legacy; +struct lpass_vbit_ctrl *vbit_ctl; +struct lpass_hdmi_tx_parity *tx_parity; +struct lpass_dp_metadata_ctl *meta_ctl; +struct lpass_sstream_ctl *sstream_ctl; +struct lpass_hdmi_tx_ch_msb *ch_msb; +struct lpass_hdmi_tx_ch_lsb *ch_lsb; +struct lpass_hdmitx_dmactl *tx_dmactl;
I see that you split the data structures into logical groups, does it really help the driver in anyway? I mean do you pass this structures to any functions? Question is do you really need this level of abstraction?
Can't you just use flat regmap fileds with prefixes that would make code even cleaner!
Quoted 80 lines
sound/soc/qcom/lpass-hdmi.c new file +80
-0+int rval; + + tx_ctl =devm_kzalloc (dev,sizeof (*tx_ctl),GFP_KERNEL ); +if (!tx_ctl) +return -ENOMEM ; + +QCOM_REGMAP_FILED_ALLOC (dev, map, v->soft_reset, tx_ctl->soft_reset); +QCOM_REGMAP_FILED_ALLOC (dev, map, v->force_reset, tx_ctl->force_reset); + drvdata->tx_ctl = tx_ctl; + + legacy =devm_kzalloc (dev,sizeof (*legacy),GFP_KERNEL ); +if (!legacy) +return -ENOMEM ; + +QCOM_REGMAP_FILED_ALLOC (dev, map, v->legacy_en, legacy->legacy_en); + drvdata->legacy = legacy; + + vbit_ctl =devm_kzalloc (dev,sizeof (*vbit_ctl),GFP_KERNEL ); +if (!vbit_ctl) +return -ENOMEM ; + +QCOM_REGMAP_FILED_ALLOC (dev, map, v->replace_vbit, vbit_ctl->replace_vbit); +QCOM_REGMAP_FILED_ALLOC (dev, map, v->vbit_stream, vbit_ctl->vbit_stream); + drvdata->vbit_ctl = vbit_ctl; + + tx_parity =devm_kzalloc (dev,sizeof (*tx_parity),GFP_KERNEL ); +if (!tx_parity) +return -ENOMEM ; + +QCOM_REGMAP_FILED_ALLOC (dev, map, v->calc_en, tx_parity->calc_en); + drvdata->tx_parity = 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, &meta_ctl->mute, &v->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, &sstream_ctl->sstream_en, &v->sstream_en,9 ); +if (rval) +return rval; + + drvdata->sstream_ctl = sstream_ctl; + +for (i =0 ; i <LPASS_MAX_HDMI_DMA_CHANNELS ; i++) { + ch_msb =devm_kzalloc (dev,sizeof (*ch_msb),GFP_KERNEL ); +if (!ch_msb) +return -ENOMEM ; + +QCOM_REGMAP_FILED_ALLOC (dev, map, v->msb_bits, ch_msb->msb_bits); + drvdata->ch_msb[i] = ch_msb; + + ch_lsb =devm_kzalloc (dev,sizeof (*ch_lsb),GFP_KERNEL ); +if (!ch_lsb) +return -ENOMEM ; + +QCOM_REGMAP_FILED_ALLOC (dev, map, v->lsb_bits, ch_lsb->lsb_bits); + drvdata->ch_lsb[i] = ch_lsb; + + tx_dmactl =devm_kzalloc (dev,sizeof (*tx_dmactl),GFP_KERNEL ); +if (!tx_dmactl) +return -ENOMEM ; + +QCOM_REGMAP_FILED_ALLOC (dev, map, v->use_hw_chs, tx_dmactl->use_hw_chs); +QCOM_REGMAP_FILED_ALLOC (dev, map, v->use_hw_usr, tx_dmactl->use_hw_usr); +QCOM_REGMAP_FILED_ALLOC (dev, map, v->hw_chs_sel, tx_dmactl->hw_chs_sel); +QCOM_REGMAP_FILED_ALLOC (dev, map, v->hw_usr_sel, tx_dmactl->hw_usr_sel); + drvdata->hdmi_tx_dmactl[i] = tx_dmactl; + } +return 0 ; +} +EXPORT_SYMBOL (lpass_hdmi_init_bitfields); +
...
sound/soc/qcom/lpass-hdmi.c line 456
Quoted 5 lines
sound/soc/qcom/lpass-hdmi.c new file +5
-0+ +static bool lpass_hdmi_regmap_volatile (struct device *dev,unsigned int reg) +{ +return true; +}
Are you sure are all the registers volatile?
Quoted 127 lines
sound/soc/qcom/lpass-hdmi.c new file +14
-0+ +struct regmap_config lpass_hdmi_regmap_config = { + .reg_bits =32 , + .reg_stride =4 , + .val_bits =32 , + .writeable_reg = lpass_hdmi_regmap_writeable, + .readable_reg = lpass_hdmi_regmap_readable, + .volatile_reg = lpass_hdmi_regmap_volatile, + .cache_type =REGCACHE_FLAT , +}; +EXPORT_SYMBOL (lpass_hdmi_regmap_config); + +MODULE_DESCRIPTION ("QTi LPASS HDMI Driver" ); +MODULE_LICENSE ("GPL v2" );sound/soc/qcom/lpass-hdmi.h new file +107
-0@@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* Copyright (c) 2020 The Linux Foundation. All rights reserved. +* +* lpass_hdmi.h - Definitions for the QTi LPASS HDMI +*/ + +#ifndef __LPASS_HDMI_H__ +#define __LPASS_HDMI_H__ + +#include <linux/regmap.h> + +#define LPASS_HDMITX_LEGACY_DISABLE 0x0 +#define LPASS_HDMITX_LEGACY_ENABLE 0x1 +#define LPASS_DP_AUDIO_BITWIDTH16 0x0 +#define LPASS_DP_AUDIO_BITWIDTH24 0xb +#define LPASS_DATA_FORMAT_SHIFT 0x1 +#define LPASS_FREQ_BIT_SHIFT 24 +#define LPASS_DATA_FORMAT_LINEAR 0x0 +#define LPASS_DATA_FORMAT_NON_LINEAR 0x1 +#define LPASS_SAMPLING_FREQ32 0x3 +#define LPASS_SAMPLING_FREQ44 0x0 +#define LPASS_SAMPLING_FREQ48 0x2 +#define LPASS_TX_CTL_RESET 0x1 +#define LPASS_TX_CTL_CLEAR 0x0 +#define LPASS_SSTREAM_ENABLE 1 +#define LPASS_SSTREAM_DISABLE 0 +#define LPASS_LAYOUT_SP_DEFAULT 0xf +#define LPASS_SSTREAM_DEFAULT_ENABLE 1 +#define LPASS_SSTREAM_DEFAULT_DISABLE 0 +#define LPASS_MUTE_ENABLE 1 +#define LPASS_MUTE_DISABLE 0 +#define LPASS_META_DEFAULT_VAL 0 +#define HW_MODE 1 +#define SW_MODE 0 +#define LEGACY_LPASS_LPAIF 1 +#define LEGACY_LPASS_HDMI 0 +#define REPLACE_VBIT 0x1 +#define LINEAR_PCM_DATA 0x0 +#define NON_LINEAR_PCM_DATA 0x1 +#define HDMITX_PARITY_CALC_EN 0x1 +#define HDMITX_PARITY_CALC_DIS 0x0 +#define LPASS_DATA_FORMAT_MASK GENMASK(1, 1) +#define LPASS_WORDLENGTH_MASK GENMASK(3, 0) +#define LPASS_FREQ_BIT_MASK GENMASK(27, 24) + +#define LPASS_HDMI_TX_CTL_ADDR (v) (v->hdmi_tx_ctl_addr) +#define LPASS_HDMI_TX_LEGACY_ADDR (v) (v->hdmi_legacy_addr) +#define LPASS_HDMI_TX_VBIT_CTL_ADDR (v) (v->hdmi_vbit_addr) +#define LPASS_HDMI_TX_PARITY_ADDR (v) (v->hdmi_parity_addr) +#define LPASS_HDMI_TX_DP_ADDR (v) (v->hdmi_DP_addr) +#define LPASS_HDMI_TX_SSTREAM_ADDR (v) (v->hdmi_sstream_addr) + +#define LPASS_HDMI_TX_CH_LSB_ADDR (v, port) \ + (v->hdmi_ch_lsb_addr + v->ch_stride * (port)) +#define LPASS_HDMI_TX_CH_MSB_ADDR (v, port) \ + (v->hdmi_ch_msb_addr + v->ch_stride * (port)) +#define LPASS_HDMI_TX_DMA_ADDR (v, port) \ + (v->hdmi_dmactl_addr + v->hdmi_dma_stride * (port)) + +struct lpass_sstream_ctl { +struct regmap_field *sstream_en; +struct regmap_field *dma_sel; +struct regmap_field *auto_bbit_en; +struct regmap_field *layout; +struct regmap_field *layout_sp; +struct regmap_field *set_sp_on_en; +struct regmap_field *dp_audio; +struct regmap_field *dp_staffing_en; +struct regmap_field *dp_sp_b_hw_en; +}; + +struct lpass_dp_metadata_ctl { +struct regmap_field *mute; +struct regmap_field *as_sdp_cc; +struct regmap_field *as_sdp_ct; +struct regmap_field *aif_db4; +struct regmap_field *frequency; +struct regmap_field *mst_index; +struct regmap_field *dptx_index; +}; + +struct lpass_hdmi_tx_ctl { +struct regmap_field *soft_reset; +struct regmap_field *force_reset; +}; + +struct lpass_hdmitx_dmactl { +struct regmap_field *use_hw_chs; +struct regmap_field *use_hw_usr; +struct regmap_field *hw_chs_sel; +struct regmap_field *hw_usr_sel; +}; + +struct lpass_vbit_ctrl { +struct regmap_field *replace_vbit; +struct regmap_field *vbit_stream; +}; + +struct lpass_hdmitx_legacy { +struct regmap_field *legacy_en; +}; + +struct lpass_hdmi_tx_parity { +struct regmap_field *calc_en; +}; +
sound/soc/qcom/lpass-hdmi.h line 117
Quoted 10 lines
sound/soc/qcom/lpass-hdmi.h new file +10
-0+struct lpass_hdmi_tx_ch_lsb { +struct regmap_field *lsb_bits; +}; + +struct lpass_hdmi_tx_ch_msb { +struct regmap_field *msb_bits; +}; + +extern int lpass_hdmi_init_bitfields (struct device *dev,struct regmap *map); +extern struct regmap_config lpass_hdmi_regmap_config;
You should consider moving the regmap_config to lpass-cpu.c, Not sure why we really need to export this symbol! most of this regmap config is only used in lpass-cpu.c
Quoted 27 lines
sound/soc/qcom/lpass-hdmi.h new file +5
-0+extern const struct snd_soc_dai_ops asoc_qcom_lpass_hdmi_dai_ops; + + + +#endif /* __LPASS_HDMI_H__ */ sound/soc/qcom/lpass-ipq806x.c +2
-2@@ -96,7 +96,7 @@ static int ipq806x_lpass_exit(struct platform_device *pdev)return 0 ; } -static int ipq806x_lpass_alloc_dma_channel (struct lpass_data *drvdata,int dir) +static int ipq806x_lpass_alloc_dma_channel (struct lpass_data *drvdata,int dir,unsigned int dai_id) {if (dir ==SNDRV_PCM_STREAM_PLAYBACK )return IPQ806X_LPAIF_RDMA_CHAN_MI2S ;@@ -104,7 +104,7 @@ static int ipq806x_lpass_alloc_dma_channel(struct lpass_data *drvdata, int dir)return -EINVAL ; } -static int ipq806x_lpass_free_dma_channel (struct lpass_data *drvdata,int chan) +static int ipq806x_lpass_free_dma_channel (struct lpass_data *drvdata,int chan,unsigned int dai_id) {return 0 ; }
...
sound/soc/qcom/lpass-platform.c struct lpass_pcm_data { · line 26
Quoted 10 lines
sound/soc/qcom/lpass-platform.c +1
-1@@ -23,7 +23,7 @@ struct lpass_pcm_data {int i2s_port; }; -#define LPASS_PLATFORM_BUFFER_SIZE (16 * 1024) +#define LPASS_PLATFORM_BUFFER_SIZE (24 * 2 * 1024)
Why do you need to change this?
even if you plan to change this please send this as a seperate patch!
Quoted 28 lines
sound/soc/qcom/lpass-platform.c +17
-0#define LPASS_PLATFORM_PERIODS 2static const struct snd_pcm_hardware lpass_platform_pcm_hardware = {@@ -80,6 +80,23 @@ static int lpass_platform_alloc_dmactl_fields(struct device *dev, &v->wrdma_intf, 6); } +static int lpass_platform_alloc_hdmidmactl_fields (struct device *dev, +struct regmap *map) +{ +struct lpass_data *drvdata =dev_get_drvdata (dev); +struct lpass_variant *v = drvdata->variant; +struct lpaif_dmactl *rd_dmactl; + + rd_dmactl =devm_kzalloc (dev,sizeof (struct lpaif_dmactl ),GFP_KERNEL ); +if (rd_dmactl ==NULL ) +return -ENOMEM ; + + drvdata->hdmi_rd_dmactl = rd_dmactl; + +return devm_regmap_field_bulk_alloc (dev, map, &rd_dmactl->bursten, + &v->hdmi_rdma_bursten,8 ); +} +static int lpass_platform_pcmops_open (struct snd_soc_component *component,struct snd_pcm_substream *substream) {
sound/soc/qcom/lpass-platform.c static int lpass_platform_pcmops_open(struct snd_soc_component *component, · line 109
Quoted 5 lines
sound/soc/qcom/lpass-platform.c +1
-1@@ -89,7 +106,9 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component,struct lpass_data *drvdata =snd_soc_component_get_drvdata (component);struct lpass_variant *v = drvdata->variant;int ret, dma_ch, dir = substream->stream; -struct lpass_pcm_data *data; +struct lpass_pcm_data *data =NULL ;
What is the reason for intializing, Did you hit any compile warning?
Quoted 44 lines
sound/soc/qcom/lpass-platform.c +13
-8+struct regmap *map; +unsigned int dai_id = cpu_dai->driver->id; data =kzalloc (sizeof (*data),GFP_KERNEL );if (!data)@@ -99,25 +118,28 @@ static int lpass_platform_pcmops_open(struct snd_soc_component *component, runtime->private_data = data;if (v->alloc_dma_channel) - dma_ch = v->alloc_dma_channel (drvdata, dir); + dma_ch = v->alloc_dma_channel (drvdata, dir, dai_id);else dma_ch =0 ;if (dma_ch <0 )return dma_ch; - drvdata->substream[dma_ch] = substream; - - ret =regmap_write (drvdata->lpaif_map, -LPAIF_DMACTL_REG (v, dma_ch, dir),0 ); +if (cpu_dai->driver->id ==LPASS_DP_RX ) { + map = drvdata->hdmiif_map; + drvdata->hdmi_substream[dma_ch] = substream; + }else { + map = drvdata->lpaif_map; + drvdata->substream[dma_ch] = substream; + } + data->dma_ch = dma_ch; + ret =regmap_write (map, +LPAIF_DMACTL_REG (v, dma_ch, dir, data->i2s_port),0 );if (ret) {dev_err (soc_runtime->dev,"error writing to rdmactl reg: %d\n" , ret);return ret; } - - data->dma_ch = dma_ch; -snd_soc_set_runtime_hwparams (substream, &lpass_platform_pcm_hardware); runtime->dma_bytes = lpass_platform_pcm_hardware.buffer_bytes_max;@@ -139,14 +161,20 @@ static int lpass_platform_pcmops_close(struct snd_soc_component *component,
...
Quoted 5 lines
static int lpass_platform_pcm_new(struct
snd_soc_component*component,
structsnd_soc_pcm_runtime*soc_runtime)
{sound/soc/qcom/lpass-platform.c +0
-0@@ -625,22 +856,20 @@ int asoc_qcom_lpass_platform_register(struct platform_device *pdev)if (drvdata->lpaif_irq <0 )
sound/soc/qcom/lpass-platform.c int asoc_qcom_lpass_platform_register(struct platform_device *pdev) · line 862
Quoted 10 lines
sound/soc/qcom/lpass-platform.c +3
-4return -ENODEV ; -/* ensure audio hardware is disabled */ - ret =regmap_write (drvdata->lpaif_map, -LPAIF_IRQEN_REG (v,LPAIF_IRQ_PORT_HOST ),0 ); + ret =devm_request_irq (&pdev->dev, drvdata->lpaif_irq, + lpass_platform_lpaif_irq,0 ,"lpass-irq-lpaif" , drvdata);if (ret) { -dev_err (&pdev->dev,"error writing to irqen reg: %d\n" , ret); +dev_err (&pdev->dev,"irq request failed: %d\n" , ret);
This type of changes can be in seperate patch!
Quoted 5 lines
sound/soc/qcom/lpass-platform.c +0
-2return ret; } - ret = devm_request_irq(&pdev->dev, drvdata->lpaif_irq, - lpass_platform_lpaif_irq, IRQF_TRIGGER_RISING,
sound/soc/qcom/lpass-platform.c int asoc_qcom_lpass_platform_register(struct platform_device *pdev) · line 643
Quoted 10 lines
sound/soc/qcom/lpass-platform.c +4
-3- "lpass-irq-lpaif", drvdata); +/* ensure audio hardware is disabled */ + ret =regmap_write (drvdata->lpaif_map, +LPAIF_IRQEN_REG (v,LPAIF_IRQ_PORT_HOST ),0 );if (ret) { -dev_err (&pdev->dev,"irq request failed: %d\n" , ret); +dev_err (&pdev->dev,"error writing to irqen reg: %d\n" , ret);return ret; } -
Unnecessary change!
sound/soc/qcom/lpass-platform.c int asoc_qcom_lpass_platform_register(struct platform_device *pdev) · line 874
Quoted 2 lines
sound/soc/qcom/lpass-platform.c +0
-0ret =lpass_platform_alloc_dmactl_fields (&pdev->dev, drvdata->lpaif_map);
Thanks,
srini
Re: [PATCH v7 5/6] ASoC: qcom: Add support for lpass hdmi driver
Thanks Srinivas For Review Comments!!!
Quoted 72 lines · Srinivas Kandagatla
Quoted 5 lines · Srinivasa Rao Mandadapu
From: V Sujith Kumar Reddy <[email protected]>
Upadate lpass cpu and platform driver to support audio over dp. Also add
lpass-hdmi.candlpass-hdmi.h.Thanks for doing the rework this patch looks much better now!
However I have few comments below!
Quoted 41 lines
Signed-off-by V Sujith Kumar Reddy <[email protected]>Signed-off-by Srinivasa Rao <[email protected]>---
sound/soc/qcom/Kconfig | 17 ++ sound/soc/qcom/Makefile | 2 + sound/soc/qcom/lpass-apq8016.c | 4 +- sound/soc/qcom/lpass-cpu.c | 53 ++++- sound/soc/qcom/lpass-hdmi.c | 470
+++++++++++++++++++++++++++++++++++++++
sound/soc/qcom/lpass-hdmi.h | 122 ++++++++++ sound/soc/qcom/lpass-ipq806x.c | 4 +-sound/soc/qcom/lpass-lpaif-reg.h| 52 ++++- sound/soc/qcom/lpass-platform.c | 411
+++++++++++++++++++++++++++-------
sound/soc/qcom/lpass.h | 113 +++++++++-10 files changed, 1137 insertions(+), 111 deletions(-)create mode 100644
sound/soc/qcom/lpass-hdmi.c
create mode 100644sound/soc/qcom/lpass-hdmi.hsound/soc/qcom/Kconfig +0
-0@@ -12,6 +12,10 @@ config SND_SOC_LPASS_CPUtristate
selectREGMAP_MMIO
+configSND_SOC_LPASS_HDMI
+ tristate
+ selectREGMAP_MMIO
+
configSND_SOC_LPASS_PLATFORM
tristate
selectREGMAP_MMIOsound/soc/qcom/Kconfig +0
-0@@ -30,6 +34,7 @@ config SND_SOC_LPASS_SC7180tristate
selectSND_SOC_LPASS_CPU
selectSND_SOC_LPASS_PLATFORM
+ selectSND_SOC_LPASS_HDMI
configSND_SOC_STORM
tristate "ASoC I2S support for Storm boards"sound/soc/qcom/Kconfig +0
-0@@ -120,4 +125,16 @@ config SND_SOC_SDM845Quoted 2 lines
SDM845 SoC-based systems.
Say Y if you want to use audio device on this SoCs.<<<<<<
Quoted 12 lines
sound/soc/qcom/Kconfig +12
-0+config SND_SOC_SC7180 + tristate "SoC Machine driver for SC7180 boards" + depends on I2C + select SND_SOC_QCOM_COMMON + select SND_SOC_LPASS_SC7180 + select SND_SOC_MAX98357A + select SND_SOC_RT5682_I2C + help + To add support for audio on Qualcomm Technologies Inc. + SC7180 SoC-based systems. + Say Y if you want to use audio device on this SoCs. +Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Quoted 1 line
Does this change belong to this patch!
Yeah! This change is not related but compilation depends on this.
we will remove this change for now.
Quoted 70 lines
Quoted 70 lines
endif #SND_SOC_QCOM
sound/soc/qcom/Makefile +0
-0@@ -1,12 +1,14 @@ # SPDX-License-Identifier: GPL-2.0 # Platformsnd-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
sound/soc/qcom/lpass-apq8016.c +2
-1@@ -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(structlpass_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, &drvdata->dma_ch_bit_map);
diff --gita/sound/soc/qcom/lpass-cpu.cb/sound/soc/qcom/lpass-cpu.cindex 12950d2..81aaf51 100644sound/soc/qcom/lpass-cpu.c +10
-6@@ -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"); + } }
Quoted 8 lines
Quoted 6 lines
sound/soc/qcom/lpass-cpu.c +0
-0}@@ -589,13 +593,34 @@ int
asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev)variant->wrdma_channel_start);
drvdata->lpaif_map= devm_regmap_init_mmio(dev,drvdata->lpaif,
-&lpass_cpu_regmap_config);
+&lpass_cpu_regmap_config);Looks like unnecessary change!
Yes! will remove this.
Quoted 82 lines
Quoted 82 lines
if (
IS_ERR(drvdata->lpaif_map)) {
dev_err(dev, "error initializing regmap: %ld\n", PTR_ERR(drvdata->lpaif_map));
returnPTR_ERR(drvdata->lpaif_map);
}
+ if (drvdata->hdmi_port_enable) {
+ res =platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-hdmiif");sound/soc/qcom/lpass-cpu.c +9
-0+ + drvdata->hdmiif = devm_ioremap_resource(dev, res); + if (IS_ERR((void const __force *)drvdata->hdmiif)) { + dev_err(dev, "error mapping reg resource: %ld\n", + PTR_ERR((void const __force *)drvdata->hdmiif)); + return PTR_ERR((void const __force *)drvdata->hdmiif); + } + + lpass_hdmi_regmap_config.max_register =LPAIF_HDMI_RDMAPER_REG(variant,
+variant->hdmi_rdma_channels); +drvdata->hdmiif_map= devm_regmap_init_mmio(dev,drvdata->hdmiif,
+&lpass_hdmi_regmap_config);
+ if (IS_ERR(drvdata->hdmiif_map)) {
+dev_err(dev, "error initializing regmap: %ld\n", + PTR_ERR(drvdata->hdmiif_map));
+ returnPTR_ERR(drvdata->hdmiif_map);
+ }
+ }
+
if (variant->init) {
ret =variant->init(pdev);
if (ret) {sound/soc/qcom/lpass-cpu.c +10
-3@@ -606,6 +631,9 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) for (i = 0; i < variant->num_dai; i++) { dai_id = variant->dai_driver[i].id; + if (dai_id == LPASS_DP_RX) + continue; + drvdata->mi2s_osr_clk[dai_id] = devm_clk_get(dev, variant->dai_osr_clk_names[i]); if (IS_ERR(drvdata->mi2s_osr_clk[dai_id])) {@@ -636,11 +664,16 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platform_device *pdev) /* Initialize bitfields for dai I2SCTL register */ ret = lpass_cpu_init_i2sctl_bitfields(dev, drvdata->i2sctl, drvdata->lpaif_map); - if (ret) { + if (ret) dev_err(dev, "error init i2sctl field: %d\n", ret); - return ret; - } + if (drvdata->hdmi_port_enable) { + ret = lpass_hdmi_init_bitfields(dev, drvdata->hdmiif_map); + if (ret) { + dev_err(dev, "%s error hdmi init failed\n", __func__); + return ret; + } + } ret = devm_snd_soc_register_component(dev, &lpass_cpu_comp_driver,
variant->dai_driver,sound/soc/qcom/lpass-hdmi.c new file +13
-0@@ -0,0 +1,470 @@ +// 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 <linux/kernel.h> +#include <linux/module.h> +#include <sound/pcm_params.h> +#include <linux/regmap.h> +#include <sound/soc.h>
Quoted 8 lines
sound/soc/qcom/lpass-hdmi.c line 19
Quoted 6 lines
sound/soc/qcom/lpass-hdmi.c new file +6
-0+#include <sound/soc-dai.h> +#include <dt-bindings/sound/sc7180-lpass.h> +#include "lpass-lpaif-reg.h" +#include "lpass.h" + +#define QCOM_REGMAP_FILED_ALLOC (d, m, f, mf) \s/QCOM_REGMAP_FILED_ALLOC/QCOM_REGMAP_FIELD_ALLOC
Okay! will update this.
Quoted 18 lines
Quoted 18 lines
sound/soc/qcom/lpass-hdmi.c new file +17
-0+ do { \ + mf = devm_regmap_field_alloc(d, m, f); \ + if (IS_ERR(mf)) \ + return -EINVAL; \ + } while (0) + + +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 lpass_hdmitx_legacy *legacy; + struct lpass_vbit_ctrl *vbit_ctl; + struct lpass_hdmi_tx_parity *tx_parity; + struct lpass_dp_metadata_ctl *meta_ctl;
Quoted 8 lines
sound/soc/qcom/lpass-hdmi.c line 40
Quoted 4 lines
sound/soc/qcom/lpass-hdmi.c new file +4
-0+ struct lpass_sstream_ctl *sstream_ctl; + struct lpass_hdmi_tx_ch_msb *ch_msb; + struct lpass_hdmi_tx_ch_lsb *ch_lsb; + struct lpass_hdmitx_dmactl *tx_dmactl;I see that you split the data structures into logical groups, does it really help the driver in anyway? I mean do you pass this structures to any functions? Question is do you really need this level of abstraction?
Can't you just use flat regmap fileds with prefixes that would make code even cleaner!
Yes! We will try to use direct regmap field where single member is there.
Quoted 96 lines
Quoted 94 lines
sound/soc/qcom/lpass-hdmi.c new file +7
-0+ int rval; + + tx_ctl = devm_kzalloc(dev, sizeof(*tx_ctl), GFP_KERNEL); + if (!tx_ctl) + return -ENOMEM; + + QCOM_REGMAP_FILED_ALLOC(dev, map, v->soft_reset,
tx_ctl->soft_reset);
+QCOM_REGMAP_FILED_ALLOC(dev, map, v->force_reset, tx_ctl->force_reset);
+drvdata->tx_ctl=tx_ctl;sound/soc/qcom/lpass-hdmi.c new file +13
-0+ + legacy = devm_kzalloc(dev, sizeof(*legacy), GFP_KERNEL); + if (!legacy) + return -ENOMEM; + + QCOM_REGMAP_FILED_ALLOC(dev, map, v->legacy_en, legacy->legacy_en); + drvdata->legacy = legacy; + + vbit_ctl = devm_kzalloc(dev, sizeof(*vbit_ctl), GFP_KERNEL); + if (!vbit_ctl) + return -ENOMEM; + + QCOM_REGMAP_FILED_ALLOC(dev, map, v->replace_vbit,
vbit_ctl->replace_vbit);
+QCOM_REGMAP_FILED_ALLOC(dev, map, v->vbit_stream, vbit_ctl->vbit_stream);
+drvdata->vbit_ctl=vbit_ctl;sound/soc/qcom/lpass-hdmi.c new file +13
-0+ + tx_parity = devm_kzalloc(dev, sizeof(*tx_parity), GFP_KERNEL); + if (!tx_parity) + return -ENOMEM; + + QCOM_REGMAP_FILED_ALLOC(dev, map, v->calc_en, tx_parity->calc_en); + drvdata->tx_parity = 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, &meta_ctl->mute,
&v->mute, 7);
+ if (rval)
+ return rval;
+drvdata->meta_ctl=meta_ctl;sound/soc/qcom/lpass-hdmi.c new file +6
-0+ + sstream_ctl = devm_kzalloc(dev, sizeof(*sstream_ctl), GFP_KERNEL); + if (!sstream_ctl) + return -ENOMEM; + + rval = devm_regmap_field_bulk_alloc(dev, map,
&sstream_ctl->sstream_en,&v->sstream_en, 9);
+ if (rval)
+ return rval;sound/soc/qcom/lpass-hdmi.c new file +9
-0+ + drvdata->sstream_ctl = sstream_ctl; + + for (i = 0; i < LPASS_MAX_HDMI_DMA_CHANNELS; i++) { + ch_msb = devm_kzalloc(dev, sizeof(*ch_msb), GFP_KERNEL); + if (!ch_msb) + return -ENOMEM; + + QCOM_REGMAP_FILED_ALLOC(dev, map, v->msb_bits,
ch_msb->msb_bits);
+ drvdata->ch_msb[i] =ch_msb;sound/soc/qcom/lpass-hdmi.c new file +6
-0+ + ch_lsb = devm_kzalloc(dev, sizeof(*ch_lsb), GFP_KERNEL); + if (!ch_lsb) + return -ENOMEM; + + QCOM_REGMAP_FILED_ALLOC(dev, map, v->lsb_bits,
ch_lsb->lsb_bits);
+ drvdata->ch_lsb[i] =ch_lsb;sound/soc/qcom/lpass-hdmi.c new file +6
-0+ + tx_dmactl = devm_kzalloc(dev, sizeof(*tx_dmactl), GFP_KERNEL); + if (!tx_dmactl) + return -ENOMEM; + + QCOM_REGMAP_FILED_ALLOC(dev, map, v->use_hw_chs,
tx_dmactl->use_hw_chs);
+QCOM_REGMAP_FILED_ALLOC(dev, map, v->use_hw_usr, tx_dmactl->use_hw_usr);
+QCOM_REGMAP_FILED_ALLOC(dev, map, v->hw_chs_sel, tx_dmactl->hw_chs_sel);
+QCOM_REGMAP_FILED_ALLOC(dev, map, v->hw_usr_sel, tx_dmactl->hw_usr_sel);
+ drvdata->hdmi_tx_dmactl[i] =tx_dmactl; + }
+ return 0;sound/soc/qcom/lpass-hdmi.c new file +3
-0+} +EXPORT_SYMBOL (lpass_hdmi_init_bitfields); +...
Quoted 8 lines
sound/soc/qcom/lpass-hdmi.c line 389
Quoted 6 lines
sound/soc/qcom/lpass-hdmi.c new file +2
-0+ +static bool lpass_hdmi_regmap_volatile(struct device *dev, unsignedint reg)
sound/soc/qcom/lpass-hdmi.c new file +3
-0+{ + return true; +}Are you sure are all the registers volatile?
Yes! Without volatile observed some issue.
Quoted 134 lines
Quoted 134 lines
sound/soc/qcom/lpass-hdmi.c new file +14
-0+ +struct regmap_config lpass_hdmi_regmap_config = { + .reg_bits = 32, + .reg_stride = 4, + .val_bits = 32, + .writeable_reg = lpass_hdmi_regmap_writeable, + .readable_reg = lpass_hdmi_regmap_readable, + .volatile_reg = lpass_hdmi_regmap_volatile, + .cache_type = REGCACHE_FLAT, +}; +EXPORT_SYMBOL (lpass_hdmi_regmap_config); + +MODULE_DESCRIPTION ("QTi LPASS HDMI Driver" ); +MODULE_LICENSE ("GPL v2" );sound/soc/qcom/lpass-hdmi.h new file +112
-0@@ -0,0 +1,122 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* +* Copyright (c) 2020 The Linux Foundation. All rights reserved. +* +* lpass_hdmi.h - Definitions for the QTi LPASS HDMI +*/ + +#ifndef __LPASS_HDMI_H__ +#define __LPASS_HDMI_H__ + +#include <linux/regmap.h> + +#define LPASS_HDMITX_LEGACY_DISABLE 0x0 +#define LPASS_HDMITX_LEGACY_ENABLE 0x1 +#define LPASS_DP_AUDIO_BITWIDTH16 0x0 +#define LPASS_DP_AUDIO_BITWIDTH24 0xb +#define LPASS_DATA_FORMAT_SHIFT 0x1 +#define LPASS_FREQ_BIT_SHIFT 24 +#define LPASS_DATA_FORMAT_LINEAR 0x0 +#define LPASS_DATA_FORMAT_NON_LINEAR 0x1 +#define LPASS_SAMPLING_FREQ32 0x3 +#define LPASS_SAMPLING_FREQ44 0x0 +#define LPASS_SAMPLING_FREQ48 0x2 +#define LPASS_TX_CTL_RESET 0x1 +#define LPASS_TX_CTL_CLEAR 0x0 +#define LPASS_SSTREAM_ENABLE 1 +#define LPASS_SSTREAM_DISABLE 0 +#define LPASS_LAYOUT_SP_DEFAULT 0xf +#define LPASS_SSTREAM_DEFAULT_ENABLE 1 +#define LPASS_SSTREAM_DEFAULT_DISABLE 0 +#define LPASS_MUTE_ENABLE 1 +#define LPASS_MUTE_DISABLE 0 +#define LPASS_META_DEFAULT_VAL 0 +#define HW_MODE 1 +#define SW_MODE 0 +#define LEGACY_LPASS_LPAIF 1 +#define LEGACY_LPASS_HDMI 0 +#define REPLACE_VBIT 0x1 +#define LINEAR_PCM_DATA 0x0 +#define NON_LINEAR_PCM_DATA 0x1 +#define HDMITX_PARITY_CALC_EN 0x1 +#define HDMITX_PARITY_CALC_DIS 0x0 +#define LPASS_DATA_FORMAT_MASK GENMASK(1, 1) +#define LPASS_WORDLENGTH_MASK GENMASK(3, 0) +#define LPASS_FREQ_BIT_MASK GENMASK(27, 24) + +#define LPASS_HDMI_TX_CTL_ADDR (v) (v->hdmi_tx_ctl_addr) +#define LPASS_HDMI_TX_LEGACY_ADDR (v) (v->hdmi_legacy_addr) +#define LPASS_HDMI_TX_VBIT_CTL_ADDR (v) (v->hdmi_vbit_addr) +#define LPASS_HDMI_TX_PARITY_ADDR (v) (v->hdmi_parity_addr) +#define LPASS_HDMI_TX_DP_ADDR (v) (v->hdmi_DP_addr) +#define LPASS_HDMI_TX_SSTREAM_ADDR (v) (v->hdmi_sstream_addr) + +#define LPASS_HDMI_TX_CH_LSB_ADDR (v, port) \ + (v->hdmi_ch_lsb_addr + v->ch_stride * (port)) +#define LPASS_HDMI_TX_CH_MSB_ADDR (v, port) \ + (v->hdmi_ch_msb_addr + v->ch_stride * (port)) +#define LPASS_HDMI_TX_DMA_ADDR (v, port) \ + (v->hdmi_dmactl_addr + v->hdmi_dma_stride * (port)) + +struct lpass_sstream_ctl { + struct regmap_field *sstream_en; + struct regmap_field *dma_sel; + struct regmap_field *auto_bbit_en; + struct regmap_field *layout; + struct regmap_field *layout_sp; + struct regmap_field *set_sp_on_en; + struct regmap_field *dp_audio; + struct regmap_field *dp_staffing_en; + struct regmap_field *dp_sp_b_hw_en; +}; + +struct lpass_dp_metadata_ctl { + struct regmap_field *mute; + struct regmap_field *as_sdp_cc; + struct regmap_field *as_sdp_ct; + struct regmap_field *aif_db4; + struct regmap_field *frequency; + struct regmap_field *mst_index; + struct regmap_field *dptx_index; +}; + +struct lpass_hdmi_tx_ctl { + struct regmap_field *soft_reset; + struct regmap_field *force_reset; +}; + +struct lpass_hdmitx_dmactl { + struct regmap_field *use_hw_chs; + struct regmap_field *use_hw_usr; + struct regmap_field *hw_chs_sel; + struct regmap_field *hw_usr_sel; +}; + +struct lpass_vbit_ctrl { + struct regmap_field *replace_vbit; + struct regmap_field *vbit_stream; +}; + +struct lpass_hdmitx_legacy { + struct regmap_field *legacy_en; +}; + +struct lpass_hdmi_tx_parity { + struct regmap_field *calc_en; +}; + +struct lpass_hdmi_tx_ch_lsb { + struct regmap_field *lsb_bits; +}; + +struct lpass_hdmi_tx_ch_msb {
Quoted 8 lines
Quoted 6 lines
sound/soc/qcom/lpass-hdmi.h new file +4
-0+ struct regmap_field *msb_bits; +}; + +extern int lpass_hdmi_init_bitfields(struct device *dev, structregmap *map);
+extern structregmap_configlpass_hdmi_regmap_config;You should consider moving the
regmap_configtolpass-cpu.c, Not sure why we really need to export this symbol! most of this regmap config is only used inlpass-cpu.c
Okay! will move it lpass-cpu.c
Quoted 33 lines
Quoted 31 lines
sound/soc/qcom/lpass-hdmi.h new file +5
-0+extern const struct snd_soc_dai_ops asoc_qcom_lpass_hdmi_dai_ops; + + + +#endif /* __LPASS_HDMI_H__ */ sound/soc/qcom/lpass-ipq806x.c +1
-0@@ -96,7 +96,7 @@ static int ipq806x_lpass_exit(struct platform_device *pdev) return 0; } -static int ipq806x_lpass_alloc_dma_channel(struct lpass_data *drvdata, int dir) +static int ipq806x_lpass_alloc_dma_channel(struct lpass_data *drvdata, int dir, unsigned int dai_id) {if (dir ==
SNDRV_PCM_STREAM_PLAYBACK)
returnIPQ806X_LPAIF_RDMA_CHAN_MI2S;sound/soc/qcom/lpass-ipq806x.c +1
-0@@ -104,7 +104,7 @@ static int ipq806x_lpass_alloc_dma_channel(struct lpass_data *drvdata, int dir) return -EINVAL; } -static int ipq806x_lpass_free_dma_channel(struct lpass_data *drvdata, int chan) +static int ipq806x_lpass_free_dma_channel(struct lpass_data *drvdata, int chan, unsigned int dai_id) {return 0;
}...
Quoted 13 lines
sound/soc/qcom/lpass-platform.c struct lpass_pcm_data { · line 26
Quoted 9 lines
sound/soc/qcom/lpass-platform.c +1
-0@@ -23,7 +23,7 @@ struct lpass_pcm_data { int i2s_port; }; -#define LPASS_PLATFORM_BUFFER_SIZE (16 * 1024) +#define LPASS_PLATFORM_BUFFER_SIZE (24 * 2 * 1024)Why do you need to change this?
even if you plan to change this please send this as a seperate patch!
Okay We will create separate patch for this change
Quoted 29 lines
Quoted 29 lines
sound/soc/qcom/lpass-platform.c +16
-0#define LPASS_PLATFORM_PERIODS 2 static const struct snd_pcm_hardware lpass_platform_pcm_hardware = {@@ -80,6 +80,23 @@ static int lpass_platform_alloc_dmactl_fields(struct device *dev, &v->wrdma_intf, 6); } +static int lpass_platform_alloc_hdmidmactl_fields(struct device *dev, + struct regmap *map) +{ + struct lpass_data *drvdata = dev_get_drvdata(dev); + struct lpass_variant *v = drvdata->variant; + struct lpaif_dmactl *rd_dmactl; + + rd_dmactl = devm_kzalloc(dev, sizeof(struct lpaif_dmactl),GFP_KERNEL ); + if (rd_dmactl == NULL) + return -ENOMEM; + + drvdata->hdmi_rd_dmactl = rd_dmactl; + + return devm_regmap_field_bulk_alloc(dev, map, &rd_dmactl->bursten, + &v->hdmi_rdma_bursten, 8); +} + static int lpass_platform_pcmops_open(struct snd_soc_component *component,struct
snd_pcm_substream*substream) {sound/soc/qcom/lpass-platform.c +0
-0@@ -89,7 +106,9 @@ static int lpass_platform_pcmops_open(struct
Quoted 8 lines
sound/soc/qcom/lpass-platform.c static int lpass_platform_pcmops_open(struct snd_soc_component *component, · line 109
Quoted 6 lines
sound/soc/qcom/lpass-platform.c +1
-1snd_soc_component *component, struct lpass_data *drvdata = snd_soc_component_get_drvdata(component); struct lpass_variant *v = drvdata->variant; int ret, dma_ch, dir = substream->stream; - struct lpass_pcm_data *data; + struct lpass_pcm_data *data = NULL;What is the reason for intializing, Did you hit any compile warning?
Yeah.. It's redundant. will remove this.
Quoted 53 lines
Quoted 41 lines
sound/soc/qcom/lpass-platform.c +3
-1+ struct regmap *map; + unsigned int dai_id = cpu_dai->driver->id; data = kzalloc(sizeof(*data), GFP_KERNEL); if (!data)@@ -99,25 +118,28 @@ static int lpass_platform_pcmops_open(structsnd_soc_component *component, runtime->private_data = data; if (v->alloc_dma_channel) - dma_ch = v->alloc_dma_channel(drvdata, dir); + dma_ch = v->alloc_dma_channel(drvdata, dir, dai_id);else
dma_ch= 0;
if (dma_ch< 0)
returndma_ch;
- drvdata->substream[dma_ch] = substream;
-
- ret = regmap_write(drvdata->lpaif_map,
-LPAIF_DMACTL_REG(v, dma_ch, dir), 0);
+ if (cpu_dai->driver->id==LPASS_DP_RX) {
+ map =drvdata->hdmiif_map;
+ drvdata->hdmi_substream[dma_ch] = substream;
+ } else {
+ map =drvdata->lpaif_map;
+ drvdata->substream[dma_ch] = substream;
+ }
+data->dma_ch=dma_ch;
+ ret = regmap_write(map,
+LPAIF_DMACTL_REG(v, dma_ch, dir, data->i2s_port), 0); if (ret) {
dev_err(soc_runtime->dev,
"error writing to rdmactl reg: %d\n", ret); return ret;
}sound/soc/qcom/lpass-platform.c +0
-3- - data->dma_ch = dma_ch; -
snd_soc_set_runtime_hwparams(substream, &lpass_platform_pcm_hardware);runtime->dma_bytes= lpass_platform_pcm_hardware.buffer_bytes_max;sound/soc/qcom/lpass-platform.c +0
-0@@ -139,14 +161,20 @@ static int lpass_platform_pcmops_close(struct snd_soc_component *component,...
Quoted 9 lines
static int
lpass_platform_pcm_new(struct snd_soc_component *component, struct snd_soc_pcm_runtime *soc_runtime){sound/soc/qcom/lpass-platform.c +0
-0@@ -625,22 +856,20 @@ int asoc_qcom_lpass_platform_register(struct platform_device *pdev) if (drvdata->lpaif_irq < 0) return -ENODEV;- /* ensure audio hardware is disabled */
- ret = regmap_write(drvdata->lpaif_map,
Quoted 8 lines
Quoted 6 lines
-
LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST), 0);
+ ret = devm_request_irq(&pdev->dev,drvdata->lpaif_irq, +lpass_platform_lpaif_irq, 0, "lpass-irq-lpaif", drvdata); if (ret) {
-dev_err(&pdev->dev, "error writing to irqen reg: %d\n", ret); +dev_err(&pdev->dev, "irq request failed: %d\n", ret);This type of changes can be in seperate patch!
This is change not required. will remove this change.
Quoted 16 lines
Quoted 15 lines
return ret;
}
- ret = devm_request_irq(&pdev->dev,drvdata->lpaif_irq, -lpass_platform_lpaif_irq,IRQF_TRIGGER_RISING, - "lpass-irq-lpaif", drvdata);
+ /* ensure audio hardware is disabled */
+ ret = regmap_write(drvdata->lpaif_map,
+LPAIF_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST), 0); if (ret) {
-dev_err(&pdev->dev, "irq request failed: %d\n", ret); +dev_err(&pdev->dev, "error writing to irqen reg: %d\n", ret); return ret;
}
-
Quoted 1 line
Unnecessary change!
Okay!. Will remove this.
Quoted 6 lines
Quoted 3 lines
ret =
lpass_platform_alloc_dmactl_fields(&pdev->dev, drvdata->lpaif_map);Thanks,
srini
Signature · 2 lines
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.
PATCH v7 6/6 ASoC: qcom: sc7180: Add support for audio over DP
In reply to Srinivasa Rao MandadapuFrom: V Sujith Kumar Reddy <[email protected]>
Add support for audio playback over DP in lpass
sc7180 platform driver. Update lpass_variant
structure for hdmi data configuaration.
--- sound/soc/qcom/lpass-sc7180.c | 116 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 102 insertions(+), 14 deletions(-)
sound/soc/qcom/lpass-sc7180.c +102 -14
@@ -60,38 +60,65 @@ static struct snd_soc_dai_driver sc7180_lpass_cpu_dai_driver[] = { .probe = &asoc_qcom_lpass_cpu_dai_probe, .ops = &asoc_qcom_lpass_cpu_dai_ops, }, + [LPASS_DP_RX] = { + .id = LPASS_DP_RX, + .name = "Hdmi", + .playback = { + .stream_name = "Hdmi Playback", + .formats = SNDRV_PCM_FMTBIT_S24, + .rates = SNDRV_PCM_RATE_48000, + .rate_min = 48000, + .rate_max = 48000, + .channels_min = 2, + .channels_max = 2, + }, + .ops = &asoc_qcom_lpass_hdmi_dai_ops, + }, };static int sc7180_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 ; -if (direction ==SNDRV_PCM_STREAM_PLAYBACK ) { - chan =find_first_zero_bit (&drvdata->dma_ch_bit_map, - v->rdma_channels); +if (dai_id ==LPASS_DP_RX ) { +if (direction ==SNDRV_PCM_STREAM_PLAYBACK ) { + chan =find_first_zero_bit (&drvdata->hdmi_dma_ch_bit_map, + v->hdmi_rdma_channels); + +if (chan >= v->hdmi_rdma_channels) +return -EBUSY ; + } +set_bit (chan, &drvdata->hdmi_dma_ch_bit_map); + }else { +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, + }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); +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) +static int sc7180_lpass_free_dma_channel (struct lpass_data *drvdata,int chan,unsigned int dai_id) { -clear_bit (chan, &drvdata->dma_ch_bit_map); +if (dai_id ==LPASS_DP_RX ) +clear_bit (chan, &drvdata->hdmi_dma_ch_bit_map); +else +clear_bit (chan, &drvdata->dma_ch_bit_map);return 0 ; }
@@ -144,6 +171,9 @@ static struct lpass_variant sc7180_data = { .rdma_reg_base = 0xC000, .rdma_reg_stride = 0x1000, .rdma_channels = 5, + .hdmi_rdma_reg_base = 0x64000, + .hdmi_rdma_reg_stride = 0x1000, + .hdmi_rdma_channels = 4, .dmactl_audif_start = 1, .wrdma_reg_base = 0x18000, .wrdma_reg_stride = 0x1000,
@@ -163,7 +193,7 @@ static struct lpass_variant sc7180_data = { .rdma_dyncclk = REG_FIELD_ID(0xC000, 21, 21, 5, 0x1000), .rdma_bursten = REG_FIELD_ID(0xC000, 20, 20, 5, 0x1000), .rdma_wpscnt = REG_FIELD_ID(0xC000, 16, 19, 5, 0x1000), - .rdma_intf = REG_FIELD_ID(0xC000, 12, 15, 5, 0x1000), + .rdma_intf = REG_FIELD_ID(0xC000, 12, 15, 5, 0x1000), .rdma_fifowm = REG_FIELD_ID(0xC000, 1, 5, 5, 0x1000), .rdma_enable = REG_FIELD_ID(0xC000, 0, 0, 5, 0x1000),
@@ -174,6 +204,64 @@ static struct lpass_variant sc7180_data = { .wrdma_fifowm = REG_FIELD_ID(0x18000, 1, 5, 4, 0x1000), .wrdma_enable = REG_FIELD_ID(0x18000, 0, 0, 4, 0x1000), + .hdmi_tx_ctl_addr = 0x1000, + .hdmi_legacy_addr = 0x1008, + .hdmi_vbit_addr = 0x610c0, + .hdmi_ch_lsb_addr = 0x61048, + .hdmi_ch_msb_addr = 0x6104c, + .ch_stride = 0x8, + .hdmi_parity_addr = 0x61034, + .hdmi_dmactl_addr = 0x61038, + .hdmi_dma_stride = 0x4, + .hdmi_DP_addr = 0x610c8, + .hdmi_sstream_addr = 0x6101c, + .hdmi_irq_reg_base = 0x63000, + .hdmi_irq_ports = 1, + + .hdmi_rdma_dyncclk = REG_FIELD_ID(0x64000, 14, 14, 4, 0x1000), + .hdmi_rdma_bursten = REG_FIELD_ID(0x64000, 13, 13, 4, 0x1000), + .hdmi_rdma_burst8 = REG_FIELD_ID(0x64000, 15, 15, 4, 0x1000), + .hdmi_rdma_burst16 = REG_FIELD_ID(0x64000, 16, 16, 4, 0x1000), + .hdmi_rdma_dynburst = REG_FIELD_ID(0x64000, 18, 18, 4, 0x1000), + .hdmi_rdma_wpscnt = REG_FIELD_ID(0x64000, 10, 12, 4, 0x1000), + .hdmi_rdma_fifowm = REG_FIELD_ID(0x64000, 1, 5, 4, 0x1000), + .hdmi_rdma_enable = REG_FIELD_ID(0x64000, 0, 0, 4, 0x1000), + + .sstream_en = REG_FIELD(0x6101c, 0, 0), + .dma_sel = REG_FIELD(0x6101c, 1, 2), + .auto_bbit_en = REG_FIELD(0x6101c, 3, 3), + .layout = REG_FIELD(0x6101c, 4, 4), + .layout_sp = REG_FIELD(0x6101c, 5, 8), + .set_sp_on_en = REG_FIELD(0x6101c, 10, 10), + .dp_audio = REG_FIELD(0x6101c, 11, 11), + .dp_staffing_en = REG_FIELD(0x6101c, 12, 12), + .dp_sp_b_hw_en = REG_FIELD(0x6101c, 13, 13), + + .mute = REG_FIELD(0x610c8, 0, 0), + .as_sdp_cc = REG_FIELD(0x610c8, 1, 3), + .as_sdp_ct = REG_FIELD(0x610c8, 4, 7), + .aif_db4 = REG_FIELD(0x610c8, 8, 15), + .frequency = REG_FIELD(0x610c8, 16, 21), + .mst_index = REG_FIELD(0x610c8, 28, 29), + .dptx_index = REG_FIELD(0x610c8, 30, 31), + + .soft_reset = REG_FIELD(0x1000, 31, 31), + .force_reset = REG_FIELD(0x1000, 30, 30), + + .use_hw_chs = REG_FIELD(0x61038, 0, 0), + .use_hw_usr = REG_FIELD(0x61038, 1, 1), + .hw_chs_sel = REG_FIELD(0x61038, 2, 4), + .hw_usr_sel = REG_FIELD(0x61038, 5, 6), + + .replace_vbit = REG_FIELD(0x610c0, 0, 0), + .vbit_stream = REG_FIELD(0x610c0, 1, 1), + + .legacy_en = REG_FIELD(0x1008, 0, 0), + .calc_en = REG_FIELD(0x61034, 0, 0), + .lsb_bits = REG_FIELD(0x61048, 0, 31), + .msb_bits = REG_FIELD(0x6104c, 0, 31), + + .clk_name = (const char *[]) {"pcnoc-sway-clk" ,"audio-core" ,
Signature · 2 lines
Qualcomm India Private Limited, on behalf of Qualcomm Innovation Center, Inc., is a member of Code Aurora Forum, a Linux Foundation Collaborative Project.