From nobody Fri Sep 25 14:31:50 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 65CB246C845; Fri, 11 Sep 2026 09:19:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118387; cv=none; b=REigsSC6bpbv/cagtDs9gxqNDJ8dH4LV59i7HJ9dyS8NGsxBGWFLeDvnidHqTDM8nTsA3k5Ad7DdeWz/gdirPuFvqdLqtvnI08HUnqflc1PDxrRPpHRkeMsXP80/E6I3UpMK1UjxeI6E/n/0dwvPXxtKRGZpjgb2KhHodqZlrZ0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118387; c=relaxed/simple; bh=SYAANv+8i1Rigy2uAXoUAEwYlaihmVXi5TENdPGZ/bY=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=qW4T50APz0WzuYoycgbGx7sKGBXS1MYxbQdQ2SMaqWM9WDP0xIziA8h8Kk4+IVJbi9OyVQfHuHxPegfjbVP2YTwczwh8XJJPSHuiHYNCHymqGMUxoKwc5eoXeLPhXxlvLtT/RBZKQ5bXLH5x7thbWu7WflNVmKFYhhdCz0F8cSA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=g+tHumtG; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="g+tHumtG" Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B7klNi4046183; Fri, 11 Sep 2026 09:19:25 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= BmjsZ4hwemQXi8jIeiH9FBX+J40y7PNXceXqm8T5qNU=; b=g+tHumtGDQQhkE6o eUwZq/S9L2pG/cZU9oXe4Xk22NXkhY+qacu9xBi6pk0XqiqY1853wHmnklC2Fcmz 9RU7/lj6zShcu9vGfva5GiE8gU91JzD+LUu3KPANLnIQkpKRcRqw/yTN0sLcWVWi DZmfoq+5/tF/a6ctS8d6a0B4wpTCruBR1MlFJYgxrkk/abkb6/Nh0TZE5oSnmQ7Y nfY50QkczBFLJm2og2ik6CETH14rYjuKI7P9YGRCS01N2xEhBdVcCMWhi9yFLxN6 F7/e7aCtitzYKcx5VvW8thYvmqsTWv3+gPADezyURE0WBkwthBL9iETuhjZLkOaJ CTYxJA== Received: from apblrppmta02.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gm2q12ran-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 09:19:24 +0000 (GMT) Received: from pps.filterd (apblrppmta02.qualcomm.com [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B9HBf42868308; Fri, 11 Sep 2026 09:19:22 GMT Received: from hu-hgautam-hyd.qualcomm.com (hu-hgautam-hyd.qualcomm.com [10.147.247.91]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTP id 68B9JL2X2870824; Fri, 11 Sep 2026 09:19:22 +0000 (GMT) From: Harendra Gautam Date: Fri, 11 Sep 2026 14:47:25 +0530 Subject: [PATCH v6 01/10] ASoC: dt-bindings: qcom,shikra-qaif-cpu: Add binding Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260911-b4-qaif-shikra-audio-v6-1-e9addb358201@oss.qualcomm.com> References: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> In-Reply-To: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> To: Srinivas Kandagatla Cc: Mark Brown , Liam Girdwood , Rob Herring , Krzysztof Kozlowski , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai , Kuninori Morimoto , linux-sound@vger.kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Prasad Kumpatla , Krzysztof Kozlowski , Sarath Ganapathiraju , Kumar Anurag Singh , Mohammad Rafi Shaik , Harendra Gautam X-Mailer: b4 0.15.2 X-Proofpoint-Reinject: loops=2 maxloops=12 X-QCInternal: smtphost X-QCInternal: smtphost X-Authority-Analysis: v=2.4 cv=d6lgWhjE c=1 sm=1 tr=0 ts=6aa3c79d cx=c_pps a=Ou0eQOY4+eZoSc0qltEV5Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=3WHJM1ZQz_JShphwDgj5:22 a=gEfo2CItAAAA:8 a=EUspDBNiAAAA:8 a=dsExs6sBCjvf26iM2HEA:9 a=QEXdDO2ut3YA:10 a=sptkURWiP4Gy88Gu7hUp:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfX7YeKw997Fu9n pqIa4APmwHO3zaUY+HCNIoMOiaTZOOVPlXyPaaAUACEoztsdxSKv4jUc+34odhT/jC7wZlnFTu6 4qdLIlYQT26SYngcMdXLOg2Thdn2VDnn/Nn/LaK+vkDBgyQhOi5Z/lou2yFyMn+amtFlcGwkS84 T1BN2yhsdBde453wvcXkYcb1bfAoElIr79sp+6iUgXvTAPnioNXWDo+XBNdZreMbzwRINPjJYJk hIRs+BG+AJyKfB7PrzrAtw6I6NHllPvArzOkoXuXidmqSGUUujKJt7T9/4f8QZ1uJu+AQff1Gq7 XcbYNMd+TM7Mj976uEBoOVrUnXITKcrkgLmIN7IXBABmqKVct5hQvaYBYn781aCYuFhp8LR23Ur eA1gUsYItjFkQ4pjgim630zfHgsURezaZlXDJ1lmwkmhHPNKuYV84UzKHSqpsPyK0knLruNGdZp Oim+4Hj6AaXXWguT5pA== X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfX05eO6Pw7BCas WPaAxFA7tyvwM1Rvo4XEHY2lzrqoo1ZnFAY/qnDPzNAKLSbFJZ1WUp/EgLL/XSzGSgY1mPuBnQ5 Nh8ukHUdCxa22wVgnlrTitppAueOnqY= X-Proofpoint-GUID: EVl5wyWfNJGUN9DBMCL0C7CQVSkIjFYT X-Proofpoint-ORIG-GUID: EVl5wyWfNJGUN9DBMCL0C7CQVSkIjFYT X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_03,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 suspectscore=0 spamscore=0 priorityscore=1501 bulkscore=0 adultscore=0 lowpriorityscore=0 phishscore=0 clxscore=1015 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110129 Add the Devicetree binding for the Qualcomm Audio Interface (QAIF) CPU DAI controller used on the Shikra audio platform, together with a dt-bindings header for QAIF DAI and AIF interface IDs. QAIF routes audio between system memory, external PCM/TDM/MI2S serial interfaces and the internal Bolero/WCD codec. Platform Devicetree files need a binding to describe the controller resources, DAI cells and per- interface AIF configuration, and named constants to avoid raw numeric IDs in sound-dai references and child-node reg values. Describe the MMIO region, interrupt, clocks, DMA IOMMU mapping and aif-interface child nodes required by the controller. Signed-off-by: Harendra Gautam --- .../bindings/sound/qcom,shikra-qaif-cpu.yaml | 305 +++++++++++++++++= ++++ include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h | 52 ++++ 2 files changed, 357 insertions(+) diff --git a/Documentation/devicetree/bindings/sound/qcom,shikra-qaif-cpu.y= aml b/Documentation/devicetree/bindings/sound/qcom,shikra-qaif-cpu.yaml new file mode 100644 index 000000000000..5cabbe54d6fd --- /dev/null +++ b/Documentation/devicetree/bindings/sound/qcom,shikra-qaif-cpu.yaml @@ -0,0 +1,305 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/qcom,shikra-qaif-cpu.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Qualcomm Audio Interface (QAIF) CPU DAI Controller + +maintainers: + - Harendra Gautam + +description: | + The Qualcomm Audio Interface (QAIF) is a fully configurable DMA-based + audio subsystem controller. It serialises and deserialises PCM audio + between system memory and external serial audio peripherals (PCM, TDM, + I2S, MI2S) through the AIF path, and transfers parallel audio between + memory and an internal WCD codec through the CIF path. + + AIF (Audio Interface): up to 13 multi-lane Unified Audio Interfaces, + each supporting up to 8 independent data lanes. Each lane is individually + configurable as TX (output/speaker) or RX (input/mic). All lanes of an + interface share a single bit clock and frame sync. Supported modes are + PCM (short/long sync), TDM, and MI2S (stereo/mono). Per-interface + configuration includes sync source (master/slave), sync mode, sync delay, + sync inversion, slot width (8/16/24/32-bit), sample width, active slot + masks (up to 32 slots), bits-per-lane frame size, lane enable/direction + masks, loopback, output-enable control, and full-cycle path support for + long chip-to-chip connections. + + CIF (Codec Interface): up to 10 RDDMA (playback) and 10 WRDMA (capture) + channels connecting to an internal codec over a parallel bus. Each chann= el + supports active-channel enable mask (up to 16 channels), frame-sync + selection, frame-sync delay, frame-sync output gating, dynamic clock + gating, and 16-bit packing/unpacking. + + Note on RX/TX naming convention: in QAIF, TX refers to the output + (speaker/playback) direction and RX refers to the input (mic/capture) + direction. This applies to both AIF lane directions and CIF slot/mask + properties. + + DMA engine: RDDMA fetches audio from DDR/TCM/LPM into a shared SRAM + latency buffer (SHRAM) and drains it to the interface. WRDMA collects + data from the interface into SHRAM and writes it to memory. Each DMA + owns a private SHRAM region defined by start address and length register= s. + Burst sizes of 1/2/4/8/16 beats (64-bit) are supported with up to 4 + outstanding transactions per DMA. Two QSB master ports (QXM0 for TCM, + QXM1 for DDR/LPM) provide the memory interface. + + Resources are partitioned among up to 5 Execution Engines (EEs) via + EE map registers. Each EE owns a set of DMAs, audio interfaces, and + interface groups, and receives its own independent interrupt output. + The interrupt hierarchy has a two-level structure: a summary register + identifies the event class (DMA period, underflow/overflow, error + response, audio interface underflow/overflow, group done, rate detector, + VFR), and per-resource status registers identify the specific channel. + + Interface grouping (bonding) allows up to 6 groups of audio and codec + interfaces to start synchronously and align their DMA period interrupts + within half a frame duration using the RDDMA padding feature. + + Two rate detector blocks measure the frequency of incoming frame sync or + word select signals and generate interrupts on rate change, undetected + rate, or sync timeout. + + Block diagram:: + + System Memory (DDR / LPM / TCM) + +---------------------------------+ + | Circular Buffers (ping-pong) | + +----------+----------+-----------+ + | ^ + 64-bit AXI 64-bit AXI + | | + +----------v----------+-----------+ + | QSB Master Ports | + | +----------+ +----------+ | + | | QXM0 | | QXM1 | | + | +----+-----+ +-----+----+ | + +-------|--------------|----------+ + | | + +-------v--------------v----------+ + | Shared RAM (SHRAM) | + | +------------+ +------------+ | + | | QXM0 Read | | QXM0 Write | | + | | SHRAM | | SHRAM | | + | +------------+ +------------+ | + | +------------+ +------------+ | + | | QXM1 Read | | QXM1 Write | | + | | SHRAM | | SHRAM | | + | +------------+ +------------+ | + +---+--------+--------+-------+---+ + | | | | + +---v--+ +--v---+ +--v---+ +-v----+ + |RDDMA | |RDDMA | |WRDMA | |WRDMA | + | AIF | | CIF | | AIF | | CIF | + |[0..n]| |[0..n]| |[0..n]| |[0..n]| + +--+---+ +--+---+ +--+---+ +-+----+ + | | ^ ^ + | TX | TX | RX | RX + v v | | + +--+--------------------+ +----+----------+ + | Unified Audio Intf | | Codec DMA | + | (AIF 0..12) | | Interface | + | | | (CIF) | + | AUD_INTFa block: | | | + | - Serializer (TX) | | RDDMA: DDR -> | + | - De-serializer (RX) | | internal | + | - Sync gen/detect | | codec | + | - Up to 8 data lanes | | WRDMA: codec | + | - PCM / TDM / MI2S | | -> DDR | + | - Near Pad Logic | | Up to 16 ch | + +--+--------------------+ +----+----------+ + | Lane 0..7 (TX/RX) | Parallel bus + | Bit clk + Frame sync | + Frame sync + v v + +--+--------+ +------+------+ + | External | | Internal | + | Serial | | Digital | + | Peripherals| | Codec | + | (PCM/TDM/ | | (Bolero/ | + | MI2S) | | WCD) | + +-----------+ +-------------+ + +allOf: + - $ref: dai-common.yaml# + +properties: + compatible: + const: qcom,shikra-qaif-cpu + + reg: + maxItems: 1 + description: QAIF core registers + + interrupts: + maxItems: 1 + description: + QAIF summary interrupt for this Execution Engine. Signals DMA period + completion, buffer underflow/overflow, error response, audio interfa= ce + underflow/overflow, interface-group done, rate detector and VFR even= ts. + + iommus: + maxItems: 1 + description: Phandle to apps_smmu node with sid mask + + dma-coherent: true + + clocks: + maxItems: 9 + + clock-names: + description: + Core clocks for register access and DMA, followed by one bit + clock per AIF interface. + items: + - const: lpass_config + - const: lpass_core_axim + - const: aud_dma + - const: aud_dma_mem + - const: bus + - const: aif_if0_ibit + - const: aif_if1_ibit + - const: aif_if2_ibit + - const: aif_if3_ibit + + '#sound-dai-cells': + const: 1 + + '#address-cells': + const: 1 + + '#size-cells': + const: 0 + +patternProperties: + '^aif@[0-9a-f]+$': + type: object + description: + QAIF AIF interface child node for PCM, TDM or MI2S configuration. + + properties: + reg: + maxItems: 1 + description: + DAI ID of the AIF interface (QAIF_MI2S_AIF* or QAIF_TDM_AIF*). + + dai-format: + description: Serial audio interface format (MI2S, TDM or PCM). + enum: [i2s, dsp_a, dsp_b] + + dai-tdm-slot-width: + $ref: /schemas/types.yaml#/definitions/uint32 + enum: [8, 16, 24, 32] + description: + Slot width in bits. + + dai-tdm-slot-num: + $ref: /schemas/types.yaml#/definitions/uint32 + description: + Number of slots per lane. + minimum: 1 + maximum: 32 + + dai-tdm-slot-rx-mask: + $ref: /schemas/types.yaml#/definitions/uint32-array + description: + Active RX slots, one entry per slot. A nonzero value marks the + slot as active. + minItems: 1 + maxItems: 32 + + dai-tdm-slot-tx-mask: + $ref: /schemas/types.yaml#/definitions/uint32-array + description: + Active TX slots, one entry per slot. A nonzero value marks the + slot as active. + minItems: 1 + maxItems: 32 + + qcom,qaif-aif-lane-map: + $ref: /schemas/types.yaml#/definitions/uint32-array + description: + Per-lane direction map, one entry per lane starting from lane 0. + Use 0 for TX (output/speaker) and 1 for RX (input/mic). + minItems: 1 + maxItems: 8 + items: + enum: [0, 1] + + required: + - reg + - dai-format + - qcom,qaif-aif-lane-map + + if: + properties: + dai-format: + enum: [dsp_a, dsp_b] + then: + required: + - dai-tdm-slot-width + - dai-tdm-slot-num + - dai-tdm-slot-rx-mask + - dai-tdm-slot-tx-mask + + additionalProperties: false + +required: + - compatible + - reg + - interrupts + - iommus + - clocks + - clock-names + - '#sound-dai-cells' + - '#address-cells' + - '#size-cells' + +unevaluatedProperties: false + +examples: + - | + #include + soc { + #address-cells =3D <2>; + #size-cells =3D <2>; + + qaif_cpu: audio-controller@a000000 { + compatible =3D "qcom,shikra-qaif-cpu"; + reg =3D <0x0 0x0a000000 0x0 0x20000>; + interrupts =3D ; + iommus =3D <&apps_smmu 0x1c0 0x0>; + clocks =3D <&gcc 213>, + <&gcc 214>, + <&audiocorecc 15>, + <&audiocorecc 17>, + <&audiocorecc 18>, + <&audiocorecc 5>, + <&audiocorecc 8>, + <&audiocorecc 11>, + <&audiocorecc 14>; + clock-names =3D "lpass_config", + "lpass_core_axim", + "aud_dma", + "aud_dma_mem", + "bus", + "aif_if0_ibit", + "aif_if1_ibit", + "aif_if2_ibit", + "aif_if3_ibit"; + #sound-dai-cells =3D <1>; + #address-cells =3D <1>; + #size-cells =3D <0>; + + aif@b5 { + reg =3D <181>; + dai-format =3D "dsp_a"; + dai-tdm-slot-width =3D <32>; + dai-tdm-slot-num =3D <2>; + dai-tdm-slot-rx-mask =3D <1 1>; + dai-tdm-slot-tx-mask =3D <1 1>; + qcom,qaif-aif-lane-map =3D <1 0>; + }; + }; + }; diff --git a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h b/include/d= t-bindings/sound/qcom,q6dsp-lpass-ports.h index 3a99703dbc4a..f08c20c84c60 100644 --- a/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h +++ b/include/dt-bindings/sound/qcom,q6dsp-lpass-ports.h @@ -156,6 +156,58 @@ #define LPI_MI2S_TX_5 150 #define LPI_MI2S_RX_6 151 #define LPI_MI2S_TX_6 152 +#define AIF_MI2S_RX_0 153 +#define AIF_MI2S_RX_1 154 +#define AIF_MI2S_RX_2 155 +#define AIF_MI2S_RX_3 156 +#define AIF_MI2S_RX_4 157 +#define AIF_MI2S_RX_5 158 +#define AIF_MI2S_RX_6 159 +#define AIF_MI2S_RX_7 160 +#define AIF_MI2S_RX_8 161 +#define AIF_MI2S_RX_9 162 +#define AIF_MI2S_RX_10 163 +#define AIF_MI2S_RX_11 164 +#define AIF_MI2S_RX_12 165 +#define AIF_MI2S_TX_0 166 +#define AIF_MI2S_TX_1 167 +#define AIF_MI2S_TX_2 168 +#define AIF_MI2S_TX_3 169 +#define AIF_MI2S_TX_4 170 +#define AIF_MI2S_TX_5 171 +#define AIF_MI2S_TX_6 172 +#define AIF_MI2S_TX_7 173 +#define AIF_MI2S_TX_8 174 +#define AIF_MI2S_TX_9 175 +#define AIF_MI2S_TX_10 176 +#define AIF_MI2S_TX_11 177 +#define AIF_MI2S_TX_12 178 +#define AIF_TDM_RX_0 179 +#define AIF_TDM_RX_1 180 +#define AIF_TDM_RX_2 181 +#define AIF_TDM_RX_3 182 +#define AIF_TDM_RX_4 183 +#define AIF_TDM_RX_5 184 +#define AIF_TDM_RX_6 185 +#define AIF_TDM_RX_7 186 +#define AIF_TDM_RX_8 187 +#define AIF_TDM_RX_9 188 +#define AIF_TDM_RX_10 189 +#define AIF_TDM_RX_11 190 +#define AIF_TDM_RX_12 191 +#define AIF_TDM_TX_0 192 +#define AIF_TDM_TX_1 193 +#define AIF_TDM_TX_2 194 +#define AIF_TDM_TX_3 195 +#define AIF_TDM_TX_4 196 +#define AIF_TDM_TX_5 197 +#define AIF_TDM_TX_6 198 +#define AIF_TDM_TX_7 199 +#define AIF_TDM_TX_8 200 +#define AIF_TDM_TX_9 201 +#define AIF_TDM_TX_10 202 +#define AIF_TDM_TX_11 203 +#define AIF_TDM_TX_12 204 =20 #define LPASS_CLK_ID_PRI_MI2S_IBIT 1 #define LPASS_CLK_ID_PRI_MI2S_EBIT 2 --=20 2.34.1 From nobody Fri Sep 25 14:31:50 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 65E8846C851; Fri, 11 Sep 2026 09:19:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118388; cv=none; b=ZI+412j5Vku97lL/mWNrppzcJkfPbX4ITc+PXxRtNH/1pi0UAkSZwn3oXh/luns4L7JKULi3IiO5BOMNIHwk+AW67tK2Z09QpQkCEwejVMGcqyXFzE3CtvwIUyh/l2wF3uXMmrIWE+oquWCb4THRJ4Y5DxRk4R22fWg++oaD8xs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118388; c=relaxed/simple; bh=4qNQGmtxGP6HcFjmT0kred7WeWsqs975pEc3HYi6gws=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=riBnICYIH6jWEv6f3647sgfeqS1JFgdb3ge2BJ0+pMfAtxkg83yqYLI81R8OPX5gkXXHwDn9NfNrIoTvKczs7D+toBmJMczAlXswGZH7f+BV3SPJQVP4stDO+jglN6fPo8LEDQZtIk7Mmvvu1Xls6BkTiy7/RKy47PfmwQwMEcE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=bG8vEoDP; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="bG8vEoDP" Received: from pps.filterd (m0279868.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B7kjIJ3366323; Fri, 11 Sep 2026 09:19:26 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= bPDdMJRpp7rphpfkWCRPY8Ty+fg05HAAzkXJjwRXaaM=; b=bG8vEoDPYFythJ14 Em71CblOeZ5BbPGGDhVf/3/CTonkPb4uChxI17YZcfSSEZvZX1gssGBWY25Wm9g7 3s6bc2YNJbqAXdcPPtFnVWjqRYBEL66I5rD17HIuD7T/XmXGdJI5plDIRXD1S4D2 s4kXOuGjxwCqN9prHnGfvHb+gHQIaFWrropc+xZ6fsReBl5fAKk9UZxXqa/ql1qR JOxpp/Q+eK36Lwah0LL8lBdArq/D/+6VNbHeM3j6RHD2+VhqJWLpHD7t/KxrlKaT l/83wvn0x+ugskdTLeARF8KJEj6FgVITC/bHKnfx4swgftkx5y5q+oq8hiRnIIyr Fu8OfA== Received: from apblrppmta02.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gm1k2b39t-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 09:19:25 +0000 (GMT) Received: from pps.filterd (apblrppmta02.qualcomm.com [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B9JN4N2870856; Fri, 11 Sep 2026 09:19:23 GMT Received: from hu-hgautam-hyd.qualcomm.com (hu-hgautam-hyd.qualcomm.com [10.147.247.91]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTP id 68B9JL2Y2870824; Fri, 11 Sep 2026 09:19:22 +0000 (GMT) From: Harendra Gautam Date: Fri, 11 Sep 2026 14:47:26 +0530 Subject: [PATCH v6 02/10] ASoC: qcom: Add QAIF shared data structures and variant interface Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260911-b4-qaif-shikra-audio-v6-2-e9addb358201@oss.qualcomm.com> References: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> In-Reply-To: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> To: Srinivas Kandagatla Cc: Mark Brown , Liam Girdwood , Rob Herring , Krzysztof Kozlowski , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai , Kuninori Morimoto , linux-sound@vger.kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Prasad Kumpatla , Krzysztof Kozlowski , Sarath Ganapathiraju , Kumar Anurag Singh , Mohammad Rafi Shaik , Harendra Gautam X-Mailer: b4 0.15.2 X-Proofpoint-Reinject: loops=2 maxloops=12 X-QCInternal: smtphost X-QCInternal: smtphost X-Authority-Analysis: v=2.4 cv=cM11IVeN c=1 sm=1 tr=0 ts=6aa3c79d cx=c_pps a=Ou0eQOY4+eZoSc0qltEV5Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=ZpdpYltYx_vBUK5n70dp:22 a=EUspDBNiAAAA:8 a=8qrotg54OhH-pQjW1TwA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-GUID: vCrDdlpdRb3mNEefa8whZWcnSo9ltfme X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfXySvJPsjYvp1c D+VIV++Vqnu6pgy7u0JCwEhaNvGP+bUG2Lol4Oq4vDsiSU6P6NMYFazLSJ2ZJ08kYZMl9fTtgoO h0JHVmWVpQD5IBum9fBiCskz+E+BAJQ= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfX6lpcs1+DXqmQ ffQClq1EeXNQSXQAUUqlakvbcEfbx+6Og3eIlRp7CENXEsITdqRfFkTCpgQpX4wLVef3pUCunFj hIc6YlAVvo+6+9YncuWtg1TdjyLc0U9KvEU8B474vNNioqE8jINctwwPL8Tph405WwEXm1LRxZ8 kfFjWQMtfIK0Ofh0+VGiKDgWAbAYH5vOHY7pnUIYmYxXmqkx+u3aUkpJijE6q/Qa6IdchXCnH7w YTcZ30CVBPpinbfKYrTXrWAJRBoUkJtRp2SZSLjMuZU3GCGhfHbWTP3kbEuQQLkPh3dTm2SFCU6 sDMcYq1yIkR+v7cxBIW9u5LVzkVzXaOQ9pUb+vEZDnpyAaR0bi6yL8miFLggtVL8k5Ui+gpJNuq KSJhIpgsRyrsoe3nEg4Rv8VPh7/PkBI9hCrswtjZxt7SbfCa6FjEzrIraW5cq8qnFmZpeT8hD4d rIsCje514yMRoHIsqtg== X-Proofpoint-ORIG-GUID: vCrDdlpdRb3mNEefa8whZWcnSo9ltfme X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_03,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 lowpriorityscore=0 clxscore=1015 adultscore=0 bulkscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 spamscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110129 Add qaif.h to hold common definitions shared by the QAIF CPU DAI and PCM platform drivers. Also update LPASS_MAX_PORT in common.h to cover the newly added QAIF DAI ID range. QAIF exposes AIF DMA paths for external audio interfaces and CIF DMA paths for the internal codec interface. The two drivers need a common place to describe DMA channel allocation, regmap fields, interrupt dispatch, SHRAM buffer tracking and per-stream runtime data. Introduce the QAIF driver data, AIF and CIF register-field descriptions, IRQ mapping helpers and SoC variant descriptor. The variant descriptor describes the register layout, DMA channel counts, clock names, DAI table and platform callbacks used by the QAIF driver code. Signed-off-by: Harendra Gautam --- sound/soc/qcom/common.h | 3 +- sound/soc/qcom/qaif.h | 302 ++++++++++++++++++++++++++++++++++++++++++++= ++++ 2 files changed, 304 insertions(+), 1 deletion(-) diff --git a/sound/soc/qcom/common.h b/sound/soc/qcom/common.h index c1deac109f24..3bc45fcfc62e 100644 --- a/sound/soc/qcom/common.h +++ b/sound/soc/qcom/common.h @@ -5,9 +5,10 @@ #define __QCOM_SND_COMMON_H__ =20 #include +#include #include =20 -#define LPASS_MAX_PORT (LPI_MI2S_TX_6 + 1) +#define LPASS_MAX_PORT (AIF_TDM_TX_12 + 1) =20 struct qcom_snd_tdm_slot_cfg { unsigned int tx_mask; diff --git a/sound/soc/qcom/qaif.h b/sound/soc/qcom/qaif.h new file mode 100644 index 000000000000..ba02784771a2 --- /dev/null +++ b/sound/soc/qcom/qaif.h @@ -0,0 +1,302 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + */ + +#ifndef SND_SOC_QCOM_QAIF_H +#define SND_SOC_QCOM_QAIF_H + +#include +#include +#include +#include +#include +#include +#include +#include + +struct snd_pcm_substream; +struct snd_soc_dai_driver; +struct snd_soc_dai_ops; +struct platform_device; + +#define QAIF_CIF_DMA_INTF_ONE_CHANNEL 0x01 +#define QAIF_CIF_DMA_INTF_TWO_CHANNEL 0x03 +#define QAIF_CIF_DMA_INTF_FOUR_CHANNEL 0x0f +#define QAIF_CIF_DMA_INTF_SIX_CHANNEL 0x3f +#define QAIF_CIF_DMA_INTF_EIGHT_CHANNEL 0xff + +#define QAIF_AIF_SLOT_WIDTH(bits) ((bits) - 1) +#define QAIF_AIF_SAMPLE_WIDTH(bits) ((bits) - 1) + +/* Watermark level 5 encoded as N-1: hardware field value =3D watermark - = 1 */ +#define QAIF_DMACTL_WM_5 4 + +#define QAIF_DMA_BYTES_TO_WORDS_SHIFT 3 +#define QAIF_DMA_CLOCK_FREQ 38400000 + +#define QAIF_MAX_AIF_CFG_CNT 4 +#define QAIF_MAX_LANES 8 + +#define QAIF_MAX_MI2S_PORTS 8 +#define QAIF_MI2S_SLOTS 2 +#define QAIF_MAX_AIF_DMA_IDX 8 +#define QAIF_MAX_CIF_DMA_IDX 8 + +/* SID map register CSID field (WRDMA_SID/RDDMA_SID), bits [4:0] */ +#define QAIF_CSID_MASK GENMASK(4, 0) + +static inline bool qaif_is_aif_mi2s_port(unsigned int dai_id) +{ + return (dai_id >=3D AIF_MI2S_RX_0 && dai_id <=3D AIF_MI2S_RX_12) || + (dai_id >=3D AIF_MI2S_TX_0 && dai_id <=3D AIF_MI2S_TX_12); +} + +static inline bool qaif_is_aif_tdm_port(unsigned int dai_id) +{ + return (dai_id >=3D AIF_TDM_RX_0 && dai_id <=3D AIF_TDM_RX_12) || + (dai_id >=3D AIF_TDM_TX_0 && dai_id <=3D AIF_TDM_TX_12); +} + +static inline bool qaif_is_aif_port(unsigned int dai_id) +{ + return qaif_is_aif_mi2s_port(dai_id) || qaif_is_aif_tdm_port(dai_id); +} + +static inline bool qaif_is_cif_port(unsigned int dai_id) +{ + return (dai_id >=3D WSA_CODEC_DMA_RX_0 && dai_id <=3D RX_CODEC_DMA_RX_7); +} + +enum qxm_sel { + QAIF_QXM0 =3D 0, + QAIF_QXM1 =3D 1, +}; + +enum qaif_irq_type { + QAIF_AIF_IRQ =3D 0, + QAIF_CIF_IRQ =3D 1, + QAIF_IRQ_TYPE_MAX, +}; + +enum qaif_dma_type { + QAIF_AIF_DMA =3D 0, + QAIF_CIF_DMA =3D 1, +}; + +struct qaif_aif_config { + u32 sync_mode; + u32 sync_src; + bool invert_sync; + u32 sync_delay; + u32 slot_width; + u32 slot_en_rx_mask; + u32 slot_en_tx_mask; + bool loopback_en; + bool ctrl_data_oe; + u32 lane_en_mask; + u32 lane_dir_mask; + bool full_cycle_en; + u32 slot_num; +}; + +struct qaif_pcm_data { + /* Flat slot in aif_substream[]/aif_dma_heap[] (or cif_*) used to track + * this stream. Direction-encoded: playback uses the raw DMA channel + * number (0..num_rddma-1), capture adds wrdma_start so playback and + * capture of the same DAI occupy distinct slots. + * Set by alloc_stream_dma_idx(); bounded by QAIF_MAX_AIF/CIF_DMA_IDX. + */ + int stream_dma_idx; + /* Hardware channel number (0-based within its DMA bank) passed to + * register address helpers (e.g. QAIF_RDDMA_CFG_REG(v, chan)). + * Direction-agnostic: the register helpers select RDDMA or WRDMA bank + * based on stream direction, so both directions of the same DAI share + * the same value. Set by get_dma_idx(). + */ + int dma_reg_idx; +}; + +/* Named 0-based DMA channel indices used as the dma_idx of a + * qaif_dmaidx_dai_map entry, so board tables reference channels by name. + */ +enum qaif_dma_idx { + QAIF_DMA_IDX0 =3D 0, + QAIF_DMA_IDX1, + QAIF_DMA_IDX2, + QAIF_DMA_IDX3, + QAIF_DMA_IDX4, + QAIF_DMA_IDX5, + QAIF_DMA_IDX6, + QAIF_DMA_IDX7, +}; + +/* Associates a DAI ID with its physical DMA channel index on a given + * board/variant. @dai_id is the DAI to match; @dma_idx (a qaif_dma_idx va= lue) + * is the 0-based hardware channel that get_dma_idx() returns for it. + */ +struct qaif_dmaidx_dai_map { + unsigned int dai_id; + int dma_idx; +}; + +struct qaif_dma_mem_info { + dma_addr_t dma_addr; + size_t alloc_size; + void *vaddr; +}; + +struct qaif_drv_data { + struct clk *mi2s_bit_clk[QAIF_MAX_MI2S_PORTS]; + struct clk_bulk_data *clks; + int num_clks; + struct clk *aud_dma_clk; + struct clk *aud_dma_mem_clk; + void __iomem *audio_qaif; + struct regmap *audio_qaif_map; + int audio_qaif_irq; + struct mutex stream_lock; /* serializes stream open/close */ + bool qaif_hw_configured; + const struct qaif_variant *variant; + struct qaif_aif_config aif_intf_cfg[QAIF_MAX_AIF_CFG_CNT]; + unsigned long aif_dma_idx_bit_map; + unsigned long cif_dma_idx_bit_map; + struct snd_pcm_substream *aif_substream[QAIF_MAX_AIF_DMA_IDX]; + struct snd_pcm_substream *cif_substream[QAIF_MAX_CIF_DMA_IDX]; + u32 smmu_csid_bits; /* SMMU stream ID bits from DT iommus cell */ + struct qaif_dma_mem_info *aif_dma_heap[QAIF_MAX_AIF_DMA_IDX]; + struct qaif_dma_mem_info *cif_dma_heap[QAIF_MAX_CIF_DMA_IDX]; +}; + +enum qaif_summary_irq_bitmask { + QAIF_SUMMARY_BITMASK_AIF_PERIOD_RDDMA =3D BIT(0), + QAIF_SUMMARY_BITMASK_AIF_UNDERFLOW_RDDMA =3D BIT(1), + QAIF_SUMMARY_BITMASK_AIF_ERR_RSP_RDDMA =3D BIT(2), + QAIF_SUMMARY_BITMASK_AIF_PERIOD_WRDMA =3D BIT(3), + QAIF_SUMMARY_BITMASK_AIF_OVERFLOW_WRDMA =3D BIT(4), + QAIF_SUMMARY_BITMASK_AIF_ERR_RSP_WRDMA =3D BIT(5), + QAIF_SUMMARY_BITMASK_CIF_PERIOD_RDDMA =3D BIT(18), + QAIF_SUMMARY_BITMASK_CIF_UNDERFLOW_RDDMA =3D BIT(19), + QAIF_SUMMARY_BITMASK_CIF_ERR_RSP_RDDMA =3D BIT(20), + QAIF_SUMMARY_BITMASK_CIF_PERIOD_WRDMA =3D BIT(24), + QAIF_SUMMARY_BITMASK_CIF_OVERFLOW_WRDMA =3D BIT(25), + QAIF_SUMMARY_BITMASK_CIF_ERR_RSP_WRDMA =3D BIT(26), +}; + +enum qaif_client_status_register_bitmask_info { + QAIF_BITMASK_AIF_RDDMA_WRDMA =3D GENMASK(5, 0), + QAIF_BITMASK_CIF_RDDMA_WRDMA =3D GENMASK(26, 18), +}; + +struct qaif_irq_map { + u32 client_id; + u32 mask; + /* + * Called from the hard IRQ handler (asoc_platform_qaif_irq()) with + * @status holding the summary interrupt status. Must not sleep. + */ + irqreturn_t (*client_irq_handler)(struct qaif_drv_data *drvdata, u32 stat= us); +}; + +enum qaif_dma_dir { + QAIF_DMA_RDDMA =3D 0, + QAIF_DMA_WRDMA =3D 1, +}; + +enum qaif_irq { + QAIF_IRQ_PERIOD =3D 0, + QAIF_IRQ_OVERFLOW, + QAIF_IRQ_UNDERFLOW, + QAIF_IRQ_ERROR, +}; + +enum qaif_irq_op { + QAIF_IRQ_CLEAR =3D 0, + QAIF_IRQ_ENABLE, + QAIF_IRQ_DISABLE, +}; + +enum qaif_client_info { + QAIF_CLIENT_ID_AIF_DMA =3D 0, + QAIF_CLIENT_ID_CIF_DMA, +}; + +struct qaif_variant { + u32 ee; /* Hardware EE index assigned to this driver instance */ + + u32 num_rddma; + u32 num_wrdma; + u32 wrdma_start; + u32 num_codec_rddma; + u32 num_codec_wrdma; + u32 codec_wrdma_start; + u32 num_intf; + + u32 rddma_reg_base; + u32 rddma_stride; + u32 codec_rddma_reg_base; + u32 codec_rddma_stride; + u32 wrdma_reg_base; + u32 wrdma_stride; + u32 codec_wrdma_reg_base; + u32 codec_wrdma_stride; + + u32 rddma_irq_reg_base; + u32 rddma_irq_stride; + u32 codec_rddma_irq_reg_base; + u32 codec_rddma_irq_stride; + u32 wrdma_irq_reg_base; + u32 wrdma_irq_stride; + u32 codec_wrdma_irq_reg_base; + u32 codec_wrdma_irq_stride; + + /* QSB master port selector; only QAIF_QXM0 is supported today */ + enum qxm_sel qxm_type; + /* All *_len values below are SHRAM sizes in 64-bit words */ + u32 rd_len; + u32 rddma_shram_len; + /* SHRAM start offsets (in 64-bit words), indexed by enum qaif_dma_type */ + u32 rddma_shram_start_addr[2]; + u32 wr_len; + u32 wrdma_shram_len; + u32 wrdma_shram_start_addr[2]; + + const char * const *clk_name; + int num_clks; + struct snd_soc_dai_driver *dai_driver; + int num_dai; + const char * const *dai_bit_clk_names; + /* + * Optional per-AIF configuration tables, indexed by AIF interface + * index (0..num_intf-1). NULL if the variant does not use them. + */ + const bool *aif_full_cycle_en; + const bool *aif_ctrl_data_oe; + const bool *aif_loopback_en; + + /* Returns a direction-encoded flat slot index for use in + * aif_substream[]/cif_substream[] and the dma_idx_bit_map. + * Playback returns the raw channel number; capture adds wrdma_start (or + * codec_wrdma_start) so both directions of the same DAI get distinct + * slots. Sets the corresponding bit atomically; returns -EBUSY if + * already open, -EINVAL if @dai_id or the computed index is out of range. + */ + int (*alloc_stream_dma_idx)(struct qaif_drv_data *data, int direction, + unsigned int dai_id); + /* Clears the bit set by alloc_stream_dma_idx. */ + int (*free_stream_dma_idx)(struct qaif_drv_data *data, int chan, + unsigned int dai_id); + /* Returns the hardware channel number (0-based within its DMA bank) + * for @dai_id, direction-agnostic. Used as dma_reg_idx. + */ + int (*get_dma_idx)(unsigned int dai_id); +}; + +extern const struct snd_soc_dai_ops asoc_qcom_qaif_cif_dai_ops; +extern const struct snd_soc_dai_ops asoc_qcom_qaif_aif_cpu_dai_ops; + +int asoc_qcom_qaif_cpu_platform_probe(struct platform_device *pdev); +int asoc_qcom_qaif_platform_register(struct platform_device *pdev); +extern const struct dev_pm_ops asoc_qcom_qaif_pm_ops; + +#endif /* SND_SOC_QCOM_QAIF_H */ --=20 2.34.1 From nobody Fri Sep 25 14:31:50 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 9707C46C4A9; Fri, 11 Sep 2026 09:19:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118390; cv=none; b=n6B98Nv1L1l1Y+BNvHdkFiAysMlhm6Kf4bTOAfc63H28+7CCUhhRUaYZramxC5QwinecPZdOM4scLs70WMY1o5E1xRDWFJ5uNPxWRGr92eD588YL3rxIsY4dDKTROrieQmNV+2ZaghQ+cDpvLGttIHSsO0g7A1WSf0axKwEcFG4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118390; c=relaxed/simple; bh=U0Dg99fWF7AT9aItfQcYBJZ86YlsjcK8bawXg5YGUYE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=Je3T5OJqXrp+Tccy4fcpZJLUQpdloPexuNfIwRCIJ250qO5qxcUJdRNAYZFvHhP+gx/+yq6JWTSu8/hKrFKmVubepcvLnK0wVzTqidqzUGyFoN/wmqQXZS5tRUsusmRUBRYGsW3C8MtWwxQcwoKUuUCKrg/gxDN5YLrtDPqHWu0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=SO+BRljL; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="SO+BRljL" Received: from pps.filterd (m0279869.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B7ksfG3845486; Fri, 11 Sep 2026 09:19:26 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= gUslnKoBPEF2R1OEVgh0jKwJivhbzqr7hfr3N3ZyE7s=; b=SO+BRljLbFQTOFql eN50jW1rdt2c4xBF04kvg5+JnGMvcyoMW+agjtpSGltSQO6TvnTlQbLB8QRusSkW B+oDUPkscFmM8u7WHm2b7M5Qqlcn8roaJdJpd/XXTXXnbnyoMgY3I1AxcWD/zwda lftaJgV11Ms9rE8zmS5QGul4ybyQBY5apFxyerQw46yk1/ujriCm1AMOOhG8KoBk jfiyKdQ8wRqOvQhYJRvzJszgDtgzDh0i7d9E8p05icUBcPA0NzMk7NFt/CBrGJ2N pXaq8eGp7dEeu8LFCe6TQYWdv5ULCVTlDJaAXH63PdsVm6Lb5iZWKkTrFIntn0+7 AJumZw== Received: from apblrppmta02.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gm5q424jy-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 09:19:25 +0000 (GMT) Received: from pps.filterd (apblrppmta02.qualcomm.com [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B9JNKc2870867; Fri, 11 Sep 2026 09:19:23 GMT Received: from hu-hgautam-hyd.qualcomm.com (hu-hgautam-hyd.qualcomm.com [10.147.247.91]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTP id 68B9JL2Z2870824; Fri, 11 Sep 2026 09:19:23 +0000 (GMT) From: Harendra Gautam Date: Fri, 11 Sep 2026 14:47:27 +0530 Subject: [PATCH v6 03/10] ASoC: qcom: Add QAIF hardware register map Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260911-b4-qaif-shikra-audio-v6-3-e9addb358201@oss.qualcomm.com> References: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> In-Reply-To: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> To: Srinivas Kandagatla Cc: Mark Brown , Liam Girdwood , Rob Herring , Krzysztof Kozlowski , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai , Kuninori Morimoto , linux-sound@vger.kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Prasad Kumpatla , Krzysztof Kozlowski , Sarath Ganapathiraju , Kumar Anurag Singh , Mohammad Rafi Shaik , Harendra Gautam X-Mailer: b4 0.15.2 X-Proofpoint-Reinject: loops=2 maxloops=12 X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-GUID: N0BgHJV5jdCFSbNRL4wstqr29nv22N37 X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfX/020YFeEiC/M HZFUycGVy4MDdzAyJC/loSzkfYPE1+k1lUVF8phJ4JtT9Y4IjmwOraDc0VGGHd8FQ0uONHuD/hi XHRcFoCufa4vIec7F5Xt2JPK6uJAXJw= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfX1yuDOMMCjIvo AtWaS7KsT12nSn3c7U0iyw/bkc1AQ06814psmyPYD7SGfbk2pESuO06Y4/jkBsK06rpeGLlvVzC DAFOqK09ts0kpJK2ztMxKKrE4czYYdsGzjd2S4K0vBZ3L05IyyI0sZyb9muS1wbBL2YCGC2HEbL v6IcYlwmlDLPhodn45DEqntqdGlaepCfgG1X5a0r/Uh8H4OUuQJVllnrJTm4jEiyo51eH8XI0/e 3GLsgA3J3uwiOSiuCKPrPlRHaDX9UGbaEsNH3cLH6YnsHzJsDUgNKwGBBvCvtqAI6OhoA5SmhKe FV+jkhyGJ6+lpWWqpd0QC4oX7iv6bbb4X2JuikFFrBiEApCAv4bu4tdDvPVgu5Ke1kgv7O95h+Q 1qRdjveD0jzx5JIhoOyjIrY+PI22asT2llCgPZPeQsoZQCDKwz8DwE8ybSvEERJjBXaiTkHaMIP x3z6BEuXUCfKJzHYT4w== X-Proofpoint-ORIG-GUID: N0BgHJV5jdCFSbNRL4wstqr29nv22N37 X-Authority-Analysis: v=2.4 cv=Wsa+otfv c=1 sm=1 tr=0 ts=6aa3c79e cx=c_pps a=Ou0eQOY4+eZoSc0qltEV5Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=_glEPmIy2e8OvE2BGh3C:22 a=EUspDBNiAAAA:8 a=lZfL7hTs5R9vjdWfsbYA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_03,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 lowpriorityscore=0 priorityscore=1501 suspectscore=0 spamscore=0 bulkscore=0 impostorscore=0 clxscore=1015 adultscore=0 phishscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110129 Add qaif-reg.h to define the MMIO register offsets for the Qualcomm Audio Interface (QAIF) hardware block. The QAIF driver needs a common register map to program the core registers, audio interfaces, AIF/CIF DMA channels, interrupt registers, SHRAM/QXM routing, and SID maps. Add accessor helpers so the driver can select the proper AIF or CIF DMA register set based on the DAI ID. Signed-off-by: Harendra Gautam --- sound/soc/qcom/qaif-reg.h | 458 ++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 458 insertions(+) diff --git a/sound/soc/qcom/qaif-reg.h b/sound/soc/qcom/qaif-reg.h new file mode 100644 index 000000000000..84a9c0285289 --- /dev/null +++ b/sound/soc/qcom/qaif-reg.h @@ -0,0 +1,458 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * qaif-reg.h -- QAIF ALSA SoC CPU-Platform DAI driver register header + */ +#ifndef SND_SOC_QCOM_QAIF_REG_H +#define SND_SOC_QCOM_QAIF_REG_H + +#include "qaif.h" + +#define QAIF_SUMMARY_IRQSTAT_REG(v) (0x19188 + (0x1000 * ((v)->ee))) + +/* Core HW info */ +#define QAIF_HW_VERSION_REG (0x0000) +#define QAIF_HW_INFO_REG (0x0004) +#define QAIF_HW_INFO2_REG (0x0008) + +/* Interface lane and channel info */ +#define QAIF_AUD_INTF_LANE_INFO_REG (0x0020) +#define QAIF_AUD_INTF_LANE_INFO2_REG (0x0024) +#define QAIF_CDC_TX_INTF_CH_INFO_REG(n) (0x0028 + (0x4 * (n))) +#define QAIF_CDC_RX_INTF_CH_INFO_REG(n) (0x0068 + (0x4 * (n))) +#define QAIF_QXM1_SHRAM_LENGTH_INFO_REG (0x0088) +#define QAIF_QXM0_SHRAM_LENGTH_INFO_REG (0x008C) +#define QAIF_NUM_AUD_INTF_TO_RAIL_INFO_REG (0x0090) + +/* Debug/control and status */ +#define QAIF_DEBUG_CTL_REG (0x0200) +#define QAIF_WRDMA_LOOPBACK_EN_REG (0x0204) +#define QAIF_WRDMA_LOOPBACK_SEL_REG (0x0208) +#define QAIF_SHRAM_DYNAMIC_CLK_GATING_EN_REG (0x0300) +#define QAIF_AXI_STATUS_REG (0x0304) +#define QAIF_QSB_DYNAMIC_CLK_GATING_EN_REG (0x0308) +#define QAIF_START_STOP_CTRL_BYPASS_EN_REG (0x030C) +#define QAIF_QXM0_AXI_ATTR_CFG_REG (0x040C) + +/* QXM request/grant debug */ +#define QAIF_QXM0_AUD_WR_REQ_GNT_DBG_STAT_REG (0x0500) +#define QAIF_QXM1_AUD_WR_REQ_GNT_DBG_STAT_REG (0x0504) +#define QAIF_QXM0_CODEC_RX_WR_REQ_DBG_STAT_REG (0x0508) +#define QAIF_QXM0_CODEC_RX_WR_GNT_DBG_STAT_REG (0x050C) +#define QAIF_QXM1_CODEC_RX_WR_REQ_DBG_STAT_REG (0x0510) +#define QAIF_QXM1_CODEC_RX_WR_GNT_DBG_STAT_REG (0x0514) +#define QAIF_QXM0_AUD_RD_REQ_GNT_DBG_STAT_REG (0x0518) +#define QAIF_QXM1_AUD_RD_REQ_GNT_DBG_STAT_REG (0x051C) +#define QAIF_QXM0_CODEC_TX_RD_REQ_DBG_STAT_REG (0x0520) +#define QAIF_QXM0_CODEC_TX_RD_GNT_DBG_STAT_REG (0x0524) +#define QAIF_QXM1_CODEC_TX_RD_REQ_DBG_STAT_REG (0x0528) +#define QAIF_QXM1_CODEC_TX_RD_GNT_DBG_STAT_REG (0x052C) +#define QAIF_QXM0_EXT_RDDMA_RD_REQ_GNT_DBG_STAT_REG (0x0530) +#define QAIF_QXM1_EXT_RDDMA_RD_REQ_GNT_DBG_STAT_REG (0x0534) + +/* QSB transaction debug */ +#define QAIF_QSB_AUD_WR_TXN_DBG_STAT_REG (0x0538) +#define QAIF_QSB_CODEC_RX_WR_TXN_ERR_DBG_STAT_REG (0x053C) +#define QAIF_QSB_CODEC_RX_WR_TXN_OKAY_DBG_STAT_REG (0x0540) +#define QAIF_QSB_AUD_ADDR_SENT_DBG_STAT_REG (0x0544) +#define QAIF_QSB_CODEC_TX_RD_ADDR_SENT_DBG_STAT_REG (0x0548) +#define QAIF_QSB_EXT_RDDMA_RD_ADDR_SENT_DBG_STAT_REG (0x054C) +#define QAIF_QSB_CODEC_RX_WR_ADDR_SENT_DBG_STAT_REG (0x0550) +#define QAIF_QSB_AUD_RD_TXN_DBG_STAT_REG (0x0554) +#define QAIF_QSB_CODEC_TX_RD_TXN_ERR_DBG_STAT_REG (0x0558) +#define QAIF_QSB_CODEC_TX_RD_TXN_RCVD_DBG_STAT_REG (0x055C) +#define QAIF_QSB_EXT_RDDMA_RD_TXN_DBG_STAT_REG (0x0560) +#define QAIF_QSB_MISC_DBG_STATUS_REG (0x0564) + +/* Global spare and HWE */ +#define QAIF_GLOBAL_SPARE_IN_REG (0x0B00) +#define QAIF_GLOBAL_SPARE_OUT_REG (0x0B04) +#define QAIF_HWE_CFG_REG (0x0B08) + +/* SID maps */ +#define QAIF_WRDMA_SID_MAP_REG (0x1B00) +#define QAIF_CDC_WRDMA_SID_MAP_REG (0x1B40) +#define QAIF_RDDMA_SID_MAP_REG (0x1C00) +#define QAIF_CDC_RDDMA_SID_MAP_REG (0x1C40) + +/* EE overlap interrupts */ +#define QAIF_EE_OVERLAP_IRQ_EN_REG (0x1D00) +#define QAIF_EE_OVERLAP_IRQ_RAW_STATUS_REG (0x1D04) +#define QAIF_EE_OVERLAP_IRQ_CLEAR_REG (0x1D08) +#define QAIF_EE_OVERLAP_IRQ_FORCE_REG (0x1D0C) + +/* + * EE (Execution Engine) assignment and map registers. + * + * The EE offset (v->ee) is an address/index offset relative to the + * platform-defined QAIF/EE base and lets the hardware route the AIF + * operation to the correct EE context. It is hardware/platform-specific a= nd + * must match the mapping defined for the selected QAIF AIF/lane in the + * hardware programming guide. It is not a runtime data offset and must not + * be changed based on the stream configuration. + */ +#define QAIF_EE_RDDMA_ASSIGNMENT_REG(v) (0x19148 + (0x1000 * ((v)->ee))) +#define QAIF_EE_WRDMA_ASSIGNMENT_REG(v) (0x19150 + (0x1000 * ((v)->ee))) +#define QAIF_EE_INTF_ASSIGNMENT_REG(v) (0x19158 + (0x1000 * ((v)->ee))) +#define QAIF_EE_CODEC_RDDMA_ASSIGN_REG(v) (0x19308 + (0x1000 * ((v)->ee))) +#define QAIF_EE_CODEC_WRDMA_ASSIGN_REG(v) (0x19318 + (0x1000 * ((v)->ee))) +#define QAIF_EE_RDDMA_MAP_REG(v) (0x1920 + (0x1000 * ((v)->ee))) +#define QAIF_EE_WRDMA_MAP_REG(v) (0x1940 + (0x1000 * ((v)->ee))) +#define QAIF_EE_INTF_MAP_REG(v) (0x1960 + (0x1000 * ((v)->ee))) +#define QAIF_EE_CODEC_RDDMA_MAP_REG(v) (0x1980 + (0x1000 * ((v)->ee))) +#define QAIF_EE_CODEC_WRDMA_MAP_REG(v) (0x1A00 + (0x1000 * ((v)->ee))) + +/* EE rate-detection and VFR interrupts */ +#define QAIF_EE_RATE_DET_IRQ_EN_REG(v) (0x190F0 + (0x1000 * ((v)->ee))) +#define QAIF_EE_RATE_DET_IRQ_STAT_REG(v) (0x190F4 + (0x1000 * ((v)->ee))) +#define QAIF_EE_RATE_DET_IRQ_RAW_STAT_REG(v) (0x190F8 + (0x1000 * ((v)->e= e))) +#define QAIF_EE_RATE_DET_IRQ_CLEAR_REG(v) (0x190FC + (0x1000 * ((v)->ee))) +#define QAIF_EE_RATE_DET_IRQ_FORCE_REG(v) (0x19100 + (0x1000 * ((v)->ee))) + +#define QAIF_EE_VFR_IRQ_EN_REG(v) (0x19104 + (0x1000 * ((v)->ee))) +#define QAIF_EE_VFR_IRQ_STATUS_REG(v) (0x19108 + (0x1000 * ((v)->ee))) +#define QAIF_EE_VFR_IRQ_RAW_STATUS_REG(v) (0x1910C + (0x1000 * ((v)->ee))) +#define QAIF_EE_VFR_IRQ_CLEAR_REG(v) (0x19110 + (0x1000 * ((v)->ee))) +#define QAIF_EE_VFR_IRQ_FORCE_REG(v) (0x19114 + (0x1000 * ((v)->ee))) + +/* EE AUD_INTF underflow/overflow interrupts */ +#define QAIF_EE_AUD_INTF_UF_IRQ_EN_REG(v) (0x19160 + (0x1000 * ((v)->ee))) +#define QAIF_EE_AUD_INTF_UF_IRQ_STAT_REG(v) (0x19164 + (0x1000 * ((v)->ee= ))) +#define QAIF_EE_AUD_INTF_UF_IRQ_RAW_STAT_REG(v) (0x19168 + (0x1000 * ((v)= ->ee))) +#define QAIF_EE_AUD_INTF_UF_IRQ_CLEAR_REG(v) (0x1916C + (0x1000 * ((v)->e= e))) +#define QAIF_EE_AUD_INTF_UF_IRQ_FORCE_REG(v) (0x19170 + (0x1000 * ((v)->e= e))) + +#define QAIF_EE_AUD_INTF_OF_IRQ_EN_REG(v) (0x19174 + (0x1000 * ((v)->ee))) +#define QAIF_EE_AUD_INTF_OF_IRQ_STAT_REG(v) (0x19178 + (0x1000 * ((v)->ee= ))) +#define QAIF_EE_AUD_INTF_OF_IRQ_RAW_STAT_REG(v) (0x1917C + (0x1000 * ((v)= ->ee))) +#define QAIF_EE_AUD_INTF_OF_IRQ_CLEAR_REG(v) (0x19180 + (0x1000 * ((v)->e= e))) +#define QAIF_EE_AUD_INTF_OF_IRQ_FORCE_REG(v) (0x19184 + (0x1000 * ((v)->e= e))) + +/* EE L2 Period IRQ mux selection */ +#define QAIF_EE_L2_PERIOD_IRQ_0_3_MUX_SEL_REG(v) (0x19F00 + (0x1000 * ((v)= ->ee))) +#define QAIF_EE_L2_PERIOD_IRQ_4_7_MUX_SEL_REG(v) (0x19F04 + (0x1000 * ((v)= ->ee))) + +/* AUD_INTF block (per interface, stride 0x1000 starting at 0x4000) */ +#define QAIF_AUD_INTF_REG_ADDR(offset, i) (0x4000 + (offset) + (0x1000 * = (i))) + +#define QAIF_AUD_INTF_CTL_REG(i) QAIF_AUD_INTF_REG_ADDR(0x0000, (i)) +#define QAIF_AUD_INTF_SYNC_CFG_REG(i) QAIF_AUD_INTF_REG_ADDR(0x0004, (i)) +#define QAIF_AUD_INTF_BIT_WIDTH_CFG_REG(i) QAIF_AUD_INTF_REG_ADDR(0x0008,= (i)) +#define QAIF_AUD_INTF_FRAME_CFG_REG(i) QAIF_AUD_INTF_REG_ADDR(0x000C, (i= )) +#define QAIF_AUD_INTF_ACTV_SLOT_EN_TX_REG(i) QAIF_AUD_INTF_REG_ADDR(0x001= 0, (i)) +#define QAIF_AUD_INTF_ACTV_SLOT_EN_RX_REG(i) QAIF_AUD_INTF_REG_ADDR(0x003= 0, (i)) +#define QAIF_AUD_INTF_LANE_CFG_REG(i) QAIF_AUD_INTF_REG_ADDR(0x0050, (i)) +#define QAIF_AUD_INTF_MI2S_CFG_REG(i) QAIF_AUD_INTF_REG_ADDR(0x0054, (i)) +#define QAIF_AUD_INTF_CFG_REG(i) QAIF_AUD_INTF_REG_ADDR(0x0058, (i)) +#define QAIF_AUD_INTF_CHAR_CTL_REG(i) QAIF_AUD_INTF_REG_ADDR(0x005C, (i)) +#define QAIF_AUD_INTF_CHAR_CFG_REG(i) QAIF_AUD_INTF_REG_ADDR(0x0060, (i)) +#define QAIF_AUD_INTF_CHAR_DATA_REG(i) QAIF_AUD_INTF_REG_ADDR(0x0064, (i= )) +#define QAIF_AUD_INTF_CHAR_DATA_EXT_REG(i) QAIF_AUD_INTF_REG_ADDR(0x0068,= (i)) +#define QAIF_AUD_INTF_CHAR_SYNC_REG(i) QAIF_AUD_INTF_REG_ADDR(0x006C, (i= )) +#define QAIF_AUD_INTF_INIT_DBG_STATUS_REG(i) QAIF_AUD_INTF_REG_ADDR(0x0FF= 0, (i)) +#define QAIF_AUD_INTF_TX_DBG_STATUS_REG(i) QAIF_AUD_INTF_REG_ADDR(0x0FF4,= (i)) +#define QAIF_AUD_INTF_RX_DBG_STATUS_REG(i) QAIF_AUD_INTF_REG_ADDR(0x0FF8,= (i)) + +/* RATE_DET block (per detector, stride 0x1000 starting at 0x1E000) */ +#define QAIF_RATE_DET_REG_ADDR(offset, det) (0x1E000 + (offset) + (0x1000= * (det))) + +#define QAIF_RATE_DET_CONFIG_REG(det) QAIF_RATE_DET_REG_ADDR(0x0000, (de= t)) +#define QAIF_RATE_DET_TARGET1_CONF_REG(det) QAIF_RATE_DET_REG_ADDR(0x0004= , (det)) +#define QAIF_RATE_DET_TARGET2_CONF_REG(det) QAIF_RATE_DET_REG_ADDR(0x0008= , (det)) +#define QAIF_RATE_DET_BIN_REG(det) QAIF_RATE_DET_REG_ADDR(0x000C, (det)) +#define QAIF_RATE_DET_STC_DIFF_REG(det) QAIF_RATE_DET_REG_ADDR(0x0010, (= det)) +#define QAIF_RATE_DET_SEL_REG(det) QAIF_RATE_DET_REG_ADDR(0x0014, (det)) +#define QAIF_RATE_DET_TIMEOUT_CFG_REG(det) QAIF_RATE_DET_REG_ADDR(0x0018,= (det)) + +#define QAIF_WRDMA_MAP_QXM (0x1000) +#define QAIF_CDC_WRDMA_MAP_QXM (0x1004) +#define QAIF_RDDMA_MAP_QXM (0x1010) +#define QAIF_CDC_RDDMA_MAP_QXM (0x1014) +#define QAIF_RDDMA_QXM1_SHRAM_ST_ADDR(i) (0x1100 + (0x4 * (i))) +#define QAIF_CDC_RDDMA_QXM1_SHRAM_ST_ADDR(i) (0x1140 + (0x4 * (i))) +#define QAIF_RDDMA_QXM0_SHRAM_ST_ADDR(i) (0x1200 + (0x4 * (i))) +#define QAIF_CDC_RDDMA_QXM0_SHRAM_ST_ADDR(i) (0x1240 + (0x4 * (i))) +#define QAIF_RDDMA_QXM1_SHRAM_LEN(i) (0x1300 + (0x4 * (i))) +#define QAIF_CDC_RDDMA_QXM1_SHRAM_LEN(i) (0x1340 + (0x4 * (i))) +#define QAIF_RDDMA_QXM0_SHRAM_LEN(i) (0x1400 + (0x4 * (i))) +#define QAIF_CDC_RDDMA_QXM0_SHRAM_LEN(i) (0x1440 + (0x4 * (i))) +#define QAIF_WRDMA_QXM1_SHRAM_ST_ADDR(i) (0x1500 + (0x4 * (i))) +#define QAIF_CDC_WRDMA_QXM1_SHRAM_ST_ADDR(i) (0x1540 + (0x4 * (i))) +#define QAIF_WRDMA_QXM0_SHRAM_ST_ADDR(i) (0x1600 + (0x4 * (i))) +#define QAIF_CDC_WRDMA_QXM0_SHRAM_ST_ADDR(i) (0x1640 + (0x4 * (i))) +#define QAIF_WRDMA_QXM1_SHRAM_LEN(i) (0x1700 + (0x4 * (i))) +#define QAIF_CDC_WRDMA_QXM1_SHRAM_LEN(i) (0x1740 + (0x4 * (i))) +#define QAIF_WRDMA_QXM0_SHRAM_LEN(i) (0x1800 + (0x4 * (i))) +#define QAIF_CDC_WRDMA_QXM0_SHRAM_LEN(i) (0x1840 + (0x4 * (i))) + +/* RDDMA */ +static inline u32 qaif_rddma_reg_addr(const struct qaif_variant *v, + u32 offset, u32 i) +{ + return v->rddma_reg_base + offset + v->rddma_stride * i; +} + +#define QAIF_RDDMA_CTL_REG(v, i) qaif_rddma_reg_addr(v, 0x00, (i)) +#define QAIF_RDDMA_CFG_REG(v, i) qaif_rddma_reg_addr(v, 0x04, (i)) +#define QAIF_RDDMA_BASE_ADDR_REG(v, i) qaif_rddma_reg_addr(v, 0x08, (i)) +#define QAIF_RDDMA_BUFF_LEN_REG(v, i) qaif_rddma_reg_addr(v, 0x10, (i)) +#define QAIF_RDDMA_CURR_ADDR_REG(v, i) qaif_rddma_reg_addr(v, 0x14, (i)) +#define QAIF_RDDMA_PERIOD_LEN_REG(v, i) qaif_rddma_reg_addr(v, 0x1C, (i)) +#define QAIF_RDDMA_PERIOD_CNT_REG(v, i) qaif_rddma_reg_addr(v, 0x20, (i)) +#define QAIF_RDDMA_SHRAM_WORDCNT_REG(v, i) qaif_rddma_reg_addr(v, 0x24, (= i)) +#define QAIF_RDDMA_FRAME_STATUS_REG(v, i) qaif_rddma_reg_addr(v, 0x28, (i= )) +#define QAIF_RDDMA_FRAME_STATUS_EXTN_REG(v, i) qaif_rddma_reg_addr(v, 0x2= C, (i)) +#define QAIF_RDDMA_FRAME_STATUS_CLR_REG(v, i) qaif_rddma_reg_addr(v, 0x30= , (i)) +#define QAIF_RDDMA_SET_BUFF_CNT_REG(v, i) qaif_rddma_reg_addr(v, 0x34, (i= )) +#define QAIF_RDDMA_SET_PERIOD_CNT_REG(v, i) qaif_rddma_reg_addr(v, 0x38, = (i)) +#define QAIF_RDDMA_STC_LSB_REG(v, i) qaif_rddma_reg_addr(v, 0x3C, (i)) +#define QAIF_RDDMA_STC_MSB_REG(v, i) qaif_rddma_reg_addr(v, 0x40, (i)) +#define QAIF_RDDMA_PERIOD_DET_STAT_REG(v, i) qaif_rddma_reg_addr(v, 0x44,= (i)) +#define QAIF_RDDMA_PERIOD_DET_CLR_REG(v, i) qaif_rddma_reg_addr(v, 0x48, = (i)) +#define QAIF_RDDMA_FORMAT_ERR_REG(v, i) qaif_rddma_reg_addr(v, 0x4C, (i)) +#define QAIF_RDDMA_AHB_BYPASS_REG(v, i) qaif_rddma_reg_addr(v, 0x50, (i)) +#define QAIF_RDDMA_SHUTDOWN_STAT_REG(v, i) qaif_rddma_reg_addr(v, 0x54, (= i)) +#define QAIF_RDDMA_PADDING_CFG_REG(v, i) qaif_rddma_reg_addr(v, 0x58, (i)) +#define QAIF_RDDMA_STATUS_REG(v, i) qaif_rddma_reg_addr(v, 0x60, (i)) +#define QAIF_RDDMA_DBG_STATUS_REG(v, i) qaif_rddma_reg_addr(v, 0xFF0, (i= )) + +static inline u32 qaif_codec_rddma_reg_addr(const struct qaif_variant *v, + u32 offset, u32 i) +{ + return v->codec_rddma_reg_base + offset + v->codec_rddma_stride * i; +} + +#define QAIF_CDC_RDDMA_CTL_REG(v, i) qaif_codec_rddma_reg_addr(v, 0x00, = (i)) +#define QAIF_CDC_RDDMA_CFG_REG(v, i) qaif_codec_rddma_reg_addr(v, 0x04, = (i)) +#define QAIF_CDC_RDDMA_BASE_ADDR_REG(v, i) qaif_codec_rddma_reg_addr(v, 0= x08, (i)) +#define QAIF_CDC_RDDMA_BUFF_LEN_REG(v, i) qaif_codec_rddma_reg_addr(v, 0x= 10, (i)) +#define QAIF_CDC_RDDMA_CURR_ADDR_REG(v, i) qaif_codec_rddma_reg_addr(v, 0= x14, (i)) +#define QAIF_CDC_RDDMA_PERIOD_LEN_REG(v, i) qaif_codec_rddma_reg_addr(v, = 0x1C, (i)) +#define QAIF_CDC_RDDMA_PERIOD_CNT_REG(v, i) qaif_codec_rddma_reg_addr(v, = 0x20, (i)) +#define QAIF_CDC_RDDMA_SHRAM_WORDCNT_REG(v, i) qaif_codec_rddma_reg_addr(= v, 0x24, (i)) +#define QAIF_CDC_RDDMA_FRAME_STAT_REG(v, i) qaif_codec_rddma_reg_addr(v, = 0x28, (i)) +#define QAIF_CDC_RDDMA_FRAME_STAT_EXTN_REG(v, i) qaif_codec_rddma_reg_addr= (v, 0x2C, (i)) +#define QAIF_CDC_RDDMA_FRAME_STAT_CLR_REG(v, i) qaif_codec_rddma_reg_addr= (v, 0x30, (i)) +#define QAIF_CDC_RDDMA_SET_BUFF_CNT_REG(v, i) qaif_codec_rddma_reg_addr(v= , 0x34, (i)) +#define QAIF_CDC_RDDMA_SET_PERIOD_CNT_REG(v, i) qaif_codec_rddma_reg_addr= (v, 0x38, (i)) +#define QAIF_CDC_RDDMA_STC_LSB_REG(v, i) qaif_codec_rddma_reg_addr(v, 0x3= C, (i)) +#define QAIF_CDC_RDDMA_STC_MSB_REG(v, i) qaif_codec_rddma_reg_addr(v, 0x4= 0, (i)) +#define QAIF_CDC_RDDMA_PERIOD_DET_STAT_REG(v, i) qaif_codec_rddma_reg_addr= (v, 0x44, (i)) +#define QAIF_CDC_RDDMA_PERIOD_DET_CLR_REG(v, i) qaif_codec_rddma_reg_addr= (v, 0x48, (i)) +#define QAIF_CDC_RDDMA_FORMAT_ERR_REG(v, i) qaif_codec_rddma_reg_addr(v, = 0x4C, (i)) +#define QAIF_CDC_RDDMA_AHB_BYPASS_REG(v, i) qaif_codec_rddma_reg_addr(v, = 0x50, (i)) +#define QAIF_CDC_RDDMA_SHUTDOWN_STAT_REG(v, i) qaif_codec_rddma_reg_addr(= v, 0x54, (i)) +#define QAIF_CDC_RDDMA_PADDING_CFG_REG(v, i) qaif_codec_rddma_reg_addr(v,= 0x58, (i)) +#define QAIF_CDC_RDDMA_INTF_CFG_REG(v, i) qaif_codec_rddma_reg_addr(v, 0x= 5C, (i)) +#define QAIF_CDC_RDDMA_STATUS_REG(v, i) qaif_codec_rddma_reg_addr(v, 0x6= 0, (i)) +#define QAIF_CDC_RDDMA_DBG_STATUS_REG(v, i) qaif_codec_rddma_reg_addr(v, = 0xFF0, (i)) +#define QAIF_CDC_RDDMA_INTF_DBG_STATUS_REG(v, i) qaif_codec_rddma_reg_addr= (v, 0xFF4, (i)) + +/* WRDMA */ +static inline u32 qaif_wrdma_reg_addr(const struct qaif_variant *v, + u32 offset, u32 i) +{ + return v->wrdma_reg_base + offset + v->wrdma_stride * i; +} + +#define QAIF_WRDMA_CTL_REG(v, i) qaif_wrdma_reg_addr(v, 0x00, (i)) +#define QAIF_WRDMA_CFG_REG(v, i) qaif_wrdma_reg_addr(v, 0x04, (i)) +#define QAIF_WRDMA_BASE_ADDR_REG(v, i) qaif_wrdma_reg_addr(v, 0x08, (i)) +#define QAIF_WRDMA_BUFF_LEN_REG(v, i) qaif_wrdma_reg_addr(v, 0x10, (i)) +#define QAIF_WRDMA_CURR_ADDR_REG(v, i) qaif_wrdma_reg_addr(v, 0x14, (i)) +#define QAIF_WRDMA_PERIOD_LEN_REG(v, i) qaif_wrdma_reg_addr(v, 0x1C, (i)) +#define QAIF_WRDMA_PERIOD_CNT_REG(v, i) qaif_wrdma_reg_addr(v, 0x20, (i)) +#define QAIF_WRDMA_SHRAM_WORDCNT_REG(v, i) qaif_wrdma_reg_addr(v, 0x24, (= i)) +#define QAIF_WRDMA_FRAME_STATUS_REG(v, i) qaif_wrdma_reg_addr(v, 0x28, (i= )) +#define QAIF_WRDMA_FRAME_STATUS_EXTN_REG(v, i) qaif_wrdma_reg_addr(v, 0x2= C, (i)) +#define QAIF_WRDMA_FRAME_STATUS_CLR_REG(v, i) qaif_wrdma_reg_addr(v, 0x30= , (i)) +#define QAIF_WRDMA_SET_BUFF_CNT_REG(v, i) qaif_wrdma_reg_addr(v, 0x34, (i= )) +#define QAIF_WRDMA_SET_PERIOD_CNT_REG(v, i) qaif_wrdma_reg_addr(v, 0x38, = (i)) +#define QAIF_WRDMA_STC_LSB_REG(v, i) qaif_wrdma_reg_addr(v, 0x3C, (i)) +#define QAIF_WRDMA_STC_MSB_REG(v, i) qaif_wrdma_reg_addr(v, 0x40, (i)) +#define QAIF_WRDMA_PERIOD_DET_STAT_REG(v, i) qaif_wrdma_reg_addr(v, 0x44,= (i)) +#define QAIF_WRDMA_PERIOD_DET_CLR_REG(v, i) qaif_wrdma_reg_addr(v, 0x48, = (i)) +#define QAIF_WRDMA_FORMAT_ERR_REG(v, i) qaif_wrdma_reg_addr(v, 0x4C, (i)) +#define QAIF_WRDMA_AHB_BYPASS_REG(v, i) qaif_wrdma_reg_addr(v, 0x50, (i)) +#define QAIF_WRDMA_SHUTDOWN_STAT_REG(v, i) qaif_wrdma_reg_addr(v, 0x54, (= i)) +#define QAIF_WRDMA_DBG_STATUS_REG(v, i) qaif_wrdma_reg_addr(v, 0xFF0, (i= )) + +static inline u32 qaif_codec_wrdma_reg_addr(const struct qaif_variant *v, + u32 offset, u32 i) +{ + return v->codec_wrdma_reg_base + offset + v->codec_wrdma_stride * i; +} + +#define QAIF_CDC_WRDMA_CTL_REG(v, i) qaif_codec_wrdma_reg_addr(v, 0x00, = (i)) +#define QAIF_CDC_WRDMA_CFG_REG(v, i) qaif_codec_wrdma_reg_addr(v, 0x04, = (i)) +#define QAIF_CDC_WRDMA_BASE_ADDR_REG(v, i) qaif_codec_wrdma_reg_addr(v, 0= x08, (i)) +#define QAIF_CDC_WRDMA_BUFF_LEN_REG(v, i) qaif_codec_wrdma_reg_addr(v, 0x= 10, (i)) +#define QAIF_CDC_WRDMA_CURR_ADDR_REG(v, i) qaif_codec_wrdma_reg_addr(v, 0= x14, (i)) +#define QAIF_CDC_WRDMA_PERIOD_LEN_REG(v, i) qaif_codec_wrdma_reg_addr(v, = 0x1C, (i)) +#define QAIF_CDC_WRDMA_PERIOD_CNT_REG(v, i) qaif_codec_wrdma_reg_addr(v, = 0x20, (i)) +#define QAIF_CDC_WRDMA_SHRAM_WORDCNT_REG(v, i) qaif_codec_wrdma_reg_addr(= v, 0x24, (i)) +#define QAIF_CDC_WRDMA_FRAME_STAT_REG(v, i) qaif_codec_wrdma_reg_addr(v, = 0x28, (i)) +#define QAIF_CDC_WRDMA_FRAME_STAT_EXTN_REG(v, i) qaif_codec_wrdma_reg_addr= (v, 0x2C, (i)) +#define QAIF_CDC_WRDMA_FRAME_STAT_CLR_REG(v, i) qaif_codec_wrdma_reg_addr= (v, 0x30, (i)) +#define QAIF_CDC_WRDMA_SET_BUFF_CNT_REG(v, i) qaif_codec_wrdma_reg_addr(v= , 0x34, (i)) +#define QAIF_CDC_WRDMA_SET_PERIOD_CNT_REG(v, i) qaif_codec_wrdma_reg_addr= (v, 0x38, (i)) +#define QAIF_CDC_WRDMA_STC_LSB_REG(v, i) qaif_codec_wrdma_reg_addr(v, 0x3= C, (i)) +#define QAIF_CDC_WRDMA_STC_MSB_REG(v, i) qaif_codec_wrdma_reg_addr(v, 0x4= 0, (i)) +#define QAIF_CDC_WRDMA_PERIOD_DET_STAT_REG(v, i) qaif_codec_wrdma_reg_addr= (v, 0x44, (i)) +#define QAIF_CDC_WRDMA_PERIOD_DET_CLR_REG(v, i) qaif_codec_wrdma_reg_addr= (v, 0x48, (i)) +#define QAIF_CDC_WRDMA_FORMAT_ERR_REG(v, i) qaif_codec_wrdma_reg_addr(v, = 0x4C, (i)) +#define QAIF_CDC_WRDMA_AHB_BYPASS_REG(v, i) qaif_codec_wrdma_reg_addr(v, = 0x50, (i)) +#define QAIF_CDC_WRDMA_SHUTDOWN_STAT_REG(v, i) qaif_codec_wrdma_reg_addr(= v, 0x54, (i)) +#define QAIF_CDC_WRDMA_INTF_CFG_REG(v, i) qaif_codec_wrdma_reg_addr(v, 0x= 58, (i)) +#define QAIF_CDC_WRDMA_DBG_STATUS_REG(v, i) qaif_codec_wrdma_reg_addr(v, = 0xFF0, (i)) +#define QAIF_CDC_WRDMA_INTF_DBG_STATUS_REG(v, i) qaif_codec_wrdma_reg_addr= (v, 0xFF4, (i)) + +static inline u32 qaif_rddma_irq_reg_addr(const struct qaif_variant *v, + enum qaif_irq_type dma_type, + u32 offset) +{ + if (dma_type =3D=3D QAIF_AIF_IRQ) + return v->rddma_irq_reg_base + offset + + v->rddma_irq_stride * v->ee; + return v->codec_rddma_irq_reg_base + offset + + v->codec_rddma_irq_stride * v->ee; +} + +/* RDDMA Period Interrupts */ +#define QAIF_EE_RDDMA_PERIOD_IRQ_EN_REG(v, i) qaif_rddma_irq_reg_addr(v, = i, 0x00) +#define QAIF_EE_RDDMA_PERIOD_IRQ_STAT_REG(v, i) qaif_rddma_irq_reg_addr(v= , i, 0x08) +#define QAIF_EE_RDDMA_PERIOD_IRQ_RAW_STAT_REG(v, i) qaif_rddma_irq_reg_add= r(v, i, 0x10) +#define QAIF_EE_RDDMA_PERIOD_IRQ_CLR_REG(v, i) qaif_rddma_irq_reg_addr(v,= i, 0x18) +#define QAIF_EE_RDDMA_PERIOD_IRQ_FORCE_REG(v, i) qaif_rddma_irq_reg_addr(v= , i, 0x20) +/* RDDMA Underflow Interrupts */ +#define QAIF_EE_RDDMA_UF_IRQ_EN_REG(v, i) qaif_rddma_irq_reg_addr(v, i, 0= x28) +#define QAIF_EE_RDDMA_UF_IRQ_STAT_REG(v, i) qaif_rddma_irq_reg_addr(v, i,= 0x30) +#define QAIF_EE_RDDMA_UF_IRQ_RAW_STAT_REG(v, i) qaif_rddma_irq_reg_addr(v= , i, 0x38) +#define QAIF_EE_RDDMA_UF_IRQ_CLR_REG(v, i) qaif_rddma_irq_reg_addr(v, i, = 0x40) +#define QAIF_EE_RDDMA_UF_IRQ_FORCE_REG(v, i) qaif_rddma_irq_reg_addr(v, i= , 0x48) +/* RDDMA Error Response Interrupts */ +#define QAIF_EE_RDDMA_ERR_RSP_IRQ_EN_REG(v, i) qaif_rddma_irq_reg_addr(v,= i, 0x50) +#define QAIF_EE_RDDMA_ERR_RSP_IRQ_STAT_REG(v, i) qaif_rddma_irq_reg_addr(v= , i, 0x58) +#define QAIF_EE_RDDMA_ERR_RSP_IRQ_RAW_STAT(v, i) qaif_rddma_irq_reg_addr(v= , i, 0x60) +#define QAIF_EE_RDDMA_ERR_RSP_IRQ_CLR_REG(v, i) qaif_rddma_irq_reg_addr(v= , i, 0x68) +#define QAIF_EE_RDDMA_ERR_RSP_IRQ_FORCE_REG(v, i) qaif_rddma_irq_reg_addr(= v, i, 0x70) + +static inline u32 qaif_wrdma_irq_reg_addr(const struct qaif_variant *v, + enum qaif_irq_type dma_type, + u32 offset) +{ + if (dma_type =3D=3D QAIF_AIF_IRQ) + return v->wrdma_irq_reg_base + offset + + v->wrdma_irq_stride * v->ee; + return v->codec_wrdma_irq_reg_base + offset + + v->codec_wrdma_irq_stride * v->ee; +} + +/* WRDMA Period Interrupts */ +#define QAIF_EE_WRDMA_PERIOD_IRQ_EN_REG(v, i) qaif_wrdma_irq_reg_addr(v, = i, 0x00) +#define QAIF_EE_WRDMA_PERIOD_IRQ_STAT_REG(v, i) qaif_wrdma_irq_reg_addr(v= , i, 0x08) +#define QAIF_EE_WRDMA_PERIOD_IRQ_RAW_STAT_REG(v, i) qaif_wrdma_irq_reg_add= r(v, i, 0x10) +#define QAIF_EE_WRDMA_PERIOD_IRQ_CLR_REG(v, i) qaif_wrdma_irq_reg_addr(v,= i, 0x18) +#define QAIF_EE_WRDMA_PERIOD_IRQ_FORCE_REG(v, i) qaif_wrdma_irq_reg_addr(v= , i, 0x20) +/* WRDMA Overflow Interrupts */ +#define QAIF_EE_WRDMA_OF_IRQ_EN_REG(v, i) qaif_wrdma_irq_reg_addr(v, i, 0= x28) +#define QAIF_EE_WRDMA_OF_IRQ_STAT_REG(v, i) qaif_wrdma_irq_reg_addr(v, i,= 0x30) +#define QAIF_EE_WRDMA_OF_IRQ_RAW_STAT_REG(v, i) qaif_wrdma_irq_reg_addr(v= , i, 0x38) +#define QAIF_EE_WRDMA_OF_IRQ_CLR_REG(v, i) qaif_wrdma_irq_reg_addr(v, i, = 0x40) +#define QAIF_EE_WRDMA_OF_IRQ_FORCE_REG(v, i) qaif_wrdma_irq_reg_addr(v, i= , 0x48) +/* WRDMA Error Response Interrupts */ +#define QAIF_EE_WRDMA_ERR_RSP_IRQ_EN_REG(v, i) qaif_wrdma_irq_reg_addr(v,= i, 0x50) +#define QAIF_EE_WRDMA_ERR_RSP_IRQ_STAT_REG(v, i) qaif_wrdma_irq_reg_addr(v= , i, 0x58) +#define QAIF_EE_WRDMA_ERR_RSP_IRQ_RAW_STAT(v, i) qaif_wrdma_irq_reg_addr(v= , i, 0x60) +#define QAIF_EE_WRDMA_ERR_RSP_IRQ_CLR_REG(v, i) qaif_wrdma_irq_reg_addr(v= , i, 0x68) +#define QAIF_EE_WRDMA_ERR_RSP_IRQ_FORCE_REG(v, i) qaif_wrdma_irq_reg_addr(= v, i, 0x70) + +static inline u32 qaif_dmacfg_reg(const struct qaif_variant *v, + u32 i, int dir, unsigned int dai_id) +{ + if (qaif_is_cif_port(dai_id)) + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_CDC_RDDMA_CFG_REG(v, i) : + QAIF_CDC_WRDMA_CFG_REG(v, i); + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_RDDMA_CFG_REG(v, i) : QAIF_WRDMA_CFG_REG(v, i); +} + +static inline u32 qaif_dmactl_reg(const struct qaif_variant *v, + u32 i, int dir, unsigned int dai_id) +{ + if (qaif_is_cif_port(dai_id)) + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_CDC_RDDMA_CTL_REG(v, i) : + QAIF_CDC_WRDMA_CTL_REG(v, i); + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_RDDMA_CTL_REG(v, i) : QAIF_WRDMA_CTL_REG(v, i); +} + +static inline u32 qaif_dmabuff_reg(const struct qaif_variant *v, + u32 i, int dir, unsigned int dai_id) +{ + if (qaif_is_cif_port(dai_id)) + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_CDC_RDDMA_BUFF_LEN_REG(v, i) : + QAIF_CDC_WRDMA_BUFF_LEN_REG(v, i); + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_RDDMA_BUFF_LEN_REG(v, i) : QAIF_WRDMA_BUFF_LEN_REG(v, i); +} + +static inline u32 qaif_dmacurr_reg(const struct qaif_variant *v, + u32 i, int dir, unsigned int dai_id) +{ + if (qaif_is_cif_port(dai_id)) + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_CDC_RDDMA_CURR_ADDR_REG(v, i) : + QAIF_CDC_WRDMA_CURR_ADDR_REG(v, i); + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_RDDMA_CURR_ADDR_REG(v, i) : QAIF_WRDMA_CURR_ADDR_REG(v, i); +} + +static inline u32 qaif_dmaper_cnt_reg(const struct qaif_variant *v, + u32 i, int dir, unsigned int dai_id) +{ + if (qaif_is_cif_port(dai_id)) + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_CDC_RDDMA_PERIOD_CNT_REG(v, i) : + QAIF_CDC_WRDMA_PERIOD_CNT_REG(v, i); + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_RDDMA_PERIOD_CNT_REG(v, i) : QAIF_WRDMA_PERIOD_CNT_REG(v, i); +} + +static inline u32 qaif_dmaper_len_reg(const struct qaif_variant *v, + u32 i, int dir, unsigned int dai_id) +{ + if (qaif_is_cif_port(dai_id)) + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_CDC_RDDMA_PERIOD_LEN_REG(v, i) : + QAIF_CDC_WRDMA_PERIOD_LEN_REG(v, i); + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_RDDMA_PERIOD_LEN_REG(v, i) : QAIF_WRDMA_PERIOD_LEN_REG(v, i); +} + +static inline u32 qaif_dmabase_reg(const struct qaif_variant *v, + u32 i, int dir, unsigned int dai_id) +{ + if (qaif_is_cif_port(dai_id)) + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_CDC_RDDMA_BASE_ADDR_REG(v, i) : + QAIF_CDC_WRDMA_BASE_ADDR_REG(v, i); + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_RDDMA_BASE_ADDR_REG(v, i) : QAIF_WRDMA_BASE_ADDR_REG(v, i); +} + +static inline u32 qaif_sid_map_reg(int dir, unsigned int dai_id) +{ + if (qaif_is_cif_port(dai_id)) + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_CDC_RDDMA_SID_MAP_REG : + QAIF_CDC_WRDMA_SID_MAP_REG; + return dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_RDDMA_SID_MAP_REG : QAIF_WRDMA_SID_MAP_REG; +} + +#endif /* SND_SOC_QCOM_QAIF_REG_H */ --=20 2.34.1 From nobody Fri Sep 25 14:31:50 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 4C4CF46D54B; Fri, 11 Sep 2026 09:19:46 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118388; cv=none; b=QgH9tHSctQnGcvrSbZ8vredMk7smjdcNqn97CwdQC/I7okyORKhTOorXFsU+SSkpjDqt2Iz4vd6dZHLhcyJ7rKLqM3jyWITkBU8noRO4ruKZZ9Z/vgCToX0CwVLlBHkCZQzSSVb4XQ5fcbU3ypYMXqNWvhfE5QoglaqbAVRdqOQ= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118388; c=relaxed/simple; bh=rs8KylcwU8G3tJsMEzDMxtLd5dSTEhyB6gThypKzmN0=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=B5mH14poGGF3BVn+DJCfu69vjrNdYW8SSo47Rou1aWMXG/Oy6mvLUmmy/q9UBbCCYRkpQvTDN1E1Wjvp30e8sA6jQpqtJ9cCP8HLt9npVA6O/1O2lO8oXxDOM7LnzqM/BXfeZFpKlaYsSvXgne3Rwtlp//wKZ1InVh3f3h/2rM4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=Dm//n7kJ; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="Dm//n7kJ" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B7l1rU3687109; Fri, 11 Sep 2026 09:19:27 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= /E3DW4dXHO/whGgIACsyiCxP3MD0k/STHDmIkC2J/oo=; b=Dm//n7kJvQerPp/c rDLWWoMq0/dpaoVC6rzoR7fCaJFjG0rm6Q8J4DcAWTLbIw2OIYKlJbOqTHTBuBH6 fip2WsmZRmdHbWZ0WnUoeKPd/HhkScf8IoZr0P5Amk3n0QYDd5BoIrHyTJKefdNU BFWFFPTwWnQckD3EVKHrdV2sEOGkSOQue6pWB2ss2xF3s6+KKKztYUj4VQ+gpqrz keMOtHX66NHygoiK5AbzvvlwGp/jl2WLWwKykrv0DqDLf+CpFkGRbsGFcTv0aVGk d+ce1fuhsWn8Ioz2oY0KTekTZ13M3TRyn1nxPyb/vJqJdwinSDrK66T/8t3OhOTd nQb1wA== Received: from apblrppmta02.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gmapg12kb-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 09:19:26 +0000 (GMT) Received: from pps.filterd (apblrppmta02.qualcomm.com [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B9JOEI2870877; Fri, 11 Sep 2026 09:19:24 GMT Received: from hu-hgautam-hyd.qualcomm.com (hu-hgautam-hyd.qualcomm.com [10.147.247.91]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTP id 68B9JL2a2870824; Fri, 11 Sep 2026 09:19:23 +0000 (GMT) From: Harendra Gautam Date: Fri, 11 Sep 2026 14:47:28 +0530 Subject: [PATCH v6 04/10] ASoC: qcom: Add QAIF CPU DAI ops, regmap, DT parsing and platform init Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260911-b4-qaif-shikra-audio-v6-4-e9addb358201@oss.qualcomm.com> References: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> In-Reply-To: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> To: Srinivas Kandagatla Cc: Mark Brown , Liam Girdwood , Rob Herring , Krzysztof Kozlowski , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai , Kuninori Morimoto , linux-sound@vger.kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Prasad Kumpatla , Krzysztof Kozlowski , Sarath Ganapathiraju , Kumar Anurag Singh , Mohammad Rafi Shaik , Harendra Gautam X-Mailer: b4 0.15.2 X-Proofpoint-Reinject: loops=2 maxloops=12 X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-ORIG-GUID: IFF7rKwd9MFxNHbnaEpBjdCgHOt_dfYC X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfX1bMaZuE//sfR LH5PvmVBWKQIPHAiTP2RDVN4FJP+WQ7hLpWzi+zSeXTQdnPvEPei345kNWuwbaCeeHJBP2nTldv ykaE6SV7noVr/vmwjpanpLEtwAoZE6Q= X-Proofpoint-GUID: IFF7rKwd9MFxNHbnaEpBjdCgHOt_dfYC X-Authority-Analysis: v=2.4 cv=DLoacCNb c=1 sm=1 tr=0 ts=6aa3c79e cx=c_pps a=Ou0eQOY4+eZoSc0qltEV5Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=EUspDBNiAAAA:8 a=IKOdykDz4KF-cjZmJaIA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfX6WCXmy+/1M/H f1Q1FmZvW1bOSk1M6v+PfXSlB1OktVZlpHOm5AVeR0XWQ9OQf7DIJo3uGtBFkoX+W40TcR0Goav s950l7BhlCg+n7atYpSZOdlgDtm38X66YHqtfviEbEHk6pCiE5n+6tDAZi+3ILb+xiWaMphKb1I 5fepqmnpXuX489BdYtiouOzhi9vkFOgwJx3e+JVTs+0ngInySOqZoZazLkLlavFNuIn5tQxk3AT 2jnoMa/H4fSYs1ZOPWJJN/wOHTo1IHqA8oM79x6+SAtX0dV7CJ7dFsh/T4mn9KQJpgH62p0DRZY IR4vDArBATNSJ15mqGgZtpRdBC6lu/lF8t+e5IkKHYnWPv2lhXrpFnxTHL3Ppqr03frS4qxXULu FjKeHpYScoCvmYvvvmfwb/VhVhN/WsF007Jt0TGY9ziVayuUzoXVQNMmyGY1GlKZtDM9izRHlcH KxhUrOg4nNZKEc/9ksg== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_03,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 priorityscore=1501 phishscore=0 adultscore=0 suspectscore=0 spamscore=0 impostorscore=0 bulkscore=0 clxscore=1015 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110129 Add the QAIF CPU DAI driver to support Qualcomm audio interface paths used for CDC DMA and serial AIF audio links. Implement CIF DAI operations for CDC DMA paths, including channel mask programming and dynamic clock control. Implement AIF DAI operations for MI2S, TDM and PCM paths, including format setup, slot and lane configuration, bit clock management and stream enable handling. Also add the QAIF MMIO regmap setup, parse per-interface configuration from devicetree, manage required clocks and register the CPU DAI component. Signed-off-by: Harendra Gautam --- sound/soc/qcom/qaif-cpu.c | 877 ++++++++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 877 insertions(+) diff --git a/sound/soc/qcom/qaif-cpu.c b/sound/soc/qcom/qaif-cpu.c new file mode 100644 index 000000000000..e1868dc95cf4 --- /dev/null +++ b/sound/soc/qcom/qaif-cpu.c @@ -0,0 +1,877 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * qaif-cpu.c -- ALSA SoC CPU-Platform DAI driver for QTi QAIF + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qaif-reg.h" +#include "qaif.h" + +/* CIF INTF CFG register bit positions */ +#define QAIF_CIF_INTF_16BIT_UNPACK_BIT BIT(0) +#define QAIF_CIF_INTF_DYNCLK_BIT BIT(2) +#define QAIF_CIF_INTF_FS_SEL_MASK GENMASK(7, 4) +#define QAIF_CIF_INTF_ACTIVE_CH_MASK GENMASK(27, 12) +#define QAIF_CIF_INTF_ACTIVE_CH_SHIFT 12 + +/* AIF CTL register (QAIF_AUD_INTF_CTL_REG) bit positions */ +#define QAIF_AIF_CTL_ENABLE_BIT BIT(0) +#define QAIF_AIF_CTL_ENABLE_TX_BIT BIT(4) +#define QAIF_AIF_CTL_ENABLE_RX_BIT BIT(8) + +/* AIF SYNC CFG register (QAIF_AUD_INTF_SYNC_CFG_REG) bit positions */ +#define QAIF_AIF_SYNC_SRC_BIT BIT(0) +#define QAIF_AIF_SYNC_MODE_MASK GENMASK(5, 4) +#define QAIF_AIF_SYNC_MODE_SHIFT 4 +#define QAIF_AIF_SYNC_DELAY_MASK GENMASK(9, 8) +#define QAIF_AIF_SYNC_DELAY_SHIFT 8 +#define QAIF_AIF_SYNC_INV_BIT BIT(12) + +/* SYNC_MODE field values */ +#define QAIF_AIF_SYNC_MODE_SHORT 0 +#define QAIF_AIF_SYNC_MODE_ONE_SLOT 1 +#define QAIF_AIF_SYNC_MODE_LONG 2 + +/* SYNC_DELAY field values */ +#define QAIF_AIF_SYNC_DELAY_SAME 0 +#define QAIF_AIF_SYNC_DELAY_ONE 1 + +/* AIF BIT WIDTH CFG register (QAIF_AUD_INTF_BIT_WIDTH_CFG_REG) bit positi= ons */ +#define QAIF_AIF_SLOT_WIDTH_TX_MASK GENMASK(4, 0) +#define QAIF_AIF_SLOT_WIDTH_RX_MASK GENMASK(12, 8) +#define QAIF_AIF_SLOT_WIDTH_RX_SHIFT 8 +#define QAIF_AIF_SAMPLE_WIDTH_TX_MASK GENMASK(20, 16) +#define QAIF_AIF_SAMPLE_WIDTH_TX_SHIFT 16 +#define QAIF_AIF_SAMPLE_WIDTH_RX_MASK GENMASK(28, 24) +#define QAIF_AIF_SAMPLE_WIDTH_RX_SHIFT 24 + +/* + * slot_width is programmed 0-based into the 5-bit SLOT_WIDTH field and the + * frame length (slots * slot_width) 0-based into the 10-bit BITS_PER_LANE + * field, so these are the largest values the registers can represent. + */ +#define QAIF_AIF_SLOT_WIDTH_MAX 32 +#define QAIF_AIF_FRAME_BITS_MAX 1024 + +/* AIF FRAME CFG register (QAIF_AUD_INTF_FRAME_CFG_REG) bit positions */ +#define QAIF_AIF_BITS_PER_LANE_MASK GENMASK(9, 0) + +/* AIF LANE CFG register (QAIF_AUD_INTF_LANE_CFG_REG) bit positions */ +#define QAIF_AIF_LANE_DIR_MASK GENMASK(7, 0) +#define QAIF_AIF_LANE_EN_MASK GENMASK(15, 8) +#define QAIF_AIF_LANE_EN_SHIFT 8 +#define QAIF_AIF_CTRL_DATA_OE_BIT BIT(16) +#define QAIF_AIF_LOOPBACK_EN_BIT BIT(31) + +/* AIF MI2S CFG register (QAIF_AUD_INTF_MI2S_CFG_REG) bit positions */ +#define QAIF_AIF_MONO_MODE_TX_BIT BIT(0) +#define QAIF_AIF_MONO_MODE_RX_BIT BIT(1) + +/* AIF CFG register (QAIF_AUD_INTF_CFG_REG) bit positions */ +#define QAIF_AIF_FULL_CYCLE_EN_BIT BIT(0) + +static int qaif_cif_daiops_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd =3D snd_soc_substream_to_rtd(substream); + struct qaif_drv_data *drvdata =3D snd_soc_dai_get_drvdata(dai); + const struct qaif_variant *v =3D drvdata->variant; + unsigned int dai_id =3D dai->driver->id; + unsigned int regval; + u32 reg; + int idx; + + switch (params_channels(params)) { + case 1: + regval =3D QAIF_CIF_DMA_INTF_ONE_CHANNEL; + break; + case 2: + regval =3D QAIF_CIF_DMA_INTF_TWO_CHANNEL; + break; + case 4: + regval =3D QAIF_CIF_DMA_INTF_FOUR_CHANNEL; + break; + case 6: + regval =3D QAIF_CIF_DMA_INTF_SIX_CHANNEL; + break; + case 8: + regval =3D QAIF_CIF_DMA_INTF_EIGHT_CHANNEL; + break; + default: + dev_dbg(rtd->dev, "unsupported channel count %u\n", + params_channels(params)); + return -EINVAL; + } + + idx =3D v->get_dma_idx(dai_id); + if (idx < 0) { + dev_err(rtd->dev, "Invalid DMA index: %d\n", idx); + return -EINVAL; + } + + reg =3D substream->stream =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_CDC_RDDMA_INTF_CFG_REG(v, idx) : + QAIF_CDC_WRDMA_INTF_CFG_REG(v, idx); + + return regmap_update_bits(drvdata->audio_qaif_map, reg, + QAIF_CIF_INTF_ACTIVE_CH_MASK, + regval << QAIF_CIF_INTF_ACTIVE_CH_SHIFT); +} + +static int qaif_cif_daiops_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct snd_soc_pcm_runtime *rtd =3D snd_soc_substream_to_rtd(substream); + struct qaif_drv_data *drvdata =3D snd_soc_dai_get_drvdata(dai); + const struct qaif_variant *v =3D drvdata->variant; + unsigned int dai_id =3D dai->driver->id; + struct regmap *map =3D drvdata->audio_qaif_map; + u32 reg; + int idx, ret; + + idx =3D v->get_dma_idx(dai_id); + if (idx < 0) { + dev_err(rtd->dev, "Invalid DMA index: %d\n", idx); + return -EINVAL; + } + + reg =3D substream->stream =3D=3D SNDRV_PCM_STREAM_PLAYBACK ? + QAIF_CDC_RDDMA_INTF_CFG_REG(v, idx) : + QAIF_CDC_WRDMA_INTF_CFG_REG(v, idx); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + ret =3D regmap_update_bits(map, reg, + QAIF_CIF_INTF_DYNCLK_BIT, + QAIF_CIF_INTF_DYNCLK_BIT); + if (ret) + return ret; + ret =3D regmap_update_bits(map, reg, QAIF_CIF_INTF_FS_SEL_MASK, 0); + if (ret) + return ret; + return regmap_update_bits(map, reg, + QAIF_CIF_INTF_16BIT_UNPACK_BIT, + QAIF_CIF_INTF_16BIT_UNPACK_BIT); + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + ret =3D regmap_update_bits(map, reg, QAIF_CIF_INTF_DYNCLK_BIT, 0); + if (ret) + return ret; + return regmap_update_bits(map, reg, + QAIF_CIF_INTF_16BIT_UNPACK_BIT, 0); + default: + dev_err(rtd->dev, "invalid trigger cmd %d\n", cmd); + return -EINVAL; + } +} + +static int qaif_cif_daiops_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct qaif_drv_data *drvdata =3D snd_soc_dai_get_drvdata(dai); + int ret; + + ret =3D clk_prepare_enable(drvdata->aud_dma_clk); + if (ret) { + dev_err(dai->dev, "error enabling aud_dma clk: %d\n", ret); + return ret; + } + + ret =3D clk_prepare_enable(drvdata->aud_dma_mem_clk); + if (ret) { + dev_err(dai->dev, "error enabling aud_dma_mem clk: %d\n", ret); + clk_disable_unprepare(drvdata->aud_dma_clk); + return ret; + } + return 0; +} + +static void qaif_cif_daiops_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct qaif_drv_data *drvdata =3D snd_soc_dai_get_drvdata(dai); + + clk_disable_unprepare(drvdata->aud_dma_mem_clk); + clk_disable_unprepare(drvdata->aud_dma_clk); +} + +/* + * asoc_qcom_qaif_cif_dai_ops - DAI ops for QAIF CIF (CDC DMA) paths + * + * Provides startup, shutdown, hw_params and trigger callbacks for the + * Codec Interface DMA (CIF) DAI. startup/shutdown enable and disable the + * audio DMA clocks. Used by Shikra machine drivers for Bolero CDC DMA + * RX, TX and VA TX paths. + */ +const struct snd_soc_dai_ops asoc_qcom_qaif_cif_dai_ops =3D { + .startup =3D qaif_cif_daiops_startup, + .shutdown =3D qaif_cif_daiops_shutdown, + .hw_params =3D qaif_cif_daiops_hw_params, + .trigger =3D qaif_cif_daiops_trigger, +}; +EXPORT_SYMBOL_GPL(asoc_qcom_qaif_cif_dai_ops); + +static int qaif_aif_cpu_daiops_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct qaif_drv_data *drvdata =3D snd_soc_dai_get_drvdata(dai); + const struct qaif_variant *v =3D drvdata->variant; + int idx, ret; + + idx =3D v->get_dma_idx(dai->driver->id); + if (idx < 0) { + dev_err(dai->dev, "Invalid DMA index: %d\n", idx); + return -EINVAL; + } + + ret =3D clk_prepare_enable(drvdata->aud_dma_clk); + if (ret) { + dev_err(dai->dev, "error enabling aud_dma clk: %d\n", ret); + return ret; + } + + ret =3D clk_prepare_enable(drvdata->aud_dma_mem_clk); + if (ret) { + dev_err(dai->dev, "error enabling aud_dma_mem clk: %d\n", ret); + clk_disable_unprepare(drvdata->aud_dma_clk); + return ret; + } + + ret =3D clk_prepare_enable(drvdata->mi2s_bit_clk[idx]); + if (ret) { + dev_err(dai->dev, "error enabling mi2s bit clk: %d\n", ret); + clk_disable_unprepare(drvdata->aud_dma_mem_clk); + clk_disable_unprepare(drvdata->aud_dma_clk); + } + return ret; +} + +static void qaif_aif_cpu_daiops_shutdown(struct snd_pcm_substream *substre= am, + struct snd_soc_dai *dai) +{ + struct qaif_drv_data *drvdata =3D snd_soc_dai_get_drvdata(dai); + const struct qaif_variant *v =3D drvdata->variant; + struct qaif_aif_config *cfg; + unsigned int enable_bit; + int idx =3D v->get_dma_idx(dai->driver->id); + int ret; + + if (idx < 0) { + dev_err(dai->dev, "Invalid DMA index: %d\n", idx); + return; + } + + cfg =3D &drvdata->aif_intf_cfg[idx]; + if (cfg->loopback_en) + enable_bit =3D QAIF_AIF_CTL_ENABLE_BIT; + else if (substream->stream =3D=3D SNDRV_PCM_STREAM_PLAYBACK) + enable_bit =3D QAIF_AIF_CTL_ENABLE_TX_BIT; + else + enable_bit =3D QAIF_AIF_CTL_ENABLE_RX_BIT; + + ret =3D regmap_update_bits(drvdata->audio_qaif_map, + QAIF_AUD_INTF_CTL_REG(idx), enable_bit, 0); + if (ret) + dev_err(dai->dev, "error clearing AIF enable bit: %d\n", ret); + + clk_disable_unprepare(drvdata->mi2s_bit_clk[idx]); + clk_disable_unprepare(drvdata->aud_dma_mem_clk); + clk_disable_unprepare(drvdata->aud_dma_clk); +} + +static int qaif_aif_cpu_daiops_hw_params(struct snd_pcm_substream *substre= am, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + struct qaif_drv_data *drvdata =3D snd_soc_dai_get_drvdata(dai); + const struct qaif_variant *v =3D drvdata->variant; + const struct qaif_aif_config *cfg; + struct regmap *map =3D drvdata->audio_qaif_map; + snd_pcm_format_t format =3D params_format(params); + unsigned int channels =3D params_channels(params); + unsigned int slot_width; + int bitwidth, idx, ret; + + idx =3D v->get_dma_idx(dai->driver->id); + if (idx < 0) { + dev_err(dai->dev, "Invalid DMA index: %d\n", idx); + return -EINVAL; + } + + cfg =3D &drvdata->aif_intf_cfg[idx]; + + bitwidth =3D snd_pcm_format_width(format); + if (bitwidth < 0) { + dev_err(dai->dev, "invalid bit width given: %d\n", bitwidth); + return bitwidth; + } + + /* + * The sync, lane and frame configuration and the MI2S bit clock are + * shared by both directions of an AIF. Concurrent playback and + * capture on the same interface are therefore expected to use a + * compatible format, rate and slot configuration. + */ + ret =3D regmap_update_bits(map, QAIF_AUD_INTF_SYNC_CFG_REG(idx), + QAIF_AIF_SYNC_SRC_BIT | + QAIF_AIF_SYNC_MODE_MASK | + QAIF_AIF_SYNC_DELAY_MASK | + QAIF_AIF_SYNC_INV_BIT, + (cfg->sync_src ? QAIF_AIF_SYNC_SRC_BIT : 0) | + (cfg->sync_mode << QAIF_AIF_SYNC_MODE_SHIFT) | + (cfg->sync_delay << QAIF_AIF_SYNC_DELAY_SHIFT) | + (cfg->invert_sync ? QAIF_AIF_SYNC_INV_BIT : 0)); + if (ret) + return ret; + + ret =3D regmap_update_bits(map, QAIF_AUD_INTF_LANE_CFG_REG(idx), + QAIF_AIF_LANE_DIR_MASK | + QAIF_AIF_LANE_EN_MASK | + QAIF_AIF_CTRL_DATA_OE_BIT | + QAIF_AIF_LOOPBACK_EN_BIT, + cfg->lane_dir_mask | + (cfg->lane_en_mask << QAIF_AIF_LANE_EN_SHIFT) | + (cfg->ctrl_data_oe ? QAIF_AIF_CTRL_DATA_OE_BIT : 0) | + (cfg->loopback_en ? QAIF_AIF_LOOPBACK_EN_BIT : 0)); + if (ret) + return ret; + + ret =3D regmap_update_bits(map, QAIF_AUD_INTF_CFG_REG(idx), + QAIF_AIF_FULL_CYCLE_EN_BIT, + cfg->full_cycle_en ? QAIF_AIF_FULL_CYCLE_EN_BIT : 0); + if (ret) + return ret; + + if (qaif_is_aif_mi2s_port(dai->driver->id) && !cfg->slot_width) { + slot_width =3D bitwidth; + if (substream->stream =3D=3D SNDRV_PCM_STREAM_PLAYBACK) + drvdata->aif_intf_cfg[idx].slot_en_tx_mask =3D + GENMASK(channels - 1, 0); + else + drvdata->aif_intf_cfg[idx].slot_en_rx_mask =3D + GENMASK(channels - 1, 0); + drvdata->aif_intf_cfg[idx].slot_num =3D QAIF_MI2S_SLOTS; + } else { + slot_width =3D cfg->slot_width; + if (!slot_width || !cfg->slot_num) { + dev_err(dai->dev, "invalid TDM slot config: width=3D%u num=3D%u\n", + slot_width, cfg->slot_num); + return -EINVAL; + } + } + + if (substream->stream =3D=3D SNDRV_PCM_STREAM_PLAYBACK) { + ret =3D regmap_update_bits(map, QAIF_AUD_INTF_BIT_WIDTH_CFG_REG(idx), + QAIF_AIF_SLOT_WIDTH_TX_MASK | + QAIF_AIF_SAMPLE_WIDTH_TX_MASK, + QAIF_AIF_SLOT_WIDTH(slot_width) | + (QAIF_AIF_SAMPLE_WIDTH(bitwidth) << + QAIF_AIF_SAMPLE_WIDTH_TX_SHIFT)); + if (ret) + return ret; + ret =3D regmap_write(map, QAIF_AUD_INTF_ACTV_SLOT_EN_TX_REG(idx), + cfg->slot_en_tx_mask); + if (ret) + return ret; + ret =3D regmap_update_bits(map, QAIF_AUD_INTF_MI2S_CFG_REG(idx), + QAIF_AIF_MONO_MODE_TX_BIT, + (channels < 2) ? QAIF_AIF_MONO_MODE_TX_BIT : 0); + } else { + ret =3D regmap_update_bits(map, QAIF_AUD_INTF_BIT_WIDTH_CFG_REG(idx), + QAIF_AIF_SLOT_WIDTH_RX_MASK | + QAIF_AIF_SAMPLE_WIDTH_RX_MASK, + (QAIF_AIF_SLOT_WIDTH(slot_width) << + QAIF_AIF_SLOT_WIDTH_RX_SHIFT) | + (QAIF_AIF_SAMPLE_WIDTH(bitwidth) << + QAIF_AIF_SAMPLE_WIDTH_RX_SHIFT)); + if (ret) + return ret; + ret =3D regmap_write(map, QAIF_AUD_INTF_ACTV_SLOT_EN_RX_REG(idx), + cfg->slot_en_rx_mask); + if (ret) + return ret; + ret =3D regmap_update_bits(map, QAIF_AUD_INTF_MI2S_CFG_REG(idx), + QAIF_AIF_MONO_MODE_RX_BIT, + (channels < 2) ? QAIF_AIF_MONO_MODE_RX_BIT : 0); + } + if (ret) + return ret; + + ret =3D regmap_update_bits(map, QAIF_AUD_INTF_FRAME_CFG_REG(idx), + QAIF_AIF_BITS_PER_LANE_MASK, + (slot_width * cfg->slot_num) - 1); + if (ret) + return ret; + + return 0; +} + +static int qaif_aif_cpu_daiops_trigger(struct snd_pcm_substream *substream, + int cmd, struct snd_soc_dai *dai) +{ + struct qaif_drv_data *drvdata =3D snd_soc_dai_get_drvdata(dai); + const struct qaif_variant *v =3D drvdata->variant; + const struct qaif_aif_config *cfg; + unsigned int enable_bit; + int idx, ret; + + idx =3D v->get_dma_idx(dai->driver->id); + if (idx < 0) { + dev_err(dai->dev, "Invalid DMA index: %d\n", idx); + return -EINVAL; + } + + cfg =3D &drvdata->aif_intf_cfg[idx]; + if (cfg->loopback_en) + enable_bit =3D QAIF_AIF_CTL_ENABLE_BIT; + else if (substream->stream =3D=3D SNDRV_PCM_STREAM_PLAYBACK) + enable_bit =3D QAIF_AIF_CTL_ENABLE_TX_BIT; + else + enable_bit =3D QAIF_AIF_CTL_ENABLE_RX_BIT; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + ret =3D regmap_update_bits(drvdata->audio_qaif_map, + QAIF_AUD_INTF_CTL_REG(idx), enable_bit, enable_bit); + if (ret) + dev_err(dai->dev, "error setting AIF enable bit: %d\n", ret); + return ret; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + ret =3D regmap_update_bits(drvdata->audio_qaif_map, + QAIF_AUD_INTF_CTL_REG(idx), enable_bit, 0); + if (ret) + dev_err(dai->dev, "error clearing AIF enable bit: %d\n", ret); + return ret; + default: + dev_err(dai->dev, "invalid trigger cmd %d\n", cmd); + return -EINVAL; + } +} + +static int qaif_aif_cpu_daiops_set_tdm_slot(struct snd_soc_dai *dai, + unsigned int tx_mask, + unsigned int rx_mask, int slots, + int slot_width) +{ + struct qaif_drv_data *drvdata =3D snd_soc_dai_get_drvdata(dai); + const struct qaif_variant *v =3D drvdata->variant; + int idx =3D v->get_dma_idx(dai->driver->id); + struct qaif_aif_config *cfg; + + if (idx < 0) + return -EINVAL; + + if (slots <=3D 0 || slot_width <=3D 0) + return -EINVAL; + + if (slot_width > QAIF_AIF_SLOT_WIDTH_MAX || + slots * slot_width > QAIF_AIF_FRAME_BITS_MAX) + return -EINVAL; + + cfg =3D &drvdata->aif_intf_cfg[idx]; + cfg->slot_num =3D slots; + cfg->slot_width =3D slot_width; + cfg->slot_en_tx_mask =3D tx_mask; + cfg->slot_en_rx_mask =3D rx_mask; + + return 0; +} + +static int qaif_aif_cpu_daiops_set_sysclk(struct snd_soc_dai *dai, + int clk_id, unsigned int freq, + int dir) +{ + struct qaif_drv_data *drvdata =3D snd_soc_dai_get_drvdata(dai); + const struct qaif_variant *v =3D drvdata->variant; + int idx =3D v->get_dma_idx(dai->driver->id); + + if (idx < 0) + return -EINVAL; + + /* + * The bit clock is prepared and enabled for the lifetime of the + * stream by startup()/shutdown(); only the rate is set here. + */ + return clk_set_rate(drvdata->mi2s_bit_clk[idx], freq); +} + +static int qaif_aif_cpu_daiops_set_fmt(struct snd_soc_dai *dai, + unsigned int fmt) +{ + struct qaif_drv_data *drvdata =3D snd_soc_dai_get_drvdata(dai); + const struct qaif_variant *v =3D drvdata->variant; + int idx =3D v->get_dma_idx(dai->driver->id); + struct qaif_aif_config *cfg; + + if (idx < 0) + return -EINVAL; + + cfg =3D &drvdata->aif_intf_cfg[idx]; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + cfg->sync_mode =3D QAIF_AIF_SYNC_MODE_LONG; + cfg->sync_delay =3D QAIF_AIF_SYNC_DELAY_ONE; + break; + case SND_SOC_DAIFMT_DSP_A: + cfg->sync_mode =3D QAIF_AIF_SYNC_MODE_ONE_SLOT; + cfg->sync_delay =3D QAIF_AIF_SYNC_DELAY_ONE; + break; + case SND_SOC_DAIFMT_DSP_B: + cfg->sync_mode =3D QAIF_AIF_SYNC_MODE_SHORT; + cfg->sync_delay =3D QAIF_AIF_SYNC_DELAY_SAME; + break; + default: + dev_err(dai->dev, "unsupported format 0x%x\n", + fmt & SND_SOC_DAIFMT_FORMAT_MASK); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_CBP_CFP: + cfg->sync_src =3D 1; + break; + case SND_SOC_DAIFMT_CBC_CFC: + cfg->sync_src =3D 0; + break; + default: + dev_err(dai->dev, "unsupported clock provider mode\n"); + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + case SND_SOC_DAIFMT_NB_IF: + cfg->invert_sync =3D (fmt & SND_SOC_DAIFMT_INV_MASK) =3D=3D + SND_SOC_DAIFMT_NB_IF; + break; + default: + dev_err(dai->dev, "bit clock inversion is not supported\n"); + return -EINVAL; + } + + return 0; +} + +/* + * asoc_qcom_qaif_aif_cpu_dai_ops - DAI ops for QAIF AIF (MI2S/TDM/PCM) pa= ths + * + * Provides startup, shutdown, hw_params and trigger callbacks + * for the Unified Audio Interface (AIF) DAI. Used by Shikra machine + * drivers for MI2S, TDM and PCM serial audio paths. + */ +const struct snd_soc_dai_ops asoc_qcom_qaif_aif_cpu_dai_ops =3D { + .set_fmt =3D qaif_aif_cpu_daiops_set_fmt, + .set_tdm_slot =3D qaif_aif_cpu_daiops_set_tdm_slot, + .set_sysclk =3D qaif_aif_cpu_daiops_set_sysclk, + .startup =3D qaif_aif_cpu_daiops_startup, + .shutdown =3D qaif_aif_cpu_daiops_shutdown, + .hw_params =3D qaif_aif_cpu_daiops_hw_params, + .trigger =3D qaif_aif_cpu_daiops_trigger, +}; +EXPORT_SYMBOL_GPL(asoc_qcom_qaif_aif_cpu_dai_ops); + +static const struct snd_soc_component_driver qaif_cpu_comp_driver =3D { + .name =3D "qaif-cpu", +}; + +static const struct regmap_config audio_qaif_regmap_config =3D { + .name =3D "audio_qaif_cpu", + .reg_bits =3D 32, + .reg_stride =3D 4, + .val_bits =3D 32, + .cache_type =3D REGCACHE_NONE, +}; + +static int of_qaif_parse_aif_intf_cfg(struct device *dev, + struct qaif_drv_data *data) +{ + const struct qaif_variant *v =3D data->variant; + struct device_node *np =3D dev->of_node; + struct device_node *intf_np; + struct qaif_aif_config *cfg; + int ret; + u32 dai_id; + int intf_idx; + int num_interfaces =3D 0; + u32 val_buf[QAIF_MAX_LANES]; + int j, n; + unsigned long configured_intf_mask =3D 0; + + for_each_child_of_node(np, intf_np) { + if (!of_property_present(intf_np, "reg")) + continue; + + if (num_interfaces >=3D QAIF_MAX_AIF_CFG_CNT) { + dev_warn(dev, "Too many AIF interfaces, limiting to %d\n", + QAIF_MAX_AIF_CFG_CNT); + of_node_put(intf_np); + break; + } + + ret =3D of_property_read_u32(intf_np, "reg", &dai_id); + if (ret) { + dev_err(dev, "Missing reg for interface %pOFn\n", intf_np); + of_node_put(intf_np); + return ret; + } + + intf_idx =3D v->get_dma_idx(dai_id); + if (intf_idx < 0) { + dev_err(dev, "Invalid DAI ID %d for interface %pOFn\n", + dai_id, intf_np); + of_node_put(intf_np); + return -EINVAL; + } + if (intf_idx >=3D ARRAY_SIZE(data->aif_intf_cfg)) { + dev_err(dev, "DAI ID %d maps to out-of-range intf_idx %d\n", + dai_id, intf_idx); + of_node_put(intf_np); + return -EINVAL; + } + + if (configured_intf_mask & BIT(intf_idx)) { + dev_err(dev, "Duplicate reg %d for interface %pOFn\n", + dai_id, intf_np); + of_node_put(intf_np); + return -EINVAL; + } + configured_intf_mask |=3D BIT(intf_idx); + + cfg =3D &data->aif_intf_cfg[intf_idx]; + if (v->aif_full_cycle_en) + cfg->full_cycle_en =3D v->aif_full_cycle_en[intf_idx]; + if (v->aif_ctrl_data_oe) + cfg->ctrl_data_oe =3D v->aif_ctrl_data_oe[intf_idx]; + if (v->aif_loopback_en) + cfg->loopback_en =3D v->aif_loopback_en[intf_idx]; + + switch (snd_soc_daifmt_parse_format(intf_np, NULL) & + SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + cfg->sync_mode =3D QAIF_AIF_SYNC_MODE_LONG; + cfg->sync_delay =3D QAIF_AIF_SYNC_DELAY_ONE; + cfg->invert_sync =3D true; + break; + case SND_SOC_DAIFMT_DSP_A: + cfg->sync_mode =3D QAIF_AIF_SYNC_MODE_ONE_SLOT; + cfg->sync_delay =3D QAIF_AIF_SYNC_DELAY_ONE; + break; + case SND_SOC_DAIFMT_DSP_B: + cfg->sync_mode =3D QAIF_AIF_SYNC_MODE_SHORT; + cfg->sync_delay =3D QAIF_AIF_SYNC_DELAY_SAME; + break; + default: + break; + } + + if (!qaif_is_aif_mi2s_port(dai_id)) { + ret =3D of_property_read_u32(intf_np, "dai-tdm-slot-width", + &cfg->slot_width); + if (ret || !cfg->slot_width) { + dev_err(dev, "Missing/invalid dai-tdm-slot-width for %pOFn\n", + intf_np); + of_node_put(intf_np); + return ret ? ret : -EINVAL; + } + ret =3D of_property_read_u32(intf_np, "dai-tdm-slot-num", + &cfg->slot_num); + if (ret || !cfg->slot_num) { + dev_err(dev, "Missing/invalid dai-tdm-slot-num for %pOFn\n", + intf_np); + of_node_put(intf_np); + return ret ? ret : -EINVAL; + } + snd_soc_of_get_slot_mask(intf_np, "dai-tdm-slot-rx-mask", + &cfg->slot_en_rx_mask); + snd_soc_of_get_slot_mask(intf_np, "dai-tdm-slot-tx-mask", + &cfg->slot_en_tx_mask); + if (!cfg->slot_en_rx_mask && !cfg->slot_en_tx_mask) { + dev_err(dev, "No active TDM slots for %pOFn\n", + intf_np); + of_node_put(intf_np); + return -EINVAL; + } + } + + n =3D of_property_read_variable_u32_array(intf_np, + "qcom,qaif-aif-lane-map", + val_buf, 1, QAIF_MAX_LANES); + if (n < 0) { + dev_err(dev, "Missing qcom,qaif-aif-lane-map for %pOFn\n", + intf_np); + of_node_put(intf_np); + return n; + } + for (j =3D 0; j < n; j++) { + if (val_buf[j] > 1) { + dev_err(dev, "Invalid lane-map value %u for %pOFn\n", + val_buf[j], intf_np); + of_node_put(intf_np); + return -EINVAL; + } + cfg->lane_en_mask |=3D BIT(j); + if (val_buf[j]) + cfg->lane_dir_mask |=3D BIT(j); + } + + num_interfaces++; + } + + return 0; +} + +/** + * asoc_qcom_qaif_cpu_platform_probe - Probe the QAIF CPU and platform dri= ver + * @pdev: Platform device + * + * Initialises the QAIF regmap, parses DT, sets up clocks and registers + * the CPU DAI component and PCM platform. + * + * Return: 0 on success, negative error code on failure. + */ +int asoc_qcom_qaif_cpu_platform_probe(struct platform_device *pdev) +{ + struct regmap_config regmap_cfg =3D audio_qaif_regmap_config; + struct qaif_drv_data *drvdata; + struct resource *res; + const struct qaif_variant *variant; + struct device *dev =3D &pdev->dev; + const struct of_device_id *match; + int ret, i, dai_id, idx; + + drvdata =3D devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL); + if (!drvdata) + return dev_err_probe(dev, -ENOMEM, "Failed to allocate driver data\n"); + platform_set_drvdata(pdev, drvdata); + + match =3D of_match_device(dev->driver->of_match_table, dev); + if (!match || !match->data) + return dev_err_probe(dev, -EINVAL, "No matching device data\n"); + + drvdata->variant =3D match->data; + variant =3D drvdata->variant; + + if (!variant->get_dma_idx) + return dev_err_probe(dev, -EINVAL, + "variant is missing get_dma_idx callback\n"); + + ret =3D of_qaif_parse_aif_intf_cfg(dev, drvdata); + if (ret) + return dev_err_probe(dev, ret, "Failed to parse aif interfaces\n"); + + drvdata->audio_qaif =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(drvdata->audio_qaif)) + return dev_err_probe(dev, PTR_ERR(drvdata->audio_qaif), + "Failed to ioremap QAIF registers\n"); + + res =3D platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (!res) + return dev_err_probe(dev, -EINVAL, "Failed to get MMIO resource\n"); + + regmap_cfg.max_register =3D resource_size(res) - regmap_cfg.reg_stride; + drvdata->audio_qaif_map =3D devm_regmap_init_mmio(dev, drvdata->audio_qai= f, + ®map_cfg); + if (IS_ERR(drvdata->audio_qaif_map)) + return dev_err_probe(dev, PTR_ERR(drvdata->audio_qaif_map), + "Failed to init regmap\n"); + + drvdata->aud_dma_clk =3D devm_clk_get(dev, "aud_dma"); + if (IS_ERR(drvdata->aud_dma_clk)) + return dev_err_probe(dev, PTR_ERR(drvdata->aud_dma_clk), + "Failed to get aud_dma clock\n"); + + drvdata->aud_dma_mem_clk =3D devm_clk_get(dev, "aud_dma_mem"); + if (IS_ERR(drvdata->aud_dma_mem_clk)) + return dev_err_probe(dev, PTR_ERR(drvdata->aud_dma_mem_clk), + "Failed to get aud_dma_mem clock\n"); + + for (i =3D 0; i < variant->num_dai; i++) { + dai_id =3D variant->dai_driver[i].id; + if (qaif_is_cif_port(dai_id)) + continue; + idx =3D variant->get_dma_idx(dai_id); + if (idx < 0) + continue; + + if (drvdata->mi2s_bit_clk[idx]) + continue; + + drvdata->mi2s_bit_clk[idx] =3D + devm_clk_get(dev, variant->dai_bit_clk_names[idx]); + if (IS_ERR(drvdata->mi2s_bit_clk[idx])) + return dev_err_probe(dev, PTR_ERR(drvdata->mi2s_bit_clk[idx]), + "Failed to get bit clock %d\n", idx); + } + + drvdata->num_clks =3D variant->num_clks; + drvdata->clks =3D devm_kcalloc(dev, drvdata->num_clks, + sizeof(*drvdata->clks), GFP_KERNEL); + if (!drvdata->clks) + return dev_err_probe(dev, -ENOMEM, "Failed to allocate clocks\n"); + + 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) + return dev_err_probe(dev, ret, "Failed to get clocks\n"); + + ret =3D devm_pm_runtime_enable(dev); + if (ret) + return dev_err_probe(dev, ret, "Failed to enable runtime PM\n"); + + ret =3D devm_snd_soc_register_component(dev, &qaif_cpu_comp_driver, + variant->dai_driver, variant->num_dai); + if (ret) + return dev_err_probe(dev, ret, "error registering cpu driver\n"); + + return asoc_qcom_qaif_platform_register(pdev); +} +EXPORT_SYMBOL_GPL(asoc_qcom_qaif_cpu_platform_probe); + +static int asoc_qcom_qaif_runtime_suspend(struct device *dev) +{ + struct qaif_drv_data *drvdata =3D dev_get_drvdata(dev); + + clk_bulk_disable_unprepare(drvdata->num_clks, drvdata->clks); + return 0; +} + +static int asoc_qcom_qaif_runtime_resume(struct device *dev) +{ + struct qaif_drv_data *drvdata =3D dev_get_drvdata(dev); + + return clk_bulk_prepare_enable(drvdata->num_clks, drvdata->clks); +} + +EXPORT_GPL_DEV_PM_OPS(asoc_qcom_qaif_pm_ops) =3D { + RUNTIME_PM_OPS(asoc_qcom_qaif_runtime_suspend, + asoc_qcom_qaif_runtime_resume, NULL) + SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume) +}; + +MODULE_DESCRIPTION("Qualcomm Audio Interface (QAIF) CPU DAI driver"); +MODULE_AUTHOR("Harendra Gautam "); +MODULE_LICENSE("GPL"); --=20 2.34.1 From nobody Fri Sep 25 14:31:50 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 76381471CF9; Fri, 11 Sep 2026 09:20:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118408; cv=none; b=gxx9/Bjdxnp6hwm7beCaXzlNc0avqei0nroC3K3Kn0ZUV0Jcn5hJfDKT/XZG5qqnNQE4b8Dzdmpf2oAw0C9fnTpMbZF6cvfSprExaE9UTKOj5evohXa7vsNmbXAy1mmYbMe8UsMqjAZ5i6bbhWGU1Zj1QUtfspPVVZ/cCg79MzM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118408; c=relaxed/simple; bh=mlMTLQ7tIxz62IXqVC1ezTP7gqDCbVHHehLD9vHfAoU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=pL68t4ALB52TlXYAY44UVMRP2Oc3LyEY4HAGxaw3oyr5tNCZhL2KGkLrhkh72jXUzngKETGJ7lmc4v/BNfgjpGrzn9GY/6DW5rvTqo7mQCitu5CPv4iQwEYYO8Ftk/QhPFLiZjG0Ez39tL/8+1QRd8//N8M+uy+aPCjaAe+UWdo= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=HA0yJHD/; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="HA0yJHD/" Received: from pps.filterd (m0279872.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B7kbn02831841; Fri, 11 Sep 2026 09:19:27 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= RL1Vgd3KT46F8p0X1dUXEvKStXwgH6I1W2BexVhSZVg=; b=HA0yJHD/0NCKAAZo 8vQtH2Y6V0u2/iu7XWPBMrVhzYK6OjXlz6cHV9oCqpm9Rb4cSS9GyPO7I3IMJlHu qslieQLjJ3H3XU8KVae7roNHpHweBuqsNbUdZuQoddlmiqYA05FLtUoY87wEnwhx fhuoT4y93r6c6SugSTtT8aaxdH+9RWgUKmFW6INtHxa5UzrfwBLVlqfTc5JBE3sU JVGbmnbjuiDEF4C/ZU7riSEDE57hXu+RSroibOLmG4V3ZjTFvIGiMK+wZPUeQmZP 1BaZA5t4Mu34V0rZsrmvoBMdkDFLxvC7v1mm8EXJ0LYKEKSWtlhLQzokr1w75HAW RPWwEA== Received: from apblrppmta02.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gmcgfgmph-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 09:19:27 +0000 (GMT) Received: from pps.filterd (apblrppmta02.qualcomm.com [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B9JMw52870843; Fri, 11 Sep 2026 09:19:24 GMT Received: from hu-hgautam-hyd.qualcomm.com (hu-hgautam-hyd.qualcomm.com [10.147.247.91]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTP id 68B9JL2b2870824; Fri, 11 Sep 2026 09:19:24 +0000 (GMT) From: Harendra Gautam Date: Fri, 11 Sep 2026 14:47:29 +0530 Subject: [PATCH v6 05/10] ASoC: soc-core: Add snd_soc_of_xlate_dai_name() generic helper Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260911-b4-qaif-shikra-audio-v6-5-e9addb358201@oss.qualcomm.com> References: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> In-Reply-To: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> To: Srinivas Kandagatla Cc: Mark Brown , Liam Girdwood , Rob Herring , Krzysztof Kozlowski , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai , Kuninori Morimoto , linux-sound@vger.kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Prasad Kumpatla , Krzysztof Kozlowski , Sarath Ganapathiraju , Kumar Anurag Singh , Mohammad Rafi Shaik , Harendra Gautam X-Mailer: b4 0.15.2 X-Proofpoint-Reinject: loops=2 maxloops=12 X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfX6ok7E7U83InW SCp6n07eiQz+aUMn30+iU5jgd2mZECRlqtHxn+j3L2Ec2Ajxax6X9iy6MplSLmq0NppEskYXOxO cYbM/+kD1Bhccg0xsf7sSGiIR/hUpwExlUDM4Xdj48uDMtzUdV3WC4obt1gUXSFOFL7IY2fyMxK Mf7vpcZjpTfGDbL34yTRmuRyZsxKouKiuSdwizQOzWenOPQ2q41lkGZwsXpWN6AqXliX7760Cv/ Vig3rIJGsHLyhUc293LI7d728fdfcZAqoeRrG+rLR3yrudW0fL9uMe/XUv2rfBpm19E4XFaIJBU NbigE4SfHf+BE5X7he9JI7l52xellMxJ7D6e6/FamoRuUARr7PIYk81xUQIK4Tx1oqAKmPgzUzF zODKBPCBDTjkkti3D93DM3Im7Rk8w/Sp9LC8DQUKjjkaII2wfuo9tNUFZDlnh9GwlHnXcYJGAlU 95G1tx7pIhuZv8K5tCQ== X-Proofpoint-GUID: 0OoxTXucw-sQzaXPjotA_hIPjI9SgQQG X-Proofpoint-ORIG-GUID: 0OoxTXucw-sQzaXPjotA_hIPjI9SgQQG X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfX8sW4UIQ3iMH9 k+uk9f7lZiaRJ1IbxcPTvGII6pJtEJxMc52KdVLr7a14eu74+zzi2eQwbxFxXe0Y65wv1/y4H5T W+TucDK3ekRuooVjlkkPmoku9oWib6o= X-Authority-Analysis: v=2.4 cv=ULtIjyfy c=1 sm=1 tr=0 ts=6aa3c79f cx=c_pps a=Ou0eQOY4+eZoSc0qltEV5Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=yx91gb_oNiZeI1HMLzn7:22 a=EUspDBNiAAAA:8 a=bovOucATokvHoRHO1osA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_03,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 priorityscore=1501 adultscore=0 phishscore=0 bulkscore=0 clxscore=1015 malwarescore=0 suspectscore=0 spamscore=0 lowpriorityscore=0 impostorscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110129 Some ASoC CPU DAI drivers need to resolve a sound-dai phandle argument to a DAI name by matching the argument against the component's DAI IDs. lpass-cpu carries a local implementation of this lookup. Add snd_soc_of_xlate_dai_name() to soc-core.c as a generic helper that can be assigned directly to the .of_xlate_dai_name component driver callback. It iterates the component's DAI list using for_each_component_dais() and matches by DAI ID. Signed-off-by: Harendra Gautam --- include/sound/soc.h | 3 +++ sound/soc/soc-core.c | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/include/sound/soc.h b/include/sound/soc.h index f46b2bc2a022..b772273b7183 100644 --- a/include/sound/soc.h +++ b/include/sound/soc.h @@ -1330,6 +1330,9 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np, unsigned int *rx_mask, unsigned int *slots, unsigned int *slot_width); +int snd_soc_of_xlate_dai_name(struct snd_soc_component *component, + const struct of_phandle_args *args, + const char **dai_name); void snd_soc_of_parse_node_prefix(struct device_node *np, struct snd_soc_codec_conf *codec_conf, struct device_node *of_node, diff --git a/sound/soc/soc-core.c b/sound/soc/soc-core.c index b9c70268d49f..42c57c24ab70 100644 --- a/sound/soc/soc-core.c +++ b/sound/soc/soc-core.c @@ -3053,6 +3053,39 @@ int snd_soc_of_parse_tdm_slot(struct device_node *np, } EXPORT_SYMBOL_GPL(snd_soc_of_parse_tdm_slot); =20 +/** + * snd_soc_of_xlate_dai_name - Resolve a sound-dai phandle argument to a + * DAI name by searching the component DAI lis= t. + * @component: ASoC component to search. + * @args: Phandle arguments from the sound-dai property; args[0] is t= he + * DAI ID. + * @dai_name: Output pointer set to the matched DAI name on success. + * + * Return: 0 on success, -EINVAL if args_count !=3D 1 or no match is found. + */ +int snd_soc_of_xlate_dai_name(struct snd_soc_component *component, + const struct of_phandle_args *args, + const char **dai_name) +{ + struct snd_soc_dai *dai; + int id; + + if (args->args_count !=3D 1) + return -EINVAL; + + id =3D args->args[0]; + + for_each_component_dais(component, dai) { + if (dai->driver->id =3D=3D id) { + *dai_name =3D snd_soc_dai_name_get(dai); + return 0; + } + } + + return -EINVAL; +} +EXPORT_SYMBOL_GPL(snd_soc_of_xlate_dai_name); + void snd_soc_dlc_use_cpu_as_platform(struct snd_soc_dai_link_component *pl= atforms, struct snd_soc_dai_link_component *cpus) { --=20 2.34.1 From nobody Fri Sep 25 14:31:50 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 76C3E472F66; Fri, 11 Sep 2026 09:20:06 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118408; cv=none; b=NzCv8yTnw6RGLZb3SuM8jodoXjkxUdE/rGjMNvI7UkMKdbVIYA4Doi1ErHCohdVoV5jqFSRDAvXjkQk9crq5AkBAILWgU3C/yHNllQ8UziU84J5lx3/kgg5FP2X6bqLqWdYWh0w57x0C+xY3g11BjH4T7scwkyKaC6fwGztmn5g= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118408; c=relaxed/simple; bh=Fa2B2z1p2vnYcl9Lt5OrEI5EEaAjDuIeC/VPBFc1ls4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=G0ZW/dZtw9G2AgsdBpD9IQMgp1OCW01xaWoe0GtpuPNdw49A9dOAIMc4XlRqfUGkOQ9Hmw7dy/a+08JSrGAc+WZo3kpz+0W5gCiUDIm/TsDGAiSulliGCzqWb16kqSisiXqybkZzy6EeKfiw9Tx0L2kXGTK7FBxzlq4hsEh8+FU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=Q/yMEmGb; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="Q/yMEmGb" Received: from pps.filterd (m0279868.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B7kqVW3366446; Fri, 11 Sep 2026 09:19:28 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= PZQ3j0/GmXO1wptiFOYvqy5+qNLnbETvh0uO4ql081U=; b=Q/yMEmGbtSuitt/5 CRttM6yzj2ti5EEijT6S1OBja7vPQMCyTvlhNM+PZSrWYnqEW1bLFO5G3cbkOSWI M6yyRl1qNoIbJ1EMJRDTbg6r81rbS8ElgFct5tjsQZaQW1ZII5svMLU7zSCYne1E Si4la85QhW5mxeAI6lrR553IKOv8nN3pFr0vpA2UFln49q2Btda6CU/VU++5ZxmM k5K80EnyhN/WYJWb/jEm5rYysltS4MhvYs6ZZnyHiXDmnT0ry1VYkXoxGSJift9k XqSwsqIeFbcekFirH7jb5l2Ygo1DLjPyxNTj8nScXjI4HlcO+2anMEQGgrMb6jf3 g9HrtA== Received: from apblrppmta02.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gm1k2b39v-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 09:19:27 +0000 (GMT) Received: from pps.filterd (apblrppmta02.qualcomm.com [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B9JPPw2871029; Fri, 11 Sep 2026 09:19:25 GMT Received: from hu-hgautam-hyd.qualcomm.com (hu-hgautam-hyd.qualcomm.com [10.147.247.91]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTP id 68B9JL2c2870824; Fri, 11 Sep 2026 09:19:24 +0000 (GMT) From: Harendra Gautam Date: Fri, 11 Sep 2026 14:47:30 +0530 Subject: [PATCH v6 06/10] ASoC: qcom: Switch lpass-cpu and qaif-cpu to snd_soc_of_xlate_dai_name() Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260911-b4-qaif-shikra-audio-v6-6-e9addb358201@oss.qualcomm.com> References: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> In-Reply-To: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> To: Srinivas Kandagatla Cc: Mark Brown , Liam Girdwood , Rob Herring , Krzysztof Kozlowski , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai , Kuninori Morimoto , linux-sound@vger.kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Prasad Kumpatla , Krzysztof Kozlowski , Sarath Ganapathiraju , Kumar Anurag Singh , Mohammad Rafi Shaik , Harendra Gautam X-Mailer: b4 0.15.2 X-Proofpoint-Reinject: loops=2 maxloops=12 X-QCInternal: smtphost X-QCInternal: smtphost X-Authority-Analysis: v=2.4 cv=cM11IVeN c=1 sm=1 tr=0 ts=6aa3c7a0 cx=c_pps a=Ou0eQOY4+eZoSc0qltEV5Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=ZpdpYltYx_vBUK5n70dp:22 a=EUspDBNiAAAA:8 a=Hfps_RfwFyUEpd0PCboA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-GUID: Ae6F_WgE2fEuWe_6ZIu0mmMAprJc9INd X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfXxcKKYwoD3/x6 0Yk719aSuoWaxPj2uUF2BNDR8uSQhQhuTNSMlA5002VDxtCiznDxlXTWn3C+AUA1mqeeU0IIDnh If5v6judbF6em8uriI5zWq5H2WceEcw= X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfXzLf4g6DSPlBs /oO/qheplprhWthMX1IsJm1yowMZQvRgDT5/peDtsm5xql35Sn2Tae37gACLK38AUmUdMaq4uxW 5QmvHc3lHNMs5NicojXcjZNTAHgh6Rgrxeidc325twrF2qf3FPYCTXq2zF6FzrL1kH+Q7Dceaka MIZVfcaoYDAdiw29nFraprHXNK2sK3mAGz5IxsETDMI+zBN3ihf80b2XMQZ++mrzv4zxy4EwoNi U90C5kTldfF17uD5QMCfZKVVtqYKIeIxhCUmcVhBZeSf7INywhvKCG71ZiortK4ZCAs2HqzIiNY LLugi9cIEjEUzrUTzdqW3SuabctBfXzC9ihXb2+HzfUJ4U/M8d/m4qZAZZcatdD/K6H5vxVXuQE 8ZFFDiyxCm5QFCtpOZqGV4wS7jrEi9qRarTlJx9vj1+pLWMaLH3LrK4VW3mMlZFgNrOBOe22V3h jIWmuapq6Dtb3r0HZBg== X-Proofpoint-ORIG-GUID: Ae6F_WgE2fEuWe_6ZIu0mmMAprJc9INd X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_03,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 phishscore=0 lowpriorityscore=0 clxscore=1015 adultscore=0 bulkscore=0 priorityscore=1501 impostorscore=0 malwarescore=0 spamscore=0 suspectscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110129 Use the new generic snd_soc_of_xlate_dai_name() helper in lpass-cpu.c and qaif-cpu.c, and remove the local lpass implementation. Signed-off-by: Harendra Gautam --- sound/soc/qcom/lpass-cpu.c | 23 +---------------------- sound/soc/qcom/qaif-cpu.c | 1 + 2 files changed, 2 insertions(+), 22 deletions(-) diff --git a/sound/soc/qcom/lpass-cpu.c b/sound/soc/qcom/lpass-cpu.c index 242bc16da36d..61efa45376cd 100644 --- a/sound/soc/qcom/lpass-cpu.c +++ b/sound/soc/qcom/lpass-cpu.c @@ -458,30 +458,9 @@ const struct snd_soc_dai_ops asoc_qcom_lpass_cpu_dai_o= ps2 =3D { }; EXPORT_SYMBOL_GPL(asoc_qcom_lpass_cpu_dai_ops2); =20 -static int asoc_qcom_of_xlate_dai_name(struct snd_soc_component *component, - const struct of_phandle_args *args, - const char **dai_name) -{ - struct lpass_data *drvdata =3D snd_soc_component_get_drvdata(component); - const struct lpass_variant *variant =3D drvdata->variant; - int id =3D args->args[0]; - int ret =3D -EINVAL; - int i; - - for (i =3D 0; i < variant->num_dai; i++) { - if (variant->dai_driver[i].id =3D=3D id) { - *dai_name =3D variant->dai_driver[i].name; - ret =3D 0; - break; - } - } - - return ret; -} - static const struct snd_soc_component_driver lpass_cpu_comp_driver =3D { .name =3D "lpass-cpu", - .of_xlate_dai_name =3D asoc_qcom_of_xlate_dai_name, + .of_xlate_dai_name =3D snd_soc_of_xlate_dai_name, .legacy_dai_naming =3D 1, }; =20 diff --git a/sound/soc/qcom/qaif-cpu.c b/sound/soc/qcom/qaif-cpu.c index e1868dc95cf4..c096ef5133bb 100644 --- a/sound/soc/qcom/qaif-cpu.c +++ b/sound/soc/qcom/qaif-cpu.c @@ -594,6 +594,7 @@ EXPORT_SYMBOL_GPL(asoc_qcom_qaif_aif_cpu_dai_ops); =20 static const struct snd_soc_component_driver qaif_cpu_comp_driver =3D { .name =3D "qaif-cpu", + .of_xlate_dai_name =3D snd_soc_of_xlate_dai_name, }; =20 static const struct regmap_config audio_qaif_regmap_config =3D { --=20 2.34.1 From nobody Fri Sep 25 14:31:50 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 2461E472097; Fri, 11 Sep 2026 09:20:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118408; cv=none; b=kH1dQDa1ZZcIYhUyWaiG5+d/eD8E2Z0r26M53vXAWVDmqrZz9f24rY8ypexQXwVGG6c05VtK6Dbg5PYi0J0Yx1G5S0dygNqg/Fwv7bSQil9ncup6aeTbL/AxFo/0yfw0klLfLtOE6pe+IYc78/XnVLvakesSnElRNWi/85RvMlk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118408; c=relaxed/simple; bh=+L9A84UQAY+55WBYE0FtTMZt0PCf9OmVRvaewqTB0l4=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=HPUAWlPLUYQYYADxLnsdQDqwTzccup0NUqbUv++gWqrjKRbxUzUN+WUp84RR6x+UYuDRAAozTmoM3AB9PEZmJ13C3PUeXuk9ZsHQUm8QiaL1tcEzeE0imM2BcM8aWJZXN+QeV7PptMkc9CJso4SwoPB7SLJwTQcYS3O8wLfW5eg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=TGME//G8; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="TGME//G8" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B7l1rV3687109; Fri, 11 Sep 2026 09:19:28 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= tZw8S0EYBzzfN2qRZ+Q+CLFRQS8Z5f2RXX5C6j4QntE=; b=TGME//G8LBXtpXSQ FNUnGt5ATq3z1afHYt3i+92MvYY4YwJQg5+JvC6dGs3MZwc4eXgyErr3qrSVMuri jPVNAGfAFiKX9q3Kgup0tSEdKtzLzb9Gvov+DHUwJw/JmaZRIEJ5O7JyIn6wOUdN p/pj5swNaHWpieoxcgHrhAS6FGuB2DL2cw56ZZLADY+iNh61HM+v3CkVZU+XPOoM pKlnmF3JH8ZnU3Im1vW4LM27NmNL2ksWKdjOJ1HS4ZS6itDjakg9vlvkX4bww1+J aRyhqgP9+KYOl0lvR66oDhKdryI7Y1JpUcE7nuVYpmq4fhj4mdSZS6vEkAPKIois KHiqGQ== Received: from apblrppmta02.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gmapg12kf-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 09:19:28 +0000 (GMT) Received: from pps.filterd (apblrppmta02.qualcomm.com [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B9JNKd2870867; Fri, 11 Sep 2026 09:19:25 GMT Received: from hu-hgautam-hyd.qualcomm.com (hu-hgautam-hyd.qualcomm.com [10.147.247.91]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTP id 68B9JL2d2870824; Fri, 11 Sep 2026 09:19:25 +0000 (GMT) From: Harendra Gautam Date: Fri, 11 Sep 2026 14:47:31 +0530 Subject: [PATCH v6 07/10] ASoC: qcom: Add QAIF PCM operations Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260911-b4-qaif-shikra-audio-v6-7-e9addb358201@oss.qualcomm.com> References: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> In-Reply-To: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> To: Srinivas Kandagatla Cc: Mark Brown , Liam Girdwood , Rob Herring , Krzysztof Kozlowski , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai , Kuninori Morimoto , linux-sound@vger.kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Prasad Kumpatla , Krzysztof Kozlowski , Sarath Ganapathiraju , Kumar Anurag Singh , Mohammad Rafi Shaik , Harendra Gautam X-Mailer: b4 0.15.2 X-Proofpoint-Reinject: loops=2 maxloops=12 X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-ORIG-GUID: dquHEf5QzlXp249NEMuMV6F5eHOFGOds X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfX8xvQaVNO82my p9LQGfkjuQxl9uszXdwRTyaKZcxvtlXDVZjccfiM71g37Ncs87f8bqv8jy6Fv+4Cqbldyi0N5sT AXFFZPzLymw3/UoS8o7Zs8aeMNEeZeE= X-Proofpoint-GUID: dquHEf5QzlXp249NEMuMV6F5eHOFGOds X-Authority-Analysis: v=2.4 cv=DLoacCNb c=1 sm=1 tr=0 ts=6aa3c7a0 cx=c_pps a=Ou0eQOY4+eZoSc0qltEV5Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=EUspDBNiAAAA:8 a=cLyI3y7MXus-7omccr0A:9 a=QEXdDO2ut3YA:10 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfXzPj9+bOAkjXO JVur37JgKSqx2vg94Rs8Nbl3u75UUqidHISmwrR6ljbTEBPwKO9QTjQMR/omXlIRkTWyheDrOM8 KgijXJZ/mk2vrLriCORLpirlJC0ON3VtEEEwLoOK9MiPLMB1f/eRd4d1HeJ3fn9wyzW4UjD34qC eNjXb+PiIkakKPbyITg3U3qdIoAY/sRL2bgZ0Q9xhGxHytmnPNp1wL6h5YUg20ON8xgcpSZedqL n4zHWzOnZAQzu9D50kc5ea7GJTgoyijkw1FUEJL5qoN1hPaPow8J7ZNaUzQEh3aqk5a5ITjxmtQ X0zG1ELsCiB2OVpmlDd1HSyNrBK7OJsayo9JbUFAgS5GhmZbHLsgxGtqi+BjWXBt9zehwI+0NsI EhkVIzKedFTUn6LiKb5Rwe1r98Xjw5FpQVnLV6MvpvcXctomP+KcAxXpzz46cZwfeE4olgnRViV /OdeU7sm+zUZbvxP6WA== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_03,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 priorityscore=1501 phishscore=0 adultscore=0 suspectscore=0 spamscore=0 impostorscore=0 bulkscore=0 clxscore=1015 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110129 Add the PCM platform callbacks needed to use QAIF DAIs for playback and capture. Allocate and map the DMA buffer in open(), reserve a stream DMA index and perform the one-time QAIF hardware initialization. Program the DMA configuration in hw_params(), set the DMA clock rate and program the DMA base, buffer and period registers in prepare(), and report the current DMA position from pointer(). Release all resources in close(). The DMA clocks themselves are prepared and enabled by the CPU DAI driver's startup and shutdown callbacks. Support mmap() for CIF and AIF paths, and add copy() to transfer PCM data between userspace and the DMA buffer. Signed-off-by: Harendra Gautam --- sound/soc/qcom/qaif-platform.c | 539 +++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 539 insertions(+) diff --git a/sound/soc/qcom/qaif-platform.c b/sound/soc/qcom/qaif-platform.c new file mode 100644 index 000000000000..84ce3ad9a1f2 --- /dev/null +++ b/sound/soc/qcom/qaif-platform.c @@ -0,0 +1,539 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * qaif-platform.c -- ALSA SoC PCM platform driver for the Qualcomm Audio = Interface (QAIF) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "qaif-reg.h" +#include "qaif.h" + +#define DRV_NAME "qaif-platform" + +/* period: 5ms @ 48kHz/1ch/S16 min, 20ms @ 48kHz/8ch/S32 max */ +#define QAIF_PLATFORM_PERIOD_BYTES_MIN (48 * 5 * 1 * 2) /* 480 B */ +#define QAIF_PLATFORM_PERIOD_BYTES_MAX (48 * 20 * 8 * 4) /* 30720 B */ +#define QAIF_PLATFORM_PERIODS_MIN 2 +#define QAIF_PLATFORM_PERIODS_MAX 4 +/* QAIF_PLATFORM_PERIODS_MAX * QAIF_PLATFORM_PERIOD_BYTES_MAX =3D 122880 B= */ +#define QAIF_PLATFORM_BUFFER_BYTES_MAX \ + (QAIF_PLATFORM_PERIODS_MAX * QAIF_PLATFORM_PERIOD_BYTES_MAX) + +/* DMA CFG register bit positions */ +#define QAIF_DMACFG_SHRAM_WM_MASK GENMASK(11, 0) +#define QAIF_DMACFG_BURST4_BIT BIT(18) +#define QAIF_DMACFG_DYNCLK_BIT BIT(24) + +/* DMA CTL register bit positions */ +#define QAIF_DMACTL_ENABLE_BIT BIT(0) +#define QAIF_ALL_CLIENTS_MASK (QAIF_BITMASK_AIF_RDDMA_WRDMA | \ + QAIF_BITMASK_CIF_RDDMA_WRDMA) + +static const struct snd_pcm_hardware qaif_platform_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 QAIF_PLATFORM_BUFFER_BYTES_MAX, + .period_bytes_min =3D QAIF_PLATFORM_PERIOD_BYTES_MIN, + .period_bytes_max =3D QAIF_PLATFORM_PERIOD_BYTES_MAX, + .periods_min =3D QAIF_PLATFORM_PERIODS_MIN, + .periods_max =3D QAIF_PLATFORM_PERIODS_MAX, + .fifo_size =3D 0, +}; + +static int qaif_map_ee_resource(struct qaif_drv_data *drvdata) +{ + const struct qaif_variant *v =3D drvdata->variant; + struct regmap *map =3D drvdata->audio_qaif_map; + int ret; + + ret =3D regmap_write(map, QAIF_EE_RDDMA_MAP_REG(v), GENMASK(v->num_rddma = - 1, 0)); + if (ret) + return ret; + ret =3D regmap_write(map, QAIF_EE_WRDMA_MAP_REG(v), GENMASK(v->num_wrdma = - 1, 0)); + if (ret) + return ret; + if (v->num_intf > 0) { + ret =3D regmap_write(map, QAIF_EE_INTF_MAP_REG(v), GENMASK(v->num_intf -= 1, 0)); + if (ret) + return ret; + } + ret =3D regmap_write(map, QAIF_EE_CODEC_RDDMA_MAP_REG(v), + GENMASK(v->num_codec_rddma - 1, 0)); + if (ret) + return ret; + return regmap_write(map, QAIF_EE_CODEC_WRDMA_MAP_REG(v), + GENMASK(v->num_codec_wrdma - 1, 0)); +} + +static int qaif_map_dma_path(struct qaif_drv_data *drvdata) +{ + struct regmap *map =3D drvdata->audio_qaif_map; + int ret; + + if (drvdata->variant->qxm_type !=3D QAIF_QXM0) { + dev_err(regmap_get_device(map), + "only QXM0 is supported, qxm_type=3D%d\n", + drvdata->variant->qxm_type); + return -EINVAL; + } + + ret =3D regmap_write(map, QAIF_RDDMA_MAP_QXM, QAIF_QXM0); + if (ret) + return ret; + ret =3D regmap_write(map, QAIF_WRDMA_MAP_QXM, QAIF_QXM0); + if (ret) + return ret; + ret =3D regmap_write(map, QAIF_CDC_RDDMA_MAP_QXM, QAIF_QXM0); + if (ret) + return ret; + return regmap_write(map, QAIF_CDC_WRDMA_MAP_QXM, QAIF_QXM0); +} + +static int qaif_config_shram(struct qaif_drv_data *drvdata) +{ + const struct qaif_variant *v =3D drvdata->variant; + struct regmap *map =3D drvdata->audio_qaif_map; + u32 start_addr, shram_len; + int ret, i; + + if (v->qxm_type !=3D QAIF_QXM0) { + dev_err(regmap_get_device(map), + "only QXM0 is supported, qxm_type=3D%d\n", + v->qxm_type); + return -EINVAL; + } + + start_addr =3D v->rddma_shram_start_addr[QAIF_AIF_DMA]; + shram_len =3D v->rddma_shram_len; + for (i =3D 0; i < v->num_rddma; i++) { + ret =3D regmap_write(map, QAIF_RDDMA_QXM0_SHRAM_ST_ADDR(i), + start_addr + (shram_len * i)); + if (ret) + return ret; + ret =3D regmap_write(map, QAIF_RDDMA_QXM0_SHRAM_LEN(i), shram_len); + if (ret) + return ret; + } + + start_addr =3D v->wrdma_shram_start_addr[QAIF_AIF_DMA]; + shram_len =3D v->wrdma_shram_len; + for (i =3D 0; i < v->num_wrdma; i++) { + ret =3D regmap_write(map, QAIF_WRDMA_QXM0_SHRAM_ST_ADDR(i), + start_addr + (shram_len * i)); + if (ret) + return ret; + ret =3D regmap_write(map, QAIF_WRDMA_QXM0_SHRAM_LEN(i), shram_len); + if (ret) + return ret; + } + + start_addr =3D v->rddma_shram_start_addr[QAIF_CIF_DMA]; + shram_len =3D v->rddma_shram_len; + for (i =3D 0; i < v->num_codec_rddma; i++) { + ret =3D regmap_write(map, QAIF_CDC_RDDMA_QXM0_SHRAM_ST_ADDR(i), + start_addr + (shram_len * i)); + if (ret) + return ret; + ret =3D regmap_write(map, QAIF_CDC_RDDMA_QXM0_SHRAM_LEN(i), shram_len); + if (ret) + return ret; + } + + start_addr =3D v->wrdma_shram_start_addr[QAIF_CIF_DMA]; + shram_len =3D v->wrdma_shram_len; + for (i =3D 0; i < v->num_codec_wrdma; i++) { + ret =3D regmap_write(map, QAIF_CDC_WRDMA_QXM0_SHRAM_ST_ADDR(i), + start_addr + (shram_len * i)); + if (ret) + return ret; + ret =3D regmap_write(map, QAIF_CDC_WRDMA_QXM0_SHRAM_LEN(i), shram_len); + if (ret) + return ret; + } + return 0; +} + +static int qaif_init(struct snd_soc_component *component) +{ + struct qaif_drv_data *drvdata =3D snd_soc_component_get_drvdata(component= ); + int ret; + + if (drvdata->qaif_hw_configured) + return 0; + + ret =3D qaif_config_shram(drvdata); + if (ret) { + dev_err(component->dev, "failed to config shram: %d\n", ret); + return ret; + } + + ret =3D qaif_map_ee_resource(drvdata); + if (ret) { + dev_err(component->dev, "failed to map EE resources: %d\n", ret); + return ret; + } + + ret =3D qaif_map_dma_path(drvdata); + if (ret) + return ret; + + drvdata->qaif_hw_configured =3D true; + return 0; +} + +static int qaif_platform_pcmops_open(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime =3D substream->runtime; + struct snd_soc_pcm_runtime *soc_runtime =3D snd_soc_substream_to_rtd(subs= tream); + struct snd_soc_dai *cpu_dai =3D snd_soc_rtd_to_cpu(soc_runtime, 0); + struct qaif_drv_data *drvdata =3D snd_soc_component_get_drvdata(component= ); + const struct qaif_variant *v =3D drvdata->variant; + unsigned int dai_id =3D cpu_dai->driver->id; + struct snd_dma_buffer *buf =3D &substream->dma_buffer; + struct qaif_dma_mem_info *dma_mem_info; + struct qaif_pcm_data *data; + int ret, stream_dma_idx, dma_reg_idx, dir =3D substream->stream; + + dma_reg_idx =3D v->get_dma_idx(dai_id); + if (dma_reg_idx < 0) { + dev_err(component->dev, "invalid DMA register index for DAI %u: %d\n", + dai_id, dma_reg_idx); + return dma_reg_idx; + } + + data =3D kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) + return -ENOMEM; + runtime->private_data =3D data; + + buf->dev.dev =3D component->dev; + buf->private_data =3D NULL; + buf->dev.type =3D SNDRV_DMA_TYPE_DEV; + + dma_mem_info =3D kzalloc(sizeof(*dma_mem_info), GFP_KERNEL); + if (!dma_mem_info) { + ret =3D -ENOMEM; + goto err_free_data; + } + dma_mem_info->alloc_size =3D qaif_platform_hardware.buffer_bytes_max; + dma_mem_info->vaddr =3D dma_alloc_coherent(component->dev, + dma_mem_info->alloc_size, + &dma_mem_info->dma_addr, + GFP_KERNEL); + if (!dma_mem_info->vaddr) { + ret =3D -ENOMEM; + goto err_free_mem_info; + } + + mutex_lock(&drvdata->stream_lock); + stream_dma_idx =3D v->alloc_stream_dma_idx(drvdata, dir, dai_id); + mutex_unlock(&drvdata->stream_lock); + if (stream_dma_idx < 0) { + ret =3D stream_dma_idx; + goto err_free_dma; + } + + data->stream_dma_idx =3D stream_dma_idx; + data->dma_reg_idx =3D dma_reg_idx; + + buf->bytes =3D qaif_platform_hardware.buffer_bytes_max; + buf->addr =3D dma_mem_info->dma_addr; + buf->area =3D (unsigned char *)dma_mem_info->vaddr; + + if (qaif_is_cif_port(dai_id)) { + WRITE_ONCE(drvdata->cif_substream[stream_dma_idx], substream); + drvdata->cif_dma_heap[stream_dma_idx] =3D dma_mem_info; + } else { + WRITE_ONCE(drvdata->aif_substream[stream_dma_idx], substream); + drvdata->aif_dma_heap[stream_dma_idx] =3D dma_mem_info; + } + + snd_soc_set_runtime_hwparams(substream, &qaif_platform_hardware); + runtime->dma_bytes =3D qaif_platform_hardware.buffer_bytes_max; + snd_pcm_set_runtime_buffer(substream, buf); + + /* + * The DMA buffer/period length registers are programmed in 64-bit + * (8-byte) words, so constrain buffer and period sizes to that step + * to keep the ALSA and hardware sizes identical. + */ + ret =3D snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_BUFFER_BYTES, + BIT(QAIF_DMA_BYTES_TO_WORDS_SHIFT)); + if (ret >=3D 0) + ret =3D snd_pcm_hw_constraint_step(runtime, 0, + SNDRV_PCM_HW_PARAM_PERIOD_BYTES, + BIT(QAIF_DMA_BYTES_TO_WORDS_SHIFT)); + if (ret >=3D 0) + ret =3D snd_pcm_hw_constraint_integer(runtime, + SNDRV_PCM_HW_PARAM_PERIODS); + if (ret < 0) { + dev_err(soc_runtime->dev, "setting constraints failed: %d\n", ret); + if (qaif_is_cif_port(dai_id)) { + WRITE_ONCE(drvdata->cif_substream[stream_dma_idx], NULL); + drvdata->cif_dma_heap[stream_dma_idx] =3D NULL; + } else { + WRITE_ONCE(drvdata->aif_substream[stream_dma_idx], NULL); + drvdata->aif_dma_heap[stream_dma_idx] =3D NULL; + } + mutex_lock(&drvdata->stream_lock); + v->free_stream_dma_idx(drvdata, stream_dma_idx, dai_id); + mutex_unlock(&drvdata->stream_lock); + goto err_free_dma; + } + return 0; + +err_free_dma: + dma_free_coherent(component->dev, dma_mem_info->alloc_size, + dma_mem_info->vaddr, dma_mem_info->dma_addr); +err_free_mem_info: + kfree(dma_mem_info); +err_free_data: + kfree(data); + return ret; +} + +static int qaif_platform_pcmops_close(struct snd_soc_component *component, + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *soc_runtime =3D snd_soc_substream_to_rtd(subs= tream); + struct snd_soc_dai *cpu_dai =3D snd_soc_rtd_to_cpu(soc_runtime, 0); + struct qaif_drv_data *drvdata =3D snd_soc_component_get_drvdata(component= ); + const struct qaif_variant *v =3D drvdata->variant; + struct qaif_pcm_data *data =3D substream->runtime->private_data; + struct qaif_dma_mem_info *dma_mem_info; + unsigned int dai_id =3D cpu_dai->driver->id; + + if (qaif_is_cif_port(dai_id)) { + WRITE_ONCE(drvdata->cif_substream[data->stream_dma_idx], NULL); + dma_mem_info =3D drvdata->cif_dma_heap[data->stream_dma_idx]; + drvdata->cif_dma_heap[data->stream_dma_idx] =3D NULL; + } else { + WRITE_ONCE(drvdata->aif_substream[data->stream_dma_idx], NULL); + dma_mem_info =3D drvdata->aif_dma_heap[data->stream_dma_idx]; + drvdata->aif_dma_heap[data->stream_dma_idx] =3D NULL; + } + + mutex_lock(&drvdata->stream_lock); + v->free_stream_dma_idx(drvdata, data->stream_dma_idx, dai_id); + mutex_unlock(&drvdata->stream_lock); + + if (dma_mem_info) { + dma_free_coherent(component->dev, dma_mem_info->alloc_size, + dma_mem_info->vaddr, dma_mem_info->dma_addr); + kfree(dma_mem_info); + } + + substream->dma_buffer.area =3D NULL; + substream->dma_buffer.addr =3D 0; + substream->dma_buffer.bytes =3D 0; + snd_pcm_set_runtime_buffer(substream, NULL); + substream->runtime->private_data =3D NULL; + + kfree(data); + return 0; +} + +static int qaif_platform_pcmops_hw_params(struct snd_soc_component *compon= ent, + struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params) +{ + struct snd_soc_pcm_runtime *soc_runtime =3D snd_soc_substream_to_rtd(subs= tream); + struct snd_soc_dai *cpu_dai =3D snd_soc_rtd_to_cpu(soc_runtime, 0); + struct qaif_drv_data *drvdata =3D snd_soc_component_get_drvdata(component= ); + const struct qaif_variant *v =3D drvdata->variant; + struct qaif_pcm_data *data =3D substream->runtime->private_data; + unsigned int dai_id =3D cpu_dai->driver->id; + int idx =3D data->dma_reg_idx; + int ret; + + mutex_lock(&drvdata->stream_lock); + ret =3D qaif_init(component); + mutex_unlock(&drvdata->stream_lock); + if (ret) { + dev_err(soc_runtime->dev, "qaif_init failed: %d\n", ret); + return ret; + } + + ret =3D regmap_update_bits(drvdata->audio_qaif_map, + qaif_dmacfg_reg(v, idx, substream->stream, dai_id), + QAIF_DMACFG_BURST4_BIT | QAIF_DMACFG_SHRAM_WM_MASK, + QAIF_DMACFG_BURST4_BIT | QAIF_DMACTL_WM_5); + if (ret) + dev_err(soc_runtime->dev, "error updating DMA CFG: %d\n", ret); + return ret; +} + +static int qaif_platform_pcmops_hw_free(struct snd_soc_component *componen= t, + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *soc_runtime =3D snd_soc_substream_to_rtd(subs= tream); + struct snd_soc_dai *cpu_dai =3D snd_soc_rtd_to_cpu(soc_runtime, 0); + struct qaif_drv_data *drvdata =3D snd_soc_component_get_drvdata(component= ); + const struct qaif_variant *v =3D drvdata->variant; + struct qaif_pcm_data *data =3D substream->runtime->private_data; + unsigned int dai_id =3D cpu_dai->driver->id; + int idx =3D data->dma_reg_idx; + int ret; + + ret =3D regmap_update_bits(drvdata->audio_qaif_map, + qaif_dmactl_reg(v, idx, substream->stream, dai_id), + QAIF_DMACTL_ENABLE_BIT, 0); + if (ret) { + dev_err(soc_runtime->dev, "error disabling DMA: %d\n", ret); + return ret; + } + + ret =3D regmap_write(drvdata->audio_qaif_map, + qaif_dmacfg_reg(v, idx, substream->stream, dai_id), 0); + if (ret) + dev_err(soc_runtime->dev, "error clearing DMA CFG: %d\n", ret); + return ret; +} + +static int qaif_platform_pcmops_prepare(struct snd_soc_component *componen= t, + struct snd_pcm_substream *substream) +{ + struct snd_pcm_runtime *runtime =3D substream->runtime; + struct snd_soc_pcm_runtime *soc_runtime =3D snd_soc_substream_to_rtd(subs= tream); + struct snd_soc_dai *cpu_dai =3D snd_soc_rtd_to_cpu(soc_runtime, 0); + struct qaif_drv_data *drvdata =3D snd_soc_component_get_drvdata(component= ); + const struct qaif_variant *v =3D drvdata->variant; + struct regmap *map =3D drvdata->audio_qaif_map; + struct qaif_pcm_data *data =3D runtime->private_data; + unsigned int dai_id =3D cpu_dai->driver->id; + int idx =3D data->dma_reg_idx; + int ret, dir =3D substream->stream; + + ret =3D clk_set_rate(drvdata->aud_dma_clk, QAIF_DMA_CLOCK_FREQ); + if (ret) { + dev_err(soc_runtime->dev, "error setting aud_dma_clk rate: %d\n", ret); + return ret; + } + ret =3D clk_set_rate(drvdata->aud_dma_mem_clk, QAIF_DMA_CLOCK_FREQ); + if (ret) { + dev_err(soc_runtime->dev, "error setting aud_dma_mem_clk rate: %d\n", re= t); + return ret; + } + + ret =3D regmap_write(map, qaif_sid_map_reg(dir, dai_id), drvdata->smmu_cs= id_bits); + if (ret) { + dev_err(soc_runtime->dev, "error writing to SID MAP reg: %d\n", ret); + return ret; + } + + ret =3D regmap_write(map, qaif_dmabase_reg(v, idx, dir, dai_id), + lower_32_bits(runtime->dma_addr)); + if (ret) { + dev_err(soc_runtime->dev, "error writing to dma base reg: %d\n", ret); + return ret; + } + + ret =3D regmap_write(map, qaif_dmabuff_reg(v, idx, dir, dai_id), + (snd_pcm_lib_buffer_bytes(substream) >> + QAIF_DMA_BYTES_TO_WORDS_SHIFT) - 1); + if (ret) { + dev_err(soc_runtime->dev, "error writing to dma buf reg: %d\n", ret); + return ret; + } + + ret =3D regmap_write(map, qaif_dmaper_len_reg(v, idx, dir, dai_id), + (snd_pcm_lib_period_bytes(substream) >> + QAIF_DMA_BYTES_TO_WORDS_SHIFT) - 1); + if (ret) + dev_err(soc_runtime->dev, "error writing to dma period reg: %d\n", ret); + return ret; +} + +static snd_pcm_uframes_t qaif_platform_pcmops_pointer(struct snd_soc_compo= nent *component, + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *soc_runtime =3D snd_soc_substream_to_rtd(subs= tream); + struct snd_soc_dai *cpu_dai =3D snd_soc_rtd_to_cpu(soc_runtime, 0); + struct qaif_drv_data *drvdata =3D snd_soc_component_get_drvdata(component= ); + const struct qaif_variant *v =3D drvdata->variant; + struct regmap *map =3D drvdata->audio_qaif_map; + struct qaif_pcm_data *data =3D substream->runtime->private_data; + unsigned int dai_id =3D cpu_dai->driver->id; + unsigned int base_addr, curr_addr; + int idx =3D data->dma_reg_idx; + int ret, dir =3D substream->stream; + + ret =3D regmap_read(map, qaif_dmabase_reg(v, idx, dir, dai_id), &base_add= r); + if (ret) { + dev_err(soc_runtime->dev, "error reading from rdmabase reg: %d\n", ret); + return SNDRV_PCM_POS_XRUN; + } + + ret =3D regmap_read(map, qaif_dmacurr_reg(v, idx, dir, dai_id), &curr_add= r); + if (ret) { + dev_err(soc_runtime->dev, "error reading from rdmacurr reg: %d\n", ret); + return SNDRV_PCM_POS_XRUN; + } + + return bytes_to_frames(substream->runtime, + (curr_addr - base_addr) % + snd_pcm_lib_buffer_bytes(substream)); +} + +static int qaif_platform_pcmops_mmap(struct snd_soc_component *component, + struct snd_pcm_substream *substream, + struct vm_area_struct *vma) +{ + struct snd_pcm_runtime *runtime =3D substream->runtime; + + return dma_mmap_coherent(component->dev, vma, + runtime->dma_area, runtime->dma_addr, + runtime->dma_bytes); +} + +static int qaif_platform_copy(struct snd_soc_component *component, + struct snd_pcm_substream *substream, + int channel, unsigned long pos, + struct iov_iter *buf, unsigned long bytes) +{ + struct snd_pcm_runtime *rt =3D substream->runtime; + size_t buffer_bytes =3D snd_pcm_lib_buffer_bytes(substream); + size_t channel_bytes =3D buffer_bytes / rt->channels; + unsigned long offset; + void *dma_buf; + size_t copied; + + if (channel < 0 || channel >=3D rt->channels) + return -EINVAL; + + /* Absolute byte offset into the configured (not the max) buffer. */ + offset =3D pos + channel * channel_bytes; + if (offset > buffer_bytes || bytes > buffer_bytes - offset) + return -EINVAL; + + dma_buf =3D rt->dma_area + offset; + + if (substream->stream =3D=3D SNDRV_PCM_STREAM_PLAYBACK) + copied =3D copy_from_iter(dma_buf, bytes, buf); + else + copied =3D copy_to_iter(dma_buf, bytes, buf); + + return (copied !=3D bytes) ? -EFAULT : 0; +} --=20 2.34.1 From nobody Fri Sep 25 14:31:50 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id A3A8346EF9F; Fri, 11 Sep 2026 09:19:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118390; cv=none; b=lhVUOHd7RrF9aZ/5g2Jf15d6XS9n0x5aSqijyyoiIPTo/6iuTkeT6kg4RqshWirwScRpKqZ7HekRCEHmuEBznMK/4DaGVWSGKhtg7tfKPdbPKKqnQVsaGT/fiFGo8Ee2R8AcC2IUo4CuVaFIy0+1Iu5mWiK8fbEg38vScjuGcgY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118390; c=relaxed/simple; bh=gJ5DXOX7jBKeYe72ISFn3zdPd5rtDygHQ+XOvvWMtNI=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=MeCm+61pgVPeBjamob59dh9CUI4TWlWRQwwnKVyVIFXfX7FNgvOXDFsO0wt+ihQBM/b7iCqk9FUpAGjLJ9Ip8FB9NBI7aZQeDcgFX7Gln/kAl12YkcfBq6J6i4fLPupzzXQ8HqlqeiBLFWWj+62GZjVi2b4623PhHwt8zOoRzGU= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=It1BQ00U; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="It1BQ00U" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B7kf5k3686805; Fri, 11 Sep 2026 09:19:29 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= NDdtGMlJp2sw1ZrNuusyBMpiqnd8GAq2TlRldVUODRg=; b=It1BQ00UN2ZKlwhE RLgsr0Tz/bNYGxeLm3OuoCuJ2QtTKXpghlHEF8qU3+dmyZrSSOKoA30H8zSCybBz XVdy5KjFwCP6T2F774k0RjJ9QKeKxPNecmFGvXtTjx5A/MWzZEmPK6iNijjUpbIX NPT9TLhXTWTgw627dsdFG88UC/5rNixDb1SL8nkmcxUqORL+82cWv90FxIKUzuxh KpnHB3rwNIGEubbSmHbUZ6wcuYWMBCGVvnAaSSmWT6G1I4Db1kjnkK+GgBxZWqPT qjUfm/2m84YHbrFfBfUAiN6Qvi79y5c5XcQglmjWFaFfS+Q2+gSXyXUZe+WgR+GU uui28A== Received: from apblrppmta02.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gmapg12kg-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 09:19:28 +0000 (GMT) Received: from pps.filterd (apblrppmta02.qualcomm.com [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B9CXtR2863390; Fri, 11 Sep 2026 09:19:26 GMT Received: from hu-hgautam-hyd.qualcomm.com (hu-hgautam-hyd.qualcomm.com [10.147.247.91]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTP id 68B9JL2e2870824; Fri, 11 Sep 2026 09:19:25 +0000 (GMT) From: Harendra Gautam Date: Fri, 11 Sep 2026 14:47:32 +0530 Subject: [PATCH v6 08/10] ASoC: qcom: Add QAIF IRQ handling and platform register Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260911-b4-qaif-shikra-audio-v6-8-e9addb358201@oss.qualcomm.com> References: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> In-Reply-To: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> To: Srinivas Kandagatla Cc: Mark Brown , Liam Girdwood , Rob Herring , Krzysztof Kozlowski , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai , Kuninori Morimoto , linux-sound@vger.kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Prasad Kumpatla , Krzysztof Kozlowski , Sarath Ganapathiraju , Kumar Anurag Singh , Mohammad Rafi Shaik , Harendra Gautam X-Mailer: b4 0.15.2 X-Proofpoint-Reinject: loops=2 maxloops=12 X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-ORIG-GUID: psF9FZYAldgX0H0_LJyk3qyWLzYzsOmE X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfXyfDETKYqjuPA DlInIE370CQehUqwl3rGkgAxNrOF8XrNhwMNA2c4wRl57P45pCnhBYaqcnCSf/FDOJF0xsbVOxV hhKrcbw4DXb+fy9qpQAT3aNDrIHvtwo= X-Proofpoint-GUID: psF9FZYAldgX0H0_LJyk3qyWLzYzsOmE X-Authority-Analysis: v=2.4 cv=DLoacCNb c=1 sm=1 tr=0 ts=6aa3c7a0 cx=c_pps a=Ou0eQOY4+eZoSc0qltEV5Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=EUspDBNiAAAA:8 a=o7TJiAN18BN_QPpExZUA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfXwdhkE2BffVOJ b02HRLGGO4on6ZIQnFCqh+XCq3c0zs1cu/Sc3QYSJDDEteifurAEGYHNKxsk+Ml3zj6cwuee85H ZxZ+6smGT0VheUubdv9qc4WAK65O/WI9jYeOCLRMCABNzu6x7E1n3U2vSAVJcvOJ47TwrP59U3Z sJ/P/7COH7s/PEy558alj3cwmGCsVMDyaMsXXvjjc3UngrclGe3RsQYPQV6W9Wi4dAceT+qrIFM h7C+oOvvgMgZyd1dStdb3n4mr9+xHVD4gcgWPlHJ0CPbaUVD7Rzjn9vO5ccbCU51UNYWR644QUA tcm661YhnNU8gI0RUM9Lp+cDRPmHDRjO29nFFUyaxcppXK6Nv40nKzJXAg86ZT9XubxQaKb38F+ DwxJiS2JEpvF9ZtOUmRw/Cg25AlNWGcnu1Mo1Z1ciFXpVT1BAsloP0uOPSX1fJoRbm0WETDoC19 LazFXQ50QJ4VPTN4uWg== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_03,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 priorityscore=1501 phishscore=0 adultscore=0 suspectscore=0 spamscore=0 impostorscore=0 bulkscore=0 clxscore=1015 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110129 Finish the QAIF PCM platform support so streams can be registered, started, stopped and serviced by DMA interrupts. Register the ASoC component, request the QAIF interrupt and add trigger handling to enable or disable DMA and its interrupt sources. Dispatch the top-level IRQ status to the AIF and CIF DMA handlers, report period elapsed events to ALSA, warn on xrun conditions and stop the stream on bus errors. Signed-off-by: Harendra Gautam --- sound/soc/qcom/qaif-platform.c | 392 +++++++++++++++++++++++++++++++++++++= ++++ 1 file changed, 392 insertions(+) diff --git a/sound/soc/qcom/qaif-platform.c b/sound/soc/qcom/qaif-platform.c index 84ce3ad9a1f2..762ba3eb6575 100644 --- a/sound/soc/qcom/qaif-platform.c +++ b/sound/soc/qcom/qaif-platform.c @@ -537,3 +537,395 @@ static int qaif_platform_copy(struct snd_soc_componen= t *component, =20 return (copied !=3D bytes) ? -EFAULT : 0; } + +static int qaif_platform_irq_op(struct qaif_drv_data *drvdata, int dir, + enum qaif_irq_type irq_type, int idx, + enum qaif_irq_op op) +{ + const struct qaif_variant *v =3D drvdata->variant; + struct regmap *map =3D drvdata->audio_qaif_map; + unsigned int bit =3D BIT(idx); + unsigned int val =3D op =3D=3D QAIF_IRQ_ENABLE ? bit : 0; + u32 per_reg, err_reg, xrun_reg; + int ret; + + if (dir =3D=3D SNDRV_PCM_STREAM_PLAYBACK) { + per_reg =3D op =3D=3D QAIF_IRQ_CLEAR ? QAIF_EE_RDDMA_PERIOD_IRQ_CLR_REG(= v, irq_type) + : QAIF_EE_RDDMA_PERIOD_IRQ_EN_REG(v, irq_type); + xrun_reg =3D op =3D=3D QAIF_IRQ_CLEAR ? QAIF_EE_RDDMA_UF_IRQ_CLR_REG(v, = irq_type) + : QAIF_EE_RDDMA_UF_IRQ_EN_REG(v, irq_type); + err_reg =3D op =3D=3D QAIF_IRQ_CLEAR ? QAIF_EE_RDDMA_ERR_RSP_IRQ_CLR_REG= (v, irq_type) + : QAIF_EE_RDDMA_ERR_RSP_IRQ_EN_REG(v, irq_type); + } else { + per_reg =3D op =3D=3D QAIF_IRQ_CLEAR ? QAIF_EE_WRDMA_PERIOD_IRQ_CLR_REG(= v, irq_type) + : QAIF_EE_WRDMA_PERIOD_IRQ_EN_REG(v, irq_type); + xrun_reg =3D op =3D=3D QAIF_IRQ_CLEAR ? QAIF_EE_WRDMA_OF_IRQ_CLR_REG(v, = irq_type) + : QAIF_EE_WRDMA_OF_IRQ_EN_REG(v, irq_type); + err_reg =3D op =3D=3D QAIF_IRQ_CLEAR ? QAIF_EE_WRDMA_ERR_RSP_IRQ_CLR_REG= (v, irq_type) + : QAIF_EE_WRDMA_ERR_RSP_IRQ_EN_REG(v, irq_type); + } + + if (op =3D=3D QAIF_IRQ_CLEAR) { + ret =3D regmap_write(map, per_reg, bit); + if (ret) + return ret; + ret =3D regmap_write(map, xrun_reg, bit); + if (ret) + return ret; + return regmap_write(map, err_reg, bit); + } + + ret =3D regmap_write_bits(map, per_reg, bit, val); + if (ret) + return ret; + ret =3D regmap_write_bits(map, xrun_reg, bit, val); + if (ret) + return ret; + return regmap_write_bits(map, err_reg, bit, val); +} + +static int qaif_platform_pcmops_trigger(struct snd_soc_component *componen= t, + struct snd_pcm_substream *substream, + int cmd) +{ + struct snd_soc_pcm_runtime *soc_runtime =3D snd_soc_substream_to_rtd(subs= tream); + struct snd_soc_dai *cpu_dai =3D snd_soc_rtd_to_cpu(soc_runtime, 0); + struct qaif_drv_data *drvdata =3D snd_soc_component_get_drvdata(component= ); + const struct qaif_variant *v =3D drvdata->variant; + struct qaif_pcm_data *data =3D substream->runtime->private_data; + unsigned int dai_id =3D cpu_dai->driver->id; + enum qaif_irq_type irq_type =3D qaif_is_cif_port(dai_id) ? QAIF_CIF_IRQ := QAIF_AIF_IRQ; + struct regmap *map =3D drvdata->audio_qaif_map; + int idx =3D data->dma_reg_idx; + int ret; + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + case SNDRV_PCM_TRIGGER_PAUSE_RELEASE: + ret =3D qaif_platform_irq_op(drvdata, substream->stream, irq_type, + idx, QAIF_IRQ_CLEAR); + if (ret) { + dev_err(soc_runtime->dev, "error clearing irq regs: %d\n", ret); + return ret; + } + ret =3D regmap_update_bits(map, + qaif_dmacfg_reg(v, idx, substream->stream, dai_id), + QAIF_DMACFG_DYNCLK_BIT, QAIF_DMACFG_DYNCLK_BIT); + if (ret) { + dev_err(soc_runtime->dev, "error enabling dma_dynclk: %d\n", ret); + return ret; + } + ret =3D regmap_update_bits(map, + qaif_dmactl_reg(v, idx, substream->stream, dai_id), + QAIF_DMACTL_ENABLE_BIT, QAIF_DMACTL_ENABLE_BIT); + if (ret) { + dev_err(soc_runtime->dev, "error enabling DMA: %d\n", ret); + return ret; + } + ret =3D qaif_platform_irq_op(drvdata, substream->stream, irq_type, + idx, QAIF_IRQ_ENABLE); + if (ret) + dev_err(soc_runtime->dev, "error enabling irq regs: %d\n", ret); + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + case SNDRV_PCM_TRIGGER_PAUSE_PUSH: + ret =3D regmap_update_bits(map, + qaif_dmactl_reg(v, idx, substream->stream, dai_id), + QAIF_DMACTL_ENABLE_BIT, 0); + if (ret) { + dev_err(soc_runtime->dev, "error disabling DMA: %d\n", ret); + return ret; + } + ret =3D regmap_update_bits(map, + qaif_dmacfg_reg(v, idx, substream->stream, dai_id), + QAIF_DMACFG_DYNCLK_BIT, 0); + if (ret) + dev_err(soc_runtime->dev, "error disabling dma_dynclk: %d\n", ret); + ret =3D qaif_platform_irq_op(drvdata, substream->stream, irq_type, + idx, QAIF_IRQ_DISABLE); + if (ret) + dev_err(soc_runtime->dev, "error disabling irq regs: %d\n", ret); + break; + default: + return -EINVAL; + } + return ret; +} + +static int qaif_platform_pcmops_sync_stop(struct snd_soc_component *compon= ent, + struct snd_pcm_substream *substream) +{ + struct snd_soc_pcm_runtime *soc_runtime =3D snd_soc_substream_to_rtd(subs= tream); + struct snd_soc_dai *cpu_dai =3D snd_soc_rtd_to_cpu(soc_runtime, 0); + struct qaif_drv_data *drvdata =3D snd_soc_component_get_drvdata(component= ); + struct qaif_pcm_data *data =3D substream->runtime->private_data; + unsigned int dai_id =3D cpu_dai->driver->id; + enum qaif_irq_type irq_type =3D qaif_is_cif_port(dai_id) ? QAIF_CIF_IRQ := QAIF_AIF_IRQ; + int idx =3D data->dma_reg_idx; + int ret; + + synchronize_irq(drvdata->audio_qaif_irq); + ret =3D qaif_platform_irq_op(drvdata, substream->stream, irq_type, + idx, QAIF_IRQ_CLEAR); + if (ret) + dev_err(soc_runtime->dev, "error clearing irq regs: %d\n", ret); + return ret; +} + +static irqreturn_t qaif_process_dma_irq(struct qaif_drv_data *drvdata, + u32 stat_reg_addr, + u32 clr_reg_addr, + enum qaif_irq_type irq_type, + enum qaif_dma_dir dma_type, + enum qaif_irq irq, + struct snd_pcm_substream **substream) +{ + const struct qaif_variant *v =3D drvdata->variant; + unsigned int reg =3D 0; + int dma_idx, stream_dma_idx, rv, num_dma, stream_offset, array_size; + u32 mask; + struct snd_pcm_substream *ss; + + stream_offset =3D (dma_type =3D=3D QAIF_DMA_WRDMA) ? + ((irq_type =3D=3D QAIF_AIF_IRQ) ? v->wrdma_start : v->codec_wrdma_start)= : 0; + num_dma =3D (dma_type =3D=3D QAIF_DMA_WRDMA) ? + ((irq_type =3D=3D QAIF_AIF_IRQ) ? v->num_wrdma : v->num_codec_wrdma) : + ((irq_type =3D=3D QAIF_AIF_IRQ) ? v->num_rddma : v->num_codec_rddma); + if (!num_dma) + return IRQ_NONE; + + array_size =3D (irq_type =3D=3D QAIF_AIF_IRQ) ? + QAIF_MAX_AIF_DMA_IDX : QAIF_MAX_CIF_DMA_IDX; + if (stream_offset + num_dma > array_size) { + dev_err(regmap_get_device(drvdata->audio_qaif_map), + "DMA index range %d+%d exceeds substream table %d\n", + stream_offset, num_dma, array_size); + return IRQ_NONE; + } + mask =3D GENMASK(num_dma - 1, 0); + + rv =3D regmap_read(drvdata->audio_qaif_map, stat_reg_addr, ®); + if (rv) { + dev_err_ratelimited(regmap_get_device(drvdata->audio_qaif_map), + "error reading stat reg 0x%x: %d\n", stat_reg_addr, rv); + return IRQ_NONE; + } + + if (!(reg & mask)) { + dev_warn_ratelimited(regmap_get_device(drvdata->audio_qaif_map), + "spurious IRQ: stat reg 0x%x status 0x%x mask 0x%x\n", + stat_reg_addr, reg, mask); + return IRQ_NONE; + } + + if (regmap_write(drvdata->audio_qaif_map, clr_reg_addr, reg & mask)) + return IRQ_NONE; + + for (dma_idx =3D 0; dma_idx < num_dma; dma_idx++) { + stream_dma_idx =3D dma_idx + stream_offset; + ss =3D READ_ONCE(substream[stream_dma_idx]); + if (!(reg & BIT(dma_idx)) || !ss) + continue; + switch (irq) { + case QAIF_IRQ_PERIOD: + snd_pcm_period_elapsed(ss); + break; + case QAIF_IRQ_OVERFLOW: + case QAIF_IRQ_UNDERFLOW: + dev_warn_ratelimited(regmap_get_device(drvdata->audio_qaif_map), + "QAIF DMA xRun\n"); + snd_pcm_stop_xrun(ss); + break; + case QAIF_IRQ_ERROR: + snd_pcm_stop_xrun(ss); + dev_err_ratelimited(regmap_get_device(drvdata->audio_qaif_map), + "QAIF bus error\n"); + break; + } + } + return IRQ_HANDLED; +} + +static irqreturn_t qaif_aif_irq_handler(struct qaif_drv_data *drvdata, u32= status) +{ + const struct qaif_variant *v =3D drvdata->variant; + struct snd_pcm_substream **ss =3D drvdata->aif_substream; + irqreturn_t ret =3D IRQ_NONE; + + if (status & QAIF_SUMMARY_BITMASK_AIF_PERIOD_RDDMA) + ret |=3D qaif_process_dma_irq(drvdata, + QAIF_EE_RDDMA_PERIOD_IRQ_STAT_REG(v, QAIF_AIF_IRQ), + QAIF_EE_RDDMA_PERIOD_IRQ_CLR_REG(v, QAIF_AIF_IRQ), + QAIF_AIF_IRQ, QAIF_DMA_RDDMA, QAIF_IRQ_PERIOD, ss); + if (status & QAIF_SUMMARY_BITMASK_AIF_PERIOD_WRDMA) + ret |=3D qaif_process_dma_irq(drvdata, + QAIF_EE_WRDMA_PERIOD_IRQ_STAT_REG(v, QAIF_AIF_IRQ), + QAIF_EE_WRDMA_PERIOD_IRQ_CLR_REG(v, QAIF_AIF_IRQ), + QAIF_AIF_IRQ, QAIF_DMA_WRDMA, QAIF_IRQ_PERIOD, ss); + if (status & QAIF_SUMMARY_BITMASK_AIF_OVERFLOW_WRDMA) + ret |=3D qaif_process_dma_irq(drvdata, + QAIF_EE_WRDMA_OF_IRQ_STAT_REG(v, QAIF_AIF_IRQ), + QAIF_EE_WRDMA_OF_IRQ_CLR_REG(v, QAIF_AIF_IRQ), + QAIF_AIF_IRQ, QAIF_DMA_WRDMA, QAIF_IRQ_OVERFLOW, ss); + if (status & QAIF_SUMMARY_BITMASK_AIF_UNDERFLOW_RDDMA) + ret |=3D qaif_process_dma_irq(drvdata, + QAIF_EE_RDDMA_UF_IRQ_STAT_REG(v, QAIF_AIF_IRQ), + QAIF_EE_RDDMA_UF_IRQ_CLR_REG(v, QAIF_AIF_IRQ), + QAIF_AIF_IRQ, QAIF_DMA_RDDMA, QAIF_IRQ_UNDERFLOW, ss); + if (status & QAIF_SUMMARY_BITMASK_AIF_ERR_RSP_RDDMA) + ret |=3D qaif_process_dma_irq(drvdata, + QAIF_EE_RDDMA_ERR_RSP_IRQ_STAT_REG(v, QAIF_AIF_IRQ), + QAIF_EE_RDDMA_ERR_RSP_IRQ_CLR_REG(v, QAIF_AIF_IRQ), + QAIF_AIF_IRQ, QAIF_DMA_RDDMA, QAIF_IRQ_ERROR, ss); + if (status & QAIF_SUMMARY_BITMASK_AIF_ERR_RSP_WRDMA) + ret |=3D qaif_process_dma_irq(drvdata, + QAIF_EE_WRDMA_ERR_RSP_IRQ_STAT_REG(v, QAIF_AIF_IRQ), + QAIF_EE_WRDMA_ERR_RSP_IRQ_CLR_REG(v, QAIF_AIF_IRQ), + QAIF_AIF_IRQ, QAIF_DMA_WRDMA, QAIF_IRQ_ERROR, ss); + return ret; +} + +static irqreturn_t qaif_cif_irq_handler(struct qaif_drv_data *drvdata, u32= status) +{ + const struct qaif_variant *v =3D drvdata->variant; + struct snd_pcm_substream **ss =3D drvdata->cif_substream; + irqreturn_t ret =3D IRQ_NONE; + + if (status & QAIF_SUMMARY_BITMASK_CIF_PERIOD_RDDMA) + ret |=3D qaif_process_dma_irq(drvdata, + QAIF_EE_RDDMA_PERIOD_IRQ_STAT_REG(v, QAIF_CIF_IRQ), + QAIF_EE_RDDMA_PERIOD_IRQ_CLR_REG(v, QAIF_CIF_IRQ), + QAIF_CIF_IRQ, QAIF_DMA_RDDMA, QAIF_IRQ_PERIOD, ss); + if (status & QAIF_SUMMARY_BITMASK_CIF_PERIOD_WRDMA) + ret |=3D qaif_process_dma_irq(drvdata, + QAIF_EE_WRDMA_PERIOD_IRQ_STAT_REG(v, QAIF_CIF_IRQ), + QAIF_EE_WRDMA_PERIOD_IRQ_CLR_REG(v, QAIF_CIF_IRQ), + QAIF_CIF_IRQ, QAIF_DMA_WRDMA, QAIF_IRQ_PERIOD, ss); + if (status & QAIF_SUMMARY_BITMASK_CIF_OVERFLOW_WRDMA) + ret |=3D qaif_process_dma_irq(drvdata, + QAIF_EE_WRDMA_OF_IRQ_STAT_REG(v, QAIF_CIF_IRQ), + QAIF_EE_WRDMA_OF_IRQ_CLR_REG(v, QAIF_CIF_IRQ), + QAIF_CIF_IRQ, QAIF_DMA_WRDMA, QAIF_IRQ_OVERFLOW, ss); + if (status & QAIF_SUMMARY_BITMASK_CIF_UNDERFLOW_RDDMA) + ret |=3D qaif_process_dma_irq(drvdata, + QAIF_EE_RDDMA_UF_IRQ_STAT_REG(v, QAIF_CIF_IRQ), + QAIF_EE_RDDMA_UF_IRQ_CLR_REG(v, QAIF_CIF_IRQ), + QAIF_CIF_IRQ, QAIF_DMA_RDDMA, QAIF_IRQ_UNDERFLOW, ss); + if (status & QAIF_SUMMARY_BITMASK_CIF_ERR_RSP_RDDMA) + ret |=3D qaif_process_dma_irq(drvdata, + QAIF_EE_RDDMA_ERR_RSP_IRQ_STAT_REG(v, QAIF_CIF_IRQ), + QAIF_EE_RDDMA_ERR_RSP_IRQ_CLR_REG(v, QAIF_CIF_IRQ), + QAIF_CIF_IRQ, QAIF_DMA_RDDMA, QAIF_IRQ_ERROR, ss); + if (status & QAIF_SUMMARY_BITMASK_CIF_ERR_RSP_WRDMA) + ret |=3D qaif_process_dma_irq(drvdata, + QAIF_EE_WRDMA_ERR_RSP_IRQ_STAT_REG(v, QAIF_CIF_IRQ), + QAIF_EE_WRDMA_ERR_RSP_IRQ_CLR_REG(v, QAIF_CIF_IRQ), + QAIF_CIF_IRQ, QAIF_DMA_WRDMA, QAIF_IRQ_ERROR, ss); + return ret; +} + +static const struct qaif_irq_map qaif_irq_clients[] =3D { + { QAIF_CLIENT_ID_AIF_DMA, QAIF_BITMASK_AIF_RDDMA_WRDMA, qaif_aif_irq_hand= ler }, + { QAIF_CLIENT_ID_CIF_DMA, QAIF_BITMASK_CIF_RDDMA_WRDMA, qaif_cif_irq_hand= ler }, +}; + +static irqreturn_t asoc_platform_qaif_irq(int irq, void *data) +{ + struct qaif_drv_data *drvdata =3D data; + const struct qaif_variant *v =3D drvdata->variant; + u32 summary_irq_status; + int rv, client; + irqreturn_t ret =3D IRQ_NONE; + + rv =3D regmap_read(drvdata->audio_qaif_map, QAIF_SUMMARY_IRQSTAT_REG(v), + &summary_irq_status); + if (rv) { + dev_err(regmap_get_device(drvdata->audio_qaif_map), + "error reading from irqstat reg: %d\n", rv); + return IRQ_NONE; + } + + if (!(summary_irq_status & QAIF_ALL_CLIENTS_MASK)) + return IRQ_NONE; + + for (client =3D 0; client < ARRAY_SIZE(qaif_irq_clients); client++) { + if (summary_irq_status & qaif_irq_clients[client].mask) + ret |=3D qaif_irq_clients[client].client_irq_handler(drvdata, + summary_irq_status); + } + return ret; +} + +static const struct snd_soc_component_driver qaif_component_driver =3D { + .name =3D DRV_NAME, + .open =3D qaif_platform_pcmops_open, + .close =3D qaif_platform_pcmops_close, + .hw_params =3D qaif_platform_pcmops_hw_params, + .hw_free =3D qaif_platform_pcmops_hw_free, + .prepare =3D qaif_platform_pcmops_prepare, + .trigger =3D qaif_platform_pcmops_trigger, + .sync_stop =3D qaif_platform_pcmops_sync_stop, + .pointer =3D qaif_platform_pcmops_pointer, + .mmap =3D qaif_platform_pcmops_mmap, + .copy =3D qaif_platform_copy, +}; + +int asoc_qcom_qaif_platform_register(struct platform_device *pdev) +{ + struct qaif_drv_data *drvdata =3D platform_get_drvdata(pdev); + struct of_phandle_args iommu_spec; + u32 sid; + int ret; + + if (!drvdata->variant->alloc_stream_dma_idx || + !drvdata->variant->free_stream_dma_idx) + return dev_err_probe(&pdev->dev, -EINVAL, + "Variant missing mandatory callbacks\n"); + + ret =3D of_parse_phandle_with_args(pdev->dev.of_node, + "iommus", "#iommu-cells", 0, + &iommu_spec); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "failed to parse iommus property\n"); + sid =3D iommu_spec.args[0]; + of_node_put(iommu_spec.np); + drvdata->smmu_csid_bits =3D sid & QAIF_CSID_MASK; + + /* + * The DMA base register only holds the low 32 bits of the buffer + * address, so the coherent buffer must come from the low 32-bit + * address space. + */ + ret =3D dma_set_mask_and_coherent(&pdev->dev, DMA_BIT_MASK(32)); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "Failed to set 32-bit DMA mask\n"); + + drvdata->audio_qaif_irq =3D platform_get_irq(pdev, 0); + if (drvdata->audio_qaif_irq < 0) + return dev_err_probe(&pdev->dev, drvdata->audio_qaif_irq, + "Failed to get IRQ\n"); + + drvdata->qaif_hw_configured =3D false; + mutex_init(&drvdata->stream_lock); + + ret =3D devm_request_irq(&pdev->dev, drvdata->audio_qaif_irq, + asoc_platform_qaif_irq, 0, + "qaif-irq-audio-core", drvdata); + if (ret) + return dev_err_probe(&pdev->dev, ret, "irq request failed\n"); + + ret =3D devm_snd_soc_register_component(&pdev->dev, &qaif_component_drive= r, NULL, 0); + if (ret) + return dev_err_probe(&pdev->dev, ret, + "Failed to register platform component\n"); + return 0; +} +EXPORT_SYMBOL_GPL(asoc_qcom_qaif_platform_register); + +MODULE_DESCRIPTION("Qualcomm Audio Interface (QAIF) PCM platform driver"); +MODULE_AUTHOR("Harendra Gautam "); +MODULE_LICENSE("GPL"); --=20 2.34.1 From nobody Fri Sep 25 14:31:50 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 177583B5820; Fri, 11 Sep 2026 09:19:38 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118380; cv=none; b=fh8M8LcQMbQM7LK9gqiKkZuRVxmwpx3epednqHq7cVj1G2c86vF/7T9+Iw5n9gwKrReP3EL6NqveE7/tKLk63U2ASFDHzB6a8vyzEX2yw3jwhsqQ+WRnNnf3psTGY6GUsIF7pS7jn84iF69xhKfOTlN0RcFifbrqT/4Y5D8maQo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118380; c=relaxed/simple; bh=FW/XeAHbrTNr82j0hz8EWpWL1b0PvJT8ATOveejkZjU=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=DsKG3mUkF+XEJ3YiN8oA27ZH0U7nQvfiq0mNASqy3SJ3S4FVwYPkJtRIBFZkSXe9MWJwyaujgdlTkLsatEGxGdzM5Bic1qN6Mg475Oyt5b8kEZd94kdmK//5Ns2ZOFX2CZOvTD0zapG7wrxcQBuki1vB3oAG2XEPIYqIv78MAKc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=I7KQiR2j; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="I7KQiR2j" Received: from pps.filterd (m0279870.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B7ktd63687072; Fri, 11 Sep 2026 09:19:29 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 2pY80PvDV6iExYov5wC67KqHfSfKYMJwWVmg4/2GrSw=; b=I7KQiR2jXkm3a6Xl IAbRESLMYmiSbPtrQq8+nANwJjFIk8hfD3hYkuEjYvmSaDsV/Meg0mW2nVHedvHc gUYnx0wGbZuNoDSFRCYWofvVqLdrav/GeKY3Wrqo59eWuV4LHVIDJucb6eBjqkFE I7E0nxi3ksplK4I3EIEM9c2SU9qV6vmBMwATjMfmZb6Q4Ewpej7TkzzyUjndZjdq tXfKODI7qsGY+L0HyqlroYaIAyE+gTv4NLASRGJSN3C+LLNi9IjCQl8HSx7ZCRmR o8SXUADokTPJgyWxncQ1CnhOt8NqXlnHODx2WZTwA8Q4TgaSOICfKOOqvpVDcHj1 70pY9Q== Received: from apblrppmta02.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gmapg12kh-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 09:19:29 +0000 (GMT) Received: from pps.filterd (apblrppmta02.qualcomm.com [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B9JMU32870832; Fri, 11 Sep 2026 09:19:26 GMT Received: from hu-hgautam-hyd.qualcomm.com (hu-hgautam-hyd.qualcomm.com [10.147.247.91]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTP id 68B9JL2f2870824; Fri, 11 Sep 2026 09:19:26 +0000 (GMT) From: Harendra Gautam Date: Fri, 11 Sep 2026 14:47:33 +0530 Subject: [PATCH v6 09/10] ASoC: qcom: Add Shikra QAIF support Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260911-b4-qaif-shikra-audio-v6-9-e9addb358201@oss.qualcomm.com> References: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> In-Reply-To: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> To: Srinivas Kandagatla Cc: Mark Brown , Liam Girdwood , Rob Herring , Krzysztof Kozlowski , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai , Kuninori Morimoto , linux-sound@vger.kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Prasad Kumpatla , Krzysztof Kozlowski , Sarath Ganapathiraju , Kumar Anurag Singh , Mohammad Rafi Shaik , Harendra Gautam X-Mailer: b4 0.15.2 X-Proofpoint-Reinject: loops=2 maxloops=12 X-QCInternal: smtphost X-QCInternal: smtphost X-Proofpoint-ORIG-GUID: rJqRA7pYiIgAKtz50RTtYb1Wp6TyH6ur X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfX67NTxHn/jqcy /d+PI5V3xypE8eq7OShIv+vELKEUUSdpJYfbdnCITKx4r4G3FNqmdS0GFhX+KdvNlzUjdHtYcom OZBVwAT0/auJOce7WLdX6iWPcMk89V8= X-Proofpoint-GUID: rJqRA7pYiIgAKtz50RTtYb1Wp6TyH6ur X-Authority-Analysis: v=2.4 cv=DLoacCNb c=1 sm=1 tr=0 ts=6aa3c7a1 cx=c_pps a=Ou0eQOY4+eZoSc0qltEV5Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=gowsoOTTUOVcmtlkKump:22 a=EUspDBNiAAAA:8 a=uD8aj_56PGaHGp0t6EcA:9 a=QEXdDO2ut3YA:10 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfX1A1AUAodZpmA VEaKCV1U5QcbH6izu+ebEhovFvpLtNq/enmWzLDXebcrnC87WBPCy9m0FkdWdBUp7JIyM7gWGfZ IdVyf1Jb8pFMPp/D4G/YW4AB0tNStvH2sKXLVk8bepNcPPrG/3C5MjbUepKKsAwsIgxhq352EU0 1LnkZYPLWs0DpccrujinXlThTu5AILXATunbAeU1kFCyD+jKBqYE6KPMzTTKjjj+8vmb5t4vBBa 4S5m+RiN9NbkUTFZL2/R8ia7A0KTUWxV5Nu7eioVnqXZAPHIZsPq+lCmsKAeEAJZ+uHp3fEP9i9 jg/JBR39K3rMz2DGcBwuL+PRjhZ/Q4aMUWGO8Ny5thRT63TEd0WaeSC2F7JuS5Eq9cpUJsd+tqv 987ZOi6PKSuDJ1mTPUt8TJKwdfUElkkYmQDhbKEHiAYaVcUdkILg255mArlhTCFg1Iru3ziv01O 28KpYjutwIFnz9k4ClQ== X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_03,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 malwarescore=0 priorityscore=1501 phishscore=0 adultscore=0 suspectscore=0 spamscore=0 impostorscore=0 bulkscore=0 clxscore=1015 lowpriorityscore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110129 Add the Shikra variant data for the Qualcomm Audio Interface driver so the common QAIF code can bind to the Shikra QAIF device and expose the SoC-specific DAIs. Provide the Shikra DMA-to-DAI mappings, DMA and SHRAM layout, clock names, DAI driver data and power-management hooks required by the QAIF driver. Add the Kconfig symbol and Makefile entries needed to build the new variant. Signed-off-by: Harendra Gautam --- sound/soc/qcom/Kconfig | 10 + sound/soc/qcom/Makefile | 3 + sound/soc/qcom/qaif-shikra.c | 447 +++++++++++++++++++++++++++++++++++++++= ++++ 3 files changed, 460 insertions(+) diff --git a/sound/soc/qcom/Kconfig b/sound/soc/qcom/Kconfig index e6e24f3b9922..b7088b1e5cad 100644 --- a/sound/soc/qcom/Kconfig +++ b/sound/soc/qcom/Kconfig @@ -71,6 +71,16 @@ config SND_SOC_QCOM_COMMON config SND_SOC_QCOM_SDW tristate =20 +config SND_SOC_QCOM_QAIF + tristate "Qualcomm QAIF audio interface support" + depends on COMMON_CLK + select REGMAP_MMIO + help + Say Y or M to enable the Qualcomm Audio Interface (QAIF) driver + for the Shikra audio platform. QAIF is a DMA-based audio + subsystem that moves PCM data between memory and external serial + audio interfaces (AIF) and internal codec interfaces (CIF). + config SND_SOC_QDSP6_COMMON tristate =20 diff --git a/sound/soc/qcom/Makefile b/sound/soc/qcom/Makefile index 985ce2ae286b..cf50b7a24bcf 100644 --- a/sound/soc/qcom/Makefile +++ b/sound/soc/qcom/Makefile @@ -47,3 +47,6 @@ obj-$(CONFIG_SND_SOC_QCOM_OFFLOAD_UTILS) +=3D snd-soc-qco= m-offload-utils.o =20 #DSP lib obj-$(CONFIG_SND_SOC_QDSP6) +=3D qdsp6/ + +snd-soc-qcom-qaif-y :=3D qaif-cpu.o qaif-platform.o qaif-shikra.o +obj-$(CONFIG_SND_SOC_QCOM_QAIF) +=3D snd-soc-qcom-qaif.o diff --git a/sound/soc/qcom/qaif-shikra.c b/sound/soc/qcom/qaif-shikra.c new file mode 100644 index 000000000000..0d5c2baade28 --- /dev/null +++ b/sound/soc/qcom/qaif-shikra.c @@ -0,0 +1,447 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) Qualcomm Technologies, Inc. and/or its subsidiaries. + * + * qaif-shikra.c -- ALSA SoC CPU-Platform DAI driver for QTi QAIF + */ + +#include +#include +#include +#include +#include "qaif.h" + +static const struct qaif_dmaidx_dai_map shikra_mi2s_dma_dai_map[] =3D { + { AIF_MI2S_RX_0, QAIF_DMA_IDX0 }, + { AIF_MI2S_RX_1, QAIF_DMA_IDX1 }, + { AIF_MI2S_RX_2, QAIF_DMA_IDX2 }, + { AIF_MI2S_RX_3, QAIF_DMA_IDX3 }, + { AIF_MI2S_TX_0, QAIF_DMA_IDX0 }, + { AIF_MI2S_TX_1, QAIF_DMA_IDX1 }, + { AIF_MI2S_TX_2, QAIF_DMA_IDX2 }, + { AIF_MI2S_TX_3, QAIF_DMA_IDX3 }, +}; + +static const struct qaif_dmaidx_dai_map shikra_tdm_dma_dai_map[] =3D { + { AIF_TDM_RX_0, QAIF_DMA_IDX0 }, + { AIF_TDM_RX_1, QAIF_DMA_IDX1 }, + { AIF_TDM_RX_2, QAIF_DMA_IDX2 }, + { AIF_TDM_RX_3, QAIF_DMA_IDX3 }, + { AIF_TDM_TX_0, QAIF_DMA_IDX0 }, + { AIF_TDM_TX_1, QAIF_DMA_IDX1 }, + { AIF_TDM_TX_2, QAIF_DMA_IDX2 }, + { AIF_TDM_TX_3, QAIF_DMA_IDX3 }, +}; + +static const struct qaif_dmaidx_dai_map shikra_cif_dma_dai_map[] =3D { + { RX_CODEC_DMA_RX_0, QAIF_DMA_IDX0 }, + { RX_CODEC_DMA_RX_1, QAIF_DMA_IDX1 }, + { VA_CODEC_DMA_TX_0, QAIF_DMA_IDX0 }, + { VA_CODEC_DMA_TX_1, QAIF_DMA_IDX1 }, +}; + +static struct snd_soc_dai_driver shikra_qaif_cpu_dai_driver[] =3D { + { + .id =3D AIF_MI2S_RX_0, + .name =3D "MI2S AIF RX Zero", + .playback =3D { + .stream_name =3D "MI2S AIF RX Zero Playback", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 2, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D AIF_MI2S_TX_0, + .name =3D "MI2S AIF TX Zero", + .capture =3D { + .stream_name =3D "MI2S AIF TX Zero Capture", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 2, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D AIF_TDM_RX_0, + .name =3D "TDM AIF RX Zero", + .playback =3D { + .stream_name =3D "TDM AIF RX Zero Playback", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S24 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 8, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D AIF_TDM_TX_0, + .name =3D "TDM AIF TX Zero", + .capture =3D { + .stream_name =3D "TDM AIF TX Zero Capture", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S24 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 8, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D AIF_MI2S_RX_1, + .name =3D "MI2S AIF RX One", + .playback =3D { + .stream_name =3D "MI2S AIF RX One Playback", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 2, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D AIF_MI2S_TX_1, + .name =3D "MI2S AIF TX One", + .capture =3D { + .stream_name =3D "MI2S AIF TX One Capture", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 2, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D AIF_TDM_RX_1, + .name =3D "TDM AIF RX One", + .playback =3D { + .stream_name =3D "TDM AIF RX One Playback", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S24 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 8, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D AIF_TDM_TX_1, + .name =3D "TDM AIF TX One", + .capture =3D { + .stream_name =3D "TDM AIF TX One Capture", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S24 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 8, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D AIF_MI2S_RX_2, + .name =3D "MI2S AIF RX Two", + .playback =3D { + .stream_name =3D "MI2S AIF RX Two Playback", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 2, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D AIF_MI2S_TX_2, + .name =3D "MI2S AIF TX Two", + .capture =3D { + .stream_name =3D "MI2S AIF TX Two Capture", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 2, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D AIF_TDM_RX_2, + .name =3D "TDM AIF RX Two", + .playback =3D { + .stream_name =3D "TDM AIF RX Two Playback", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S24 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 8, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D AIF_TDM_TX_2, + .name =3D "TDM AIF TX Two", + .capture =3D { + .stream_name =3D "TDM AIF TX Two Capture", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S24 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 8, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D AIF_MI2S_RX_3, + .name =3D "MI2S AIF RX Three", + .playback =3D { + .stream_name =3D "MI2S AIF RX Three Playback", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 2, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D AIF_MI2S_TX_3, + .name =3D "MI2S AIF TX Three", + .capture =3D { + .stream_name =3D "MI2S AIF TX Three Capture", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 2, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D AIF_TDM_RX_3, + .name =3D "TDM AIF RX Three", + .playback =3D { + .stream_name =3D "TDM AIF RX Three Playback", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S24 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 8, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D AIF_TDM_TX_3, + .name =3D "TDM AIF TX Three", + .capture =3D { + .stream_name =3D "TDM AIF TX Three Capture", + .formats =3D SNDRV_PCM_FMTBIT_S16 | + SNDRV_PCM_FMTBIT_S24 | + SNDRV_PCM_FMTBIT_S32, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .channels_min =3D 1, + .channels_max =3D 8, + }, + .ops =3D &asoc_qcom_qaif_aif_cpu_dai_ops, + }, { + .id =3D RX_CODEC_DMA_RX_0, + .name =3D "RX CDC DMA RX0", + .playback =3D { + .stream_name =3D "RX CDC DMA RX0 Playback", + .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 2, + }, + .ops =3D &asoc_qcom_qaif_cif_dai_ops, + }, { + .id =3D RX_CODEC_DMA_RX_1, + .name =3D "RX CDC DMA RX1", + .playback =3D { + .stream_name =3D "RX CDC DMA RX1 Playback", + .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 2, + }, + .ops =3D &asoc_qcom_qaif_cif_dai_ops, + }, { + .id =3D VA_CODEC_DMA_TX_0, + .name =3D "VA CDC DMA TX0", + .capture =3D { + .stream_name =3D "VA CDC DMA TX0 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 4, + }, + .ops =3D &asoc_qcom_qaif_cif_dai_ops, + }, { + .id =3D VA_CODEC_DMA_TX_1, + .name =3D "VA CDC DMA TX1", + .capture =3D { + .stream_name =3D "VA CDC DMA TX1 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 4, + }, + .ops =3D &asoc_qcom_qaif_cif_dai_ops, + }, +}; + +static int shikra_qaif_get_dma_idx(unsigned int dai_id) +{ + const struct qaif_dmaidx_dai_map *map; + int i, size; + + if (dai_id >=3D AIF_MI2S_RX_0 && dai_id <=3D AIF_MI2S_TX_12) { + map =3D shikra_mi2s_dma_dai_map; + size =3D ARRAY_SIZE(shikra_mi2s_dma_dai_map); + } else if (dai_id >=3D AIF_TDM_RX_0 && dai_id <=3D AIF_TDM_TX_12) { + map =3D shikra_tdm_dma_dai_map; + size =3D ARRAY_SIZE(shikra_tdm_dma_dai_map); + } else { + map =3D shikra_cif_dma_dai_map; + size =3D ARRAY_SIZE(shikra_cif_dma_dai_map); + } + + for (i =3D 0; i < size; i++) { + if (map[i].dai_id =3D=3D dai_id) + return map[i].dma_idx; + } + return -EINVAL; +} + +static int shikra_qaif_alloc_stream_dma_idx(struct qaif_drv_data *drvdata, + int direction, + unsigned int dai_id) +{ + const struct qaif_variant *v =3D drvdata->variant; + int dma_idx, index; + + dma_idx =3D shikra_qaif_get_dma_idx(dai_id); + if (dma_idx < 0) + return dma_idx; + + if (qaif_is_aif_port(dai_id)) { + index =3D (direction =3D=3D SNDRV_PCM_STREAM_PLAYBACK) ? + dma_idx : v->wrdma_start + dma_idx; + if (index >=3D QAIF_MAX_AIF_DMA_IDX) + return -EINVAL; + if (test_and_set_bit(index, &drvdata->aif_dma_idx_bit_map)) + return -EBUSY; + } else if (qaif_is_cif_port(dai_id)) { + index =3D (direction =3D=3D SNDRV_PCM_STREAM_PLAYBACK) ? + dma_idx : v->codec_wrdma_start + dma_idx; + if (index >=3D QAIF_MAX_CIF_DMA_IDX) + return -EINVAL; + if (test_and_set_bit(index, &drvdata->cif_dma_idx_bit_map)) + return -EBUSY; + } else { + return -EINVAL; + } + + return index; +} + +static int shikra_qaif_free_stream_dma_idx(struct qaif_drv_data *drvdata, + int index, + unsigned int dai_id) +{ + if (qaif_is_aif_port(dai_id)) + clear_bit(index, &drvdata->aif_dma_idx_bit_map); + else + clear_bit(index, &drvdata->cif_dma_idx_bit_map); + return 0; +} + +static const struct qaif_variant shikra_qaif_data =3D { + .ee =3D 0, + + .num_rddma =3D 4, + .num_wrdma =3D 4, + .wrdma_start =3D 4, + + .num_codec_rddma =3D 4, + .num_codec_wrdma =3D 4, + .codec_wrdma_start =3D 4, + .num_intf =3D 4, + + .rddma_reg_base =3D 0x8000, + .rddma_stride =3D 0x1000, + .codec_rddma_reg_base =3D 0xc000, + .codec_rddma_stride =3D 0x1000, + + .wrdma_reg_base =3D 0x11000, + .wrdma_stride =3D 0x1000, + .codec_wrdma_reg_base =3D 0x15000, + .codec_wrdma_stride =3D 0x1000, + + .rddma_irq_reg_base =3D 0x19000, + .rddma_irq_stride =3D 0x1000, + .codec_rddma_irq_reg_base =3D 0x191A0, + .codec_rddma_irq_stride =3D 0x1000, + + .wrdma_irq_reg_base =3D 0x19078, + .wrdma_irq_stride =3D 0x1000, + .codec_wrdma_irq_reg_base =3D 0x19290, + .codec_wrdma_irq_stride =3D 0x1000, + + .qxm_type =3D QAIF_QXM0, + .rd_len =3D 512, + .rddma_shram_len =3D 64, + .rddma_shram_start_addr =3D {0, 256}, + .wr_len =3D 512, + .wrdma_shram_len =3D 64, + .wrdma_shram_start_addr =3D {0, 256}, + + .clk_name =3D (const char * const []) { + "lpass_config", + "lpass_core_axim", + "bus", + }, + .num_clks =3D 3, + + .dai_driver =3D shikra_qaif_cpu_dai_driver, + .num_dai =3D ARRAY_SIZE(shikra_qaif_cpu_dai_driver), + + .dai_bit_clk_names =3D (const char * const []) { + "aif_if0_ibit", + "aif_if1_ibit", + "aif_if2_ibit", + "aif_if3_ibit", + }, + .aif_full_cycle_en =3D (const bool []) { false, false, false, false }, + .aif_ctrl_data_oe =3D (const bool []) { false, false, false, false }, + .aif_loopback_en =3D (const bool []) { false, false, false, false }, + .alloc_stream_dma_idx =3D shikra_qaif_alloc_stream_dma_idx, + .free_stream_dma_idx =3D shikra_qaif_free_stream_dma_idx, + .get_dma_idx =3D shikra_qaif_get_dma_idx, +}; + +static const struct of_device_id shikra_qaif_cpu_device_id[] =3D { + { .compatible =3D "qcom,shikra-qaif-cpu", .data =3D &shikra_qaif_data }, + {} +}; +MODULE_DEVICE_TABLE(of, shikra_qaif_cpu_device_id); + +static struct platform_driver shikra_qaif_cpu_platform_driver =3D { + .driver =3D { + .name =3D "shikra-qaif-cpu", + .of_match_table =3D shikra_qaif_cpu_device_id, + .pm =3D pm_ptr(&asoc_qcom_qaif_pm_ops), + }, + .probe =3D asoc_qcom_qaif_cpu_platform_probe, +}; +module_platform_driver(shikra_qaif_cpu_platform_driver); + +MODULE_DESCRIPTION("Qualcomm Audio Interface (QAIF) Shikra variant driver"= ); +MODULE_AUTHOR("Harendra Gautam "); +MODULE_LICENSE("GPL"); --=20 2.34.1 From nobody Fri Sep 25 14:31:50 2026 Received: from mx0b-0031df01.pphosted.com (mx0b-0031df01.pphosted.com [205.220.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6D19B46AA85; Fri, 11 Sep 2026 09:19:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.180.131 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118385; cv=none; b=B64Tn3E9rcT98Y4HICT1+UO8wI1ebTS0gpIxI/qhlWn4oJ7+dCsTkN2Lq+Q8u9Vw631OlOjtBn/v6wNxOWJ3gApgJdAhtf46M0OQLRZ3PxQjUROLhi3UIDTkBK7TGkXlMN6aZUVRgApfrR9mhHOUAttojsKyk2LcdflIHZFEWuw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1789118385; c=relaxed/simple; bh=/VLPwU7IBziP7tJTYFhfwJcKF4KpF5h6IYddLt9oIQE=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=PKz0abyaWQt6dlgJeE/fXDaDPcZ83Bn/6wUiuXEJ4YFiXO/sxtWqRlb6US8WyQIqbuJQT/iBv2ZMLOk4yirGCHOz+Xt2UFi1PHzJ1l24O4l2pzzofI5ivCs5jeLov3UPfAg1PEgoFUEKFUhtX/OjCc5iRfre180qSiJeVkdDwkg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=B+0RgFtC; arc=none smtp.client-ip=205.220.180.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="B+0RgFtC" Received: from pps.filterd (m0279871.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 68B7kl1O4046179; Fri, 11 Sep 2026 09:19:29 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= 6zrOdq1zF5td3T+JYJ2hNSlQsoDEC0oTmGx6Ybl0UTE=; b=B+0RgFtCvgnvvK/j 6dyRPkz5vSGGMOkZZTEfnrFsfPcdEDotNJtNm3Y2cdkZflpUcMzC/QntGiILSorv EGqdUlnQQOnTrxHxP+r0SizoaHYySg4hYRWF8N26gR4t76gsuaPkQFICl2DHsb67 /7DEHw1KbjF8ciYHxlLXQXKrFaeI4IAw21YYbXvw1DbyaVkV4LCvMIE9rnYLy3tB hlR6wRRz+Gu9OQQryI4Tzk6nVy0Luo/RPcBmaE7palDcS6YH9bWB7hOs6yjCTRUw +wJs6nbiF9erkcLE3imkhiQf9wPJDbFcPE3GKpHnvG3Sx4Va9mPO7LyN3PMKT3Rw xc0Rmw== Received: from apblrppmta02.qualcomm.com (blr-bdr-fw-01_GlobalNAT_AllZones-Outside.qualcomm.com [103.229.18.19]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4gm2q12rax-1 (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384 bits=256 verify=NOT); Fri, 11 Sep 2026 09:19:29 +0000 (GMT) Received: from pps.filterd (apblrppmta02.qualcomm.com [127.0.0.1]) by APBLRPPMTA02.qualcomm.com (8.18.1.11/8.18.1.11) with ESMTP id 68B9JOfM2870876; Fri, 11 Sep 2026 09:19:26 GMT Received: from hu-hgautam-hyd.qualcomm.com (hu-hgautam-hyd.qualcomm.com [10.147.247.91]) by APBLRPPMTA02.qualcomm.com (PPS) with ESMTP id 68B9JL2g2870824; Fri, 11 Sep 2026 09:19:26 +0000 (GMT) From: Harendra Gautam Date: Fri, 11 Sep 2026 14:47:34 +0530 Subject: [PATCH v6 10/10] MAINTAINERS: Add Qualcomm QAIF driver entry Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable Message-Id: <20260911-b4-qaif-shikra-audio-v6-10-e9addb358201@oss.qualcomm.com> References: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> In-Reply-To: <20260911-b4-qaif-shikra-audio-v6-0-e9addb358201@oss.qualcomm.com> To: Srinivas Kandagatla Cc: Mark Brown , Liam Girdwood , Rob Herring , Krzysztof Kozlowski , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai , Kuninori Morimoto , linux-sound@vger.kernel.org, linux-arm-msm@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, Prasad Kumpatla , Krzysztof Kozlowski , Sarath Ganapathiraju , Kumar Anurag Singh , Mohammad Rafi Shaik , Harendra Gautam X-Mailer: b4 0.15.2 X-Proofpoint-Reinject: loops=2 maxloops=12 X-QCInternal: smtphost X-QCInternal: smtphost X-Authority-Analysis: v=2.4 cv=d6lgWhjE c=1 sm=1 tr=0 ts=6aa3c7a1 cx=c_pps a=Ou0eQOY4+eZoSc0qltEV5Q==:117 a=Ou0eQOY4+eZoSc0qltEV5Q==:17 a=IkcTkHD0fZMA:10 a=VdqzKS8jKosA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=3WHJM1ZQz_JShphwDgj5:22 a=EUspDBNiAAAA:8 a=VwQbUJbxAAAA:8 a=COk6AnOGAAAA:8 a=PFusfAj7JESbPCsvM_wA:9 a=QEXdDO2ut3YA:10 a=TjNXssC_j7lpFel5tvFf:22 X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfX3YsII0cJd51H KRsdoP+UWGFBfyAxuE3VAvjC9uGPpY3SyDFLCOCej5BLGYd5m/UT6yTbDizLXsqsUE9znGiU+Ud V78SrLk+zhPpokQfuIBKzRoNLJGmaDfRni9TQI3ZFEd1JUCLSk3cppDp85M887Ja34WiTmjjqpk YCRLJUf01dR5pKDcWBnlLF+0s7mZs/UEiZH+XkkSGad84X30xv8DP4LVXwCuoJNjsvRx8Yec3q5 qgU6SBiJNt9/0ptH6wB885FUJeTBppCEIjyjuMQTjWXtOlW7PY2sn/EiLm//yPx3XaDgRdYwFuP JuEP30U3QmaxAQwh1i7V/pks+1kygs/yo+b16Sp5KquesIrNWPRRJyi661RC2j1kgNNW7XyvKFF aNoMGEMkCdbVnBJxzsi7RTbmgH2iQuhdL/uG+hg6eWA/aICGpNU0o6YGxCx20i176bTVbp2Cp77 F/8XyvZ9oGslEHsicWw== X-Proofpoint-Spam-Info: AW1haW4tMjYwOTExMDEyOSBTYWx0ZWRfXy6EGqlPX9m4L MbbKPBhMO1YwqKgKu1LmsDBgsoOgCCT6N4zcIs2cYA/pu48Wr0EFfN/3NgJEojEso+Gm/b/mIrl jloo2m6HmLJpY26ttNt+7y8mMJD4HAQ= X-Proofpoint-GUID: AGn7ER8ph8nTWF2bico8kgF_vV_xmYoA X-Proofpoint-ORIG-GUID: AGn7ER8ph8nTWF2bico8kgF_vV_xmYoA X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1176,Hydra:6.1.134,FMLib:17.12.100.49 definitions=2026-09-11_03,2026-09-09_02,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 impostorscore=0 suspectscore=0 spamscore=0 priorityscore=1501 bulkscore=0 adultscore=0 lowpriorityscore=0 phishscore=0 clxscore=1015 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2609040000 definitions=main-2609110129 Add a dedicated MAINTAINERS entry for the Qualcomm Audio Interface (QAIF) driver so changes to its devicetree binding, dt-bindings header, and ASoC driver files are routed to the Qualcomm ASoC maintainers and mailing lists. Signed-off-by: Harendra Gautam --- MAINTAINERS | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 7291238bc09f..4296f812ad36 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -22133,6 +22133,15 @@ F: sound/soc/codecs/wcd93*.* F: sound/soc/codecs/wsa88*.* F: sound/soc/qcom/ =20 +QCOM AUDIO INTERFACE (QAIF) DRIVER +M: Harendra Gautam +M: Srinivas Kandagatla +L: linux-sound@vger.kernel.org +L: linux-arm-msm@vger.kernel.org +S: Supported +F: Documentation/devicetree/bindings/sound/qcom,shikra-qaif-cpu.yaml +F: sound/soc/qcom/qaif* + QCOM EMBEDDED USB DEBUGGER (EUD) M: Souradeep Chowdhury L: linux-arm-msm@vger.kernel.org --=20 2.34.1