From nobody Fri Sep 25 21:40:26 2026 Received: from mail-wr1-f42.google.com (mail-wr1-f42.google.com [209.85.221.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id E689F51D519 for ; Tue, 8 Sep 2026 09:04:59 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.42 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788858302; cv=none; b=KDg3ILjpxNG+awtEGDhmsKQY+3ogzKKXxBYgVwnvT/9ymSas0b2Hrry5RPKw18GodkVmRV2GT6EBHqYSVxldSKC3L3p0v/M6fsAI0paKKc33CNkuSFMqd58KGKIvg/F4Kkmgub0JChWu7f3WnnyZl7B63O36POL3LNIn7wqlOjE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788858302; c=relaxed/simple; bh=BbwwSi4NkYc+Qs1d3CvwqDnlgSJO4+ug+OKxVntKOjw=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FfIID802zOfrr61iS4NxJq+09zoiFP/7YrbrRHOiM7ewndVB2rWIfDGAcwKeqtO6brxLSYxU+m7mat3LurdqsqFkDt7NCOROpqzAiEv096LWsDsJAXWsOeR48LJqYDqmX/jB0V75t9tSNrR+tnCz6+L4ob/Cyi0FOKsJvVd5Zx8= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=lVVUVjTu; arc=none smtp.client-ip=209.85.221.42 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="lVVUVjTu" Received: by mail-wr1-f42.google.com with SMTP id ffacd0b85a97d-4843efcbdb2so2449087f8f.2 for ; Tue, 08 Sep 2026 02:04:59 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788858298; x=1789463098; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=XiNHpVYuqEREvxb2cZ27NaECVLCJPPbGo8j+h2MHZLo=; b=lVVUVjTuhDvpPSQZRsjAi9x3dJxDWsHa0M3KVwzk1eFKlpbwrqbqT46zzDeSaxM+vx dPJd4G+aM6JRAy0NknVIuYJzbS2ufvDBrT++iUzUwt8BrTps0CJUqJcoTdPtUG6S05m3 FRWBRJKQ9YvDW/hRd3LlOnfPQmE69XC8dW7fAp18oJZWRc4QtjsyozJ9zdSQ6CJV7oaZ uOrkU7qtt5DohxjLdZErZM4xWlyVFm53vfW92ldMCaOCVM3cNQ7a4k3tD3NsUxWW04NT Zmy4m0IGeHh801yfgg13H6BK7MUNwzAY0//GO9xOrYck64tX2QsgK83+X12OmiRpO4Am ZnYQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788858298; x=1789463098; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=XiNHpVYuqEREvxb2cZ27NaECVLCJPPbGo8j+h2MHZLo=; b=BeJEXvkp6sOKO9yOEBNgTffFqWZs24ZaTwKUczhYH8YfhLOw9SiFgiO/CAAC8++sZ3 P+0zzK4s/OzlZU+CvKrTTD5IIXQojHKKC2unNF7PJjFTvXluvOKwjR5IM46H2JQQcRcn wNL9QmA0kbSZFBApnZeF0RSJh6ttuvLcVVbqDEPVi4UA2nEnyNZq/ovAMNaX+0BA04tb WPT7O80KnhKk8lflP3QNVPnRCRKFJxcAzkyfFW/HNx53PEGznrQuLzBEv+SFyM6gIlwl C90/du3eE7QB+Z+vUfdelMuiMXVZpv3JQEVBtdsX8/pVj7T5/pnfx8WMOFwHVvOFSO1D TZTw== X-Forwarded-Encrypted: i=1; AKwUvBwslAycDzkEKDy31EnhMAhUTaxR3XVd1o1OcrxOJPj+6ZI1a413NXW1Ok2hHXEMUlwoGmGmFXFinzIOV5Y=@vger.kernel.org X-Gm-Message-State: AFuF++mxRJqcyTCG9ILPd7Hp2Ild1BYtJpdm3eCMLXTJ8+TrXKDuMmot WK9DSLnuzMGn0g+4RJiLdhFogERihJX38D7IKI9mKpz39v8MUHHoT6sc2CdQEA== X-Gm-Gg: AYBFou3TziLUBfD2KfHjKSYSUDRZv9PHiJYVNckuiaJlUGZeBCt/N5IHqVBr4lIPb/6 x4RmuqXabYs0rCO4krM3ACL1lAOAnZYezie4lEwqBUz49sOzl+VBLkw0ISwzrVtM/+6VacSbwYl mMBxB9KHFUvmFSmnPlL+xbHwO4hyYuH2TKzSIt8w2J9SSDOI5TeFcDvWJyO6xX9SyDWrNGoIk/L jDKiigAocAIf80u39EMij6OWc0yl81juTX0fM2PkHxrLlCK/nUErLbajMLv1yEDVX7pciwcrBAN EeQ1p2+giMrVOtssXLgd/9a3Bjv5o4rgsSeTMEeOogzNrHXzEqfBNjgbV4rYJ7/NR5hAhrDckiO 9gTdgnhe9U9GsPweP/cunzPewN1KrxUDClPsl3+PSwtC71rsVRhPyu98n+yCpSjCuRXiUe74Zjs SaSrydpBv6rRD0TvjHqgdymJp1tSlEjc8LD/HklwmNM2dMk8mc63l0XIv07TAcPioGMVGLO8dqK 6s+H3PyKoCOnExW7ic618YJevrMvnzmvlEk4rxhzR7RKdJr6tM5lxFQ4q44SDg= X-Received: by 2002:a5d:59c1:0:b0:485:a46b:bc13 with SMTP id ffacd0b85a97d-485a46bbd19mr4173287f8f.0.1788858297632; Tue, 08 Sep 2026 02:04:57 -0700 (PDT) Received: from Ansuel-XPS24.localdomain (host-79-26-252-140.retail.telecomitalia.it. [79.26.252.140]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-485881353e8sm34767945f8f.1.2026.09.08.02.04.55 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Sep 2026 02:04:57 -0700 (PDT) From: Christian Marangi To: Christian Marangi , Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai , Matthias Brugger , AngeloGioacchino Del Regno , Philipp Zabel , Cyril Chao , Darren Ye , Rosen Penev , Daniel Golle , bui duc phuc , linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: [PATCH v6 1/5] ASoC: dt-bindings: Add Airoha AN7581 AFE Sound card Date: Tue, 8 Sep 2026 11:04:43 +0200 Message-ID: <20260908090448.3332-2-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260908090448.3332-1-ansuelsmth@gmail.com> References: <20260908090448.3332-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add YAML schema for Airoha AN7581 AFE SoC sound card. The AFE handling on this SoC is very basic with clock always enabled and all the power saving feature not available. Signed-off-by: Christian Marangi Reviewed-by: Rob Herring (Arm) --- .../bindings/sound/airoha,an7581-afe.yaml | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/airoha,an7581-a= fe.yaml diff --git a/Documentation/devicetree/bindings/sound/airoha,an7581-afe.yaml= b/Documentation/devicetree/bindings/sound/airoha,an7581-afe.yaml new file mode 100644 index 000000000000..80d9e87f1470 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/airoha,an7581-afe.yaml @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/airoha,an7581-afe.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Airoha AFE PCM controller for AN7581 + +maintainers: + - Christian Marangi + +properties: + compatible: + const: airoha,an7581-afe + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + +additionalProperties: false + +examples: + - | + #include + #include + + afe@1fbe2200 { + compatible =3D "airoha,an7581-afe"; + reg =3D <0x1fbe2200 0x9000>; + + interrupts =3D ; + }; + +... --=20 2.53.0 From nobody Fri Sep 25 21:40:26 2026 Received: from mail-ed1-f51.google.com (mail-ed1-f51.google.com [209.85.208.51]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BE0FC51E447 for ; Tue, 8 Sep 2026 09:05:01 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.208.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788858303; cv=none; b=CA4idS6UGBLeyNWAFNZ6mbhPHrtU8eutm1PCifCe413An8Zexw22WTk6+uhHdt0lbmNAY1xAcLXoz1JsmUI32NMtuJhHgkj2Hnk62GlT8PgT1rmvQ2ZNH9Ob2Y3nw4A6J9rEr7XR6RfC/35Mbq04X3UI89xoQqDRf9Dpn5tqq5c= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788858303; c=relaxed/simple; bh=cOTndiYvXLFAAAM2y9Xe4uyBomgWf+BKu0APrUCfPAs=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=i45XIRMxRFJp9r6nCMga4NROppTG++Y81vj7AedCrsI0E6krVv6ZevtQySo68jWvenO1yGnAcNzKnDgiWPZ7Y1qFsMcSSybVuVYPnjp/pXvQT8pR0gFJYhWMXsG1SMGImJiuGmkbxSp9RHep3yLt5zATm94QLQS0STr88++KvH4= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=gmeO8JYt; arc=none smtp.client-ip=209.85.208.51 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="gmeO8JYt" Received: by mail-ed1-f51.google.com with SMTP id 4fb4d7f45d1cf-6a682579c72so5550824a12.1 for ; Tue, 08 Sep 2026 02:05:01 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788858300; x=1789463100; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=lDFqPj8lYrNqkm6rPond2RAeUqExmlqhsFWYW68q/vg=; b=gmeO8JYtiOFIvUQvVhLHW5TNfGLV7PEyoufi7jtp1HSOyPoiHYMsEiwvVdjfqzrisk KcEtGO/mtcpZpVFLIm+4gLOWkWFN+eCDnMI8eM3nfw7vYfwE35ktMQiYmM2wzcbbKPVs IRdQeLuwUinia3l/8m1V8f8imtvp4/FvBsi2idDXVkczA/xn6bMynj41tj1s17LELv6/ yUVVnFUvT1jWwb/LNNiZoNHnFlhXMWQ9+ZgzUn+fABMhKcVbjFPPB91rmawSaK5CdEVd MUfl6RaOB4+6q5KKR3HLRmT+qKUj/T6PaMi82ELZix5VqcAO8PJeDHI18uFEg3/GM9kk GLWQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788858300; x=1789463100; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=lDFqPj8lYrNqkm6rPond2RAeUqExmlqhsFWYW68q/vg=; b=KFDdI9bMdei2mHkXJp/HzBI6z0EkylD8BUPgh0Mp6fR0NpH0y8JlTn+e/usi3zsklD skHTiFmNnBXd+V1rQsyIa0uwM7EVH0eXSWQYTQZ/f+mv3t7ftfxflcoSar8Q8tjBQiHV IuwT3I/YqgiHAdBxIGvMahgnRM1gbHBxt4xWdXeea0ic5dI2dK7/7yPZIiJjASrysMsJ Px1zimRQsG7IlSXRVwBiLokp1OWXIb4umFzMrwtMGKMMpKrKM99WlmOmWP5MWzKIS0/4 RvKfwECUMgBLfBjvZkgKzyugKe2BPlqYJYBCSfu5cyRkn7AYVO2EFuKdqPcjeAQmQcte PU7g== X-Forwarded-Encrypted: i=1; AKwUvBzEx0bJA5urCQaiF7AIw59F7t9XujJnrLmw0BZ/pmrck6YJy+JCmxxXJnkO09akQqI+wZT41IpdoacY7mM=@vger.kernel.org X-Gm-Message-State: AFuF++lxvo7zbIdVcG3U1x2735QDCgtEzIRalxDunF0M0By3jc1EFDTM KTZj3Snztyzuvyzm+euwODcszNz94NLw5LVQ3BRsIxcoynv7ErgJDpw5 X-Gm-Gg: AYBFou2pZ65JYcLl5EM/TJ+yBujF7cPO/rn8+1cSvMHzL3QIoSwzvZhA7l+8Yi71Sam lfJ5eE/VdnjNVOXQ58vp0I7aMjGnX3a0jIfo491+ZAXbLe+p4veppjthiPko+Ye+XRUrxHpMFKF 69N5rQ0HHtxlYhTP9Q9mGuJ1gOlbOQAvmAThGDF5+VfTawz4loHiTU+4SN3AGIjre1jApsq7Zmq mn2EJu1613orWgoaBkvteIeuKQCJdqGq/QL0/nebPgMpvJznvlW7F7M1eGmV5J01tLbiK6898iH M8UR/vP4XingvPrilvndulnVrRRGhxaEumEKMAx7L56nyq5t+CG7dApqBYzwHLKvugHgFrMPp5X fBZSpFxr6iWZdiz67+lHwJpsrpYGHnvCSly2avthE9wD2VECFWad2fNv09JYWyDz0peF6FWLTpF z1gSVOyRoGESRNJrvCqERdpSU2nT5a0KN7R1t5F5ONYQ6pXuvwoMXTjV/sjBmW+AllljI70iqX3 yYM3BVKYmofwh22faxhjnO0ViY0RbUEViCpqrlUo1fc6qoKiURU X-Received: by 2002:a05:6402:3554:b0:6a6:21d9:541f with SMTP id 4fb4d7f45d1cf-6a7e8d4d131mr18523650a12.6.1788858299489; Tue, 08 Sep 2026 02:04:59 -0700 (PDT) Received: from Ansuel-XPS24.localdomain (host-79-26-252-140.retail.telecomitalia.it. [79.26.252.140]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-485881353e8sm34767945f8f.1.2026.09.08.02.04.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Sep 2026 02:04:59 -0700 (PDT) From: Christian Marangi To: Christian Marangi , Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai , Matthias Brugger , AngeloGioacchino Del Regno , Philipp Zabel , Cyril Chao , Darren Ye , Rosen Penev , Daniel Golle , bui duc phuc , linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Cc: Krzysztof Kozlowski Subject: [PATCH v6 2/5] ASoC: dt-bindings: Add Airoha AN7581 AFE with WM8960 Codec schema Date: Tue, 8 Sep 2026 11:04:44 +0200 Message-ID: <20260908090448.3332-3-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260908090448.3332-1-ansuelsmth@gmail.com> References: <20260908090448.3332-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add DT schema for Airoha AN7581 Sound Card with the specific WM8960 i2c Codec. Reviewed-by: Krzysztof Kozlowski Signed-off-by: Christian Marangi --- .../bindings/sound/airoha,an7581-wm8960.yaml | 71 +++++++++++++++++++ 1 file changed, 71 insertions(+) create mode 100644 Documentation/devicetree/bindings/sound/airoha,an7581-w= m8960.yaml diff --git a/Documentation/devicetree/bindings/sound/airoha,an7581-wm8960.y= aml b/Documentation/devicetree/bindings/sound/airoha,an7581-wm8960.yaml new file mode 100644 index 000000000000..8886fbb6b43c --- /dev/null +++ b/Documentation/devicetree/bindings/sound/airoha,an7581-wm8960.yaml @@ -0,0 +1,71 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/airoha,an7581-wm8960.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Airoha AN7581 sound card with WM8960 codec + +maintainers: + - Christian Marangi + +allOf: + - $ref: sound-card-common.yaml# + +properties: + compatible: + const: airoha,an7581-wm8960-sound + + platform: + type: object + + additionalProperties: false + + properties: + sound-dai: + items: + - description: The phandle of AN7581 platform. + + required: + - sound-dai + + codec: + type: object + + additionalProperties: false + + properties: + sound-dai: + items: + - description: The phandle of WM8960 i2c codec. + + required: + - sound-dai + +required: + - compatible + - audio-routing + - platform + - codec + +unevaluatedProperties: false + +examples: + - | + sound { + compatible =3D "airoha,an7581-wm8960-sound"; + model =3D "an7581-wm8960"; + audio-routing =3D + "Headphone", "HP_L", + "Headphone", "HP_R", + "LINPUT1", "AMIC", + "RINPUT1", "AMIC"; + + platform { + sound-dai =3D <&afe>; + }; + + codec { + sound-dai =3D <&wm8960>; + }; + }; --=20 2.53.0 From nobody Fri Sep 25 21:40:26 2026 Received: from mail-wr1-f54.google.com (mail-wr1-f54.google.com [209.85.221.54]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 798CA4F649E for ; Tue, 8 Sep 2026 09:05:03 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788858305; cv=none; b=geQbK+w0/wnhV3mp7u0AFqsBoezNccT10MNedkUMv09J+vBhR9r2FQ5IeRTOTkTFdWyaHqFt5tZ+zvhpzC+5XYiuMA5MCnZFn7WkJRTLn8ScW18DzUMSds0ZV88avDRSf0aKM8PyuG5FHR9OIvKxCRjBQqIO/vM2nyMf31guNfw= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788858305; c=relaxed/simple; bh=ovG3KD9SWw2WSAD+Z+FkwTd4OAPzI25cyyOlO4Nkoro=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=FB6JYgHP3ehybVju3QfK362StWzOixgxyxLwq7Est1o5U6OZwXCK7vE9QZbJzoHsY8klul+hvrmDdeqbjDq5TuOd+iOMcxJJhaXXP9tWHxMzIJZeTEvzTJ4fnOZaBIWBCdDhZMYdNI9uPUXIu+MS7HUiq0YQ6gN6oW1LR6yHTRk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=kCGEdsoa; arc=none smtp.client-ip=209.85.221.54 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="kCGEdsoa" Received: by mail-wr1-f54.google.com with SMTP id ffacd0b85a97d-4858be8b509so1927019f8f.0 for ; Tue, 08 Sep 2026 02:05:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788858301; x=1789463101; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=U4zFNvqb3TCUq9G6zwsXaSter1qm2jsnjI9BXrVsaKk=; b=kCGEdsoaW5lzBo5X8NdlroTvWDvWNEZHjAdd83ElO6lW8HQahPfSxR95R6xmn4D4oT TqfR+5ZcP1VD4rW+dU5mXTxMsrKy0+SCq+Kr527iOWKgpqXPHqCvcm6NlWIA3r3Ida8v bmofGJO1ECNR2LQu505oZiOX5th4Dd2Wplo57wRREnPzpYb900zVCr+GKwUWkP/fejxo xZm+khMLGCaloEC48yEgy8l5FZO5zYZZRcsraKhoz+0ryKM8uNbnOqgWdOcQ0LG1EMug AgMG29EWhqhX11rfHDljcHAGxHhwQOfZ3MmymL0BGm5IGk5OL7Knwxlmbl3/Z+bT2tjh w2zA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788858301; x=1789463101; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=U4zFNvqb3TCUq9G6zwsXaSter1qm2jsnjI9BXrVsaKk=; b=d2Nie0Ui+IwXqjkmmCcj7EiIm3hGxlsDGnclBRqT3TGicUHstlPeVL8cECZ7xrn8jm 2bVm5F7AlMjMsGF/E0QEaoTodvSA6apnbfO6H4rbcUrDrnggltl1LPwKMXKbEPC7EqF8 iIYsL2ahbMyXSDASBPCw/hhUAC0d7DPwtJVSs/FuzUDwnLwxOEfj0r/fb8PK80nkmdny zjwKNQR3NOev9zo/uhzhGtBdL3ZRu46YI0pbaUkyf+K671m3kgxMrYFEVLu4W0frENtr TPN6EWHrnIsfK39XtPEMejRP1cUkQq/saIZ/1qq5PoBYHSps4ZgZBnajtkXjq46E6h+F vJdg== X-Forwarded-Encrypted: i=1; AKwUvBy1NQon5xMCIkdB0kaYyC2WRfFusuePRORGC8c4qPkzwZbmeel0oneGDALbae5kbf0GWyJlC7wTdaZjkvA=@vger.kernel.org X-Gm-Message-State: AFuF++msTMBpxbBRJf3liTJM+NevP1JES5OUBlFd3fAAK6h0Oov7JSu1 /h5ZUaJCzVvOKfIrNrKS/q/Lp2FDx8FTwGMpo1etuo+JWuKWr+7fOGlh X-Gm-Gg: AYBFou0Ndn/UdqRLV6s6tJQG6TPlNmhbGKMAbD3BisefI41qChUjN2hicVwmYq7M/FY fg60+m9ULQAhedlKa7nBznSvpjBfEn1dmzUSZ+VH17NDMMRwljIetMit3s1CeR+nmMA4wMCQMAa KYB00KIFZrQyjRab22VjSjr8JyDBNoEtdKA/kRazp9yI8NBAZdqwQAmlxezkNyu1xuqBAkyJ2t2 o7Ues9J4jchiiXsPAYf3c3i+X4X30S1P/vFc/PrqDYk6xjx7QrTmEaDwHP4IuV8B33IDsh00c++ OY7AtBgJmJxkAVJ4pVUbjsUoz22aZT1oPiT6XJj2EeHNgbZrCB/BVv+Zz66Pz9V33ASgE9sRVfZ P918u6wNheN2+KDEOV3ybFT5y1chZpmMQz0EH8yW47ICJlwbZXt35R7Pe7ZczHzMk25D8lTdkG7 4BvlzQXyQKUqXh96LBeIR1bP8WT2MYWommZUDzA9x4/Wp4nlfl6lypWkMywGCaCTBmMpvLgbecx frhgdydvV28kI1yE4D3TXMlyc7o7fUsLcOst+dokOV3H9YDac7b X-Received: by 2002:a05:6000:26d3:b0:484:4146:1422 with SMTP id ffacd0b85a97d-485870934f4mr28074029f8f.21.1788858301380; Tue, 08 Sep 2026 02:05:01 -0700 (PDT) Received: from Ansuel-XPS24.localdomain (host-79-26-252-140.retail.telecomitalia.it. [79.26.252.140]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-485881353e8sm34767945f8f.1.2026.09.08.02.04.59 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Sep 2026 02:05:00 -0700 (PDT) From: Christian Marangi To: Christian Marangi , Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai , Matthias Brugger , AngeloGioacchino Del Regno , Philipp Zabel , Cyril Chao , Darren Ye , Rosen Penev , Daniel Golle , bui duc phuc , linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: [PATCH v6 3/5] ASoC: mediatek: common: permit to provide dedicated regmap for irq Date: Tue, 8 Sep 2026 11:04:45 +0200 Message-ID: <20260908090448.3332-4-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260908090448.3332-1-ansuelsmth@gmail.com> References: <20260908090448.3332-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Some SoC might require dedicated regmap to configure some specific IRQ register. Add an extra entry in the base_afe_irq struct and use the specific regmap if defined. If not defined then the global AFE regmap is used instead. Signed-off-by: Christian Marangi --- sound/soc/mediatek/common/mtk-afe-fe-dai.c | 14 +++++++++----- sound/soc/mediatek/common/mtk-base-afe.h | 2 ++ 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/sound/soc/mediatek/common/mtk-afe-fe-dai.c b/sound/soc/mediate= k/common/mtk-afe-fe-dai.c index 2a20fa5dba49..948f606cbaf2 100644 --- a/sound/soc/mediatek/common/mtk-afe-fe-dai.c +++ b/sound/soc/mediatek/common/mtk-afe-fe-dai.c @@ -204,11 +204,15 @@ int mtk_afe_fe_trigger(struct snd_pcm_substream *subs= tream, int cmd, struct mtk_base_afe_irq *irqs =3D &afe->irqs[memif->irq_usage]; const struct mtk_base_irq_data *irq_data =3D irqs->irq_data; unsigned int counter =3D runtime->period_size; + struct regmap *regmap =3D afe->regmap; int fs; int ret; =20 dev_dbg(afe->dev, "%s %s cmd=3D%d\n", __func__, memif->data->name, cmd); =20 + if (irqs->regmap) + regmap =3D irqs->regmap; + switch (cmd) { case SNDRV_PCM_TRIGGER_START: case SNDRV_PCM_TRIGGER_RESUME: @@ -220,7 +224,7 @@ int mtk_afe_fe_trigger(struct snd_pcm_substream *substr= eam, int cmd, } =20 /* set irq counter */ - mtk_regmap_update_bits(afe->regmap, irq_data->irq_cnt_reg, + mtk_regmap_update_bits(regmap, irq_data->irq_cnt_reg, irq_data->irq_cnt_maskbit, counter, irq_data->irq_cnt_shift); =20 @@ -230,12 +234,12 @@ int mtk_afe_fe_trigger(struct snd_pcm_substream *subs= tream, int cmd, if (fs < 0) return -EINVAL; =20 - mtk_regmap_update_bits(afe->regmap, irq_data->irq_fs_reg, + mtk_regmap_update_bits(regmap, irq_data->irq_fs_reg, irq_data->irq_fs_maskbit, fs, irq_data->irq_fs_shift); =20 /* enable interrupt */ - mtk_regmap_update_bits(afe->regmap, irq_data->irq_en_reg, + mtk_regmap_update_bits(regmap, irq_data->irq_en_reg, 1, 1, irq_data->irq_en_shift); =20 return 0; @@ -248,10 +252,10 @@ int mtk_afe_fe_trigger(struct snd_pcm_substream *subs= tream, int cmd, } =20 /* disable interrupt */ - mtk_regmap_update_bits(afe->regmap, irq_data->irq_en_reg, + mtk_regmap_update_bits(regmap, irq_data->irq_en_reg, 1, 0, irq_data->irq_en_shift); /* and clear pending IRQ */ - mtk_regmap_write(afe->regmap, irq_data->irq_clr_reg, + mtk_regmap_write(regmap, irq_data->irq_clr_reg, 1 << irq_data->irq_clr_shift); return ret; default: diff --git a/sound/soc/mediatek/common/mtk-base-afe.h b/sound/soc/mediatek/= common/mtk-base-afe.h index a406f2e3e7a8..b5300c9ed415 100644 --- a/sound/soc/mediatek/common/mtk-base-afe.h +++ b/sound/soc/mediatek/common/mtk-base-afe.h @@ -153,6 +153,8 @@ struct mtk_base_afe_memif { struct mtk_base_afe_irq { const struct mtk_base_irq_data *irq_data; int irq_occupyed; + + struct regmap *regmap; }; =20 struct mtk_base_afe_dai { --=20 2.53.0 From nobody Fri Sep 25 21:40:26 2026 Received: from mail-wr2-f12.google.com (mail-wr2-f12.google.com [74.125.225.76]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 5721E5221C1 for ; Tue, 8 Sep 2026 09:05:05 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=74.125.225.76 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788858309; cv=none; b=N/5qOYS0Wh5eicITyKH9KSLDiwI8TJhW0PTAGjjwiS+aEHmLz8Z/m0O+glpKeq4HgCvGJEjxhS9WRAsBufvzGgL9y8m4lraNA+bpm0Qfgnokpm1oGK7xRnIFPaJ/GJichtGfLRvDU9jS4PABEWRnyLHroMSSnQj0KmLIQQHMKxk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788858309; c=relaxed/simple; bh=OsawkstsVjYgerVm/53M8tCSZTwywunSzKtRJfCIYxE=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=u1n98+mm+9P6++N8v7HbHvF8LKLkKsk4697NJ4sohMDnPHjRo1eehxikhH3Zh1GL2uEWF2r5Uju+qmUS/7HcOvF/tzEL5LZMXVwiJP4ZZMnj3sWxEXkuQA7Ep4aXMuik/uIv8is/uXT+mSQiMHU5OuhXWTr5aiTMtXOgL4fmsgk= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=CKAO+6If; arc=none smtp.client-ip=74.125.225.76 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="CKAO+6If" Received: by mail-wr2-f12.google.com with SMTP id ffacd0b85a97d-482f62ccdb1so308311f8f.1 for ; Tue, 08 Sep 2026 02:05:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788858303; x=1789463103; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=TBt1+MvMUyhjfrZRMIFJhbFWr7xZ7mudkOkw/qsyFuY=; b=CKAO+6IfePJbPM3BmjUYFqmQj9XCW+AKsxAmy5A+eTrS7ttTR+7v3cEywD06MgQtRs K4sY8tsethGeJIOHVDOz01DOkOc7sN2q/o/oAjSmA+wHC7lf6VONp5CPCIZ0Jl1K+gBa qOmutTPjFLWR5mKlv4AbCoLiGk+h5PAmRfip7I4D8lQcPnN9MfAdvXkJuc6qkDEvZ2NI J24gV9xYN4z5cQctwd5k+kkS+4x4Ty+TYDULCcHAbdnQqWJcEmLvOBjX62oC32t1DAsn Q0Y8/jZrRtisNI+1JjbRFq2/FQ3u0UZr3Ft0CtxXs/5tRGNgv2SSviMSYWtQ/f73cGq2 rJ7g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788858303; x=1789463103; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=TBt1+MvMUyhjfrZRMIFJhbFWr7xZ7mudkOkw/qsyFuY=; b=T3HPDGC+QdYAG6MyMWBLhYZI8OkRLvoP5WJ2M/xSzfUQytbOtaUGR+HbQdiUV8+Vab hApajNMLwUpc7xWiQGu/lrSGbx1e3zMCEMe1ZFUfpfOFcZp0dgZyGmEi8ILtosveMEY9 FZ3s8daRTnj3TbSXmMdcWysR4mEsh+HBzOjy66NIDmdDkm2zrX+69jEAu4y762q5drcy /FMg4eUoBKvf4JyuIE0iKv0yw8DJUEUT4sE/xas0ftC9ld5GWDtEfX7Lph3HRbz1q/4D 2S6T1UP/wPSWxS6J9TlmPuhWxEsReBGb+iD4lyVaVQAjbUxE5dpgl1JGTnkPgZS8AyRI MOSw== X-Forwarded-Encrypted: i=1; AKwUvBzK9oJIjHmoJZa6IpqEXAMwIPU1jS7Hbm2wtwOmL8wA+Hs8cCEpYBUL9HjNBgxzw1p9qJM8GdoEN0yQuiA=@vger.kernel.org X-Gm-Message-State: AFuF++lqWlNlzIkn+/1Ns4OAw7Lshp7nN79wRs37oczqMl0n8gdNKpSt nwBLi/FID3VyY9EyKFaJ1jhKhr7GM+gLOLcDptMscqntg6MlHyddkufl X-Gm-Gg: AYBFou2NkrvlzNX78UboMaihJENKMpywALwkfqeKlguiTNZQBfI/ePLjM6q2cQ5UwUq 1M8HotqVgcFVEDmFsRtsFLmEwoeVNfgXRaBfBdyhJGRY0GLpjudOAhCkiHL7KbwvreNKeFnxGcf JivhOYZzfG3qiFsW7zGlb8VPv3ybxhmifT6PxWWllCRvvdMxrtOS87IU1uTTIoNkMPQSRRZQgPV VgBtr5c4ltfOqx9f7qMbWHNy61DVTjZcVejn4VQ/QnZr+BT2vS71hs3NQVWX0r+6YANRXg0TeLe O6u+1I3UT+HyD1Vsv7poq3xaWdbo8Mr2klXygbijc+QmYySA0SwpeKUEPAgY0xfO9EyHvtrF1Di qXcJx+Yb9BLcGWHTjC3dCabP8QyVuPBgI8nuB1lA6tC4eHJr6XU0CIjVQ3ZyLXK4TNyRjop6Ii6 OIcqvr77CNJfmzIjyoZSqlk6lcTjMxsZTXN60+6hnSNTkWzishCnOc6wDHDEmJ3dNbmTGmXhlaY jfLSmphcyqrNu9k6R1I7xJG61YfPC+vvAt/gNQoPeyYUQ2uyyc1 X-Received: by 2002:a05:6000:658:b0:485:9908:91b5 with SMTP id ffacd0b85a97d-485a23e1fe0mr5069511f8f.10.1788858303318; Tue, 08 Sep 2026 02:05:03 -0700 (PDT) Received: from Ansuel-XPS24.localdomain (host-79-26-252-140.retail.telecomitalia.it. [79.26.252.140]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-485881353e8sm34767945f8f.1.2026.09.08.02.05.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Sep 2026 02:05:02 -0700 (PDT) From: Christian Marangi To: Christian Marangi , Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai , Matthias Brugger , AngeloGioacchino Del Regno , Philipp Zabel , Cyril Chao , Darren Ye , Rosen Penev , Daniel Golle , bui duc phuc , linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: [PATCH v6 4/5] ASoC: airoha: Add AFE driver for Airoha AN7581 Date: Tue, 8 Sep 2026 11:04:46 +0200 Message-ID: <20260908090448.3332-5-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260908090448.3332-1-ansuelsmth@gmail.com> References: <20260908090448.3332-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add support for the Sound system present on Airoha AN7581 SoC. This is based on the Mediatek AFE drivers and adds the PCM and the ETDM driver. Signed-off-by: Christian Marangi --- MAINTAINERS | 8 + sound/soc/mediatek/Kconfig | 17 +- sound/soc/mediatek/Makefile | 1 + sound/soc/mediatek/an7581/Makefile | 8 + sound/soc/mediatek/an7581/an7581-afe-common.h | 49 ++ sound/soc/mediatek/an7581/an7581-afe-pcm.c | 515 ++++++++++++++++++ sound/soc/mediatek/an7581/an7581-dai-etdm.c | 433 +++++++++++++++ sound/soc/mediatek/an7581/an7581-reg.h | 114 ++++ 8 files changed, 1144 insertions(+), 1 deletion(-) create mode 100644 sound/soc/mediatek/an7581/Makefile create mode 100644 sound/soc/mediatek/an7581/an7581-afe-common.h create mode 100644 sound/soc/mediatek/an7581/an7581-afe-pcm.c create mode 100644 sound/soc/mediatek/an7581/an7581-dai-etdm.c create mode 100644 sound/soc/mediatek/an7581/an7581-reg.h diff --git a/MAINTAINERS b/MAINTAINERS index c3f72058a2f2..e3b7be8ad2dc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -768,6 +768,14 @@ F: Documentation/devicetree/bindings/phy/airoha,en7581= -pcie-phy.yaml F: drivers/phy/phy-airoha-pcie-regs.h F: drivers/phy/phy-airoha-pcie.c =20 +AIROHA SOUND DRIVER +M: Christian Marangi +L: linux-sound@vger.kernel.org +S: Maintained +F: Documentation/devicetree/bindings/sound/airoha,an7581-afe.yaml +F: Documentation/devicetree/bindings/sound/airoha,an7581-wm8960.yaml +F: sound/soc/mediatek/an7581/* + AIROHA SPI SNFI DRIVER M: Lorenzo Bianconi M: Ray Liu diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index 224746e7664f..eb6f2a443b23 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -1,10 +1,25 @@ # SPDX-License-Identifier: GPL-2.0-only -menu "Mediatek" =20 config SND_SOC_MEDIATEK tristate select REGMAP_MMIO =20 +menu "Airoha" + +config SND_SOC_AN7581 + tristate "ASoC support for Airoha AN7581 chip" + depends on ARCH_AIROHA || COMPILE_TEST + select SND_SOC_MEDIATEK + help + This adds ASoC platform driver support for Airoha AN7581 chip + that can be used with other codecs. + Select Y if you have such device. + If unsure select "N". + +endmenu + +menu "Mediatek" + config SND_SOC_MT2701 tristate "ASoC support for Mediatek MT2701 chip" depends on ARCH_MEDIATEK || COMPILE_TEST diff --git a/sound/soc/mediatek/Makefile b/sound/soc/mediatek/Makefile index a6815a3c5988..54522e1fa016 100644 --- a/sound/soc/mediatek/Makefile +++ b/sound/soc/mediatek/Makefile @@ -1,5 +1,6 @@ # SPDX-License-Identifier: GPL-2.0 obj-$(CONFIG_SND_SOC_MEDIATEK) +=3D common/ +obj-$(CONFIG_SND_SOC_AN7581) +=3D an7581/ obj-$(CONFIG_SND_SOC_MT2701) +=3D mt2701/ obj-$(CONFIG_SND_SOC_MT6797) +=3D mt6797/ obj-$(CONFIG_SND_SOC_MT7986) +=3D mt7986/ diff --git a/sound/soc/mediatek/an7581/Makefile b/sound/soc/mediatek/an7581= /Makefile new file mode 100644 index 000000000000..d6de5ee1668e --- /dev/null +++ b/sound/soc/mediatek/an7581/Makefile @@ -0,0 +1,8 @@ +# SPDX-License-Identifier: GPL-2.0 + +# platform driver +snd-soc-an7581-afe-y :=3D \ + an7581-afe-pcm.o \ + an7581-dai-etdm.o + +obj-$(CONFIG_SND_SOC_AN7581) +=3D snd-soc-an7581-afe.o diff --git a/sound/soc/mediatek/an7581/an7581-afe-common.h b/sound/soc/medi= atek/an7581/an7581-afe-common.h new file mode 100644 index 000000000000..ebc8e2f7fec4 --- /dev/null +++ b/sound/soc/mediatek/an7581/an7581-afe-common.h @@ -0,0 +1,49 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * an7581-afe-common.h -- Airoha AN7581 audio driver definitions + */ + +#ifndef _AN7581_AFE_COMMON_H_ +#define _AN7581_AFE_COMMON_H_ + +#include +#include +#include +#include + +#include "../../mediatek/common/mtk-base-afe.h" + +enum { + AN7581_MEMIF_DL1, + AN7581_MEMIF_UL1, + AN7581_MEMIF_NUM, + AN7581_DAI_ETDM =3D AN7581_MEMIF_NUM, + AN7581_DAI_NUM, +}; + +enum { + AN7581_IRQ_0, + AN7581_IRQ_1, + AN7581_IRQ_NUM, +}; + +struct an7581_memif_irq_desc { + u8 irq; + u32 status_bit; + u32 clear_reg; +}; + +struct an7581_afe_private { + unsigned int users; + /* protect concurrent ETDM user tracking */ + struct mutex user_lock; + + void *dai_priv[AN7581_DAI_NUM]; +}; + +unsigned int an7581_afe_rate_transform(struct device *dev, + unsigned int rate); + +int an7581_dai_etdm_register(struct mtk_base_afe *afe); + +#endif diff --git a/sound/soc/mediatek/an7581/an7581-afe-pcm.c b/sound/soc/mediate= k/an7581/an7581-afe-pcm.c new file mode 100644 index 000000000000..a1d742362538 --- /dev/null +++ b/sound/soc/mediatek/an7581/an7581-afe-pcm.c @@ -0,0 +1,515 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Airoha ALSA SoC AFE platform driver for AN7581 + * + */ + +#include +#include +#include +#include +#include +#include +#include + +#include "an7581-afe-common.h" +#include "an7581-reg.h" +#include "../common/mtk-afe-platform-driver.h" +#include "../common/mtk-afe-fe-dai.h" + +enum { + ARH_AFE_RATE_8K =3D 0, + ARH_AFE_RATE_12K =3D 1, + ARH_AFE_RATE_16K =3D 2, + ARH_AFE_RATE_24K =3D 3, + ARH_AFE_RATE_32K =3D 4, + ARH_AFE_RATE_48K =3D 5, + ARH_AFE_RATE_96K =3D 6, + ARH_AFE_RATE_192K =3D 7, + ARH_AFE_RATE_384K =3D 8, + ARH_AFE_RATE_7K =3D 16, + ARH_AFE_RATE_11K =3D 17, + ARH_AFE_RATE_14K =3D 18, + ARH_AFE_RATE_22K =3D 19, + ARH_AFE_RATE_29K =3D 20, + ARH_AFE_RATE_44K =3D 21, + ARH_AFE_RATE_88K =3D 22, + ARH_AFE_RATE_176K =3D 23, + ARH_AFE_RATE_352K =3D 24, +}; + +unsigned int an7581_afe_rate_transform(struct device *dev, unsigned int ra= te) +{ + switch (rate) { + case 7350: + return ARH_AFE_RATE_7K; + case 8000: + return ARH_AFE_RATE_8K; + case 11025: + return ARH_AFE_RATE_11K; + case 12000: + return ARH_AFE_RATE_12K; + case 14700: + return ARH_AFE_RATE_14K; + case 16000: + return ARH_AFE_RATE_16K; + case 22050: + return ARH_AFE_RATE_22K; + case 24000: + return ARH_AFE_RATE_24K; + case 29400: + return ARH_AFE_RATE_29K; + case 32000: + return ARH_AFE_RATE_32K; + case 44100: + return ARH_AFE_RATE_44K; + case 48000: + return ARH_AFE_RATE_48K; + case 88200: + return ARH_AFE_RATE_88K; + case 96000: + return ARH_AFE_RATE_96K; + case 176400: + return ARH_AFE_RATE_176K; + case 192000: + return ARH_AFE_RATE_192K; + case 352800: + return ARH_AFE_RATE_352K; + case 384000: + return ARH_AFE_RATE_384K; + default: + dev_warn_ratelimited(dev, "%s(), rate %u invalid, using %d!\n", + __func__, rate, ARH_AFE_RATE_48K); + return ARH_AFE_RATE_48K; + } +} + +static const struct an7581_memif_irq_desc an7581_memif_irq_descs[AN7581_ME= MIF_NUM] =3D { + [AN7581_MEMIF_DL1] =3D { + .irq =3D AN7581_IRQ_0, + .status_bit =3D AFE_IRQ_STS_PLAY, + .clear_reg =3D AFE_IRQ_CON0, + }, + [AN7581_MEMIF_UL1] =3D { + .irq =3D AN7581_IRQ_1, + .status_bit =3D AFE_IRQ_STS_RECORD, + .clear_reg =3D AFE_IRQ1_CON0, + }, +}; + +static const struct snd_pcm_hardware an7581_afe_hardware =3D { + .info =3D SNDRV_PCM_INFO_MMAP | + SNDRV_PCM_INFO_INTERLEAVED | + SNDRV_PCM_INFO_MMAP_VALID, + .formats =3D SNDRV_PCM_FMTBIT_S16_LE | + SNDRV_PCM_FMTBIT_S24_LE | + SNDRV_PCM_FMTBIT_S32_LE, + .period_bytes_min =3D 512, + .period_bytes_max =3D 128 * 1024, + .periods_min =3D 2, + .periods_max =3D 256, + .buffer_bytes_max =3D 256 * 1024, +}; + +static int an7581_memif_irq_fs(struct snd_pcm_substream *substream, unsign= ed int rate) +{ + struct snd_soc_pcm_runtime *rtd =3D snd_soc_substream_to_rtd(substream); + struct snd_soc_component *component =3D snd_soc_rtdcom_lookup(rtd, AFE_PC= M_NAME); + struct mtk_base_afe *afe =3D snd_soc_component_get_drvdata(component); + + return an7581_afe_rate_transform(afe->dev, rate); +} + +static int an7581_afe_fe_startup(struct snd_pcm_substream *substream, stru= ct snd_soc_dai *dai) +{ + struct snd_pcm_runtime *runtime =3D substream->runtime; + struct mtk_base_afe *afe =3D snd_soc_dai_get_drvdata(dai); + int ret; + + ret =3D mtk_afe_fe_startup(substream, dai); + if (ret < 0) + return ret; + + if (substream->stream =3D=3D SNDRV_PCM_STREAM_CAPTURE) { + ret =3D snd_pcm_hw_constraint_minmax(runtime, + SNDRV_PCM_HW_PARAM_PERIOD_SIZE, + 0x2000, UINT_MAX); + if (ret < 0) + dev_err(afe->dev, "hw_constraint_minmax failed\n"); + } + + return ret; +} + +const struct snd_soc_dai_ops an7581_afe_fe_ops =3D { + .startup =3D an7581_afe_fe_startup, + .shutdown =3D mtk_afe_fe_shutdown, + .hw_params =3D mtk_afe_fe_hw_params, + .hw_free =3D mtk_afe_fe_hw_free, + .prepare =3D mtk_afe_fe_prepare, + .trigger =3D mtk_afe_fe_trigger, +}; + +#define ARH_PCM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver an7581_memif_dai_driver[] =3D { + /* FE DAIs: memory intefaces to CPU */ + { + .name =3D "DL1", + .id =3D AN7581_MEMIF_DL1, + .playback =3D { + .stream_name =3D "DL1", + .channels_min =3D 1, + .channels_max =3D 8, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .formats =3D ARH_PCM_FORMATS, + }, + .ops =3D &an7581_afe_fe_ops, + }, + { + .name =3D "UL1", + .id =3D AN7581_MEMIF_UL1, + .capture =3D { + .stream_name =3D "UL1", + .channels_min =3D 1, + .channels_max =3D 8, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .formats =3D ARH_PCM_FORMATS, + }, + .ops =3D &an7581_afe_fe_ops, + }, +}; + +static const struct snd_soc_dapm_widget an7581_memif_widgets[] =3D { + /* DL */ + SND_SOC_DAPM_MIXER("I032", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I033", SND_SOC_NOPM, 0, 0, NULL, 0), + + /* UL */ + SND_SOC_DAPM_MIXER("O018", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("O019", SND_SOC_NOPM, 0, 0, NULL, 0), +}; + +static const struct snd_soc_dapm_route an7581_memif_routes[] =3D { + {"I032", NULL, "DL1"}, + {"I033", NULL, "DL1"}, + {"UL1", NULL, "O018"}, + {"UL1", NULL, "O019"}, + {"O018", NULL, "I150"}, + {"O019", NULL, "I151"}, +}; + +static const struct snd_soc_component_driver an7581_afe_pcm_dai_component = =3D { + .name =3D "an7581-afe-pcm-dai", +}; + +static const struct mtk_base_memif_data memif_data[AN7581_MEMIF_NUM] =3D { + [AN7581_MEMIF_DL1] =3D { + .name =3D "DL1", + .id =3D AN7581_MEMIF_DL1, + .reg_ofs_base =3D AFE_DL1_BASE, + .reg_ofs_cur =3D AFE_DL1_CUR, + .reg_ofs_end =3D AFE_DL1_END, + .fs_reg =3D -1, + .fs_shift =3D -1, + .fs_maskbit =3D -1, + .mono_reg =3D -1, + .mono_shift =3D -1, + .hd_reg =3D AFE_DL1_CON0, + .hd_shift =3D AFE_HD_SHIFT, + .hd_align_reg =3D -1, + .hd_align_mshift =3D -1, + .enable_reg =3D AFE_DAC_CON0, + .enable_shift =3D AFE_DL1_ENABLE_SHIFT, + .msb_reg =3D -1, + .msb_shift =3D -1, + .agent_disable_reg =3D -1, + .agent_disable_shift =3D -1, + }, + [AN7581_MEMIF_UL1] =3D { + .name =3D "UL1", + .id =3D AN7581_MEMIF_UL1, + .reg_ofs_base =3D AFE_UL1_BASE, + .reg_ofs_cur =3D AFE_UL1_CUR, + .reg_ofs_end =3D AFE_UL1_END, + .fs_reg =3D -1, + .fs_shift =3D -1, + .fs_maskbit =3D -1, + .mono_reg =3D -1, + .mono_shift =3D -1, + .hd_reg =3D AFE_UL1_CON0, + .hd_shift =3D AFE_HD_SHIFT, + .hd_align_reg =3D AFE_UL1_CON0, + .hd_align_mshift =3D AFE_HD_ALIGN_SHIFT, + .enable_reg =3D AFE_DAC_CON0, + .enable_shift =3D AFE_UL1_ENABLE_SHIFT, + .msb_reg =3D -1, + .msb_shift =3D -1, + .agent_disable_reg =3D -1, + .agent_disable_shift =3D -1, + }, +}; + +static const struct mtk_base_irq_data irq_data[AN7581_IRQ_NUM] =3D { + [AN7581_IRQ_0] =3D { + .id =3D AN7581_IRQ_0, + .irq_cnt_reg =3D AFE_IRQ_CNT, + .irq_cnt_shift =3D AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit =3D AFE_IRQ_CNT_MASK, + .irq_en_reg =3D AFE_IRQ_CON0, + .irq_en_shift =3D AFE_IRQ_ON_SHIFT, + .irq_fs_reg =3D -1, + .irq_fs_shift =3D -1, + .irq_fs_maskbit =3D -1, + .irq_clr_reg =3D -1, + .irq_clr_shift =3D -1, + }, + [AN7581_IRQ_1] =3D { + .id =3D AN7581_IRQ_1, + .irq_cnt_reg =3D AFE_IRQ1_CNT, + .irq_cnt_shift =3D AFE_IRQ_CNT_SHIFT, + .irq_cnt_maskbit =3D AFE_IRQ_CNT_MASK, + .irq_en_reg =3D AFE_IRQ1_CON0, + .irq_en_shift =3D AFE_IRQ_ON_SHIFT, + .irq_fs_reg =3D -1, + .irq_fs_shift =3D -1, + .irq_fs_maskbit =3D -1, + .irq_clr_reg =3D -1, + .irq_clr_shift =3D -1, + }, +}; + +static const struct regmap_config an7581_afe_regmap_config =3D { + .name =3D "afe", + .reg_bits =3D 32, + .reg_stride =3D 4, + .val_bits =3D 32, + .max_register =3D AFE_MAX_REGISTER, +}; + +static const struct regmap_config an7581_afe_irq1_regmap_config =3D { + .name =3D "afe_irq1", + .reg_bits =3D 32, + .reg_stride =3D 4, + .val_bits =3D 32, + .max_register =3D AFE_IRQ1_MAX_REGISTER, +}; + +static irqreturn_t an7581_afe_irq_handler(int irq_id, void *dev) +{ + const struct an7581_memif_irq_desc *irq_desc; + struct mtk_base_afe *afe =3D dev; + u32 status =3D 0; + int i; + + regmap_read(afe->regmap, AFE_IRQ_STS, &status); + + for (i =3D 0; i < AN7581_MEMIF_NUM; i++) { + struct mtk_base_afe_memif *memif =3D &afe->memif[i]; + + if (!memif->substream) + continue; + + if (memif->irq_usage < 0) + continue; + + irq_desc =3D &an7581_memif_irq_descs[i]; + if (status & irq_desc->status_bit) + snd_pcm_period_elapsed(memif->substream); + } + + for (i =3D 0; i < AN7581_MEMIF_NUM; i++) { + struct regmap *irq_regmap; + + irq_desc =3D &an7581_memif_irq_descs[i]; + if (!(status & irq_desc->status_bit)) + continue; + + irq_regmap =3D afe->irqs[irq_desc->irq].regmap; + regmap_set_bits(irq_regmap, irq_desc->clear_reg, + BIT(AFE_IRQ_CLR_SHIFT)); + regmap_clear_bits(irq_regmap, irq_desc->clear_reg, + BIT(AFE_IRQ_CLR_SHIFT)); + + regmap_set_bits(irq_regmap, irq_desc->clear_reg, + BIT(AFE_IRQ_MISS_FLG_CLR_SHIFT)); + regmap_clear_bits(irq_regmap, irq_desc->clear_reg, + BIT(AFE_IRQ_MISS_FLG_CLR_SHIFT)); + } + + return IRQ_HANDLED; +} + +static int an7581_dai_memif_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai =3D devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers =3D an7581_memif_dai_driver; + dai->num_dai_drivers =3D ARRAY_SIZE(an7581_memif_dai_driver); + + dai->dapm_widgets =3D an7581_memif_widgets; + dai->num_dapm_widgets =3D ARRAY_SIZE(an7581_memif_widgets); + dai->dapm_routes =3D an7581_memif_routes; + dai->num_dapm_routes =3D ARRAY_SIZE(an7581_memif_routes); + + return 0; +} + +typedef int (*dai_register_cb)(struct mtk_base_afe *); +static const dai_register_cb dai_register_cbs[] =3D { + an7581_dai_etdm_register, + an7581_dai_memif_register, +}; + +static int an7581_afe_pcm_dev_probe(struct platform_device *pdev) +{ + struct an7581_afe_private *afe_priv; + struct device *dev =3D &pdev->dev; + struct reset_control *reset; + struct mtk_base_afe *afe; + int i, irq_id, ret; + void *base; + + afe =3D devm_kzalloc(dev, sizeof(*afe), GFP_KERNEL); + if (!afe) + return -ENOMEM; + platform_set_drvdata(pdev, afe); + + afe->platform_priv =3D devm_kzalloc(dev, sizeof(*afe_priv), + GFP_KERNEL); + if (!afe->platform_priv) + return -ENOMEM; + + afe->irqs_size =3D AN7581_IRQ_NUM; + afe->irqs =3D devm_kcalloc(dev, afe->irqs_size, sizeof(*afe->irqs), + GFP_KERNEL); + if (!afe->irqs) + return -ENOMEM; + + afe->memif_size =3D AN7581_MEMIF_NUM; + afe->memif =3D devm_kcalloc(dev, afe->memif_size, sizeof(*afe->memif), + GFP_KERNEL); + if (!afe->memif) + return -ENOMEM; + + afe_priv =3D afe->platform_priv; + mutex_init(&afe_priv->user_lock); + afe->dev =3D &pdev->dev; + + reset =3D devm_reset_control_get_exclusive(dev, NULL); + if (IS_ERR(reset)) + return PTR_ERR(reset); + + /* Global reset I2S */ + reset_control_assert(reset); + usleep_range(10, 20); + reset_control_deassert(reset); + + afe->base_addr =3D devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(afe->base_addr)) + return PTR_ERR(afe->base_addr); + + base =3D devm_platform_ioremap_resource(pdev, 1); + if (IS_ERR(base)) + return PTR_ERR(base); + + ret =3D devm_pm_runtime_enable(dev); + if (ret) + return ret; + + afe->regmap =3D devm_regmap_init_mmio(&pdev->dev, afe->base_addr, + &an7581_afe_regmap_config); + if (IS_ERR(afe->regmap)) + return PTR_ERR(afe->regmap); + + mutex_init(&afe->irq_alloc_lock); + + /* irq initialize */ + for (i =3D 0; i < afe->irqs_size; i++) + afe->irqs[i].irq_data =3D &irq_data[i]; + + afe->irqs[AN7581_IRQ_0].regmap =3D afe->regmap; + afe->irqs[AN7581_IRQ_1].regmap =3D devm_regmap_init_mmio(&pdev->dev, base, + &an7581_afe_irq1_regmap_config); + if (IS_ERR(afe->irqs[AN7581_IRQ_1].regmap)) + return PTR_ERR(afe->irqs[AN7581_IRQ_1].regmap); + + /* request irq */ + irq_id =3D platform_get_irq(pdev, 0); + if (irq_id < 0) + return irq_id; + + /* init memif */ + for (i =3D 0; i < afe->memif_size; i++) { + int sel_irq =3D an7581_memif_irq_descs[i].irq; + + afe->memif[i].data =3D &memif_data[i]; + afe->memif[i].irq_usage =3D sel_irq; + afe->memif[i].const_irq =3D 1; + afe->irqs[sel_irq].irq_occupyed =3D true; + } + + /* init sub_dais */ + INIT_LIST_HEAD(&afe->sub_dais); + + ret =3D devm_request_irq(dev, irq_id, an7581_afe_irq_handler, + IRQF_TRIGGER_NONE, "asys-isr", (void *)afe); + if (ret) + return dev_err_probe(dev, ret, "Failed to request irq for asys-isr\n"); + + for (i =3D 0; i < ARRAY_SIZE(dai_register_cbs); i++) { + ret =3D dai_register_cbs[i](afe); + if (ret) + return dev_err_probe(dev, ret, "DAI register failed, i: %d\n", i); + } + + /* init dai_driver and component_driver */ + ret =3D mtk_afe_combine_sub_dai(afe); + if (ret) + return dev_err_probe(dev, ret, "mtk_afe_combine_sub_dai fail\n"); + + afe->mtk_afe_hardware =3D &an7581_afe_hardware; + afe->memif_fs =3D an7581_memif_irq_fs; + afe->irq_fs =3D an7581_memif_irq_fs; + + /* register component */ + ret =3D devm_snd_soc_register_component(&pdev->dev, + &mtk_afe_pcm_platform, + NULL, 0); + if (ret) + return dev_err_probe(dev, ret, "Cannot register AFE component\n"); + + ret =3D devm_snd_soc_register_component(afe->dev, + &an7581_afe_pcm_dai_component, + afe->dai_drivers, + afe->num_dai_drivers); + if (ret) + return dev_err_probe(dev, ret, "Cannot register PCM DAI component\n"); + + return 0; +} + +static const struct of_device_id an7581_afe_pcm_dt_match[] =3D { + { .compatible =3D "airoha,an7581-afe" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, an7581_afe_pcm_dt_match); + +static struct platform_driver an7581_afe_pcm_driver =3D { + .driver =3D { + .name =3D "an7581-audio", + .of_match_table =3D an7581_afe_pcm_dt_match, + }, + .probe =3D an7581_afe_pcm_dev_probe, +}; +module_platform_driver(an7581_afe_pcm_driver); + +MODULE_DESCRIPTION("Airoha SoC AFE platform driver for ALSA AN7581"); +MODULE_LICENSE("GPL"); diff --git a/sound/soc/mediatek/an7581/an7581-dai-etdm.c b/sound/soc/mediat= ek/an7581/an7581-dai-etdm.c new file mode 100644 index 000000000000..7fbfd8fe1836 --- /dev/null +++ b/sound/soc/mediatek/an7581/an7581-dai-etdm.c @@ -0,0 +1,433 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Airoha ALSA SoC Audio DAI eTDM Control + * + */ + +#include +#include +#include +#include +#include "an7581-afe-common.h" +#include "an7581-reg.h" + +#define HOPPING_CLK 0 +#define APLL_CLK 1 +#define MTK_DAI_ETDM_FORMAT_I2S 0 +#define MTK_DAI_ETDM_FORMAT_DSPA 4 +#define MTK_DAI_ETDM_FORMAT_DSPB 5 + +enum { + MTK_ETDM_RATE_8K =3D 0, + MTK_ETDM_RATE_12K =3D 1, + MTK_ETDM_RATE_16K =3D 2, + MTK_ETDM_RATE_24K =3D 3, + MTK_ETDM_RATE_32K =3D 4, + MTK_ETDM_RATE_48K =3D 5, + MTK_ETDM_RATE_96K =3D 6, + MTK_ETDM_RATE_192K =3D 7, + MTK_ETDM_RATE_384K =3D 8, + MTK_ETDM_RATE_7K =3D 16, + MTK_ETDM_RATE_11K =3D 17, + MTK_ETDM_RATE_14K =3D 18, + MTK_ETDM_RATE_22K =3D 19, + MTK_ETDM_RATE_29K =3D 20, + MTK_ETDM_RATE_44K =3D 21, + MTK_ETDM_RATE_88K =3D 22, + MTK_ETDM_RATE_176K =3D 23, + MTK_ETDM_RATE_352K =3D 24, +}; + +struct mtk_dai_etdm_priv { + bool bck_inv; + bool lrck_inv; + bool slave_mode; + unsigned int format; +}; + +static unsigned int an7581_etdm_rate_transform(struct device *dev, unsigne= d int rate) +{ + switch (rate) { + case 7350: + return MTK_ETDM_RATE_7K; + case 8000: + return MTK_ETDM_RATE_8K; + case 11025: + return MTK_ETDM_RATE_11K; + case 12000: + return MTK_ETDM_RATE_12K; + case 14700: + return MTK_ETDM_RATE_14K; + case 16000: + return MTK_ETDM_RATE_16K; + case 22050: + return MTK_ETDM_RATE_22K; + case 24000: + return MTK_ETDM_RATE_24K; + case 29400: + return MTK_ETDM_RATE_29K; + case 32000: + return MTK_ETDM_RATE_32K; + case 44100: + return MTK_ETDM_RATE_44K; + case 48000: + return MTK_ETDM_RATE_48K; + case 88200: + return MTK_ETDM_RATE_88K; + case 96000: + return MTK_ETDM_RATE_96K; + case 176400: + return MTK_ETDM_RATE_176K; + case 192000: + return MTK_ETDM_RATE_192K; + case 352800: + return MTK_ETDM_RATE_352K; + case 384000: + return MTK_ETDM_RATE_384K; + default: + dev_warn_ratelimited(dev, "%s(), rate %u invalid, using %d!\n", + __func__, rate, MTK_ETDM_RATE_48K); + return MTK_ETDM_RATE_48K; + } +} + +static int get_etdm_wlen(unsigned int bitwidth) +{ + return bitwidth <=3D 16 ? 16 : 32; +} + +static const struct snd_soc_dapm_widget mtk_dai_etdm_widgets[] =3D { + /* DL */ + SND_SOC_DAPM_MIXER("I150", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("I151", SND_SOC_NOPM, 0, 0, NULL, 0), + + /* UL */ + SND_SOC_DAPM_MIXER("O124", SND_SOC_NOPM, 0, 0, NULL, 0), + SND_SOC_DAPM_MIXER("O125", SND_SOC_NOPM, 0, 0, NULL, 0), +}; + +static const struct snd_soc_dapm_route mtk_dai_etdm_routes[] =3D { + {"I150", NULL, "ETDM Capture"}, + {"I151", NULL, "ETDM Capture"}, + {"ETDM Playback", NULL, "O124"}, + {"ETDM Playback", NULL, "O125"}, + {"O124", NULL, "I032"}, + {"O125", NULL, "I033"}, +}; + +/* dai ops */ +static int mtk_dai_etdm_startup(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe =3D snd_soc_dai_get_drvdata(dai); + struct an7581_afe_private *afe_priv =3D afe->platform_priv; + + guard(mutex)(&afe_priv->user_lock); + + if (!afe_priv->users) + regmap_set_bits(afe->regmap, AFE_DAC_CON0, + BIT(AFE_AFE_ENABLE_SHIFT)); + afe_priv->users++; + + return 0; +} + +static void mtk_dai_etdm_shutdown(struct snd_pcm_substream *substream, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe =3D snd_soc_dai_get_drvdata(dai); + struct an7581_afe_private *afe_priv =3D afe->platform_priv; + + guard(mutex)(&afe_priv->user_lock); + + afe_priv->users--; + if (!afe_priv->users) + regmap_clear_bits(afe->regmap, AFE_DAC_CON0, + BIT(AFE_AFE_ENABLE_SHIFT)); +} + +static unsigned int get_etdm_ch_fixup(unsigned int channels) +{ + if (channels > 16) + return 24; + + if (channels > 8) + return 16; + + if (channels > 4) + return 8; + + if (channels > 2) + return 4; + + return 2; +} + +static int mtk_dai_etdm_config(struct mtk_base_afe *afe, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai, + int stream) +{ + struct an7581_afe_private *afe_priv =3D afe->platform_priv; + struct mtk_dai_etdm_priv *etdm_data =3D afe_priv->dai_priv[dai->id]; + unsigned int rate =3D params_rate(params); + unsigned int etdm_rate =3D an7581_etdm_rate_transform(afe->dev, rate); + unsigned int bit_width =3D params_width(params); + unsigned int mask, mask1; + unsigned int val, val1; + + dev_dbg(afe->dev, "%s(), stream %d, rate %u, bitwidth %u\n", + __func__, stream, rate, params_width(params)); + + /* CON0 */ + mask =3D ETDM_SLAVE_MODE | ETDM_BIT_LEN | ETDM_WRD_LEN | + ETDM_FMT | ETDM_CH_NUM; + val =3D FIELD_PREP(ETDM_BIT_LEN, params_width(params) - 1) | + FIELD_PREP(ETDM_WRD_LEN, get_etdm_wlen(bit_width) - 1) | + FIELD_PREP(ETDM_FMT, etdm_data->format) | + FIELD_PREP(ETDM_CH_NUM, + get_etdm_ch_fixup(params_channels(params)) - 1); + if (etdm_data->slave_mode) + val |=3D ETDM_SLAVE_MODE; + + /* CON1 */ + mask1 =3D EDTM_LRCK_AUTO_MODE | EDTM_CKEN_SEL | EDTM_LRCK_AUTO_OFF | + EDTM_INITIAL_POINT | EDTM_INITIAL_COUNT; + val1 =3D EDTM_LRCK_AUTO_MODE | EDTM_CKEN_SEL | EDTM_LRCK_AUTO_OFF | + FIELD_PREP(EDTM_INITIAL_POINT, 14) | FIELD_PREP(EDTM_INITIAL_COUNT, 14); + + switch (stream) { + case SNDRV_PCM_STREAM_PLAYBACK: + regmap_update_bits(afe->regmap, ETDM_OUT1_CON0, mask, val); + + mask1 |=3D EDTM_DIRECT_INPUT_MASTER_BCK; + val1 |=3D EDTM_DIRECT_INPUT_MASTER_BCK; + + regmap_update_bits(afe->regmap, ETDM_OUT1_CON1, mask1, val1); + + regmap_update_bits(afe->regmap, ETDM_OUT1_CON4, OUT_SEL_FS, + FIELD_PREP(OUT_SEL_FS, etdm_rate)); + + regmap_update_bits(afe->irqs[AN7581_IRQ_0].regmap, + afe->irqs[AN7581_IRQ_0].irq_data->irq_en_reg, + AFE_IRQ_EN_SEL, AFE_IRQ_EN_SEL_I2SOUT); + break; + case SNDRV_PCM_STREAM_CAPTURE: + regmap_update_bits(afe->regmap, ETDM_IN1_CON0, mask, val); + + regmap_update_bits(afe->regmap, ETDM_IN1_CON1, mask1, val1); + + regmap_update_bits(afe->regmap, ETDM_IN1_CON3, IN_SEL_FS, + FIELD_PREP(IN_SEL_FS, etdm_rate)); + + regmap_update_bits(afe->irqs[AN7581_IRQ_1].regmap, + afe->irqs[AN7581_IRQ_1].irq_data->irq_en_reg, + AFE_IRQ_EN_SEL, AFE_IRQ_EN_SEL_I2SIN); + break; + default: + break; + } + + return 0; +} + +static int mtk_dai_etdm_hw_params(struct snd_pcm_substream *substream, + struct snd_pcm_hw_params *params, + struct snd_soc_dai *dai) +{ + unsigned int rate =3D params_rate(params); + struct mtk_base_afe *afe =3D snd_soc_dai_get_drvdata(dai); + + regmap_update_bits(afe->regmap, ETDM_COWORK_CON0, + EDTM_IN1_SLAVE_SEL, + EDTM_IN1_SLAVE_FROM_ETDMIN1_SLAVE); + regmap_update_bits(afe->regmap, ETDM_COWORK_CON0, + EDTM_OUT1_SLAVE_SEL, + EDTM_OUT1_SLAVE_FROM_ETDMOUT1_SLAVE); + regmap_update_bits(afe->regmap, ETDM_COWORK_CON1, + EDTM_IN1_SDATA0_SEL, + EDTM_IN1_SDATA0_FROM_PAD); + + switch (rate) { + case 7350: + case 8000: + case 11025: + case 12000: + case 14700: + case 16000: + case 22050: + case 24000: + case 29400: + case 32000: + case 44100: + case 48000: + case 88200: + case 96000: + case 176400: + case 192000: + case 352800: + case 384000: + return mtk_dai_etdm_config(afe, params, dai, substream->stream); + default: + dev_err(afe->dev, "Sample rate %d invalid\n", rate); + return -EINVAL; + } +} + +static int mtk_dai_etdm_trigger(struct snd_pcm_substream *substream, int c= md, + struct snd_soc_dai *dai) +{ + struct mtk_base_afe *afe =3D snd_soc_dai_get_drvdata(dai); + + dev_dbg(afe->dev, "%s(), cmd %d, dai id %d\n", __func__, cmd, dai->id); + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + case SNDRV_PCM_TRIGGER_RESUME: + if (substream->stream =3D=3D SNDRV_PCM_STREAM_PLAYBACK) + regmap_set_bits(afe->regmap, ETDM_OUT1_CON0, + ETDM_OUT_EN); + + if (substream->stream =3D=3D SNDRV_PCM_STREAM_CAPTURE) + regmap_set_bits(afe->regmap, ETDM_IN1_CON0, + ETDM_IN_EN); + + break; + case SNDRV_PCM_TRIGGER_STOP: + case SNDRV_PCM_TRIGGER_SUSPEND: + if (substream->stream =3D=3D SNDRV_PCM_STREAM_PLAYBACK) + regmap_clear_bits(afe->regmap, ETDM_OUT1_CON0, + ETDM_OUT_EN); + + if (substream->stream =3D=3D SNDRV_PCM_STREAM_CAPTURE) + regmap_clear_bits(afe->regmap, ETDM_IN1_CON0, + ETDM_IN_EN); + + break; + default: + break; + } + + return 0; +} + +static int mtk_dai_etdm_set_fmt(struct snd_soc_dai *dai, unsigned int fmt) +{ + struct mtk_base_afe *afe =3D snd_soc_dai_get_drvdata(dai); + struct an7581_afe_private *afe_priv =3D afe->platform_priv; + struct mtk_dai_etdm_priv *etdm_data; + void *priv_data; + + priv_data =3D devm_kzalloc(afe->dev, sizeof(struct mtk_dai_etdm_priv), + GFP_KERNEL); + if (!priv_data) + return -ENOMEM; + + afe_priv->dai_priv[dai->id] =3D priv_data; + etdm_data =3D afe_priv->dai_priv[dai->id]; + + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) { + case SND_SOC_DAIFMT_I2S: + etdm_data->format =3D MTK_DAI_ETDM_FORMAT_I2S; + break; + case SND_SOC_DAIFMT_DSP_A: + etdm_data->format =3D MTK_DAI_ETDM_FORMAT_DSPA; + break; + case SND_SOC_DAIFMT_DSP_B: + etdm_data->format =3D MTK_DAI_ETDM_FORMAT_DSPB; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_INV_MASK) { + case SND_SOC_DAIFMT_NB_NF: + etdm_data->bck_inv =3D false; + etdm_data->lrck_inv =3D false; + break; + case SND_SOC_DAIFMT_NB_IF: + etdm_data->bck_inv =3D false; + etdm_data->lrck_inv =3D true; + break; + case SND_SOC_DAIFMT_IB_NF: + etdm_data->bck_inv =3D true; + etdm_data->lrck_inv =3D false; + break; + case SND_SOC_DAIFMT_IB_IF: + etdm_data->bck_inv =3D true; + etdm_data->lrck_inv =3D true; + break; + default: + return -EINVAL; + } + + switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) { + case SND_SOC_DAIFMT_BP_FP: + etdm_data->slave_mode =3D false; + break; + case SND_SOC_DAIFMT_BC_FC: + etdm_data->slave_mode =3D true; + break; + default: + return -EINVAL; + } + + return 0; +} + +static const struct snd_soc_dai_ops mtk_dai_etdm_ops =3D { + .startup =3D mtk_dai_etdm_startup, + .shutdown =3D mtk_dai_etdm_shutdown, + .hw_params =3D mtk_dai_etdm_hw_params, + .trigger =3D mtk_dai_etdm_trigger, + .set_fmt =3D mtk_dai_etdm_set_fmt, +}; + +/* dai driver */ +#define MTK_ETDM_FORMATS (SNDRV_PCM_FMTBIT_S16_LE |\ + SNDRV_PCM_FMTBIT_S24_LE |\ + SNDRV_PCM_FMTBIT_S32_LE) + +static struct snd_soc_dai_driver mtk_dai_etdm_driver[] =3D { + { + .name =3D "ETDM", + .id =3D AN7581_DAI_ETDM, + .capture =3D { + .stream_name =3D "ETDM Capture", + .channels_min =3D 1, + .channels_max =3D 8, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .formats =3D MTK_ETDM_FORMATS, + }, + .playback =3D { + .stream_name =3D "ETDM Playback", + .channels_min =3D 1, + .channels_max =3D 8, + .rates =3D SNDRV_PCM_RATE_8000_192000, + .formats =3D MTK_ETDM_FORMATS, + }, + .ops =3D &mtk_dai_etdm_ops, + .symmetric_rate =3D 1, + .symmetric_sample_bits =3D 1, + }, +}; + +int an7581_dai_etdm_register(struct mtk_base_afe *afe) +{ + struct mtk_base_afe_dai *dai; + + dai =3D devm_kzalloc(afe->dev, sizeof(*dai), GFP_KERNEL); + if (!dai) + return -ENOMEM; + + list_add(&dai->list, &afe->sub_dais); + + dai->dai_drivers =3D mtk_dai_etdm_driver; + dai->num_dai_drivers =3D ARRAY_SIZE(mtk_dai_etdm_driver); + + dai->dapm_widgets =3D mtk_dai_etdm_widgets; + dai->num_dapm_widgets =3D ARRAY_SIZE(mtk_dai_etdm_widgets); + dai->dapm_routes =3D mtk_dai_etdm_routes; + dai->num_dapm_routes =3D ARRAY_SIZE(mtk_dai_etdm_routes); + + return 0; +} diff --git a/sound/soc/mediatek/an7581/an7581-reg.h b/sound/soc/mediatek/an= 7581/an7581-reg.h new file mode 100644 index 000000000000..a6ada3ca97ab --- /dev/null +++ b/sound/soc/mediatek/an7581/an7581-reg.h @@ -0,0 +1,114 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * an7581-reg.h -- Airoha AN7581 audio driver reg definition + */ + +#ifndef _AN7581_REG_H_ +#define _AN7581_REG_H_ + +#define AFE_DAC_CON0 0x0 +#define AFE_DL1_ENABLE_SHIFT 17 +#define AFE_UL1_ENABLE_SHIFT 1 +#define AFE_AFE_ENABLE_SHIFT 0 + +#define ETDM_COWORK_CON0 0x4c +#define EDTM_IN1_SLAVE_SEL GENMASK(27, 24) +#define EDTM_IN1_SLAVE_FROM_ETDMIN1_SLAVE FIELD_PREP_CONST(EDTM_IN1_SL= AVE_SEL, 0x1) +#define EDTM_IN1_SLAVE_FROM_ETDMIN2_MASTER FIELD_PREP_CONST(EDTM_IN1_S= LAVE_SEL, 0x2) +#define EDTM_IN1_SLAVE_FROM_ETDMIN2_SLAVE FIELD_PREP_CONST(EDTM_IN1_SL= AVE_SEL, 0x3) +#define EDTM_IN1_SLAVE_FROM_ETDMOUT1_MASTER FIELD_PREP_CONST(EDTM_IN1_= SLAVE_SEL, 0x8) +#define EDTM_IN1_SLAVE_FROM_ETDMOUT1_SLAVE FIELD_PREP_CONST(EDTM_IN1_S= LAVE_SEL, 0x9) +#define EDTM_IN1_SLAVE_FROM_ETDMOUT2_MASTER FIELD_PREP_CONST(EDTM_IN1_= SLAVE_SEL, 0xa) +#define EDTM_IN1_SLAVE_FROM_ETDMOUT2_SLAVE FIELD_PREP_CONST(EDTM_IN1_S= LAVE_SEL, 0xb) +#define EDTM_OUT1_SLAVE_SEL GENMASK(11, 8) +#define EDTM_OUT1_SLAVE_FROM_ETDMIN1_MASTER FIELD_PREP_CONST(EDTM_OUT1= _SLAVE_SEL, 0x0) +#define EDTM_OUT1_SLAVE_FROM_ETDMIN1_SLAVE FIELD_PREP_CONST(EDTM_OUT1_= SLAVE_SEL, 0x1) +#define EDTM_OUT1_SLAVE_FROM_ETDMIN2_MASTER FIELD_PREP_CONST(EDTM_OUT1= _SLAVE_SEL, 0x2) +#define EDTM_OUT1_SLAVE_FROM_ETDMIN2_SLAVE FIELD_PREP_CONST(EDTM_OUT1_= SLAVE_SEL, 0x3) +#define EDTM_OUT1_SLAVE_FROM_ETDMOUT1_SLAVE FIELD_PREP_CONST(EDTM_OUT1= _SLAVE_SEL, 0x9) +#define EDTM_OUT1_SLAVE_FROM_ETDMOUT2_MASTER FIELD_PREP_CONST(EDTM_OUT= 1_SLAVE_SEL, 0xa) +#define EDTM_OUT1_SLAVE_FROM_ETDMOUT2_SLAVE FIELD_PREP_CONST(EDTM_OUT1= _SLAVE_SEL, 0xb) +#define ETDM_COWORK_CON1 0x50 +#define EDTM_IN1_SDATA0_SEL GENMASK(3, 0) +#define EDTM_IN1_SDATA0_FROM_PAD FIELD_PREP_CONST(EDTM_IN1_SDATA0_SEL,= 0x0) +#define EDTM_IN1_SDATA0_FROM_ETDMIN2 FIELD_PREP_CONST(EDTM_IN1_SDATA0_= SEL, 0x2) +#define EDTM_IN1_SDATA0_FROM_ETDMOUT1 FIELD_PREP_CONST(EDTM_IN1_SDATA0= _SEL, 0x8) +#define EDTM_IN1_SDATA0_FROM_ETDMOUT2 FIELD_PREP_CONST(EDTM_IN1_SDATA0= _SEL, 0xa) +#define ETDM_IN1_CON0 0x5c +#define ETDM_CH_NUM GENMASK(26, 23) +#define ETDM_WRD_LEN GENMASK(20, 16) +#define ETDM_BIT_LEN GENMASK(15, 11) +#define ETDM_FMT GENMASK(8, 6) +#define ETDM_SLAVE_MODE BIT(5) +#define ETDM_IN_EN BIT(0) +#define ETDM_IN1_CON1 0x60 +#define EDTM_LRCK_AUTO_MODE BIT(29) +#define EDTM_DIRECT_INPUT_MASTER_BCK BIT(30) +#define EDTM_CKEN_SEL BIT(12) +#define EDTM_LRCK_AUTO_OFF BIT(10) +#define EDTM_INITIAL_POINT GENMASK(9, 5) +#define EDTM_INITIAL_COUNT GENMASK(4, 0) +#define ETDM_IN1_CON2 0x64 +#define IN_CLK_SRC GENMASK(12, 10) +#define ETDM_IN1_CON3 0x68 +#define IN_SEL_FS GENMASK(30, 26) +#define ETDM_IN1_CON4 0x6c +#define IN_RELATCH GENMASK(24, 20) +#define IN_CLK_INV BIT(18) +#define ETDM_IN1_CON5 0x70 +#define ETDM_IN1_CON6 0x74 +#define ETDM_OUT1_CON0 0x7c +#define ETDM_SYNC_MODE BIT(1) +#define ETDM_OUT_EN BIT(0) +#define ETDM_OUT1_CON1 0x80 +#define ETDM_OUT1_CON2 0x84 +#define ETDM_OUT1_CON3 0x88 +#define ETDM_OUT1_CON4 0x8c +#define OUT_RELATCH GENMASK(28, 24) +#define OUT_CLK_SRC GENMASK(8, 6) +#define OUT_SEL_FS GENMASK(4, 0) +#define ETDM_OUT1_CON5 0x90 +#define ETDM_CLK_DIV BIT(12) +#define OUT_CLK_INV BIT(9) +#define ETDM_OUT1_CON6 0x94 +#define ETDM_OUT1_CON7 0x98 + +#define AFE_DL1_BASE 0xa8 +#define AFE_DL1_END 0xb0 +#define AFE_DL1_CUR 0xac +#define AFE_DL1_CON0 0xb4 +#define AFE_PBUF_SIZE_SHIFT 16 +#define AFE_PBUF_SIZE_MASK GENMASK(1, 0) +#define AFE_MINLEN_SHIFT 8 +#define AFE_MINLEN_MASK GENMASK(3, 0) +#define AFE_HD_SHIFT 5 + +#define AFE_UL1_BASE 0xc4 +#define AFE_UL1_END 0xc8 +#define AFE_UL1_CUR 0xcc +#define AFE_UL1_CON0 0xd0 +#define AFE_HD_ALIGN_SHIFT 6 + +#define AFE_IRQ_CON0 0xe4 +#define AFE_IRQ_EN_SEL BIT(4) +#define AFE_IRQ_EN_SEL_I2SIN FIELD_PREP_CONST(AFE_IRQ_EN_SEL, 0x0) +#define AFE_IRQ_EN_SEL_I2SOUT FIELD_PREP_CONST(AFE_IRQ_EN_SEL, 0x1) +#define AFE_IRQ_MISS_FLG_CLR_SHIFT 3 +#define AFE_IRQ_CLR_SHIFT 2 +#define AFE_IRQ_ON_SHIFT 0 +#define AFE_IRQ_CNT 0xe8 +#define AFE_IRQ_CNT_SHIFT 0 +#define AFE_IRQ_CNT_MASK GENMASK(31, 0) + +#define AFE_IRQ_STS 0xf8 +#define AFE_IRQ_STS_PLAY BIT(1) +#define AFE_IRQ_STS_RECORD BIT(0) + +#define AFE_MAX_REGISTER AFE_IRQ_STS + +#define AFE_IRQ1_CON0 0x0 +#define AFE_IRQ1_CNT 0x4 + +#define AFE_IRQ1_MAX_REGISTER AFE_IRQ1_CNT + +#endif --=20 2.53.0 From nobody Fri Sep 25 21:40:26 2026 Received: from mail-ej1-f53.google.com (mail-ej1-f53.google.com [209.85.218.53]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 8752D5221FB for ; Tue, 8 Sep 2026 09:05:07 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.218.53 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788858309; cv=none; b=kq4c8KnO3Mk1A6l//7lFVZqmvt8RSm6ojTelcdCEMIWMBpI6zYYMQuV5zyl1pNO2Ykx7OIvcgAhtG3TXxNEo7dfaQqjw2nxWgmxYzwrMQxgcfuyzGCW6nmS+vxGI0A7HTs/pW1+2vFD17xSFqzDy5U+kkgBpZivwFTYBzzfngWI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1788858309; c=relaxed/simple; bh=rGl5KD/Lsmhceafje8JR5J3lsWCl4QMVB9JZSb6cYSk=; h=From:To:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aNyljooI78oHZF2GEv19zVASkgEJHsOlqj8W4ZG7J0bkay9qaqreRqkE9fFWmk+zWD4bsoJXP8Ch8MMjkeX8mdZjoqrsNSVbWubrRVJDspeWG5R066B5Xm4Mp9wmDQTGFfq3RnjhrB5dSDg6JxFbyQhLH9R3yC4Vi5cFkf8VWZ0= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com; spf=pass smtp.mailfrom=gmail.com; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b=F5xAaOr2; arc=none smtp.client-ip=209.85.218.53 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=gmail.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=gmail.com header.i=@gmail.com header.b="F5xAaOr2" Received: by mail-ej1-f53.google.com with SMTP id a640c23a62f3a-c262f1186f0so307734866b.1 for ; Tue, 08 Sep 2026 02:05:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1788858305; x=1789463105; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:from:to:cc:subject:date:message-id :reply-to:content-type; bh=hbChVgQBy46bP5VSQcyBCPGQv7TiEnk5yKXI2w9RsyY=; b=F5xAaOr2C7KrexDG2DnrbyfAb8EspUl8KTJNayu3xeF8nOtbhnEojHrnJwM/XrihCT 6lP0jAv6gmBJGp1HaCDkk8yDgr1/4/cixHYmNEefiQ84oUovIzBLX5TwjcNufxuFijDm xe+Ba0JuUiBZQHYEeuvl6r06PBLxK3LgzPM6fup5FnEb39uKg5icGHvHlW1eF4y1TJLj QRcks+dMJN207/3HmnFjwLRbxT76AAR4AOeH1qv8O7WKzFcjyfaLjMRGuehOsg+K2AKC MPrYsuGspSC7XsGFr1YYcNbXobJOkmbqX/0sdr/EhejjKfQHhrVXKgGQ2ulVYNTRCydW IbFg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1788858305; x=1789463105; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:to:from:x-gm-gg:x-gm-message-state:from:to :cc:subject:date:message-id:reply-to:content-type; bh=hbChVgQBy46bP5VSQcyBCPGQv7TiEnk5yKXI2w9RsyY=; b=OWsbu9o4L4c2NOK4WX4p/VDy+/pP22MorLXa/FIdq19CIDaUOBt1Qx/GQDowWFIToV AAoFbwsY69ghgk01eSQEcc5msCSYwoteDPQq1JFsT4o9/LxdC9+XdL7alwjjSKFRV82p CIVqDGNJ7+uapyEGz3tKrGnszoYwV1Kwi53VUp8UofLvyXiWwt2ANJPtGsK5oUIHhAtn VL6Ja4PcQXwTm3g8eC7V0NtlwkBAe+RPujRR1Zwca9/3M59J0C7Mxy2gNvw/MMuF7HXP cyMQSg1hhs4MCbv/ZEOijJdrWg0TtLJPnLXAst89S2SO99+XCS6W8HDQCfLz0nORt8Th l8bg== X-Forwarded-Encrypted: i=1; AKwUvBw9zAg+PUgm6PTiVFUNojqvED4kJZnq4SYTJ8mVIzOMgDOzjI0doYePS+GvzmGwESIWwKZU6pnRqhT3SjU=@vger.kernel.org X-Gm-Message-State: AFuF++m+x/VGExxkZKg8Dp5234x+g3yS9ocHKVeL9z8Q/oKy3wM5f4cf EqAso1n6tzvT/0ujGZTanxiQVQHLh4VxsHgu+klOTS/3xIOG8SC+ss6g X-Gm-Gg: AYBFou2caCw8+pvUm5UWWmNPstL7r/53e+tIjuWHkOO9p08Gi+v42Nf54Cj9M2ErZEI O9vW/59T6IrzPSemFhD2csAcF+CPPRzjQdvBeDNaI6wAkKeDORMLSKgw1GF44f786+hzQBXRlWc mOGqTtqMmD7lvx29w5u+/teYl/MeJUN9oulsPUskIklGrN/c5fy9zNDVngBvj8DKpK+easIBmf6 FusN3Ca+i1oqOib3dztWftv+wUoJgtT7J2NetMtIDVlxkiopvcr6qeQpTGoWyRbueuPcMwHp2rH 4/YegnBOPUZgPSJa2WNM/yxQMXi/MeA4iPZQSzSVat11+L4Q+/oHUYQWLYauP4uWvmVP9poOxB2 aetefaszo6C7TP7J6erJze4rJLoLRorFB205rLr5uCQbQUNZ6CmJBNUVDWrsDvwhGQtkCYgC+vi Ugj865yZUqcw0nHy00iKW68ctN3PhTAHgP8umDuH3SaAkFt3EjlESS2xdIL4WSbYPvy+tvnvVpg pVlbOi/iuQVbZ+6jtrJXtcJ8ljpqG8xz3qT90dqfantPs+dcHpZ X-Received: by 2002:a17:906:7956:b0:c16:84dc:9607 with SMTP id a640c23a62f3a-c260ca323dcmr1963636366b.19.1788858305144; Tue, 08 Sep 2026 02:05:05 -0700 (PDT) Received: from Ansuel-XPS24.localdomain (host-79-26-252-140.retail.telecomitalia.it. [79.26.252.140]) by smtp.googlemail.com with ESMTPSA id ffacd0b85a97d-485881353e8sm34767945f8f.1.2026.09.08.02.05.03 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 08 Sep 2026 02:05:04 -0700 (PDT) From: Christian Marangi To: Christian Marangi , Liam Girdwood , Mark Brown , Rob Herring , Krzysztof Kozlowski , Conor Dooley , Jaroslav Kysela , Takashi Iwai , Matthias Brugger , AngeloGioacchino Del Regno , Philipp Zabel , Cyril Chao , Darren Ye , Rosen Penev , Daniel Golle , bui duc phuc , linux-sound@vger.kernel.org, devicetree@vger.kernel.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-mediatek@lists.infradead.org Subject: [PATCH v6 5/5] ASoC: airoha: Add machine driver for Airoha AN7581 Date: Tue, 8 Sep 2026 11:04:47 +0200 Message-ID: <20260908090448.3332-6-ansuelsmth@gmail.com> X-Mailer: git-send-email 2.53.0 In-Reply-To: <20260908090448.3332-1-ansuelsmth@gmail.com> References: <20260908090448.3332-1-ansuelsmth@gmail.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Add support for the machine driver for Airoha AN7581 paired with the WM8960 i2c codec. This driver creates the sound card for the AFE driver. Signed-off-by: Christian Marangi --- sound/soc/mediatek/Kconfig | 10 ++ sound/soc/mediatek/an7581/Makefile | 1 + sound/soc/mediatek/an7581/an7581-wm8960.c | 161 ++++++++++++++++++++++ 3 files changed, 172 insertions(+) create mode 100644 sound/soc/mediatek/an7581/an7581-wm8960.c diff --git a/sound/soc/mediatek/Kconfig b/sound/soc/mediatek/Kconfig index eb6f2a443b23..ff2869641a35 100644 --- a/sound/soc/mediatek/Kconfig +++ b/sound/soc/mediatek/Kconfig @@ -16,6 +16,16 @@ config SND_SOC_AN7581 Select Y if you have such device. If unsure select "N". =20 +config SND_SOC_AN7581_WM8960 + tristate "ASoc Audio driver for Airoha AN7581 with WM8960 codec" + depends on SND_SOC_AN7581 && I2C + select SND_SOC_WM8960 + help + This adds support for ASoC machine driver for Airoha AN7581 + boards with the WM8960 codecs. + Select Y if you have such device. + If unsure select "N". + endmenu =20 menu "Mediatek" diff --git a/sound/soc/mediatek/an7581/Makefile b/sound/soc/mediatek/an7581= /Makefile index d6de5ee1668e..f48cd0269bea 100644 --- a/sound/soc/mediatek/an7581/Makefile +++ b/sound/soc/mediatek/an7581/Makefile @@ -6,3 +6,4 @@ snd-soc-an7581-afe-y :=3D \ an7581-dai-etdm.o =20 obj-$(CONFIG_SND_SOC_AN7581) +=3D snd-soc-an7581-afe.o +obj-$(CONFIG_SND_SOC_AN7581_WM8960) +=3D an7581-wm8960.o diff --git a/sound/soc/mediatek/an7581/an7581-wm8960.c b/sound/soc/mediatek= /an7581/an7581-wm8960.c new file mode 100644 index 000000000000..03ea5732563c --- /dev/null +++ b/sound/soc/mediatek/an7581/an7581-wm8960.c @@ -0,0 +1,161 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Airoha ALSA SoC I2S platform driver for AN7581 + * + */ + +#include +#include + +#include "an7581-afe-common.h" + +SND_SOC_DAILINK_DEFS(playback, + DAILINK_COMP_ARRAY(COMP_CPU("DL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY(), COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(capture, + DAILINK_COMP_ARRAY(COMP_CPU("UL1")), + DAILINK_COMP_ARRAY(COMP_DUMMY()), + DAILINK_COMP_ARRAY(COMP_EMPTY(), COMP_EMPTY())); + +SND_SOC_DAILINK_DEFS(codec, + DAILINK_COMP_ARRAY(COMP_CPU("ETDM")), + DAILINK_COMP_ARRAY(COMP_CODEC(NULL, "wm8960-hifi")), + DAILINK_COMP_ARRAY(COMP_EMPTY(), COMP_EMPTY())); + +static struct snd_soc_dai_link an7581_wm8960_dai_links[] =3D { + /* FE */ + { + .name =3D "wm8960-playback", + .stream_name =3D "wm8960-playback", + .trigger =3D {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .dynamic =3D 1, + .playback_only =3D 1, + SND_SOC_DAILINK_REG(playback), + }, + { + .name =3D "wm8960-capture", + .stream_name =3D "wm8960-capture", + .trigger =3D {SND_SOC_DPCM_TRIGGER_POST, + SND_SOC_DPCM_TRIGGER_POST}, + .dynamic =3D 1, + .capture_only =3D 1, + SND_SOC_DAILINK_REG(capture), + }, + /* BE */ + { + .name =3D "wm8960-codec", + .no_pcm =3D 1, + .dai_fmt =3D SND_SOC_DAIFMT_I2S | + SND_SOC_DAIFMT_NB_NF | + SND_SOC_DAIFMT_CBP_CFP | + SND_SOC_DAIFMT_GATED, + SND_SOC_DAILINK_REG(codec), + }, +}; + +static struct snd_soc_card an7581_wm8960_card =3D { + .name =3D "an7581-wm8960", + .owner =3D THIS_MODULE, + .dai_link =3D an7581_wm8960_dai_links, + .num_links =3D ARRAY_SIZE(an7581_wm8960_dai_links), +}; + +static int an7581_wm8960_machine_probe(struct platform_device *pdev) +{ + struct device_node *platform_dai_node, *codec_dai_node; + struct snd_soc_card *card =3D &an7581_wm8960_card; + struct device_node *of_platform, *codec; + struct snd_soc_dai_link *dai_link; + int i, d, ret; + + card->dev =3D &pdev->dev; + + of_platform =3D of_get_child_by_name(pdev->dev.of_node, "platform"); + + if (of_platform) { + platform_dai_node =3D of_parse_phandle(of_platform, "sound-dai", 0); + of_node_put(of_platform); + + if (!platform_dai_node) { + dev_err(&pdev->dev, "Failed to parse platform/sound-dai property\n"); + return -EINVAL; + } + } else { + dev_err(&pdev->dev, "Property 'platform' missing or invalid\n"); + return -EINVAL; + } + + for_each_card_prelinks(card, i, dai_link) { + struct snd_soc_dai_link_component *platform; + + dai_link->num_platforms =3D 2; + for_each_link_platforms(dai_link, d, platform) { + if (platform->name) + continue; + platform->of_node =3D platform_dai_node; + } + } + + codec =3D of_get_child_by_name(pdev->dev.of_node, "codec"); + + if (codec) { + codec_dai_node =3D of_parse_phandle(codec, "sound-dai", 0); + of_node_put(codec); + + if (!codec_dai_node) { + of_node_put(platform_dai_node); + dev_err(&pdev->dev, "Failed to parse codec/sound-dai property\n"); + return -EINVAL; + } + } else { + of_node_put(platform_dai_node); + dev_err(&pdev->dev, "Property 'codec' missing or invalid\n"); + return -EINVAL; + } + + for_each_card_prelinks(card, i, dai_link) { + if (dai_link->codecs->name) + continue; + dai_link->codecs->of_node =3D codec_dai_node; + } + + ret =3D snd_soc_of_parse_audio_routing(card, "audio-routing"); + if (ret) { + dev_err(&pdev->dev, "Failed to parse audio-routing: %d\n", ret); + goto err_of_node_put; + } + + ret =3D devm_snd_soc_register_card(&pdev->dev, card); + if (ret) { + dev_err_probe(&pdev->dev, ret, "%s snd_soc_register_card fail\n", __func= __); + goto err_of_node_put; + } + + return 0; + +err_of_node_put: + of_node_put(platform_dai_node); + of_node_put(codec_dai_node); + return ret; +} + +static const struct of_device_id an7581_wm8960_machine_dt_match[] =3D { + { .compatible =3D "airoha,an7581-wm8960-sound" }, + { /* sentinel */ } +}; +MODULE_DEVICE_TABLE(of, an7581_wm8960_machine_dt_match); + +static struct platform_driver an7581_wm8960_driver =3D { + .driver =3D { + .name =3D "an7581-wm8960", + .of_match_table =3D an7581_wm8960_machine_dt_match, + }, + .probe =3D an7581_wm8960_machine_probe, +}; +module_platform_driver(an7581_wm8960_driver); + +MODULE_DESCRIPTION("Airoha SoC I2S platform driver for ALSA AN7581"); +MODULE_LICENSE("GPL"); --=20 2.53.0