From nobody Mon Jun 29 07:33:43 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id E6485C433FE for ; Mon, 14 Feb 2022 14:58:57 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355499AbiBNO7E (ORCPT ); Mon, 14 Feb 2022 09:59:04 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:59950 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S232830AbiBNO7A (ORCPT ); Mon, 14 Feb 2022 09:59:00 -0500 Received: from alexa-out-sd-01.qualcomm.com (alexa-out-sd-01.qualcomm.com [199.106.114.38]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 5576A49278; Mon, 14 Feb 2022 06:58:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1644850733; x=1676386733; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=tcOOcXbMcQCIhLOkKxdXC7A1Ua+4uPLUo6c+5ryCqco=; b=kfi/U/SYVhdbgfRnCTeCedt48BxOvZJuVaJBhilYkN+5kW+HFmv2lj6c tqGmP6/SR8u5KA33QoGSOISU6qGnnRTANk5OmEetFfFUY/2BtDLaMOgkt K5Ev3bM5OFvvMblwzaF5rZ8YKwua0tQ9uilu0Bib0xIgmDruo31nZkvUy Y=; Received: from unknown (HELO ironmsg-SD-alpha.qualcomm.com) ([10.53.140.30]) by alexa-out-sd-01.qualcomm.com with ESMTP; 14 Feb 2022 06:58:53 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg-SD-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Feb 2022 06:58:52 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.15; Mon, 14 Feb 2022 06:58:52 -0800 Received: from hu-srivasam-hyd.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Mon, 14 Feb 2022 06:58:46 -0800 From: Srinivasa Rao Mandadapu To: , , , , , , , , , , , , , , , , CC: Srinivasa Rao Mandadapu , "Venkata Prasad Potturu" Subject: [RESEND v13 01/10] ASoC: qcom: SC7280: Update config for building codec dma drivers Date: Mon, 14 Feb 2022 20:28:19 +0530 Message-ID: <1644850708-11099-2-git-send-email-quic_srivasam@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> References: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add configuration for building SC7280 audio codec dma drivers. Signed-off-by: Srinivasa Rao Mandadapu Co-developed-by: Venkata Prasad Potturu Signed-off-by: Venkata Prasad Potturu --- sound/soc/qcom/Kconfig | 11 +++++++++++ sound/soc/qcom/Makefile | 4 ++++ 2 files changed, 15 insertions(+) diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index dd5949e..52db003 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -20,6 +20,10 @@ config SND_SOC_LPASS_PLATFORM tristate select REGMAP_MMIO =20 +config SND_SOC_LPASS_CDC_DMA + tristate + select REGMAP_MMIO + config SND_SOC_LPASS_IPQ806X tristate select SND_SOC_LPASS_CPU @@ -36,6 +40,13 @@ config SND_SOC_LPASS_SC7180 select SND_SOC_LPASS_PLATFORM select SND_SOC_LPASS_HDMI =20 +config SND_SOC_LPASS_SC7280 + tristate + select SND_SOC_LPASS_CPU + select SND_SOC_LPASS_PLATFORM + select SND_SOC_LPASS_HDMI + select SND_SOC_LPASS_CDC_DMA + config SND_SOC_STORM tristate "ASoC I2S support for Storm boards" depends on GPIOLIB diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile index 625aec6..8b7b876 100644 --- a/sound/soc/qcom/Makefile +++ b/sound/soc/qcom/Makefile @@ -1,18 +1,22 @@ # SPDX-License-Identifier: GPL-2.0 # Platform snd-soc-lpass-cpu-objs :=3D lpass-cpu.o +snd-soc-lpass-cdc-dma-objs :=3D lpass-cdc-dma.o snd-soc-lpass-hdmi-objs :=3D lpass-hdmi.o snd-soc-lpass-platform-objs :=3D lpass-platform.o snd-soc-lpass-ipq806x-objs :=3D lpass-ipq806x.o snd-soc-lpass-apq8016-objs :=3D lpass-apq8016.o snd-soc-lpass-sc7180-objs :=3D lpass-sc7180.o +snd-soc-lpass-sc7280-objs :=3D lpass-sc7280.o =20 obj-$(CONFIG_SND_SOC_LPASS_CPU) +=3D snd-soc-lpass-cpu.o +obj-$(CONFIG_SND_SOC_LPASS_CDC_DMA) +=3D snd-soc-lpass-cdc-dma.o obj-$(CONFIG_SND_SOC_LPASS_HDMI) +=3D snd-soc-lpass-hdmi.o obj-$(CONFIG_SND_SOC_LPASS_PLATFORM) +=3D snd-soc-lpass-platform.o obj-$(CONFIG_SND_SOC_LPASS_IPQ806X) +=3D snd-soc-lpass-ipq806x.o obj-$(CONFIG_SND_SOC_LPASS_APQ8016) +=3D snd-soc-lpass-apq8016.o obj-$(CONFIG_SND_SOC_LPASS_SC7180) +=3D snd-soc-lpass-sc7180.o +obj-$(CONFIG_SND_SOC_LPASS_SC7280) +=3D snd-soc-lpass-sc7280.o =20 # Machine snd-soc-storm-objs :=3D storm.o --=20 2.7.4 From nobody Mon Jun 29 07:33:43 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 01675C433F5 for ; Mon, 14 Feb 2022 14:59:04 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355506AbiBNO7L (ORCPT ); Mon, 14 Feb 2022 09:59:11 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60006 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355497AbiBNO7G (ORCPT ); Mon, 14 Feb 2022 09:59:06 -0500 Received: from alexa-out-sd-02.qualcomm.com (alexa-out-sd-02.qualcomm.com [199.106.114.39]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 235A24754C; Mon, 14 Feb 2022 06:58:59 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1644850739; x=1676386739; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=55r7vcOOWbj/oXy8k3YYhpmLfRt+lwKbKv2++d6u+g8=; b=VNYtiBWLw7IaDSCGmtvIHIYIeeCEiZEhKhjzNWkExOv8I4DNlxyZ2why 9+UjsmxMxx0AGhBD0cZ1ZCf+9Ild0F8iYrWJkmz1HjMItr4E2Yd9HL1Aw oknVE7OcqzcuzB/tewzdUuzW6ELsvZx0tS/RYJgXNzZ7rgffA9kQieacA A=; Received: from unknown (HELO ironmsg-SD-alpha.qualcomm.com) ([10.53.140.30]) by alexa-out-sd-02.qualcomm.com with ESMTP; 14 Feb 2022 06:58:58 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg-SD-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Feb 2022 06:58:58 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.15; Mon, 14 Feb 2022 06:58:58 -0800 Received: from hu-srivasam-hyd.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Mon, 14 Feb 2022 06:58:52 -0800 From: Srinivasa Rao Mandadapu To: , , , , , , , , , , , , , , , , CC: Srinivasa Rao Mandadapu , "Venkata Prasad Potturu" Subject: [RESEND v13 02/10] ASoC: qcom: Move lpass_pcm_data structure to lpass header Date: Mon, 14 Feb 2022 20:28:20 +0530 Message-ID: <1644850708-11099-3-git-send-email-quic_srivasam@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> References: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Declare lpass_pcm_data structure in lpass header file instead of platform source file to make common use of it by other drivers Signed-off-by: Srinivasa Rao Mandadapu Co-developed-by: Venkata Prasad Potturu Signed-off-by: Venkata Prasad Potturu Reviewed-by: Srinivas Kandagatla --- sound/soc/qcom/lpass-platform.c | 5 ----- sound/soc/qcom/lpass.h | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platfor= m.c index a59e9d2..a44162c 100644 --- a/sound/soc/qcom/lpass-platform.c +++ b/sound/soc/qcom/lpass-platform.c @@ -18,11 +18,6 @@ =20 #define DRV_NAME "lpass-platform" =20 -struct lpass_pcm_data { - int dma_ch; - int i2s_port; -}; - #define LPASS_PLATFORM_BUFFER_SIZE (24 * 2 * 1024) #define LPASS_PLATFORM_PERIODS 2 =20 diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h index c0f0247..f0d21cd 100644 --- a/sound/soc/qcom/lpass.h +++ b/sound/soc/qcom/lpass.h @@ -257,6 +257,11 @@ struct lpass_variant { int num_clks; }; =20 +struct lpass_pcm_data { + int dma_ch; + int i2s_port; +}; + /* register the platform driver from the CPU DAI driver */ int asoc_qcom_lpass_platform_register(struct platform_device *); int asoc_qcom_lpass_cpu_platform_remove(struct platform_device *pdev); --=20 2.7.4 From nobody Mon Jun 29 07:33:43 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 25EB1C433F5 for ; Mon, 14 Feb 2022 14:59:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355515AbiBNO7Q (ORCPT ); Mon, 14 Feb 2022 09:59:16 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60054 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355497AbiBNO7M (ORCPT ); Mon, 14 Feb 2022 09:59:12 -0500 Received: from alexa-out.qualcomm.com (alexa-out.qualcomm.com [129.46.98.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id AC07539A; Mon, 14 Feb 2022 06:59:04 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1644850745; x=1676386745; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=VIEhuJg5H0419YEMU5IV/5/qu6XsVBmx1PQ4kc5+mZ4=; b=O2uBIfAJ6FG54qtWZ5RVrsmki0CSTZeBj/Bn6ywyCKT6PfrdYgn5eIoD AqUOy0xkvvLVYGn/XiaAonGEX6/2dgo82fvuY8LDlniFkwP0m/TDZepd1 m2srFp9/MSz8vxJvMY5KvCG0I69xH0Xfc7CgNgiKpNdD5QmNZ+e3ZfErH s=; Received: from ironmsg-lv-alpha.qualcomm.com ([10.47.202.13]) by alexa-out.qualcomm.com with ESMTP; 14 Feb 2022 06:59:04 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg-lv-alpha.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Feb 2022 06:59:04 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.15; Mon, 14 Feb 2022 06:59:04 -0800 Received: from hu-srivasam-hyd.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Mon, 14 Feb 2022 06:58:58 -0800 From: Srinivasa Rao Mandadapu To: , , , , , , , , , , , , , , , , CC: Srinivasa Rao Mandadapu , "Venkata Prasad Potturu" Subject: [RESEND v13 03/10] ASoC: qcom: lpass: Add dma fields for codec dma lpass interface Date: Mon, 14 Feb 2022 20:28:21 +0530 Message-ID: <1644850708-11099-4-git-send-email-quic_srivasam@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> References: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add lpass interface memebers to support audio path over codec dma. Signed-off-by: Srinivasa Rao Mandadapu Co-developed-by: Venkata Prasad Potturu Signed-off-by: Venkata Prasad Potturu Reviewed-by: Srinivas Kandagatla --- sound/soc/qcom/lpass.h | 116 +++++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 116 insertions(+) diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h index f0d21cd..7cc3763 100644 --- a/sound/soc/qcom/lpass.h +++ b/sound/soc/qcom/lpass.h @@ -20,6 +20,17 @@ #define LPASS_MAX_MI2S_PORTS (8) #define LPASS_MAX_DMA_CHANNELS (8) #define LPASS_MAX_HDMI_DMA_CHANNELS (4) +#define LPASS_MAX_CDC_DMA_CHANNELS (8) +#define LPASS_MAX_VA_CDC_DMA_CHANNELS (8) +#define LPASS_CDC_DMA_INTF_ONE_CHANNEL (0x01) +#define LPASS_CDC_DMA_INTF_TWO_CHANNEL (0x03) +#define LPASS_CDC_DMA_INTF_FOUR_CHANNEL (0x0F) +#define LPASS_CDC_DMA_INTF_SIX_CHANNEL (0x3F) +#define LPASS_CDC_DMA_INTF_EIGHT_CHANNEL (0xFF) + +#define LPASS_MAX_CDC_CLKS (9) +#define LPASS_ACTIVE_PDS (4) +#define LPASS_PROXY_PDS (8) =20 #define QCOM_REGMAP_FIELD_ALLOC(d, m, f, mf) \ do { \ @@ -51,6 +62,12 @@ struct lpaif_dmactl { struct regmap_field *burst8; struct regmap_field *burst16; struct regmap_field *dynburst; + struct regmap_field *codec_enable; + struct regmap_field *codec_pack; + struct regmap_field *codec_intf; + struct regmap_field *codec_fs_sel; + struct regmap_field *codec_channel; + struct regmap_field *codec_fs_delay; }; =20 /* Both the CPU DAI and platform drivers will access this data */ @@ -65,6 +82,8 @@ struct lpass_data { /* MI2S bit clock (derived from system clock by a divider */ struct clk *mi2s_bit_clk[LPASS_MAX_MI2S_PORTS]; =20 + struct clk *cdc_dma_clks[LPASS_MAX_CDC_CLKS]; + /* MI2S SD lines to use for playback/capture */ unsigned int mi2s_playback_sd_mode[LPASS_MAX_MI2S_PORTS]; unsigned int mi2s_capture_sd_mode[LPASS_MAX_MI2S_PORTS]; @@ -73,38 +92,61 @@ struct lpass_data { bool mi2s_was_prepared[LPASS_MAX_MI2S_PORTS]; =20 int hdmi_port_enable; + int codec_dma_enable; =20 /* low-power audio interface (LPAIF) registers */ void __iomem *lpaif; void __iomem *hdmiif; + void __iomem *rxtx_lpaif; + void __iomem *va_lpaif; + + u32 rxtx_cdc_dma_lpm_buf; + u32 va_cdc_dma_lpm_buf; =20 /* regmap backed by the low-power audio interface (LPAIF) registers */ struct regmap *lpaif_map; struct regmap *hdmiif_map; + struct regmap *rxtx_lpaif_map; + struct regmap *va_lpaif_map; =20 /* interrupts from the low-power audio interface (LPAIF) */ int lpaif_irq; int hdmiif_irq; + int rxtxif_irq; + int vaif_irq; + /* SOC specific variations in the LPASS IP integration */ struct lpass_variant *variant; =20 /* bit map to keep track of static channel allocations */ unsigned long dma_ch_bit_map; unsigned long hdmi_dma_ch_bit_map; + unsigned long rxtx_dma_ch_bit_map; + unsigned long va_dma_ch_bit_map; =20 /* used it for handling interrupt per dma channel */ struct snd_pcm_substream *substream[LPASS_MAX_DMA_CHANNELS]; struct snd_pcm_substream *hdmi_substream[LPASS_MAX_HDMI_DMA_CHANNELS]; + struct snd_pcm_substream *rxtx_substream[LPASS_MAX_CDC_DMA_CHANNELS]; + struct snd_pcm_substream *va_substream[LPASS_MAX_CDC_DMA_CHANNELS]; =20 /* SOC specific clock list */ struct clk_bulk_data *clks; int num_clks; + struct clk_bulk_data *cdc_clks; + int cdc_num_clks; =20 /* Regmap fields of I2SCTL & DMACTL registers bitfields */ struct lpaif_i2sctl *i2sctl; struct lpaif_dmactl *rd_dmactl; struct lpaif_dmactl *wr_dmactl; struct lpaif_dmactl *hdmi_rd_dmactl; + + /* Regmap fields of CODEC DMA CTRL registers*/ + struct lpaif_dmactl *rxtx_rd_dmactl; + struct lpaif_dmactl *rxtx_wr_dmactl; + struct lpaif_dmactl *va_wr_dmactl; + /* Regmap fields of HDMI_CTRL registers*/ struct regmap_field *hdmitx_legacy_en; struct regmap_field *hdmitx_parity_calc_en; @@ -131,6 +173,24 @@ struct lpass_variant { u32 wrdma_reg_base; u32 wrdma_reg_stride; u32 wrdma_channels; + u32 rxtx_irq_reg_base; + u32 rxtx_irq_reg_stride; + u32 rxtx_irq_ports; + u32 rxtx_rdma_reg_base; + u32 rxtx_rdma_reg_stride; + u32 rxtx_rdma_channels; + u32 rxtx_wrdma_reg_base; + u32 rxtx_wrdma_reg_stride; + u32 rxtx_wrdma_channels; + u32 va_irq_reg_base; + u32 va_irq_reg_stride; + u32 va_irq_ports; + u32 va_rdma_reg_base; + u32 va_rdma_reg_stride; + u32 va_rdma_channels; + u32 va_wrdma_reg_base; + u32 va_wrdma_reg_stride; + u32 va_wrdma_channels; u32 i2sctrl_reg_base; u32 i2sctrl_reg_stride; u32 i2s_ports; @@ -234,12 +294,66 @@ struct lpass_variant { struct reg_field wrdma_enable; struct reg_field wrdma_dyncclk; =20 + /*CDC RXTX RD_DMA */ + struct reg_field rxtx_rdma_intf; + struct reg_field rxtx_rdma_bursten; + struct reg_field rxtx_rdma_wpscnt; + struct reg_field rxtx_rdma_fifowm; + struct reg_field rxtx_rdma_enable; + struct reg_field rxtx_rdma_dyncclk; + struct reg_field rxtx_rdma_burst8; + struct reg_field rxtx_rdma_burst16; + struct reg_field rxtx_rdma_dynburst; + struct reg_field rxtx_rdma_codec_enable; + struct reg_field rxtx_rdma_codec_pack; + struct reg_field rxtx_rdma_codec_intf; + struct reg_field rxtx_rdma_codec_fs_sel; + struct reg_field rxtx_rdma_codec_ch; + struct reg_field rxtx_rdma_codec_fs_delay; + + /*CDC RXTX WR_DMA */ + struct reg_field rxtx_wrdma_intf; + struct reg_field rxtx_wrdma_bursten; + struct reg_field rxtx_wrdma_wpscnt; + struct reg_field rxtx_wrdma_fifowm; + struct reg_field rxtx_wrdma_enable; + struct reg_field rxtx_wrdma_dyncclk; + struct reg_field rxtx_wrdma_burst8; + struct reg_field rxtx_wrdma_burst16; + struct reg_field rxtx_wrdma_dynburst; + struct reg_field rxtx_wrdma_codec_enable; + struct reg_field rxtx_wrdma_codec_pack; + struct reg_field rxtx_wrdma_codec_intf; + struct reg_field rxtx_wrdma_codec_fs_sel; + struct reg_field rxtx_wrdma_codec_ch; + struct reg_field rxtx_wrdma_codec_fs_delay; + + /*CDC VA WR_DMA */ + struct reg_field va_wrdma_intf; + struct reg_field va_wrdma_bursten; + struct reg_field va_wrdma_wpscnt; + struct reg_field va_wrdma_fifowm; + struct reg_field va_wrdma_enable; + struct reg_field va_wrdma_dyncclk; + struct reg_field va_wrdma_burst8; + struct reg_field va_wrdma_burst16; + struct reg_field va_wrdma_dynburst; + struct reg_field va_wrdma_codec_enable; + struct reg_field va_wrdma_codec_pack; + struct reg_field va_wrdma_codec_intf; + struct reg_field va_wrdma_codec_fs_sel; + struct reg_field va_wrdma_codec_ch; + struct reg_field va_wrdma_codec_fs_delay; + /** * on SOCs like APQ8016 the channel control bits start * at different offset to ipq806x **/ u32 dmactl_audif_start; u32 wrdma_channel_start; + u32 rxtx_wrdma_channel_start; + u32 va_wrdma_channel_start; + /* SOC specific initialization like clocks */ int (*init)(struct platform_device *pdev); int (*exit)(struct platform_device *pdev); @@ -251,10 +365,12 @@ struct lpass_variant { int num_dai; const char * const *dai_osr_clk_names; const char * const *dai_bit_clk_names; + const char * const *cdc_dma_clk_names; =20 /* SOC specific clocks configuration */ const char **clk_name; int num_clks; + int cdc_dma_num_clks; }; =20 struct lpass_pcm_data { --=20 2.7.4 From nobody Mon Jun 29 07:33:43 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 3FC25C4332F for ; Mon, 14 Feb 2022 14:59:19 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355526AbiBNO7Z (ORCPT ); Mon, 14 Feb 2022 09:59:25 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60120 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355497AbiBNO7T (ORCPT ); Mon, 14 Feb 2022 09:59:19 -0500 Received: from alexa-out-sd-01.qualcomm.com (alexa-out-sd-01.qualcomm.com [199.106.114.38]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4439439A; Mon, 14 Feb 2022 06:59:11 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1644850751; x=1676386751; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=FFkY61nZpsiSvjL5f/R7EFLkcN0P29ZxCH0NiD7iQfk=; b=a0X/Lpm+ROWpgjTaI3Gg8Aerk3ybv2jFQVg2X09JwTL6Fap8MmthXRhC N3012w4RKhlA2a0jGWN6TnzGrkgGfN92Xx9dLjM5H3u9WIvsB95Ft5KdX Ohg6Pf5JVSbviXQ+ni3DZC0CcXrdeAuTYP+LBg6gGqMpQhlSJIv5E8EDM c=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-01.qualcomm.com with ESMTP; 14 Feb 2022 06:59:11 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg04-sd.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Feb 2022 06:59:10 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.15; Mon, 14 Feb 2022 06:59:10 -0800 Received: from hu-srivasam-hyd.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Mon, 14 Feb 2022 06:59:04 -0800 From: Srinivasa Rao Mandadapu To: , , , , , , , , , , , , , , , , CC: Srinivasa Rao Mandadapu , "Venkata Prasad Potturu" Subject: [RESEND v13 04/10] ASoC: qcom: Add helper function to get dma control and lpaif handle Date: Mon, 14 Feb 2022 20:28:22 +0530 Message-ID: <1644850708-11099-5-git-send-email-quic_srivasam@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> References: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add support function to get dma control and lpaif handle to avoid repeated code in platform driver Signed-off-by: Srinivasa Rao Mandadapu Co-developed-by: Venkata Prasad Potturu Signed-off-by: Venkata Prasad Potturu Reviewed-by: Srinivas Kandagatla --- sound/soc/qcom/lpass-platform.c | 113 +++++++++++++++++++++++-------------= ---- 1 file changed, 66 insertions(+), 47 deletions(-) diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platfor= m.c index a44162c..5d77240 100644 --- a/sound/soc/qcom/lpass-platform.c +++ b/sound/soc/qcom/lpass-platform.c @@ -177,6 +177,49 @@ static int lpass_platform_pcmops_close(struct snd_soc_= component *component, return 0; } =20 +static void __lpass_get_lpaif_handle(struct snd_pcm_substream *substream, + struct snd_soc_component *component, + struct lpaif_dmactl **dmactl, int *id, struct regmap **map) +{ + struct snd_soc_pcm_runtime *soc_runtime =3D asoc_substream_to_rtd(substre= am); + struct snd_soc_dai *cpu_dai =3D asoc_rtd_to_cpu(soc_runtime, 0); + struct lpass_data *drvdata =3D snd_soc_component_get_drvdata(component); + struct snd_pcm_runtime *rt =3D substream->runtime; + struct lpass_pcm_data *pcm_data =3D rt->private_data; + struct lpass_variant *v =3D drvdata->variant; + int dir =3D substream->stream; + unsigned int dai_id =3D cpu_dai->driver->id; + struct lpaif_dmactl *l_dmactl =3D NULL; + struct regmap *l_map =3D NULL; + int l_id =3D 0; + + switch (dai_id) { + case MI2S_PRIMARY ... MI2S_QUINARY: + if (dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK) { + l_id =3D pcm_data->dma_ch; + l_dmactl =3D drvdata->rd_dmactl; + } else { + l_dmactl =3D drvdata->wr_dmactl; + l_id =3D pcm_data->dma_ch - v->wrdma_channel_start; + } + l_map =3D drvdata->lpaif_map; + break; + case LPASS_DP_RX: + l_id =3D pcm_data->dma_ch; + l_dmactl =3D drvdata->hdmi_rd_dmactl; + l_map =3D drvdata->hdmiif_map; + break; + default: + break; + } + if (dmactl) + *dmactl =3D l_dmactl; + if (id) + *id =3D l_id; + if (map) + *map =3D l_map; +} + static int lpass_platform_pcmops_hw_params(struct snd_soc_component *compo= nent, struct snd_pcm_substream *substream, struct snd_pcm_hw_params *params) @@ -191,21 +234,15 @@ static int lpass_platform_pcmops_hw_params(struct snd= _soc_component *component, unsigned int channels =3D params_channels(params); unsigned int regval; struct lpaif_dmactl *dmactl; - int id, dir =3D substream->stream; + int id; int bitwidth; int ret, dma_port =3D pcm_data->i2s_port + v->dmactl_audif_start; unsigned int dai_id =3D cpu_dai->driver->id; =20 - if (dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK) { - id =3D pcm_data->dma_ch; - if (dai_id =3D=3D LPASS_DP_RX) - dmactl =3D drvdata->hdmi_rd_dmactl; - else - dmactl =3D drvdata->rd_dmactl; - - } else { - dmactl =3D drvdata->wr_dmactl; - id =3D pcm_data->dma_ch - v->wrdma_channel_start; + __lpass_get_lpaif_handle(substream, component, &dmactl, &id, NULL); + if (!dmactl) { + dev_err(soc_runtime->dev, "failed to get dmactl handle\n"); + return -EINVAL; } =20 bitwidth =3D snd_pcm_format_width(format); @@ -350,10 +387,11 @@ static int lpass_platform_pcmops_hw_free(struct snd_s= oc_component *component, struct regmap *map; unsigned int dai_id =3D cpu_dai->driver->id; =20 - if (dai_id =3D=3D LPASS_DP_RX) - map =3D drvdata->hdmiif_map; - else - map =3D drvdata->lpaif_map; + __lpass_get_lpaif_handle(substream, component, NULL, NULL, &map); + if (!map) { + dev_err(soc_runtime->dev, "failed to get dmactl handle\n"); + return -EINVAL; + } =20 reg =3D LPAIF_DMACTL_REG(v, pcm_data->dma_ch, substream->stream, dai_id); ret =3D regmap_write(map, reg, 0); @@ -379,22 +417,12 @@ static int lpass_platform_pcmops_prepare(struct snd_s= oc_component *component, int ret, id, ch, dir =3D substream->stream; unsigned int dai_id =3D cpu_dai->driver->id; =20 - ch =3D pcm_data->dma_ch; - if (dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK) { - if (dai_id =3D=3D LPASS_DP_RX) { - dmactl =3D drvdata->hdmi_rd_dmactl; - map =3D drvdata->hdmiif_map; - } else { - dmactl =3D drvdata->rd_dmactl; - map =3D drvdata->lpaif_map; - } =20 - id =3D pcm_data->dma_ch; - } else { - dmactl =3D drvdata->wr_dmactl; - id =3D pcm_data->dma_ch - v->wrdma_channel_start; - map =3D drvdata->lpaif_map; + __lpass_get_lpaif_handle(substream, component, &dmactl, &id, &map); + if (!dmactl) { + dev_err(soc_runtime->dev, "failed to get dmactl handle\n"); + return -EINVAL; } =20 ret =3D regmap_write(map, LPAIF_DMABASE_REG(v, ch, dir, dai_id), @@ -444,25 +472,15 @@ static int lpass_platform_pcmops_trigger(struct snd_s= oc_component *component, struct lpaif_dmactl *dmactl; struct regmap *map; int ret, ch, id; - int dir =3D substream->stream; unsigned int reg_irqclr =3D 0, val_irqclr =3D 0; unsigned int reg_irqen =3D 0, val_irqen =3D 0, val_mask =3D 0; unsigned int dai_id =3D cpu_dai->driver->id; =20 ch =3D pcm_data->dma_ch; - if (dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK) { - id =3D pcm_data->dma_ch; - if (dai_id =3D=3D LPASS_DP_RX) { - dmactl =3D drvdata->hdmi_rd_dmactl; - map =3D drvdata->hdmiif_map; - } else { - dmactl =3D drvdata->rd_dmactl; - map =3D drvdata->lpaif_map; - } - } else { - dmactl =3D drvdata->wr_dmactl; - id =3D pcm_data->dma_ch - v->wrdma_channel_start; - map =3D drvdata->lpaif_map; + __lpass_get_lpaif_handle(substream, component, &dmactl, &id, &map); + if (!dmactl) { + dev_err(soc_runtime->dev, "failed to get dmactl handle\n"); + return -EINVAL; } =20 switch (cmd) { @@ -597,10 +615,11 @@ static snd_pcm_uframes_t lpass_platform_pcmops_pointe= r( struct regmap *map; unsigned int dai_id =3D cpu_dai->driver->id; =20 - if (dai_id =3D=3D LPASS_DP_RX) - map =3D drvdata->hdmiif_map; - else - map =3D drvdata->lpaif_map; + __lpass_get_lpaif_handle(substream, component, NULL, NULL, &map); + if (!map) { + dev_err(soc_runtime->dev, "failed to get dmactl handle\n"); + return -EINVAL; + } =20 ch =3D pcm_data->dma_ch; =20 --=20 2.7.4 From nobody Mon Jun 29 07:33:43 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 98BCFC433EF for ; Mon, 14 Feb 2022 14:59:22 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355537AbiBNO72 (ORCPT ); Mon, 14 Feb 2022 09:59:28 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60192 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355520AbiBNO7Z (ORCPT ); Mon, 14 Feb 2022 09:59:25 -0500 Received: from alexa-out.qualcomm.com (alexa-out.qualcomm.com [129.46.98.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 428244754C; Mon, 14 Feb 2022 06:59:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1644850757; x=1676386757; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=Xr2sFGj3q3cyXBllz9zYKmzdAEZmg/gF3qvIuFqo76U=; b=bDJX8owoxrAv1ZF7mQWMaw1d7O/HXliXKP18K/CJI18EtIjM0m7rrqob cnm5uYAkz9ikC90+caHSPE62G2AmGvu33/fNxD4frk85DhLpzcD5liNsa owLUzIkNSx5vhBpUrKcnXzoaHqQeNCXmHG5/ppGZdIrbGttWmYPKuk/eu A=; Received: from ironmsg08-lv.qualcomm.com ([10.47.202.152]) by alexa-out.qualcomm.com with ESMTP; 14 Feb 2022 06:59:17 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg08-lv.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Feb 2022 06:59:16 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.15; Mon, 14 Feb 2022 06:59:16 -0800 Received: from hu-srivasam-hyd.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Mon, 14 Feb 2022 06:59:10 -0800 From: Srinivasa Rao Mandadapu To: , , , , , , , , , , , , , , , , CC: Srinivasa Rao Mandadapu , "Venkata Prasad Potturu" Subject: [RESEND v13 05/10] ASoC: qcom: Add register definition for codec rddma and wrdma Date: Mon, 14 Feb 2022 20:28:23 +0530 Message-ID: <1644850708-11099-6-git-send-email-quic_srivasam@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> References: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" This patch adds register definitions for codec read dma and write dma lpass interface. Signed-off-by: Srinivasa Rao Mandadapu Co-developed-by: Venkata Prasad Potturu Signed-off-by: Venkata Prasad Potturu Reviewed-by: Srinivas Kandagatla --- sound/soc/qcom/lpass-lpaif-reg.h | 127 +++++++++++++++++++++++++++++++++++= ++-- sound/soc/qcom/lpass.h | 23 +++++++ 2 files changed, 144 insertions(+), 6 deletions(-) diff --git a/sound/soc/qcom/lpass-lpaif-reg.h b/sound/soc/qcom/lpass-lpaif-= reg.h index 2eb03ad..6d9d9d1 100644 --- a/sound/soc/qcom/lpass-lpaif-reg.h +++ b/sound/soc/qcom/lpass-lpaif-reg.h @@ -74,6 +74,21 @@ #define LPAIF_IRQSTAT_REG(v, port) LPAIF_IRQ_REG_ADDR(v, 0x4, (port)) #define LPAIF_IRQCLEAR_REG(v, port) LPAIF_IRQ_REG_ADDR(v, 0xC, (port)) =20 +/* LPAIF RXTX IRQ */ +#define LPAIF_RXTX_IRQ_REG_ADDR(v, addr, port) \ + (v->rxtx_irq_reg_base + (addr) + v->rxtx_irq_reg_stride * (port)) + +#define LPAIF_RXTX_IRQEN_REG(v, port) LPAIF_RXTX_IRQ_REG_ADDR(v, 0x0, port) +#define LPAIF_RXTX_IRQSTAT_REG(v, port) LPAIF_RXTX_IRQ_REG_ADDR(v, 0x4, po= rt) +#define LPAIF_RXTX_IRQCLEAR_REG(v, port) LPAIF_RXTX_IRQ_REG_ADDR(v, 0xC, p= ort) + +/* LPAIF VA IRQ */ +#define LPAIF_VA_IRQ_REG_ADDR(v, addr, port) \ + (v->va_irq_reg_base + (addr) + v->va_irq_reg_stride * (port)) + +#define LPAIF_VA_IRQEN_REG(v, port) LPAIF_VA_IRQ_REG_ADDR(v, 0x0, port) +#define LPAIF_VA_IRQSTAT_REG(v, port) LPAIF_VA_IRQ_REG_ADDR(v, 0x4, port) +#define LPAIF_VA_IRQCLEAR_REG(v, port) LPAIF_VA_IRQ_REG_ADDR(v, 0xC, port) =20 #define LPASS_HDMITX_APP_IRQ_REG_ADDR(v, addr) \ ((v->hdmi_irq_reg_base) + (addr)) @@ -139,12 +154,112 @@ (LPAIF_INTFDMA_REG(v, chan, reg, dai_id)) : \ LPAIF_WRDMA##reg##_REG(v, chan)) =20 -#define LPAIF_DMACTL_REG(v, chan, dir, dai_id) __LPAIF_DMA_REG(v, chan, di= r, CTL, dai_id) -#define LPAIF_DMABASE_REG(v, chan, dir, dai_id) __LPAIF_DMA_REG(v, chan, d= ir, BASE, dai_id) -#define LPAIF_DMABUFF_REG(v, chan, dir, dai_id) __LPAIF_DMA_REG(v, chan, d= ir, BUFF, dai_id) -#define LPAIF_DMACURR_REG(v, chan, dir, dai_id) __LPAIF_DMA_REG(v, chan, d= ir, CURR, dai_id) -#define LPAIF_DMAPER_REG(v, chan, dir, dai_id) __LPAIF_DMA_REG(v, chan, di= r, PER, dai_id) -#define LPAIF_DMAPERCNT_REG(v, chan, dir, dai_id) __LPAIF_DMA_REG(v, chan,= dir, PERCNT, dai_id) +#define LPAIF_DMACTL_REG(v, chan, dir, dai_id) \ + (is_cdc_dma_port(dai_id) ? \ + __LPAIF_CDC_DMA_REG(v, chan, dir, CTL, dai_id) : \ + __LPAIF_DMA_REG(v, chan, dir, CTL, dai_id)) +#define LPAIF_DMABASE_REG(v, chan, dir, dai_id) \ + (is_cdc_dma_port(dai_id) ? \ + __LPAIF_CDC_DMA_REG(v, chan, dir, BASE, dai_id) : \ + __LPAIF_DMA_REG(v, chan, dir, BASE, dai_id)) +#define LPAIF_DMABUFF_REG(v, chan, dir, dai_id) \ + (is_cdc_dma_port(dai_id) ? \ + __LPAIF_CDC_DMA_REG(v, chan, dir, BUFF, dai_id) : \ + __LPAIF_DMA_REG(v, chan, dir, BUFF, dai_id)) +#define LPAIF_DMACURR_REG(v, chan, dir, dai_id) \ + (is_cdc_dma_port(dai_id) ? \ + __LPAIF_CDC_DMA_REG(v, chan, dir, CURR, dai_id) : \ + __LPAIF_DMA_REG(v, chan, dir, CURR, dai_id)) +#define LPAIF_DMAPER_REG(v, chan, dir, dai_id) \ + (is_cdc_dma_port(dai_id) ? \ + __LPAIF_CDC_DMA_REG(v, chan, dir, PER, dai_id) : \ + __LPAIF_DMA_REG(v, chan, dir, PER, dai_id)) +#define LPAIF_DMAPERCNT_REG(v, chan, dir, dai_id) \ + (is_cdc_dma_port(dai_id) ? \ + __LPAIF_CDC_DMA_REG(v, chan, dir, PERCNT, dai_id) : \ + __LPAIF_DMA_REG(v, chan, dir, PERCNT, dai_id)) + +#define LPAIF_CDC_RDMA_REG_ADDR(v, addr, chan, dai_id) \ + (is_rxtx_cdc_dma_port(dai_id) ? \ + (v->rxtx_rdma_reg_base + (addr) + v->rxtx_rdma_reg_stride * (chan)) : \ + (v->va_rdma_reg_base + (addr) + v->va_rdma_reg_stride * (chan))) + +#define LPAIF_CDC_RXTX_RDMACTL_REG(v, chan, dai_id) \ + LPAIF_CDC_RDMA_REG_ADDR(v, 0x00, (chan), dai_id) +#define LPAIF_CDC_RXTX_RDMABASE_REG(v, chan, dai_id) \ + LPAIF_CDC_RDMA_REG_ADDR(v, 0x04, (chan), dai_id) +#define LPAIF_CDC_RXTX_RDMABUFF_REG(v, chan, dai_id) \ + LPAIF_CDC_RDMA_REG_ADDR(v, 0x08, (chan), dai_id) +#define LPAIF_CDC_RXTX_RDMACURR_REG(v, chan, dai_id) \ + LPAIF_CDC_RDMA_REG_ADDR(v, 0x0C, (chan), dai_id) +#define LPAIF_CDC_RXTX_RDMAPER_REG(v, chan, dai_id) \ + LPAIF_CDC_RDMA_REG_ADDR(v, 0x10, (chan), dai_id) +#define LPAIF_CDC_RXTX_RDMA_INTF_REG(v, chan, dai_id) \ + LPAIF_CDC_RDMA_REG_ADDR(v, 0x50, (chan), dai_id) + +#define LPAIF_CDC_VA_RDMACTL_REG(v, chan, dai_id) LPAIF_CDC_RDMA_REG_ADDR(= v, 0x00, (chan), dai_id) +#define LPAIF_CDC_VA_RDMABASE_REG(v, chan, dai_id) LPAIF_CDC_RDMA_REG_ADDR= (v, 0x04, (chan), dai_id) +#define LPAIF_CDC_VA_RDMABUFF_REG(v, chan, dai_id) LPAIF_CDC_RDMA_REG_ADDR= (v, 0x08, (chan), dai_id) +#define LPAIF_CDC_VA_RDMACURR_REG(v, chan, dai_id) LPAIF_CDC_RDMA_REG_ADDR= (v, 0x0C, (chan), dai_id) +#define LPAIF_CDC_VA_RDMAPER_REG(v, chan, dai_id) LPAIF_CDC_RDMA_REG_ADDR(= v, 0x10, (chan), dai_id) +#define LPAIF_CDC_VA_RDMA_INTF_REG(v, chan, dai_id) \ + LPAIF_CDC_RDMA_REG_ADDR(v, 0x50, (chan), dai_id) + +#define LPAIF_CDC_WRDMA_REG_ADDR(v, addr, chan, dai_id) \ + (is_rxtx_cdc_dma_port(dai_id) ? \ + (v->rxtx_wrdma_reg_base + (addr) + \ + v->rxtx_wrdma_reg_stride * (chan - v->rxtx_wrdma_channel_start)) : \ + (v->va_wrdma_reg_base + (addr) + \ + v->va_wrdma_reg_stride * (chan - v->va_wrdma_channel_start))) + +#define LPAIF_CDC_RXTX_WRDMACTL_REG(v, chan, dai_id) \ + LPAIF_CDC_WRDMA_REG_ADDR(v, 0x00, (chan), dai_id) +#define LPAIF_CDC_RXTX_WRDMABASE_REG(v, chan, dai_id) \ + LPAIF_CDC_WRDMA_REG_ADDR(v, 0x04, (chan), dai_id) +#define LPAIF_CDC_RXTX_WRDMABUFF_REG(v, chan, dai_id) \ + LPAIF_CDC_WRDMA_REG_ADDR(v, 0x08, (chan), dai_id) +#define LPAIF_CDC_RXTX_WRDMACURR_REG(v, chan, dai_id) \ + LPAIF_CDC_WRDMA_REG_ADDR(v, 0x0C, (chan), dai_id) +#define LPAIF_CDC_RXTX_WRDMAPER_REG(v, chan, dai_id) \ + LPAIF_CDC_WRDMA_REG_ADDR(v, 0x10, (chan), dai_id) +#define LPAIF_CDC_RXTX_WRDMA_INTF_REG(v, chan, dai_id) \ + LPAIF_CDC_WRDMA_REG_ADDR(v, 0x50, (chan), dai_id) + +#define LPAIF_CDC_VA_WRDMACTL_REG(v, chan, dai_id) \ + LPAIF_CDC_WRDMA_REG_ADDR(v, 0x00, (chan), dai_id) +#define LPAIF_CDC_VA_WRDMABASE_REG(v, chan, dai_id) \ + LPAIF_CDC_WRDMA_REG_ADDR(v, 0x04, (chan), dai_id) +#define LPAIF_CDC_VA_WRDMABUFF_REG(v, chan, dai_id) \ + LPAIF_CDC_WRDMA_REG_ADDR(v, 0x08, (chan), dai_id) +#define LPAIF_CDC_VA_WRDMACURR_REG(v, chan, dai_id) \ + LPAIF_CDC_WRDMA_REG_ADDR(v, 0x0C, (chan), dai_id) +#define LPAIF_CDC_VA_WRDMAPER_REG(v, chan, dai_id) \ + LPAIF_CDC_WRDMA_REG_ADDR(v, 0x10, (chan), dai_id) +#define LPAIF_CDC_VA_WRDMA_INTF_REG(v, chan, dai_id) \ + LPAIF_CDC_WRDMA_REG_ADDR(v, 0x50, (chan), dai_id) + +#define __LPAIF_CDC_RDDMA_REG(v, chan, dir, reg, dai_id) \ + (is_rxtx_cdc_dma_port(dai_id) ? LPAIF_CDC_RXTX_RDMA##reg##_REG(v, chan, = dai_id) : \ + LPAIF_CDC_VA_RDMA##reg##_REG(v, chan, dai_id)) + +#define __LPAIF_CDC_WRDMA_REG(v, chan, dir, reg, dai_id) \ + (is_rxtx_cdc_dma_port(dai_id) ? LPAIF_CDC_RXTX_WRDMA##reg##_REG(v, chan,= dai_id) : \ + LPAIF_CDC_VA_WRDMA##reg##_REG(v, chan, dai_id)) + +#define __LPAIF_CDC_DMA_REG(v, chan, dir, reg, dai_id) \ + ((dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK) ? \ + __LPAIF_CDC_RDDMA_REG(v, chan, dir, reg, dai_id) : \ + __LPAIF_CDC_WRDMA_REG(v, chan, dir, reg, dai_id)) + +#define LPAIF_CDC_INTF_REG(v, chan, dir, dai_id) \ + ((dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK) ? \ + LPAIF_CDC_RDMA_INTF_REG(v, chan, dai_id) : \ + LPAIF_CDC_WRDMA_INTF_REG(v, chan, dai_id)) + +#define LPAIF_INTF_REG(v, chan, dir, dai_id) \ + (is_cdc_dma_port(dai_id) ? \ + LPAIF_CDC_INTF_REG(v, chan, dir, dai_id) : \ + LPAIF_DMACTL_REG(v, chan, dir, dai_id)) =20 #define LPAIF_DMACTL_BURSTEN_SINGLE 0 #define LPAIF_DMACTL_BURSTEN_INCR4 1 diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h index 7cc3763..e059c4a 100644 --- a/sound/soc/qcom/lpass.h +++ b/sound/soc/qcom/lpass.h @@ -39,6 +39,29 @@ return -EINVAL; \ } while (0) =20 +static inline bool is_cdc_dma_port(int dai_id) +{ + switch (dai_id) { + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8: + return true; + default: + return false; + } +} + +static inline bool is_rxtx_cdc_dma_port(int dai_id) +{ + switch (dai_id) { + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + return true; + default: + return false; + } +} + struct lpaif_i2sctl { struct regmap_field *loopback; struct regmap_field *spken; --=20 2.7.4 From nobody Mon Jun 29 07:33:43 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 92A8CC433EF for ; Mon, 14 Feb 2022 14:59:27 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355541AbiBNO7d (ORCPT ); Mon, 14 Feb 2022 09:59:33 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60260 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355520AbiBNO7a (ORCPT ); Mon, 14 Feb 2022 09:59:30 -0500 Received: from alexa-out-sd-01.qualcomm.com (alexa-out-sd-01.qualcomm.com [199.106.114.38]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E6BC6B849; Mon, 14 Feb 2022 06:59:22 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1644850763; x=1676386763; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=ngCYcUx+P6Dtxjl7rqG1A3PsNFvM/gX6DS/1nmW25EY=; b=GfIqkuWpWCzh8cMHIHJ73jgDImYqg9+F8YPFtgRSyvN2v9lFIEeVT4sh lWQG+533qdb0Y4LxFfqE1WXddY91iYzmIsfULkrZdrmQUWuD5Zye/B7Uq CwxbAjAUzjPzF7X3w+V2dUvFato+pWwcvTPEUPPXoCz/IHRKATYuoxq/k Y=; Received: from unknown (HELO ironmsg04-sd.qualcomm.com) ([10.53.140.144]) by alexa-out-sd-01.qualcomm.com with ESMTP; 14 Feb 2022 06:59:22 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg04-sd.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Feb 2022 06:59:22 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.15; Mon, 14 Feb 2022 06:59:21 -0800 Received: from hu-srivasam-hyd.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Mon, 14 Feb 2022 06:59:16 -0800 From: Srinivasa Rao Mandadapu To: , , , , , , , , , , , , , , , , CC: Srinivasa Rao Mandadapu , "Venkata Prasad Potturu" Subject: [RESEND v13 06/10] ASoC: qcom: Add regmap config support for codec dma driver Date: Mon, 14 Feb 2022 20:28:24 +0530 Message-ID: <1644850708-11099-7-git-send-email-quic_srivasam@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> References: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Update regmap configuration for supporting headset playback and capture and DMIC capture using codec dma interface Signed-off-by: Srinivasa Rao Mandadapu Co-developed-by: Venkata Prasad Potturu Signed-off-by: Venkata Prasad Potturu Reviewed-by: Srinivas Kandagatla --- sound/soc/qcom/lpass-cpu.c | 185 +++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 185 insertions(+) diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index 3bd9eb3..4fb9669 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -28,6 +28,8 @@ #define LPASS_CPU_I2S_SD2_3_MASK GENMASK(3, 2) #define LPASS_CPU_I2S_SD0_1_2_MASK GENMASK(2, 0) #define LPASS_CPU_I2S_SD0_1_2_3_MASK GENMASK(3, 0) +#define LPASS_REG_READ 1 +#define LPASS_REG_WRITE 0 =20 /* * Channel maps for Quad channel playbacks on MI2S Secondary @@ -798,6 +800,189 @@ static struct regmap_config lpass_hdmi_regmap_config = =3D { .cache_type =3D REGCACHE_FLAT, }; =20 +static bool __lpass_rxtx_regmap_accessible(struct device *dev, unsigned in= t reg, bool rw) +{ + struct lpass_data *drvdata =3D dev_get_drvdata(dev); + struct lpass_variant *v =3D drvdata->variant; + int i; + + for (i =3D 0; i < v->rxtx_irq_ports; ++i) { + if (reg =3D=3D LPAIF_RXTX_IRQCLEAR_REG(v, i)) + return true; + if (reg =3D=3D LPAIF_RXTX_IRQEN_REG(v, i)) + return true; + if (reg =3D=3D LPAIF_RXTX_IRQSTAT_REG(v, i)) + return true; + } + + for (i =3D 0; i < v->rxtx_rdma_channels; ++i) { + if (reg =3D=3D LPAIF_CDC_RXTX_RDMACTL_REG(v, i, LPASS_CDC_DMA_RX0)) + return true; + if (reg =3D=3D LPAIF_CDC_RXTX_RDMABASE_REG(v, i, LPASS_CDC_DMA_RX0)) + return true; + if (reg =3D=3D LPAIF_CDC_RXTX_RDMABUFF_REG(v, i, LPASS_CDC_DMA_RX0)) + return true; + if (rw =3D=3D LPASS_REG_READ) { + if (reg =3D=3D LPAIF_CDC_RXTX_RDMACURR_REG(v, i, LPASS_CDC_DMA_RX0)) + return true; + } + if (reg =3D=3D LPAIF_CDC_RXTX_RDMAPER_REG(v, i, LPASS_CDC_DMA_RX0)) + return true; + if (reg =3D=3D LPAIF_CDC_RXTX_RDMA_INTF_REG(v, i, LPASS_CDC_DMA_RX0)) + return true; + } + + for (i =3D 0; i < v->rxtx_wrdma_channels; ++i) { + if (reg =3D=3D LPAIF_CDC_RXTX_WRDMACTL_REG(v, i + v->rxtx_wrdma_channel_= start, + LPASS_CDC_DMA_TX3)) + return true; + if (reg =3D=3D LPAIF_CDC_RXTX_WRDMABASE_REG(v, i + v->rxtx_wrdma_channel= _start, + LPASS_CDC_DMA_TX3)) + return true; + if (reg =3D=3D LPAIF_CDC_RXTX_WRDMABUFF_REG(v, i + v->rxtx_wrdma_channel= _start, + LPASS_CDC_DMA_TX3)) + return true; + if (rw =3D=3D LPASS_REG_READ) { + if (reg =3D=3D LPAIF_CDC_RXTX_WRDMACURR_REG(v, i, LPASS_CDC_DMA_RX0)) + return true; + } + if (reg =3D=3D LPAIF_CDC_RXTX_WRDMAPER_REG(v, i + v->rxtx_wrdma_channel_= start, + LPASS_CDC_DMA_TX3)) + return true; + if (reg =3D=3D LPAIF_CDC_RXTX_WRDMA_INTF_REG(v, i + v->rxtx_wrdma_channe= l_start, + LPASS_CDC_DMA_TX3)) + return true; + } + return false; +} + +static bool lpass_rxtx_regmap_writeable(struct device *dev, unsigned int r= eg) +{ + return __lpass_rxtx_regmap_accessible(dev, reg, LPASS_REG_WRITE); +} + +static bool lpass_rxtx_regmap_readable(struct device *dev, unsigned int re= g) +{ + return __lpass_rxtx_regmap_accessible(dev, reg, LPASS_REG_READ); +} + +static bool lpass_rxtx_regmap_volatile(struct device *dev, unsigned int re= g) +{ + struct lpass_data *drvdata =3D dev_get_drvdata(dev); + struct lpass_variant *v =3D drvdata->variant; + int i; + + for (i =3D 0; i < v->rxtx_irq_ports; ++i) { + if (reg =3D=3D LPAIF_RXTX_IRQCLEAR_REG(v, i)) + return true; + if (reg =3D=3D LPAIF_RXTX_IRQSTAT_REG(v, i)) + return true; + } + + for (i =3D 0; i < v->rxtx_rdma_channels; ++i) + if (reg =3D=3D LPAIF_CDC_RXTX_RDMACURR_REG(v, i, LPASS_CDC_DMA_RX0)) + return true; + + for (i =3D 0; i < v->rxtx_wrdma_channels; ++i) + if (reg =3D=3D LPAIF_CDC_RXTX_WRDMACURR_REG(v, i + v->rxtx_wrdma_channel= _start, + LPASS_CDC_DMA_TX3)) + return true; + + return false; +} + +static bool __lpass_va_regmap_accessible(struct device *dev, unsigned int = reg, bool rw) +{ + struct lpass_data *drvdata =3D dev_get_drvdata(dev); + struct lpass_variant *v =3D drvdata->variant; + int i; + + for (i =3D 0; i < v->va_irq_ports; ++i) { + if (reg =3D=3D LPAIF_VA_IRQCLEAR_REG(v, i)) + return true; + if (reg =3D=3D LPAIF_VA_IRQEN_REG(v, i)) + return true; + if (reg =3D=3D LPAIF_VA_IRQSTAT_REG(v, i)) + return true; + } + + for (i =3D 0; i < v->va_wrdma_channels; ++i) { + if (reg =3D=3D LPAIF_CDC_VA_WRDMACTL_REG(v, i + v->va_wrdma_channel_star= t, + LPASS_CDC_DMA_VA_TX0)) + return true; + if (reg =3D=3D LPAIF_CDC_VA_WRDMABASE_REG(v, i + v->va_wrdma_channel_sta= rt, + LPASS_CDC_DMA_VA_TX0)) + return true; + if (reg =3D=3D LPAIF_CDC_VA_WRDMABUFF_REG(v, i + v->va_wrdma_channel_sta= rt, + LPASS_CDC_DMA_VA_TX0)) + return true; + if (rw =3D=3D LPASS_REG_READ) { + if (reg =3D=3D LPAIF_CDC_VA_WRDMACURR_REG(v, i + v->va_wrdma_channel_st= art, + LPASS_CDC_DMA_VA_TX0)) + return true; + } + if (reg =3D=3D LPAIF_CDC_VA_WRDMAPER_REG(v, i + v->va_wrdma_channel_star= t, + LPASS_CDC_DMA_VA_TX0)) + return true; + if (reg =3D=3D LPAIF_CDC_VA_WRDMA_INTF_REG(v, i + v->va_wrdma_channel_st= art, + LPASS_CDC_DMA_VA_TX0)) + return true; + } + return false; +} + +static bool lpass_va_regmap_writeable(struct device *dev, unsigned int reg) +{ + return __lpass_va_regmap_accessible(dev, reg, LPASS_REG_WRITE); +} + +static bool lpass_va_regmap_readable(struct device *dev, unsigned int reg) +{ + return __lpass_va_regmap_accessible(dev, reg, LPASS_REG_READ); +} + +static bool lpass_va_regmap_volatile(struct device *dev, unsigned int reg) +{ + struct lpass_data *drvdata =3D dev_get_drvdata(dev); + struct lpass_variant *v =3D drvdata->variant; + int i; + + for (i =3D 0; i < v->va_irq_ports; ++i) { + if (reg =3D=3D LPAIF_VA_IRQCLEAR_REG(v, i)) + return true; + if (reg =3D=3D LPAIF_VA_IRQSTAT_REG(v, i)) + return true; + } + + for (i =3D 0; i < v->va_wrdma_channels; ++i) { + if (reg =3D=3D LPAIF_CDC_VA_WRDMACURR_REG(v, i + v->va_wrdma_channel_sta= rt, + LPASS_CDC_DMA_VA_TX0)) + return true; + } + + return false; +} + +static struct regmap_config lpass_rxtx_regmap_config =3D { + .reg_bits =3D 32, + .reg_stride =3D 4, + .val_bits =3D 32, + .writeable_reg =3D lpass_rxtx_regmap_writeable, + .readable_reg =3D lpass_rxtx_regmap_readable, + .volatile_reg =3D lpass_rxtx_regmap_volatile, + .cache_type =3D REGCACHE_FLAT, +}; + +static struct regmap_config lpass_va_regmap_config =3D { + .reg_bits =3D 32, + .reg_stride =3D 4, + .val_bits =3D 32, + .writeable_reg =3D lpass_va_regmap_writeable, + .readable_reg =3D lpass_va_regmap_readable, + .volatile_reg =3D lpass_va_regmap_volatile, + .cache_type =3D REGCACHE_FLAT, +}; + static unsigned int of_lpass_cpu_parse_sd_lines(struct device *dev, struct device_node *node, const char *name) --=20 2.7.4 From nobody Mon Jun 29 07:33:43 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 32A81C433EF for ; Mon, 14 Feb 2022 14:59:34 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355550AbiBNO7k (ORCPT ); Mon, 14 Feb 2022 09:59:40 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60316 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1348401AbiBNO7i (ORCPT ); Mon, 14 Feb 2022 09:59:38 -0500 Received: from alexa-out-sd-01.qualcomm.com (alexa-out-sd-01.qualcomm.com [199.106.114.38]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4F84E4754C; Mon, 14 Feb 2022 06:59:29 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1644850769; x=1676386769; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=UCKISyAig63AwZrdy/8YmqGAmpvAYPvxKZryVkSau+s=; b=QEOtnPPCsPob1aNemmNLUpsHJF+2Rk3TbBXPrqWqZd+eya0DtiEMsIem UFsx6y7PxVOa/BvYLVgHXGN5fnu9BpkAiOPAODsNy/GefiK6Kfm5kllkB OIgLNQSm91aBCKwdQs2KaseTvhuqmcghMRyi+Y2KiZGS+2ytRR3KPkXtq k=; Received: from unknown (HELO ironmsg05-sd.qualcomm.com) ([10.53.140.145]) by alexa-out-sd-01.qualcomm.com with ESMTP; 14 Feb 2022 06:59:29 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg05-sd.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Feb 2022 06:59:28 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.15; Mon, 14 Feb 2022 06:59:28 -0800 Received: from hu-srivasam-hyd.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Mon, 14 Feb 2022 06:59:22 -0800 From: Srinivasa Rao Mandadapu To: , , , , , , , , , , , , , , , , CC: Srinivasa Rao Mandadapu , "Venkata Prasad Potturu" Subject: [RESEND v13 07/10] ASoC: qcom: Add support for codec dma driver Date: Mon, 14 Feb 2022 20:28:25 +0530 Message-ID: <1644850708-11099-8-git-send-email-quic_srivasam@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> References: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Upadate lpass cpu and platform driver to support audio over codec dma in ADSP bypass use case. Signed-off-by: Srinivasa Rao Mandadapu Co-developed-by: Venkata Prasad Potturu Signed-off-by: Venkata Prasad Potturu Reported-by: kernel test robot Reported-by: Dan Carpenter --- sound/soc/qcom/lpass-cpu.c | 59 ++++- sound/soc/qcom/lpass-platform.c | 499 ++++++++++++++++++++++++++++++++++++= ++-- 2 files changed, 537 insertions(+), 21 deletions(-) diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index 4fb9669..a5a46bc 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -1042,7 +1042,9 @@ static void of_lpass_cpu_parse_dai_data(struct device= *dev, } if (id =3D=3D LPASS_DP_RX) { data->hdmi_port_enable =3D 1; - } else { + } else if (is_cdc_dma_port(id)) + data->codec_dma_enable =3D 1; + else { data->mi2s_playback_sd_mode[id] =3D of_lpass_cpu_parse_sd_lines(dev, node, "qcom,playback-sd-lines"); @@ -1057,6 +1059,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platfor= m_device *pdev) { struct lpass_data *drvdata; struct device_node *dsp_of_node; + struct resource *res; struct lpass_variant *variant; struct device *dev =3D &pdev->dev; const struct of_device_id *match; @@ -1082,6 +1085,58 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platfo= rm_device *pdev) =20 of_lpass_cpu_parse_dai_data(dev, drvdata); =20 + drvdata->num_clks =3D variant->num_clks; + if (drvdata->codec_dma_enable) { + drvdata->rxtx_lpaif =3D + devm_platform_ioremap_resource_byname(pdev, "lpass-rxtx-lpaif"); + if (IS_ERR(drvdata->rxtx_lpaif)) + return PTR_ERR(drvdata->rxtx_lpaif); + + drvdata->va_lpaif =3D devm_platform_ioremap_resource_byname(pdev, "lpass= -va-lpaif"); + if (IS_ERR(drvdata->va_lpaif)) + return PTR_ERR(drvdata->va_lpaif); + + lpass_rxtx_regmap_config.max_register =3D LPAIF_CDC_RXTX_WRDMAPER_REG(va= riant, + variant->rxtx_wrdma_channels + + variant->rxtx_wrdma_channel_start, LPASS_CDC_DMA_TX3); + + drvdata->rxtx_lpaif_map =3D devm_regmap_init_mmio(dev, drvdata->rxtx_lpa= if, + &lpass_rxtx_regmap_config); + if (IS_ERR(drvdata->rxtx_lpaif_map)) { + dev_err(dev, "error initializing rxtx regmap: %ld\n", + PTR_ERR(drvdata->rxtx_lpaif_map)); + return PTR_ERR(drvdata->rxtx_lpaif_map); + } + lpass_va_regmap_config.max_register =3D LPAIF_CDC_VA_WRDMAPER_REG(varian= t, + variant->va_wrdma_channels + + variant->va_wrdma_channel_start, LPASS_CDC_DMA_VA_TX0); + + drvdata->va_lpaif_map =3D devm_regmap_init_mmio(dev, drvdata->va_lpaif, + &lpass_va_regmap_config); + if (IS_ERR(drvdata->va_lpaif_map)) { + dev_err(dev, "error initializing va regmap: %ld\n", + PTR_ERR(drvdata->va_lpaif_map)); + return PTR_ERR(drvdata->va_lpaif_map); + } + drvdata->cdc_clks =3D devm_kcalloc(dev, variant->cdc_dma_num_clks, + sizeof(*drvdata->cdc_clks), GFP_KERNEL); + drvdata->cdc_num_clks =3D variant->cdc_dma_num_clks; + + for (i =3D 0; i < drvdata->cdc_num_clks; i++) + drvdata->cdc_clks[i].id =3D variant->cdc_dma_clk_names[i]; + + ret =3D devm_clk_bulk_get(dev, drvdata->cdc_num_clks, drvdata->cdc_clks); + if (ret) { + dev_err(dev, "Failed to get clocks %d\n", ret); + return ret; + } + + res =3D platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-rxtx-c= dc-dma-lpm"); + drvdata->rxtx_cdc_dma_lpm_buf =3D res->start; + + res =3D platform_get_resource_byname(pdev, IORESOURCE_MEM, "lpass-va-cdc= -dma-lpm"); + drvdata->va_cdc_dma_lpm_buf =3D res->start; + } drvdata->lpaif =3D devm_platform_ioremap_resource_byname(pdev, "lpass-lpa= if"); if (IS_ERR(drvdata->lpaif)) return PTR_ERR(drvdata->lpaif); @@ -1124,7 +1179,7 @@ int asoc_qcom_lpass_cpu_platform_probe(struct platfor= m_device *pdev) =20 for (i =3D 0; i < variant->num_dai; i++) { dai_id =3D variant->dai_driver[i].id; - if (dai_id =3D=3D LPASS_DP_RX) + if (dai_id =3D=3D LPASS_DP_RX || is_cdc_dma_port(dai_id)) continue; =20 drvdata->mi2s_osr_clk[dai_id] =3D devm_clk_get_optional(dev, diff --git a/sound/soc/qcom/lpass-platform.c b/sound/soc/qcom/lpass-platfor= m.c index 5d77240..12b8d40 100644 --- a/sound/soc/qcom/lpass-platform.c +++ b/sound/soc/qcom/lpass-platform.c @@ -20,6 +20,9 @@ =20 #define LPASS_PLATFORM_BUFFER_SIZE (24 * 2 * 1024) #define LPASS_PLATFORM_PERIODS 2 +#define LPASS_RXTX_CDC_DMA_LPM_BUFF_SIZE (8 * 1024) +#define LPASS_VA_CDC_DMA_LPM_BUFF_SIZE (12 * 1024) +#define LPASS_CDC_DMA_REGISTER_FIELDS_MAX 15 =20 static const struct snd_pcm_hardware lpass_platform_pcm_hardware =3D { .info =3D SNDRV_PCM_INFO_MMAP | @@ -45,6 +48,99 @@ static const struct snd_pcm_hardware lpass_platform_pcm_= hardware =3D { .fifo_size =3D 0, }; =20 +static const struct snd_pcm_hardware lpass_platform_rxtx_hardware =3D { + .info =3D SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME, + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S24 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .rate_min =3D 8000, + .rate_max =3D 192000, + .channels_min =3D 1, + .channels_max =3D 8, + .buffer_bytes_max =3D LPASS_RXTX_CDC_DMA_LPM_BUFF_SIZE, + .period_bytes_max =3D LPASS_RXTX_CDC_DMA_LPM_BUFF_SIZE / + LPASS_PLATFORM_PERIODS, + .period_bytes_min =3D LPASS_RXTX_CDC_DMA_LPM_BUFF_SIZE / + LPASS_PLATFORM_PERIODS, + .periods_min =3D LPASS_PLATFORM_PERIODS, + .periods_max =3D LPASS_PLATFORM_PERIODS, + .fifo_size =3D 0, +}; + +static const struct snd_pcm_hardware lpass_platform_va_hardware =3D { + .info =3D SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_MMAP_VALID | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_PAUSE | + SNDRV_PCM_INFO_RESUME, + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S24 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .rate_min =3D 8000, + .rate_max =3D 192000, + .channels_min =3D 1, + .channels_max =3D 8, + .buffer_bytes_max =3D LPASS_VA_CDC_DMA_LPM_BUFF_SIZE, + .period_bytes_max =3D LPASS_VA_CDC_DMA_LPM_BUFF_SIZE / + LPASS_PLATFORM_PERIODS, + .period_bytes_min =3D LPASS_VA_CDC_DMA_LPM_BUFF_SIZE / + LPASS_PLATFORM_PERIODS, + .periods_min =3D LPASS_PLATFORM_PERIODS, + .periods_max =3D LPASS_PLATFORM_PERIODS, + .fifo_size =3D 0, +}; + +static int lpass_platform_alloc_rxtx_dmactl_fields(struct device *dev, + struct regmap *map) +{ + struct lpass_data *drvdata =3D dev_get_drvdata(dev); + struct lpass_variant *v =3D drvdata->variant; + struct lpaif_dmactl *rd_dmactl, *wr_dmactl; + int rval; + + rd_dmactl =3D devm_kzalloc(dev, sizeof(*rd_dmactl), GFP_KERNEL); + if (rd_dmactl =3D=3D NULL) + return -ENOMEM; + + wr_dmactl =3D devm_kzalloc(dev, sizeof(*wr_dmactl), GFP_KERNEL); + if (wr_dmactl =3D=3D NULL) + return -ENOMEM; + + drvdata->rxtx_rd_dmactl =3D rd_dmactl; + drvdata->rxtx_wr_dmactl =3D wr_dmactl; + + rval =3D devm_regmap_field_bulk_alloc(dev, map, &rd_dmactl->intf, + &v->rxtx_rdma_intf, LPASS_CDC_DMA_REGISTER_FIELDS_MAX); + if (rval) + return rval; + + return devm_regmap_field_bulk_alloc(dev, map, &wr_dmactl->intf, + &v->rxtx_wrdma_intf, LPASS_CDC_DMA_REGISTER_FIELDS_MAX); +} + +static int lpass_platform_alloc_va_dmactl_fields(struct device *dev, + struct regmap *map) +{ + struct lpass_data *drvdata =3D dev_get_drvdata(dev); + struct lpass_variant *v =3D drvdata->variant; + struct lpaif_dmactl *wr_dmactl; + + wr_dmactl =3D devm_kzalloc(dev, sizeof(*wr_dmactl), GFP_KERNEL); + if (wr_dmactl =3D=3D NULL) + return -ENOMEM; + + drvdata->va_wr_dmactl =3D wr_dmactl; + return devm_regmap_field_bulk_alloc(dev, map, &wr_dmactl->intf, + &v->va_wrdma_intf, LPASS_CDC_DMA_REGISTER_FIELDS_MAX); +} + + static int lpass_platform_alloc_dmactl_fields(struct device *dev, struct regmap *map) { @@ -123,25 +219,55 @@ static int lpass_platform_pcmops_open(struct snd_soc_= component *component, return dma_ch; } =20 - if (cpu_dai->driver->id =3D=3D LPASS_DP_RX) { - map =3D drvdata->hdmiif_map; - drvdata->hdmi_substream[dma_ch] =3D substream; - } else { + switch (dai_id) { + case MI2S_PRIMARY ... MI2S_QUINARY: map =3D drvdata->lpaif_map; drvdata->substream[dma_ch] =3D substream; + break; + case LPASS_DP_RX: + map =3D drvdata->hdmiif_map; + drvdata->hdmi_substream[dma_ch] =3D substream; + break; + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + map =3D drvdata->rxtx_lpaif_map; + drvdata->rxtx_substream[dma_ch] =3D substream; + break; + case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8: + map =3D drvdata->va_lpaif_map; + drvdata->va_substream[dma_ch] =3D substream; + break; + default: + break; } + data->dma_ch =3D dma_ch; - ret =3D 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; + switch (dai_id) { + case MI2S_PRIMARY ... MI2S_QUINARY: + case LPASS_DP_RX: + ret =3D regmap_write(map, LPAIF_DMACTL_REG(v, dma_ch, dir, data->i2s_por= t), 0); + if (ret) { + kfree(data); + dev_err(soc_runtime->dev, "error writing to rdmactl reg: %d\n", ret); + return ret; + } + snd_soc_set_runtime_hwparams(substream, &lpass_platform_pcm_hardware); + runtime->dma_bytes =3D lpass_platform_pcm_hardware.buffer_bytes_max; + break; + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + snd_soc_set_runtime_hwparams(substream, &lpass_platform_rxtx_hardware); + runtime->dma_bytes =3D lpass_platform_rxtx_hardware.buffer_bytes_max; + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + break; + case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8: + snd_soc_set_runtime_hwparams(substream, &lpass_platform_va_hardware); + runtime->dma_bytes =3D lpass_platform_va_hardware.buffer_bytes_max; + snd_pcm_set_runtime_buffer(substream, &substream->dma_buffer); + break; + default: + break; } - snd_soc_set_runtime_hwparams(substream, &lpass_platform_pcm_hardware); - - runtime->dma_bytes =3D lpass_platform_pcm_hardware.buffer_bytes_max; - ret =3D snd_pcm_hw_constraint_integer(runtime, SNDRV_PCM_HW_PARAM_PERIODS); if (ret < 0) { @@ -166,10 +292,25 @@ static int lpass_platform_pcmops_close(struct snd_soc= _component *component, unsigned int dai_id =3D cpu_dai->driver->id; =20 data =3D runtime->private_data; - if (dai_id =3D=3D LPASS_DP_RX) - drvdata->hdmi_substream[data->dma_ch] =3D NULL; - else + + switch (dai_id) { + case MI2S_PRIMARY ... MI2S_QUINARY: drvdata->substream[data->dma_ch] =3D NULL; + break; + case LPASS_DP_RX: + drvdata->hdmi_substream[data->dma_ch] =3D NULL; + break; + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + drvdata->rxtx_substream[data->dma_ch] =3D NULL; + break; + case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8: + drvdata->va_substream[data->dma_ch] =3D NULL; + break; + default: + break; + } + if (v->free_dma_channel) v->free_dma_channel(drvdata, data->dma_ch, dai_id); =20 @@ -209,9 +350,25 @@ static void __lpass_get_lpaif_handle(struct snd_pcm_su= bstream *substream, l_dmactl =3D drvdata->hdmi_rd_dmactl; l_map =3D drvdata->hdmiif_map; break; + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + l_id =3D pcm_data->dma_ch; + l_dmactl =3D drvdata->rxtx_rd_dmactl; + l_map =3D drvdata->rxtx_lpaif_map; + break; + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + l_id =3D pcm_data->dma_ch - v->rxtx_wrdma_channel_start; + l_dmactl =3D drvdata->rxtx_wr_dmactl; + l_map =3D drvdata->rxtx_lpaif_map; + break; + case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8: + l_id =3D pcm_data->dma_ch - v->va_wrdma_channel_start; + l_dmactl =3D drvdata->va_wr_dmactl; + l_map =3D drvdata->va_lpaif_map; + break; default: break; } + if (dmactl) *dmactl =3D l_dmactl; if (id) @@ -299,6 +456,10 @@ static int lpass_platform_pcmops_hw_params(struct snd_= soc_component *component, } =20 break; + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX0: + break; default: dev_err(soc_runtime->dev, "%s: invalid interface: %d\n", __func__, dai_= id); break; @@ -387,6 +548,9 @@ static int lpass_platform_pcmops_hw_free(struct snd_soc= _component *component, struct regmap *map; unsigned int dai_id =3D cpu_dai->driver->id; =20 + if (is_cdc_dma_port(dai_id)) + return 0; + __lpass_get_lpaif_handle(substream, component, NULL, NULL, &map); if (!map) { dev_err(soc_runtime->dev, "failed to get dmactl handle\n"); @@ -449,6 +613,14 @@ static int lpass_platform_pcmops_prepare(struct snd_so= c_component *component, return ret; } =20 + if (is_cdc_dma_port(dai_id)) { + ret =3D regmap_fields_write(dmactl->fifowm, id, LPAIF_DMACTL_FIFOWM_8); + if (ret) { + dev_err(soc_runtime->dev, "error writing fifowm field to dmactl reg: %d= , id: %d\n", + ret, id); + return ret; + } + } ret =3D regmap_fields_write(dmactl->enable, id, LPAIF_DMACTL_ENABLE_ON); if (ret) { dev_err(soc_runtime->dev, "error writing to rdmactl reg: %d\n", @@ -532,6 +704,35 @@ static int lpass_platform_pcmops_trigger(struct snd_so= c_component *component, val_mask =3D LPAIF_IRQ_ALL(ch); val_irqen =3D LPAIF_IRQ_ALL(ch); break; + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + ret =3D regmap_fields_write(dmactl->dyncclk, id, LPAIF_DMACTL_DYNCLK_ON= ); + if (ret) { + dev_err(soc_runtime->dev, + "error writing to rdmactl reg field: %d\n", ret); + return ret; + } + reg_irqclr =3D LPAIF_RXTX_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST); + val_irqclr =3D LPAIF_IRQ_ALL(ch); + + reg_irqen =3D LPAIF_RXTX_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST); + val_mask =3D LPAIF_IRQ_ALL(ch); + val_irqen =3D LPAIF_IRQ_ALL(ch); + break; + case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8: + ret =3D regmap_fields_write(dmactl->dyncclk, id, LPAIF_DMACTL_DYNCLK_ON= ); + if (ret) { + dev_err(soc_runtime->dev, + "error writing to rdmactl reg field: %d\n", ret); + return ret; + } + reg_irqclr =3D LPAIF_VA_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST); + val_irqclr =3D LPAIF_IRQ_ALL(ch); + + reg_irqen =3D LPAIF_VA_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST); + val_mask =3D LPAIF_IRQ_ALL(ch); + val_irqen =3D LPAIF_IRQ_ALL(ch); + break; default: dev_err(soc_runtime->dev, "%s: invalid %d interface\n", __func__, dai_i= d); return -EINVAL; @@ -583,6 +784,37 @@ static int lpass_platform_pcmops_trigger(struct snd_so= c_component *component, val_mask =3D LPAIF_IRQ_ALL(ch); val_irqen =3D 0; break; + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + ret =3D regmap_fields_write(dmactl->dyncclk, id, LPAIF_DMACTL_DYNCLK_OF= F); + if (ret) { + dev_err(soc_runtime->dev, + "error writing to rdmactl reg field: %d\n", ret); + return ret; + } + + reg_irqclr =3D LPAIF_RXTX_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST); + val_irqclr =3D LPAIF_IRQ_ALL(ch); + + reg_irqen =3D LPAIF_RXTX_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST); + val_mask =3D LPAIF_IRQ_ALL(ch); + val_irqen =3D LPAIF_IRQ_ALL(ch); + break; + case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8: + ret =3D regmap_fields_write(dmactl->dyncclk, id, LPAIF_DMACTL_DYNCLK_OF= F); + if (ret) { + dev_err(soc_runtime->dev, + "error writing to rdmactl reg field: %d\n", ret); + return ret; + } + + reg_irqclr =3D LPAIF_VA_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST); + val_irqclr =3D LPAIF_IRQ_ALL(ch); + + reg_irqen =3D LPAIF_VA_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST); + val_mask =3D LPAIF_IRQ_ALL(ch); + val_irqen =3D LPAIF_IRQ_ALL(ch); + break; default: dev_err(soc_runtime->dev, "%s: invalid %d interface\n", __func__, dai_i= d); return -EINVAL; @@ -642,6 +874,39 @@ static snd_pcm_uframes_t lpass_platform_pcmops_pointer( return bytes_to_frames(substream->runtime, curr_addr - base_addr); } =20 +static int lpass_platform_cdc_dma_mmap(struct snd_soc_component *component, + struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime =3D substream->runtime; + unsigned long size, offset; + + vma->vm_page_prot =3D pgprot_noncached(vma->vm_page_prot); + size =3D vma->vm_end - vma->vm_start; + offset =3D vma->vm_pgoff << PAGE_SHIFT; + return io_remap_pfn_range(vma, vma->vm_start, + (runtime->dma_addr + offset) >> PAGE_SHIFT, + size, vma->vm_page_prot); + +} + +static int lpass_platform_pcmops_mmap(struct snd_soc_component *component, + struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_soc_pcm_runtime *soc_runtime =3D asoc_substream_to_rtd(substre= am); + struct snd_soc_dai *cpu_dai =3D asoc_rtd_to_cpu(soc_runtime, 0); + unsigned int dai_id =3D cpu_dai->driver->id; + int err; + + if (is_cdc_dma_port(dai_id)) + err =3D lpass_platform_cdc_dma_mmap(component, substream, vma); + else + err =3D snd_pcm_lib_default_mmap(substream, vma); + + return err; +} + static irqreturn_t lpass_dma_interrupt_handler( struct snd_pcm_substream *substream, struct lpass_data *drvdata, @@ -674,6 +939,17 @@ static irqreturn_t lpass_dma_interrupt_handler( reg =3D LPAIF_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST); val =3D 0; break; + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + map =3D drvdata->rxtx_lpaif_map; + reg =3D LPAIF_RXTX_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST); + val =3D 0; + break; + case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8: + map =3D drvdata->va_lpaif_map; + reg =3D LPAIF_VA_IRQCLEAR_REG(v, LPAIF_IRQ_PORT_HOST); + val =3D 0; + break; default: dev_err(soc_runtime->dev, "%s: invalid %d interface\n", __func__, dai_id= ); return -EINVAL; @@ -781,18 +1057,122 @@ static irqreturn_t lpass_platform_hdmiif_irq(int ir= q, void *data) return rv; } } + return IRQ_HANDLED; +} + +static irqreturn_t lpass_platform_rxtxif_irq(int irq, void *data) +{ + struct lpass_data *drvdata =3D data; + struct lpass_variant *v =3D drvdata->variant; + unsigned int irqs; + int rv, chan; + + rv =3D regmap_read(drvdata->rxtx_lpaif_map, + LPAIF_RXTX_IRQSTAT_REG(v, LPAIF_IRQ_PORT_HOST), &irqs); + if (rv) + return IRQ_NONE; + /* Handle per channel interrupts */ + for (chan =3D 0; chan < LPASS_MAX_CDC_DMA_CHANNELS; chan++) { + if (irqs & LPAIF_IRQ_ALL(chan) && drvdata->rxtx_substream[chan]) { + rv =3D lpass_dma_interrupt_handler( + drvdata->rxtx_substream[chan], + drvdata, chan, irqs); + if (rv !=3D IRQ_HANDLED) + return rv; + } + } =20 return IRQ_HANDLED; } =20 +static irqreturn_t lpass_platform_vaif_irq(int irq, void *data) +{ + struct lpass_data *drvdata =3D data; + struct lpass_variant *v =3D drvdata->variant; + unsigned int irqs; + int rv, chan; + + rv =3D regmap_read(drvdata->va_lpaif_map, + LPAIF_VA_IRQSTAT_REG(v, LPAIF_IRQ_PORT_HOST), &irqs); + if (rv) + return IRQ_NONE; + /* Handle per channel interrupts */ + for (chan =3D 0; chan < LPASS_MAX_VA_CDC_DMA_CHANNELS; chan++) { + if (irqs & LPAIF_IRQ_ALL(chan) && drvdata->va_substream[chan]) { + rv =3D lpass_dma_interrupt_handler( + drvdata->va_substream[chan], + drvdata, chan, irqs); + if (rv !=3D IRQ_HANDLED) + return rv; + } + } + return IRQ_HANDLED; +} + +static int lpass_platform_prealloc_cdc_dma_buffer(struct snd_soc_component= *component, + struct snd_pcm *pcm, int dai_id) +{ + struct lpass_data *drvdata =3D snd_soc_component_get_drvdata(component); + struct snd_pcm_substream *substream; + struct snd_dma_buffer *buf; + int ret; + + if (pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream) + substream =3D pcm->streams[SNDRV_PCM_STREAM_PLAYBACK].substream; + else + substream =3D pcm->streams[SNDRV_PCM_STREAM_CAPTURE].substream; + + ret =3D dma_coerce_mask_and_coherent(pcm->card->dev, DMA_BIT_MASK(64)); + if (ret) + return ret; + + buf =3D &substream->dma_buffer; + buf->dev.dev =3D pcm->card->dev; + buf->private_data =3D NULL; + + /* Assign Codec DMA buffer pointers */ + buf->dev.type =3D SNDRV_DMA_TYPE_CONTINUOUS; + + switch (dai_id) { + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + buf->bytes =3D lpass_platform_rxtx_hardware.buffer_bytes_max; + buf->addr =3D drvdata->rxtx_cdc_dma_lpm_buf; + break; + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + buf->bytes =3D lpass_platform_rxtx_hardware.buffer_bytes_max; + buf->addr =3D drvdata->rxtx_cdc_dma_lpm_buf + LPASS_RXTX_CDC_DMA_LPM_BUF= F_SIZE; + break; + case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8: + buf->bytes =3D lpass_platform_va_hardware.buffer_bytes_max; + buf->addr =3D drvdata->va_cdc_dma_lpm_buf; + break; + default: + break; + } + + buf->area =3D (unsigned char * __force)ioremap(buf->addr, buf->bytes); + + return 0; +} + static int lpass_platform_pcm_new(struct snd_soc_component *component, struct snd_soc_pcm_runtime *soc_runtime) { struct snd_pcm *pcm =3D soc_runtime->pcm; + struct snd_soc_dai *cpu_dai =3D asoc_rtd_to_cpu(soc_runtime, 0); + unsigned int dai_id =3D cpu_dai->driver->id; + size_t size =3D lpass_platform_pcm_hardware.buffer_bytes_max; =20 - return snd_pcm_set_fixed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, - component->dev, size); + /* + * Lpass codec dma can access only lpass lpm hardware memory. + * ioremap is for HLOS to access hardware memory. + */ + if (is_cdc_dma_port(dai_id)) + return lpass_platform_prealloc_cdc_dma_buffer(component, pcm, dai_id); + else + return snd_pcm_set_fixed_buffer_all(pcm, SNDRV_DMA_TYPE_DEV, + component->dev, size); } =20 static int lpass_platform_pcmops_suspend(struct snd_soc_component *compone= nt) @@ -827,6 +1207,31 @@ static int lpass_platform_pcmops_resume(struct snd_so= c_component *component) return regcache_sync(map); } =20 +static int lpass_platform_copy(struct snd_soc_component *component, + struct snd_pcm_substream *substream, int channel, + unsigned long pos, void __user *buf, unsigned long bytes) +{ + struct snd_pcm_runtime *rt =3D substream->runtime; + unsigned int dai_id =3D component->id; + int ret =3D 0; + + void __iomem *dma_buf =3D rt->dma_area + pos + + channel * (rt->dma_bytes / rt->channels); + + if (substream->stream =3D=3D SNDRV_PCM_STREAM_PLAYBACK) { + if (is_cdc_dma_port(dai_id)) + ret =3D copy_from_user_toio(dma_buf, buf, bytes); + else + ret =3D copy_from_user((void __force *)dma_buf, buf, bytes); + } else if (substream->stream =3D=3D SNDRV_PCM_STREAM_CAPTURE) { + if (is_cdc_dma_port(dai_id)) + ret =3D copy_to_user_fromio(buf, dma_buf, bytes); + else + ret =3D copy_to_user(buf, (void __force *)dma_buf, bytes); + } + + return ret; +} =20 static const struct snd_soc_component_driver lpass_component_driver =3D { .name =3D DRV_NAME, @@ -837,9 +1242,11 @@ static const struct snd_soc_component_driver lpass_co= mponent_driver =3D { .prepare =3D lpass_platform_pcmops_prepare, .trigger =3D lpass_platform_pcmops_trigger, .pointer =3D lpass_platform_pcmops_pointer, + .mmap =3D lpass_platform_pcmops_mmap, .pcm_construct =3D lpass_platform_pcm_new, .suspend =3D lpass_platform_pcmops_suspend, .resume =3D lpass_platform_pcmops_resume, + .copy_user =3D lpass_platform_copy, =20 }; =20 @@ -877,6 +1284,60 @@ int asoc_qcom_lpass_platform_register(struct platform= _device *pdev) return ret; } =20 + if (drvdata->codec_dma_enable) { + ret =3D regmap_write(drvdata->rxtx_lpaif_map, + LPAIF_RXTX_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST), 0x0); + if (ret) { + dev_err(&pdev->dev, "error writing to rxtx irqen reg: %d\n", ret); + return ret; + } + ret =3D regmap_write(drvdata->va_lpaif_map, + LPAIF_VA_IRQEN_REG(v, LPAIF_IRQ_PORT_HOST), 0x0); + if (ret) { + dev_err(&pdev->dev, "error writing to rxtx irqen reg: %d\n", ret); + return ret; + } + drvdata->rxtxif_irq =3D platform_get_irq_byname(pdev, "lpass-irq-rxtxif"= ); + if (drvdata->rxtxif_irq < 0) + return -ENODEV; + + ret =3D devm_request_irq(&pdev->dev, drvdata->rxtxif_irq, + lpass_platform_rxtxif_irq, IRQF_TRIGGER_RISING, + "lpass-irq-rxtxif", drvdata); + if (ret) { + dev_err(&pdev->dev, "rxtx irq request failed: %d\n", ret); + return ret; + } + + ret =3D lpass_platform_alloc_rxtx_dmactl_fields(&pdev->dev, + drvdata->rxtx_lpaif_map); + if (ret) { + dev_err(&pdev->dev, + "error initializing rxtx dmactl fields: %d\n", ret); + return ret; + } + + drvdata->vaif_irq =3D platform_get_irq_byname(pdev, "lpass-irq-vaif"); + if (drvdata->vaif_irq < 0) + return -ENODEV; + + ret =3D devm_request_irq(&pdev->dev, drvdata->vaif_irq, + lpass_platform_vaif_irq, IRQF_TRIGGER_RISING, + "lpass-irq-vaif", drvdata); + if (ret) { + dev_err(&pdev->dev, "va irq request failed: %d\n", ret); + return ret; + } + + ret =3D lpass_platform_alloc_va_dmactl_fields(&pdev->dev, + drvdata->va_lpaif_map); + if (ret) { + dev_err(&pdev->dev, + "error initializing va dmactl fields: %d\n", ret); + return ret; + } + } + if (drvdata->hdmi_port_enable) { drvdata->hdmiif_irq =3D platform_get_irq_byname(pdev, "lpass-irq-hdmi"); if (drvdata->hdmiif_irq < 0) --=20 2.7.4 From nobody Mon Jun 29 07:33:43 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 70D25C433EF for ; Mon, 14 Feb 2022 14:59:41 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355554AbiBNO7r (ORCPT ); Mon, 14 Feb 2022 09:59:47 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60350 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244446AbiBNO7n (ORCPT ); Mon, 14 Feb 2022 09:59:43 -0500 Received: from alexa-out.qualcomm.com (alexa-out.qualcomm.com [129.46.98.28]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 4E40439A; Mon, 14 Feb 2022 06:59:35 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1644850775; x=1676386775; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=w3RKeE0AkTp0vTxNTvZMcYwIAerjV4UXdCebiEAKxwE=; b=c9h7t74EDKQPcNDhJCoMahdxgsMzCFudhY9dase3VCVAmqtYv/YFDrg6 h3BNqQnK5QxOYq6GJUL5Rai1DK1GOLvLVt+vSkqsTiE0nC57TpoTVnjry 3e7+kpCQLnRw9JsYArhYFr9gqPELmAMMENf/JYjwSerF5VhIm0W71blB/ o=; Received: from ironmsg07-lv.qualcomm.com ([10.47.202.151]) by alexa-out.qualcomm.com with ESMTP; 14 Feb 2022 06:59:35 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg07-lv.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Feb 2022 06:59:34 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.15; Mon, 14 Feb 2022 06:59:34 -0800 Received: from hu-srivasam-hyd.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Mon, 14 Feb 2022 06:59:28 -0800 From: Srinivasa Rao Mandadapu To: , , , , , , , , , , , , , , , , CC: Srinivasa Rao Mandadapu , "Venkata Prasad Potturu" Subject: [RESEND v13 08/10] ASoC: qcom: Add lpass CPU driver for codec dma control Date: Mon, 14 Feb 2022 20:28:26 +0530 Message-ID: <1644850708-11099-9-git-send-email-quic_srivasam@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> References: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add lpass cpu driver to support audio over codec dma for ADSP bypass usecase. Signed-off-by: Srinivasa Rao Mandadapu Co-developed-by: Venkata Prasad Potturu Signed-off-by: Venkata Prasad Potturu Reviewed-by: Srinivas Kandagatla --- sound/soc/qcom/lpass-cdc-dma.c | 304 +++++++++++++++++++++++++++++++++++++= ++++ sound/soc/qcom/lpass.h | 1 + 2 files changed, 305 insertions(+) create mode 100644 sound/soc/qcom/lpass-cdc-dma.c diff --git a/sound/soc/qcom/lpass-cdc-dma.c b/sound/soc/qcom/lpass-cdc-dma.c new file mode 100644 index 0000000..4a50baa --- /dev/null +++ b/sound/soc/qcom/lpass-cdc-dma.c @@ -0,0 +1,304 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2021 The Linux Foundation. All rights reserved. + * + * lpass-cdc-dma.c -- ALSA SoC CDC DMA CPU DAI driver for QTi LPASS + */ + +#include +#include +#include +#include + +#include "lpass-lpaif-reg.h" +#include "lpass.h" + +#define CODEC_MEM_FREQ_NORMAL 153600000 + +enum codec_dma_interfaces { + LPASS_CDC_DMA_INTERFACE1 =3D 1, + LPASS_CDC_DMA_INTERFACE2, + LPASS_CDC_DMA_INTERFACE3, + LPASS_CDC_DMA_INTERFACE4, + LPASS_CDC_DMA_INTERFACE5, + LPASS_CDC_DMA_INTERFACE6, + LPASS_CDC_DMA_INTERFACE7, + LPASS_CDC_DMA_INTERFACE8, + LPASS_CDC_DMA_INTERFACE9, + LPASS_CDC_DMA_INTERFACE10, +}; + +static void __lpass_get_dmactl_handle(struct snd_pcm_substream *substream,= struct snd_soc_dai *dai, + struct lpaif_dmactl **dmactl, int *id) +{ + struct snd_soc_pcm_runtime *soc_runtime =3D asoc_substream_to_rtd(substre= am); + struct snd_soc_dai *cpu_dai =3D asoc_rtd_to_cpu(soc_runtime, 0); + struct lpass_data *drvdata =3D snd_soc_dai_get_drvdata(dai); + struct snd_pcm_runtime *rt =3D substream->runtime; + struct lpass_pcm_data *pcm_data =3D rt->private_data; + struct lpass_variant *v =3D drvdata->variant; + unsigned int dai_id =3D cpu_dai->driver->id; + + switch (dai_id) { + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + *dmactl =3D drvdata->rxtx_rd_dmactl; + *id =3D pcm_data->dma_ch; + break; + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + *dmactl =3D drvdata->rxtx_wr_dmactl; + *id =3D pcm_data->dma_ch - v->rxtx_wrdma_channel_start; + break; + case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8: + *dmactl =3D drvdata->va_wr_dmactl; + *id =3D pcm_data->dma_ch - v->va_wrdma_channel_start; + break; + default: + dev_err(soc_runtime->dev, "invalid dai id for dma ctl: %d\n", dai_id); + break; + } +} + +static int __lpass_get_codec_dma_intf_type(int dai_id) +{ + int ret; + + switch (dai_id) { + case LPASS_CDC_DMA_RX0: + case LPASS_CDC_DMA_TX0: + case LPASS_CDC_DMA_VA_TX0: + ret =3D LPASS_CDC_DMA_INTERFACE1; + break; + case LPASS_CDC_DMA_RX1: + case LPASS_CDC_DMA_TX1: + case LPASS_CDC_DMA_VA_TX1: + ret =3D LPASS_CDC_DMA_INTERFACE2; + break; + case LPASS_CDC_DMA_RX2: + case LPASS_CDC_DMA_TX2: + case LPASS_CDC_DMA_VA_TX2: + ret =3D LPASS_CDC_DMA_INTERFACE3; + break; + case LPASS_CDC_DMA_RX3: + case LPASS_CDC_DMA_TX3: + case LPASS_CDC_DMA_VA_TX3: + ret =3D LPASS_CDC_DMA_INTERFACE4; + break; + case LPASS_CDC_DMA_RX4: + case LPASS_CDC_DMA_TX4: + case LPASS_CDC_DMA_VA_TX4: + ret =3D LPASS_CDC_DMA_INTERFACE5; + break; + case LPASS_CDC_DMA_RX5: + case LPASS_CDC_DMA_TX5: + case LPASS_CDC_DMA_VA_TX5: + ret =3D LPASS_CDC_DMA_INTERFACE6; + break; + case LPASS_CDC_DMA_RX6: + case LPASS_CDC_DMA_TX6: + case LPASS_CDC_DMA_VA_TX6: + ret =3D LPASS_CDC_DMA_INTERFACE7; + break; + case LPASS_CDC_DMA_RX7: + case LPASS_CDC_DMA_TX7: + case LPASS_CDC_DMA_VA_TX7: + ret =3D LPASS_CDC_DMA_INTERFACE8; + break; + case LPASS_CDC_DMA_RX8: + case LPASS_CDC_DMA_TX8: + case LPASS_CDC_DMA_VA_TX8: + ret =3D LPASS_CDC_DMA_INTERFACE9; + break; + case LPASS_CDC_DMA_RX9: + ret =3D LPASS_CDC_DMA_INTERFACE10; + break; + default: + ret =3D -EINVAL; + break; + } + return ret; +} + +static int __lpass_platform_codec_intf_init(struct snd_soc_dai *dai, + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *soc_runtime =3D asoc_substream_to_rtd(substre= am); + struct snd_soc_dai *cpu_dai =3D asoc_rtd_to_cpu(soc_runtime, 0); + struct lpaif_dmactl *dmactl =3D NULL; + struct device *dev =3D soc_runtime->dev; + int ret, id, codec_intf; + unsigned int dai_id =3D cpu_dai->driver->id; + + codec_intf =3D __lpass_get_codec_dma_intf_type(dai_id); + if (codec_intf < 0) { + dev_err(dev, "failed to get codec_intf: %d\n", codec_intf); + return codec_intf; + } + + __lpass_get_dmactl_handle(substream, dai, &dmactl, &id); + if (!dmactl) { + dev_err(dev, "failed to get dmactl handle for dai_id: %d\n", dai_id); + return -EINVAL; + } + + ret =3D regmap_fields_write(dmactl->codec_intf, id, codec_intf); + if (ret) { + dev_err(dev, "error writing to dmactl codec_intf reg field: %d\n", ret); + return ret; + } + ret =3D regmap_fields_write(dmactl->codec_fs_sel, id, 0x0); + if (ret) { + dev_err(dev, "error writing to dmactl codec_fs_sel reg field: %d\n", ret= ); + return ret; + } + ret =3D regmap_fields_write(dmactl->codec_fs_delay, id, 0x0); + if (ret) { + dev_err(dev, "error writing to dmactl codec_fs_delay reg field: %d\n", r= et); + return ret; + } + ret =3D regmap_fields_write(dmactl->codec_pack, id, 0x1); + if (ret) { + dev_err(dev, "error writing to dmactl codec_pack reg field: %d\n", ret); + return ret; + } + ret =3D regmap_fields_write(dmactl->codec_enable, id, LPAIF_DMACTL_ENABLE= _ON); + if (ret) { + dev_err(dev, "error writing to dmactl codec_enable reg field: %d\n", ret= ); + return ret; + } + return 0; +} + +static int lpass_cdc_dma_daiops_startup(struct snd_pcm_substream *substrea= m, + struct snd_soc_dai *dai) +{ + struct lpass_data *drvdata =3D snd_soc_dai_get_drvdata(dai); + struct snd_soc_pcm_runtime *soc_runtime =3D asoc_substream_to_rtd(substre= am); + + switch (dai->id) { + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + clk_set_rate(drvdata->cdc_clks[2].clk, CODEC_MEM_FREQ_NORMAL); + clk_prepare_enable(drvdata->cdc_clks[2].clk); + break; + case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX0: + clk_set_rate(drvdata->cdc_clks[5].clk, CODEC_MEM_FREQ_NORMAL); + clk_prepare_enable(drvdata->cdc_clks[5].clk); + break; + default: + dev_err(soc_runtime->dev, "%s: invalid interface: %d\n", __func__, dai-= >id); + break; + } + return 0; +} + +static void lpass_cdc_dma_daiops_shutdown(struct snd_pcm_substream *substr= eam, + struct snd_soc_dai *dai) +{ + struct lpass_data *drvdata =3D snd_soc_dai_get_drvdata(dai); + struct snd_soc_pcm_runtime *soc_runtime =3D asoc_substream_to_rtd(substre= am); + + switch (dai->id) { + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + clk_disable_unprepare(drvdata->cdc_clks[2].clk); + break; + case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX0: + clk_disable_unprepare(drvdata->cdc_clks[5].clk); + break; + default: + dev_err(soc_runtime->dev, "%s: invalid interface: %d\n", __func__, dai-= >id); + break; + } +} + +static int lpass_cdc_dma_daiops_hw_params(struct snd_pcm_substream *substr= eam, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *soc_runtime =3D asoc_substream_to_rtd(substre= am); + struct lpaif_dmactl *dmactl =3D NULL; + unsigned int ret, regval; + unsigned int channels =3D params_channels(params); + int id; + + switch (channels) { + case 1: + regval =3D LPASS_CDC_DMA_INTF_ONE_CHANNEL; + break; + case 2: + regval =3D LPASS_CDC_DMA_INTF_TWO_CHANNEL; + break; + case 4: + regval =3D LPASS_CDC_DMA_INTF_FOUR_CHANNEL; + break; + case 6: + regval =3D LPASS_CDC_DMA_INTF_SIX_CHANNEL; + break; + case 8: + regval =3D LPASS_CDC_DMA_INTF_EIGHT_CHANNEL; + break; + default: + dev_err(soc_runtime->dev, "invalid PCM config\n"); + return -EINVAL; + } + + __lpass_get_dmactl_handle(substream, dai, &dmactl, &id); + if (!dmactl) { + dev_err(soc_runtime->dev, "failed to get dmactl handle\n"); + return -EINVAL; + } + ret =3D regmap_fields_write(dmactl->codec_channel, id, regval); + if (ret) { + dev_err(soc_runtime->dev, + "error writing to dmactl codec_channel reg field: %d\n", ret); + return ret; + } + return 0; +} + +static int lpass_cdc_dma_daiops_trigger(struct snd_pcm_substream *substrea= m, + int cmd, struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *soc_runtime =3D asoc_substream_to_rtd(substre= am); + struct lpaif_dmactl *dmactl; + int ret =3D 0, id; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + __lpass_platform_codec_intf_init(dai, substream); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + __lpass_get_dmactl_handle(substream, dai, &dmactl, &id); + if (!dmactl) { + dev_err(soc_runtime->dev, "failed to get dmactl handle\n"); + return -EINVAL; + } + ret =3D regmap_fields_write(dmactl->codec_enable, id, LPAIF_DMACTL_ENABL= E_OFF); + if (ret) { + dev_err(soc_runtime->dev, + "error writing to dmactl codec_enable reg: %d\n", ret); + return ret; + } + break; + default: + ret =3D -EINVAL; + dev_err(soc_runtime->dev, "%s: invalid %d interface\n", __func__, cmd); + break; + } + return ret; +} + +const struct snd_soc_dai_ops asoc_qcom_lpass_cdc_dma_dai_ops =3D { + .startup =3D lpass_cdc_dma_daiops_startup, + .shutdown =3D lpass_cdc_dma_daiops_shutdown, + .hw_params =3D lpass_cdc_dma_daiops_hw_params, + .trigger =3D lpass_cdc_dma_daiops_trigger, +}; +EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cdc_dma_dai_ops); + +MODULE_DESCRIPTION("QTi LPASS CDC DMA Driver"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/qcom/lpass.h b/sound/soc/qcom/lpass.h index e059c4a..d279a72 100644 --- a/sound/soc/qcom/lpass.h +++ b/sound/soc/qcom/lpass.h @@ -410,5 +410,6 @@ int asoc_qcom_lpass_cpu_dai_probe(struct snd_soc_dai *d= ai); extern const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_ops; int lpass_cpu_pcm_new(struct snd_soc_pcm_runtime *rtd, struct snd_soc_dai *dai); +extern const struct snd_soc_dai_ops asoc_qcom_lpass_cdc_dma_dai_ops; =20 #endif /* __LPASS_H__ */ --=20 2.7.4 From nobody Mon Jun 29 07:33:43 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 251BDC433EF for ; Mon, 14 Feb 2022 14:59:46 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355562AbiBNO7w (ORCPT ); Mon, 14 Feb 2022 09:59:52 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60442 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S244446AbiBNO7t (ORCPT ); Mon, 14 Feb 2022 09:59:49 -0500 Received: from alexa-out-sd-01.qualcomm.com (alexa-out-sd-01.qualcomm.com [199.106.114.38]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 3EEEA39A; Mon, 14 Feb 2022 06:59:41 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1644850781; x=1676386781; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=kbjwhiK2tTRbM4zrwUQx7sOHj8zt1NylUTymteyHln0=; b=oxt14mnhpNY969gs82S19bp/T3sFUa4FXekdCkIiKm0eRbYoMdmrsYcX SmnCQxUsPgGW3QynSyl5zaWjNgUqqh0Mk0qZEE29PGFsvgttUGqVMrntE QqjASx9puX77w7gboRI6PIbgdSDKGzkHilgA5bCI6LMAyOl5md63iG/BC I=; Received: from unknown (HELO ironmsg01-sd.qualcomm.com) ([10.53.140.141]) by alexa-out-sd-01.qualcomm.com with ESMTP; 14 Feb 2022 06:59:41 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg01-sd.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Feb 2022 06:59:40 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.15; Mon, 14 Feb 2022 06:59:39 -0800 Received: from hu-srivasam-hyd.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Mon, 14 Feb 2022 06:59:34 -0800 From: Srinivasa Rao Mandadapu To: , , , , , , , , , , , , , , , , CC: Srinivasa Rao Mandadapu , "Venkata Prasad Potturu" Subject: [RESEND v13 09/10] ASoC: dt-bindings: Add SC7280 lpass cpu bindings Date: Mon, 14 Feb 2022 20:28:27 +0530 Message-ID: <1644850708-11099-10-git-send-email-quic_srivasam@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> References: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add bindings for sc7280 lpass cpu driver which supports audio over i2s based speaker, soundwire based headset, msm dmics and HDMI Port. Signed-off-by: Srinivasa Rao Mandadapu Co-developed-by: Venkata Prasad Potturu Signed-off-by: Venkata Prasad Potturu Reviewed-by: Rob Herring --- .../devicetree/bindings/sound/qcom,lpass-cpu.yaml | 75 ++++++++++++++++++= +--- 1 file changed, 67 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml b/= Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml index 1e23c0e..2c81efb 100644 --- a/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml +++ b/Documentation/devicetree/bindings/sound/qcom,lpass-cpu.yaml @@ -22,35 +22,41 @@ properties: - qcom,lpass-cpu - qcom,apq8016-lpass-cpu - qcom,sc7180-lpass-cpu + - qcom,sc7280-lpass-cpu =20 reg: - maxItems: 2 + minItems: 2 + maxItems: 6 description: LPAIF core registers =20 reg-names: - maxItems: 2 + minItems: 2 + maxItems: 6 =20 clocks: minItems: 3 - maxItems: 6 + maxItems: 7 =20 clock-names: minItems: 3 - maxItems: 6 + maxItems: 7 =20 interrupts: - maxItems: 2 + minItems: 2 + maxItems: 4 description: LPAIF DMA buffer interrupt =20 interrupt-names: - maxItems: 2 + minItems: 2 + maxItems: 4 =20 qcom,adsp: $ref: /schemas/types.yaml#/definitions/phandle description: Phandle for the audio DSP node =20 iommus: - maxItems: 2 + minItems: 2 + maxItems: 3 description: Phandle to apps_smmu node with sid mask =20 power-domains: @@ -69,7 +75,7 @@ patternProperties: "^dai-link@[0-9a-f]$": type: object description: | - LPASS CPU dai node for each I2S device. Bindings of each node + LPASS CPU dai node for each I2S device or Soundwire device. Bindings= of each node depends on the specific driver providing the functionality and properties. properties: @@ -174,6 +180,59 @@ allOf: - iommus - power-domains =20 + - if: + properties: + compatible: + contains: + const: qcom,sc7280-lpass-cpu + + then: + properties: + clock-names: + oneOf: + - items: #for I2S + - const: aon_cc_audio_hm_h + - const: core_cc_sysnoc_mport_core + - const: core_cc_ext_if1_ibit + - items: #for Soundwire + - const: aon_cc_audio_hm_h + - const: audio_cc_codec_mem0 + - const: audio_cc_codec_mem1 + - const: audio_cc_codec_mem2 + - items: #for HDMI + - const: aon_cc_audio_hm_h + + reg-names: + anyOf: + - items: #for I2S + - const: lpass-lpaif + - items: #for I2S and HDMI + - const: lpass-hdmiif + - const: lpass-lpaif + - items: #for I2S, soundwire and HDMI + - const: lpass-hdmiif + - const: lpass-lpaif + - const: lpass-rxtx-cdc-dma-lpm + - const: lpass-rxtx-lpaif + - const: lpass-va-lpaif + - const: lpass-va-cdc-dma-lpm + interrupt-names: + anyOf: + - items: #for I2S + - const: lpass-irq-lpaif + - items: #for I2S and HDMI + - const: lpass-irq-lpaif + - const: lpass-irq-hdmi + - items: #for I2S, soundwire and HDMI + - const: lpass-irq-lpaif + - const: lpass-irq-hdmi + - const: lpass-irq-vaif + - const: lpass-irq-rxtxif + + required: + - iommus + - power-domains + examples: - | #include --=20 2.7.4 From nobody Mon Jun 29 07:33:43 2026 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 5AA8EC433EF for ; Mon, 14 Feb 2022 14:59:51 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1355574AbiBNO75 (ORCPT ); Mon, 14 Feb 2022 09:59:57 -0500 Received: from mxb-00190b01.gslb.pphosted.com ([23.128.96.19]:60552 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1355567AbiBNO7z (ORCPT ); Mon, 14 Feb 2022 09:59:55 -0500 Received: from alexa-out-sd-01.qualcomm.com (alexa-out-sd-01.qualcomm.com [199.106.114.38]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id E45D34B87D; Mon, 14 Feb 2022 06:59:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=quicinc.com; i=@quicinc.com; q=dns/txt; s=qcdkim; t=1644850786; x=1676386786; h=from:to:cc:subject:date:message-id:in-reply-to: references:mime-version; bh=DUMRWEom12SBvjmB0sFJaBBT+LMJjsPnggYjE97qxpo=; b=AMRK7sWDwKdASEm1BfiVwBA3X55OoeuuzV+5CVZjREYt1CesEokG67bR VowTyNTbq0IZ3Fa6AwYKVYdBSRNKN/blO6iJqOkLSd3KY0TRsPmbKRqWN PBPBU/EobG7rvuck4mdVxUxCjiTKkFLzft41iUx/aonJbxjUrKKySCQM5 0=; Received: from unknown (HELO ironmsg02-sd.qualcomm.com) ([10.53.140.142]) by alexa-out-sd-01.qualcomm.com with ESMTP; 14 Feb 2022 06:59:46 -0800 X-QCInternal: smtphost Received: from nasanex01c.na.qualcomm.com ([10.47.97.222]) by ironmsg02-sd.qualcomm.com with ESMTP/TLS/ECDHE-RSA-AES256-GCM-SHA384; 14 Feb 2022 06:59:46 -0800 Received: from nalasex01a.na.qualcomm.com (10.47.209.196) by nasanex01c.na.qualcomm.com (10.47.97.222) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.986.15; Mon, 14 Feb 2022 06:59:45 -0800 Received: from hu-srivasam-hyd.qualcomm.com (10.80.80.8) by nalasex01a.na.qualcomm.com (10.47.209.196) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.922.19; Mon, 14 Feb 2022 06:59:40 -0800 From: Srinivasa Rao Mandadapu To: , , , , , , , , , , , , , , , , CC: Srinivasa Rao Mandadapu , "Venkata Prasad Potturu" Subject: [RESEND v13 10/10] ASoC: qcom: lpass-sc7280: Add platform driver for lpass audio Date: Mon, 14 Feb 2022 20:28:28 +0530 Message-ID: <1644850708-11099-11-git-send-email-quic_srivasam@quicinc.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> References: <1644850708-11099-1-git-send-email-quic_srivasam@quicinc.com> MIME-Version: 1.0 X-Originating-IP: [10.80.80.8] X-ClientProxiedBy: nasanex01a.na.qualcomm.com (10.52.223.231) To nalasex01a.na.qualcomm.com (10.47.209.196) Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add platform driver for configuring sc7280 lpass core I2S and DMA configuration to support playback & capture to external codecs connected over secondary MI2S interface and soundwire interface. Signed-off-by: Srinivasa Rao Mandadapu Co-developed-by: Venkata Prasad Potturu Signed-off-by: Venkata Prasad Potturu Reviewed-by: Srinivas Kandagatla --- sound/soc/qcom/lpass-sc7280.c | 447 ++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 447 insertions(+) create mode 100644 sound/soc/qcom/lpass-sc7280.c diff --git a/sound/soc/qcom/lpass-sc7280.c b/sound/soc/qcom/lpass-sc7280.c new file mode 100644 index 0000000..61a445c --- /dev/null +++ b/sound/soc/qcom/lpass-sc7280.c @@ -0,0 +1,447 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020-2021, The Linux Foundation. All rights reserved. + * + * lpass-sc7180.c -- ALSA SoC platform-machine driver for QTi LPASS + */ + +#include +#include +#include +#include + +#include + +#include "lpass-lpaif-reg.h" +#include "lpass.h" + +static struct snd_soc_dai_driver sc7280_lpass_cpu_dai_driver[] =3D { + { + .id =3D MI2S_PRIMARY, + .name =3D "Primary MI2S", + .playback =3D { + .stream_name =3D "Primary Playback", + .formats =3D SNDRV_PCM_FMTBIT_S16, + .rates =3D SNDRV_PCM_RATE_48000, + .rate_min =3D 48000, + .rate_max =3D 48000, + .channels_min =3D 2, + .channels_max =3D 2, + }, + .capture =3D { + .stream_name =3D "Primary Capture", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_48000, + .rate_min =3D 48000, + .rate_max =3D 48000, + .channels_min =3D 2, + .channels_max =3D 2, + }, + .probe =3D &asoc_qcom_lpass_cpu_dai_probe, + .ops =3D &asoc_qcom_lpass_cpu_dai_ops, + }, { + .id =3D MI2S_SECONDARY, + .name =3D "Secondary MI2S", + .playback =3D { + .stream_name =3D "Secondary MI2S Playback", + .formats =3D SNDRV_PCM_FMTBIT_S16, + .rates =3D SNDRV_PCM_RATE_48000, + .rate_min =3D 48000, + .rate_max =3D 48000, + .channels_min =3D 2, + .channels_max =3D 2, + }, + .probe =3D &asoc_qcom_lpass_cpu_dai_probe, + .ops =3D &asoc_qcom_lpass_cpu_dai_ops, + }, { + .id =3D LPASS_DP_RX, + .name =3D "Hdmi", + .playback =3D { + .stream_name =3D "DP Playback", + .formats =3D SNDRV_PCM_FMTBIT_S24, + .rates =3D SNDRV_PCM_RATE_48000, + .rate_min =3D 48000, + .rate_max =3D 48000, + .channels_min =3D 2, + .channels_max =3D 2, + }, + .ops =3D &asoc_qcom_lpass_hdmi_dai_ops, + }, { + .id =3D LPASS_CDC_DMA_RX0, + .name =3D "CDC DMA RX", + .playback =3D { + .stream_name =3D "WCD Playback", + .formats =3D SNDRV_PCM_FMTBIT_S16, + .rates =3D SNDRV_PCM_RATE_48000, + .rate_min =3D 48000, + .rate_max =3D 48000, + .channels_min =3D 2, + .channels_max =3D 2, + }, + .ops =3D &asoc_qcom_lpass_cdc_dma_dai_ops, + }, { + .id =3D LPASS_CDC_DMA_TX3, + .name =3D "CDC DMA TX", + .capture =3D { + .stream_name =3D "WCD Capture", + .formats =3D SNDRV_PCM_FMTBIT_S16, + .rates =3D SNDRV_PCM_RATE_48000, + .rate_min =3D 48000, + .rate_max =3D 48000, + .channels_min =3D 1, + .channels_max =3D 1, + }, + .ops =3D &asoc_qcom_lpass_cdc_dma_dai_ops, + }, { + .id =3D LPASS_CDC_DMA_VA_TX0, + .name =3D "CDC DMA VA", + .capture =3D { + .stream_name =3D "DMIC Capture", + .formats =3D SNDRV_PCM_FMTBIT_S16, + .rates =3D SNDRV_PCM_RATE_48000, + .rate_min =3D 48000, + .rate_max =3D 48000, + .channels_min =3D 2, + .channels_max =3D 4, + }, + .ops =3D &asoc_qcom_lpass_cdc_dma_dai_ops, + }, +}; + +static int sc7280_lpass_alloc_dma_channel(struct lpass_data *drvdata, + int direction, unsigned int dai_id) +{ + struct lpass_variant *v =3D drvdata->variant; + int chan =3D 0; + + switch (dai_id) { + case MI2S_PRIMARY ... MI2S_QUINARY: + if (direction =3D=3D SNDRV_PCM_STREAM_PLAYBACK) { + chan =3D find_first_zero_bit(&drvdata->dma_ch_bit_map, + v->rdma_channels); + + if (chan >=3D v->rdma_channels) + return -EBUSY; + } else { + chan =3D find_next_zero_bit(&drvdata->dma_ch_bit_map, + v->wrdma_channel_start + + v->wrdma_channels, + v->wrdma_channel_start); + + if (chan >=3D v->wrdma_channel_start + v->wrdma_channels) + return -EBUSY; + } + set_bit(chan, &drvdata->dma_ch_bit_map); + break; + case LPASS_DP_RX: + chan =3D find_first_zero_bit(&drvdata->hdmi_dma_ch_bit_map, + v->hdmi_rdma_channels); + if (chan >=3D v->hdmi_rdma_channels) + return -EBUSY; + set_bit(chan, &drvdata->hdmi_dma_ch_bit_map); + break; + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + chan =3D find_first_zero_bit(&drvdata->rxtx_dma_ch_bit_map, + v->rxtx_rdma_channels); + if (chan >=3D v->rxtx_rdma_channels) + return -EBUSY; + break; + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + chan =3D find_next_zero_bit(&drvdata->rxtx_dma_ch_bit_map, + v->rxtx_wrdma_channel_start + + v->rxtx_wrdma_channels, + v->rxtx_wrdma_channel_start); + if (chan >=3D v->rxtx_wrdma_channel_start + v->rxtx_wrdma_channels) + return -EBUSY; + set_bit(chan, &drvdata->rxtx_dma_ch_bit_map); + break; + case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8: + chan =3D find_next_zero_bit(&drvdata->va_dma_ch_bit_map, + v->va_wrdma_channel_start + + v->va_wrdma_channels, + v->va_wrdma_channel_start); + if (chan >=3D v->va_wrdma_channel_start + v->va_wrdma_channels) + return -EBUSY; + set_bit(chan, &drvdata->va_dma_ch_bit_map); + break; + default: + break; + } + + return chan; +} + +static int sc7280_lpass_free_dma_channel(struct lpass_data *drvdata, int c= han, unsigned int dai_id) +{ + switch (dai_id) { + case MI2S_PRIMARY ... MI2S_QUINARY: + clear_bit(chan, &drvdata->dma_ch_bit_map); + break; + case LPASS_DP_RX: + clear_bit(chan, &drvdata->hdmi_dma_ch_bit_map); + break; + case LPASS_CDC_DMA_RX0 ... LPASS_CDC_DMA_RX9: + case LPASS_CDC_DMA_TX0 ... LPASS_CDC_DMA_TX8: + clear_bit(chan, &drvdata->rxtx_dma_ch_bit_map); + break; + case LPASS_CDC_DMA_VA_TX0 ... LPASS_CDC_DMA_VA_TX8: + clear_bit(chan, &drvdata->va_dma_ch_bit_map); + break; + default: + break; + } + + return 0; +} + +static int sc7280_lpass_init(struct platform_device *pdev) +{ + struct lpass_data *drvdata =3D platform_get_drvdata(pdev); + struct lpass_variant *variant =3D drvdata->variant; + struct device *dev =3D &pdev->dev; + int ret, i; + + drvdata->clks =3D devm_kcalloc(dev, variant->num_clks, + sizeof(*drvdata->clks), GFP_KERNEL); + if (!drvdata->clks) + return -ENOMEM; + + drvdata->num_clks =3D variant->num_clks; + + for (i =3D 0; i < drvdata->num_clks; i++) + drvdata->clks[i].id =3D variant->clk_name[i]; + + ret =3D 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 =3D clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks); + if (ret) { + dev_err(dev, "sc7280 clk_enable failed\n"); + return ret; + } + + return 0; +} + +static int sc7280_lpass_exit(struct platform_device *pdev) +{ + struct lpass_data *drvdata =3D platform_get_drvdata(pdev); + + clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks); + + return 0; +} + +static struct lpass_variant sc7280_data =3D { + .i2sctrl_reg_base =3D 0x1000, + .i2sctrl_reg_stride =3D 0x1000, + .i2s_ports =3D 3, + .irq_reg_base =3D 0x9000, + .irq_reg_stride =3D 0x1000, + .irq_ports =3D 3, + .rdma_reg_base =3D 0xC000, + .rdma_reg_stride =3D 0x1000, + .rdma_channels =3D 5, + .rxtx_rdma_reg_base =3D 0xC000, + .rxtx_rdma_reg_stride =3D 0x1000, + .rxtx_rdma_channels =3D 8, + .hdmi_rdma_reg_base =3D 0x64000, + .hdmi_rdma_reg_stride =3D 0x1000, + .hdmi_rdma_channels =3D 4, + .dmactl_audif_start =3D 1, + .wrdma_reg_base =3D 0x18000, + .wrdma_reg_stride =3D 0x1000, + .wrdma_channel_start =3D 5, + .wrdma_channels =3D 4, + .rxtx_irq_reg_base =3D 0x9000, + .rxtx_irq_reg_stride =3D 0x1000, + .rxtx_irq_ports =3D 3, + .rxtx_wrdma_reg_base =3D 0x18000, + .rxtx_wrdma_reg_stride =3D 0x1000, + .rxtx_wrdma_channel_start =3D 5, + .rxtx_wrdma_channels =3D 6, + .va_wrdma_reg_base =3D 0x18000, + .va_wrdma_reg_stride =3D 0x1000, + .va_wrdma_channel_start =3D 5, + .va_wrdma_channels =3D 3, + .va_irq_reg_base =3D 0x9000, + .va_irq_reg_stride =3D 0x1000, + .va_irq_ports =3D 3, + + .loopback =3D REG_FIELD_ID(0x1000, 17, 17, 3, 0x1000), + .spken =3D REG_FIELD_ID(0x1000, 16, 16, 3, 0x1000), + .spkmode =3D REG_FIELD_ID(0x1000, 11, 15, 3, 0x1000), + .spkmono =3D REG_FIELD_ID(0x1000, 10, 10, 3, 0x1000), + .micen =3D REG_FIELD_ID(0x1000, 9, 9, 3, 0x1000), + .micmode =3D REG_FIELD_ID(0x1000, 4, 8, 3, 0x1000), + .micmono =3D REG_FIELD_ID(0x1000, 3, 3, 3, 0x1000), + .wssrc =3D REG_FIELD_ID(0x1000, 2, 2, 3, 0x1000), + .bitwidth =3D REG_FIELD_ID(0x1000, 0, 1, 3, 0x1000), + + .rdma_dyncclk =3D REG_FIELD_ID(0xC000, 21, 21, 5, 0x1000), + .rdma_bursten =3D REG_FIELD_ID(0xC000, 20, 20, 5, 0x1000), + .rdma_wpscnt =3D REG_FIELD_ID(0xC000, 16, 19, 5, 0x1000), + .rdma_intf =3D REG_FIELD_ID(0xC000, 12, 15, 5, 0x1000), + .rdma_fifowm =3D REG_FIELD_ID(0xC000, 1, 5, 5, 0x1000), + .rdma_enable =3D REG_FIELD_ID(0xC000, 0, 0, 5, 0x1000), + + .wrdma_dyncclk =3D REG_FIELD_ID(0x18000, 22, 22, 4, 0x1000), + .wrdma_bursten =3D REG_FIELD_ID(0x18000, 21, 21, 4, 0x1000), + .wrdma_wpscnt =3D REG_FIELD_ID(0x18000, 17, 20, 4, 0x1000), + .wrdma_intf =3D REG_FIELD_ID(0x18000, 12, 16, 4, 0x1000), + .wrdma_fifowm =3D REG_FIELD_ID(0x18000, 1, 5, 4, 0x1000), + .wrdma_enable =3D REG_FIELD_ID(0x18000, 0, 0, 4, 0x1000), + + .rxtx_rdma_enable =3D REG_FIELD_ID(0xC000, 0, 0, 7, 0x1000), + .rxtx_rdma_fifowm =3D REG_FIELD_ID(0xC000, 1, 11, 7, 0x1000), + .rxtx_rdma_intf =3D REG_FIELD_ID(0xC000, 12, 15, 7, 0x1000), + .rxtx_rdma_wpscnt =3D REG_FIELD_ID(0xC000, 16, 19, 7, 0x1000), + .rxtx_rdma_bursten =3D REG_FIELD_ID(0xC000, 20, 20, 7, 0x1000), + .rxtx_rdma_dyncclk =3D REG_FIELD_ID(0xC000, 21, 21, 7, 0x1000), + + .rxtx_rdma_codec_ch =3D REG_FIELD_ID(0xC050, 0, 7, 7, 0x1000), + .rxtx_rdma_codec_intf =3D REG_FIELD_ID(0xC050, 16, 19, 7, 0x1000), + .rxtx_rdma_codec_fs_delay =3D REG_FIELD_ID(0xC050, 21, 24, 7, 0x1000), + .rxtx_rdma_codec_fs_sel =3D REG_FIELD_ID(0xC050, 25, 27, 7, 0x1000), + .rxtx_rdma_codec_pack =3D REG_FIELD_ID(0xC050, 29, 29, 5, 0x1000), + .rxtx_rdma_codec_enable =3D REG_FIELD_ID(0xC050, 30, 30, 7, 0x1000), + + .rxtx_wrdma_enable =3D REG_FIELD_ID(0x18000, 0, 0, 5, 0x1000), + .rxtx_wrdma_fifowm =3D REG_FIELD_ID(0x18000, 1, 11, 5, 0x1000), + .rxtx_wrdma_intf =3D REG_FIELD_ID(0x18000, 12, 16, 5, 0x1000), + .rxtx_wrdma_wpscnt =3D REG_FIELD_ID(0x18000, 17, 20, 5, 0x1000), + .rxtx_wrdma_bursten =3D REG_FIELD_ID(0x18000, 21, 21, 5, 0x1000), + .rxtx_wrdma_dyncclk =3D REG_FIELD_ID(0x18000, 22, 22, 5, 0x1000), + + .rxtx_wrdma_codec_ch =3D REG_FIELD_ID(0x18050, 0, 7, 5, 0x1000), + .rxtx_wrdma_codec_intf =3D REG_FIELD_ID(0x18050, 16, 19, 5, 0x1000), + .rxtx_wrdma_codec_fs_delay =3D REG_FIELD_ID(0x18050, 21, 24, 5, 0x1000), + .rxtx_wrdma_codec_fs_sel =3D REG_FIELD_ID(0x18050, 25, 27, 5, 0x1000), + .rxtx_wrdma_codec_pack =3D REG_FIELD_ID(0x18050, 29, 29, 5, 0x1000), + .rxtx_wrdma_codec_enable =3D REG_FIELD_ID(0x18050, 30, 30, 5, 0x1000), + + .va_wrdma_enable =3D REG_FIELD_ID(0x18000, 0, 0, 5, 0x1000), + .va_wrdma_fifowm =3D REG_FIELD_ID(0x18000, 1, 11, 5, 0x1000), + .va_wrdma_intf =3D REG_FIELD_ID(0x18000, 12, 16, 5, 0x1000), + .va_wrdma_wpscnt =3D REG_FIELD_ID(0x18000, 17, 20, 5, 0x1000), + .va_wrdma_bursten =3D REG_FIELD_ID(0x18000, 21, 21, 5, 0x1000), + .va_wrdma_dyncclk =3D REG_FIELD_ID(0x18000, 22, 22, 5, 0x1000), + + .va_wrdma_codec_ch =3D REG_FIELD_ID(0x18050, 0, 7, 5, 0x1000), + .va_wrdma_codec_intf =3D REG_FIELD_ID(0x18050, 16, 19, 5, 0x1000), + .va_wrdma_codec_fs_delay =3D REG_FIELD_ID(0x18050, 21, 24, 5, 0x1000), + .va_wrdma_codec_fs_sel =3D REG_FIELD_ID(0x18050, 25, 27, 5, 0x1000), + .va_wrdma_codec_pack =3D REG_FIELD_ID(0x18050, 29, 29, 5, 0x1000), + .va_wrdma_codec_enable =3D REG_FIELD_ID(0x18050, 30, 30, 5, 0x1000), + + .hdmi_tx_ctl_addr =3D 0x1000, + .hdmi_legacy_addr =3D 0x1008, + .hdmi_vbit_addr =3D 0x610c0, + .hdmi_ch_lsb_addr =3D 0x61048, + .hdmi_ch_msb_addr =3D 0x6104c, + .ch_stride =3D 0x8, + .hdmi_parity_addr =3D 0x61034, + .hdmi_dmactl_addr =3D 0x61038, + .hdmi_dma_stride =3D 0x4, + .hdmi_DP_addr =3D 0x610c8, + .hdmi_sstream_addr =3D 0x6101c, + .hdmi_irq_reg_base =3D 0x63000, + .hdmi_irq_ports =3D 1, + + .hdmi_rdma_dyncclk =3D REG_FIELD_ID(0x64000, 14, 14, 4, 0x1000), + .hdmi_rdma_bursten =3D REG_FIELD_ID(0x64000, 13, 13, 4, 0x1000), + .hdmi_rdma_burst8 =3D REG_FIELD_ID(0x64000, 15, 15, 4, 0x1000), + .hdmi_rdma_burst16 =3D REG_FIELD_ID(0x64000, 16, 16, 4, 0x1000), + .hdmi_rdma_dynburst =3D REG_FIELD_ID(0x64000, 18, 18, 4, 0x1000), + .hdmi_rdma_wpscnt =3D REG_FIELD_ID(0x64000, 10, 12, 4, 0x1000), + .hdmi_rdma_fifowm =3D REG_FIELD_ID(0x64000, 1, 5, 4, 0x1000), + .hdmi_rdma_enable =3D REG_FIELD_ID(0x64000, 0, 0, 4, 0x1000), + + .sstream_en =3D REG_FIELD(0x6101c, 0, 0), + .dma_sel =3D REG_FIELD(0x6101c, 1, 2), + .auto_bbit_en =3D REG_FIELD(0x6101c, 3, 3), + .layout =3D REG_FIELD(0x6101c, 4, 4), + .layout_sp =3D REG_FIELD(0x6101c, 5, 8), + .set_sp_on_en =3D REG_FIELD(0x6101c, 10, 10), + .dp_audio =3D REG_FIELD(0x6101c, 11, 11), + .dp_staffing_en =3D REG_FIELD(0x6101c, 12, 12), + .dp_sp_b_hw_en =3D REG_FIELD(0x6101c, 13, 13), + + .mute =3D REG_FIELD(0x610c8, 0, 0), + .as_sdp_cc =3D REG_FIELD(0x610c8, 1, 3), + .as_sdp_ct =3D REG_FIELD(0x610c8, 4, 7), + .aif_db4 =3D REG_FIELD(0x610c8, 8, 15), + .frequency =3D REG_FIELD(0x610c8, 16, 21), + .mst_index =3D REG_FIELD(0x610c8, 28, 29), + .dptx_index =3D REG_FIELD(0x610c8, 30, 31), + + .soft_reset =3D REG_FIELD(0x1000, 31, 31), + .force_reset =3D REG_FIELD(0x1000, 30, 30), + + .use_hw_chs =3D REG_FIELD(0x61038, 0, 0), + .use_hw_usr =3D REG_FIELD(0x61038, 1, 1), + .hw_chs_sel =3D REG_FIELD(0x61038, 2, 4), + .hw_usr_sel =3D REG_FIELD(0x61038, 5, 6), + + .replace_vbit =3D REG_FIELD(0x610c0, 0, 0), + .vbit_stream =3D REG_FIELD(0x610c0, 1, 1), + + .legacy_en =3D REG_FIELD(0x1008, 0, 0), + .calc_en =3D REG_FIELD(0x61034, 0, 0), + .lsb_bits =3D REG_FIELD(0x61048, 0, 31), + .msb_bits =3D REG_FIELD(0x6104c, 0, 31), + + + .clk_name =3D (const char*[]) { + "core_cc_sysnoc_mport_core" + }, + .num_clks =3D 1, + .cdc_dma_clk_names =3D (const char*[]) { + "aon_cc_audio_hm_h", + "audio_cc_codec_mem", + "audio_cc_codec_mem0", + "audio_cc_codec_mem1", + "audio_cc_codec_mem2", + "aon_cc_va_mem0" + }, + .cdc_dma_num_clks =3D 6, + .dai_driver =3D sc7280_lpass_cpu_dai_driver, + .num_dai =3D ARRAY_SIZE(sc7280_lpass_cpu_dai_driver), + .dai_osr_clk_names =3D (const char *[]) { + "audio_cc_ext_mclk0", + "null" + }, + .dai_bit_clk_names =3D (const char *[]) { + "core_cc_ext_if0_ibit", + "core_cc_ext_if1_ibit" + }, + .init =3D sc7280_lpass_init, + .exit =3D sc7280_lpass_exit, + .alloc_dma_channel =3D sc7280_lpass_alloc_dma_channel, + .free_dma_channel =3D sc7280_lpass_free_dma_channel, +}; + +static const struct of_device_id sc7280_lpass_cpu_device_id[] =3D { + {.compatible =3D "qcom,sc7280-lpass-cpu", .data =3D &sc7280_data}, + {} +}; +MODULE_DEVICE_TABLE(of, sc7280_lpass_cpu_device_id); + +static struct platform_driver sc7280_lpass_cpu_platform_driver =3D { + .driver =3D { + .name =3D "sc7280-lpass-cpu", + .of_match_table =3D of_match_ptr(sc7280_lpass_cpu_device_id), + }, + .probe =3D asoc_qcom_lpass_cpu_platform_probe, + .remove =3D asoc_qcom_lpass_cpu_platform_remove, + .shutdown =3D asoc_qcom_lpass_cpu_platform_shutdown, +}; + +module_platform_driver(sc7280_lpass_cpu_platform_driver); + +MODULE_DESCRIPTION("SC7280 LPASS CPU DRIVER"); +MODULE_LICENSE("GPL"); --=20 2.7.4